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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9e643b14b2fe0dd153539ff16d10a0950f3c478d327620dec1b9b04d7af4f340
4
- data.tar.gz: 4eb24c0280ee5f1085024c1357a6d7b8dd0b7f16198e3cce8b4c9ce5849705b5
3
+ metadata.gz: 519b3a75fa38033ef08e8b3b41c2542e05b4525447ba36ddfc590d6d97d863cc
4
+ data.tar.gz: 13041e31c2c5fd66ceae626b14cb01bb54cd97b4ecc79aa76924056e95b40023
5
5
  SHA512:
6
- metadata.gz: 7d5567dc0637bc767f7ddff5716a2e5031902e787958e1ecd69f54931e737b2946d82c999637d6610d732e5063898c3b717b49148f8e495af328ea2f0b716d03
7
- data.tar.gz: 94df8bd72ea5548e668b1173e17b9e9bf54efc1fbca4576c109ed64740794decb94eb23fab78c50ed2b0654bc2160bb1a4be85c74a2f9281bd2a178e0f33b270
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
- # Nur echte Epochen als Zeit werten. Scheitert die ganze stat-Kette,
72
- # ist das Feld leer — das ist "unbekannt", nicht 1970.
73
- result[path] = mtime.match?(/\A\d+\z/) ? Time.at(mtime.to_i) : nil
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
- mtime = stats[rpath]
118
- j.target_exists = !mtime.nil?
119
- j.target_mtime = mtime
120
- j.conflict = !j.directory && j.source_exists && mtime && j.source_mtime &&
121
- mtime - j.source_mtime >= 60
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
@@ -1,3 +1,3 @@
1
1
  module Twin
2
- VERSION = "0.6.0"
2
+ VERSION = "0.6.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mark-twin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ralf Hülsmann