@taqueria/plugin-ligo 0.28.4 → 0.28.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/common.ts +1 -1
- package/compile-all.ts +110 -6
- package/compile.ts +40 -22
- package/index.d.ts +1 -0
- package/index.js +164 -51
- package/index.js.map +1 -1
- package/index.mjs +141 -32
- package/index.mjs.map +1 -1
- package/ligo.ts +30 -9
- package/package.json +2 -2
package/common.ts
CHANGED
|
@@ -25,7 +25,7 @@ export type IntersectionOpts = LigoOpts & CompileOpts & CompileAllOpts & TestOpt
|
|
|
25
25
|
type UnionOpts = LigoOpts | CompileOpts | CompileAllOpts | TestOpts;
|
|
26
26
|
|
|
27
27
|
// Should point to the latest stable version, so it needs to be updated as part of our release process.
|
|
28
|
-
const LIGO_DEFAULT_IMAGE = 'ligolang/ligo:0.
|
|
28
|
+
const LIGO_DEFAULT_IMAGE = 'ligolang/ligo:0.63.2';
|
|
29
29
|
|
|
30
30
|
const LIGO_IMAGE_ENV_VAR = 'TAQ_LIGO_IMAGE';
|
|
31
31
|
|
package/compile-all.ts
CHANGED
|
@@ -5,25 +5,129 @@ import { join } from 'path';
|
|
|
5
5
|
import { CompileAllOpts as Opts, CompileOpts, getInputFilenameAbsPath } from './common';
|
|
6
6
|
import { compileContractWithStorageAndParameter, TableRow } from './compile';
|
|
7
7
|
|
|
8
|
-
const isMainContract = (parsedArgs: Opts,
|
|
9
|
-
readFile(getInputFilenameAbsPath(parsedArgs,
|
|
10
|
-
|
|
8
|
+
const isMainContract = async (parsedArgs: Opts, contractFilename: string): Promise<boolean> => {
|
|
9
|
+
const fileContent = await readFile(getInputFilenameAbsPath(parsedArgs, contractFilename), 'utf8');
|
|
10
|
+
const entryOrMainFunctionRegex = /@entry|((const|let|function)\s+main)/g;
|
|
11
|
+
return entryOrMainFunctionRegex.test(fileContent);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
// Helper function to parse includes from a LIGO file
|
|
15
|
+
const parseIncludes = async (parsedArgs: Opts, contractFilename: string): Promise<string[]> => {
|
|
16
|
+
const fileContent = await readFile(getInputFilenameAbsPath(parsedArgs, contractFilename), 'utf8');
|
|
17
|
+
const includeRegex = /#include\s+"([^"]+\.m?ligo)"/g;
|
|
18
|
+
let match;
|
|
19
|
+
const includes: string[] = [];
|
|
20
|
+
|
|
21
|
+
while ((match = includeRegex.exec(fileContent)) !== null) {
|
|
22
|
+
includes.push(match[1]);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return includes;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// Helper function to build the dependency graph
|
|
29
|
+
const buildDependencyGraph = async (
|
|
30
|
+
parsedArgs: Opts,
|
|
31
|
+
contractFilenames: string[],
|
|
32
|
+
): Promise<Map<string, Set<string>>> => {
|
|
33
|
+
const graph = new Map<string, Set<string>>();
|
|
34
|
+
|
|
35
|
+
for (const filename of contractFilenames) {
|
|
36
|
+
const includes = await parseIncludes(parsedArgs, filename);
|
|
37
|
+
graph.set(filename, new Set(includes));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return graph;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const visit = (
|
|
44
|
+
node: string,
|
|
45
|
+
graph: Map<string, Set<string>>,
|
|
46
|
+
visited: Set<string>,
|
|
47
|
+
stack: Set<string>,
|
|
48
|
+
): [boolean, Set<string>] => {
|
|
49
|
+
if (stack.has(node)) return [true, visited]; // Circular dependency detected
|
|
50
|
+
|
|
51
|
+
if (!visited.has(node)) {
|
|
52
|
+
const newVisited = new Set(visited).add(node);
|
|
53
|
+
const newStack = new Set(stack).add(node);
|
|
54
|
+
|
|
55
|
+
const [circular, updatedVisited] = Array.from(graph.get(node) || []).reduce<[boolean, Set<string>]>(
|
|
56
|
+
([circularFound, vSet], dependency) => {
|
|
57
|
+
const [result, v] = visit(dependency, graph, vSet, newStack);
|
|
58
|
+
return [circularFound || result, v];
|
|
59
|
+
},
|
|
60
|
+
[false, newVisited],
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
if (!circular) return [false, updatedVisited];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return [false, visited];
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const detectCircularDependencies = (
|
|
70
|
+
graph: Map<string, Set<string>>,
|
|
71
|
+
): { safeFiles: string[]; circularFiles: string[] } => {
|
|
72
|
+
const { safeFiles, circularFiles, visited } = Array.from(graph.keys()).reduce<{
|
|
73
|
+
safeFiles: string[];
|
|
74
|
+
circularFiles: string[];
|
|
75
|
+
visited: Set<string>;
|
|
76
|
+
}>(
|
|
77
|
+
(acc, filename) => {
|
|
78
|
+
const [isCircular, updatedVisited] = visit(
|
|
79
|
+
filename,
|
|
80
|
+
graph,
|
|
81
|
+
acc.visited,
|
|
82
|
+
new Set<string>(),
|
|
83
|
+
);
|
|
84
|
+
if (isCircular) {
|
|
85
|
+
acc.circularFiles.push(filename);
|
|
86
|
+
} else {
|
|
87
|
+
acc.safeFiles.push(filename);
|
|
88
|
+
}
|
|
89
|
+
acc.visited = updatedVisited;
|
|
90
|
+
return acc;
|
|
91
|
+
},
|
|
92
|
+
{ safeFiles: [], circularFiles: [], visited: new Set<string>() },
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
return { safeFiles, circularFiles };
|
|
96
|
+
};
|
|
11
97
|
|
|
12
98
|
const compileAll = async (parsedArgs: Opts): Promise<void> => {
|
|
13
99
|
let p: Promise<TableRow[]>[] = [];
|
|
14
100
|
|
|
15
101
|
const contractFilenames = await glob(
|
|
16
102
|
['**/*.ligo', '**/*.religo', '**/*.mligo', '**/*.jsligo'],
|
|
17
|
-
{
|
|
103
|
+
{
|
|
104
|
+
cwd: join(parsedArgs.config.projectDir, parsedArgs.config.contractsDir ?? 'contracts'),
|
|
105
|
+
absolute: false,
|
|
106
|
+
},
|
|
18
107
|
);
|
|
19
108
|
|
|
20
|
-
|
|
109
|
+
const dependencyGraph = await buildDependencyGraph(parsedArgs, contractFilenames);
|
|
110
|
+
const { safeFiles, circularFiles } = detectCircularDependencies(dependencyGraph);
|
|
111
|
+
|
|
112
|
+
for (const filename of safeFiles) {
|
|
21
113
|
if (await isMainContract(parsedArgs, filename)) {
|
|
22
114
|
p.push(compileContractWithStorageAndParameter(parsedArgs as CompileOpts, filename));
|
|
23
115
|
}
|
|
24
116
|
}
|
|
25
117
|
|
|
26
|
-
return Promise.all(p)
|
|
118
|
+
return Promise.all(p)
|
|
119
|
+
.then(tables => tables.flat())
|
|
120
|
+
.then(table => {
|
|
121
|
+
if (circularFiles.length > 0) {
|
|
122
|
+
console.warn(
|
|
123
|
+
'Warning: Circular dependencies detected in the following files. They have been skipped:',
|
|
124
|
+
);
|
|
125
|
+
console.warn(circularFiles.join(', '));
|
|
126
|
+
}
|
|
127
|
+
return table;
|
|
128
|
+
})
|
|
129
|
+
.then(sendJsonRes)
|
|
130
|
+
.catch(err => sendErr(err, false));
|
|
27
131
|
};
|
|
28
132
|
|
|
29
133
|
export default compileAll;
|
package/compile.ts
CHANGED
|
@@ -28,6 +28,15 @@ const isParameterListFile = (sourceFile: string): boolean =>
|
|
|
28
28
|
const isContractFile = (sourceFile: string): boolean =>
|
|
29
29
|
isLIGOFile(sourceFile) && !isStorageListFile(sourceFile) && !isParameterListFile(sourceFile);
|
|
30
30
|
|
|
31
|
+
const getModuleName = async (parsedArgs: Opts, sourceFile: string): Promise<string | undefined> => {
|
|
32
|
+
const fileContent = await readFile(getInputFilenameAbsPath(parsedArgs, sourceFile), 'utf8');
|
|
33
|
+
if (fileContent.includes('@entry') && fileContent.includes('module')) {
|
|
34
|
+
const match = fileContent.match(/module ([^\s]+)/);
|
|
35
|
+
return match ? match[1] : undefined;
|
|
36
|
+
}
|
|
37
|
+
return undefined;
|
|
38
|
+
};
|
|
39
|
+
|
|
31
40
|
const extractExt = (path: string): string => {
|
|
32
41
|
const matchResult = path.match(/\.(ligo|religo|mligo|jsligo)$/);
|
|
33
42
|
return matchResult ? matchResult[0] : '';
|
|
@@ -68,7 +77,7 @@ const getOutputExprFilename = (parsedArgs: Opts, sourceFile: string, exprKind: E
|
|
|
68
77
|
return join(getArtifactsDir(parsedArgs), `${outputFile}`);
|
|
69
78
|
};
|
|
70
79
|
|
|
71
|
-
const getCompileContractCmd = (parsedArgs: Opts, sourceFile: string): string => {
|
|
80
|
+
const getCompileContractCmd = async (parsedArgs: Opts, sourceFile: string): Promise<string> => {
|
|
72
81
|
const projectDir = process.env.PROJECT_DIR ?? parsedArgs.projectDir;
|
|
73
82
|
if (!projectDir) throw `No project directory provided`;
|
|
74
83
|
const baseCmd =
|
|
@@ -76,7 +85,9 @@ const getCompileContractCmd = (parsedArgs: Opts, sourceFile: string): string =>
|
|
|
76
85
|
const inputFile = getInputFilenameRelPath(parsedArgs, sourceFile);
|
|
77
86
|
const outputFile = `-o ${getOutputContractFilename(parsedArgs, sourceFile)}`;
|
|
78
87
|
const flags = isOutputFormatJSON(parsedArgs) ? ' --michelson-format json ' : '';
|
|
79
|
-
const
|
|
88
|
+
const moduleName = await getModuleName(parsedArgs, sourceFile);
|
|
89
|
+
const entryFlag = moduleName ? `-m ${moduleName}` : '';
|
|
90
|
+
const cmd = `${baseCmd} ${inputFile} ${outputFile} ${flags}${entryFlag}`;
|
|
80
91
|
return cmd;
|
|
81
92
|
};
|
|
82
93
|
|
|
@@ -93,24 +104,24 @@ const getCompileExprCmd = (parsedArgs: Opts, sourceFile: string, exprKind: ExprK
|
|
|
93
104
|
return cmd;
|
|
94
105
|
};
|
|
95
106
|
|
|
96
|
-
const compileContract = (parsedArgs: Opts, sourceFile: string): Promise<TableRow> =>
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
107
|
+
const compileContract = async (parsedArgs: Opts, sourceFile: string): Promise<TableRow> => {
|
|
108
|
+
try {
|
|
109
|
+
await getArch();
|
|
110
|
+
const cmd = await getCompileContractCmd(parsedArgs, sourceFile);
|
|
111
|
+
const { stderr } = await execCmd(cmd);
|
|
112
|
+
if (stderr.length > 0) sendWarn(stderr);
|
|
113
|
+
return {
|
|
114
|
+
contract: sourceFile,
|
|
115
|
+
artifact: getOutputContractFilename(parsedArgs, sourceFile),
|
|
116
|
+
};
|
|
117
|
+
} catch (err) {
|
|
118
|
+
emitExternalError(err, sourceFile);
|
|
119
|
+
return {
|
|
120
|
+
contract: sourceFile,
|
|
121
|
+
artifact: COMPILE_ERR_MSG,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
};
|
|
114
125
|
|
|
115
126
|
const compileExpr = (parsedArgs: Opts, sourceFile: string, exprKind: ExprKind) =>
|
|
116
127
|
(exprName: string): Promise<TableRow> =>
|
|
@@ -119,9 +130,10 @@ const compileExpr = (parsedArgs: Opts, sourceFile: string, exprKind: ExprKind) =
|
|
|
119
130
|
.then(execCmd)
|
|
120
131
|
.then(({ stderr }) => {
|
|
121
132
|
if (stderr.length > 0) sendWarn(stderr);
|
|
133
|
+
const artifactName = getOutputExprFilename(parsedArgs, sourceFile, exprKind, exprName);
|
|
122
134
|
return {
|
|
123
135
|
contract: sourceFile,
|
|
124
|
-
artifact:
|
|
136
|
+
artifact: artifactName,
|
|
125
137
|
};
|
|
126
138
|
})
|
|
127
139
|
.catch(err => {
|
|
@@ -152,9 +164,15 @@ const compileExprs = (parsedArgs: Opts, sourceFile: string, exprKind: ExprKind):
|
|
|
152
164
|
emitExternalError(err, sourceFile);
|
|
153
165
|
return [{
|
|
154
166
|
contract: sourceFile,
|
|
155
|
-
artifact: `No ${isStorageKind(exprKind) ? 'storage' : 'parameter'}
|
|
167
|
+
artifact: `No ${isStorageKind(exprKind) ? 'storage' : 'parameter'} expressions compiled`,
|
|
156
168
|
}];
|
|
157
169
|
})
|
|
170
|
+
.then(results =>
|
|
171
|
+
results.length > 0 ? results : [{
|
|
172
|
+
contract: sourceFile,
|
|
173
|
+
artifact: `No ${isStorageKind(exprKind) ? 'storage' : 'parameter'} expressions found`,
|
|
174
|
+
}]
|
|
175
|
+
)
|
|
158
176
|
.then(mergeArtifactsOutput(sourceFile));
|
|
159
177
|
|
|
160
178
|
// TODO: Just for backwards compatibility. Can be deleted in the future.
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -14,12 +14,16 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
14
14
|
return to;
|
|
15
15
|
};
|
|
16
16
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
17
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
18
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
19
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
20
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
17
21
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
18
22
|
mod
|
|
19
23
|
));
|
|
20
24
|
|
|
21
25
|
// index.ts
|
|
22
|
-
var
|
|
26
|
+
var import_node_sdk9 = require("@taqueria/node-sdk");
|
|
23
27
|
|
|
24
28
|
// createContract.ts
|
|
25
29
|
var import_node_sdk = require("@taqueria/node-sdk");
|
|
@@ -171,12 +175,12 @@ var createContract = (args) => {
|
|
|
171
175
|
var createContract_default = createContract;
|
|
172
176
|
|
|
173
177
|
// main.ts
|
|
174
|
-
var
|
|
178
|
+
var import_node_sdk8 = require("@taqueria/node-sdk");
|
|
175
179
|
|
|
176
180
|
// common.ts
|
|
177
181
|
var import_node_sdk2 = require("@taqueria/node-sdk");
|
|
178
182
|
var import_path = require("path");
|
|
179
|
-
var LIGO_DEFAULT_IMAGE = "ligolang/ligo:0.
|
|
183
|
+
var LIGO_DEFAULT_IMAGE = "ligolang/ligo:0.63.2";
|
|
180
184
|
var LIGO_IMAGE_ENV_VAR = "TAQ_LIGO_IMAGE";
|
|
181
185
|
var getLigoDockerImage = () => (0, import_node_sdk2.getDockerImage)(LIGO_DEFAULT_IMAGE, LIGO_IMAGE_ENV_VAR);
|
|
182
186
|
var getInputFilenameAbsPath = (parsedArgs, sourceFile) => (0, import_path.join)(parsedArgs.config.projectDir, parsedArgs.config.contractsDir ?? "contracts", sourceFile);
|
|
@@ -199,6 +203,14 @@ var isLIGOFile = (sourceFile) => /.+\.(ligo|religo|mligo|jsligo)$/.test(sourceFi
|
|
|
199
203
|
var isStorageListFile = (sourceFile) => /.+\.(storageList|storages)\.(ligo|religo|mligo|jsligo)$/.test(sourceFile);
|
|
200
204
|
var isParameterListFile = (sourceFile) => /.+\.(parameterList|parameters)\.(ligo|religo|mligo|jsligo)$/.test(sourceFile);
|
|
201
205
|
var isContractFile = (sourceFile) => isLIGOFile(sourceFile) && !isStorageListFile(sourceFile) && !isParameterListFile(sourceFile);
|
|
206
|
+
var getModuleName = async (parsedArgs, sourceFile) => {
|
|
207
|
+
const fileContent = await (0, import_promises2.readFile)(getInputFilenameAbsPath(parsedArgs, sourceFile), "utf8");
|
|
208
|
+
if (fileContent.includes("@entry") && fileContent.includes("module")) {
|
|
209
|
+
const match = fileContent.match(/module ([^\s]+)/);
|
|
210
|
+
return match ? match[1] : void 0;
|
|
211
|
+
}
|
|
212
|
+
return void 0;
|
|
213
|
+
};
|
|
202
214
|
var extractExt = (path) => {
|
|
203
215
|
const matchResult = path.match(/\.(ligo|religo|mligo|jsligo)$/);
|
|
204
216
|
return matchResult ? matchResult[0] : "";
|
|
@@ -226,7 +238,7 @@ var getOutputExprFilename = (parsedArgs, sourceFile, exprKind, exprName) => {
|
|
|
226
238
|
const outputFile = exprKind === "default_storage" ? `${contractName}.default_storage${ext}` : `${contractName}.${exprKind}.${exprName}${ext}`;
|
|
227
239
|
return (0, import_path2.join)((0, import_node_sdk3.getArtifactsDir)(parsedArgs), `${outputFile}`);
|
|
228
240
|
};
|
|
229
|
-
var getCompileContractCmd = (parsedArgs, sourceFile) => {
|
|
241
|
+
var getCompileContractCmd = async (parsedArgs, sourceFile) => {
|
|
230
242
|
const projectDir = process.env.PROJECT_DIR ?? parsedArgs.projectDir;
|
|
231
243
|
if (!projectDir)
|
|
232
244
|
throw `No project directory provided`;
|
|
@@ -234,7 +246,9 @@ var getCompileContractCmd = (parsedArgs, sourceFile) => {
|
|
|
234
246
|
const inputFile = getInputFilenameRelPath(parsedArgs, sourceFile);
|
|
235
247
|
const outputFile = `-o ${getOutputContractFilename(parsedArgs, sourceFile)}`;
|
|
236
248
|
const flags = isOutputFormatJSON(parsedArgs) ? " --michelson-format json " : "";
|
|
237
|
-
const
|
|
249
|
+
const moduleName = await getModuleName(parsedArgs, sourceFile);
|
|
250
|
+
const entryFlag = moduleName ? `-m ${moduleName}` : "";
|
|
251
|
+
const cmd = `${baseCmd} ${inputFile} ${outputFile} ${flags}${entryFlag}`;
|
|
238
252
|
return cmd;
|
|
239
253
|
};
|
|
240
254
|
var getCompileExprCmd = (parsedArgs, sourceFile, exprKind, exprName) => {
|
|
@@ -249,26 +263,32 @@ var getCompileExprCmd = (parsedArgs, sourceFile, exprKind, exprName) => {
|
|
|
249
263
|
const cmd = `${baseCmd} ${inputFile} ${exprName} ${outputFile} ${flags}`;
|
|
250
264
|
return cmd;
|
|
251
265
|
};
|
|
252
|
-
var compileContract =
|
|
253
|
-
|
|
254
|
-
(0, import_node_sdk3.
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
+
var compileContract = async (parsedArgs, sourceFile) => {
|
|
267
|
+
try {
|
|
268
|
+
await (0, import_node_sdk3.getArch)();
|
|
269
|
+
const cmd = await getCompileContractCmd(parsedArgs, sourceFile);
|
|
270
|
+
const { stderr } = await (0, import_node_sdk3.execCmd)(cmd);
|
|
271
|
+
if (stderr.length > 0)
|
|
272
|
+
(0, import_node_sdk3.sendWarn)(stderr);
|
|
273
|
+
return {
|
|
274
|
+
contract: sourceFile,
|
|
275
|
+
artifact: getOutputContractFilename(parsedArgs, sourceFile)
|
|
276
|
+
};
|
|
277
|
+
} catch (err) {
|
|
278
|
+
emitExternalError(err, sourceFile);
|
|
279
|
+
return {
|
|
280
|
+
contract: sourceFile,
|
|
281
|
+
artifact: COMPILE_ERR_MSG
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
};
|
|
266
285
|
var compileExpr = (parsedArgs, sourceFile, exprKind) => (exprName) => (0, import_node_sdk3.getArch)().then(() => getCompileExprCmd(parsedArgs, sourceFile, exprKind, exprName)).then(import_node_sdk3.execCmd).then(({ stderr }) => {
|
|
267
286
|
if (stderr.length > 0)
|
|
268
287
|
(0, import_node_sdk3.sendWarn)(stderr);
|
|
288
|
+
const artifactName = getOutputExprFilename(parsedArgs, sourceFile, exprKind, exprName);
|
|
269
289
|
return {
|
|
270
290
|
contract: sourceFile,
|
|
271
|
-
artifact:
|
|
291
|
+
artifact: artifactName
|
|
272
292
|
};
|
|
273
293
|
}).catch((err) => {
|
|
274
294
|
emitExternalError(err, sourceFile);
|
|
@@ -292,9 +312,14 @@ var compileExprs = (parsedArgs, sourceFile, exprKind) => getExprNames(parsedArgs
|
|
|
292
312
|
emitExternalError(err, sourceFile);
|
|
293
313
|
return [{
|
|
294
314
|
contract: sourceFile,
|
|
295
|
-
artifact: `No ${isStorageKind(exprKind) ? "storage" : "parameter"}
|
|
315
|
+
artifact: `No ${isStorageKind(exprKind) ? "storage" : "parameter"} expressions compiled`
|
|
296
316
|
}];
|
|
297
|
-
}).then(
|
|
317
|
+
}).then(
|
|
318
|
+
(results) => results.length > 0 ? results : [{
|
|
319
|
+
contract: sourceFile,
|
|
320
|
+
artifact: `No ${isStorageKind(exprKind) ? "storage" : "parameter"} expressions found`
|
|
321
|
+
}]
|
|
322
|
+
).then(mergeArtifactsOutput(sourceFile));
|
|
298
323
|
var tryLegacyStorageNamingConvention = (parsedArgs, sourceFile) => {
|
|
299
324
|
const storageListFile = `${removeExt(sourceFile)}.storages${extractExt(sourceFile)}`;
|
|
300
325
|
const storageListFilename = getInputFilenameAbsPath(parsedArgs, storageListFile);
|
|
@@ -414,29 +439,106 @@ var import_node_sdk4 = require("@taqueria/node-sdk");
|
|
|
414
439
|
var import_fast_glob = __toESM(require("fast-glob"));
|
|
415
440
|
var import_promises3 = require("fs/promises");
|
|
416
441
|
var import_path3 = require("path");
|
|
417
|
-
var isMainContract =
|
|
442
|
+
var isMainContract = async (parsedArgs, contractFilename) => {
|
|
443
|
+
const fileContent = await (0, import_promises3.readFile)(getInputFilenameAbsPath(parsedArgs, contractFilename), "utf8");
|
|
444
|
+
const entryOrMainFunctionRegex = /@entry|((const|let|function)\s+main)/g;
|
|
445
|
+
return entryOrMainFunctionRegex.test(fileContent);
|
|
446
|
+
};
|
|
447
|
+
var parseIncludes = async (parsedArgs, contractFilename) => {
|
|
448
|
+
const fileContent = await (0, import_promises3.readFile)(getInputFilenameAbsPath(parsedArgs, contractFilename), "utf8");
|
|
449
|
+
const includeRegex = /#include\s+"([^"]+\.m?ligo)"/g;
|
|
450
|
+
let match;
|
|
451
|
+
const includes = [];
|
|
452
|
+
while ((match = includeRegex.exec(fileContent)) !== null) {
|
|
453
|
+
includes.push(match[1]);
|
|
454
|
+
}
|
|
455
|
+
return includes;
|
|
456
|
+
};
|
|
457
|
+
var buildDependencyGraph = async (parsedArgs, contractFilenames) => {
|
|
458
|
+
const graph = /* @__PURE__ */ new Map();
|
|
459
|
+
for (const filename of contractFilenames) {
|
|
460
|
+
const includes = await parseIncludes(parsedArgs, filename);
|
|
461
|
+
graph.set(filename, new Set(includes));
|
|
462
|
+
}
|
|
463
|
+
return graph;
|
|
464
|
+
};
|
|
465
|
+
var visit = (node, graph, visited, stack) => {
|
|
466
|
+
if (stack.has(node))
|
|
467
|
+
return [true, visited];
|
|
468
|
+
if (!visited.has(node)) {
|
|
469
|
+
const newVisited = new Set(visited).add(node);
|
|
470
|
+
const newStack = new Set(stack).add(node);
|
|
471
|
+
const [circular, updatedVisited] = Array.from(graph.get(node) || []).reduce(
|
|
472
|
+
([circularFound, vSet], dependency) => {
|
|
473
|
+
const [result, v] = visit(dependency, graph, vSet, newStack);
|
|
474
|
+
return [circularFound || result, v];
|
|
475
|
+
},
|
|
476
|
+
[false, newVisited]
|
|
477
|
+
);
|
|
478
|
+
if (!circular)
|
|
479
|
+
return [false, updatedVisited];
|
|
480
|
+
}
|
|
481
|
+
return [false, visited];
|
|
482
|
+
};
|
|
483
|
+
var detectCircularDependencies = (graph) => {
|
|
484
|
+
const { safeFiles, circularFiles, visited } = Array.from(graph.keys()).reduce(
|
|
485
|
+
(acc, filename) => {
|
|
486
|
+
const [isCircular, updatedVisited] = visit(
|
|
487
|
+
filename,
|
|
488
|
+
graph,
|
|
489
|
+
acc.visited,
|
|
490
|
+
/* @__PURE__ */ new Set()
|
|
491
|
+
);
|
|
492
|
+
if (isCircular) {
|
|
493
|
+
acc.circularFiles.push(filename);
|
|
494
|
+
} else {
|
|
495
|
+
acc.safeFiles.push(filename);
|
|
496
|
+
}
|
|
497
|
+
acc.visited = updatedVisited;
|
|
498
|
+
return acc;
|
|
499
|
+
},
|
|
500
|
+
{ safeFiles: [], circularFiles: [], visited: /* @__PURE__ */ new Set() }
|
|
501
|
+
);
|
|
502
|
+
return { safeFiles, circularFiles };
|
|
503
|
+
};
|
|
418
504
|
var compileAll = async (parsedArgs) => {
|
|
419
505
|
let p = [];
|
|
420
506
|
const contractFilenames = await (0, import_fast_glob.default)(
|
|
421
507
|
["**/*.ligo", "**/*.religo", "**/*.mligo", "**/*.jsligo"],
|
|
422
|
-
{
|
|
508
|
+
{
|
|
509
|
+
cwd: (0, import_path3.join)(parsedArgs.config.projectDir, parsedArgs.config.contractsDir ?? "contracts"),
|
|
510
|
+
absolute: false
|
|
511
|
+
}
|
|
423
512
|
);
|
|
424
|
-
|
|
513
|
+
const dependencyGraph = await buildDependencyGraph(parsedArgs, contractFilenames);
|
|
514
|
+
const { safeFiles, circularFiles } = detectCircularDependencies(dependencyGraph);
|
|
515
|
+
for (const filename of safeFiles) {
|
|
425
516
|
if (await isMainContract(parsedArgs, filename)) {
|
|
426
517
|
p.push(compileContractWithStorageAndParameter(parsedArgs, filename));
|
|
427
518
|
}
|
|
428
519
|
}
|
|
429
|
-
return Promise.all(p).then((tables) => tables.flat()).then(
|
|
520
|
+
return Promise.all(p).then((tables) => tables.flat()).then((table) => {
|
|
521
|
+
if (circularFiles.length > 0) {
|
|
522
|
+
console.warn(
|
|
523
|
+
"Warning: Circular dependencies detected in the following files. They have been skipped:"
|
|
524
|
+
);
|
|
525
|
+
console.warn(circularFiles.join(", "));
|
|
526
|
+
}
|
|
527
|
+
return table;
|
|
528
|
+
}).then(import_node_sdk4.sendJsonRes).catch((err) => (0, import_node_sdk4.sendErr)(err, false));
|
|
430
529
|
};
|
|
431
530
|
var compile_all_default = compileAll;
|
|
432
531
|
|
|
433
532
|
// ligo.ts
|
|
434
533
|
var import_node_sdk5 = require("@taqueria/node-sdk");
|
|
435
|
-
var
|
|
534
|
+
var import_node_sdk6 = require("@taqueria/node-sdk");
|
|
535
|
+
var import_path4 = require("path");
|
|
536
|
+
var getArbitraryLigoCmd = (parsedArgs, uid, gid, userArgs) => {
|
|
436
537
|
const projectDir = process.env.PROJECT_DIR ?? parsedArgs.projectDir;
|
|
437
538
|
if (!projectDir)
|
|
438
539
|
throw `No project directory provided`;
|
|
439
|
-
const
|
|
540
|
+
const userMap = uid && gid ? `${uid}:${gid}` : uid;
|
|
541
|
+
const userMapArgs = uid ? ["-u", userMap] : [];
|
|
440
542
|
const binary = "docker";
|
|
441
543
|
const baseArgs = [
|
|
442
544
|
"run",
|
|
@@ -445,8 +547,7 @@ var getArbitraryLigoCmd = (parsedArgs, userArgs) => {
|
|
|
445
547
|
`${projectDir}:/project`,
|
|
446
548
|
"-w",
|
|
447
549
|
"/project",
|
|
448
|
-
|
|
449
|
-
owner,
|
|
550
|
+
...userMapArgs,
|
|
450
551
|
getLigoDockerImage()
|
|
451
552
|
];
|
|
452
553
|
const processedUserArgs = userArgs.split(" ").map((arg) => arg.startsWith("\\-") ? arg.substring(1) : arg).filter(
|
|
@@ -459,7 +560,19 @@ var getArbitraryLigoCmd = (parsedArgs, userArgs) => {
|
|
|
459
560
|
envVars
|
|
460
561
|
];
|
|
461
562
|
};
|
|
462
|
-
var
|
|
563
|
+
var ensureEsyExists = async (parsedArgs) => {
|
|
564
|
+
const esyJsonPath = (0, import_path4.join)(parsedArgs.projectDir, "esy.json");
|
|
565
|
+
try {
|
|
566
|
+
return await (0, import_node_sdk6.readJsonFile)(esyJsonPath);
|
|
567
|
+
} catch {
|
|
568
|
+
return await (0, import_node_sdk6.writeJsonFile)(esyJsonPath)({});
|
|
569
|
+
}
|
|
570
|
+
};
|
|
571
|
+
var runArbitraryLigoCmd = (parsedArgs, cmd) => ensureEsyExists(parsedArgs).then(import_node_sdk5.getArch).then(async () => {
|
|
572
|
+
const uid = await (0, import_node_sdk5.execCmd)("id -u");
|
|
573
|
+
const gid = await (0, import_node_sdk5.execCmd)("id -g");
|
|
574
|
+
return [uid.stdout.trim(), gid.stdout.trim()];
|
|
575
|
+
}).then(([uid, gid]) => getArbitraryLigoCmd(parsedArgs, uid, gid, cmd)).then(([cmd2, envVars]) => (0, import_node_sdk5.spawnCmd)(cmd2, envVars)).then(
|
|
463
576
|
(code) => code !== null && code === 0 ? `Command "${cmd}" ran successfully by LIGO` : `Command "${cmd}" failed. Please check your command`
|
|
464
577
|
).catch((err) => (0, import_node_sdk5.sendAsyncErr)(`An internal error has occurred: ${err.message}`));
|
|
465
578
|
var ligo = (parsedArgs) => {
|
|
@@ -469,7 +582,7 @@ var ligo = (parsedArgs) => {
|
|
|
469
582
|
var ligo_default = ligo;
|
|
470
583
|
|
|
471
584
|
// test.ts
|
|
472
|
-
var
|
|
585
|
+
var import_node_sdk7 = require("@taqueria/node-sdk");
|
|
473
586
|
var getTestContractCmd = (parsedArgs, sourceFile) => {
|
|
474
587
|
const projectDir = process.env.PROJECT_DIR ?? parsedArgs.projectDir;
|
|
475
588
|
if (!projectDir)
|
|
@@ -479,9 +592,9 @@ var getTestContractCmd = (parsedArgs, sourceFile) => {
|
|
|
479
592
|
const cmd = `${baseCmd} ${inputFile}`;
|
|
480
593
|
return cmd;
|
|
481
594
|
};
|
|
482
|
-
var testContract = (parsedArgs, sourceFile) => (0,
|
|
595
|
+
var testContract = (parsedArgs, sourceFile) => (0, import_node_sdk7.getArch)().then(() => getTestContractCmd(parsedArgs, sourceFile)).then(import_node_sdk7.execCmd).then(({ stdout, stderr }) => {
|
|
483
596
|
if (stderr.length > 0)
|
|
484
|
-
(0,
|
|
597
|
+
(0, import_node_sdk7.sendWarn)(stderr);
|
|
485
598
|
const result = "\u{1F389} All tests passed \u{1F389}";
|
|
486
599
|
return {
|
|
487
600
|
contract: sourceFile,
|
|
@@ -498,9 +611,9 @@ ${result}` : result
|
|
|
498
611
|
var test = (parsedArgs) => {
|
|
499
612
|
const sourceFile = parsedArgs.sourceFile;
|
|
500
613
|
if (!sourceFile)
|
|
501
|
-
return (0,
|
|
502
|
-
return testContract(parsedArgs, sourceFile).then((result) => [result]).then(
|
|
503
|
-
(err) => (0,
|
|
614
|
+
return (0, import_node_sdk7.sendAsyncErr)(`No source file provided`);
|
|
615
|
+
return testContract(parsedArgs, sourceFile).then((result) => [result]).then(import_node_sdk7.sendJsonRes).catch(
|
|
616
|
+
(err) => (0, import_node_sdk7.sendAsyncErr)(err, false)
|
|
504
617
|
);
|
|
505
618
|
};
|
|
506
619
|
var test_default = test;
|
|
@@ -518,25 +631,25 @@ var main = (parsedArgs) => {
|
|
|
518
631
|
case "test":
|
|
519
632
|
return test_default(parsedArgs);
|
|
520
633
|
case "get-image":
|
|
521
|
-
return (0,
|
|
634
|
+
return (0, import_node_sdk8.sendAsyncRes)(getLigoDockerImage());
|
|
522
635
|
default:
|
|
523
|
-
return (0,
|
|
636
|
+
return (0, import_node_sdk8.sendAsyncErr)(`${unsafeOpts.task} is not an understood task by the LIGO plugin`);
|
|
524
637
|
}
|
|
525
638
|
};
|
|
526
639
|
var main_default = main;
|
|
527
640
|
|
|
528
641
|
// index.ts
|
|
529
|
-
|
|
642
|
+
import_node_sdk9.Plugin.create((i18n) => ({
|
|
530
643
|
schema: "1.0",
|
|
531
644
|
version: "0.1",
|
|
532
645
|
alias: "ligo",
|
|
533
646
|
tasks: [
|
|
534
|
-
|
|
647
|
+
import_node_sdk9.Task.create({
|
|
535
648
|
task: "ligo",
|
|
536
649
|
command: "ligo",
|
|
537
650
|
description: "This task allows you to run arbitrary LIGO native commands. Note that they might not benefit from the abstractions provided by Taqueria",
|
|
538
651
|
options: [
|
|
539
|
-
|
|
652
|
+
import_node_sdk9.Option.create({
|
|
540
653
|
shortFlag: "c",
|
|
541
654
|
flag: "command",
|
|
542
655
|
type: "string",
|
|
@@ -547,13 +660,13 @@ import_node_sdk8.Plugin.create((i18n) => ({
|
|
|
547
660
|
handler: "proxy",
|
|
548
661
|
encoding: "none"
|
|
549
662
|
}),
|
|
550
|
-
|
|
663
|
+
import_node_sdk9.Task.create({
|
|
551
664
|
task: "compile",
|
|
552
665
|
command: "compile <sourceFile>",
|
|
553
666
|
aliases: ["c", "compile-ligo"],
|
|
554
667
|
description: "Compile a smart contract written in a LIGO syntax to Michelson code, along with its associated storage/parameter list files if they are found",
|
|
555
668
|
options: [
|
|
556
|
-
|
|
669
|
+
import_node_sdk9.Option.create({
|
|
557
670
|
flag: "json",
|
|
558
671
|
boolean: true,
|
|
559
672
|
description: "Emit JSON-encoded Michelson"
|
|
@@ -562,12 +675,12 @@ import_node_sdk8.Plugin.create((i18n) => ({
|
|
|
562
675
|
handler: "proxy",
|
|
563
676
|
encoding: "json"
|
|
564
677
|
}),
|
|
565
|
-
|
|
678
|
+
import_node_sdk9.Task.create({
|
|
566
679
|
task: "compile-all",
|
|
567
680
|
command: "compile-all",
|
|
568
681
|
description: "Compile all main smart contracts written in a LIGO syntax to Michelson code, along with their associated storage/parameter list files if they are found",
|
|
569
682
|
options: [
|
|
570
|
-
|
|
683
|
+
import_node_sdk9.Option.create({
|
|
571
684
|
flag: "json",
|
|
572
685
|
boolean: true,
|
|
573
686
|
description: "Emit JSON-encoded Michelson"
|
|
@@ -576,14 +689,14 @@ import_node_sdk8.Plugin.create((i18n) => ({
|
|
|
576
689
|
handler: "proxy",
|
|
577
690
|
encoding: "json"
|
|
578
691
|
}),
|
|
579
|
-
|
|
692
|
+
import_node_sdk9.Task.create({
|
|
580
693
|
task: "test",
|
|
581
694
|
command: "test <sourceFile>",
|
|
582
695
|
description: "Test a smart contract written in LIGO",
|
|
583
696
|
handler: "proxy",
|
|
584
697
|
encoding: "json"
|
|
585
698
|
}),
|
|
586
|
-
|
|
699
|
+
import_node_sdk9.Task.create({
|
|
587
700
|
task: "get-image",
|
|
588
701
|
command: "get-image",
|
|
589
702
|
description: "Gets the name of the image to be used",
|
|
@@ -592,19 +705,19 @@ import_node_sdk8.Plugin.create((i18n) => ({
|
|
|
592
705
|
})
|
|
593
706
|
],
|
|
594
707
|
templates: [
|
|
595
|
-
|
|
708
|
+
import_node_sdk9.Template.create({
|
|
596
709
|
template: "contract",
|
|
597
710
|
command: "contract <sourceFileName>",
|
|
598
711
|
description: "Create a LIGO contract with boilerplate code",
|
|
599
712
|
positionals: [
|
|
600
|
-
|
|
713
|
+
import_node_sdk9.PositionalArg.create({
|
|
601
714
|
placeholder: "sourceFileName",
|
|
602
715
|
type: "string",
|
|
603
716
|
description: "The name of the LIGO contract to generate"
|
|
604
717
|
})
|
|
605
718
|
],
|
|
606
719
|
options: [
|
|
607
|
-
|
|
720
|
+
import_node_sdk9.Option.create({
|
|
608
721
|
shortFlag: "s",
|
|
609
722
|
flag: "syntax",
|
|
610
723
|
type: "string",
|