Skip to content

Commit 51f831c

Browse files
authored
fix(builder): script no overwrite (#1799)
1 parent 874277f commit 51f831c

File tree

10 files changed

+172
-23
lines changed

10 files changed

+172
-23
lines changed

examples/sample-foundry-project/write-script-models/build-foundry-write-script.cast

Lines changed: 13 additions & 0 deletions
Large diffs are not rendered by default.

examples/sample-foundry-project/write-script-models/build-foundry-write-script.ethers

Lines changed: 5 additions & 0 deletions
Large diffs are not rendered by default.

examples/sample-foundry-project/write-script-models/build-foundry-write-script.foundry

Lines changed: 91 additions & 0 deletions
Large diffs are not rendered by default.

examples/sample-foundry-project/write-script-models/build-foundry-write-script.json

Lines changed: 3 additions & 0 deletions
Large diffs are not rendered by default.

packages/builder/src/constants.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ export const DEFAULT_REGISTRY_CONFIG = [
1515
name: 'OP Mainnet',
1616
chainId: 10,
1717
rpcUrl: [
18-
'frame',
19-
'direct',
2018
'https://optimism-mainnet.infura.io/v3/9f7e95d07f4e42e7a54d4dc90f57fd5d',
2119
'https://opt-mainnet.g.alchemy.com/v2/2c6Mq72inJF0FBlKPMK8pe6TolJMar6G',
2220
],
@@ -26,8 +24,6 @@ export const DEFAULT_REGISTRY_CONFIG = [
2624
name: 'Ethereum Mainnet',
2725
chainId: 1,
2826
rpcUrl: [
29-
'frame',
30-
'direct',
3127
'https://mainnet.infura.io/v3/9f7e95d07f4e42e7a54d4dc90f57fd5d',
3228
'https://eth-mainnet.g.alchemy.com/v2/2c6Mq72inJF0FBlKPMK8pe6TolJMar6G',
3329
],

packages/cli/src/commands/build.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import { getChainById } from '../chains';
2828
import { filterSettings, saveToMetadataCache } from '../helpers';
2929
import { getMainLoader } from '../loader';
3030
import { listInstalledPlugins, loadPlugins } from '../plugins';
31-
import { createDefaultReadRegistry, createOnChainOnlyRegistry } from '../registry';
31+
import { createDefaultReadRegistry, createLocalOnlyRegistry, createOnChainOnlyRegistry } from '../registry';
3232
import { resolveCliSettings } from '../settings';
3333
import { PackageSpecification } from '../types';
3434
import { log, warn, error } from '../util/console';
@@ -140,6 +140,7 @@ export async function build({
140140
};
141141

142142
const onChainOnlyResolver = await createOnChainOnlyRegistry(cliSettings);
143+
const localOnlyResolver = await createLocalOnlyRegistry(cliSettings);
143144
const resolver = overrideResolver || (await createDefaultReadRegistry(cliSettings));
144145

145146
const runtime = new ChainBuilderRuntime(runtimeOptions, resolver, getMainLoader(cliSettings), 'ipfs');
@@ -149,11 +150,14 @@ export async function build({
149150
let oldDeployData: DeploymentInfo | null = null;
150151

151152
// before building, make sure that the name/version isnt already taken on the registry
152-
const isPackageAlreadyPublished = await onChainOnlyResolver.getUrl(fullPackageRef, chainId);
153-
if (isPackageAlreadyPublished.url) {
154-
throw new Error(
155-
'The package ${fullPackageRef} is already published on the registry. Please bump the `version` field in your cannonfile.'
156-
);
153+
const localPackageUrl = await localOnlyResolver.getUrl(fullPackageRef, chainId);
154+
if (!localPackageUrl.url) {
155+
const isPackageAlreadyPublished = await onChainOnlyResolver.getUrl(fullPackageRef, chainId);
156+
if (isPackageAlreadyPublished.url) {
157+
throw new Error(
158+
'The package ${fullPackageRef} is already published on the registry. Please bump the `version` field in your cannonfile.'
159+
);
160+
}
157161
}
158162

159163
if (!wipe) {

packages/cli/src/registry.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,10 @@ export async function createOnChainOnlyRegistry(cliSettings: CliSettings): Promi
217217
);
218218
}
219219

220+
export async function createLocalOnlyRegistry(cliSettings: CliSettings): Promise<LocalRegistry> {
221+
return new LocalRegistry(cliSettings.cannonDirectory);
222+
}
223+
220224
export async function createDefaultReadRegistry(
221225
cliSettings: CliSettings,
222226
additionalRegistries: CannonRegistry[] = []

packages/cli/src/write-script/write.ts

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import { createWriteStream } from 'node:fs';
2-
import { finished } from 'node:stream/promises';
31
import { ChainBuilderRuntime } from '@usecannon/builder';
42
import { ensureFileSync } from 'fs-extra';
5-
import * as viem from 'viem';
63
import { createStepsStream } from './stream-steps';
74
import { DumpRenderer } from './types';
5+
import { writeFile } from 'node:fs/promises';
6+
import * as logger from '../util/console';
87

98
export const WRITE_SCRIPT_FORMATS = ['json', 'ethers', 'foundry', 'cast'] as const;
109

@@ -28,24 +27,38 @@ export async function createWriteScript(
2827
const createRenderer = (await import(`./render-${format}`)).createRenderer as DumpRenderer;
2928

3029
const events = createStepsStream(runtime);
31-
3230
const blockNumber = await runtime.provider.getBlockNumber();
31+
const renderer = createRenderer(Number(blockNumber));
32+
33+
// Collect all events into an array
34+
const eventsData: string[] = [];
35+
36+
// Set up the event processing pipeline
37+
const pipeline = events.stream.pipe(events.fetchTransactions).pipe(renderer);
3338

34-
const stream = events.stream // Listen for step execution events
35-
.pipe(events.fetchTransactions) // asynchronically add the executed transactions
36-
.pipe(createRenderer(Number(blockNumber))) // render step lines into the desired format
37-
.pipe(createWriteStream(targetFile)); // save to file
39+
pipeline.on('data', (chunk: string) => {
40+
eventsData.push(chunk);
41+
});
3842

3943
return {
4044
end: async () => {
41-
// The runtime does not have an event to notify when the build has finished
42-
// so, we have to manully stop listening to it and close the streams.
45+
// Signal the start of the pipeline to end
4346
events.stream.end();
4447

45-
await viem.withTimeout(() => finished(stream), {
46-
timeout: 10000,
47-
errorInstance: new Error('stream timed out'),
48+
// Wait for the entire pipeline to finish processing
49+
await new Promise<void>((resolve, reject) => {
50+
pipeline.on('end', () => {
51+
resolve();
52+
});
53+
54+
pipeline.on('error', (error: Error) => {
55+
logger.error('Pipeline error:', error);
56+
reject(error);
57+
});
4858
});
59+
60+
// Write all collected data to file atomically
61+
await writeFile(targetFile, eventsData.join(''));
4962
},
5063
};
5164
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
$CANNON build \
2+
$CANNON_REPO_DIR/examples/sample-foundry-project/cannonfile.toml \
3+
--wipe \
4+
--write-script-format $1 \
5+
--write-script /tmp/build-foundry-write-script.${1}
6+
7+
# make sure the outputted write script file matches the model file
8+
# check first 20 lines of the generated file against the model file
9+
head -n 20 /tmp/build-foundry-write-script.${1} > /tmp/generated-head.txt
10+
head -n 20 $CANNON_REPO_DIR/examples/sample-foundry-project/write-script-models/build-foundry-write-script.$1 > /tmp/model-head.txt
11+
cmp /tmp/generated-head.txt /tmp/model-head.txt

packages/cli/test/e2e/series.bats

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,15 @@ teardown() {
6969
assert_file_exists "$CANNON_DIRECTORY/tags/greeter-foundry-private-source_latest_13370-main.txt"
7070
}
7171

72+
@test "Build - Write Scripts with Foundry" {
73+
run build-foundry-write-script.sh cast
74+
run build-foundry-write-script.sh ethers
75+
run build-foundry-write-script.sh foundry
76+
#run build-foundry-write-script.sh json # this is currently not stable
77+
echo $output
78+
assert_success
79+
}
80+
7281
@test "Build - Building foundry greeter example live" {
7382
set_custom_config
7483
run build-foundry-live.sh

0 commit comments

Comments
 (0)