Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New commands (dao new, dao install, dao upgrade, aragon ipfs) + aragon run refactor #94

Merged
merged 14 commits into from
May 21, 2018
24 changes: 17 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
},
"homepage": "https://github.com/aragon/aragon-dev-cli#readme",
"dependencies": {
"@aragon/apm": "^1.0.0",
"@aragon/apm": "^1.1.1",
"@aragon/apps-finance": "^1.0.1",
"@aragon/apps-token-manager": "^1.0.0",
"@aragon/apps-vault": "^2.0.1",
Expand All @@ -44,6 +44,7 @@
"@aragon/os": "3.1.4",
"@aragon/templates-beta": "^1.1.3",
"@aragon/wrapper": "^2.0.0-beta.33",
"bignumber.js": "^7.1.0",
"chalk": "^2.1.0",
"cli-table": "^0.3.1",
"colors": "^1.2.4",
Expand Down
35 changes: 18 additions & 17 deletions src/commands/apm_cmds/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const execa = require('execa')
const { compileContracts } = require('../../helpers/truffle-runner')
const web3Utils = require('web3-utils')
const deploy = require('../deploy')
const startIPFS = require('../ipfs')

exports.command = 'publish [contract]'

Expand Down Expand Up @@ -58,7 +59,6 @@ async function generateApplicationArtifact (web3, cwd, outputPath, module, contr

// Set `appId`
artifact.appId = namehash.hash(artifact.appName)
delete artifact.appName

// Set ABI
const contractInterface = await readJson(contractInterfacePath)
Expand Down Expand Up @@ -152,6 +152,8 @@ exports.task = function ({
ignore,
automaticallyBump
}) {
apmOptions.ensRegistryAddress = apmOptions['ens-registry']
const apm = APM(web3, apmOptions)
return new TaskList([
{
title: 'Preflight checks for publishing to APM',
Expand All @@ -176,9 +178,9 @@ exports.task = function ({
task: async (ctx) => {
let repo = { version: '0.0.0' }
try {
repo = await ctx.apm.getLatestVersion(module.appName)
repo = await apm.getLatestVersion(module.appName)
} catch (e) {
if (ctx.apm.validInitialVersions.indexOf(ctx.version) == -1) {
if (apm.validInitialVersions.indexOf(ctx.version) == -1) {
throw new Error('Invalid initial version, it can only be 0.0.1, 0.1.0 or 1.0.0. Check your arapp file.')
} else {
ctx.isMajor = true // consider first version as major
Expand All @@ -190,7 +192,7 @@ exports.task = function ({
throw new Error('Version is already published, please bump it using `aragon apm version [major, minor, patch]`')
}

const isValid = await ctx.apm.isValidBump(module.appName, repo.version, ctx.version)
const isValid = await apm.isValidBump(module.appName, repo.version, ctx.version)

if (!isValid) {
throw new Error('Version bump is not valid, you have to respect APM bumps policy. Check version upgrade rules in documentation https://hack.aragon.one/docs/aragonos-ref.html#631-version-upgrade-rules')
Expand All @@ -208,13 +210,11 @@ exports.task = function ({
enabled: () => web3Utils.isAddress(contract)
},
{
title: 'Deploying contract',
title: 'Deploy contract',
task: async (ctx) => {
const deployTaskParams = { contract: deploy.arappContract(), reporter, network, cwd, web3 }

const { deployedContract } = await deploy.task(deployTaskParams)

ctx.contract = deployedContract
return await deploy.task(deployTaskParams)
},
enabled: ctx => (contract && !web3Utils.isAddress(contract)) || (!contract && ctx.isMajor && !reuse) || automaticallyBump
},
Expand All @@ -223,7 +223,7 @@ exports.task = function ({
task: async (ctx, task) => {
let nextMajorVersion
try {
const { version } = await ctx.apm.getLatestVersion(module.appName)
const { version } = await apm.getLatestVersion(module.appName)
nextMajorVersion = parseInt(version.split('.')[0]) + 1
} catch (_) {
ctx.version = '1.0.0'
Expand All @@ -246,7 +246,7 @@ exports.task = function ({
task.output = 'No contract address provided, using previous one'

try {
const { contract } = ctx.apm.getLatestVersion(module.appName)
const { contract } = apm.getLatestVersion(module.appName)
ctx.contract = contract
return `Using ${contract}`
} catch (err) {
Expand Down Expand Up @@ -290,6 +290,10 @@ exports.task = function ({
})
}
},
{
title: 'Check IPFS',
task: () => startIPFS.task({ apmOptions }),
},
{
title: 'Prepare files for publishing',
task: async (ctx, task) => {
Expand All @@ -316,13 +320,14 @@ exports.task = function ({
const from = accounts[0]

try {
const transaction = await ctx.apm.publishVersion(
const transaction = await apm.publishVersion(
from,
module.appName,
ctx.version,
provider,
ctx.pathToPublish,
ctx.contract
ctx.contract,
from
)
// Fix because APM.js gas comes with decimals and from doesn't work
transaction.from = from
Expand All @@ -346,11 +351,7 @@ exports.handler = async (args) => {

const web3 = await ensureWeb3(network)

apmOptions.ensRegistryAddress = apmOptions['ens-registry']

const apm = APM(web3, apmOptions)

return exports.task({ ...args, web3 }).run({ web3, apm })
return exports.task({ ...args, web3 }).run({ web3 })
.then(() => { process.exit() })
.catch(() => { process.exit() })
}
18 changes: 12 additions & 6 deletions src/commands/dao_cmds/apps.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const printContent = (content) => {
return `${content.provider}:${content.location}`.slice(0,25) + '...'
}

exports.handler = async function ({ reporter, dao, network, apm }) {
exports.handler = async function ({ reporter, dao, network, apm: apmOptions }) {
knownApps = listApps()
const web3 = await ensureWeb3(network)

Expand All @@ -41,7 +41,7 @@ exports.handler = async function ({ reporter, dao, network, apm }) {
task.output = `Fetching apps for ${dao}...`

return new Promise((resolve, reject) => {
initAragonJS(dao, apm['ens-registry'], {
initAragonJS(dao, apmOptions['ens-registry'], {
provider: web3.currentProvider,
onApps: apps => {
ctx.apps = apps
Expand All @@ -62,17 +62,23 @@ exports.handler = async function ({ reporter, dao, network, apm }) {
return tasks.run()
.then((ctx) => {
reporter.success(`Successfully fetched DAO apps for ${ctx.daoAddress}`)

const appsContent = ctx.apps.map(
({ appId, proxyAddress, codeAddress, content }) =>
([ printAppName(appId), proxyAddress, printContent(content)])
({ appId, proxyAddress, codeAddress, content, appName, version }) =>
([ appName ? `${appName}@v${version}`: printAppName(appId), proxyAddress, printContent(content)])
)

// filter registry name to make it shorter
// TODO: Add flag to turn off
const filteredContent = appsContent.map((row) => {
row[0] = row[0].replace('.aragonpm.eth', '')
return row
})

const table = new Table({
head: ['App', 'Proxy address', 'Content'].map(x => x.white),
})

appsContent.forEach(row => table.push(row))
filteredContent.forEach(row => table.push(row))

console.log(table.toString())
process.exit() // force exit, as aragonjs hangs
Expand Down
110 changes: 110 additions & 0 deletions src/commands/dao_cmds/install.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
const TaskList = require('listr')
const Web3 = require('web3')
const daoArg = require('./utils/daoArg')
import initAragonJS from './utils/aragonjs-wrapper'
const { ensureWeb3 } = require('../../helpers/web3-fallback')
const path = require('path')
const APM = require('@aragon/apm')
const defaultAPMName = require('../../helpers/default-apm')
const chalk = require('chalk')
const getRepoTask = require('./utils/getRepoTask')
const upgrade = require('./upgrade')
const { getContract, ANY_ENTITY } = require('../../util')

const setPermissions = async (web3, sender, aclAddress, permissions) => {
const acl = new web3.eth.Contract(
getContract('@aragon/os', 'ACL').abi,
aclAddress
)
return Promise.all(
permissions.map(([who, where, what]) =>
acl.methods.createPermission(who, where, what, who).send({
from: sender,
gasLimit: 1e6
})
)
)
}

exports.command = 'install <dao> <apmRepo> [apmRepoVersion]'

exports.describe = 'Install an app into a DAO'

exports.builder = function (yargs) {
return getRepoTask.args(daoArg(yargs))
}

exports.task = async ({ web3, reporter, dao, network, apmOptions, apmRepo, apmRepoVersion }) => {
apmOptions.ensRegistryAddress = apmOptions['ens-registry']
const apm = await APM(web3, apmOptions)

apmRepo = defaultAPMName(apmRepo)
// TODO: Resolve DAO ens name

const tasks = new TaskList([
{
title: `Fetching ${chalk.bold(apmRepo)}@${apmRepoVersion}`,
task: getRepoTask.task({ apm, apmRepo, apmRepoVersion }),
},
{
title: `Upgrading app`,
task: ctx => upgrade.task({ repo: ctx.repo, web3, dao, apmRepo, apmRepoVersion, apmOptions, reporter })
},
{
title: 'Deploying app instance',
task: async (ctx) => {
const kernel = new web3.eth.Contract(
getContract('@aragon/os', 'Kernel').abi,
dao
)

ctx.aclAddress = await kernel.methods.acl().call()
if (!ctx.accounts) {
ctx.accounts = await web3.eth.getAccounts()
}

const { events } = await kernel.methods.newAppInstance(
ctx.repo.appId,
ctx.repo.contractAddress
).send({
from: ctx.accounts[0],
gasLimit: 1e6
})

ctx.appAddress = events['NewAppProxy'].returnValues.proxy
}
},
{
title: 'Set permissions',
task: async (ctx, task) => {
if (!ctx.repo.roles || ctx.repo.roles.length === 0) {
throw new Error('You have no permissions defined in your arapp.json\nThis is required for your app to properly show up.')
return
}

const permissions = ctx.repo.roles
.map((role) => [ANY_ENTITY, ctx.appAddress, role.bytes])

return setPermissions(
web3,
ctx.accounts[0],
ctx.aclAddress,
permissions
)
}
}
])

return tasks
}

exports.handler = async function ({ reporter, dao, network, apm: apmOptions, apmRepo, apmRepoVersion }) {
const web3 = await ensureWeb3(network)

const task = await exports.task({ web3, reporter, dao, network, apmOptions, apmRepo, apmRepoVersion })
return task.run()
.then((ctx) => {
reporter.success(`Installed ${apmRepo} at: ${chalk.bold(ctx.appAddress)}`)
process.exit()
})
}
Loading