UNPKG

@google/dscc-gen

Version:

Create component & connector projects with sane defaults.

157 lines (156 loc) 7.26 kB
"use strict"; /** * @license * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); const chalk_1 = require("chalk"); const path = require("path"); const terminal_link_1 = require("terminal-link"); const files = require("../files"); const index_1 = require("../index"); const util = require("../util"); const appsscript = require("./appsscript"); const validation = require("./validation"); const clear = require('clear'); const green = chalk_1.default.bold.rgb(15, 157, 88); const blue = chalk_1.default.bold.rgb(66, 133, 244); const yellow = chalk_1.default.bold.rgb(244, 160, 0); const red = chalk_1.default.bold.rgb(219, 68, 55); const getTemplates = (answers) => { return [ { match: /{{MANIFEST_NAME}}/, replace: answers.projectName }, { match: /{{MANIFEST_LOGO_URL}}/, replace: answers.manifestLogoUrl }, { match: /{{MANIFEST_COMPANY}}/, replace: answers.manifestCompany }, { match: /{{MANIFEST_COMPANY_URL}}/, replace: answers.manifestCompanyUrl }, { match: /{{MANIFEST_ADDON_URL}}/, replace: answers.manifestAddonUrl }, { match: /{{MANIFEST_SUPPORT_URL}}/, replace: answers.manifestSupportUrl }, { match: /{{MANIFEST_DESCRIPTION}}/, replace: answers.manifestDescription }, { match: /{{MANIFEST_SOURCES}}/, replace: `[${answers .manifestSources.split(',') .map((a) => `"${a}"`) .join(',')}]`, }, ]; }; const ensureAuthenticated = async (execOptions) => { const authenticated = util.spinnify('Ensuring clasp is authenticated...', async () => { return validation.claspAuthenticated(); }); if (!authenticated) { const infoText = yellow('Clasp must be globally authenticated for dscc-gen.'); const claspLogin = green('npx @google/clasp login'); console.log(`${infoText}\nrunning ${claspLogin} ...\n`); await util.exec('npx @google/clasp login', execOptions, true); } }; const installDependencies = async (projectPath, answers) => { return util.spinnify('Installing project dependencies...', async () => util.npmInstall(projectPath, answers)); }; const createAppsScriptProject = async (projectPath, projectName, execOptions) => { return util.spinnify('Creating Apps Script project...', async () => { await appsscript.create(projectPath, projectName); // Since clasp creating a new project overwrites the manifest, we want to // copy the template manifest over the one generated by clasp. await util.exec('mv temp/appsscript.json src/appsscript.json', execOptions); await appsscript.push(projectPath); }); }; const cloneAppsScriptProject = async (projectPath, scriptId) => { // We don't need the template source files since we want the Apps Scripts project's return util.spinnify('Cloning existing project...', async () => { await util.exec('rm -rf src', { cwd: projectPath }); await appsscript.clone(projectPath, scriptId, 'src'); }); }; const manageDeployments = async (projectPath, answers) => { let productionDeploymentId; if (answers.scriptId !== undefined) { // See if there is already a 'Production' deployment. productionDeploymentId = await util.spinnify('Checking for a production deployment', async () => { return appsscript.getDeploymentIdByName(projectPath, 'Production'); }); } if (productionDeploymentId === undefined) { productionDeploymentId = await util.spinnify('Creating a production deployment', async () => { return await appsscript.deploy(projectPath, 'Production'); }); } const latestDeploymentId = await util.spinnify('Getting the latest deploymentId', async () => { return await appsscript.getDeploymentIdByName(projectPath, '@HEAD'); }); if (latestDeploymentId === undefined) { throw new Error(`Wasn't able to get the latest deploymentId. This is probably a bug with dscc-gen.`); } return util.spinnify('Updating templates with your values...', async () => { return files.fixTemplates(projectPath, [ { match: /{{PRODUCTION_DEPLOYMENT_ID}}/, replace: productionDeploymentId }, { match: /{{LATEST_DEPLOYMENT_ID}}/, replace: latestDeploymentId }, ]); }); }; exports.createFromTemplate = async (answers) => { clear(); const { projectName, basePath } = answers; const templatePath = path.join(basePath, 'templates', answers.projectChoice); const projectPath = path.join(index_1.PWD, projectName); await files.createAndCopyFiles(projectPath, templatePath, projectName); await util.spinnify('Updating templates with your values...', async () => { await files.fixTemplates(projectPath, getTemplates(answers)); }); const execOptions = { cwd: projectPath }; await installDependencies(projectPath, answers); await ensureAuthenticated(execOptions); if (answers.scriptId !== undefined) { await cloneAppsScriptProject(projectPath, answers.scriptId); } else { await createAppsScriptProject(projectPath, projectName, execOptions); } await manageDeployments(projectPath, answers); // Remove temp directory. await util.exec('rm -rf temp', execOptions); const connectorOverview = blue(terminal_link_1.default('connector overview', 'https://developers.google.com/datastudio/connector/')); const styledProjectName = green(projectName); const cdDirection = yellow(`cd ${projectName}`); const runCmd = answers.yarn ? 'yarn' : 'npm run'; const open = red(`${runCmd} open`); const push = blue(`${runCmd} push`); const watch = green(`${runCmd} watch`); const prettier = yellow(`${runCmd} prettier`); const tryLatest = red(`${runCmd} try_latest`); const tryProduction = blue(`${runCmd} try_production`); const updateProduction = green(`${runCmd} update_production`); console.log(`\ Created a new community connector: ${styledProjectName}\n\ \n\ If this is your first connector, see ${connectorOverview}\n\ \n\ ${cdDirection} to start working on your connector\n\ \n\ Scripts are provided to simplify development:\n\ \n\ ${open} - open your project in Apps Script.\n\ ${push} - push your local changes to Apps Script.\n\ ${watch} - watches for local changes & pushes them to Apps Script.\n\ ${prettier} - formats your code using community standards.\n\ ${tryLatest} - opens the deployment with your latest code.\n\ ${tryProduction} - opens your production deployment.\n\ ${updateProduction} - updates your production deployment to use the latest code.\n\ `); return 0; };