From 1799d0c425338365d05e5a06e12972601db21c19 Mon Sep 17 00:00:00 2001 From: cegekaJG <120664985+cegekaJG@users.noreply.github.com> Date: Mon, 22 Apr 2024 15:11:59 +0000 Subject: [PATCH 1/9] Update package.json to include new "FolderPathPattern" property Add new placeholder to pattern properties --- package.json | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 1a1323a9..4f1be580 100644 --- a/package.json +++ b/package.json @@ -180,19 +180,25 @@ "CRS.FileNamePattern": { "Type": "string", "default": "..al", - "description": "The pattern of the filename for non-extension objects.. These vars can be used: ,,,,,,,,", + "description": "The pattern of the filename for non-extension objects.. These vars can be used: ,,,,,,,,,", "scope": "resource" }, "CRS.FileNamePatternExtensions": { "Type": "string", "default": "-Ext..al", - "description": "The pattern of the filename for extension objects. These vars can be used: ,,,,,,,,,,, (If you want this to work, you need to put the Id in comment after the base name, like //21)", + "description": "The pattern of the filename for extension objects. These vars can be used: ,,,,,,,,,,,, (If you want this to work, you need to put the Id in comment after the base name, like //21)", "scope": "resource" }, "CRS.FileNamePatternPageCustomizations": { "Type": "string", "default": "-PageCust..al", - "description": "The pattern of the filename for extension objects. These vars can be used: ,,,,,,,,,, (If you want this to work, you need to put the Id in comment after the base name, like //21)", + "description": "The pattern of the filename for extension objects. These vars can be used: ,,,,,,,,,,, (If you want this to work, you need to put the Id in comment after the base name, like //21)", + "scope": "resource" + }, + "CRS.FolderPathPattern": { + "Type": "string", + "default": "\\\\", + "description": "The pattern of the folder containing the object. These vars can be used: ,,,,,,,,,,,", "scope": "resource" }, "CRS.AlSubFolderName": { @@ -471,20 +477,23 @@ }, "dependencies": { "applicationinsights": "^2.2.0", + "ncp": "^2.0.0", "open": "^6.0.0", - "simple-git": "^3.16.0" + "powershell": "^2.3.2", + "simple-git": "^3.16.0", + "vscode": "^1.1.37" }, "devDependencies": { - "@types/vscode": "^1.28.0", "@types/glob": "^7.2.0", "@types/mocha": "^9.0.0", - "@types/node": "14.x", + "@types/node": "^14.18.63", + "@types/vscode": "^1.28.0", "@typescript-eslint/eslint-plugin": "^5.9.1", "@typescript-eslint/parser": "^5.9.1", + "@vscode/test-electron": "^2.0.3", "eslint": "^8.6.0", "glob": "^7.2.0", - "mocha": "^9.1.3", - "typescript": "^4.5.4", - "@vscode/test-electron": "^2.0.3" + "mocha": "^9.2.2", + "typescript": "^4.5.4" } -} \ No newline at end of file +} From 1e0325835a07064fc24f2469634a1a4a9d999fd2 Mon Sep 17 00:00:00 2001 From: cegekaJG <120664985+cegekaJG@users.noreply.github.com> Date: Mon, 22 Apr 2024 15:12:36 +0000 Subject: [PATCH 2/9] Add new "FolderPathPattern" to Settings class --- src/Settings.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Settings.ts b/src/Settings.ts index 64bdf4b9..c7bbaf1d 100644 --- a/src/Settings.ts +++ b/src/Settings.ts @@ -25,6 +25,7 @@ export class Settings { static readonly FileNamePattern = 'FileNamePattern'; static readonly FileNamePatternExtensions = 'FileNamePatternExtensions'; static readonly FileNamePatternPageCustomizations = 'FileNamePatternPageCustomizations'; + static readonly FolderPathPattern = 'FolderPathPattern'; static readonly OnSaveAlFileAction = 'OnSaveAlFileAction'; static readonly ObjectNamePrefix = 'ObjectNamePrefix'; static readonly ObjectNameSuffix = 'ObjectNameSuffix'; @@ -90,6 +91,7 @@ export class Settings { this.SettingCollection[this.FileNamePattern] = this.getSetting(this.FileNamePattern); this.SettingCollection[this.FileNamePatternExtensions] = this.getSetting(this.FileNamePatternExtensions); this.SettingCollection[this.FileNamePatternPageCustomizations] = this.getSetting(this.FileNamePatternPageCustomizations); + this.SettingCollection[this.FolderPathPattern] = this.getSetting(this.FolderPathPattern); this.SettingCollection[this.ObjectNamePrefix] = this.getSetting(this.ObjectNamePrefix); this.SettingCollection[this.ObjectNameSuffix] = this.getSetting(this.ObjectNameSuffix); this.SettingCollection[this.RemovePrefixFromFilename] = this.getSetting(this.RemovePrefixFromFilename); From c6ae86e8b47a1856d1a5d8361a1bbf45502bf147 Mon Sep 17 00:00:00 2001 From: cegekaJG <120664985+cegekaJG@users.noreply.github.com> Date: Mon, 22 Apr 2024 15:17:07 +0000 Subject: [PATCH 3/9] Update NAVObjects class to expand pattern matching Avoid duplicate code by reusing functions Add "fixedFolderPath" property to generate subfolders --- src/NAVObject.ts | 66 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 16 deletions(-) diff --git a/src/NAVObject.ts b/src/NAVObject.ts index 33c6e7c2..e16d1a0d 100644 --- a/src/NAVObject.ts +++ b/src/NAVObject.ts @@ -19,6 +19,7 @@ export class NAVObject { public NAVObjectText: string; private _workSpaceSettings: Settings; private _objectFileNamePattern: string; + private _objectFolderPathPattern: string; // Windows chars not allowed in filenames or paths (includes Linux): // < (less than) @@ -44,16 +45,12 @@ export class NAVObject { } setObjectProperies(objectType: string, objectId: string, objectName: string) { - this._objectFileNamePattern = this._workSpaceSettings[Settings.FileNamePattern]; - this.objectType = objectType; - this.objectId = objectId; - this.objectName = objectName; - this.extendedObjectName = ''; - this.extendedObjectId = ''; + this.setObjectExtensionProperies(objectType, objectId, objectName, '', ''); } setObjectExtensionProperies(objectType: string, objectId: string, objectName: string, extendedObjectId: string, extendedObjectName: string) { this._objectFileNamePattern = this._workSpaceSettings[Settings.FileNamePatternExtensions]; + this._objectFolderPathPattern = this._workSpaceSettings[Settings.FolderPathPattern]; this.objectType = objectType; this.objectId = objectId; this.objectName = objectName; @@ -123,6 +120,15 @@ export class NAVObject { return objectFileNameFixed; } + get objectFolderPathFixed(): string { + let objectFolderPathFixed = this._objectFolderPathPattern + + objectFolderPathFixed = this.ApplyPatternToFolderPath(objectFolderPathFixed); + objectFolderPathFixed = this.RemoveUnderscore(objectFolderPathFixed); + + return objectFolderPathFixed; + } + get objectCodeunitSubType(): string { if (this.objectType.toLowerCase() != 'codeunit') { return null } @@ -153,6 +159,7 @@ export class NAVObject { let ObjectTypeArr = filteredlines.toString().match(patternObjectType); this._objectFileNamePattern = ''; + this._objectFolderPathPattern = ''; this.objectType = ''; this.objectId = ''; this.objectName = ''; @@ -190,6 +197,7 @@ export class NAVObject { this.objectName = currObject[3]; this._objectFileNamePattern = this._workSpaceSettings[Settings.FileNamePattern]; + this._objectFolderPathPattern = this._workSpaceSettings[Settings.FolderPathPattern]; break; } @@ -213,6 +221,7 @@ export class NAVObject { this.extendedObjectId = currObject[6] ? currObject[6] : ''; this._objectFileNamePattern = this._workSpaceSettings[Settings.FileNamePatternExtensions]; + this._objectFolderPathPattern = this._workSpaceSettings[Settings.FolderPathPattern]; break; } @@ -226,6 +235,7 @@ export class NAVObject { this.objectName = currObject[2]; this._objectFileNamePattern = this._workSpaceSettings[Settings.FileNamePattern]; + this._objectFolderPathPattern = this._workSpaceSettings[Settings.FolderPathPattern]; break; } @@ -239,6 +249,7 @@ export class NAVObject { this.objectName = currObject[2]; this._objectFileNamePattern = this._workSpaceSettings[Settings.FileNamePattern]; + this._objectFolderPathPattern = this._workSpaceSettings[Settings.FolderPathPattern]; break; } @@ -251,6 +262,7 @@ export class NAVObject { this.objectName = currObject[2]; this._objectFileNamePattern = this._workSpaceSettings[Settings.FileNamePattern]; + this._objectFolderPathPattern = this._workSpaceSettings[Settings.FolderPathPattern]; break; } @@ -265,6 +277,7 @@ export class NAVObject { this.extendedObjectName = currObject[3]; this.extendedObjectId = currObject[5] ? currObject[5] : ''; this._objectFileNamePattern = this._workSpaceSettings[Settings.FileNamePatternPageCustomizations]; + this._objectFolderPathPattern = this._workSpaceSettings[Settings.FolderPathPattern]; break; } @@ -290,6 +303,7 @@ export class NAVObject { if (!(this.IsValidObjectType(this.objectType))) { //reset variables this._objectFileNamePattern = ''; + this._objectFolderPathPattern = ''; this.objectType = ''; this.objectId = ''; this.objectName = ''; @@ -374,6 +388,7 @@ export class NAVObject { result = StringFunctions.replaceAll(result, '', this._workSpaceSettings[Settings.ObjectNamePrefix]); result = StringFunctions.replaceAll(result, '', this._workSpaceSettings[Settings.ObjectNameSuffix]); result = StringFunctions.replaceAll(result, '', this.objectType) + result = StringFunctions.replaceAll(result, '', this.objectType.toLowerCase()); result = StringFunctions.replaceAll(result, '', this.objectTypeShort); result = StringFunctions.replaceAll(result, '', this.ObjectTypeShortPascalCase); result = StringFunctions.replaceAll(result, '', this.objectTypeShort.toUpperCase()); @@ -387,19 +402,38 @@ export class NAVObject { private ApplyPatternToFileName(pattern: string): string { let result = pattern; - result = StringFunctions.replaceAll(result, '', this._workSpaceSettings[Settings.ObjectNamePrefix]); - result = StringFunctions.replaceAll(result, '', this._workSpaceSettings[Settings.ObjectNameSuffix]); - result = StringFunctions.replaceAll(result, '', this.objectType) - result = StringFunctions.replaceAll(result, '', this.objectTypeShort); - result = StringFunctions.replaceAll(result, '', this.ObjectTypeShortPascalCase); - result = StringFunctions.replaceAll(result, '', this.objectTypeShort.toUpperCase()); - result = StringFunctions.replaceAll(result, '', this.objectId); result = StringFunctions.replaceAll(result, '', this.objectNameFixedForFileName); result = StringFunctions.replaceAll(result, '', this.objectNameFixedShort); - result = StringFunctions.replaceAll(result, '', this.extendedObjectNameFixedForFileName); - result = StringFunctions.replaceAll(result, '', this.extendedObjectNameFixedShort); - result = StringFunctions.replaceAll(result, '', this.extendedObjectId); + result = this.ApplyPatternToObjectName(result); + + return result; + } + private ApplyPatternToFolderPath(pattern: string): string { + let result = pattern; + result = this.replaceControlAddIn(result); + result = StringFunctions.replaceAll(result, '', this._workSpaceSettings[Settings.AlSubFolderName]); + result = this.ApplyPatternToFileName(result); + + let folders = result.split('\\'); + folders = folders.map(folder => folder.replace(/^\s+|\s+$/g, '')); + result = folders.join('\\'); + + return result; + } + private replaceControlAddIn(pattern: string): string { + let result = pattern; + let controladdin = ''; + const controlAddInPattern = ''; + const doubleBackslashPattern = '\\'; + if (this.objectType.toLocaleLowerCase() == 'controladdin') { + controladdin = this.objectNameFixedShort; + } + if (controladdin == '' && result.includes(doubleBackslashPattern)) { + result = StringFunctions.replaceAll(result, doubleBackslashPattern, controladdin); + } else { + result = StringFunctions.replaceAll(result, controlAddInPattern, controladdin); + } return result; } private AddPrefixAndSuffixToObjectNameFixed(objectName: string): string { From 408277244bfe00a6428578ef8209ee49840ef42f Mon Sep 17 00:00:00 2001 From: cegekaJG <120664985+cegekaJG@users.noreply.github.com> Date: Mon, 22 Apr 2024 15:18:06 +0000 Subject: [PATCH 4/9] Update "ReorganizeFile" function to allow for custom subfolders --- src/WorkspaceFiles.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/WorkspaceFiles.ts b/src/WorkspaceFiles.ts index a3ab46e8..08346efe 100644 --- a/src/WorkspaceFiles.ts +++ b/src/WorkspaceFiles.ts @@ -87,12 +87,12 @@ export class WorkspaceFiles { let fixedname = navObject.objectFileNameFixed if (navObject.objectFileName && navObject.objectFileName != '' && fixedname && fixedname != '') { - let objectFolder = path.join(vscode.workspace.getWorkspaceFolder(fileName).uri.fsPath, this.getDestinationFolder(navObject, settings)); - let objectTypeFolder = path.join(objectFolder, this.getObjectTypeFolder(navObject, settings)); - let objectSubFolder = path.join(objectTypeFolder, this.getObjectSubFolder(navObject)); - let destinationFileName = path.join(objectSubFolder, fixedname); + let appFolder = vscode.workspace.getWorkspaceFolder(fileName).uri.fsPath; + let relativeFolderPath = navObject.objectFolderPathFixed; + let absoluteFolderPath = path.join(appFolder, relativeFolderPath); + let destinationFileName = path.join(absoluteFolderPath, fixedname); - if (destinationFileName.toLocaleLowerCase() == fileName.fsPath.toLocaleLowerCase()) { + if (destinationFileName == fileName.fsPath) { //console.log('paths are the same.'); return fileName.fsPath; } else { @@ -100,7 +100,7 @@ export class WorkspaceFiles { //(!fs.existsSync(objectFolder)) ? fs.mkdirSync(objectFolder) : ''; //(!fs.existsSync(objectTypeFolder)) ? fs.mkdirSync(objectTypeFolder) : ''; //(!fs.existsSync(objectSubFolder)) ? fs.mkdirSync(objectSubFolder) : ''; - this.createDirectoryIfNotExists(objectSubFolder); + this.createDirectoryIfNotExists(absoluteFolderPath); withGit = withGit ? withGit : (git.isGitRepositorySync() && settings[Settings.RenameWithGit]) this.DoRenameFile(fileName, destinationFileName, withGit) From 897c29de6dbb3fc74e14e54289bec7e5cc11b0f1 Mon Sep 17 00:00:00 2001 From: cegekaJG <120664985+cegekaJG@users.noreply.github.com> Date: Mon, 22 Apr 2024 15:38:36 +0000 Subject: [PATCH 5/9] Remove obsolete function --- src/WorkspaceFiles.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/WorkspaceFiles.ts b/src/WorkspaceFiles.ts index 08346efe..b4cadf68 100644 --- a/src/WorkspaceFiles.ts +++ b/src/WorkspaceFiles.ts @@ -324,14 +324,6 @@ export class WorkspaceFiles { return navObject.objectType } - static getObjectSubFolder(navObject: NAVObject): string { - if (navObject.objectType == 'controladdin') { - return navObject.objectNameFixedShort - } - - return ""; - } - static createDirectoryIfNotExists(dir) { const segments = dir.split(path.sep); let currentPath = segments[0]; From e3fad9a64c1f87e93cb240a837d78af8b8ef0e5d Mon Sep 17 00:00:00 2001 From: cegekaJG <120664985+cegekaJG@users.noreply.github.com> Date: Mon, 22 Apr 2024 15:40:27 +0000 Subject: [PATCH 6/9] Update README.md to include new settings --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.md b/README.md index b47b8587..16f5905a 100644 --- a/README.md +++ b/README.md @@ -151,6 +151,7 @@ This extension contributes the following settings: - `` - `` - `` + - `` - same as "ObjectType", but lowercased - `` - a short notation of the object type. - `` - PascalCased object type - `` - Same as "ObjectTypeShort" but uppercased @@ -162,6 +163,7 @@ This extension contributes the following settings: - `` - just the prefix separately - `` - just the suffix separately - `` + - `` - same as "ObjectType", but lowercased - `` - a short notation of the object type. - `` - PascalCased object type - `` - Same as "ObjectTypeShort" but uppercased @@ -172,6 +174,7 @@ This extension contributes the following settings: - `` - just the prefix separately - `` - just the suffix separately - `` + - `` - same as "ObjectType", but lowercased - `` - a short notation of the object type. - `` - PascalCased object type - `` - Same as "ObjectTypeShort" but uppercased @@ -198,6 +201,7 @@ tableextension 50100 "Just Some Table Extension" extends Customer //18 - `` - just the prefix separately - `` - just the suffix separately - `` + - `` - same as "ObjectType", but lowercased - `` - a short notation of the object type. - `` - PascalCased object type - `` - Same as "ObjectTypeShort" but uppercased @@ -206,6 +210,19 @@ tableextension 50100 "Just Some Table Extension" extends Customer //18 - `` - weird chars are removed - does NOT include prefix nor suffix - `` - does NOT include prefix nor suffix - `` - same remarks as above! +* `CRS.FolderPathPattern`: The pattern of the path containing the file, relative to the app folder. These vars can be used: + - `` - just the prefix separately + - `` - just the suffix separately + - `` + - `` - same as "ObjectType", but lowercased + - `` - a short notation of the object type. + - `` - PascalCased object type + - `` - Same as "ObjectTypeShort" but uppercased + - `` + - `` - weird chars are removed - includes prefix and suffix + - `` + - `` - same as "CRS.AlSubFolderName" + - `` - same as "ObjectNameShort" if the object type is "Control Addin", otherwise skipped * `CRS.ObjectNamePrefix`: When using the Reorganize/Rename-commands, this setting will make sure the object name (and filename) will have a Prefix. - Tip 1: use as a workspace-setting. - Tip 2: use an ending-space if you want the prefix to be separated with a space. From 0be4216d91e3e587745b73f3a2ebbc185592bdd0 Mon Sep 17 00:00:00 2001 From: cegekaJG <120664985+cegekaJG@users.noreply.github.com> Date: Tue, 23 Apr 2024 10:31:57 +0000 Subject: [PATCH 7/9] Add control addin test object --- src/test/suite/NAVTestObjectLibrary.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/test/suite/NAVTestObjectLibrary.ts b/src/test/suite/NAVTestObjectLibrary.ts index be49e326..ef4b1fa9 100644 --- a/src/test/suite/NAVTestObjectLibrary.ts +++ b/src/test/suite/NAVTestObjectLibrary.ts @@ -1225,4 +1225,28 @@ export function getSimpleReportExtensionWithSummaryComments(): NAVTestObject { return object; } +export function getControlAddinObject(): NAVTestObject { + let object = new NAVTestObject; + object.ObjectFileName = 'SomeControlAddin.al' + object.ObjectText = `controladdin "My Control Addin" + { + RequestedHeight = 1; + MinimumHeight = 1; + MaximumHeight = 1; + RequestedWidth = 1; + MinimumWidth = 1; + MaximumWidth = 1; + VerticalStretch = true; + VerticalShrink = true; + HorizontalStretch = true; + HorizontalShrink = true; + Scripts = '.\src\javascript\MyScript.js'; + + event Ready() + + procedure MyProcedure() + } + ` + return object; +} From 7d3788f58bab5020f0b824689d8812bf4fca205e Mon Sep 17 00:00:00 2001 From: cegekaJG <120664985+cegekaJG@users.noreply.github.com> Date: Tue, 23 Apr 2024 10:32:00 +0000 Subject: [PATCH 8/9] Add test cases for folder path pattern --- src/test/suite/NAVObject.FilePattern.test.ts | 34 ++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/test/suite/NAVObject.FilePattern.test.ts b/src/test/suite/NAVObject.FilePattern.test.ts index 55df5bee..ced1deca 100644 --- a/src/test/suite/NAVObject.FilePattern.test.ts +++ b/src/test/suite/NAVObject.FilePattern.test.ts @@ -526,4 +526,38 @@ suite("NAVObject FilePattern Tests", () => { assert.strictEqual(navObject.objectFileNameFixed, 'CustomerTop10ListExt.ReportExt.al') }) + test("Folder path - Default folder path", () => { + let testSettings = Settings.GetConfigSettings(null) + + let navTestObject = NAVTestObjectLibrary.getPageNoPrefixCorrectNameWithActions(); + let navObject = new NAVObject(navTestObject.ObjectText, testSettings, navTestObject.ObjectFileName); + + assert.strictEqual(navObject.objectFolderPathFixed, + testSettings[Settings.AlSubFolderName] + '\\' + + navObject.objectType.toLowerCase() + '\\'); + }) + test("Folder path - Default folder path with control addin", () => { + let testSettings = Settings.GetConfigSettings(null) + + let navTestObject = NAVTestObjectLibrary.getControlAddinObject(); + let navObject = new NAVObject(navTestObject.ObjectText, testSettings, navTestObject.ObjectFileName); + + assert.strictEqual(navObject.objectFolderPathFixed, + testSettings[Settings.AlSubFolderName] + '\\' + + navObject.objectType.toLowerCase() + '\\' + + navObject.objectNameFixedShort); + }) + test("Folder path - Custom folder path with prefix", () => { + let testSettings = Settings.GetConfigSettings(null) + + testSettings[Settings.FolderPathPattern] = '\\\\'; + + let navTestObject = NAVTestObjectLibrary.getTestCodeunitWithPrefix(); + let navObject = new NAVObject(navTestObject.ObjectText, testSettings, navTestObject.ObjectFileName); + + assert.strictEqual(navObject.objectFolderPathFixed, + testSettings[Settings.AlSubFolderName] + '\\' + + testSettings[Settings.ObjectNamePrefix] + '\\' + + navObject.objectType.toLowerCase()); + }) }) From ecf1f5d48df61fa6e235f9f4cb2f6526fdca9922 Mon Sep 17 00:00:00 2001 From: cegekaJG <120664985+cegekaJG@users.noreply.github.com> Date: Tue, 23 Apr 2024 11:56:06 +0000 Subject: [PATCH 9/9] Remove accidental changes to dependencies --- package.json | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 4f1be580..4cd13121 100644 --- a/package.json +++ b/package.json @@ -477,23 +477,20 @@ }, "dependencies": { "applicationinsights": "^2.2.0", - "ncp": "^2.0.0", "open": "^6.0.0", - "powershell": "^2.3.2", - "simple-git": "^3.16.0", - "vscode": "^1.1.37" + "simple-git": "^3.16.0" }, "devDependencies": { + "@types/vscode": "^1.28.0", "@types/glob": "^7.2.0", "@types/mocha": "^9.0.0", - "@types/node": "^14.18.63", - "@types/vscode": "^1.28.0", + "@types/node": "14.x", "@typescript-eslint/eslint-plugin": "^5.9.1", "@typescript-eslint/parser": "^5.9.1", - "@vscode/test-electron": "^2.0.3", "eslint": "^8.6.0", "glob": "^7.2.0", - "mocha": "^9.2.2", - "typescript": "^4.5.4" + "mocha": "^9.1.3", + "typescript": "^4.5.4", + "@vscode/test-electron": "^2.0.3" } -} +} \ No newline at end of file