diff --git a/docs/Apm-commands.md b/docs/Apm-commands.md index f20a96d9a..c46ff3481 100644 --- a/docs/Apm-commands.md +++ b/docs/Apm-commands.md @@ -53,7 +53,7 @@ Grant an address or a group of addresses the permission to create new versions i aragon apm grant [addr1 ... addrN] ``` -- `addresses`: The addresses being granted the permission to publish to the repo. +- `addresses`: The addresses being granted the permission to publish to the repo. ## aragon apm publish @@ -85,8 +85,10 @@ The command has the following parameters: - `--files`: The path to the files that will be published. Defaults to the current directory. - `--ignore`: A gitignore pattern of files to ignore. Specify multiple times to add multiple patterns. Defaults to just the `node_modules` directory. - `--publish-dir`: The path to the directory where all the files and generated artifacts will be copied to before publishing. If it is not specified, it will create a temporary directory. -- `--build`: A flag to specify whether the webapp should be built while publishing, running the script specified in `--build-script`. Defaults to `true`. +- `--build`: A flag to specify whether the webapp should be built while publishing, running the script specified in `build-script` of `package.json`. Defaults to `true`. - `--build-script`: The name of the NPM script in your app that will be used for building the webapp. +- `--prepublish`: A flag to specify whether to run a prepublish script specified in `prepublish-script` of `package.json`. Defaults to `true`. +- `--prepublish-script`: The name of the NPM script in your app that will be run before publishing the app. - `--http`: The URI for the HTTP server that will be serving your app files (e.g. localhost:1234). See [instructions on running from HTTP](#running-your-app-from-a-development-http-server) for more information. - `--http-served-from`: Path to the directory that the HTTP server exposes (e.g. ./dist). Some artifacts are generated and placed in this directory during the publishing process of your app. - `--ipfs-check`: Whether to have start IPFS if not started. Defaults to `true`. diff --git a/docs/Main-commands.md b/docs/Main-commands.md index 2b42a4649..52b154b9e 100644 --- a/docs/Main-commands.md +++ b/docs/Main-commands.md @@ -2,7 +2,7 @@ These are general purpose commands that will help you to set up and interact wit ## aragon run -The `run` command takes care of completely setting up the environment needed for running your Aragon app. +The `run` command takes care of completely setting up the environment needed for running your Aragon app. ```sh aragon run @@ -22,7 +22,10 @@ Available options to customize the `run` command: - `--template`: The name of the contract that will be deployed as the [DAO template](templates-intro.md) that will be used to create your DAO. If no Template is provided it will use a default Template that sets up the DAO with just your app (`bare-template.aragonpm.eth`). - `--template-init [argument1 ... argumentN]`: The constructor arguments for the Template contract, each separated by a space. See the [deploy command](#aragon-deploy) for more information on constructor arguments. - `--template-deploy-event`: Arguments to be passed to the template constructor. Defaults to `DeployInstance`. +- `--build`: A flag to specify whether the webapp should be built while publishing, running the script specified in `build-script` of `package.json`. Defaults to `true`. - `--build-script`: The name of the NPM script in your app that will be used for building the webapp. +- `--prepublish`: A flag to specify whether to run a prepublish script specified in `prepublish-script` of `package.json`. Defaults to `true`. +- `--prepublish-script`: The name of the NPM script in your app that will be run before publishing the app. - `--client`: Whether to start the Aragon client or not. Defaults to `true`. - `--client-version`: Version of Aragon client used to run your sandboxed app. - `--client-port`: Port being used by Aragon client. @@ -30,7 +33,6 @@ Available options to customize the `run` command: - `--app-init`: Name of the function that will be called to initialize an app. Defaults to `initialize`. - `--app-init-args`: Arguments for calling the app init function. - ### Running your app from a development HTTP server `aragon run` by default will replicate Aragon's production environment and publish your app using IPFS. However, when developing the webapp part of your Aragon app, using IPFS would require you to repeat the entire publishing process every time you make a change and want to try it out. @@ -71,7 +73,7 @@ Options: ## aragon devchain -The `devchain` command is used for starting a local development testnet with all the required components already deployed and ready to use. +The `devchain` command is used for starting a local development testnet with all the required components already deployed and ready to use. ```sh aragon devchain @@ -84,6 +86,7 @@ This snapshot contains a local instance of ENS, the first-party [Aragon apps](ht Devchains can be started on different ports and will keep their state independent from other chains. Options: + - `--reset`: Resets the devchain to the snapshot. - `--port`: The port number where the devchain will be started. - `--verbose`: Enable verbose output. Similar to ganache-cli. diff --git a/packages/aragon-cli/src/commands/apm_cmds/publish.js b/packages/aragon-cli/src/commands/apm_cmds/publish.js index 79ff21edf..255979a00 100644 --- a/packages/aragon-cli/src/commands/apm_cmds/publish.js +++ b/packages/aragon-cli/src/commands/apm_cmds/publish.js @@ -1,5 +1,4 @@ const { ensureWeb3 } = require('../../helpers/web3-fallback') -const fs = require('fs') const tmp = require('tmp-promise') const path = require('path') const { readJson, writeJson, pathExistsSync } = require('fs-extra') @@ -7,8 +6,7 @@ const APM = require('@aragon/apm') const semver = require('semver') const TaskList = require('listr') const taskInput = require('listr-input') -const { findProjectRoot, getNodePackageManager } = require('../../util') -const execa = require('execa') +const { findProjectRoot, runScriptTask } = require('../../util') const { compileContracts } = require('../../helpers/truffle-runner') const web3Utils = require('web3-utils') const deploy = require('../deploy') @@ -100,6 +98,16 @@ exports.builder = function(yargs) { description: 'The npm script that will be run when building the app', default: 'build', }) + .option('prepublish', { + description: + 'Whether publish should run prepublish script specified in --prepublish-script before publishing', + default: true, + boolean: true, + }) + .option('prepublish-script', { + description: 'The npm script that will be run before publishing the app', + default: 'prepublish', + }) .option('http', { description: 'URL for where your app is served e.g. localhost:1234', default: null, @@ -143,6 +151,8 @@ exports.task = function({ onlyContent, build, buildScript, + prepublish, + prepublishScript, http, httpServedFrom, }) { @@ -155,6 +165,11 @@ exports.task = function({ return new TaskList( [ + { + title: 'Running prepublish script', + enabled: () => prepublish, + task: async (ctx, task) => runScriptTask(task, prepublishScript), + }, { title: 'Check IPFS', task: () => startIPFS.task({ apmOptions }), @@ -270,33 +285,7 @@ exports.task = function({ { title: 'Building frontend', enabled: () => build && !http, - task: async (ctx, task) => { - if (!fs.existsSync('package.json')) { - task.skip('No package.json found') - return - } - - const packageJson = await readJson('package.json') - const scripts = packageJson.scripts || {} - if (!scripts[buildScript]) { - task.skip('Build script not defined in package.json') - return - } - - const bin = getNodePackageManager() - const buildTask = execa(bin, ['run', buildScript]) - - buildTask.stdout.on('data', log => { - if (!log) return - task.output = `npm run ${buildScript}: ${log}` - }) - - return buildTask.catch(err => { - throw new Error( - `${err.message}\n${err.stderr}\n\nFailed to build. See above output.` - ) - }) - }, + task: async (ctx, task) => runScriptTask(task, buildScript), }, { title: 'Prepare files for publishing', diff --git a/packages/aragon-cli/src/commands/run.js b/packages/aragon-cli/src/commands/run.js index fc3ca03c4..5be93fb04 100644 --- a/packages/aragon-cli/src/commands/run.js +++ b/packages/aragon-cli/src/commands/run.js @@ -74,10 +74,26 @@ exports.builder = function(yargs) { description: 'Arguments to be passed to the template constructor', default: newDAO.BARE_TEMPLATE_DEPLOY_EVENT, }) + .option('build', { + description: + 'Whether publish should try to build the app before publishing, running the script specified in --build-script', + default: true, + boolean: true, + }) .option('build-script', { description: 'The npm script that will be run when building the app', default: 'build', }) + .option('prepublish', { + description: + 'Whether publish should run prepublish script specified in --prepublish-script before publishing', + default: true, + boolean: true, + }) + .option('prepublish-script', { + description: 'The npm script that will be run before publishing the app', + default: 'prepublish', + }) .option('http', { description: 'URL for where your app is served from e.g. localhost:1234', default: null, @@ -131,7 +147,10 @@ exports.handler = function({ template, templateInit, templateDeployEvent, + build, buildScript, + prepublish, + prepublishScript, http, httpServedFrom, appInit, @@ -182,7 +201,9 @@ exports.handler = function({ network, module, buildScript, - build: true, + build, + prepublishScript, + prepublish, contract: deploy.arappContract(), web3: ctx.web3, apm: apmOptions, diff --git a/packages/aragon-cli/src/util.js b/packages/aragon-cli/src/util.js index 90591ae4a..200f6815c 100644 --- a/packages/aragon-cli/src/util.js +++ b/packages/aragon-cli/src/util.js @@ -3,6 +3,7 @@ const path = require('path') const execa = require('execa') const net = require('net') const fs = require('fs') +const { readJson } = require('fs-extra') const web3Utils = require('web3-utils') let cachedProjectRoot @@ -62,6 +63,34 @@ const installDeps = (cwd, task) => { }) } +const runScriptTask = async (task, scritpName) => { + if (!fs.existsSync('package.json')) { + task.skip('No package.json found') + return + } + + const packageJson = await readJson('package.json') + const scripts = packageJson.scripts || {} + if (!scripts[scritpName]) { + task.skip('Build script not defined in package.json') + return + } + + const bin = getNodePackageManager() + const scriptTask = execa(bin, ['run', scritpName]) + + scriptTask.stdout.on('data', log => { + if (!log) return + task.output = `npm run ${scritpName}: ${log}` + }) + + return scriptTask.catch(err => { + throw new Error( + `${err.message}\n${err.stderr}\n\nFailed to build. See above output.` + ) + }) +} + const getDependentBinary = (binaryName, projectRoot) => { if (!projectRoot) { // __dirname evaluates to the directory of this file (util.js) @@ -241,6 +270,7 @@ module.exports = { findProjectRoot, isPortTaken, installDeps, + runScriptTask, getNodePackageManager, getDependentBinary, getContract, diff --git a/packages/e2e-tests/src/cli/run.test.js.md b/packages/e2e-tests/src/cli/run.test.js.md index 6b5bf406d..ac46dfe1f 100644 --- a/packages/e2e-tests/src/cli/run.test.js.md +++ b/packages/e2e-tests/src/cli/run.test.js.md @@ -19,6 +19,9 @@ Generated by [AVA](https://ava.li). Add local files [completed]␊ Check IPFS [completed]␊ Publish app to aragonPM [started]␊ + Running prepublish script [started]␊ + Running prepublish script [skipped]␊ + → Build script not defined in package.json␊ Applying version bump (major) [started]␊ i Fetching latest version from aragonPM...␊ Applying version bump (major) [completed]␊ diff --git a/packages/e2e-tests/src/cli/run.test.js.snap b/packages/e2e-tests/src/cli/run.test.js.snap index 44eb92dd9..c174ee321 100644 Binary files a/packages/e2e-tests/src/cli/run.test.js.snap and b/packages/e2e-tests/src/cli/run.test.js.snap differ