@taqueria/plugin-ligo 0.28.5 → 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/compile-all.ts +110 -6
- package/compile.ts +40 -22
- package/index.js +151 -46
- package/index.js.map +1 -1
- package/index.mjs +129 -24
- package/index.mjs.map +1 -1
- package/ligo.ts +14 -1
- package/package.json +2 -2
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.js
CHANGED
|
@@ -23,7 +23,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
23
23
|
));
|
|
24
24
|
|
|
25
25
|
// index.ts
|
|
26
|
-
var
|
|
26
|
+
var import_node_sdk9 = require("@taqueria/node-sdk");
|
|
27
27
|
|
|
28
28
|
// createContract.ts
|
|
29
29
|
var import_node_sdk = require("@taqueria/node-sdk");
|
|
@@ -175,7 +175,7 @@ var createContract = (args) => {
|
|
|
175
175
|
var createContract_default = createContract;
|
|
176
176
|
|
|
177
177
|
// main.ts
|
|
178
|
-
var
|
|
178
|
+
var import_node_sdk8 = require("@taqueria/node-sdk");
|
|
179
179
|
|
|
180
180
|
// common.ts
|
|
181
181
|
var import_node_sdk2 = require("@taqueria/node-sdk");
|
|
@@ -203,6 +203,14 @@ var isLIGOFile = (sourceFile) => /.+\.(ligo|religo|mligo|jsligo)$/.test(sourceFi
|
|
|
203
203
|
var isStorageListFile = (sourceFile) => /.+\.(storageList|storages)\.(ligo|religo|mligo|jsligo)$/.test(sourceFile);
|
|
204
204
|
var isParameterListFile = (sourceFile) => /.+\.(parameterList|parameters)\.(ligo|religo|mligo|jsligo)$/.test(sourceFile);
|
|
205
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
|
+
};
|
|
206
214
|
var extractExt = (path) => {
|
|
207
215
|
const matchResult = path.match(/\.(ligo|religo|mligo|jsligo)$/);
|
|
208
216
|
return matchResult ? matchResult[0] : "";
|
|
@@ -230,7 +238,7 @@ var getOutputExprFilename = (parsedArgs, sourceFile, exprKind, exprName) => {
|
|
|
230
238
|
const outputFile = exprKind === "default_storage" ? `${contractName}.default_storage${ext}` : `${contractName}.${exprKind}.${exprName}${ext}`;
|
|
231
239
|
return (0, import_path2.join)((0, import_node_sdk3.getArtifactsDir)(parsedArgs), `${outputFile}`);
|
|
232
240
|
};
|
|
233
|
-
var getCompileContractCmd = (parsedArgs, sourceFile) => {
|
|
241
|
+
var getCompileContractCmd = async (parsedArgs, sourceFile) => {
|
|
234
242
|
const projectDir = process.env.PROJECT_DIR ?? parsedArgs.projectDir;
|
|
235
243
|
if (!projectDir)
|
|
236
244
|
throw `No project directory provided`;
|
|
@@ -238,7 +246,9 @@ var getCompileContractCmd = (parsedArgs, sourceFile) => {
|
|
|
238
246
|
const inputFile = getInputFilenameRelPath(parsedArgs, sourceFile);
|
|
239
247
|
const outputFile = `-o ${getOutputContractFilename(parsedArgs, sourceFile)}`;
|
|
240
248
|
const flags = isOutputFormatJSON(parsedArgs) ? " --michelson-format json " : "";
|
|
241
|
-
const
|
|
249
|
+
const moduleName = await getModuleName(parsedArgs, sourceFile);
|
|
250
|
+
const entryFlag = moduleName ? `-m ${moduleName}` : "";
|
|
251
|
+
const cmd = `${baseCmd} ${inputFile} ${outputFile} ${flags}${entryFlag}`;
|
|
242
252
|
return cmd;
|
|
243
253
|
};
|
|
244
254
|
var getCompileExprCmd = (parsedArgs, sourceFile, exprKind, exprName) => {
|
|
@@ -253,26 +263,32 @@ var getCompileExprCmd = (parsedArgs, sourceFile, exprKind, exprName) => {
|
|
|
253
263
|
const cmd = `${baseCmd} ${inputFile} ${exprName} ${outputFile} ${flags}`;
|
|
254
264
|
return cmd;
|
|
255
265
|
};
|
|
256
|
-
var compileContract =
|
|
257
|
-
|
|
258
|
-
(0, import_node_sdk3.
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
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
|
+
};
|
|
270
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 }) => {
|
|
271
286
|
if (stderr.length > 0)
|
|
272
287
|
(0, import_node_sdk3.sendWarn)(stderr);
|
|
288
|
+
const artifactName = getOutputExprFilename(parsedArgs, sourceFile, exprKind, exprName);
|
|
273
289
|
return {
|
|
274
290
|
contract: sourceFile,
|
|
275
|
-
artifact:
|
|
291
|
+
artifact: artifactName
|
|
276
292
|
};
|
|
277
293
|
}).catch((err) => {
|
|
278
294
|
emitExternalError(err, sourceFile);
|
|
@@ -296,9 +312,14 @@ var compileExprs = (parsedArgs, sourceFile, exprKind) => getExprNames(parsedArgs
|
|
|
296
312
|
emitExternalError(err, sourceFile);
|
|
297
313
|
return [{
|
|
298
314
|
contract: sourceFile,
|
|
299
|
-
artifact: `No ${isStorageKind(exprKind) ? "storage" : "parameter"}
|
|
315
|
+
artifact: `No ${isStorageKind(exprKind) ? "storage" : "parameter"} expressions compiled`
|
|
300
316
|
}];
|
|
301
|
-
}).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));
|
|
302
323
|
var tryLegacyStorageNamingConvention = (parsedArgs, sourceFile) => {
|
|
303
324
|
const storageListFile = `${removeExt(sourceFile)}.storages${extractExt(sourceFile)}`;
|
|
304
325
|
const storageListFilename = getInputFilenameAbsPath(parsedArgs, storageListFile);
|
|
@@ -418,24 +439,100 @@ var import_node_sdk4 = require("@taqueria/node-sdk");
|
|
|
418
439
|
var import_fast_glob = __toESM(require("fast-glob"));
|
|
419
440
|
var import_promises3 = require("fs/promises");
|
|
420
441
|
var import_path3 = require("path");
|
|
421
|
-
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
|
+
};
|
|
422
504
|
var compileAll = async (parsedArgs) => {
|
|
423
505
|
let p = [];
|
|
424
506
|
const contractFilenames = await (0, import_fast_glob.default)(
|
|
425
507
|
["**/*.ligo", "**/*.religo", "**/*.mligo", "**/*.jsligo"],
|
|
426
|
-
{
|
|
508
|
+
{
|
|
509
|
+
cwd: (0, import_path3.join)(parsedArgs.config.projectDir, parsedArgs.config.contractsDir ?? "contracts"),
|
|
510
|
+
absolute: false
|
|
511
|
+
}
|
|
427
512
|
);
|
|
428
|
-
|
|
513
|
+
const dependencyGraph = await buildDependencyGraph(parsedArgs, contractFilenames);
|
|
514
|
+
const { safeFiles, circularFiles } = detectCircularDependencies(dependencyGraph);
|
|
515
|
+
for (const filename of safeFiles) {
|
|
429
516
|
if (await isMainContract(parsedArgs, filename)) {
|
|
430
517
|
p.push(compileContractWithStorageAndParameter(parsedArgs, filename));
|
|
431
518
|
}
|
|
432
519
|
}
|
|
433
|
-
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));
|
|
434
529
|
};
|
|
435
530
|
var compile_all_default = compileAll;
|
|
436
531
|
|
|
437
532
|
// ligo.ts
|
|
438
533
|
var import_node_sdk5 = require("@taqueria/node-sdk");
|
|
534
|
+
var import_node_sdk6 = require("@taqueria/node-sdk");
|
|
535
|
+
var import_path4 = require("path");
|
|
439
536
|
var getArbitraryLigoCmd = (parsedArgs, uid, gid, userArgs) => {
|
|
440
537
|
const projectDir = process.env.PROJECT_DIR ?? parsedArgs.projectDir;
|
|
441
538
|
if (!projectDir)
|
|
@@ -463,7 +560,15 @@ var getArbitraryLigoCmd = (parsedArgs, uid, gid, userArgs) => {
|
|
|
463
560
|
envVars
|
|
464
561
|
];
|
|
465
562
|
};
|
|
466
|
-
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 () => {
|
|
467
572
|
const uid = await (0, import_node_sdk5.execCmd)("id -u");
|
|
468
573
|
const gid = await (0, import_node_sdk5.execCmd)("id -g");
|
|
469
574
|
return [uid.stdout.trim(), gid.stdout.trim()];
|
|
@@ -477,7 +582,7 @@ var ligo = (parsedArgs) => {
|
|
|
477
582
|
var ligo_default = ligo;
|
|
478
583
|
|
|
479
584
|
// test.ts
|
|
480
|
-
var
|
|
585
|
+
var import_node_sdk7 = require("@taqueria/node-sdk");
|
|
481
586
|
var getTestContractCmd = (parsedArgs, sourceFile) => {
|
|
482
587
|
const projectDir = process.env.PROJECT_DIR ?? parsedArgs.projectDir;
|
|
483
588
|
if (!projectDir)
|
|
@@ -487,9 +592,9 @@ var getTestContractCmd = (parsedArgs, sourceFile) => {
|
|
|
487
592
|
const cmd = `${baseCmd} ${inputFile}`;
|
|
488
593
|
return cmd;
|
|
489
594
|
};
|
|
490
|
-
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 }) => {
|
|
491
596
|
if (stderr.length > 0)
|
|
492
|
-
(0,
|
|
597
|
+
(0, import_node_sdk7.sendWarn)(stderr);
|
|
493
598
|
const result = "\u{1F389} All tests passed \u{1F389}";
|
|
494
599
|
return {
|
|
495
600
|
contract: sourceFile,
|
|
@@ -506,9 +611,9 @@ ${result}` : result
|
|
|
506
611
|
var test = (parsedArgs) => {
|
|
507
612
|
const sourceFile = parsedArgs.sourceFile;
|
|
508
613
|
if (!sourceFile)
|
|
509
|
-
return (0,
|
|
510
|
-
return testContract(parsedArgs, sourceFile).then((result) => [result]).then(
|
|
511
|
-
(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)
|
|
512
617
|
);
|
|
513
618
|
};
|
|
514
619
|
var test_default = test;
|
|
@@ -526,25 +631,25 @@ var main = (parsedArgs) => {
|
|
|
526
631
|
case "test":
|
|
527
632
|
return test_default(parsedArgs);
|
|
528
633
|
case "get-image":
|
|
529
|
-
return (0,
|
|
634
|
+
return (0, import_node_sdk8.sendAsyncRes)(getLigoDockerImage());
|
|
530
635
|
default:
|
|
531
|
-
return (0,
|
|
636
|
+
return (0, import_node_sdk8.sendAsyncErr)(`${unsafeOpts.task} is not an understood task by the LIGO plugin`);
|
|
532
637
|
}
|
|
533
638
|
};
|
|
534
639
|
var main_default = main;
|
|
535
640
|
|
|
536
641
|
// index.ts
|
|
537
|
-
|
|
642
|
+
import_node_sdk9.Plugin.create((i18n) => ({
|
|
538
643
|
schema: "1.0",
|
|
539
644
|
version: "0.1",
|
|
540
645
|
alias: "ligo",
|
|
541
646
|
tasks: [
|
|
542
|
-
|
|
647
|
+
import_node_sdk9.Task.create({
|
|
543
648
|
task: "ligo",
|
|
544
649
|
command: "ligo",
|
|
545
650
|
description: "This task allows you to run arbitrary LIGO native commands. Note that they might not benefit from the abstractions provided by Taqueria",
|
|
546
651
|
options: [
|
|
547
|
-
|
|
652
|
+
import_node_sdk9.Option.create({
|
|
548
653
|
shortFlag: "c",
|
|
549
654
|
flag: "command",
|
|
550
655
|
type: "string",
|
|
@@ -555,13 +660,13 @@ import_node_sdk8.Plugin.create((i18n) => ({
|
|
|
555
660
|
handler: "proxy",
|
|
556
661
|
encoding: "none"
|
|
557
662
|
}),
|
|
558
|
-
|
|
663
|
+
import_node_sdk9.Task.create({
|
|
559
664
|
task: "compile",
|
|
560
665
|
command: "compile <sourceFile>",
|
|
561
666
|
aliases: ["c", "compile-ligo"],
|
|
562
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",
|
|
563
668
|
options: [
|
|
564
|
-
|
|
669
|
+
import_node_sdk9.Option.create({
|
|
565
670
|
flag: "json",
|
|
566
671
|
boolean: true,
|
|
567
672
|
description: "Emit JSON-encoded Michelson"
|
|
@@ -570,12 +675,12 @@ import_node_sdk8.Plugin.create((i18n) => ({
|
|
|
570
675
|
handler: "proxy",
|
|
571
676
|
encoding: "json"
|
|
572
677
|
}),
|
|
573
|
-
|
|
678
|
+
import_node_sdk9.Task.create({
|
|
574
679
|
task: "compile-all",
|
|
575
680
|
command: "compile-all",
|
|
576
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",
|
|
577
682
|
options: [
|
|
578
|
-
|
|
683
|
+
import_node_sdk9.Option.create({
|
|
579
684
|
flag: "json",
|
|
580
685
|
boolean: true,
|
|
581
686
|
description: "Emit JSON-encoded Michelson"
|
|
@@ -584,14 +689,14 @@ import_node_sdk8.Plugin.create((i18n) => ({
|
|
|
584
689
|
handler: "proxy",
|
|
585
690
|
encoding: "json"
|
|
586
691
|
}),
|
|
587
|
-
|
|
692
|
+
import_node_sdk9.Task.create({
|
|
588
693
|
task: "test",
|
|
589
694
|
command: "test <sourceFile>",
|
|
590
695
|
description: "Test a smart contract written in LIGO",
|
|
591
696
|
handler: "proxy",
|
|
592
697
|
encoding: "json"
|
|
593
698
|
}),
|
|
594
|
-
|
|
699
|
+
import_node_sdk9.Task.create({
|
|
595
700
|
task: "get-image",
|
|
596
701
|
command: "get-image",
|
|
597
702
|
description: "Gets the name of the image to be used",
|
|
@@ -600,19 +705,19 @@ import_node_sdk8.Plugin.create((i18n) => ({
|
|
|
600
705
|
})
|
|
601
706
|
],
|
|
602
707
|
templates: [
|
|
603
|
-
|
|
708
|
+
import_node_sdk9.Template.create({
|
|
604
709
|
template: "contract",
|
|
605
710
|
command: "contract <sourceFileName>",
|
|
606
711
|
description: "Create a LIGO contract with boilerplate code",
|
|
607
712
|
positionals: [
|
|
608
|
-
|
|
713
|
+
import_node_sdk9.PositionalArg.create({
|
|
609
714
|
placeholder: "sourceFileName",
|
|
610
715
|
type: "string",
|
|
611
716
|
description: "The name of the LIGO contract to generate"
|
|
612
717
|
})
|
|
613
718
|
],
|
|
614
719
|
options: [
|
|
615
|
-
|
|
720
|
+
import_node_sdk9.Option.create({
|
|
616
721
|
shortFlag: "s",
|
|
617
722
|
flag: "syntax",
|
|
618
723
|
type: "string",
|