Skip to content

Commit

Permalink
feat(cli): ability to print many different types of data with inspect (
Browse files Browse the repository at this point in the history
  • Loading branch information
dbeal-eth authored Dec 23, 2024
1 parent 674675a commit aa0c7e5
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 88 deletions.
6 changes: 5 additions & 1 deletion packages/cli/src/commands/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,11 @@ export const commandsConfig: CommandsConfig = {
},
{
flags: '-j --json',
description: 'Output as JSON',
description: 'DEPRECATED. use `--out json`. Output as JSON',
},
{
flags: '-o --out <mode>',
description: 'Output the given data. Options: `json` or `misc-json`',
},
{
flags: '-w --write-deployments <writeDeployments>',
Expand Down
8 changes: 4 additions & 4 deletions packages/cli/src/commands/inspect.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ describe('inspect', () => {
});

test('should inspect package deployment', async () => {
const result = await inspect(packageName, cliSettings, chainId, false, '', false);
const result = await inspect(packageName, cliSettings, chainId, 'overview', '', false);

expect(result).toEqual(testPkgData);
expect(mockedFallBackRegistry.getUrl).toHaveBeenCalledWith(packageName, chainId);
Expand All @@ -152,7 +152,7 @@ describe('inspect', () => {

test('should write deployment files', async () => {
const writeDeployments = 'contracts';
const result = await inspect(packageName, cliSettings, chainId, false, writeDeployments, false);
const result = await inspect(packageName, cliSettings, chainId, 'overview', writeDeployments, false);

expect(result).toEqual(testPkgData);
expect(mockedFallBackRegistry.getUrl).toHaveBeenCalledWith(packageName, chainId);
Expand All @@ -161,7 +161,7 @@ describe('inspect', () => {
});

test('should call inspect with sources flag ', async () => {
const result = await inspect(packageName, cliSettings, chainId, false, '', true);
const result = await inspect(packageName, cliSettings, chainId, 'overview', '', true);

expect(result).toEqual(testPkgData);
expect(mockedFallBackRegistry.getUrl).toHaveBeenCalledWith(packageName, chainId);
Expand All @@ -173,7 +173,7 @@ describe('inspect', () => {
});

test('should call inspect with json flag ', async () => {
const result = await inspect(packageName, cliSettings, chainId, true, '', false);
const result = await inspect(packageName, cliSettings, chainId, 'deploy-json', '', false);

expect(result).toEqual(testPkgData);
expect(mockedFallBackRegistry.getUrl).toHaveBeenCalledWith(packageName, chainId);
Expand Down
32 changes: 22 additions & 10 deletions packages/cli/src/commands/inspect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
ContractData,
DeploymentState,
fetchIPFSAvailability,
getArtifacts,
PackageReference,
} from '@usecannon/builder';
import { bold, cyan, green, yellow } from 'chalk';
Expand All @@ -23,7 +24,7 @@ export async function inspect(
packageRef: string,
cliSettings: CliSettings,
chainId: number,
json: boolean,
out: 'overview' | 'deploy-json' | 'misc-json' | 'artifact-json',
writeDeployments: string,
sources: boolean
) {
Expand All @@ -39,7 +40,7 @@ export async function inspect(

// Mute all build outputs when printing the result to json, this is so it
// doesn't break the result.
if (json) {
if (out && out !== 'overview') {
// eslint-disable-next-line no-console
console.log = debug;
// eslint-disable-next-line no-console
Expand All @@ -65,15 +66,17 @@ export async function inspect(
);
}

if (json) {
// use process.stdout.write and write in chunks because bash piping seems to have some sort of
// a problem with outputting huge amounts of data all at once while using pipes
const toOutput = JSON.stringify(deployData, null, 2);

const chunkSize = 16;
for (let i = 0; i < toOutput.length; i += chunkSize) {
process.stdout.write(toOutput.slice(i, i + chunkSize));
if (out === 'deploy-json') {
_outputJson(deployData);
} else if (out === 'misc-json') {
if (!deployData.miscUrl) {
log('null');
return;
}
const miscData = await loader[deployData.miscUrl.split(':')[0] as 'ipfs'].read(deployData.miscUrl);
_outputJson(miscData);
} else if (out === 'artifact-json') {
_outputJson(getArtifacts(chainDefinition, deployData.state));
} else {
const metaUrl = await resolver.getMetaUrl(fullPackageRef, chainId);
const packageOwner = deployData.def.setting?.owner?.defaultValue;
Expand Down Expand Up @@ -166,3 +169,12 @@ function _getNestedStateFiles(artifacts: ChainArtifacts, pathname: string, resul
function _listSourceCodeContracts(miscData: any) {
return Object.keys(_.pickBy(miscData.artifacts, (v) => v.source));
}

function _outputJson(obj: object) {
const toOutput = JSON.stringify(obj, null, 2);

const chunkSize = 16;
for (let i = 0; i < toOutput.length; i += chunkSize) {
process.stdout.write(toOutput.slice(i, i + chunkSize));
}
}
142 changes: 71 additions & 71 deletions packages/cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ function configureRun(program: Command) {
return applyCommandsConfig(program, commandsConfig.run).action(async function (
packages: PackageSpecification[],
options,
program
program,
) {
log(bold('Starting local node...\n'));

Expand Down Expand Up @@ -258,74 +258,67 @@ applyCommandsConfig(program.command('verify'), commandsConfig.verify).action(asy
await verify(fullPackageRef, cliSettings, chainId);
});

applyCommandsConfig(program.command('diff'), commandsConfig.diff).action(async function (
packageRef,
projectDirectory,
options
) {
const { diff } = await import('./commands/diff');

const cliSettings = resolveCliSettings(options);
const { fullPackageRef, chainId } = await getPackageInfo(packageRef, options.chainId, cliSettings.rpcUrl);

const foundDiffs = await diff(
fullPackageRef,
cliSettings,
chainId,
projectDirectory,
options.matchContract,
options.matchSource
);
applyCommandsConfig(program.command('diff'), commandsConfig.diff).action(
async function (packageRef, projectDirectory, options) {
const { diff } = await import('./commands/diff');

// exit code is the number of differences found--useful for CI checks
process.exit(foundDiffs);
});
const cliSettings = resolveCliSettings(options);
const { fullPackageRef, chainId } = await getPackageInfo(packageRef, options.chainId, cliSettings.rpcUrl);

const foundDiffs = await diff(
fullPackageRef,
cliSettings,
chainId,
projectDirectory,
options.matchContract,
options.matchSource,
);

applyCommandsConfig(program.command('alter'), commandsConfig.alter).action(async function (
packageName,
command,
options,
flags
) {
const { alter } = await import('./commands/alter');
// exit code is the number of differences found--useful for CI checks
process.exit(foundDiffs);
},
);

const cliSettings = resolveCliSettings(flags);
applyCommandsConfig(program.command('alter'), commandsConfig.alter).action(
async function (packageName, command, options, flags) {
const { alter } = await import('./commands/alter');

// throw an error if the chainId is not consistent with the provider's chainId
await ensureChainIdConsistency(cliSettings.rpcUrl, flags.chainId);
const cliSettings = resolveCliSettings(flags);

// note: for command below, pkgInfo is empty because forge currently supplies no package.json or anything similar
const newUrl = await alter(
packageName,
flags.subpkg ? flags.subpkg.split(',') : [],
parseInt(flags.chainId),
cliSettings,
{},
command,
options,
{}
);
// throw an error if the chainId is not consistent with the provider's chainId
await ensureChainIdConsistency(cliSettings.rpcUrl, flags.chainId);

// note: for command below, pkgInfo is empty because forge currently supplies no package.json or anything similar
const newUrl = await alter(
packageName,
flags.subpkg ? flags.subpkg.split(',') : [],
parseInt(flags.chainId),
cliSettings,
{},
command,
options,
{},
);

log(newUrl);
});
log(newUrl);
},
);

applyCommandsConfig(program.command('fetch'), commandsConfig.fetch).action(async function (
packageRef,
givenIpfsUrl,
options
) {
const { fetch } = await import('./commands/fetch');
applyCommandsConfig(program.command('fetch'), commandsConfig.fetch).action(
async function (packageRef, givenIpfsUrl, options) {
const { fetch } = await import('./commands/fetch');

const { fullPackageRef, chainId } = await getPackageReference(packageRef, options.chainId);
const ipfsUrl = getIpfsUrl(givenIpfsUrl);
const metaIpfsUrl = getIpfsUrl(options.metaHash) || undefined;
const { fullPackageRef, chainId } = await getPackageReference(packageRef, options.chainId);
const ipfsUrl = getIpfsUrl(givenIpfsUrl);
const metaIpfsUrl = getIpfsUrl(options.metaHash) || undefined;

if (!ipfsUrl) {
throw new Error('IPFS URL is required.');
}
if (!ipfsUrl) {
throw new Error('IPFS URL is required.');
}

await fetch(fullPackageRef, chainId, ipfsUrl, metaIpfsUrl);
});
await fetch(fullPackageRef, chainId, ipfsUrl, metaIpfsUrl);
},
);

applyCommandsConfig(program.command('pin'), commandsConfig.pin).action(async function (packageRef, options) {
const cliSettings = resolveCliSettings(options);
Expand All @@ -351,7 +344,7 @@ applyCommandsConfig(program.command('pin'), commandsConfig.pin).action(async fun

applyCommandsConfig(program.command('publish'), commandsConfig.publish).action(async function (
packageRef,
options: { [opt: string]: string }
options: { [opt: string]: string },
) {
const { publish } = await import('./commands/publish');

Expand Down Expand Up @@ -428,8 +421,8 @@ applyCommandsConfig(program.command('publish'), commandsConfig.publish).action(a
log();
log(
gray(
`Package "${pkgRef.name}" not yet registered, please use "cannon register" to register your package first.\nYou need enough gas on Ethereum Mainnet to register the package on Cannon Registry`
)
`Package "${pkgRef.name}" not yet registered, please use "cannon register" to register your package first.\nYou need enough gas on Ethereum Mainnet to register the package on Cannon Registry`,
),
);
log();

Expand Down Expand Up @@ -482,7 +475,7 @@ applyCommandsConfig(program.command('publish'), commandsConfig.publish).action(a
}\n - Max Priority Fee Per Gas: ${
overrides.maxPriorityFeePerGas ? overrides.maxPriorityFeePerGas.toString() : 'default'
}\n - Gas Limit: ${overrides.gasLimit ? overrides.gasLimit : 'default'}\n` +
" - To alter these settings use the parameters '--max-fee-per-gas', '--max-priority-fee-per-gas', '--gas-limit'.\n"
" - To alter these settings use the parameters '--max-fee-per-gas', '--max-priority-fee-per-gas', '--gas-limit'.\n",
);

await publish({
Expand Down Expand Up @@ -528,7 +521,14 @@ applyCommandsConfig(program.command('inspect'), commandsConfig.inspect).action(a
const cliSettings = resolveCliSettings(options);
const { fullPackageRef, chainId } = await getPackageInfo(packageRef, options.chainId, cliSettings.rpcUrl);

await inspect(fullPackageRef, cliSettings, chainId, options.json, options.writeDeployments, options.sources);
await inspect(
fullPackageRef,
cliSettings,
chainId,
options.json ? 'json' : options.out,
options.writeDeployments,
options.sources,
);
});

applyCommandsConfig(program.command('prune'), commandsConfig.prune).action(async function (options) {
Expand All @@ -548,7 +548,7 @@ applyCommandsConfig(program.command('prune'), commandsConfig.prune).action(async
storage,
options.filterPackage?.split(',') || '',
options.filterVariant?.split(',') || '',
options.keepAge
options.keepAge,
);

if (pruneUrls.length) {
Expand Down Expand Up @@ -635,9 +635,9 @@ applyCommandsConfig(program.command('test'), commandsConfig.test).action(async f
warn(
yellowBright(
bold(
'⚠️ The `--` syntax for passing options to forge or anvil is deprecated. Please use `--forge.*` or `--anvil.*` instead.'
)
)
'⚠️ The `--` syntax for passing options to forge or anvil is deprecated. Please use `--forge.*` or `--anvil.*` instead.',
),
),
);
log();
}
Expand Down Expand Up @@ -702,22 +702,22 @@ applyCommandsConfig(program.command('interact'), commandsConfig.interact).action
priorityGasFee: options.maxPriorityFee,
},
resolver,
getMainLoader(cliSettings)
getMainLoader(cliSettings),
);

const deployData = await runtime.readDeploy(fullPackageRef, runtime.chainId);

if (!deployData) {
throw new Error(
`deployment not found for package: ${fullPackageRef} with chaindId ${chainId}. please make sure it exists for the given preset and current network.`
`deployment not found for package: ${fullPackageRef} with chaindId ${chainId}. please make sure it exists for the given preset and current network.`,
);
}

const outputs = await getOutputs(runtime, new ChainDefinition(deployData.def), deployData.state);

if (!outputs) {
throw new Error(
`no cannon build found for ${fullPackageRef} with chaindId ${chainId}. Did you mean to run the package instead?`
`no cannon build found for ${fullPackageRef} with chaindId ${chainId}. Did you mean to run the package instead?`,
);
}

Expand Down
6 changes: 4 additions & 2 deletions packages/cli/src/write-script/render-foundry.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { EOL } from 'node:os';
import { Transform } from 'node:stream';

import { getAddress } from 'viem';

/**
* This script is used to deploy contracts using Foundry Cast.
* It outputs a bash script that can be used to deploy contracts and execute transactions.
Expand Down Expand Up @@ -47,7 +49,7 @@ export const createRenderer = () =>
// Loggin txn types
for (const c in line.result.contracts) {
this.push(`${indent}// > CONTRACT DEPLOYED: ${line.result.contracts[c].address}\n`);
this.push(`${indent}getAddress[keccak256("${c}")] = address(${line.result.contracts[c].address});\n`);
this.push(`${indent}getAddress[keccak256("${c}")] = address(${getAddress(line.result.contracts[c].address)});\n`);
}

for (const t in line.result.txns) {
Expand All @@ -57,7 +59,7 @@ export const createRenderer = () =>

for (const { to, from, input, value } of line.txns) {
if (from) {
this.push(`${indent}vm.broadcast(address(${from}));\n`);
this.push(`${indent}vm.broadcast(${getAddress(from)});\n`);
this.push(`${indent}data = hex"${input.slice(2)}";\n`);
}

Expand Down

0 comments on commit aa0c7e5

Please sign in to comment.