Skip to content

Commit

Permalink
LibraryFormatter: Add fallback to derive namespace from library.js path
Browse files Browse the repository at this point in the history
  • Loading branch information
RandomByte committed Jun 13, 2019
1 parent 2be9fd0 commit 813e5b5
Show file tree
Hide file tree
Showing 5 changed files with 265 additions and 34 deletions.
107 changes: 88 additions & 19 deletions lib/types/library/LibraryFormatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,13 @@ class LibraryFormatter extends AbstractUi5Formatter {
*/
async getNamespace() {
let libraryId;
let realNamspacePath;
let fsNamespacePath;
try {
const {content: manifest, fsPath} = await this.getManifest();
// check for a proper sap.app/id in manifest.json to determine namespace
if (manifest["sap.app"] && manifest["sap.app"].id) {
libraryId = manifest["sap.app"] && manifest["sap.app"].id;
realNamspacePath = path.dirname(fsPath);
fsNamespacePath = path.dirname(fsPath);
} else {
log.verbose(
`No "sap.app" ID configuration found in manifest.json of project ${this._project.metadata.name}`);
Expand All @@ -93,43 +93,83 @@ class LibraryFormatter extends AbstractUi5Formatter {
const {content: dotLibrary, fsPath} = await this.getDotLibrary();
if (dotLibrary && dotLibrary.library && dotLibrary.library.name) {
libraryId = dotLibrary.library.name;
realNamspacePath = path.dirname(fsPath);
fsNamespacePath = path.dirname(fsPath);
} else {
throw new Error(
`No library name found in .library of project ${this._project.metadata.name}`);
}
} catch (err) {
throw new Error(`Namespace resolution from .library failed for project ` +
log.verbose(`Namespace resolution from .library failed for project ` +
`${this._project.metadata.name}: ${err.message}`);
log.verbose("Falling back to library.js file path...");
}
}

if (this.hasMavenPlaceholder(libraryId)) {
let namespace;
if (libraryId) {
if (this.hasMavenPlaceholder(libraryId)) {
try {
libraryId = await this.resolveMavenPlaceholder(libraryId);
} catch (err) {
throw new Error(
`Failed to resolve namespace maven placeholder of project ` +
`${this._project.metadata.name}: ${err.message}`);
}
}

namespace = libraryId.replace(/\./g, "/");

const namespacePath = this.getNamespaceFromFsPath(fsNamespacePath);
if (namespacePath !== namespace) {
throw new Error(
`Detected namespace "${namespace}" does not match detected directory ` +
`structure "${namespacePath}" for project ${this._project.metadata.name}`);
}
} else {
try {
libraryId = await this.resolveMavenPlaceholder(libraryId);
const fsPath = await this.getLibraryJsPath();
namespace = this.getNamespaceFromFsPath(path.dirname(fsPath));
if (!namespace || namespace === "/") {
throw new Error(`Found library.js file in root directory. ` +
`Expected it to be in namespace directory.`);
}
} catch (err) {
throw new Error(
`Failed to resolve namespace maven placeholder of project ` +
log.verbose(`Namespace resolution from library.js file path failed for project ` +
`${this._project.metadata.name}: ${err.message}`);
}
}

const namespace = libraryId.replace(/\./g, "/");
const posixBasePath = this.getSourceBasePath(true);
// Transform path to POSIX
const posixNamespacePath = path.posix.normalize(realNamspacePath);
const basePathPrefixRegExp = new RegExp(`^${posixBasePath}`);
const namespacePath = posixNamespacePath.replace(basePathPrefixRegExp, "");
if (namespacePath !== namespace) {
throw new Error(
`Detected namespace "${namespace}" does not match detected directory ` +
`structure "${namespacePath}" for project ${this._project.metadata.name}`);
if (!namespace) {
throw new Error(`Failed to detect namespace or namespace is empty for ` +
`project ${this._project.metadata.name}. Check verbose log for details.`);
}

log.verbose(`Namespace of project ${this._project.metadata.name} is ${namespace}`);
return namespace;
}

getNamespaceFromFsPath(fsPath) {
// Transform path to POSIX
const posixFsPath = path.posix.normalize(fsPath);

// Remove base path from fsPath
const posixBasePath = this.getSourceBasePath(true);
const basePathPrefixRegExp = new RegExp(`^${posixBasePath}`);

if (!basePathPrefixRegExp.test(posixFsPath)) {
if (posixBasePath === posixFsPath + "/") {
// The given file system path does not contain a namespace path
// It is equal to the source base path
// Therefore return an empty namespace
return "";
}
throw new Error(`Given file system path ${posixFsPath} is not based on source base ` +
`path ${posixBasePath}.`);
}
const namespacePath = posixFsPath.replace(basePathPrefixRegExp, "");
return namespacePath;
}

/**
* Determines library copyright from given project configuration with fallback to .library.
*
Expand Down Expand Up @@ -168,7 +208,7 @@ class LibraryFormatter extends AbstractUi5Formatter {
followSymlinkedDirectories: false
}).then(async (manifestResources) => {
if (!manifestResources.length) {
throw new Error(`Could not find manifest.json for project ${this._project.metadata.name}`);
throw new Error(`Could not find manifest.json file for project ${this._project.metadata.name}`);
}
if (manifestResources.length > 1) {
throw new Error(`Found multiple (${manifestResources.length}) manifest.json files ` +
Expand Down Expand Up @@ -226,6 +266,35 @@ class LibraryFormatter extends AbstractUi5Formatter {
});
}

/**
* Determines the path of the library.js file
*
* @returns {Promise<string>} resolves with an a string containing the file system path
* of the library.js file
*/
async getLibraryJsPath() {
if (this._pLibraryJs) {
return this._pLibraryJs;
}
const basePath = this.getSourceBasePath();
return this._pLibraryJs = glob("**/library.js", {
cwd: basePath,
followSymlinkedDirectories: false
}).then(async (libraryJsResources) => {
if (!libraryJsResources.length) {
throw new Error(`Could not find library.js file for project ${this._project.metadata.name}`);
}
if (libraryJsResources.length > 1) {
throw new Error(`Found multiple (${libraryJsResources.length}) library.js files ` +
`for project ${this._project.metadata.name}`);
}
const fsPath = path.join(basePath, libraryJsResources[0]);

// Content is not yet relevant, so don't read it
return fsPath;
});
}

/**
* Validates the project
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*!
* UI development toolkit for HTML5 (OpenUI5)
* (c) Copyright 2009-xxx SAP SE or an SAP affiliate company.
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
*/
console.log('HelloWorld');
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*!
* UI development toolkit for HTML5 (OpenUI5)
* (c) Copyright 2009-xxx SAP SE or an SAP affiliate company.
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
*/
console.log("HelloWorld");
4 changes: 4 additions & 0 deletions test/fixtures/library.e/src/library/e/library.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/*!
* ${copyright}
*/
console.log('HelloWorld');
Loading

0 comments on commit 813e5b5

Please sign in to comment.