UNPKG

@ui5/project

Version:
360 lines (337 loc) 14.4 kB
import { createReaderCollection, createReaderCollectionPrioritized, createResource, createFilterReader, createLinkReader, createFlatReader } from "@ui5/fs/resourceFactory"; /** * Convenience functions for UI5 tasks. * An instance of this class is passed to every standard UI5 task that requires it. * * Custom tasks that define a specification version >= 2.2 will receive an interface * to an instance of this class when called. * The set of available functions on that interface depends on the specification * version defined for the extension. * * @public * @class * @alias @ui5/project/build/helpers/TaskUtil * @hideconstructor */ class TaskUtil { /** * Standard Build Tags. See UI5 Tooling * [RFC 0008]{@link https://github.com/SAP/ui5-tooling/blob/main/rfcs/0008-resource-tagging-during-build.md} * for details. * * @public * @typedef {object} @ui5/project/build/helpers/TaskUtil~StandardBuildTags * @property {string} OmitFromBuildResult * Setting this tag to true will prevent the resource from being written to the build target directory * @property {string} IsBundle * This tag identifies resources that contain (i.e. bundle) multiple other resources * @property {string} IsDebugVariant * This tag identifies resources that are a debug variant (typically named with a "-dbg" suffix) * of another resource. This tag is part of the build manifest. * @property {string} HasDebugVariant * This tag identifies resources for which a debug variant has been created. * This tag is part of the build manifest. */ /** * Since <code>@ui5/project/build/helpers/ProjectBuildContext</code> is a private class, TaskUtil must not be * instantiated by modules other than @ui5/project itself. * * @param {object} parameters * @param {@ui5/project/build/helpers/ProjectBuildContext} parameters.projectBuildContext ProjectBuildContext * @public */ constructor({projectBuildContext}) { this._projectBuildContext = projectBuildContext; /** * @member {@ui5/project/build/helpers/TaskUtil~StandardBuildTags} * @public */ this.STANDARD_TAGS = Object.freeze({ // "Project" tags: // Will be stored on project instance and are hence part of the build manifest IsDebugVariant: "ui5:IsDebugVariant", HasDebugVariant: "ui5:HasDebugVariant", // "Build" tags: // Will be stored on the project build context // They are only available to the build tasks of a single project OmitFromBuildResult: "ui5:OmitFromBuildResult", IsBundle: "ui5:IsBundle" }); } /** * Stores a tag with value for a given resource's path. Note that the tag is independent of the supplied * resource instance. For two resource instances with the same path, the same tag value is returned. * If the path of a resource is changed, any tag information previously stored for that resource is lost. * * </br></br> * This method is only available to custom task extensions defining * <b>Specification Version 2.2 and above</b>. * * @param {@ui5/fs/Resource} resource Resource-instance the tag should be stored for * @param {string} tag Name of the tag. Currently only the * [STANDARD_TAGS]{@link @ui5/project/build/helpers/TaskUtil#STANDARD_TAGS} are allowed * @param {string|boolean|integer} [value=true] Tag value. Must be primitive * @public */ setTag(resource, tag, value) { if (typeof resource === "string") { throw new Error("Deprecated parameter: " + "Since UI5 Tooling 3.0, #setTag requires a resource instance. Strings are no longer accepted"); } const collection = this._projectBuildContext.getResourceTagCollection(resource, tag); return collection.setTag(resource, tag, value); } /** * Retrieves the value for a stored tag. If no value is stored, <code>undefined</code> is returned. * * </br></br> * This method is only available to custom task extensions defining * <b>Specification Version 2.2 and above</b>. * * @param {@ui5/fs/Resource} resource Resource-instance the tag should be retrieved for * @param {string} tag Name of the tag * @returns {string|boolean|integer|undefined} Tag value for the given resource. * <code>undefined</code> if no value is available * @public */ getTag(resource, tag) { if (typeof resource === "string") { throw new Error("Deprecated parameter: " + "Since UI5 Tooling 3.0, #getTag requires a resource instance. Strings are no longer accepted"); } const collection = this._projectBuildContext.getResourceTagCollection(resource, tag); return collection.getTag(resource, tag); } /** * Clears the value of a tag stored for the given resource's path. * It's like the tag was never set for that resource. * * </br></br> * This method is only available to custom task extensions defining * <b>Specification Version 2.2 and above</b>. * * @param {@ui5/fs/Resource} resource Resource-instance the tag should be cleared for * @param {string} tag Tag * @public */ clearTag(resource, tag) { if (typeof resource === "string") { throw new Error("Deprecated parameter: " + "Since UI5 Tooling 3.0, #clearTag requires a resource instance. Strings are no longer accepted"); } const collection = this._projectBuildContext.getResourceTagCollection(resource, tag); return collection.clearTag(resource, tag); } /** * Check whether the project currently being built is the root project. * * </br></br> * This method is only available to custom task extensions defining * <b>Specification Version 2.2 and above</b>. * * @returns {boolean} <code>true</code> if the currently built project is the root project * @public */ isRootProject() { return this._projectBuildContext.isRootProject(); } /** * Retrieves a build option defined by its <code>key</code. * If no option with the given <code>key</code> is stored, <code>undefined</code> is returned. * * @param {string} key The option key * @returns {any|undefined} The build option (or undefined) * @private */ getBuildOption(key) { return this._projectBuildContext.getOption(key); } /** * Callback that is executed once the build has finished * * @public * @callback @ui5/project/build/helpers/TaskUtil~cleanupTaskCallback * @param {boolean} force Whether the cleanup callback should * gracefully wait for certain jobs to be completed (<code>false</code>) * or enforce immediate termination (<code>true</code>) */ /** * Register a function that must be executed once the build is finished. This can be used to, for example, * clean up files temporarily created on the file system. If the callback returns a Promise, it will be waited for. * It will also be executed in cases where the build has failed or has been aborted. * * </br></br> * This method is only available to custom task extensions defining * <b>Specification Version 2.2 and above</b>. * * @param {@ui5/project/build/helpers/TaskUtil~cleanupTaskCallback} callback Callback to * register; it will be waited for if it returns a Promise * @public */ registerCleanupTask(callback) { return this._projectBuildContext.registerCleanupTask(callback); } /** * Specification Version-dependent [Project]{@link @ui5/project/specifications/Project} interface. * For details on individual functions, see [Project]{@link @ui5/project/specifications/Project} * * @public * @typedef {object} @ui5/project/build/helpers/TaskUtil~ProjectInterface * @property {Function} getType Get the project type * @property {Function} getName Get the project name * @property {Function} getVersion Get the project version * @property {Function} getNamespace Get the project namespace * @property {Function} getRootReader Get the project rootReader * @property {Function} getReader Get the project reader * @property {Function} getRootPath Get the local File System path of the project's root directory * @property {Function} getSourcePath Get the local File System path of the project's source directory * @property {Function} getCustomConfiguration Get the project Custom Configuration * @property {Function} isFrameworkProject Check whether the project is a UI5-Framework project * @property {Function} getFrameworkName Get the project's framework name configuration * @property {Function} getFrameworkVersion Get the project's framework version configuration * @property {Function} getFrameworkDependencies Get the project's framework dependencies configuration */ /** * Retrieve a single project from the dependency graph * * </br></br> * This method is only available to custom task extensions defining * <b>Specification Version 3.0 and above</b>. * * @param {string|@ui5/fs/Resource} [projectNameOrResource] * Name of the project to retrieve or a Resource instance to retrieve the associated project for. * Defaults to the name of the project currently being built * @returns {@ui5/project/build/helpers/TaskUtil~ProjectInterface|undefined} * Specification Version-dependent interface to the Project instance or <code>undefined</code> * if the project name is unknown or the provided resource is not associated with any project. * @public */ getProject(projectNameOrResource) { if (projectNameOrResource) { if (typeof projectNameOrResource === "string" || projectNameOrResource instanceof String) { // A project name has been provided return this._projectBuildContext.getProject(projectNameOrResource); } else { // A Resource instance has been provided return projectNameOrResource.getProject(); } } // No parameter has been provided, default to the project currently being built. return this._projectBuildContext.getProject(); } /** * Retrieve a list of direct dependencies of a given project from the dependency graph. * Note that this list does not include transitive dependencies. * * </br></br> * This method is only available to custom task extensions defining * <b>Specification Version 3.0 and above</b>. * * @param {string} [projectName] Name of the project to retrieve. Defaults to the project currently being built * @returns {string[]} Names of all direct dependencies * @throws {Error} If the requested project is unknown to the graph * @public */ getDependencies(projectName) { return this._projectBuildContext.getDependencies(projectName); } /** * Specification Version-dependent set of [@ui5/fs/resourceFactory]{@link @ui5/fs/resourceFactory} * functions provided to tasks. * For details on individual functions, see [@ui5/fs/resourceFactory]{@link @ui5/fs/resourceFactory} * * @public * @typedef {object} @ui5/project/build/helpers/TaskUtil~resourceFactory * @property {Function} createResource Creates a [Resource]{@link @ui5/fs/Resource}. * Accepts the same parameters as the [Resource]{@link @ui5/fs/Resource} constructor. * @property {Function} createReaderCollection Creates a reader collection: * [ReaderCollection]{@link @ui5/fs/ReaderCollection} * @property {Function} createReaderCollectionPrioritized Creates a prioritized reader collection: * [ReaderCollectionPrioritized]{@link @ui5/fs/ReaderCollectionPrioritized} * @property {Function} createFilterReader * Create a [Filter-Reader]{@link @ui5/fs/readers/Filter} with the given reader. * @property {Function} createLinkReader * Create a [Link-Reader]{@link @ui5/fs/readers/Filter} with the given reader. * @property {Function} createFlatReader Create a [Link-Reader]{@link @ui5/fs/readers/Link} * where all requests are prefixed with <code>/resources/<namespace></code>. */ /** * Provides limited access to [@ui5/fs/resourceFactory]{@link @ui5/fs/resourceFactory} functions * * </br></br> * This attribute is only available to custom task extensions defining * <b>Specification Version 3.0 and above</b>. * * @type {@ui5/project/build/helpers/TaskUtil~resourceFactory} * @public */ resourceFactory = { createResource, createReaderCollection, createReaderCollectionPrioritized, createFilterReader, createLinkReader, createFlatReader, }; /** * Get an interface to an instance of this class that only provides those functions * that are supported by the given custom task extension specification version. * * @param {@ui5/project/specifications/SpecificationVersion} specVersion * SpecVersionComparator instance of the custom task * @returns {object} An object with bound instance methods supported by the given specification version */ getInterface(specVersion) { if (specVersion.lte("2.1")) { // Tasks defining specVersion <= 2.1 do not have access to any TaskUtil APIs return undefined; } const baseInterface = { STANDARD_TAGS: this.STANDARD_TAGS, }; bindFunctions(this, baseInterface, [ "setTag", "clearTag", "getTag", "isRootProject", "registerCleanupTask" ]); if (specVersion.gte("3.0")) { // getProject function, returning an interfaced project instance baseInterface.getProject = (projectName) => { const project = this.getProject(projectName); const baseProjectInterface = {}; bindFunctions(project, baseProjectInterface, [ "getType", "getName", "getVersion", "getNamespace", "getRootReader", "getReader", "getRootPath", "getSourcePath", "getCustomConfiguration", "isFrameworkProject", "getFrameworkName", "getFrameworkVersion", "getFrameworkDependencies" ]); return baseProjectInterface; }; // getDependencies function, returning an array of project names baseInterface.getDependencies = (projectName) => { return this.getDependencies(projectName); }; baseInterface.resourceFactory = Object.create(null); [ // Once new functions get added, extract this array into a variable // and enhance based on spec version once new functions get added "createResource", "createReaderCollection", "createReaderCollectionPrioritized", "createFilterReader", "createLinkReader", "createFlatReader", ].forEach((factoryFunction) => { baseInterface.resourceFactory[factoryFunction] = this.resourceFactory[factoryFunction]; }); } return baseInterface; } } function bindFunctions(sourceObject, targetObject, funcNames) { funcNames.forEach((funcName) => { targetObject[funcName] = sourceObject[funcName].bind(sourceObject); }); } export default TaskUtil;