@vm0/cli 1.16.0 → 3.0.0
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/index.js +217 -152
- package/package.json +2 -2
package/index.js
CHANGED
|
@@ -12488,44 +12488,56 @@ function validateAgentConfig(config2) {
|
|
|
12488
12488
|
if (!cfg.version) {
|
|
12489
12489
|
return { valid: false, error: "Missing config.version" };
|
|
12490
12490
|
}
|
|
12491
|
-
if (!cfg.agents ||
|
|
12492
|
-
return { valid: false, error: "Missing
|
|
12491
|
+
if (!cfg.agents || typeof cfg.agents !== "object") {
|
|
12492
|
+
return { valid: false, error: "Missing agents object in config" };
|
|
12493
12493
|
}
|
|
12494
|
-
if (cfg.agents
|
|
12495
|
-
return {
|
|
12496
|
-
|
|
12497
|
-
|
|
12498
|
-
|
|
12499
|
-
return { valid: false, error: "First agent must be an object" };
|
|
12494
|
+
if (Array.isArray(cfg.agents)) {
|
|
12495
|
+
return {
|
|
12496
|
+
valid: false,
|
|
12497
|
+
error: "agents must be an object, not an array. Use format: agents: { agent-name: { ... } }"
|
|
12498
|
+
};
|
|
12500
12499
|
}
|
|
12501
|
-
|
|
12502
|
-
|
|
12500
|
+
const agentKeys = Object.keys(cfg.agents);
|
|
12501
|
+
if (agentKeys.length === 0) {
|
|
12502
|
+
return {
|
|
12503
|
+
valid: false,
|
|
12504
|
+
error: "agents must have at least one agent defined"
|
|
12505
|
+
};
|
|
12503
12506
|
}
|
|
12504
|
-
if (
|
|
12505
|
-
return {
|
|
12507
|
+
if (agentKeys.length > 1) {
|
|
12508
|
+
return {
|
|
12509
|
+
valid: false,
|
|
12510
|
+
error: "Multiple agents not supported yet. Only one agent allowed."
|
|
12511
|
+
};
|
|
12506
12512
|
}
|
|
12507
|
-
|
|
12513
|
+
const agentName = agentKeys[0];
|
|
12514
|
+
if (!validateAgentName(agentName)) {
|
|
12508
12515
|
return {
|
|
12509
12516
|
valid: false,
|
|
12510
|
-
error: "Invalid
|
|
12517
|
+
error: "Invalid agent name format. Must be 3-64 characters, letters, numbers, and hyphens only. Must start and end with letter or number."
|
|
12511
12518
|
};
|
|
12512
12519
|
}
|
|
12520
|
+
const agentsObj = cfg.agents;
|
|
12521
|
+
const agent = agentsObj[agentName];
|
|
12522
|
+
if (!agent || typeof agent !== "object") {
|
|
12523
|
+
return { valid: false, error: "Agent definition must be an object" };
|
|
12524
|
+
}
|
|
12513
12525
|
if (!agent.working_dir || typeof agent.working_dir !== "string") {
|
|
12514
12526
|
return {
|
|
12515
12527
|
valid: false,
|
|
12516
|
-
error: "Missing or invalid
|
|
12528
|
+
error: "Missing or invalid agent.working_dir (must be a string)"
|
|
12517
12529
|
};
|
|
12518
12530
|
}
|
|
12519
12531
|
if (!agent.image || typeof agent.image !== "string") {
|
|
12520
12532
|
return {
|
|
12521
12533
|
valid: false,
|
|
12522
|
-
error: "Missing or invalid
|
|
12534
|
+
error: "Missing or invalid agent.image (must be a string)"
|
|
12523
12535
|
};
|
|
12524
12536
|
}
|
|
12525
12537
|
if (!agent.provider || typeof agent.provider !== "string") {
|
|
12526
12538
|
return {
|
|
12527
12539
|
valid: false,
|
|
12528
|
-
error: "Missing or invalid
|
|
12540
|
+
error: "Missing or invalid agent.provider (must be a string)"
|
|
12529
12541
|
};
|
|
12530
12542
|
}
|
|
12531
12543
|
const agentVolumes = agent.volumes;
|
|
@@ -13446,15 +13458,96 @@ var initCommand = new Command3().name("init").description("Initialize a volume i
|
|
|
13446
13458
|
// src/commands/volume/push.ts
|
|
13447
13459
|
import { Command as Command4 } from "commander";
|
|
13448
13460
|
import chalk6 from "chalk";
|
|
13449
|
-
import
|
|
13461
|
+
import path4 from "path";
|
|
13462
|
+
import * as fs2 from "fs";
|
|
13463
|
+
import * as os from "os";
|
|
13464
|
+
import * as tar2 from "tar";
|
|
13465
|
+
|
|
13466
|
+
// src/lib/file-utils.ts
|
|
13450
13467
|
import * as fs from "fs";
|
|
13451
|
-
import
|
|
13468
|
+
import * as path3 from "path";
|
|
13469
|
+
import * as tar from "tar";
|
|
13470
|
+
function excludeVm0Filter(filePath) {
|
|
13471
|
+
const shouldExclude = filePath === ".vm0" || filePath.startsWith(".vm0/") || filePath.startsWith("./.vm0");
|
|
13472
|
+
return !shouldExclude;
|
|
13473
|
+
}
|
|
13474
|
+
function listTarFiles(tarPath) {
|
|
13475
|
+
return new Promise((resolve, reject) => {
|
|
13476
|
+
const files = [];
|
|
13477
|
+
tar.list({
|
|
13478
|
+
file: tarPath,
|
|
13479
|
+
onReadEntry: (entry) => {
|
|
13480
|
+
if (entry.type === "File") {
|
|
13481
|
+
files.push(entry.path);
|
|
13482
|
+
}
|
|
13483
|
+
}
|
|
13484
|
+
}).then(() => resolve(files)).catch(reject);
|
|
13485
|
+
});
|
|
13486
|
+
}
|
|
13487
|
+
async function listLocalFiles(dir, excludeDirs = [".vm0"]) {
|
|
13488
|
+
const files = [];
|
|
13489
|
+
async function walkDir(currentDir, relativePath = "") {
|
|
13490
|
+
const entries = await fs.promises.readdir(currentDir, {
|
|
13491
|
+
withFileTypes: true
|
|
13492
|
+
});
|
|
13493
|
+
for (const entry of entries) {
|
|
13494
|
+
const entryRelativePath = relativePath ? path3.join(relativePath, entry.name) : entry.name;
|
|
13495
|
+
if (entry.isDirectory()) {
|
|
13496
|
+
if (!excludeDirs.includes(entry.name)) {
|
|
13497
|
+
await walkDir(path3.join(currentDir, entry.name), entryRelativePath);
|
|
13498
|
+
}
|
|
13499
|
+
} else {
|
|
13500
|
+
files.push(entryRelativePath);
|
|
13501
|
+
}
|
|
13502
|
+
}
|
|
13503
|
+
}
|
|
13504
|
+
await walkDir(dir);
|
|
13505
|
+
return files;
|
|
13506
|
+
}
|
|
13507
|
+
async function removeExtraFiles(dir, remoteFiles, excludeDirs = [".vm0"]) {
|
|
13508
|
+
const localFiles = await listLocalFiles(dir, excludeDirs);
|
|
13509
|
+
let removedCount = 0;
|
|
13510
|
+
for (const localFile of localFiles) {
|
|
13511
|
+
const normalizedPath = localFile.replace(/\\/g, "/");
|
|
13512
|
+
if (!remoteFiles.has(normalizedPath)) {
|
|
13513
|
+
const fullPath = path3.join(dir, localFile);
|
|
13514
|
+
await fs.promises.unlink(fullPath);
|
|
13515
|
+
removedCount++;
|
|
13516
|
+
}
|
|
13517
|
+
}
|
|
13518
|
+
await removeEmptyDirs(dir, excludeDirs);
|
|
13519
|
+
return removedCount;
|
|
13520
|
+
}
|
|
13521
|
+
async function removeEmptyDirs(dir, excludeDirs = [".vm0"]) {
|
|
13522
|
+
const entries = await fs.promises.readdir(dir, { withFileTypes: true });
|
|
13523
|
+
let isEmpty = true;
|
|
13524
|
+
for (const entry of entries) {
|
|
13525
|
+
const fullPath = path3.join(dir, entry.name);
|
|
13526
|
+
if (entry.isDirectory()) {
|
|
13527
|
+
if (excludeDirs.includes(entry.name)) {
|
|
13528
|
+
isEmpty = false;
|
|
13529
|
+
} else {
|
|
13530
|
+
const subDirEmpty = await removeEmptyDirs(fullPath, excludeDirs);
|
|
13531
|
+
if (subDirEmpty) {
|
|
13532
|
+
await fs.promises.rmdir(fullPath);
|
|
13533
|
+
} else {
|
|
13534
|
+
isEmpty = false;
|
|
13535
|
+
}
|
|
13536
|
+
}
|
|
13537
|
+
} else {
|
|
13538
|
+
isEmpty = false;
|
|
13539
|
+
}
|
|
13540
|
+
}
|
|
13541
|
+
return isEmpty;
|
|
13542
|
+
}
|
|
13543
|
+
|
|
13544
|
+
// src/commands/volume/push.ts
|
|
13452
13545
|
async function getAllFiles(dirPath, baseDir = dirPath) {
|
|
13453
13546
|
const files = [];
|
|
13454
|
-
const entries = await
|
|
13547
|
+
const entries = await fs2.promises.readdir(dirPath, { withFileTypes: true });
|
|
13455
13548
|
for (const entry of entries) {
|
|
13456
|
-
const fullPath =
|
|
13457
|
-
const relativePath =
|
|
13549
|
+
const fullPath = path4.join(dirPath, entry.name);
|
|
13550
|
+
const relativePath = path4.relative(baseDir, fullPath);
|
|
13458
13551
|
if (relativePath.startsWith(".vm0")) {
|
|
13459
13552
|
continue;
|
|
13460
13553
|
}
|
|
@@ -13491,7 +13584,7 @@ var pushCommand = new Command4().name("push").description("Push local files to c
|
|
|
13491
13584
|
const files = await getAllFiles(cwd);
|
|
13492
13585
|
let totalSize = 0;
|
|
13493
13586
|
for (const file2 of files) {
|
|
13494
|
-
const stats = await
|
|
13587
|
+
const stats = await fs2.promises.stat(file2);
|
|
13495
13588
|
totalSize += stats.size;
|
|
13496
13589
|
}
|
|
13497
13590
|
if (files.length === 0) {
|
|
@@ -13502,14 +13595,34 @@ var pushCommand = new Command4().name("push").description("Push local files to c
|
|
|
13502
13595
|
);
|
|
13503
13596
|
}
|
|
13504
13597
|
console.log(chalk6.gray("Compressing files..."));
|
|
13505
|
-
const
|
|
13506
|
-
|
|
13507
|
-
|
|
13508
|
-
|
|
13598
|
+
const tmpDir = fs2.mkdtempSync(path4.join(os.tmpdir(), "vm0-"));
|
|
13599
|
+
const tarPath = path4.join(tmpDir, "volume.tar.gz");
|
|
13600
|
+
const relativePaths = files.map((file2) => path4.relative(cwd, file2));
|
|
13601
|
+
if (relativePaths.length > 0) {
|
|
13602
|
+
await tar2.create(
|
|
13603
|
+
{
|
|
13604
|
+
gzip: true,
|
|
13605
|
+
file: tarPath,
|
|
13606
|
+
cwd
|
|
13607
|
+
},
|
|
13608
|
+
relativePaths
|
|
13609
|
+
);
|
|
13610
|
+
} else {
|
|
13611
|
+
await tar2.create(
|
|
13612
|
+
{
|
|
13613
|
+
gzip: true,
|
|
13614
|
+
file: tarPath,
|
|
13615
|
+
cwd,
|
|
13616
|
+
filter: excludeVm0Filter
|
|
13617
|
+
},
|
|
13618
|
+
["."]
|
|
13619
|
+
);
|
|
13509
13620
|
}
|
|
13510
|
-
const
|
|
13621
|
+
const tarBuffer = await fs2.promises.readFile(tarPath);
|
|
13622
|
+
await fs2.promises.unlink(tarPath);
|
|
13623
|
+
await fs2.promises.rmdir(tmpDir);
|
|
13511
13624
|
console.log(
|
|
13512
|
-
chalk6.green(`\u2713 Compressed to ${formatBytes(
|
|
13625
|
+
chalk6.green(`\u2713 Compressed to ${formatBytes(tarBuffer.length)}`)
|
|
13513
13626
|
);
|
|
13514
13627
|
console.log(chalk6.gray("Uploading..."));
|
|
13515
13628
|
const formData = new FormData();
|
|
@@ -13520,8 +13633,8 @@ var pushCommand = new Command4().name("push").description("Push local files to c
|
|
|
13520
13633
|
}
|
|
13521
13634
|
formData.append(
|
|
13522
13635
|
"file",
|
|
13523
|
-
new Blob([
|
|
13524
|
-
"volume.
|
|
13636
|
+
new Blob([tarBuffer], { type: "application/gzip" }),
|
|
13637
|
+
"volume.tar.gz"
|
|
13525
13638
|
);
|
|
13526
13639
|
const response = await apiClient.post("/api/storages", {
|
|
13527
13640
|
body: formData
|
|
@@ -13555,78 +13668,8 @@ import { Command as Command5 } from "commander";
|
|
|
13555
13668
|
import chalk7 from "chalk";
|
|
13556
13669
|
import path5 from "path";
|
|
13557
13670
|
import * as fs3 from "fs";
|
|
13558
|
-
import
|
|
13559
|
-
|
|
13560
|
-
// src/lib/file-utils.ts
|
|
13561
|
-
import * as fs2 from "fs";
|
|
13562
|
-
import * as path4 from "path";
|
|
13563
|
-
function getRemoteFilesFromZip(zipEntries) {
|
|
13564
|
-
const remoteFiles = /* @__PURE__ */ new Set();
|
|
13565
|
-
for (const entry of zipEntries) {
|
|
13566
|
-
if (!entry.isDirectory) {
|
|
13567
|
-
remoteFiles.add(entry.entryName.replace(/\\/g, "/"));
|
|
13568
|
-
}
|
|
13569
|
-
}
|
|
13570
|
-
return remoteFiles;
|
|
13571
|
-
}
|
|
13572
|
-
async function listLocalFiles(dir, excludeDirs = [".vm0"]) {
|
|
13573
|
-
const files = [];
|
|
13574
|
-
async function walkDir(currentDir, relativePath = "") {
|
|
13575
|
-
const entries = await fs2.promises.readdir(currentDir, {
|
|
13576
|
-
withFileTypes: true
|
|
13577
|
-
});
|
|
13578
|
-
for (const entry of entries) {
|
|
13579
|
-
const entryRelativePath = relativePath ? path4.join(relativePath, entry.name) : entry.name;
|
|
13580
|
-
if (entry.isDirectory()) {
|
|
13581
|
-
if (!excludeDirs.includes(entry.name)) {
|
|
13582
|
-
await walkDir(path4.join(currentDir, entry.name), entryRelativePath);
|
|
13583
|
-
}
|
|
13584
|
-
} else {
|
|
13585
|
-
files.push(entryRelativePath);
|
|
13586
|
-
}
|
|
13587
|
-
}
|
|
13588
|
-
}
|
|
13589
|
-
await walkDir(dir);
|
|
13590
|
-
return files;
|
|
13591
|
-
}
|
|
13592
|
-
async function removeExtraFiles(dir, remoteFiles, excludeDirs = [".vm0"]) {
|
|
13593
|
-
const localFiles = await listLocalFiles(dir, excludeDirs);
|
|
13594
|
-
let removedCount = 0;
|
|
13595
|
-
for (const localFile of localFiles) {
|
|
13596
|
-
const normalizedPath = localFile.replace(/\\/g, "/");
|
|
13597
|
-
if (!remoteFiles.has(normalizedPath)) {
|
|
13598
|
-
const fullPath = path4.join(dir, localFile);
|
|
13599
|
-
await fs2.promises.unlink(fullPath);
|
|
13600
|
-
removedCount++;
|
|
13601
|
-
}
|
|
13602
|
-
}
|
|
13603
|
-
await removeEmptyDirs(dir, excludeDirs);
|
|
13604
|
-
return removedCount;
|
|
13605
|
-
}
|
|
13606
|
-
async function removeEmptyDirs(dir, excludeDirs = [".vm0"]) {
|
|
13607
|
-
const entries = await fs2.promises.readdir(dir, { withFileTypes: true });
|
|
13608
|
-
let isEmpty = true;
|
|
13609
|
-
for (const entry of entries) {
|
|
13610
|
-
const fullPath = path4.join(dir, entry.name);
|
|
13611
|
-
if (entry.isDirectory()) {
|
|
13612
|
-
if (excludeDirs.includes(entry.name)) {
|
|
13613
|
-
isEmpty = false;
|
|
13614
|
-
} else {
|
|
13615
|
-
const subDirEmpty = await removeEmptyDirs(fullPath, excludeDirs);
|
|
13616
|
-
if (subDirEmpty) {
|
|
13617
|
-
await fs2.promises.rmdir(fullPath);
|
|
13618
|
-
} else {
|
|
13619
|
-
isEmpty = false;
|
|
13620
|
-
}
|
|
13621
|
-
}
|
|
13622
|
-
} else {
|
|
13623
|
-
isEmpty = false;
|
|
13624
|
-
}
|
|
13625
|
-
}
|
|
13626
|
-
return isEmpty;
|
|
13627
|
-
}
|
|
13628
|
-
|
|
13629
|
-
// src/commands/volume/pull.ts
|
|
13671
|
+
import * as os2 from "os";
|
|
13672
|
+
import * as tar3 from "tar";
|
|
13630
13673
|
function formatBytes2(bytes) {
|
|
13631
13674
|
if (bytes === 0) return "0 B";
|
|
13632
13675
|
const k = 1024;
|
|
@@ -13674,31 +13717,31 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
|
|
|
13674
13717
|
process.exit(1);
|
|
13675
13718
|
}
|
|
13676
13719
|
const arrayBuffer = await response.arrayBuffer();
|
|
13677
|
-
const
|
|
13678
|
-
console.log(chalk7.green(`\u2713 Downloaded ${formatBytes2(
|
|
13679
|
-
|
|
13680
|
-
const
|
|
13681
|
-
|
|
13682
|
-
const remoteFiles = getRemoteFilesFromZip(zipEntries);
|
|
13720
|
+
const tarBuffer = Buffer.from(arrayBuffer);
|
|
13721
|
+
console.log(chalk7.green(`\u2713 Downloaded ${formatBytes2(tarBuffer.length)}`));
|
|
13722
|
+
const tmpDir = fs3.mkdtempSync(path5.join(os2.tmpdir(), "vm0-"));
|
|
13723
|
+
const tarPath = path5.join(tmpDir, "volume.tar.gz");
|
|
13724
|
+
await fs3.promises.writeFile(tarPath, tarBuffer);
|
|
13683
13725
|
console.log(chalk7.gray("Syncing local files..."));
|
|
13684
|
-
const
|
|
13726
|
+
const remoteFiles = await listTarFiles(tarPath);
|
|
13727
|
+
const remoteFilesSet = new Set(
|
|
13728
|
+
remoteFiles.map((f) => f.replace(/\\/g, "/"))
|
|
13729
|
+
);
|
|
13730
|
+
const removedCount = await removeExtraFiles(cwd, remoteFilesSet);
|
|
13685
13731
|
if (removedCount > 0) {
|
|
13686
13732
|
console.log(
|
|
13687
13733
|
chalk7.green(`\u2713 Removed ${removedCount} files not in remote`)
|
|
13688
13734
|
);
|
|
13689
13735
|
}
|
|
13690
|
-
|
|
13691
|
-
|
|
13692
|
-
|
|
13693
|
-
|
|
13694
|
-
|
|
13695
|
-
|
|
13696
|
-
|
|
13697
|
-
|
|
13698
|
-
|
|
13699
|
-
}
|
|
13700
|
-
}
|
|
13701
|
-
console.log(chalk7.green(`\u2713 Extracted ${extractedCount} files`));
|
|
13736
|
+
console.log(chalk7.gray("Extracting files..."));
|
|
13737
|
+
await tar3.extract({
|
|
13738
|
+
file: tarPath,
|
|
13739
|
+
cwd,
|
|
13740
|
+
gzip: true
|
|
13741
|
+
});
|
|
13742
|
+
await fs3.promises.unlink(tarPath);
|
|
13743
|
+
await fs3.promises.rmdir(tmpDir);
|
|
13744
|
+
console.log(chalk7.green(`\u2713 Extracted ${remoteFiles.length} files`));
|
|
13702
13745
|
} catch (error43) {
|
|
13703
13746
|
console.error(chalk7.red("\u2717 Pull failed"));
|
|
13704
13747
|
if (error43 instanceof Error) {
|
|
@@ -13781,7 +13824,8 @@ import { Command as Command8 } from "commander";
|
|
|
13781
13824
|
import chalk9 from "chalk";
|
|
13782
13825
|
import path7 from "path";
|
|
13783
13826
|
import * as fs4 from "fs";
|
|
13784
|
-
import
|
|
13827
|
+
import * as os3 from "os";
|
|
13828
|
+
import * as tar4 from "tar";
|
|
13785
13829
|
async function getAllFiles2(dirPath, baseDir = dirPath) {
|
|
13786
13830
|
const files = [];
|
|
13787
13831
|
const entries = await fs4.promises.readdir(dirPath, { withFileTypes: true });
|
|
@@ -13844,14 +13888,34 @@ var pushCommand2 = new Command8().name("push").description("Push local files to
|
|
|
13844
13888
|
);
|
|
13845
13889
|
}
|
|
13846
13890
|
console.log(chalk9.gray("Compressing files..."));
|
|
13847
|
-
const
|
|
13848
|
-
|
|
13849
|
-
|
|
13850
|
-
|
|
13891
|
+
const tmpDir = fs4.mkdtempSync(path7.join(os3.tmpdir(), "vm0-"));
|
|
13892
|
+
const tarPath = path7.join(tmpDir, "artifact.tar.gz");
|
|
13893
|
+
const relativePaths = files.map((file2) => path7.relative(cwd, file2));
|
|
13894
|
+
if (relativePaths.length > 0) {
|
|
13895
|
+
await tar4.create(
|
|
13896
|
+
{
|
|
13897
|
+
gzip: true,
|
|
13898
|
+
file: tarPath,
|
|
13899
|
+
cwd
|
|
13900
|
+
},
|
|
13901
|
+
relativePaths
|
|
13902
|
+
);
|
|
13903
|
+
} else {
|
|
13904
|
+
await tar4.create(
|
|
13905
|
+
{
|
|
13906
|
+
gzip: true,
|
|
13907
|
+
file: tarPath,
|
|
13908
|
+
cwd,
|
|
13909
|
+
filter: excludeVm0Filter
|
|
13910
|
+
},
|
|
13911
|
+
["."]
|
|
13912
|
+
);
|
|
13851
13913
|
}
|
|
13852
|
-
const
|
|
13914
|
+
const tarBuffer = await fs4.promises.readFile(tarPath);
|
|
13915
|
+
await fs4.promises.unlink(tarPath);
|
|
13916
|
+
await fs4.promises.rmdir(tmpDir);
|
|
13853
13917
|
console.log(
|
|
13854
|
-
chalk9.green(`\u2713 Compressed to ${formatBytes3(
|
|
13918
|
+
chalk9.green(`\u2713 Compressed to ${formatBytes3(tarBuffer.length)}`)
|
|
13855
13919
|
);
|
|
13856
13920
|
console.log(chalk9.gray("Uploading..."));
|
|
13857
13921
|
const formData = new FormData();
|
|
@@ -13862,8 +13926,8 @@ var pushCommand2 = new Command8().name("push").description("Push local files to
|
|
|
13862
13926
|
}
|
|
13863
13927
|
formData.append(
|
|
13864
13928
|
"file",
|
|
13865
|
-
new Blob([
|
|
13866
|
-
"artifact.
|
|
13929
|
+
new Blob([tarBuffer], { type: "application/gzip" }),
|
|
13930
|
+
"artifact.tar.gz"
|
|
13867
13931
|
);
|
|
13868
13932
|
const response = await apiClient.post("/api/storages", {
|
|
13869
13933
|
body: formData
|
|
@@ -13896,7 +13960,8 @@ import { Command as Command9 } from "commander";
|
|
|
13896
13960
|
import chalk10 from "chalk";
|
|
13897
13961
|
import path8 from "path";
|
|
13898
13962
|
import * as fs5 from "fs";
|
|
13899
|
-
import
|
|
13963
|
+
import * as os4 from "os";
|
|
13964
|
+
import * as tar5 from "tar";
|
|
13900
13965
|
function formatBytes4(bytes) {
|
|
13901
13966
|
if (bytes === 0) return "0 B";
|
|
13902
13967
|
const k = 1024;
|
|
@@ -13955,31 +14020,31 @@ var pullCommand2 = new Command9().name("pull").description("Pull cloud artifact
|
|
|
13955
14020
|
process.exit(1);
|
|
13956
14021
|
}
|
|
13957
14022
|
const arrayBuffer = await response.arrayBuffer();
|
|
13958
|
-
const
|
|
13959
|
-
console.log(chalk10.green(`\u2713 Downloaded ${formatBytes4(
|
|
13960
|
-
|
|
13961
|
-
const
|
|
13962
|
-
|
|
13963
|
-
const remoteFiles = getRemoteFilesFromZip(zipEntries);
|
|
14023
|
+
const tarBuffer = Buffer.from(arrayBuffer);
|
|
14024
|
+
console.log(chalk10.green(`\u2713 Downloaded ${formatBytes4(tarBuffer.length)}`));
|
|
14025
|
+
const tmpDir = fs5.mkdtempSync(path8.join(os4.tmpdir(), "vm0-"));
|
|
14026
|
+
const tarPath = path8.join(tmpDir, "artifact.tar.gz");
|
|
14027
|
+
await fs5.promises.writeFile(tarPath, tarBuffer);
|
|
13964
14028
|
console.log(chalk10.gray("Syncing local files..."));
|
|
13965
|
-
const
|
|
14029
|
+
const remoteFiles = await listTarFiles(tarPath);
|
|
14030
|
+
const remoteFilesSet = new Set(
|
|
14031
|
+
remoteFiles.map((f) => f.replace(/\\/g, "/"))
|
|
14032
|
+
);
|
|
14033
|
+
const removedCount = await removeExtraFiles(cwd, remoteFilesSet);
|
|
13966
14034
|
if (removedCount > 0) {
|
|
13967
14035
|
console.log(
|
|
13968
14036
|
chalk10.green(`\u2713 Removed ${removedCount} files not in remote`)
|
|
13969
14037
|
);
|
|
13970
14038
|
}
|
|
13971
|
-
|
|
13972
|
-
|
|
13973
|
-
|
|
13974
|
-
|
|
13975
|
-
|
|
13976
|
-
|
|
13977
|
-
|
|
13978
|
-
|
|
13979
|
-
|
|
13980
|
-
}
|
|
13981
|
-
}
|
|
13982
|
-
console.log(chalk10.green(`\u2713 Extracted ${extractedCount} files`));
|
|
14039
|
+
console.log(chalk10.gray("Extracting files..."));
|
|
14040
|
+
await tar5.extract({
|
|
14041
|
+
file: tarPath,
|
|
14042
|
+
cwd,
|
|
14043
|
+
gzip: true
|
|
14044
|
+
});
|
|
14045
|
+
await fs5.promises.unlink(tarPath);
|
|
14046
|
+
await fs5.promises.rmdir(tmpDir);
|
|
14047
|
+
console.log(chalk10.green(`\u2713 Extracted ${remoteFiles.length} files`));
|
|
13983
14048
|
} catch (error43) {
|
|
13984
14049
|
console.error(chalk10.red("\u2717 Pull failed"));
|
|
13985
14050
|
if (error43 instanceof Error) {
|
|
@@ -13994,7 +14059,7 @@ var artifactCommand = new Command10().name("artifact").description("Manage cloud
|
|
|
13994
14059
|
|
|
13995
14060
|
// src/index.ts
|
|
13996
14061
|
var program = new Command11();
|
|
13997
|
-
program.name("vm0").description("VM0 CLI - A modern build tool").version("
|
|
14062
|
+
program.name("vm0").description("VM0 CLI - A modern build tool").version("3.0.0");
|
|
13998
14063
|
program.command("hello").description("Say hello from the App").action(() => {
|
|
13999
14064
|
console.log(chalk11.blue("Welcome to the VM0 CLI!"));
|
|
14000
14065
|
console.log(chalk11.green(`Core says: ${FOO}`));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vm0/cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "CLI application",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
"."
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"adm-zip": "^0.5.16",
|
|
19
18
|
"chalk": "^5.6.0",
|
|
20
19
|
"commander": "^14.0.0",
|
|
20
|
+
"tar": "^7.5.2",
|
|
21
21
|
"yaml": "^2.3.4"
|
|
22
22
|
}
|
|
23
23
|
}
|