1
- import type { ParameterTypeToValueType } from "../types/common.js" ;
1
+ import type {
2
+ ParameterTypeToValueType ,
3
+ ParameterValue ,
4
+ } from "../types/common.js" ;
2
5
import type {
3
6
GlobalOptions ,
4
7
GlobalOption ,
@@ -7,21 +10,24 @@ import type {
7
10
import type { HardhatPlugin } from "../types/plugins.js" ;
8
11
9
12
import { HardhatError } from "@nomicfoundation/hardhat-errors" ;
13
+ import { camelToSnakeCase } from "@nomicfoundation/hardhat-utils/string" ;
10
14
11
15
import { ParameterType } from "../types/common.js" ;
12
16
13
17
import {
14
18
RESERVED_PARAMETER_NAMES ,
15
19
isParameterValueValid ,
16
20
isValidParamNameCasing ,
21
+ parseParameterValue ,
17
22
} from "./parameters.js" ;
18
23
19
24
/**
20
- * Builds a map of the global options, validating them.
25
+ * Builds a map of the global option definitions by going through all the
26
+ * plugins and validating the global options they define.
21
27
*
22
28
* Note: this function can be used before initializing the HRE, so the plugins
23
29
* shouldn't be consider validated. Hence, we should validate the global
24
- * parameters .
30
+ * options .
25
31
*/
26
32
export function buildGlobalOptionsMap (
27
33
resolvedPlugins : HardhatPlugin [ ] ,
@@ -60,6 +66,10 @@ export function buildGlobalOptionsMap(
60
66
return globalOptionsMap ;
61
67
}
62
68
69
+ /**
70
+ * Builds a global option definition, validating the name, type, and default
71
+ * value.
72
+ */
63
73
export function buildGlobalOptionDefinition < T extends ParameterType > ( {
64
74
name,
65
75
description,
@@ -104,13 +114,50 @@ export function buildGlobalOptionDefinition<T extends ParameterType>({
104
114
} ;
105
115
}
106
116
117
+ /**
118
+ * Resolves global options by merging user-provided options with environment
119
+ * variables, adhering to predefined global option definitions. This function
120
+ * ensures that only options specified in the globalOptionsMap are considered.
121
+ * Each option is validated against its definition in the map, with
122
+ * user-provided options taking precedence over environment variables. If an
123
+ * option is not provided by the user or set as an environment variable, its
124
+ * default value (as specified in the globalOptionsMap) is used.
125
+ *
126
+ * @param userProvidedGlobalOptions The options explicitly provided by the
127
+ * user. These take precedence over equivalent environment variables.
128
+ * @param globalOptionsMap A map defining valid global options, their default
129
+ * values, and expected types. This map is used to validate and parse the options.
130
+ * @returns {GlobalOptions } An object containing the resolved global options,
131
+ * with each option adhering to its definition in the globalOptionsMap.
132
+ * @throws {HardhatError } with descriptor
133
+ * {@link HardhatError.ERRORS.ARGUMENTS.INVALID_VALUE_FOR_TYPE} if a user-provided
134
+ * option has an invalid value for its type.
135
+ */
107
136
export function resolveGlobalOptions (
108
137
userProvidedGlobalOptions : Partial < GlobalOptions > ,
109
- _globalOptionsMap : GlobalOptionsMap ,
138
+ globalOptionsMap : GlobalOptionsMap ,
110
139
) : GlobalOptions {
111
- // TODO: Validate the userProvidedGlobalOptions and get the remaining ones
112
- // from env variables
140
+ const globalOptions : GlobalOptions = { } ;
141
+ // iterate over the definitions to parse and validate the arguments
142
+ for ( const [ name , { option } ] of globalOptionsMap ) {
143
+ let value =
144
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions
145
+ -- GlobalOptions is empty for user extension, so we need to cast it to
146
+ assign the value. */
147
+ ( userProvidedGlobalOptions as Record < string , string | undefined > ) [ name ] ;
148
+ if ( value === undefined ) {
149
+ value = process . env [ `HARDHAT_${ camelToSnakeCase ( name ) . toUpperCase ( ) } ` ] ;
150
+ }
151
+
152
+ let parsedValue : ParameterValue ;
153
+ if ( value !== undefined ) {
154
+ parsedValue = parseParameterValue ( value , option . parameterType , name ) ;
155
+ } else {
156
+ parsedValue = option . defaultValue ;
157
+ }
158
+
159
+ globalOptions [ name ] = parsedValue ;
160
+ }
113
161
114
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- TODO
115
- return userProvidedGlobalOptions as GlobalOptions ;
162
+ return globalOptions ;
116
163
}
0 commit comments