dotlayer 0.2.0 → 0.2.2

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: d30157869fd9bd7c0d98d7957fd82879a06db355368ae7a66919d43ba2dac6dc
4
- data.tar.gz: 560bf0f69bc6a68083d67739d91a97cbd3f208696313ba97f03619ccbae3901a
3
+ metadata.gz: b0489157f2a066cbd4729f51ad5dff3800e75c0144061ea85f49cd4005bcb297
4
+ data.tar.gz: 21e4467266812d237318d0ca70aab7491ae3e87dcf95d66dd2db1c85c74a5e65
5
5
  SHA512:
6
- metadata.gz: ffe27ed4bf4d65aacd1a52fc1c7697771f53b1fe69b1622a10a0789a2e01ce698d56ce6f4a485256e9b86faf5b696efe974d32dacfdfc894ddfdeb6540bb26fc
7
- data.tar.gz: 919ce9855ebfb9a7a5ba0b74c06d818f405bf843ba7505433f3529a89dc6565a5f6a04e5f8bf03853fb45f625b964b19c3e2a8686821f5fced95b7e952f2294d
6
+ metadata.gz: 8062c90a687287e5f0e1e2205064f537be913f5e6a91f844d3d3cdc994d280eeb14428f808ebd2e5e268bd2f01ff603f1be431bbcac2abcff0ff77d5d20eb58b
7
+ data.tar.gz: 6bcc1d1000022e64bda327a7a60a15b65bf77b2c4e394a6077482204bdb2a7ae46911f2502d5e95f50c1c30f65cf1388dc6ee5296aa364f3bbeb4011c92fc60b
data/README.md CHANGED
@@ -13,7 +13,7 @@ config-macos/ → stowed on macOS
13
13
  config-omarchy/ → stowed when Omarchy is detected
14
14
  config-omarchy-desktop/ → stowed on Omarchy + desktop profile
15
15
  config-omarchy-laptop/ → stowed on Omarchy + laptop profile
16
- config-doximity/ → stowed when doximity group is detected
16
+ config-mycompany/ → stowed when mycompany group is detected
17
17
  ```
18
18
 
19
19
  No config file needed — just name your directories and dotlayer figures out the rest.
@@ -64,7 +64,7 @@ Dotlayer auto-detects four things about your system:
64
64
  | **OS** | `RbConfig::CONFIG["host_os"]` | `linux`, `macos` |
65
65
  | **Profile** | `hostnamectl chassis` or `$DOTLAYER_PROFILE` | `desktop`, `laptop` |
66
66
  | **Distro** | Shell commands from config | `omarchy`, `fedora` |
67
- | **Group** | Shell commands from config | `doximity`, `acme` |
67
+ | **Group** | Shell commands from config | `work`, `mycompany` |
68
68
 
69
69
  It then scans your dotfiles repo for directories matching these tags and stows them in layer order:
70
70
 
@@ -72,7 +72,7 @@ It then scans your dotfiles repo for directories matching these tags and stows t
72
72
  2. **OS layer** — `config-linux` or `config-macos`
73
73
  3. **Distro layer** — `config-omarchy`
74
74
  4. **Distro + profile** — `config-omarchy-desktop`
75
- 5. **Group layer** — `config-doximity`
75
+ 5. **Group layer** — `config-mycompany`
76
76
 
77
77
  Each layer can add files but never conflict with earlier layers (Stow constraint).
78
78
 
@@ -106,8 +106,8 @@ distros:
106
106
  detect: . /etc/os-release && test "$ID" = "fedora"
107
107
 
108
108
  groups:
109
- doximity:
110
- detect: test -d ~/src/dox
109
+ mycompany:
110
+ detect: test -d ~/src/mycompany
111
111
 
112
112
  system_files:
113
113
  - source: config-linux/etc/systemd/system-sleep/xremap-restart.sh
@@ -124,9 +124,35 @@ Config file is discovered automatically from:
124
124
  - `~/.public_dotfiles/dotlayer.yml`
125
125
  - `~/.dotfiles/dotlayer.yml`
126
126
 
127
- ## Multi-repo support
127
+ ## Public and private dotfiles
128
128
 
129
- Dotlayer supports multiple repos. Each repo can have its own base packages:
129
+ Most people have two kinds of config: stuff you can share (shell aliases, editor themes, window manager rules) and stuff you can't (API keys, work credentials, employer-specific tooling). Dotlayer handles this with two repos:
130
+
131
+ ```
132
+ ~/.public_dotfiles/ ← shared on GitHub, safe for the world to see
133
+ ~/.private_dotfiles/ ← private repo (or not pushed at all)
134
+ ```
135
+
136
+ ### Why two repos?
137
+
138
+ A single dotfiles repo forces a choice: keep it private (lose the benefit of sharing) or keep it public (risk leaking secrets). Two repos solves this cleanly:
139
+
140
+ - **Public repo** — your shell, editor, git, and desktop config. Push to GitHub, share with the community, clone on any new machine.
141
+ - **Private repo** — work-specific config, API tokens, SSH configs, fonts with restrictive licenses, employer tooling. Keep in a private repo or don't push at all.
142
+
143
+ Both repos stow into the same target (`~`), so your home directory looks the same regardless of which repo a file came from.
144
+
145
+ ### Setting it up
146
+
147
+ Create both repos:
148
+
149
+ ```sh
150
+ mkdir -p ~/.public_dotfiles ~/.private_dotfiles
151
+ cd ~/.public_dotfiles && git init
152
+ cd ~/.private_dotfiles && git init
153
+ ```
154
+
155
+ Add the dotlayer config at `~/.config/dotlayer/dotlayer.yml`:
130
156
 
131
157
  ```yaml
