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