mark-twin 0.6.0 → 0.6.1
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.
- checksums.yaml +4 -4
- data/README.md +24 -1
- data/lib/twin/remote.rb +14 -5
- data/lib/twin/scanner.rb +8 -5
- data/lib/twin/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 519b3a75fa38033ef08e8b3b41c2542e05b4525447ba36ddfc590d6d97d863cc
|
|
4
|
+
data.tar.gz: 13041e31c2c5fd66ceae626b14cb01bb54cd97b4ecc79aa76924056e95b40023
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '07758fd73934de83ac8690f63da7d208c6921af143928c0de4d0a60d230bd50541cef667a5896b95261e0efa742d92669ea21a12874a9ee539e714f8679568dc'
|
|
7
|
+
data.tar.gz: 20cd8530927aa75138ddef786044166dbaded5b82d143890204926d3398d3bfbbbd1ea28346f5d32864e55f69c88ae6c1954cb0a960a5d345347c7bf7336400f
|
data/README.md
CHANGED
|
@@ -39,7 +39,9 @@ way.
|
|
|
39
39
|
That is the whole idea, and for most entries it stays as small as the excerpt
|
|
40
40
|
above. The rest of this README is long because twin also covers more complex
|
|
41
41
|
cases: files that are specific to the other computer, files that have changed
|
|
42
|
-
on both sides since the last sync, and paths that differ per host.
|
|
42
|
+
on both sides since the last sync, and paths that differ per host. If you are
|
|
43
|
+
wondering how this differs from chezmoi and its kind:
|
|
44
|
+
[Alternatives](#alternatives).
|
|
43
45
|
|
|
44
46
|
## Why Markdown
|
|
45
47
|
|
|
@@ -492,6 +494,27 @@ global_excludes:
|
|
|
492
494
|
Environment overrides: `TWIN_SYNC_DIR`, `TWIN_CONFIG`, `TWIN_HOST` (which host
|
|
493
495
|
twin runs as — lets one config serve both machines).
|
|
494
496
|
|
|
497
|
+
## Alternatives
|
|
498
|
+
|
|
499
|
+
twin overlaps with the dotfile managers without being one: it syncs whatever
|
|
500
|
+
you want, documents included, but it specialises in configuration files.
|
|
501
|
+
Taking [chezmoi](https://chezmoi.io) as the most capable representative of
|
|
502
|
+
its kind:
|
|
503
|
+
|
|
504
|
+
| | twin | dotfile managers (e.g. chezmoi) |
|
|
505
|
+
|---|---|---|
|
|
506
|
+
| Focus | deliberate sync between a few machines | converging many machines from one repo |
|
|
507
|
+
| Model | interactive: pick, preview, sync | git: commit, push, apply |
|
|
508
|
+
| Where the *why* lives | prose next to the YAML block, same file | commit messages, separate docs |
|
|
509
|
+
| Conflicts | stops and asks, diff in hand | three-way merge on apply |
|
|
510
|
+
| Templating | host paths (`{{dst.home}}`) | full engine, secrets from password managers |
|
|
511
|
+
| Scale | two or three Macs/servers | dozens of machines |
|
|
512
|
+
|
|
513
|
+
If you want a fleet converging automatically, or secrets injected at apply
|
|
514
|
+
time, choose chezmoi. twin is built for the smaller case: easy to configure,
|
|
515
|
+
with room to read and think about what the target changed before it gets
|
|
516
|
+
overwritten.
|
|
517
|
+
|
|
495
518
|
## Design
|
|
496
519
|
|
|
497
520
|
Sync instructions and their context in one place. No TUI framework: `fzf` does
|
data/lib/twin/remote.rb
CHANGED
|
@@ -64,17 +64,26 @@ module Twin
|
|
|
64
64
|
)
|
|
65
65
|
return nil unless status.success?
|
|
66
66
|
|
|
67
|
+
parse_stats(out)
|
|
68
|
+
rescue Errno::ENOENT
|
|
69
|
+
nil # ssh not installed
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Nur echte Epochen als Zeit werten. Scheitert die ganze stat-Kette, ist
|
|
73
|
+
# das Feld leer — das ist "unbekannt", nicht 1970. Und unbekannt ist
|
|
74
|
+
# nicht fehlend: "-" heißt, die Datei ist nicht da; nil heißt, sie ist
|
|
75
|
+
# da, aber niemand konnte ihre mtime nennen.
|
|
76
|
+
def parse_stats(out)
|
|
67
77
|
result = {}
|
|
68
78
|
out.each_line do |line|
|
|
69
79
|
path, mtime = line.chomp.split("\t", 2)
|
|
70
80
|
next unless path && mtime
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
81
|
+
result[path] =
|
|
82
|
+
if mtime == "-" then :missing
|
|
83
|
+
elsif mtime.match?(/\A\d+\z/) then Time.at(mtime.to_i)
|
|
84
|
+
end
|
|
74
85
|
end
|
|
75
86
|
result
|
|
76
|
-
rescue Errno::ENOENT
|
|
77
|
-
nil # ssh not installed
|
|
78
87
|
end
|
|
79
88
|
|
|
80
89
|
# Checksum many paths in one ssh round-trip, same shape as stat_paths:
|
data/lib/twin/scanner.rb
CHANGED
|
@@ -114,11 +114,14 @@ module Twin
|
|
|
114
114
|
j.target_unreachable = true
|
|
115
115
|
next
|
|
116
116
|
end
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
117
|
+
# :missing = not there; nil = there, but the stat chain could not
|
|
118
|
+
# name an mtime (degrades to unknown, exactly what doctor warns).
|
|
119
|
+
# A path absent from the answer counts as missing, not as unknown.
|
|
120
|
+
mtime = stats.fetch(rpath, :missing)
|
|
121
|
+
j.target_exists = mtime != :missing
|
|
122
|
+
j.target_mtime = mtime.is_a?(Time) ? mtime : nil
|
|
123
|
+
j.conflict = !j.directory && j.source_exists && j.target_mtime &&
|
|
124
|
+
j.source_mtime && j.target_mtime - j.source_mtime >= 60
|
|
122
125
|
end
|
|
123
126
|
verify_remote_file_content(host, host_jobs)
|
|
124
127
|
end
|
data/lib/twin/version.rb
CHANGED