packages/cli/src/utils/script.ts (75 lines of code) (raw):

import { PipelineMeta, ScriptConfig, ScriptType, PipcookScript } from '@pipcook/costa'; import * as constants from '../constants'; import * as fs from 'fs-extra'; import * as path from 'path'; import { parse } from 'url'; import { fetchWithCache } from './cache'; import * as queryString from 'query-string'; import { DownloadProtocol } from './'; export const downloadScript = async (scriptDir: string, scriptOrder: number, url: string, type: ScriptType, enableCache: boolean, devMode: boolean): Promise<PipcookScript> => { const urlObj = parse(url); const baseName = path.parse(urlObj.pathname).base; let localPath = path.join(scriptDir, `${scriptOrder}-${baseName}`); const query = queryString.parse(urlObj.query); // if the url is is file protocol, import it directly in development mode or copy it in normal mode. if (urlObj.protocol === DownloadProtocol.FILE || urlObj.protocol === null) { if (path.isAbsolute(urlObj.pathname)) { if (devMode) { localPath = urlObj.pathname; } else { await fs.copy(urlObj.pathname, localPath); } } else { if (devMode) { localPath = path.join(process.cwd(), urlObj.pathname); } else { await fs.copy(path.join(process.cwd(), urlObj.pathname), localPath); } } } else { if (urlObj.protocol === DownloadProtocol.HTTP || urlObj.protocol === DownloadProtocol.HTTPS) { // maybe should copy the script with COW await fetchWithCache(constants.PIPCOOK_SCRIPT_PATH, url, localPath, enableCache, true); } else { throw new TypeError(`unsupported protocol ${urlObj.protocol}`); } } return { name: baseName, path: localPath, type, query }; }; export const prepareScript = async (pipelineMeta: PipelineMeta, scriptDir: string, enableCache = true, devMode = false): Promise<ScriptConfig> => { const scripts: ScriptConfig = { datasource: null, dataflow: null, model: null }; let scriptOrder = 0; scripts.datasource = await downloadScript(scriptDir, scriptOrder, pipelineMeta.datasource, ScriptType.DataSource, enableCache, devMode); scriptOrder++; if (Array.isArray(pipelineMeta.dataflow) && pipelineMeta.dataflow.length > 0) { scripts.dataflow = []; for (const dataflowUri of pipelineMeta.dataflow) { scripts.dataflow.push(await downloadScript(scriptDir, scriptOrder, dataflowUri, ScriptType.Dataflow, enableCache, devMode)); scriptOrder++; } } scripts.model = await downloadScript(scriptDir, scriptOrder, pipelineMeta.model, ScriptType.Model, enableCache, devMode); return scripts; }; export const linkCoreToScript = async (scriptModulePath: string): Promise<void> => { const coreTargetPath = path.join(scriptModulePath, '@pipcook/core'); await fs.remove(path.join(coreTargetPath)); const coreScriptPath = require.resolve('@pipcook/core'); const coreDir = path.join('/core/'); const coreSourcePath = coreScriptPath.substr(0, coreScriptPath.lastIndexOf(coreDir) + coreDir.length - 1); await fs.mkdirp(path.join(scriptModulePath, '@pipcook')); await fs.symlink(coreSourcePath, coreTargetPath); };