dotsync 0.1.18 → 0.1.19

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: 8e9f29b4444bb3395cb499524272b6a1b4ca3071c4055970de7c4c3990ed8d29
4
- data.tar.gz: 9a1e346bb050beb363cb99a5a6f1476d50523cf37bfcc1d9b8dd30038fe74403
3
+ metadata.gz: 296888a8438bcbc159e621b7e1423429c6a937e7d67ec8970c4b0779d85b840f
4
+ data.tar.gz: 2d6fa4363f2a107cd074002ef8d40bb553cf5aa5bb11f52048ec3eb58cf90a09
5
5
  SHA512:
6
- metadata.gz: fbc66575cbb99d7dab60eb1d623058f2c9cc1b13648004a0b14cdaaed28c19c2a6c1f9b13454b90d4acac50566df804df946f94f7104aac0f1b0e161f2b6eb1b
7
- data.tar.gz: 150d2c742dca25f35baa5e288df8a21fa3ab34b4b236769de12f2f183f2064953fbe744494a8e505886cf780ce25b71f5efd05b0967ce0966ac83484e53bf2cc
6
+ metadata.gz: 389498f088842bebc6a45426d1451b9ac5cd00724526fcf92633d7dbf48ad32adc35986067ade21d086963d557a993b58d5a35c6332b5ef6e81ec36065f81600
7
+ data.tar.gz: 740404a8803dcc05f053c0f1b7ba57f1187b7b920a8f34af3217162c554e8d263740bad31921bf8249e9b25820a6905651c200da63e8e072573f031d775516cf
data/AGENTS.md ADDED
@@ -0,0 +1,93 @@
1
+ # Agents
2
+
3
+ This document describes AI agents and automation helpers that can assist with developing and maintaining the Dotsync project.
4
+
5
+ ## Development Agents
6
+
7
+ ### Code Review Agent
8
+
9
+ **Purpose**: Review code changes for quality, consistency, and adherence to Ruby best practices.
10
+
11
+ **When to use**:
12
+ - Before submitting pull requests
13
+ - After implementing new features
14
+ - When refactoring existing code
15
+
16
+ **What it checks**:
17
+ - Ruby style guide compliance (follows .rubocop.yml)
18
+ - Test coverage for new functionality
19
+ - Proper error handling
20
+ - Documentation completeness
21
+ - Performance considerations
22
+
23
+ ### Test Generation Agent
24
+
25
+ **Purpose**: Generate and enhance RSpec tests for Dotsync functionality.
26
+
27
+ **When to use**:
28
+ - When adding new actions or utilities
29
+ - When test coverage is insufficient
30
+ - When refactoring existing code
31
+
32
+ **Focus areas**:
33
+ - Unit tests for models (Mapping, Diff)
34
+ - Integration tests for actions (PullAction, PushAction, WatchAction)
35
+ - Edge cases and error scenarios
36
+ - File system operations
37
+
38
+ ### Documentation Agent
39
+
40
+ **Purpose**: Maintain and improve project documentation.
41
+
42
+ **When to use**:
43
+ - After adding new features
44
+ - When configuration options change
45
+ - When updating usage examples
46
+
47
+ **Responsibilities**:
48
+ - Keep README.md synchronized with code
49
+ - Update inline code documentation
50
+ - Maintain CHANGELOG.md
51
+ - Generate usage examples
52
+
53
+ ## Maintenance Agents
54
+
55
+ ### Dependency Update Agent
56
+
57
+ **Purpose**: Monitor and suggest updates for gem dependencies.
58
+
59
+ **What it monitors**:
60
+ - Security vulnerabilities in dependencies
61
+ - New versions of runtime and development dependencies
62
+ - Ruby version compatibility
63
+
64
+ ### Release Agent
65
+
66
+ **Purpose**: Assist with the release process following RELEASING.md guidelines.
67
+
68
+ **Checklist**:
69
+ - Version number updated in version.rb
70
+ - CHANGELOG.md updated with changes
71
+ - Tests passing
72
+ - RuboCop compliance
73
+ - Tag creation and push
74
+ - Gem publication to rubygems.org
75
+
76
+ ## Usage
77
+
78
+ To work with these agents effectively:
79
+
80
+ 1. **Be specific**: Provide clear context about what you're working on
81
+ 2. **Reference files**: Point to specific files or line numbers when discussing issues
82
+ 3. **Run tests**: Always run `rake spec` after changes
83
+ 4. **Follow conventions**: Adhere to existing code patterns and Ruby style guide
84
+
85
+ ## Contributing
86
+
87
+ When working with agents on this project:
88
+
89
+ - Review generated code carefully before committing
90
+ - Ensure all tests pass (`rake spec`)
91
+ - Run RuboCop (`bundle exec rubocop`)
92
+ - Update documentation as needed
93
+ - Follow the project's [Code of Conduct](CODE_OF_CONDUCT.md)
data/CHANGELOG.md CHANGED
@@ -1,3 +1,33 @@
1
+ # 0.1.19
2
+
3
+ **Documentation & Testing:**
4
+ - Add comprehensive icons test suite with 40 test cases covering all icon functionality
5
+ - Add icons customization documentation section to README with complete examples
6
+ - Add "What is Dotsync?" overview section highlighting 7 key features
7
+ - Add Table of Contents for improved README navigation
8
+ - Add Quick Start guide with 5-step setup process
9
+ - Add Common Use Cases section with practical configuration examples (Neovim, Alacritty, shell configs)
10
+ - Add comprehensive Troubleshooting section covering 6 common issues and solutions
11
+ - Enhance Pro Tips section with 7 useful tips including environment variables and backup locations
12
+ - Add License and Ruby version badges to README
13
+ - Add IMPORTANT callout about --apply flag and preview mode behavior
14
+
15
+ **Bug Fixes:**
16
+ - Fix duplicate `src` typo in push/watch mapping examples (corrected to `dest`)
17
+ - Fix section title: "force and ignore" → "force, only, and ignore"
18
+ - Add defensive nil handling in `Icons.load_custom_icons` method
19
+
20
+ **Developer Experience:**
21
+ - Add AGENTS.md with AI agent guidelines for project development
22
+ - Improve user onboarding with clearer documentation and examples
23
+
24
+ # 0.1.18
25
+
26
+ - Add automatic version checking with non-intrusive upgrade prompts
27
+ - Version check runs once per 24 hours using cached timestamp
28
+ - Can be disabled with `DOTSYNC_NO_UPDATE_CHECK` environment variable
29
+ - Cache stored in XDG-compliant location (`~/.cache/dotsync/last_version_check`)
30
+
1
31
  # 0.1.17
