Skip to content

Commit 5900f09

Browse files
briceyan0237hYaroShkvorets
authored
fix: honor --contract-name and --start-block (#1778)
* fix: honor --contract-name and --start-block * Improve `startBlock` validation * Add changeset * Add `startBlock` to test case * Fix contract name uniqueness check * Parse `startBlockFlag` only if defined * Fix lint * remove default value for `--contract-name` * fix add command exit * lint --------- Co-authored-by: Etienne Donneger <[email protected]> Co-authored-by: YaroShkvorets <[email protected]>
1 parent 91766cd commit 5900f09

File tree

5 files changed

+42
-38
lines changed

5 files changed

+42
-38
lines changed

.changeset/@graphprotocol_graph-cli-1829-dependencies.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/heavy-socks-cross.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@graphprotocol/graph-cli': patch
3+
---
4+
5+
Fix `graph add` flag parameters parsing

packages/cli/src/commands/add.ts

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import EthereumABI from '../protocols/ethereum/abi.js';
1818
import Protocol from '../protocols/index.js';
1919
import Subgraph from '../subgraph.js';
2020

21+
const DEFAULT_CONTRACT_NAME = 'Contract';
22+
2123
export default class AddCommand extends Command {
2224
static description = 'Adds a new datasource to a subgraph.';
2325

@@ -36,14 +38,14 @@ export default class AddCommand extends Command {
3638
char: 'h',
3739
}),
3840
abi: Flags.string({
39-
summary: 'Path to the contract ABI.',
41+
summary: 'Path to the contract ABI. If not provided, will be fetched from contract API.',
4042
}),
4143
'start-block': Flags.string({
42-
summary: 'The block number to start indexing events from.',
44+
summary:
45+
'The block number to start indexing events from. If not provided, will be fetched from contract API',
4346
}),
4447
'contract-name': Flags.string({
45-
summary: 'Name of the contract.',
46-
default: 'Contract',
48+
summary: 'Name of the contract. If not provided, will be fetched from contract API',
4749
}),
4850
'merge-entities': Flags.boolean({
4951
summary: 'Whether to merge entities with the same name.',
@@ -79,17 +81,8 @@ export default class AddCommand extends Command {
7981
const registry = await loadRegistry();
8082
const contractService = new ContractService(registry);
8183

82-
let startBlock = startBlockFlag;
83-
let contractName = contractNameFlag;
84-
85-
const entities = getEntities(manifest);
86-
const contractNames = getContractNames(manifest);
87-
if (contractNames.includes(contractName)) {
88-
this.error(
89-
`Datasource or template with name ${contractName} already exists, please choose a different name.`,
90-
{ exit: 1 },
91-
);
92-
}
84+
let startBlock = startBlockFlag ? parseInt(startBlockFlag).toString() : startBlockFlag;
85+
let contractName = contractNameFlag || DEFAULT_CONTRACT_NAME;
9386

9487
let ethabi = null;
9588
if (abi) {
@@ -103,44 +96,36 @@ export default class AddCommand extends Command {
10396
'Fetching ABI from contract API...',
10497
'Failed to fetch ABI',
10598
'Warning fetching ABI',
106-
() => contractService?.getABI(EthereumABI, network, address),
99+
() => contractService.getABI(EthereumABI, network, address),
107100
),
108101
);
102+
if (!ethabi) throw Error;
109103
} catch (error) {
110104
// we cannot ask user to do prompt in test environment
111105
if (process.env.NODE_ENV !== 'test') {
112-
const { abi: abiFromFile } = await prompt.ask<{ abi: EthereumABI }>([
106+
const { abi: abiFile } = await prompt.ask<{ abi: string }>([
113107
{
114108
type: 'input',
115109
name: 'abi',
116110
message: 'ABI file (path)',
117-
initial: ethabi,
118111
validate: async (value: string) => {
119112
try {
120113
EthereumABI.load(contractName, value);
121114
return true;
122115
} catch (e) {
123-
this.error(e.message);
124-
}
125-
},
126-
result: async (value: string) => {
127-
try {
128-
return EthereumABI.load(contractName, value);
129-
} catch (e) {
130-
return e.message;
116+
return `Failed to load ABI from ${value}: ${e.message}`;
131117
}
132118
},
133119
},
134120
]);
135-
ethabi = abiFromFile;
121+
ethabi = EthereumABI.load(contractName, abiFile);
136122
}
137123
}
138124
}
139125

140126
try {
141127
if (isLocalHost) throw Error; // Triggers user prompting without waiting for Etherscan lookup to fail
142-
143-
startBlock ||= Number(await contractService?.getStartBlock(network, address)).toString();
128+
startBlock ||= Number(await contractService.getStartBlock(network, address)).toString();
144129
} catch (error) {
145130
// we cannot ask user to do prompt in test environment
146131
if (process.env.NODE_ENV !== 'test') {
@@ -163,8 +148,10 @@ export default class AddCommand extends Command {
163148

164149
try {
165150
if (isLocalHost) throw Error; // Triggers user prompting without waiting for Etherscan lookup to fail
166-
167-
contractName = (await contractService?.getContractName(network, address)) ?? '';
151+
if (contractName === DEFAULT_CONTRACT_NAME) {
152+
contractName =
153+
(await contractService.getContractName(network, address)) ?? DEFAULT_CONTRACT_NAME;
154+
}
168155
} catch (error) {
169156
// not asking user to do prompt in test environment
170157
if (process.env.NODE_ENV !== 'test') {
@@ -184,6 +171,15 @@ export default class AddCommand extends Command {
184171
}
185172
}
186173

174+
const entities = getEntities(manifest);
175+
const contractNames = getContractNames(manifest);
176+
if (contractNames.includes(contractName)) {
177+
this.error(
178+
`Datasource or template with name ${contractName} already exists, please choose a different name.`,
179+
{ exit: 1 },
180+
);
181+
}
182+
187183
await writeABI(ethabi, contractName);
188184

189185
const { collisionEntities, onlyCollisions, abiData } = updateEventNamesOnCollision(
@@ -246,9 +242,14 @@ export default class AddCommand extends Command {
246242
});
247243
}
248244

249-
await withSpinner('Running codegen', 'Failed to run codegen', 'Warning during codegen', () =>
250-
system.run(yarn ? 'yarn codegen' : 'npm run codegen'),
245+
await withSpinner(
246+
'Running codegen',
247+
'Failed to run codegen',
248+
'Warning during codegen',
249+
async () => await system.run(yarn ? 'yarn codegen' : 'npm run codegen'),
251250
);
251+
252+
this.exit(0);
252253
}
253254
}
254255

packages/cli/tests/cli/add.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ describe('Add command', () => {
1919
'0x2E645469f354BB4F5c8a05B3b30A929361cf77eC',
2020
'--contract-name',
2121
'Gravatar',
22+
'--start-block',
23+
'6175244',
2224
'--abi',
2325
`${EXAMPLE_SUBGRAPH_PATH}/abis/Gravity.json`,
2426
],

packages/cli/tests/cli/add/expected/subgraph.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ dataSources:
3232
source:
3333
address: "0x2E645469f354BB4F5c8a05B3b30A929361cf77eC"
3434
abi: Gravatar
35+
startBlock: 6175244
3536
mapping:
3637
kind: ethereum/events
3738
apiVersion: 0.0.7

0 commit comments

Comments
 (0)