1
- import { execa , Options } from "execa" ;
1
+ import { execa , ExecaChildProcess , Options } from "execa" ;
2
2
3
3
export interface ForgeConfig {
4
4
// project
@@ -18,13 +18,19 @@ export interface ForgeConfig {
18
18
[ key : string ] : unknown ;
19
19
}
20
20
21
+ // Execa options for Foundry commands
22
+ export interface FoundryExecOptions extends Options {
23
+ silent ?: boolean ;
24
+ profile ?: string ;
25
+ }
26
+
21
27
/**
22
28
* Get forge config as a parsed json object.
23
29
*/
24
- export async function getForgeConfig ( profile ?: string ) : Promise < ForgeConfig > {
30
+ export async function getForgeConfig ( opts ?: FoundryExecOptions ) : Promise < ForgeConfig > {
25
31
const { stdout } = await execa ( "forge" , [ "config" , "--json" ] , {
26
32
stdio : [ "inherit" , "pipe" , "pipe" ] ,
27
- env : { FOUNDRY_PROFILE : profile } ,
33
+ ... getExecOptions ( opts ) ,
28
34
} ) ;
29
35
30
36
return JSON . parse ( stdout ) as ForgeConfig ;
@@ -34,87 +40,97 @@ export async function getForgeConfig(profile?: string): Promise<ForgeConfig> {
34
40
* Get the value of "src" from forge config.
35
41
* The path to the contract sources relative to the root of the project.
36
42
*/
37
- export async function getSrcDirectory ( profile ?: string ) : Promise < string > {
38
- return ( await getForgeConfig ( profile ) ) . src ;
43
+ export async function getSrcDirectory ( opts ?: FoundryExecOptions ) : Promise < string > {
44
+ return ( await getForgeConfig ( opts ) ) . src ;
39
45
}
40
46
41
47
/**
42
48
* Get the value of "script" from forge config.
43
49
* The path to the contract sources relative to the root of the project.
44
50
*/
45
- export async function getScriptDirectory ( profile ?: string ) : Promise < string > {
46
- return ( await getForgeConfig ( profile ) ) . script ;
51
+ export async function getScriptDirectory ( opts ?: FoundryExecOptions ) : Promise < string > {
52
+ return ( await getForgeConfig ( opts ) ) . script ;
47
53
}
48
54
49
55
/**
50
56
* Get the value of "test" from forge config.
51
57
* The path to the test contract sources relative to the root of the project.
52
58
*/
53
- export async function getTestDirectory ( profile ?: string ) : Promise < string > {
54
- return ( await getForgeConfig ( profile ) ) . test ;
59
+ export async function getTestDirectory ( opts ?: FoundryExecOptions ) : Promise < string > {
60
+ return ( await getForgeConfig ( opts ) ) . test ;
55
61
}
56
62
57
63
/**
58
64
* Get the value of "out" from forge config.
59
65
* The path to put contract artifacts in, relative to the root of the project.
60
66
*/
61
- export async function getOutDirectory ( profile ?: string ) : Promise < string > {
62
- return ( await getForgeConfig ( profile ) ) . out ;
67
+ export async function getOutDirectory ( opts ?: FoundryExecOptions ) : Promise < string > {
68
+ return ( await getForgeConfig ( opts ) ) . out ;
63
69
}
64
70
65
71
/**
66
72
* Get the value of "eth_rpc_url" from forge config, default to "http://127.0.0.1:8545"
67
- * @param profile The foundry profile to use
73
+ * @param opts The options to pass to getForgeConfig
68
74
* @returns The rpc url
69
75
*/
70
- export async function getRpcUrl ( profile ?: string ) : Promise < string > {
71
- return ( await getForgeConfig ( profile ) ) . eth_rpc_url || "http://127.0.0.1:8545" ;
76
+ export async function getRpcUrl ( opts ?: FoundryExecOptions ) : Promise < string > {
77
+ return ( await getForgeConfig ( opts ) ) . eth_rpc_url || "http://127.0.0.1:8545" ;
72
78
}
73
79
74
80
/**
75
81
* Execute a forge command
76
82
* @param args The arguments to pass to forge
77
- * @param options { profile?: The foundry profile to use; silent?: If true, nothing will be logged to the console }
83
+ * @param opts { profile?: The foundry profile to use; silent?: If true, nothing will be logged to the console }
78
84
*/
79
- export async function forge (
80
- args : string [ ] ,
81
- options ?: { profile ?: string ; silent ?: boolean ; env ?: NodeJS . ProcessEnv ; cwd ?: string } ,
82
- ) : Promise < void > {
83
- const execOptions : Options < string > = {
84
- env : { FOUNDRY_PROFILE : options ?. profile , ...options ?. env } ,
85
- stdout : "inherit" ,
86
- stderr : "pipe" ,
87
- cwd : options ?. cwd ,
88
- } ;
89
-
90
- await ( options ?. silent ? execa ( "forge" , args , execOptions ) : execLog ( "forge" , args , execOptions ) ) ;
85
+ export async function forge ( args : string [ ] , opts ?: FoundryExecOptions ) : Promise < string | ExecaChildProcess > {
86
+ return execFoundry ( "forge" , args , opts ) ;
91
87
}
92
88
93
89
/**
94
90
* Execute a cast command
95
91
* @param args The arguments to pass to cast
92
+ * @param options The execution options
96
93
* @returns Stdout of the command
97
94
*/
98
- export async function cast ( args : string [ ] , options ?: { profile ?: string } ) : Promise < string > {
99
- return execLog ( "cast" , args , {
100
- env : { FOUNDRY_PROFILE : options ?. profile } ,
101
- } ) ;
95
+ export async function cast ( args : string [ ] , options ?: FoundryExecOptions ) : Promise < string | ExecaChildProcess > {
96
+ return execLog ( "cast" , args , getExecOptions ( options ) ) ;
102
97
}
103
98
104
99
/**
105
100
* Start an anvil chain
106
101
* @param args The arguments to pass to anvil
102
+ * @param options The execution options
107
103
* @returns Stdout of the command
108
104
*/
109
- export async function anvil ( args : string [ ] ) : Promise < string > {
110
- return execLog ( "anvil" , args ) ;
105
+ export async function anvil ( args : string [ ] , options ?: FoundryExecOptions ) : Promise < string | ExecaChildProcess > {
106
+ return execFoundry ( "anvil" , args , options ) ;
107
+ }
108
+
109
+ /**
110
+ * Execute a foundry command
111
+ * @param command The command to execute
112
+ * @param args The arguments to pass to the command
113
+ * @param options The executable options. If `silent` is true, nothing will be logged to the console
114
+ */
115
+ async function execFoundry (
116
+ command : string ,
117
+ args : string [ ] ,
118
+ options ?: FoundryExecOptions ,
119
+ ) : Promise < string | ExecaChildProcess > {
120
+ const execOptions : Options < string > = {
121
+ stdout : "inherit" ,
122
+ stderr : "pipe" ,
123
+ ...getExecOptions ( options ) ,
124
+ } ;
125
+ return options ?. silent ? execa ( command , args , execOptions ) : execLog ( command , args , execOptions ) ;
111
126
}
112
127
113
128
/**
114
129
* Executes the given command, returns the stdout, and logs the command to the console.
115
130
* Throws an error if the command fails.
116
131
* @param command The command to execute
117
132
* @param args The arguments to pass to the command
133
+ * @param options The executable options
118
134
* @returns The stdout of the command
119
135
*/
120
136
async function execLog ( command : string , args : string [ ] , options ?: Options < string > ) : Promise < string > {
@@ -130,3 +146,10 @@ async function execLog(command: string, args: string[], options?: Options<string
130
146
throw new Error ( errorMessage ) ;
131
147
}
132
148
}
149
+
150
+ function getExecOptions ( { profile, env, silent : _ , ...opts } : FoundryExecOptions = { } ) : Options < string > {
151
+ return {
152
+ env : { FOUNDRY_PROFILE : profile , ...env } ,
153
+ ...opts ,
154
+ } ;
155
+ }
0 commit comments