Skip to content

Commit

Permalink
Merge pull request #94 from aragon/dao-install
Browse files Browse the repository at this point in the history
New commands (dao new, dao install, dao upgrade, aragon ipfs) + aragon run refactor
  • Loading branch information
izqui authored and 0xGabi committed Feb 25, 2019
1 parent 00a6d81 commit e95aeb9
Show file tree
Hide file tree
Showing 15 changed files with 475 additions and 204 deletions.
24 changes: 17 additions & 7 deletions packages/aragon-cli/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 packages/aragon-cli/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 packages/aragon-cli/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 packages/aragon-cli/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 packages/aragon-cli/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

0 comments on commit e95aeb9

Please sign in to comment.