@google/clasp
Version:
Develop Apps Script Projects locally
76 lines (75 loc) • 3.21 kB
JavaScript
import path from 'path';
import { Command } from 'commander';
import inquirer from 'inquirer';
import { intl } from '../intl.js';
import { isInteractive, withSpinner } from './utils.js';
export const command = new Command('push')
.description('Update the remote project')
.option('-f, --force', 'Forcibly overwrites the remote manifest.')
.option('-w, --watch', 'Watches for local file changes. Pushes when a non-ignored file changes.')
.action(async function (options) {
const clasp = this.opts().clasp;
const watch = options.watch;
let force = options.force;
const onChange = async (paths) => {
const isManifestUpdated = paths.findIndex(p => path.basename(p) === 'appsscript.json') !== -1;
if (isManifestUpdated && !force) {
force = await confirmManifestUpdate();
if (!force) {
const msg = intl.formatMessage({ id: "TItFfu", defaultMessage: [{ type: 0, value: "Skipping push." }] });
console.log(msg);
return;
}
}
const spinnerMsg = intl.formatMessage({ id: "qUq++d", defaultMessage: [{ type: 0, value: "Pushing files..." }] });
const files = await withSpinner(spinnerMsg, async () => {
return await clasp.files.push();
});
const successMessage = intl.formatMessage({ id: "aD3XSt", defaultMessage: [{ type: 0, value: "Pushed " }, { type: 6, value: "count", options: { "=0": { value: [{ type: 0, value: "no files." }] }, one: { value: [{ type: 0, value: "one file." }] }, other: { value: [{ type: 7 }, { type: 0, value: " files" }] } }, offset: 0, pluralType: "cardinal" }, { type: 0, value: "." }] }, {
count: files.length,
});
console.log(successMessage);
files.forEach(f => console.log(`└─ ${f.localPath}`));
return true;
};
const pendingChanges = await clasp.files.getChangedFiles();
if (pendingChanges.length) {
const paths = pendingChanges.map(f => f.localPath);
await onChange(paths);
}
else {
const msg = intl.formatMessage({ id: "X/QgBZ", defaultMessage: [{ type: 0, value: "Script is already up to date." }] });
console.log(msg);
}
if (!watch) {
return;
}
const onReady = async () => {
const msg = intl.formatMessage({ id: "m/C0lF", defaultMessage: [{ type: 0, value: "Waiting for changes..." }] });
console.log(msg);
};
const stopWatching = await clasp.files.watchLocalFiles(onReady, async (paths) => {
if (!(await onChange(paths))) {
stopWatching();
}
});
});
/**
* Confirms that the manifest file has been updated.
* @returns {Promise<boolean>}
*/
async function confirmManifestUpdate() {
if (!isInteractive()) {
return false;
}
const prompt = intl.formatMessage({ id: "Dh7naZ", defaultMessage: [{ type: 0, value: "Manifest file has been updated. Do you want to push and overwrite?" }] });
const answer = await inquirer.prompt([
{
default: false,
message: prompt,
name: 'overwrite',
type: 'confirm',
},
]);
return answer.overwrite;
}