UNPKG

@electron-forge/core

Version:

A complete tool for building modern Electron applications

146 lines (134 loc) 4.82 kB
import path from 'path'; import { safeYarnOrNpm } from '@electron-forge/core-utils'; import { ForgeTemplate } from '@electron-forge/shared-types'; import debug from 'debug'; import { Listr } from 'listr2'; import semver from 'semver'; import installDepList, { DepType, DepVersionRestriction } from '../util/install-dependencies'; import { readRawPackageJson } from '../util/read-package-json'; import { findTemplate } from './init-scripts/find-template'; import { initDirectory } from './init-scripts/init-directory'; import { initGit } from './init-scripts/init-git'; import { initNPM } from './init-scripts/init-npm'; const d = debug('electron-forge:init'); export interface InitOptions { /** * The path to the app to be initialized */ dir?: string; /** * Whether to use sensible defaults or prompt the user visually */ interactive?: boolean; /** * Whether to copy template CI files */ copyCIFiles?: boolean; /** * Whether to overwrite an existing directory */ force?: boolean; /** * The custom template to use. If left empty, the default template is used */ template?: string; } async function validateTemplate(template: string, templateModule: ForgeTemplate): Promise<void> { if (!templateModule.requiredForgeVersion) { throw new Error(`Cannot use a template (${template}) with this version of Electron Forge, as it does not specify its required Forge version.`); } const forgeVersion = (await readRawPackageJson(path.join(__dirname, '..', '..'))).version; if (!semver.satisfies(forgeVersion, templateModule.requiredForgeVersion)) { throw new Error( `Template (${template}) is not compatible with this version of Electron Forge (${forgeVersion}), it requires ${templateModule.requiredForgeVersion}` ); } } export default async ({ dir = process.cwd(), interactive = false, copyCIFiles = false, force = false, template = 'base' }: InitOptions): Promise<void> => { d(`Initializing in: ${dir}`); const packageManager = safeYarnOrNpm(); const runner = new Listr<{ templateModule: ForgeTemplate; }>( [ { title: `Locating custom template: "${template}"`, task: async (ctx) => { ctx.templateModule = await findTemplate(dir, template); }, }, { title: 'Initializing directory', task: async (_, task) => { await initDirectory(dir, task, force); await initGit(dir); }, options: { persistentOutput: true, }, }, { title: 'Preparing template', task: async ({ templateModule }) => { await validateTemplate(template, templateModule); }, }, { title: 'Initializing template', task: async ({ templateModule }, task) => { if (typeof templateModule.initializeTemplate === 'function') { const tasks = await templateModule.initializeTemplate(dir, { copyCIFiles }); if (tasks) { return task.newListr(tasks, { concurrent: false }); } } }, }, { title: 'Installing template dependencies', task: async ({ templateModule }, task) => { return task.newListr( [ { title: 'Installing production dependencies', task: async (_, task) => { d('installing dependencies'); if (templateModule.dependencies?.length) { task.output = `${packageManager} install ${templateModule.dependencies.join(' ')}`; } return await installDepList(dir, templateModule.dependencies || [], DepType.PROD, DepVersionRestriction.RANGE); }, }, { title: 'Installing development dependencies', task: async (_, task) => { d('installing devDependencies'); if (templateModule.devDependencies?.length) { task.output = `${packageManager} install --dev ${templateModule.devDependencies.join(' ')}`; } await installDepList(dir, templateModule.devDependencies || [], DepType.DEV); }, }, { title: 'Finalizing dependencies', task: async (_, task) => { await initNPM(dir, task); }, }, ], { concurrent: false, exitOnError: false, } ); }, }, ], { concurrent: false, rendererSilent: !interactive, rendererFallback: Boolean(process.env.DEBUG && process.env.DEBUG.includes('electron-forge')), } ); await runner.run(); };