2
32
 
3
33
  - Fixes skipped files
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dotsync (0.1.18)
4
+ dotsync (0.1.19)
5
5
  fileutils (~> 1.7.3)
6
6
  find (~> 0.2.0)
7
7
  listen (~> 3.9.0)
data/README.md CHANGED
@@ -2,11 +2,42 @@
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/dotsync.svg)](https://rubygems.org/gems/dotsync)
4
4
  [![Ruby Gem Test Status](https://github.com/dsaenztagarro/dotsync/actions/workflows/gem-push.yml/badge.svg)](https://github.com/dsaenztagarro/dotsync/actions)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+ [![Ruby Version](https://img.shields.io/badge/ruby-%3E%3D%203.2-blue)](https://www.ruby-lang.org/)
5
7
 
6
8
  > [!WARNING]
7
9
  > This gem is under active development. You can expect new changes that may not be backward-compatible.
8
10
 
9
- Welcome to Dotsync! This gem helps you manage and synchronize your dotfiles effortlessly. Below you'll find information on installation, usage, and some tips for getting started.
11
+ ## What is Dotsync?
12
+
13
+ Dotsync is a powerful Ruby gem for managing and synchronizing your dotfiles across machines. Whether you're setting up a new development environment or keeping configurations in sync, Dotsync makes it effortless.
14
+
15
+ **Key Features:**
16
+ - **Bidirectional Sync**: Push local dotfiles to your repository or pull from repository to local machine
17
+ - **Preview Mode**: See what changes would be made before applying them (dry-run by default)
18
+ - **Smart Filtering**: Use `force`, `only`, and `ignore` options to precisely control what gets synced
19
+ - **Automatic Backups**: Pull operations create timestamped backups for easy recovery
20
+ - **Live Watching**: Continuously monitor and sync changes in real-time with `watch` command
21
+ - **Customizable Output**: Control verbosity and customize icons to match your preferences
22
+ - **Auto-Updates**: Get notified when new versions are available
23
+
24
+ ## Table of Contents
25
+
26
+ - [Requirements](#requirements)
27
+ - [Installation](#installation)
28
+ - [Quick Start](#quick-start)
29
+ - [Usage](#usage)
30
+ - [Executable Commands](#executable-commands)
31
+ - [Configuration](#configuration)
32
+ - [Customizing Icons](#customizing-icons)
33
+ - [Automatic Update Checks](#automatic-update-checks)
34
+ - [Pro Tips](#pro-tips)
35
+ - [Common Use Cases](#common-use-cases)
36
+ - [Troubleshooting](#troubleshooting)
37
+ - [Development](#development)
38
+ - [Contributing](#contributing)
39
+ - [License](#license)
40
+ - [Code of Conduct](#code-of-conduct)
10
41
 
11
42
  ![dotsync options](docs/images/dotsync_options.png)
12
43
 
@@ -29,12 +60,48 @@ Or install it yourself as:
29
60
 
30
61
  $ gem install dotsync
31
62
 
63
+ ## Quick Start
64
+
65
+ Get started with Dotsync in just a few steps:
66
+
67
+ 1. **Install the gem**:
68
+ ```shell
69
+ gem install dotsync
70
+ ```
71
+
72
+ 2. **Generate a default configuration**:
73
+ ```shell
74
+ dotsync setup
75
+ ```
76
+ This creates `~/.config/dotsync.toml` with example mappings.
77
+
78
+ 3. **Edit the configuration** (`~/.config/dotsync.toml`) to define your dotfile mappings:
79
+ ```toml
80
+ [[pull.mappings]]
81
+ src = "$HOME/dotfiles/config"
82
+ dest = "$HOME/.config"
83
+ ```
84
+
85
+ 4. **Preview your changes** (dry-run mode):
86
+ ```shell
87
+ dotsync pull
88
+ ```
89
+ This shows what would be changed without modifying any files.
90
+
91
+ 5. **Apply changes** when you're ready:
92
+ ```shell
93
+ dotsync pull --apply
94
+ ```
95
+
32
96
  ## Usage
33
97
 
34
98
  ### Executable Commands
35
99
 
36
100
  Dotsync provides the following commands to manage your dotfiles:
37
101
 
102
+ > [!IMPORTANT]
103
+ > By default, both `push` and `pull` commands run in **preview mode** (dry-run). They will show you what changes would be made without actually modifying any files. To apply changes, you **must** use the `--apply` flag.
104
+
38
105
  - **Push**: Transfer dotfiles from your local machine to the destination repository.
39
106
  ```shell
40
107
  dotsync push --apply [OPTION]
@@ -108,7 +175,7 @@ dest = "$HOME"
108
175
 
109
176
  [[push.mappings]]
110
177
  src = "$HOME/.zshenv"
111
- src = "$HOME_MIRROR/.zshenv"
178
+ dest = "$HOME_MIRROR/.zshenv"
112
179
 
113
180
  [[push.mappings]]
114
181
  src = "$XDG_CONFIG_HOME/alacritty"
@@ -119,7 +186,7 @@ only = ["alacritty.toml", "rose-pine.toml"]
119
186
 
120
187
  [[watch.mappings]]
121
188
  src = "$HOME/.zshenv"
122
- src = "$HOME_MIRROR/.zshenv"
189
+ dest = "$HOME_MIRROR/.zshenv"
123
190
 
124
191
  [[watch.mappings]]
125
192
  src = "$XDG_CONFIG_HOME/alacritty"
@@ -133,7 +200,7 @@ dest = "$DOTFILES_DIR/config/alacritty"
133
200
  > export XDG_CONFIG_HOME_MIRROR="$HOME/Code/dotfiles/xdg_config_home"
134
201
  > ```
135
202
 
136
- #### `force` and `ignore` Options in Mappings
203
+ #### `force`, `only`, and `ignore` Options in Mappings
137
204
 
138
205
  Each mapping entry supports the following options:
139
206
 
@@ -150,34 +217,97 @@ Each mapping entry supports the following options:
150
217
 
151
218
  These options apply when the source is a directory and are relevant for both `push` and `pull` operations.
152
219
 
153
- ### Rendering Mappings with Icons
220
+ ### Customizing Icons
154
221
 
155
- When running `push` or `pull` actions, the mappings are rendered in the console with relevant icons to provide visual feedback on the status of each mapping. To correctly view these icons, ensure you are using a terminal that supports a patched [Nerd Font](https://www.nerdfonts.com). Below are some examples of how the mappings are displayed:
222
+ Dotsync allows you to customize the icons displayed in the console output by adding an `[icons]` section to your configuration file (`~/.config/dotsync.toml`). This is useful if you prefer different icons or need compatibility with terminals that don't support Nerd Fonts.
156
223
 
157
- - **Force Icon**:
158
- ```
159
- Mappings:
160
- $DOTFILES_DIR/config/ → $XDG_CONFIG_HOME ⚡
161
- ```
162
- The ⚡ icon (`Dotsync::Icons::FORCE`) indicates that the `force` option is enabled and the destination folder will be cleared before the transfer.
224
+ #### Available Icon Options
163
225
 
164
- - **Ignore Icon**:
165
- ```
166
- Mappings:
167
- $DOTFILES_DIR/home/.zshenv $HOME 🚫
168
- ```
169
- The 🚫 icon (`Dotsync::Icons::IGNORE`) indicates that certain files or patterns are being ignored during the transfer.
226
+ You can customize the following icons in your configuration:
227
+
228
+ **Mapping Status Icons** (shown next to each mapping):
229
+ - `force` - Indicates force deletion is enabled (clears destination before transfer)
230
+ - `only` - Indicates only specific files will be transferred
231
+ - `ignore` - Indicates files are being ignored during transfer
232
+ - `invalid` - Indicates the mapping is invalid (missing source/destination)
233
+
234
+ **Difference Status Icons** (shown in diff output):
235
+ - `diff_created` - Shows newly created/added files
236
+ - `diff_updated` - Shows updated/modified files
237
+ - `diff_removed` - Shows removed/deleted files
238
+
239
+ #### Example Configuration
240
+
241
+ Here's a complete example showing all customizable icons using UTF-8 emojis (works without Nerd Fonts):
242
+
243
+ ```toml
244
+ [icons]
245
+ # Mapping status icons
246
+ force = "⚡" # Force deletion enabled
247
+ only = "📋" # Only specific files transferred
248
+ ignore = "🚫" # Files ignored during transfer
249
+ invalid = "❌" # Invalid mapping
250
+
251
+ # Diff status icons
252
+ diff_created = "✨" # New files created
253
+ diff_updated = "📝" # Files modified
254
+ diff_removed = "🗑️ " # Files deleted
255
+
256
+ # Example mappings section
257
+ [[pull.mappings]]
258
+ src = "$XDG_CONFIG_HOME_MIRROR"
259
+ dest = "$XDG_CONFIG_HOME"
260
+ ignore = ["cache"]
261
+ ```
170
262
 
171
- - **Invalid Icon**:
263
+ #### Default Icons
264
+
265
+ If you don't specify custom icons, Dotsync uses [Nerd Font](https://www.nerdfonts.com) icons by default. These icons will only display correctly if you're using a terminal with a patched Nerd Font installed.
266
+
267
+ | Icon | Default (Nerd Font) | Nerd Font Code | Purpose |
268
+ |------|---------------------|----------------|---------|
269
+ | `force` | `󰁪 ` | `nf-md-lightning_bolt` | Force deletion enabled |
270
+ | `only` | ` ` | `nf-md-filter` | Only mode active |
271
+ | `ignore` | `󰈉 ` | `nf-md-cancel` | Ignoring files |
272
+ | `invalid` | `󱏏 ` | `nf-md-alert_octagram` | Invalid mapping |
273
+ | `diff_created` | ` ` | `nf-md-plus` | File created |
274
+ | `diff_updated` | ` ` | `nf-md-pencil` | File updated |
275
+ | `diff_removed` | ` ` | `nf-md-minus` | File removed |
276
+
277
+ > [!NOTE]
278
+ > The icons in the "Default (Nerd Font)" column may not be visible unless you're viewing this with a Nerd Font. You can find these icons at [nerdfonts.com](https://www.nerdfonts.com/cheat-sheet) by searching for the Nerd Font Code.
279
+
280
+ > [!TIP]
281
+ > You can set any icon to an empty string (`""`) to hide it completely, or use any UTF-8 character or emoji. The `dotsync setup` command generates a configuration file with some example custom icons to get you started.
282
+
283
+ ### Automatic Update Checks
284
+
285
+ Dotsync automatically checks for new versions once per day and notifies you if an update is available. This check is non-intrusive and will not interrupt your workflow.
286
+
287
+ To disable automatic update checks:
288
+ - Set environment variable: `export DOTSYNC_NO_UPDATE_CHECK=1`
289
+
290
+ The check runs after your command completes and uses a cached timestamp to avoid excessive API calls. The cache is stored in `~/.cache/dotsync/last_version_check` following the XDG Base Directory specification.
291
+
292
+ ### Pro Tips
293
+
294
+ - **Preview Before Applying**: Always run commands without `--apply` first to preview changes:
295
+ ```shell
296
+ dotsync pull # Preview changes
297
+ dotsync pull --apply # Apply after reviewing
172
298
  ```
173
- Mappings:
174
- $DOTFILES_DIR/home/.vimrc $HOME
299
+
300
+ - **Using Environment Variables**: Simplify your configuration with mirror environment variables:
301
+ ```bash
302
+ # Add to your ~/.zshrc or ~/.bashrc
303
+ export DOTFILES_DIR="$HOME/dotfiles"
304
+ export XDG_CONFIG_HOME_MIRROR="$DOTFILES_DIR/config"
305
+ export HOME_MIRROR="$DOTFILES_DIR/home"
175
306
  ```
176
- The ❌ icon (`Dotsync::Icons::INVALID`) indicates that the mapping is invalid due to missing source or destination paths.
177
307
 
178
- ### Pro Tips
308
+ - **Backup Location**: Pull operations automatically backup files to `~/.cache/dotsync/backups/` with timestamps. Only the 10 most recent backups are kept.
179
309
 
180
- - **Using rbenv**: To ensure the gem uses the correct Ruby version managed by rbenv, you can run:
310
+ - **Using rbenv**: To ensure the gem uses the correct Ruby version managed by rbenv:
181
311
  ```shell
182
312
  RBENV_VERSION=3.2.0 dotsync push
183
313
  ```
@@ -187,6 +317,127 @@ When running `push` or `pull` actions, the mappings are rendered in the console
187
317
  gem install dotsync
188
318
  ```
189
319
 
320
+ - **Disable Update Checks**: If you prefer not to see update notifications:
321
+ ```shell
322
+ export DOTSYNC_NO_UPDATE_CHECK=1
323
+ ```
324
+
325
+ - **Quiet Mode**: For use in scripts or when you only want to see errors:
326
+ ```shell
327
+ dotsync pull --apply --quiet
328
+ ```
329
+
330
+ ## Common Use Cases
331
+
332
+ Here are some practical examples of how to use Dotsync for popular configuration files:
333
+
334
+ ### Syncing Neovim Configuration
335
+
336
+ ```toml
337
+ [[pull.mappings]]
338
+ src = "$HOME/dotfiles/config/nvim"
339
+ dest = "$HOME/.config/nvim"
340
+ force = true
341
+ ignore = ["lazy-lock.json", ".luarc.json"]
342
+ ```
343
+
344
+ ### Syncing Terminal Emulator (Alacritty)
345
+
346
+ ```toml
347
+ [[push.mappings]]
348
+ src = "$HOME/.config/alacritty"
349
+ dest = "$HOME/dotfiles/config/alacritty"
350
+ only = ["alacritty.toml", "themes"]
351
+ ```
352
+
353
+ ### Syncing Shell Configuration
354
+
355
+ ```toml
356
+ [[pull.mappings]]
357
+ src = "$HOME/dotfiles/shell/.zshrc"
358
+ dest = "$HOME"
359
+
360
+ [[pull.mappings]]
361
+ src = "$HOME/dotfiles/shell/.zshenv"
362
+ dest = "$HOME"
363
+ ```
364
+
365
+ ### Syncing Multiple Config Directories
366
+
367
+ ```toml
368
+ [[pull.mappings]]
369
+ src = "$HOME/dotfiles/config"
370
+ dest = "$HOME/.config"
371
+ ignore = ["nvim", "cache", "*.log"]
372
+ ```
373
+
374
+ ## Troubleshooting
375
+
376
+ ### Icons Not Displaying Correctly
377
+
378
+ **Problem**: Icons appear as boxes, question marks, or strange characters.
379
+
380
+ **Solution**:
381
+ - Install a [Nerd Font](https://www.nerdfonts.com/) and configure your terminal to use it
382
+ - Or customize icons in `~/.config/dotsync.toml` using UTF-8 emojis or regular characters:
383
+ ```toml
384
+ [icons]
385
+ force = "!"
386
+ only = "*"
387
+ ignore = "x"
388
+ invalid = "?"
389
+ diff_created = "+"
390
+ diff_updated = "~"
391
+ diff_removed = "-"
392
+ ```
393
+
394
+ ### Changes Not Being Applied
395
+
396
+ **Problem**: Running `dotsync push` or `dotsync pull` doesn't modify files.
397
+
398
+ **Solution**: Remember to use the `--apply` flag to apply changes. Without it, commands run in preview mode:
399
+ ```shell
400
+ dotsync pull --apply
401
+ ```
402
+
403
+ ### Permission Denied Errors
404
+
405
+ **Problem**: Getting permission errors when syncing files.
406
+
407
+ **Solution**:
408
+ - Ensure you have write permissions for destination directories
409
+ - Check file ownership: `ls -la ~/.config`
410
+ - For system directories, you may need to adjust your mappings to use user-writable locations
411
+
412
+ ### Source or Destination Not Found
413
+
414
+ **Problem**: Error messages about missing source or destination paths.
415
+
416
+ **Solution**:
417
+ - Verify environment variables are set correctly (e.g., `echo $XDG_CONFIG_HOME`)
418
+ - Use absolute paths in your configuration if environment variables aren't available
419
+ - Create destination directories before running pull: `mkdir -p ~/.config`
420
+
421
+ ### Restoring from Backups
422
+
423
+ **Problem**: Need to restore files after a pull operation.
424
+
425
+ **Solution**: Pull operations create automatic backups in `~/.cache/dotsync/backups/`:
426
+ ```shell
427
+ ls -la ~/.cache/dotsync/backups/
428
+ # Copy files from the timestamped backup directory
429
+ cp -r ~/.cache/dotsync/backups/YYYYMMDD_HHMMSS/* ~/.config/
430
+ ```
431
+
432
+ ### Watch Command Not Detecting Changes
433
+
434
+ **Problem**: `dotsync watch` doesn't sync changes automatically.
435
+
436
+ **Solution**:
437
+ - Verify your watch mappings are configured correctly in `~/.config/dotsync.toml`
438
+ - Ensure the source directories exist and are accessible
439
+ - Try stopping and restarting the watch command
440
+
190
441
  ## Development
191
442
 
192
443
  - After checking out the repo, run `bin/setup` to install dependencies.
data/lib/dotsync/icons.rb CHANGED
@@ -43,6 +43,7 @@ module Dotsync
43
43
  @custom_icons = {}
44
44
 
45
45
  def self.load_custom_icons(config)
46
+ config ||= {}
46
47
  @custom_icons = {
47
48
  # Mappings Legend
48
49
  force: config.dig("icons", "force") || DEFAULT_FORCE,
@@ -33,6 +33,8 @@ module Dotsync
33
33
  @logger.error("Error running '#{action_name}':")
34
34
  @logger.info(e.message)
35
35
  raise
36
+ ensure
37
+ check_for_updates
36
38
  end
37
39
  end
38
40
  end
@@ -77,6 +79,17 @@ module Dotsync
77
79
  @logger.info("Configuration file created at #{config_path}")
78
80
  end
79
81
 
82
+ # Check for available updates
83
+ def check_for_updates
84
+ return if ENV["DOTSYNC_NO_UPDATE_CHECK"]
85
+
86
+ checker = Dotsync::VersionChecker.new(Dotsync::VERSION, logger: @logger)
87
+ checker.check_for_updates if checker.should_check?
88
+ rescue => e
89
+ # Silently fail - never break the tool
90
+ @logger.log("Debug: Version check failed - #{e.message}") if ENV["DEBUG"]
91
+ end
92
+
80
93
  # Utility to convert 'pull' to 'Pull', 'sync' to 'Sync', etc.
81
94
  def camelize(str)
82
95
  str.split("_").map(&:capitalize).join
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+ require "json"
5
+ require "time"
6
+ require "fileutils"
7
+
8
+ module Dotsync
9
+ class VersionChecker
10
+ include Dotsync::XDGBaseDirectory
11
+
12
+ RUBYGEMS_API_URL = "https://rubygems.org/api/v1/versions/dotsync/latest.json"
13
+ CHECK_INTERVAL = 86400 # 24 hours in seconds
14
+ REQUEST_TIMEOUT = 3 # seconds
15
+
16
+ def initialize(current_version, logger: nil)
17
+ @current_version = current_version
18
+ @logger = logger
19
+ end
20
+
21
+ # Returns true if we should check for updates (cache expired or doesn't exist)
22
+ def should_check?
23
+ return false if ENV["DOTSYNC_NO_UPDATE_CHECK"]
24
+ return true unless File.exist?(cache_file_path)
25
+
26
+ Time.now - last_check_time > CHECK_INTERVAL
27
+ rescue => e
28
+ # If we can't determine, be conservative and don't check
29
+ debug_log("Error checking if should check: #{e.message}")
30
+ false
31
+ end
32
+
33
+ # Main method to check for updates and display message if needed
34
+ def check_for_updates
35
+ return unless should_check?
36
+
37
+ latest_version = fetch_latest_version
38
+ return unless latest_version
39
+
40
+ update_cache
41
+
42
+ display_update_message(latest_version) if version_outdated?(@current_version, latest_version)
43
+ rescue => e
44
+ # Silently fail - never break the application
45
+ debug_log("Error checking for updates: #{e.message}")
46
+ end
47
+
48
+ private
49
+ def cache_file_path
50
+ @cache_file_path ||= File.join(xdg_cache_home, "dotsync", "last_version_check")
51
+ end
52
+
53
+ def last_check_time
54
+ return Time.at(0) unless File.exist?(cache_file_path)
55
+
56
+ Time.parse(File.read(cache_file_path).strip)
57
+ rescue => e
58
+ debug_log("Error reading cache time: #{e.message}")
59
+ Time.at(0)
60
+ end
61
+
62
+ def update_cache
63
+ FileUtils.mkdir_p(File.dirname(cache_file_path))
64
+ File.write(cache_file_path, Time.now.iso8601)
65
+ rescue => e
66
+ debug_log("Error updating cache: #{e.message}")
67
+ end
68
+
69
+ def fetch_latest_version
70
+ uri = URI(RUBYGEMS_API_URL)
71
+
72
+ response = Net::HTTP.start(uri.host, uri.port, use_ssl: true, open_timeout: REQUEST_TIMEOUT, read_timeout: REQUEST_TIMEOUT) do |http|
73
+ request = Net::HTTP::Get.new(uri)
74
+ http.request(request)
75
+ end
76
+
77
+ return nil unless response.is_a?(Net::HTTPSuccess)
78
+
79
+ data = JSON.parse(response.body)
80
+ data["version"]
81
+ rescue => e
82
+ debug_log("Error fetching latest version: #{e.message}")
83
+ nil
84
+ end
85
+
86
+ def version_outdated?(current, latest)
87
+ Gem::Version.new(current) < Gem::Version.new(latest)
88
+ rescue => e
89
+ debug_log("Error comparing versions: #{e.message}")
90
+ false
91
+ end
92
+
93
+ def display_update_message(latest_version)
94
+ msg = "\n"
95
+ msg += "\e[38;5;226m" # Yellow color
96
+ msg += "A new version of dotsync is available: #{latest_version} "
97
+ msg += "(current: #{@current_version})\n"
98
+ msg += "Run 'gem update dotsync' to upgrade"
99
+ msg += "\e[0m\n" # Reset color
100
+
101
+ $stderr.puts msg
102
+ end
103
+
104
+ def debug_log(message)
105
+ return unless ENV["DEBUG"]
106
+
107
+ if @logger
108
+ @logger.log("Debug: #{message}")
109
+ else
110
+ $stderr.puts "Debug: #{message}"
111
+ end
112
+ end
113
+ end
114
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dotsync
4
- VERSION = "0.1.18"
4
+ VERSION = "0.1.19"
5
5
  end
data/lib/dotsync.rb CHANGED
@@ -17,19 +17,20 @@ require_relative "dotsync/colors"
17
17
  require_relative "dotsync/runner"
18
18
  require_relative "dotsync/version"
19
19
 
20
+ # Config Concerns (loaded early as they're used by other modules)
21
+ require_relative "dotsync/config/concerns/xdg_base_directory"
22
+
20
23
  # Utils
21
24
  require_relative "dotsync/utils/path_utils"
22
25
  require_relative "dotsync/utils/logger"
23
26
  require_relative "dotsync/utils/file_transfer"
24
27
  require_relative "dotsync/utils/directory_differ"
28
+ require_relative "dotsync/utils/version_checker"
25
29
 
26
30
  # Models
27
31
  require_relative "dotsync/models/mapping"
28
32
  require_relative "dotsync/models/diff"
29
33
 
30
- # Config Concerns
31
- require_relative "dotsync/config/concerns/xdg_base_directory"
32
-
33
34
  # Config
34
35
  require_relative "dotsync/config/base_config"
35
36
  require_relative "dotsync/config/pull_action_config"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dotsync
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.18
4
+ version: 0.1.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Sáenz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-11-09 00:00:00.000000000 Z
11
+ date: 2025-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: toml-rb
@@ -262,6 +262,7 @@ files:
262
262
  - ".rspec"
263
263
  - ".rubocop.yml"
264
264
  - ".ruby-version"
265
+ - AGENTS.md
265
266
  - CHANGELOG.md
266
267
  - CODE_OF_CONDUCT.md
267
268
  - Gemfile
@@ -301,6 +302,7 @@ files:
301
302
  - lib/dotsync/utils/file_transfer.rb
302
303
  - lib/dotsync/utils/logger.rb
303
304
  - lib/dotsync/utils/path_utils.rb
305
+ - lib/dotsync/utils/version_checker.rb
304
306
  - lib/dotsync/version.rb
305
307
  homepage: https://github.com/dsaenztagarro/dotsync
306
308
  licenses: