Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorganize By Namespace #292

Merged
merged 1 commit into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ tableextension 50100 "Just Some Table Extension" extends Customer //18
* `DisableWaldoSnippets`: Disables the CRS snippets that come with this extension. When you change the setting, you need to restart VSCode twice. Once for disabling the snippets on activation (at that time, the snippets are still loaded). And the second time to actually not load the snippets anymore.
* `SkipWarningMessageOnRenameAll`: Skips the Warning when renaming all files which can disturb custom VS tasks.
* `RenameWithGit`: Use 'git mv' to rename a file. This keeps history of the file, but stages the rename, which you should commit separately. **The feature is still in preview-mode, therefore the default value is 'false'**

* `ReorganizeByNamespace`: This is a feature that allows for the automatic reorganization of files by creating folder structures based on the namespaces defined within the files. **The feature is still in preview-mode, therefore the default value is 'false'**
## Skip String manipulation

You can skip string manipulation by adding comments to your code:
Expand Down
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,12 @@
"description": "Use 'git mv' to rename a file. This keeps history of the file, but stages the rename, which you should commit separately. The feature is still in preview-mode, therefore the default value is 'false'",
"scope": "resource"
},
"CRS.ReorganizeByNamespace": {
"type": "boolean",
"default": false,
"description": "This is a feature that allows for the automatic reorganization of files by creating folder structures based on the namespaces defined within the files. The feature is still in preview-mode, therefore the default value is 'false'",
"scope": "resource"
},
"CRS.SearchObjectNamesRegexPattern": {
"type": "string",
"default": "^\\w+ (\\d* )?\"*",
Expand Down
8 changes: 7 additions & 1 deletion src/NAVObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export class NAVObject {
public objectType: string;
public objectId: string;
public objectName: string;
public objectNamespace: string;
public objectActions: NAVObjectAction[] = new Array();
public tableFields: NAVTableField[] = new Array();
public pageFields: NAVPageField[] = new Array();
Expand Down Expand Up @@ -155,6 +156,7 @@ export class NAVObject {
this.objectType = '';
this.objectId = '';
this.objectName = '';
this.objectNamespace = '';
this.extendedObjectName = '';
this.extendedObjectId = '';
var ObjectNamePattern = '"[^"]*"' // All characters except "
Expand Down Expand Up @@ -273,7 +275,11 @@ export class NAVObject {
return null
}
}

var patternObject = new RegExp('namespace\\s+([A-Za-z0-9_.]+?)\\s*;', "i");
var match = this.NAVObjectText.match(patternObject);
if (match && match[1]) {
this.objectNamespace = match[1];
}
this.objectType = this.objectType.trim().toString();
this.objectId = this.objectId.trim().toString();
this.objectName = this.objectName.trim().toString().replace(/["]/g, '');
Expand Down
2 changes: 2 additions & 0 deletions src/Settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export class Settings {
static readonly DisableDefaultAlSnippets = 'DisableDefaultAlSnippets';
static readonly DisableCRSSnippets = 'DisableCRSSnippets';
static readonly RenameWithGit = 'RenameWithGit';
static readonly ReorganizeByNamespace = 'ReorganizeByNamespace';
static readonly Browser = 'browser';
static readonly Incognito = 'incognito';
static readonly packageCachePath = 'packageCachePath';
Expand Down Expand Up @@ -100,6 +101,7 @@ export class Settings {
this.SettingCollection[this.DisableCRSSnippets] = this.getSetting(this.DisableCRSSnippets);
this.SettingCollection[this.PublicWebBaseUrl] = this.getSetting(this.PublicWebBaseUrl);
this.SettingCollection[this.RenameWithGit] = this.getSetting(this.RenameWithGit);
this.SettingCollection[this.ReorganizeByNamespace] = this.getSetting(this.ReorganizeByNamespace);
this.SettingCollection[this.SearchObjectNamesRegexPattern] = this.getSetting(this.SearchObjectNamesRegexPattern);
this.SettingCollection[this.DependencyGraphIncludeTestApps] = this.getSetting(this.DependencyGraphIncludeTestApps);
this.SettingCollection[this.DependencyGraphExcludeAppNames] = this.getSetting(this.DependencyGraphExcludeAppNames);
Expand Down
31 changes: 26 additions & 5 deletions src/WorkspaceFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export class WorkspaceFiles {
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));
let objectTypeFolder = path.join(objectFolder, this.getObjectTypeFolder(navObject, settings));//Boe
let objectSubFolder = path.join(objectTypeFolder, this.getObjectSubFolder(navObject));
let destinationFileName = path.join(objectSubFolder, fixedname);

Expand All @@ -97,9 +97,10 @@ export class WorkspaceFiles {
return fileName.fsPath;
} else {

(!fs.existsSync(objectFolder)) ? fs.mkdirSync(objectFolder) : '';
(!fs.existsSync(objectTypeFolder)) ? fs.mkdirSync(objectTypeFolder) : '';
(!fs.existsSync(objectSubFolder)) ? fs.mkdirSync(objectSubFolder) : '';
//(!fs.existsSync(objectFolder)) ? fs.mkdirSync(objectFolder) : '';
//(!fs.existsSync(objectTypeFolder)) ? fs.mkdirSync(objectTypeFolder) : '';
//(!fs.existsSync(objectSubFolder)) ? fs.mkdirSync(objectSubFolder) : '';
this.createDirectoryIfNotExists(objectSubFolder);

withGit = withGit ? withGit : (git.isGitRepositorySync() && settings[Settings.RenameWithGit])
this.DoRenameFile(fileName, destinationFileName, withGit)
Expand Down Expand Up @@ -308,13 +309,19 @@ export class WorkspaceFiles {
return mySettings[Settings.AlSubFolderName]
}

static getObjectTypeFolder(navObject: NAVObject): string {
static getObjectTypeFolder(navObject: NAVObject, mySettings: any): string {
if (navObject.objectCodeunitSubType) {
if (navObject.objectCodeunitSubType.toLowerCase() == 'test') {
return ''
}
}

if (mySettings[Settings.ReorganizeByNamespace])
{
let directoryPath = path.join(...navObject.objectNamespace.split("."))
return directoryPath
}

return navObject.objectType
}

Expand All @@ -326,6 +333,20 @@ export class WorkspaceFiles {
return "";
}

static createDirectoryIfNotExists(dir) {
const segments = dir.split(path.sep);
let currentPath = segments[0];

for (let i = 1; i < segments.length; i++) {
if (segments[i]) {
currentPath = path.join(currentPath, segments[i]);
if (!fs.existsSync(currentPath)) {
fs.mkdirSync(currentPath);
}
}
}
}

static async CreateGraphVizDependencyGraph() {
crsOutput.showOutput(`Creating dependency graph (GraphViz) from apps in this workspace`, true);

Expand Down
21 changes: 21 additions & 0 deletions src/test/suite/NAVTestObjectLibrary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,27 @@ export function getNormalCodeunitWithLongName(): NAVTestObject {
return object;
}

export function getNormalCodeunitWithNamespace(): NAVTestObject {
let object = new NAVTestObject;

object.ObjectFileName = 'Cod50100.justAName.al'
object.ObjectText = `
namespace spycoclown.test;
using Microsoft.Inventory.Item;
codeunit 50100 "Test Overload"
{
[EventSubscriber(ObjectType::Codeunit, Codeunit::LogInManagement, 'OnAfterLogInStart', '', false, false)]
local procedure TestOverLoad()
var
Item: Record Item;
begin
item.CalculateClassification(true, 'namespace');
end;
}
`
return object;
}

export function getTestCodeunit(): NAVTestObject {
let object = new NAVTestObject;

Expand Down
15 changes: 13 additions & 2 deletions src/test/suite/WorkspaceFiles.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ suite("WorkspaceFiles Tests", () => {
let navTestObject = NAVTestObjectLibrary.getTestCodeunit();
let navObject = new NAVObject(navTestObject.ObjectText, testSettings, navTestObject.ObjectFileName);

let foldersuggestion = WorkspaceFiles.getObjectTypeFolder(navObject);
let foldersuggestion = WorkspaceFiles.getObjectTypeFolder(navObject,testSettings);

assert.strictEqual(foldersuggestion.toLowerCase(), '');
})
Expand All @@ -44,9 +44,20 @@ suite("WorkspaceFiles Tests", () => {
let navTestObject = NAVTestObjectLibrary.getNormalCodeunitWithLongName();
let navObject = new NAVObject(navTestObject.ObjectText, testSettings, navTestObject.ObjectFileName);

let foldersuggestion = WorkspaceFiles.getObjectTypeFolder(navObject);
let foldersuggestion = WorkspaceFiles.getObjectTypeFolder(navObject,testSettings);

assert.strictEqual(foldersuggestion.toLowerCase().toString(), navObject.objectType.toString());
assert.notStrictEqual(foldersuggestion.toLowerCase().toString(), '');
})
test("getObjectTypeFolder - return namespace", () => {
let testSettings = Settings.GetConfigSettings(null);
testSettings[Settings.ReorganizeByNamespace] = true;
let navTestObject = NAVTestObjectLibrary.getNormalCodeunitWithNamespace();
let navObject = new NAVObject(navTestObject.ObjectText, testSettings, navTestObject.ObjectFileName);

let foldersuggestion = WorkspaceFiles.getObjectTypeFolder(navObject,testSettings);

assert.notStrictEqual(foldersuggestion.toLowerCase().toString(), navObject.objectNamespace.toLowerCase().toString());
assert.strictEqual(foldersuggestion.toLowerCase().toString(), 'spycoclown\\test');
})
})