export function dynamicPathParser(project: any, entityName: string, appConfig: any) { const projectRoot = project.root; const sourceDir = appConfig.root; const appRoot = path.join(sourceDir, 'app'); const cwd = process.env.PWD; const rootPath = path.join(projectRoot, appRoot); let outputPath = path.join(rootPath, entityName); if (entityName.indexOf(path.sep) === 0) { outputPath = path.join(rootPath, entityName.substr(1)); } else if (cwd.indexOf(rootPath) >= 0) { outputPath = path.join(cwd, entityName); } if (!fs.existsSync(outputPath)) { // Verify the path exists on disk. const parsedOutputPath = path.parse(outputPath); const parts = parsedOutputPath.dir.split(path.sep).slice(1); const newPath = parts.reduce((tempPath: string, part: string) => { // if (tempPath === '') { // return part; // } const withoutPlus = path.join(tempPath, part); const withPlus = path.join(tempPath, '+' + part); if (fs.existsSync(withoutPlus)) { return withoutPlus; } else if (fs.existsSync(withPlus)) { return withPlus; } // Folder not found, create it, and return it const dasherizedPart = stringUtils.dasherize(part); const dasherizedDirName = path.join(tempPath, dasherizedPart); fs.mkdirpSync(dasherizedDirName); return dasherizedDirName; }, parsedOutputPath.root); outputPath = path.join(newPath, parsedOutputPath.name); } if (outputPath.indexOf(rootPath) < 0) { throw `Invalid path: "${entityName}" cannot be ` + `above the "${appRoot}" directory`; } const adjustedPath = outputPath.replace(projectRoot, ''); const parsedPath = path.parse(adjustedPath); if (parsedPath.dir.indexOf(path.sep) === 0) { parsedPath.dir = parsedPath.dir.substr(1); } parsedPath.dir = parsedPath.dir === path.sep ? '' : parsedPath.dir; return { ...parsedPath, appRoot, sourceDir }; };
this.watcher.on('change', (file: string) => { switch (path.parse(file).ext) { case '.glsl': log.info('Recompiling ' + path.parse(file).name); this.compileShader(file, options); break; } });
export default function nodeModulesPaths( basedir: Config.Path, options: NodeModulesPathsOptions, ): Array<Config.Path> { const modules = options && options.moduleDirectory ? Array.from(options.moduleDirectory) : ['node_modules']; // ensure that `basedir` is an absolute path at this point, // resolving against the process' current working directory const basedirAbs = path.resolve(basedir); let prefix = '/'; if (/^([A-Za-z]:)/.test(basedirAbs)) { prefix = ''; } else if (/^\\\\/.test(basedirAbs)) { prefix = '\\\\'; } // The node resolution algorithm (as implemented by NodeJS and TypeScript) // traverses parents of the physical path, not the symlinked path let physicalBasedir; try { physicalBasedir = realpath(basedirAbs); } catch (err) { // realpath can throw, e.g. on mapped drives physicalBasedir = basedirAbs; } const paths: Array<Config.Path> = [physicalBasedir]; let parsed = path.parse(physicalBasedir); while (parsed.dir !== paths[paths.length - 1]) { paths.push(parsed.dir); parsed = path.parse(parsed.dir); } const dirs = paths .reduce( (dirs, aPath) => dirs.concat( modules.map(moduleDir => path.isAbsolute(moduleDir) ? aPath === basedirAbs ? moduleDir : '' : path.join(prefix, aPath, moduleDir), ), ), [] as Array<Config.Path>, ) .filter(dir => dir !== ''); return options.paths ? dirs.concat(options.paths) : dirs; }
this.watcher.on('add', (file: string) => { if (ready) { switch (path.parse(file).ext) { case '.glsl': log.info('Recompiling ' + path.parse(file).name); this.compileShader(file, options); break; } } else { shaders.push(file); } });
export async function comparePngs( sessionPath: string, baselinePath: string, diffPath: string, sessionDirectory: string, log: ToolingLog ) { log.debug(`comparePngs: ${sessionPath} vs ${baselinePath}`); const session = (await Jimp.read(sessionPath)).clone(); const baseline = (await Jimp.read(baselinePath)).clone(); if ( session.bitmap.width !== baseline.bitmap.width || session.bitmap.height !== baseline.bitmap.height ) { // eslint-disable-next-line no-console console.log( 'expected height ' + baseline.bitmap.height + ' and width ' + baseline.bitmap.width ); // eslint-disable-next-line no-console console.log('actual height ' + session.bitmap.height + ' and width ' + session.bitmap.width); const width = Math.min(session.bitmap.width, baseline.bitmap.width); const height = Math.min(session.bitmap.height, baseline.bitmap.height); session.resize(width, height); // , Jimp.HORIZONTAL_ALIGN_LEFT | Jimp.VERTICAL_ALIGN_TOP); baseline.resize(width, height); // , Jimp.HORIZONTAL_ALIGN_LEFT | Jimp.VERTICAL_ALIGN_TOP); } session.quality(60); baseline.quality(60); log.debug(`calculating diff pixels...`); // Note that this threshold value only affects color comparison from pixel to pixel. It won't have // any affect when comparing neighboring pixels - so slight shifts, font variations, or "blurry-ness" // will still show up as diffs, but upping this will not help that. Instead we keep the threshold low, and expect // some the diffCount to be lower than our own threshold value. const THRESHOLD = 0.1; const { image, percent } = Jimp.diff(session, baseline, THRESHOLD); log.debug(`percent different: ${percent}`); if (percent > 0) { image.write(diffPath); // For debugging purposes it'll help to see the resized images and how they compare. session.write(join(sessionDirectory, `${parse(sessionPath).name}-session-resized.png`)); baseline.write(join(sessionDirectory, `${parse(baselinePath).name}-baseline-resized.png`)); } return percent; }
async function compile(shader: any, index: number) { let parsed = path.parse(shader); log.info('Compiling shader ' + (index + 1) + ' of ' + shaders.length + ' (' + parsed.base + ').'); let compiledShader: CompiledShader = null; try { compiledShader = await self.compileShader(shader, options, recompileAll); } catch (error) { log.error('Compiling shader ' + (index + 1) + ' of ' + shaders.length + ' (' + parsed.base + ') failed:'); log.error(error); return Promise.reject(error); } if (compiledShader === null) { compiledShader = new CompiledShader(); compiledShader.noembed = options.noembed; // mark variables as invalid, so they are loaded from previous compilation compiledShader.files = null; compiledShader.inputs = null; compiledShader.outputs = null; compiledShader.uniforms = null; compiledShader.types = null; } if (compiledShader.files != null && compiledShader.files.length === 0) { // TODO: Remove when krafix has been recompiled everywhere compiledShader.files.push(parsed.name + '.' + self.type); } compiledShader.name = AssetConverter.createExportInfo(parsed, false, options, self.exporter.options.from).name; compiledShaders.push(compiledShader); ++index; return Promise.resolve(); }
this.watcher.on('ready', async () => { ready = true; let compiledShaders: CompiledShader[] = []; let index = 0; for (let shader of shaders) { let parsed = path.parse(shader); log.info('Compiling shader ' + (index + 1) + ' of ' + shaders.length + ' (' + parsed.base + ').'); let compiledShader: CompiledShader = null; try { compiledShader = await this.compileShader(shader, options); } catch (error) { reject(error); return; } if (compiledShader === null) { compiledShader = new CompiledShader(); // mark variables as invalid, so they are loaded from previous compilation compiledShader.inputs = null; compiledShader.outputs = null; compiledShader.uniforms = null; } if (compiledShader.files.length === 0) { // TODO: Remove when krafix has been recompiled everywhere compiledShader.files.push(parsed.name + '.' + this.type); } compiledShader.name = AssetConverter.createExportInfo(parsed, false, options, this.exporter.options.from).name; compiledShaders.push(compiledShader); ++index; } resolve(compiledShaders); return; });
export function copyGoldImagesToDatabase(name: string, resourceState: string, fileBucket: any) { // The name should always look like "goldens/xxx.png" let parsedPath = path.parse(name); // Get the file name. if (parsedPath.root != '' || parsedPath.dir != 'goldens' || parsedPath.ext.toLowerCase() != '.png') { return; } let filenameKey = path.basename(parsedPath.name, '.screenshot'); let databaseRef = firebaseAdmin.database().ref(FIREBASE_DATA_GOLDENS).child(filenameKey); // When a gold image is deleted, also delete the corresponding record in the firebase database. if (resourceState === 'not_exists') { return databaseRef.set(null); } let tempFilePath = `/tmp/${parsedPath.base}`; let bucket = gcs.bucket(fileBucket); // Download file from bucket. return bucket.file(name).download({destination: tempFilePath}) .then(() => { let data = readFileSync(tempFilePath); return databaseRef.set(data); }).catch((error: any) => console.error(`${filenameKey} ${error}`)); }
return function (path: string) { const nmIndex = path.lastIndexOf('node_modules'); if (nmIndex !== -1) { const subPath = path.substr(nmIndex + 'node_modules'.length).replace(/\\/g, '/'); const shouldResolve = explicitResolve.length && explicitResolve.some(packageName => subPath.indexOf(packageName) !== -1); const pathParts = subPath.split(/[/\-_]/); if (!shouldResolve && pathParts.every(p => nsPackageFilters.every(f => f !== p))) { return path; } } const { dir, name, ext } = parse(path); if (platformSpecificExt.indexOf(ext) === -1) { return path; } for (const platform of platforms) { const platformFileName = `${name}.${platform}${ext}`; const platformPath = toSystemPath(join(dir, platformFileName)); try { if (statSync(platformPath)) { return platformPath; } } catch (_e) { // continue checking the other platforms } } return path; }
export function trueCasePathSync(fsPath: string): string { // Normalize the path so as to resolve . and .. components. // !! As of Node v4.1.1, a path starting with ../ is NOT resolved relative // !! to the current dir, and glob.sync() below then fails. // !! When in doubt, resolve with fs.realPathSync() *beforehand*. let fsPathNormalized = path.normalize(fsPath); // OSX: HFS+ stores filenames in NFD (decomposed normal form) Unicode format, // so we must ensure that the input path is in that format first. if (process.platform === "darwin") fsPathNormalized = fsPathNormalized.normalize("NFD"); // !! Windows: Curiously, the drive component mustn't be part of a glob, // !! otherwise glob.sync() will invariably match nothing. // !! Thus, we remove the drive component and instead pass it in as the 'cwd' // !! (working dir.) property below. const pathRoot = path.parse(fsPathNormalized).root; const noDrivePath = fsPathNormalized.slice(Math.max(pathRoot.length - 1, 0)); // Perform case-insensitive globbing (on Windows, relative to the drive / // network share) and return the 1st match, if any. // Fortunately, glob() with nocase case-corrects the input even if it is // a *literal* path. return glob.sync(noDrivePath, { nocase: true, cwd: pathRoot })[0]; }