Skip to content
This repository has been archived by the owner on Oct 23, 2022. It is now read-only.

Commit

Permalink
Merge pull request #103 from amtrack/handle-folders
Browse files Browse the repository at this point in the history
handle DashboardFolder, DocumentFolder, EmailFolder and ReportFolder
  • Loading branch information
amtrack authored Jan 3, 2018
2 parents 3ca3a84 + 4700022 commit be7ba97
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 23 deletions.
75 changes: 68 additions & 7 deletions lib/describe-metadata-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,32 @@ var childTypes = [{

var metadataTypesAdditions = [];

var additionalMetadataTypes = [{
directoryName: "dashboards",
inFolder: false,
metaFile: true,
xmlName: "DashboardFolder"
},
{
directoryName: "documents",
inFolder: false,
metaFile: true,
xmlName: "DocumentFolder"
},
{
directoryName: "email",
inFolder: false,
metaFile: true,
xmlName: "EmailFolder"
},
{
directoryName: "reports",
inFolder: false,
metaFile: true,
xmlName: "ReportFolder"
}
];

var DescribeMetadataService = module.exports = function(describeMetadataResult) {
var self = this;
self.describeMetadataResult = describeMetadataResult ? describeMetadataResult : require('./describe-metadata-result.json');
Expand Down Expand Up @@ -309,6 +335,7 @@ var DescribeMetadataService = module.exports = function(describeMetadataResult)
}
self.metadataObjectsExtended.push(metadataObject);
});
self.metadataObjectsExtended = self.metadataObjectsExtended.concat(additionalMetadataTypes);
};

