sftp-push-sync 1.0.14 → 1.0.15
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/bin/sftp-push-sync.mjs +24 -20
- package/package.json +1 -1
package/bin/sftp-push-sync.mjs
CHANGED
|
@@ -55,6 +55,9 @@ const hr1 = () => "─".repeat(65); // horizontal line -
|
|
|
55
55
|
const hr2 = () => "=".repeat(65); // horizontal line =
|
|
56
56
|
const tab_a = () => " ".repeat(3); // indentation for formatting the terminal output.
|
|
57
57
|
const tab_b = () => " ".repeat(6);
|
|
58
|
+
const cr_a = () => "\n".repeat(1);
|
|
59
|
+
const cr_b = () => "\n".repeat(2);
|
|
60
|
+
|
|
58
61
|
|
|
59
62
|
// ---------------------------------------------------------------------------
|
|
60
63
|
// CLI arguments
|
|
@@ -246,7 +249,7 @@ function clearProgressLine() {
|
|
|
246
249
|
const blank = " ".repeat(width);
|
|
247
250
|
|
|
248
251
|
// Beide Progress-Zeilen leeren
|
|
249
|
-
process.stdout.write("\r" + blank +
|
|
252
|
+
process.stdout.write("\r" + blank + cr_a() + blank + "\r");
|
|
250
253
|
|
|
251
254
|
progressActive = false;
|
|
252
255
|
}
|
|
@@ -350,7 +353,7 @@ function updateProgress2(prefix, current, total, rel = "") {
|
|
|
350
353
|
if (line2.length > width) line2 = line2.slice(0, width - 1);
|
|
351
354
|
|
|
352
355
|
// zwei Zeilen überschreiben
|
|
353
|
-
process.stdout.write("\r" + line1.padEnd(width) +
|
|
356
|
+
process.stdout.write("\r" + line1.padEnd(width) + cr_a());
|
|
354
357
|
process.stdout.write(line2.padEnd(width));
|
|
355
358
|
|
|
356
359
|
// Cursor wieder nach oben (auf die Fortschrittszeile)
|
|
@@ -437,7 +440,7 @@ async function walkLocal(root) {
|
|
|
437
440
|
if (scanned > 0) {
|
|
438
441
|
// last line + neat finish
|
|
439
442
|
updateProgress2(`${tab_a()}Scan local: `, scanned, 0, "fertig");
|
|
440
|
-
process.stdout.write(
|
|
443
|
+
process.stdout.write(cr_a());
|
|
441
444
|
progressActive = false;
|
|
442
445
|
}
|
|
443
446
|
|
|
@@ -487,7 +490,7 @@ async function walkRemote(sftp, remoteRoot) {
|
|
|
487
490
|
|
|
488
491
|
if (scanned > 0) {
|
|
489
492
|
updateProgress2(`${tab_a()}Scan remote: `, scanned, 0, "fertig");
|
|
490
|
-
process.stdout.write(
|
|
493
|
+
process.stdout.write(cr_a());
|
|
491
494
|
progressActive = false;
|
|
492
495
|
}
|
|
493
496
|
|
|
@@ -613,7 +616,7 @@ function describeSftpError(err) {
|
|
|
613
616
|
async function main() {
|
|
614
617
|
const start = Date.now();
|
|
615
618
|
|
|
616
|
-
log(
|
|
619
|
+
log(`${cr_b()}${hr2()}`);
|
|
617
620
|
log(
|
|
618
621
|
pc.bold(
|
|
619
622
|
`🔐 SFTP Push-Synchronisation: sftp-push-sync v${pkg.version} [logLevel=${LOG_LEVEL}]`
|
|
@@ -634,7 +637,7 @@ async function main() {
|
|
|
634
637
|
)
|
|
635
638
|
);
|
|
636
639
|
}
|
|
637
|
-
log(`${hr1()}
|
|
640
|
+
log(`${hr1()}${cr_a()}`);
|
|
638
641
|
|
|
639
642
|
const sftp = new SftpClient();
|
|
640
643
|
let connected = false;
|
|
@@ -662,7 +665,7 @@ async function main() {
|
|
|
662
665
|
process.exit(1);
|
|
663
666
|
}
|
|
664
667
|
|
|
665
|
-
log(pc.bold(pc.cyan("📥 Phase 1: Scan local files …")));
|
|
668
|
+
log(cr_a() + pc.bold(pc.cyan("📥 Phase 1: Scan local files …")));
|
|
666
669
|
const local = await walkLocal(CONNECTION.localRoot);
|
|
667
670
|
log(`${tab_a()}→ ${local.size} local files`);
|
|
668
671
|
|
|
@@ -675,14 +678,14 @@ async function main() {
|
|
|
675
678
|
log("");
|
|
676
679
|
}
|
|
677
680
|
|
|
678
|
-
log(pc.bold(pc.cyan("📤 Phase 2: Scan remote files …")));
|
|
681
|
+
log(cr_a() + pc.bold(pc.cyan("📤 Phase 2: Scan remote files …")));
|
|
679
682
|
const remote = await walkRemote(sftp, CONNECTION.remoteRoot);
|
|
680
|
-
log(`${tab_a()}→ ${remote.size} remote files
|
|
683
|
+
log(`${tab_a()}→ ${remote.size} remote files${cr_a()}`);
|
|
681
684
|
|
|
682
685
|
const localKeys = new Set(local.keys());
|
|
683
686
|
const remoteKeys = new Set(remote.keys());
|
|
684
687
|
|
|
685
|
-
log(pc.bold(pc.cyan("🔎 Phase 3: Compare & decide …")));
|
|
688
|
+
log(cr_a() + pc.bold(pc.cyan("🔎 Phase 3: Compare & decide …")));
|
|
686
689
|
const totalToCheck = localKeys.size;
|
|
687
690
|
let checkedCount = 0;
|
|
688
691
|
|
|
@@ -782,7 +785,7 @@ async function main() {
|
|
|
782
785
|
}
|
|
783
786
|
|
|
784
787
|
log(
|
|
785
|
-
|
|
788
|
+
cr_a() + pc.bold(pc.cyan("🧹 Phase 4: Removing orphaned remote files …"))
|
|
786
789
|
);
|
|
787
790
|
for (const rel of remoteKeys) {
|
|
788
791
|
if (!localKeys.has(rel)) {
|
|
@@ -804,7 +807,7 @@ async function main() {
|
|
|
804
807
|
// -------------------------------------------------------------------
|
|
805
808
|
|
|
806
809
|
if (!DRY_RUN) {
|
|
807
|
-
log(
|
|
810
|
+
log(cr_a() + pc.bold(pc.cyan("🚚 Phase 5: Apply changes …")));
|
|
808
811
|
|
|
809
812
|
// Upload new files
|
|
810
813
|
await runTasks(
|
|
@@ -858,7 +861,7 @@ async function main() {
|
|
|
858
861
|
} else {
|
|
859
862
|
log(
|
|
860
863
|
pc.yellow(
|
|
861
|
-
|
|
864
|
+
`${cr_a()}💡 DRY-RUN: Connection tested, no files transferred or deleted.`
|
|
862
865
|
)
|
|
863
866
|
);
|
|
864
867
|
}
|
|
@@ -869,7 +872,7 @@ async function main() {
|
|
|
869
872
|
|
|
870
873
|
if (RUN_UPLOAD_LIST && UPLOAD_LIST.length > 0) {
|
|
871
874
|
log(
|
|
872
|
-
|
|
875
|
+
cr_a() +
|
|
873
876
|
pc.bold(pc.cyan("⬆️ Extra Phase: Upload-List (explicit files) …"))
|
|
874
877
|
);
|
|
875
878
|
|
|
@@ -904,7 +907,7 @@ async function main() {
|
|
|
904
907
|
|
|
905
908
|
if (RUN_DOWNLOAD_LIST && DOWNLOAD_LIST.length > 0) {
|
|
906
909
|
log(
|
|
907
|
-
|
|
910
|
+
cr_a() +
|
|
908
911
|
pc.bold(pc.cyan("⬇️ Extra Phase: Download-List (explicit files) …"))
|
|
909
912
|
);
|
|
910
913
|
|
|
@@ -938,7 +941,8 @@ async function main() {
|
|
|
938
941
|
await saveCache(true);
|
|
939
942
|
|
|
940
943
|
// Summary
|
|
941
|
-
log(
|
|
944
|
+
log(hr1());
|
|
945
|
+
log(cr_a() + pc.bold(pc.cyan("📊 Summary:")));
|
|
942
946
|
log(`${tab_a()}Duration: ${pc.green(duration + " s")}`);
|
|
943
947
|
log(`${tab_a()}${ADD} Added : ${toAdd.length}`);
|
|
944
948
|
log(`${tab_a()}${CHA} Changed: ${toUpdate.length}`);
|
|
@@ -949,7 +953,7 @@ async function main() {
|
|
|
949
953
|
);
|
|
950
954
|
}
|
|
951
955
|
if (toAdd.length || toUpdate.length || toDelete.length) {
|
|
952
|
-
log(
|
|
956
|
+
log(`${cr_a()}📄 Changes:`);
|
|
953
957
|
[...toAdd.map((t) => t.rel)]
|
|
954
958
|
.sort()
|
|
955
959
|
.forEach((f) => console.log(`${tab_a()}${ADD} ${f}`));
|
|
@@ -960,10 +964,10 @@ async function main() {
|
|
|
960
964
|
.sort()
|
|
961
965
|
.forEach((f) => console.log(`${tab_a()}${DEL} ${f}`));
|
|
962
966
|
} else {
|
|
963
|
-
log(
|
|
967
|
+
log(`${cr_a()}No changes.`);
|
|
964
968
|
}
|
|
965
969
|
|
|
966
|
-
log(
|
|
970
|
+
log(cr_a() + pc.bold(pc.green("✅ Sync complete.")));
|
|
967
971
|
} catch (err) {
|
|
968
972
|
const hint = describeSftpError(err);
|
|
969
973
|
elog(pc.red("❌ Synchronisation error:"), err.message || err);
|
|
@@ -993,7 +997,7 @@ async function main() {
|
|
|
993
997
|
);
|
|
994
998
|
}
|
|
995
999
|
}
|
|
996
|
-
log(`${hr2()}
|
|
1000
|
+
log(`${hr2()}${cr_b()}`);
|
|
997
1001
|
}
|
|
998
1002
|
|
|
999
1003
|
main();
|