UNPKG

@acdf/build

Version:

Build dependency for Adobe Campaign Developer Framework projects

243 lines (207 loc) 7.36 kB
const { src, dest } = require("gulp"); const clean = require("gulp-clean"); const fs = require("fs"); const merge = require("merge-stream"); const path = require("path"); const zip = require("gulp-zip"); const resolve = (filepath) => path.resolve(process.cwd(), filepath); const CLEAN_CONFIG = { read: false, allowEmpty: true }; const CONFIG_FILE = resolve("acdf.config.json") const RELEASE_FILE = resolve("release.js") const ENV_DIR = resolve("envs"); const PACKAGE_JSON = JSON.parse(fs.readFileSync(resolve("package.json"), "utf8")); // Default configuration values const DEFAULT_CONFIG = { namespace: "acdf", }; // Filename suffixes const suffix = { ACTIVITY: ".activity", LIBRARY: ".library", TYPOLOGY: ".typology", ENVIRONMENT: ".env", CONF: ".conf" }; const CONFIG = (() => { if (fs.existsSync(CONFIG_FILE)) { const projectConfig = JSON.parse(fs.readFileSync(CONFIG_FILE)); return { ...DEFAULT_CONFIG, ...projectConfig }; } return DEFAULT_CONFIG; })(); /** * Creates the globs to find the different types of script files in a given directory * * @param {string} directoryPath * @returns a list of glob strings */ function createScriptGlobs(directoryPath) { return [suffix.ACTIVITY, suffix.LIBRARY, suffix.TYPOLOGY].map((extension) => `${directoryPath}/**/*${extension}.js`); } /** * Creates relative and absolute versions of all paths defined in the paths object. In the format: * paths.<directory>.<type>.<name> * Eg: * paths.dist.absolute.MODULE_DIR * * @param {obj} paths * @returns an object containing relative and absolute paths */ function constructPaths(paths) { return Object.keys(paths).reduce((result, folder) => { result[folder] = { relative: {}, absolute: {} }; Object.keys(paths[folder]).forEach(key => { result[folder].relative[key] = `${folder}/${paths[folder][key]}`; result[folder].absolute[key] = resolve(result[folder].relative[key]) }) return result }, {}) } // Useful paths const paths = constructPaths({ src: { CONF_DIR: "conf", SCRIPTS_DIR: "js", PACKAGES_DIR: "packages", }, dist: { CONF_DIR: "conf", COMPILED_DIR: "compiled", COMPRESSED_DIR: "compressed", MODULE_DIR: "modules", PACKAGE_DIR: "packages", STAGING_DIR: "staging", WIZARD_DIR: "wizards", } }); /** * Recursively builds a map where, for each entry, the key is the script name and the entry is the path * of the corresponding CommonJS module file. * * @param {string} filepath * @param {string} map * @returns */ function buildScriptMap(filepath, map) { const addScript = (filename, filepath) => { const key = `${CONFIG.namespace}:${filename}`; if (map[key]) { throw `Attempted to add script with identifier '${key}' but such a script already exists at '${map[key]}'. Each script must have a unique identifier.`; } else { map[key] = filepath; } }; if (!map) { map = {}; } if (!fs.existsSync(filepath)) { return map; } const filename = path.parse(filepath).base; const isScript = [suffix.LIBRARY, suffix.ACTIVITY, suffix.TYPOLOGY].some((suffix) => filename.includes(suffix)); if (fs.lstatSync(filepath).isDirectory()) { if (isScript) { addScript(filename, filepath); return map; } fs.readdirSync(filepath).forEach((child) => buildScriptMap(path.resolve(filepath, child), map)); } else if (isScript) { addScript(filename, filepath); } return map; } /** * Creates an array containing the properties exported in each environment file. * * @returns an array of environments */ function getEnvs() { if (!fs.existsSync(ENV_DIR)) { throw `Cannot build project. Please create at least one environment file in ${ENV_DIR}` } return fs // Find env files .readdirSync(ENV_DIR) .filter((envFilename) => fs.statSync(path.resolve(ENV_DIR, envFilename)).isFile() && envFilename.includes(suffix.ENVIRONMENT)) // For each env file, save a reference to the environment .reduce((envs, envFilename) => { const envName = envFilename.replace(suffix.ENVIRONMENT + ".js", ""); const env = require(path.resolve(ENV_DIR, envFilename)); // Copy the global properties into each installation object const envProperties = env.properties || {}; env.installations.forEach(installation => { installation.properties = installation.properties ? { ...envProperties, ...installation.properties } : envProperties }) envs.push({ name: envName, ...env }) return envs }, []) } /** * Finds the release with the installationName provided. Throws an error if no such release is present * in the release.js file. * * @param {string} installationName the name of the installation to create a release for * @returns the release */ function getRelease(installationName) { const installation = require(resolve("release.js")).installations.find(installation => installationName === installation.name) if (!installation) { throw `Could not find any installation by the name ${installationName} in the 'release.js' file.` } return installation; } module.exports = { // Objects paths: paths, suffix: suffix, CLEAN_CONFIG: CLEAN_CONFIG, CONFIG: CONFIG, PACKAGE_JSON: PACKAGE_JSON, REGEX_LOAD_LIBRARY: /^ *loadLibrary\(["'](.*)["']\);?$/gm, GLOB_COMPILED_SCRIPTS: createScriptGlobs(paths.dist.absolute.COMPILED_DIR), GLOB_MODULE_SCRIPTS: createScriptGlobs(paths.dist.absolute.MODULE_DIR), GLOB_STAGING_SCRIPTS: createScriptGlobs(paths.dist.absolute.STAGING_DIR), GLOB_STAGING_PACKAGES: `${paths.dist.absolute.STAGING_DIR}/packages/**/*.xml`, GLOB_PACKAGE_PACKAGES: `dist/packages/**/*.xml`, GLOB_SRC_SCRIPTS: createScriptGlobs("src"), // Functions resolve: resolve, buildScriptMap: buildScriptMap, getEnvs: getEnvs, getRelease: getRelease, cleanDest: function () { return merge(src("dist", CLEAN_CONFIG).pipe(clean()), src("docs", CLEAN_CONFIG).pipe(clean())); }, clearStage: () => { return src(paths.dist.absolute.STAGING_DIR, CLEAN_CONFIG).pipe(clean()); }, /** * Creates a deployable zip archive for each application-environment subdirectory of the directory * provided, containing files that subdirectory. * * @param {string} directory * @returns a gulp stream */ createArtifact: (directory) => { // Skip if directory does not exist if (!fs.existsSync(directory)) { return src("."); } const streams = fs .readdirSync(directory) .map(subdirectory => { return src(`${path.resolve(directory, subdirectory)}/**/*`) .pipe(zip(`${PACKAGE_JSON.name}.${subdirectory}-${PACKAGE_JSON.version}.zip`)) .pipe(dest("dist")); }) return merge(streams); }, };