DescribeMetadataService.prototype.getTypes = function() {
Expand Down Expand Up @@ -351,12 +378,46 @@ DescribeMetadataService.prototype.getTypeForFilepath = function(filepath) {
var directoryMatches = self.getTypesForDirectoryName(directoryName);
var parentDirectoryMatches = self.getTypesForDirectoryName(parentDirectoryName);
var matches = _.unique([].concat(directoryMatches, parentDirectoryMatches));
if (matches.length > 1) {
// find the container metadata type
return _.find(matches, function(item) {
return item.childXmlNames;
});
} else {
return matches[0];

// find the container metadata type
var childMatch = _.find(matches, function(item) {
return item.childXmlNames;
});
if (childMatch) {
return childMatch;
}

var extnameMatch = _.find(matches, function(item) {
return item.suffix === extname;
});
if (extnameMatch) {
return extnameMatch;
}

// no required extension
var folderMatches = _.find(directoryMatches, function(item) {
return !item.inFolder && !item.suffix;
});
var parentFolderMatches = _.find(parentDirectoryMatches, function(item) {
return !item.inFolder && !item.suffix;
});
if (folderMatches && !parentFolderMatches) {
return folderMatches;
}

var extnameInFolder = _.find(matches, function(item) {
return item.inFolder && !item.suffix;
});
if (extnameInFolder) {
return extnameInFolder;
}

var inFolderMatches = _.find(matches, function(item) {
return item.inFolder;
});
if (inFolderMatches) {
return inFolderMatches;
}

return matches[0];
};
15 changes: 14 additions & 1 deletion lib/manifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ module.exports.fromFetchResult = function(resultJSON) {

Manifest.prototype.toPackageXml = function(destructive) {
var self = this;
self.transformFolders();
if (destructive) {
self.apiVersion = null;
}
Expand Down Expand Up @@ -114,6 +115,18 @@ Manifest.prototype.unique = function() {
return self;
}

Manifest.prototype.transformFolders = function() {
var self = this;
self.manifestJSON = self.manifestJSON.map(function(item) {
if (Object.keys(folderBasedMetadataMap).indexOf(item.type) > -1) {
// DocumentFolder has to be listed as Document
item.type = folderBasedMetadataMap[item.type];
}
return item;
});
return self;
}

// TODO: in order to factory reset, the following metadata has to be disabled manually:
// * ApprovalProcess
// * WorkflowRule?
Expand Down Expand Up @@ -144,7 +157,7 @@ Manifest.prototype.filterStandard = function() {
// ... is standard and cannot be deleted
return false;
}
if (['Dashboard', 'Document', 'EmailTemplate', 'Report'].indexOf(component.type) >= 0 && !new RegExp('^.*/.*$').test(component.fullName)) {
if (['Dashboard', 'DashboardFolder', 'Document', 'DocumentFolder', 'EmailTemplate', 'EmailFolder', 'Report', 'ReportFolder'].indexOf(component.type) >= 0 && !new RegExp('^.*/.*$').test(component.fullName)) {
// don't list folders
return false;
}
Expand Down
8 changes: 8 additions & 0 deletions lib/metadata-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
var describeMetadataService = new(require('./describe-metadata-service'))();
var metadataUtils = require('./utils');
var path = require('path');
var _ = require('underscore');

var config = new(require("./config"))();
var folderToMetadataType = config.get("folderBasedMetadataMap");
var metadataTypeToFolder = _.invert(folderToMetadataType);

/**
* MetadataComponent is a wrapper for a metadata component with its content
Expand Down Expand Up @@ -45,6 +50,9 @@ var MetadataComponent = module.exports = function(opts) {
// not a Folder
filenameParts.push(parts[2] + (firstPartType.xmlName === 'Document' ? '' : '.' + firstPartType.suffix));
fullNameParts.push(firstPartType.xmlName === 'Document' ? basename : filename);
} else {
// return the folder type
self.type = metadataTypeToFolder[self.type];
}
self.fileName = path.join.apply('', filenameParts);
self.fullName = fullNameParts.join('/');
Expand Down
11 changes: 7 additions & 4 deletions lib/metadata-container.js
Original file line number Diff line number Diff line change
Expand Up @@ -242,10 +242,13 @@ MetadataContainer.prototype.completeMetadataWith = function(opts) {
var stat = fs.statSync(realPath);
var relativePaths = [];
if (stat.isDirectory()) {
var foo = _.map(fs.readdirSync(realPath), function(f) {
return path.join(filename, f);
});
relativePaths = [].concat(relativePaths, foo);
// add all files in that directory in case of AuraDefitionBundle
if (filename.indexOf('aura') === 0) {
var foo = _.map(fs.readdirSync(realPath), function(f) {
return path.join(filename, f);
});
relativePaths = [].concat(relativePaths, foo);
}
} else {
relativePaths.push(filename);
}
Expand Down
8 changes: 8 additions & 0 deletions lib/metadata-file.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@

var File = require('vinyl');
var path = require('path');
var _ = require('underscore');
var metadataUtils = require('./utils');
var Manifest = require('./manifest');
var MetadataComponent = require('./metadata-component');
var describeMetadataService = new(require('./describe-metadata-service'))();

var config = new(require("./config"))();
var folderToMetadataType = config.get("folderBasedMetadataMap");
var metadataTypeToFolder = _.invert(folderToMetadataType);

/**
* MetadataFile represents a file on the filesystem.
* It inherits from vinyl.
Expand Down Expand Up @@ -111,6 +116,9 @@ MetadataFile.prototype.getComponent = function() {
// not a Folder, then prepend folder name
fileNameParts.unshift(metadataFile.basenameDirname());
fullNameParts.unshift(metadataFile.basenameDirname());
} else {
// return the folder type
result.type = metadataTypeToFolder[metadataType.xmlName];
}
var fileNamePartsPath = path.join.apply('', fileNameParts);
result.fileName = path.join(metadataType.directoryName, fileNamePartsPath);
Expand Down
9 changes: 9 additions & 0 deletions test/describe-metadata-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,21 @@ describe('Metadata', function() {
describe('#getTypeForFilepath()', function() {
it('should return metadata type for a given file path', function() {
assert.deepEqual(describeMetadataService.getTypeForFilepath(path.join('pages', 'Test.page')).xmlName, 'ApexPage');
assert.deepEqual(describeMetadataService.getTypeForFilepath(path.join('pages', 'Test.page-meta.xml')).xmlName, 'ApexPage');
assert.deepEqual(describeMetadataService.getTypeForFilepath(path.join('objects', 'Account.object')).xmlName, 'CustomObject');
assert.deepEqual(describeMetadataService.getTypeForFilepath(path.join('aura', 'TestApp')).xmlName, 'AuraDefinitionBundle');
assert.deepEqual(describeMetadataService.getTypeForFilepath(path.join('aura', 'TestApp', 'TestApp.app')).xmlName, 'AuraDefinitionBundle');
assert.deepEqual(describeMetadataService.getTypeForFilepath(path.join('aura', 'TestApp', 'TestApp.cmp')).xmlName, 'AuraDefinitionBundle');
assert.deepEqual(describeMetadataService.getTypeForFilepath(path.join('aura', 'TestApp', 'TestApp.js')).xmlName, 'AuraDefinitionBundle');
assert.deepEqual(describeMetadataService.getTypeForFilepath(path.join('aura', 'TestApp', 'TestApp.css')).xmlName, 'AuraDefinitionBundle');
assert.deepEqual(describeMetadataService.getTypeForFilepath(path.join('reports', 'unfiled$public')).xmlName, 'ReportFolder');
assert.deepEqual(describeMetadataService.getTypeForFilepath(path.join('reports', 'unfiled$public', 'Foo.report')).xmlName, 'Report');
assert.deepEqual(describeMetadataService.getTypeForFilepath(path.join('documents', 'unfiled$public')).xmlName, 'DocumentFolder');
assert.deepEqual(describeMetadataService.getTypeForFilepath(path.join('documents', 'unfiled$public', 'Foo')).xmlName, 'Document');
assert.deepEqual(describeMetadataService.getTypeForFilepath(path.join("documents", "unfiled$public", "Foo.bin")).xmlName, "Document");
assert.deepEqual(describeMetadataService.getTypeForFilepath(path.join("documents", "documents")).xmlName, "DocumentFolder");
assert.deepEqual(describeMetadataService.getTypeForFilepath(path.join("documents", "documents", "Foo")).xmlName, "Document");
assert.deepEqual(describeMetadataService.getTypeForFilepath(path.join("documents", "documents", "Foo.bin")).xmlName, "Document");
});
it('should return undefined for an invalid file path', function() {
assert.deepEqual(describeMetadataService.getTypeForFilepath(path.join('foo', 'bar')), undefined);
Expand Down
2 changes: 1 addition & 1 deletion test/manifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ describe('Manifest', function() {
});
manifest.add(new MetadataComponent('CustomObject/Account'));
manifest.add(new MetadataComponent('AppMenu/Salesforce1'));
manifest.add(new MetadataComponent('Document/MyFolder'));
manifest.add(new MetadataComponent('DocumentFolder/unfiled$public'));
manifest.add(new MetadataComponent('MatchingRule/Account.Standard_Account_Match_Rule_v1_0'));
manifest.add(new MetadataComponent('CustomApplication/standard__Sales'));
assert.deepEqual(manifest.filterStandard().getComponentNames(), ['ApexComponent/C1', 'ApexComponent/Z1', 'ApexPage/Test', 'ApexPage/Test2', 'CustomLabel/MyLabel']);
Expand Down
29 changes: 21 additions & 8 deletions test/metadata-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,27 @@ describe('MetadataComponent', function() {
assert.deepEqual(metadataComponent.fileName, path.join('documents', 'unfiled$public', 'Test.pdf'));
assert.deepEqual(metadataComponent.toString(), 'Document/unfiled$public/Test.pdf');
});
// TODO: it should be possible to construct a DocumentFolder component
// it('should return a metadata component for a DocumentFolder', function() {
// var metadataComponent = new MetadataComponent('DocumentFolder/unfiled$public');
// assert.deepEqual(metadataComponent.type, 'DocumentFolder');
// assert.deepEqual(metadataComponent.fullName, 'unfiled$public/Test.pdf');
// assert.deepEqual(metadataComponent.fileName, path.join('documents', 'unfiled$public'));
// assert.deepEqual(metadataComponent.toString(), 'DocumentFolder/unfiled$public');
// });
it('should return a metadata component for a DocumentFolder', function() {
var metadataComponent = new MetadataComponent('DocumentFolder/unfiled$public');
assert.deepEqual(metadataComponent.type, 'DocumentFolder');
assert.deepEqual(metadataComponent.fullName, 'unfiled$public');
assert.deepEqual(metadataComponent.fileName, path.join('documents', 'unfiled$public'));
assert.deepEqual(metadataComponent.toString(), 'DocumentFolder/unfiled$public');
});
it('should return a metadata component for a ReportFolder', function() {
var metadataComponent = new MetadataComponent('ReportFolder/unfiled$public');
assert.deepEqual(metadataComponent.type, 'ReportFolder');
assert.deepEqual(metadataComponent.fullName, 'unfiled$public');
assert.deepEqual(metadataComponent.fileName, path.join('reports', 'unfiled$public'));
assert.deepEqual(metadataComponent.toString(), 'ReportFolder/unfiled$public');
});
it('should return a metadata component for a ReportFolder given as Report', function() {
var metadataComponent = new MetadataComponent('Report/unfiled$public');
assert.deepEqual(metadataComponent.type, 'ReportFolder');
assert.deepEqual(metadataComponent.fullName, 'unfiled$public');
assert.deepEqual(metadataComponent.fileName, path.join('reports', 'unfiled$public'));
assert.deepEqual(metadataComponent.toString(), 'ReportFolder/unfiled$public');
});
it('should return a metadata component for the CustomLabels container component', function() {
var metadataComponent = new MetadataComponent('CustomLabels/CustomLabels');
assert.deepEqual(metadataComponent.type, 'CustomLabels');
Expand Down
13 changes: 11 additions & 2 deletions test/metadata-file.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,10 @@ describe('MetadataFile', function() {
var component = new MetadataFile({
path: path.join('documents', 'MyFolder')
}).getComponent();
assert.deepEqual(component.type, 'Document');
assert.deepEqual(component.type, 'DocumentFolder');
assert.deepEqual(component.fileName, path.join('documents', 'MyFolder'));
assert.deepEqual(component.fullName, 'MyFolder');
assert.deepEqual(component.toString(), 'Document/MyFolder');
assert.deepEqual(component.toString(), 'DocumentFolder/MyFolder');
});
it('should return a component for a file in a folder', function() {
var component = new MetadataFile({
Expand All @@ -94,6 +94,15 @@ describe('MetadataFile', function() {
assert.deepEqual(component.fullName, 'MyFolder/MyFile.pdf');
assert.deepEqual(component.toString(), 'Document/MyFolder/MyFile.pdf');
});
it('should return a component for a file without extension in a folder', function() {
var component = new MetadataFile({
path: path.join('documents', 'MyFolder', 'MyFile')
}).getComponent();
assert.deepEqual(component.type, 'Document');
assert.deepEqual(component.fileName, path.join('documents', 'MyFolder', 'MyFile'));
assert.deepEqual(component.fullName, 'MyFolder/MyFile');
assert.deepEqual(component.toString(), 'Document/MyFolder/MyFile');
});
it('should return null otherwise', function() {
var component = new MetadataFile({
path: path.join('foo', 'bar')
Expand Down

0 comments on commit be7ba97

Please sign in to comment.