132
158
  repos:
@@ -138,9 +164,67 @@ repos:
138
164
  - fonts
139
165
  ```
140
166
 
141
- Repos without any matching base packages automatically stow all their top-level directories (sorted alphabetically). This is useful for private repos that only contain standalone packages.
167
+ The `private: true` flag tells dotlayer which repo to use when you run `dotlayer adopt --private`.
168
+
169
+ ### What goes where?
170
+
171
+ **Public repo** — uses the standard base packages (`stow`, `bin`, `git`, `zsh`, `config`) with full layering support:
172
+
173
+ ```
174
+ ~/.public_dotfiles/
175
+ config/ ← shared config (editor, terminal, etc.)
176
+ config-linux/ ← Linux-specific overrides
177
+ config-omarchy/ ← Omarchy distro overrides
178
+ config-omarchy-desktop/ ← Omarchy + desktop profile
179
+ git/ ← git config
180
+ zsh/ ← shell config
181
+ bin/ ← personal scripts
182
+ stow/ ← stow's own config
183
+ ```
184
+
185
+ **Private repo** — can use per-repo packages for layered resolution, plus standalone directories that are all stowed automatically:
142
186
 
143
- Repos are processed in order — packages from the first repo are stowed before packages from the second.
187
+ ```
188
+ ~/.private_dotfiles/
189
+ config/ ← private config overlays (SSH, API keys)
190
+ config-mycompany/ ← work-specific config (group layer)
191
+ fonts/ ← licensed fonts
192
+ fonts-linux/ ← Linux-specific font config
193
+ claude/ ← standalone: Claude AI config
194
+ work/ ← standalone: work tooling
195
+ scripts/ ← standalone: work automation scripts
196
+ ```
197
+
198
+ Directories that match the per-repo base packages (`config`, `fonts`) get full layer resolution. Everything else (`claude`, `work`, `scripts`) is stowed as-is in alphabetical order.
199
+
200
+ ### Adopting files into the right repo
201
+
202
+ ```sh
203
+ # Public config — goes to ~/.public_dotfiles
204
+ dotlayer adopt ~/.config/lazygit config
205
+
206
+ # Private config — goes to ~/.private_dotfiles
207
+ dotlayer adopt --private ~/.config/lazysql config
208
+ ```
209
+
210
+ ### Layer precedence across repos
211
+
212
+ Repos are processed in order. Public packages are stowed first, then private packages overlay on top. This means:
213
+
214
+ 1. `~/.public_dotfiles/config/` — base config (stowed first)
215
+ 2. `~/.public_dotfiles/config-linux/` — OS layer
216
+ 3. `~/.public_dotfiles/config-omarchy/` — distro layer
217
+ 4. `~/.private_dotfiles/config/` — private overlays (stowed after public)
218
+ 5. `~/.private_dotfiles/config-mycompany/` — work group layer
219
+
220
+ Each layer adds files — they never conflict because different layers use different file paths within the same directory structure.
221
+
222
+ ### Keeping private dotfiles private
223
+
224
+ Your private repo doesn't need to be pushed anywhere. It works fine as a local-only git repo for tracking changes. If you do want backup:
225
+
226
+ - Push to a **private GitHub/GitLab repo**
227
+ - Use `dotlayer update` to pull both repos at once — it runs `git pull --rebase` on each repo that has a `.git` directory
144
228
 
145
229
  ## CLI reference
146
230
 
@@ -182,6 +266,16 @@ dotlayer adopt --dry-run ~/.config/lazygit config
182
266
 
183
267
  The last argument is always the package name. Dotlayer finds the first repo containing that package, or falls back to the first repo for new packages.
184
268
 
269
+ ## Development
270
+
271
+ ```sh
272
+ bundle exec rake test # run tests
273
+ bundle exec standardrb # lint
274
+ bundle exec rubycritic lib/ # code quality report
275
+ ```
276
+
277
+ See [Contributing](CONTRIBUTING.md) for full setup, testing, and contribution guidelines.
278
+
185
279
  ## Documentation
186
280
 
187
281
  - [Architecture](docs/architecture.md) — system design, data flow, and class responsibilities
data/lib/dotlayer/cli.rb CHANGED
@@ -13,11 +13,11 @@ module Dotlayer
13
13
  config = Config.new(options[:config])
14
14
 
15
15
  case command
16
- when "status" then Commands::Status.new(config:).run
16
+ when "status" then Commands::Status.new(config:).run
17
17
  when "install" then Commands::Install.new(config:, dry_run: options[:dry_run], verbose: options[:verbose]).run
18
- when "update" then Commands::Update.new(config:, dry_run: options[:dry_run], verbose: options[:verbose]).run
19
- when "doctor" then Commands::Doctor.new(config:).run
20
- when "adopt" then run_adopt(config:, argv:, options:)
18
+ when "update" then Commands::Update.new(config:, dry_run: options[:dry_run], verbose: options[:verbose]).run
19
+ when "doctor" then Commands::Doctor.new(config:).run
20
+ when "adopt" then run_adopt(config:, argv:, options:)
21
21
  when "version"
22
22
  puts "dotlayer #{VERSION}"
23
23
  else
@@ -28,7 +28,7 @@ module Dotlayer
28
28
  private
29
29
 
30
30
  def parse_global_options(argv)
31
- options = { dry_run: false, verbose: false, config: nil, private: false }
31
+ options = {dry_run: false, verbose: false, config: nil, private: false}
32
32
 
33
33
  OptionParser.new do |opts|
34
34
  opts.on("-c", "--config PATH", "Config file path") { |v| options[:config] = v }
@@ -72,7 +72,11 @@ module Dotlayer
72
72
  else
73
73
  warning "#{broken.size} found"
74
74
  broken.each do |link|
75
- target = File.readlink(link) rescue "(deleted)"
75
+ target = begin
76
+ File.readlink(link)
77
+ rescue
78
+ "(deleted)"
79
+ end
76
80
  @issues << "Broken symlink: #{link} -> #{target}"
77
81
  end
78
82
  end
@@ -23,7 +23,7 @@ module Dotlayer
23
23
  end
24
24
 
25
25
  def repos
26
- @repos ||= @data.fetch("repos", [{ "path" => "~/.public_dotfiles" }]).filter_map do |entry|
26
+ @repos ||= @data.fetch("repos", [{"path" => "~/.public_dotfiles"}]).filter_map do |entry|
27
27
  path = entry["path"]&.to_s
28
28
  next if path.nil? || path.empty?
29
29
 
@@ -17,7 +17,7 @@ module Dotlayer
17
17
  def detect_os
18
18
  case RbConfig::CONFIG["host_os"]
19
19
  when /darwin/ then "macos"
20
- when /linux/ then "linux"
20
+ when /linux/ then "linux"
21
21
  else "unknown"
22
22
  end
23
23
  end
@@ -1,5 +1,3 @@
1
- require "set"
2
-
3
1
  module Dotlayer
4
2
  class Resolver
5
3
  def initialize(config:, detection:)
data/lib/dotlayer/stow.rb CHANGED
@@ -20,7 +20,7 @@ module Dotlayer
20
20
  args << package
21
21
 
22
22
  if @verbose || @dry_run
23
- $stderr.puts " #{args.join(" ")}"
23
+ warn " #{args.join(" ")}"
24
24
  end
25
25
 
26
26
  return true if @dry_run
data/lib/dotlayer.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Dotlayer
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.2"
3
3
 
4
4
  autoload :CLI, "dotlayer/cli"
5
5
  autoload :Config, "dotlayer/config"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dotlayer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Douglas Andrade
@@ -53,7 +53,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  requirements: []
56
- rubygems_version: 4.0.3
56
+ rubygems_version: 4.0.8
57
57
  specification_version: 4
58
58
  summary: Layered dotfiles management with GNU Stow
59
59
  test_files: []