dotsync 0.1.13 → 0.1.14

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: 6902bf77ffae5ae4fa88c9a35e452207c7ee5fd1cc274690023a5e2622079681
4
- data.tar.gz: 024ac7795cae1eee0a342f96b7957a024297d64bac16e1375b7541b0e963e8b5
3
+ metadata.gz: 1a3bda4bc44a07335f8373e9411b3bf480b3531875e7decf97bd7b8bf013737f
4
+ data.tar.gz: f16173b0468886005524702cf3b808a46c90d6c06d1bef30228b6d3d7cbf08cb
5
5
  SHA512:
6
- metadata.gz: aa928d590ce5a9fc6e7494e9c31c542ed336e0ce7a46afaf3050847acefb9033c9b7812027661e49c963f1cb17204e4b0ab81820ccb2544964aaa1d8159f97ba
7
- data.tar.gz: 17d532898d18d4b11a11f649fdfd097f37af75dbd091096b52da9eb6ba420cce28657f37872c912636a71e7206ae391f30c69523a4b59ae214e5fdab9ac54027
6
+ metadata.gz: f558392c0c9f8cf336fa7088c99df08e9d390f5e29eb2b2a62286aeae09fd13fde752499dff070bf0cd683195a2514d2b911d6adebcb82247e9430575501e3ae
7
+ data.tar.gz: edb809cda8a1d9c5c2aec1bd9f0588015df1bb2d4ffad14d7fe1761ae8ff30494c8e57f96ca46cbc7a1e2221b395948fad2d42454e6bcea621f05aa9238aaf15
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ # 0.1.14
2
+
3
+ - Render environment variables and mappings with a table
4
+ - Added mappings legend
5
+ - Added transfer files with "only" option
6
+
1
7
  # 0.1.13
2
8
 
3
9
  - PullAction: backup message simplified
data/Gemfile.lock CHANGED
@@ -1,12 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dotsync (0.1.13)
4
+ dotsync (0.1.14)
5
5
  fileutils (~> 1.7.3)
6
6
  find (~> 0.2.0)
7
7
  listen (~> 3.9.0)
8
8
  logger (~> 1.7.0)
9
9
  ostruct (~> 0.6.3)
10
+ terminal-table (~> 4.0.0)
10
11
  toml-rb (~> 4.0.0)
11
12
 
12
13
  GEM
@@ -118,6 +119,8 @@ GEM
118
119
  rbs (>= 3, < 5)
119
120
  ruby-progressbar (1.13.0)
120
121
  stringio (3.1.7)
122
+ terminal-table (4.0.0)
123
+ unicode-display_width (>= 1.1.1, < 4)
121
124
  timecop (0.9.10)
122
125
  toml-rb (4.0.0)
123
126
  citrus (~> 3.0, > 3.0)
data/README.md CHANGED
@@ -35,14 +35,14 @@ Dotsync provides the following commands to manage your dotfiles:
35
35
 
36
36
  - **Push**: Transfer dotfiles from your local machine to the destination repository.
37
37
  ```shell
38
- dotsync push
38
+ dotsync push --apply
39
39
  ```
40
40
 
41
41
  ![dotsync push](docs/images/dotsync_push.png)
42
42
 
43
43
  - **Pull**: Synchronize dotfiles from the repository to your local machine.
44
44
  ```shell
45
- dotsync pull
45
+ dotsync pull --apply
46
46
  ```
47
47
 
48
48
  During the `pull` operation, `Dotsync::PullAction` creates a backup of the existing files on the destination. These backups are stored in a directory under the XDG path, with each backup organized by a timestamp. To prevent excessive storage usage, only the 10 most recent backups are retained. Older backups are automatically purged, ensuring efficient storage management.
@@ -72,8 +72,10 @@ ignore = ["nvim"]
72
72
  [[pull.mappings]]
73
73
  src = "$XDG_CONFIG_HOME_MIRROR/nvim"
74
74
  dest = "$XDG_CONFIG_HOME/nvim"
75
- force = true # it forces the deletion of destination folder
76
- ignore = ["lazy-lock.json"] # use relative paths to "dest" to ignore files and folders
75
+ # FEATURE: forces the deletion of destination folder
76
+ force = true
77
+ # FEATURE: use relative paths to "dest" to ignore files and folders
78
+ ignore = ["lazy-lock.json"]
77
79
 
78
80
  [[pull.mappings]]
79
81
  src = "$HOME_MIRROR/.zshenv"
@@ -87,6 +89,8 @@ src = "$HOME_MIRROR/.zshenv"
87
89
  [[push.mappings]]
88
90
  src = "$XDG_CONFIG_HOME/alacritty"
89
91
  dest = "$DOTFILES_DIR/config/alacritty"
92
+ # FEATURE: transfer only relative paths of files and folders passed here
93
+ only = ["alacritty.toml", "rose-pine.toml"]
90
94
 
91
95
 
92
96
  [[watch.mappings]]
data/dotsync.gemspec CHANGED
@@ -33,6 +33,7 @@ Gem::Specification.new do |spec|
33
33
  spec.add_dependency "logger", "~> 1.7.0" # No longer part of default gems from Ruby 3.5
34
34
  spec.add_dependency "ostruct", "~> 0.6.3" # No longer part of default gems from Ruby 3.5
35
35
  spec.add_dependency "find", "~> 0.2.0"
36
+ spec.add_dependency "terminal-table", "~> 4.0.0"
36
37
 
37
38
  # Debug with:
38
39
  # require 'debug'; binding.break
@@ -23,6 +23,7 @@ module Dotsync
23
23
  def show_options(options)
24
24
  info("Options:", icon: :options)
25
25
  logger.log(" Apply: #{options[:apply] ? "TRUE" : "FALSE"}")
26
+ logger.log("")
26
27
  end
27
28
  end
28
29
  end
@@ -2,6 +2,15 @@
2
2
 
3
3
  module Dotsync
4
4
  module MappingsTransfer
5
+ include Dotsync::PathUtils
6
+
7
+ LEGEND = [
8
+ [Dotsync::Icons.force, "The source will overwrite the destination"],
9
+ [Dotsync::Icons.only, " Only paths configured to considered in the source"],
10
+ [Dotsync::Icons.ignore, "Paths configured to be ignored in the destination"],
11
+ [Dotsync::Icons.invalid, "Invalid paths detected in the source or destination"]
12
+ ]
13
+
5
14
  extend Forwardable # def_delegator
6
15
 
7
16
  def_delegator :@config, :mappings
@@ -11,17 +20,33 @@ module Dotsync
11
20
  return unless env_vars.any?
12
21
 
13
22
  info("Environment variables:", icon: :env_vars)
14
- env_vars.each do |env_var|
15
- logger.log(" #{env_var}: #{ENV[env_var]}")
16
- end
23
+
24
+ rows = env_vars.map { |env_var| [env_var, ENV[env_var]] }.sort_by(&:first)
25
+ table = Terminal::Table.new(rows: rows)
26
+ logger.log(table)
27
+ logger.log("")
28
+ end
29
+
30
+ def show_mappings_legend
31
+ info("Legend:", icon: :legend)
32
+ table = Terminal::Table.new(rows: LEGEND)
33
+ logger.log(table)
34
+ logger.log("")
17
35
  end
18
36
 
19
37
  def show_mappings
20
38
  info("Mappings:", icon: :config)
21
39
 
22
- mappings.each do |mapping|
23
- logger.log(" #{mapping}")
40
+ rows = mappings.map do |mapping|
41
+ [
42
+ mapping.icons,
43
+ colorize_env_vars(mapping.original_src),
44
+ colorize_env_vars(mapping.original_dest)
45
+ ]
24
46
  end
47
+ table = Terminal::Table.new(headings: ["Flags", "Source", "Destination"], rows: rows)
48
+ logger.log(table)
49
+ logger.log("")
25
50
  end
26
51
 
27
52
  def show_changes
@@ -9,6 +9,7 @@ module Dotsync
9
9
  def execute(options = {})
10
10
  show_options(options)
11
11
  show_env_vars
12
+ show_mappings_legend
12
13
  show_mappings
13
14
  show_changes
14
15
  return unless options[:apply]
@@ -19,7 +20,7 @@ module Dotsync
19
20
  end
20
21
 
21
22
  transfer_mappings
22
- action("Dotfiles pulled")
23
+ action("Mappings pulled", icon: :done)
23
24
  end
24
25
 
25
26
  private
@@ -7,12 +7,13 @@ module Dotsync
7
7
  def execute(options = {})
8
8
  show_options(options)
9
9
  show_env_vars
10
+ show_mappings_legend
10
11
  show_mappings
11
12
  show_changes
12
13
  return unless options[:apply]
13
14
 
14
15
  transfer_mappings
15
- action("Dotfiles pushed", icon: :copy)
16
+ action("Mappings pushed", icon: :done)
16
17
  end
17
18
  end
18
19
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Dotsync
4
4
  class WatchAction < BaseAction
5
+ include Dotsync::MappingsTransfer
6
+
5
7
  def_delegator :@config, :mappings
6
8
 
7
9
  def initialize(config, logger)
@@ -11,7 +13,8 @@ module Dotsync
11
13
  end
12
14
 
13
15
  def execute
14
- show_config
16
+ show_mappings_legend
17
+ show_mappings
15
18
 
16
19
  @listeners.each(&:start)
17
20
 
@@ -21,11 +24,6 @@ module Dotsync
21
24
  end
22
25
 
23
26
  private
24
- def show_config
25
- logger.info("Mappings:", icon: :config)
26
- mappings.each { |mapping| logger.log(" #{mapping}") }
27
- end
28
-
29
27
  def setup_listeners
30
28
  @listeners = mappings.map do |mapping|
31
29
  src = mapping.src
data/lib/dotsync/icons.rb CHANGED
@@ -9,11 +9,13 @@ module Dotsync
9
9
  # Configuration icon
10
10
  OPTIONS = " "
11
11
  ENV_VARS = " "
12
+ LEGEND = " "
12
13
  CONFIG = " "
13
14
  DIFF = " "
14
15
 
15
- # Default Mapping icons
16
+ # Default Mapping Flags icons
16
17
  DEFAULT_FORCE = "󰁪 "
18
+ DEFAULT_ONLY = " "
17
19
  DEFAULT_IGNORE = "󰈉 "
18
20
  DEFAULT_INVALID = "󱏏 "
19
21
 
@@ -38,6 +40,7 @@ module Dotsync
38
40
  def self.load_custom_icons(config)
39
41
  @custom_icons = {
40
42
  force: config.dig("icons", "force") || DEFAULT_FORCE,
43
+ only: config.dig("icons", "only") || DEFAULT_ONLY,
41
44
  ignore: config.dig("icons", "ignore") || DEFAULT_IGNORE,
42
45
  invalid: config.dig("icons", "invalid") || DEFAULT_INVALID
43
46
  }
@@ -47,6 +50,10 @@ module Dotsync
47
50
  @custom_icons[:force] || DEFAULT_FORCE
48
51
  end
49
52
 
53
+ def self.only
54
+ @custom_icons[:only] || DEFAULT_ONLY
55
+ end
56
+
50
57
  def self.ignore
51
58
  @custom_icons[:ignore] || DEFAULT_IGNORE
52
59
  end
@@ -61,6 +68,7 @@ module Dotsync
61
68
  error: ERROR,
62
69
  env_vars: ENV_VARS,
63
70
  options: OPTIONS,
71
+ legend: LEGEND,
64
72
  config: CONFIG,
65
73
  diff: DIFF,
66
74
  force: -> { force },
@@ -4,18 +4,20 @@ module Dotsync
4
4
  class Mapping
5
5
  include Dotsync::PathUtils
6
6
 
7
- attr_reader :original_src, :original_dest, :original_ignores
7
+ attr_reader :original_src, :original_dest, :original_ignores, :original_only
8
8
 
9
9
  def initialize(attributes)
10
10
  @original_src = attributes["src"]
11
11
  @original_dest = attributes["dest"]
12
12
  @original_ignores = Array(attributes["ignore"])
13
+ @original_only = Array(attributes["only"])
13
14
  @force = attributes["force"] || false
14
15
 
15
- @sanitized_src, @sanitized_dest, @sanitized_ignore = process_paths(
16
+ @sanitized_src, @sanitized_dest, @sanitized_ignore, @sanitized_only = process_paths(
16
17
  @original_src,
17
18
  @original_dest,
18
- @original_ignores
19
+ @original_ignores,
20
+ @original_only
19
21
  )
20
22
  end
21
23
 
@@ -31,6 +33,10 @@ module Dotsync
31
33
  @sanitized_ignore
32
34
  end
33
35
 
36
+ def inclusions
37
+ @sanitized_only
38
+ end
39
+
34
40
  def force?
35
41
  @force
36
42
  end
@@ -69,16 +75,29 @@ module Dotsync
69
75
  File.basename(dest)
70
76
  end
71
77
 
72
- def to_s
73
- colorized_src = colorize_env_vars(original_src)
74
- colorized_dest = colorize_env_vars(original_dest)
75
- msg = ["#{colorized_src} → #{colorized_dest}"]
76
- msg << Icons.force if force?
77
- msg << Icons.ignore if ignores?
78
+ def icons
79
+ msg = []
78
80
  msg << Icons.invalid unless valid?
81
+ msg << Icons.only if only?
82
+ msg << Icons.ignore if ignores?
83
+ msg << Icons.force if force?
79
84
  msg.join(" ")
80
85
  end
81
86
 
87
+ def to_s
88
+ msg = "#{decorated_src} → #{decorated_dest}"
89
+ msg += " #{icons}" if icons != ""
90
+ msg
91
+ end
92
+
93
+ def decorated_src
94
+ colorize_env_vars(original_src)
95
+ end
96
+
97
+ def decorated_dest
98
+ colorize_env_vars(original_dest)
99
+ end
100
+
82
101
  def apply_to(path)
83
102
  relative_path = if Pathname.new(path).absolute?
84
103
  path.delete_prefix(File.join(src, "/"))
@@ -90,6 +109,7 @@ module Dotsync
90
109
  "src" => File.join(@original_src, relative_path),
91
110
  "dest" => File.join(@original_dest, relative_path),
92
111
  "force" => @force,
112
+ "only" => @only,
93
113
  "ignore" => @original_ignores
94
114
  )
95
115
  end
@@ -99,13 +119,20 @@ module Dotsync
99
119
  @original_ignores.any?
100
120
  end
101
121
 
102
- def process_paths(src, dest, ignores)
103
- sanitized_src = sanitize_path(src)
104
- sanitized_dest = sanitize_path(dest)
105
- sanitized_ignore = ignores.flat_map do |path|
122
+ def only?
123
+ @original_only.any?
124
+ end
125
+
126
+ def process_paths(raw_src, raw_dest, raw_ignores, raw_only)
127
+ sanitized_src = sanitize_path(raw_src)
128
+ sanitized_dest = sanitize_path(raw_dest)
129
+ sanitized_ignore = raw_ignores.flat_map do |path|
106
130
  [File.join(sanitized_src, path), File.join(sanitized_dest, path)]
107
131
  end
108
- [sanitized_src, sanitized_dest, sanitized_ignore]
132
+ sanitized_only = raw_only.map do |path|
133
+ File.join(sanitized_src, path)
134
+ end
135
+ [sanitized_src, sanitized_dest, sanitized_ignore, sanitized_only]
109
136
  end
110
137
  end
111
138
  end
@@ -15,6 +15,7 @@ module Dotsync
15
15
  @src = mapping.src
16
16
  @dest = mapping.dest
17
17
  @force = mapping.force?
18
+ @inclusions = mapping.inclusions || []
18
19
  @ignores = mapping.ignores || []
19
20
  end
20
21
 
@@ -39,6 +40,7 @@ module Dotsync
39
40
  next if [".", ".."].include?(File.basename(path))
40
41
 
41
42
  full_path = File.expand_path(path)
43
+ next unless inclusion?(full_path)
42
44
  next if ignore?(full_path)
43
45
 
44
46
  target = File.join(folder_dest, File.basename(path))
@@ -76,6 +78,11 @@ module Dotsync
76
78
  end
77
79
  end
78
80
 
81
+ def inclusion?(path)
82
+ return true unless @inclusions.any?
83
+ @inclusions.any? { |inclusion| path.start_with?(inclusion) || inclusion.start_with?(path) }
84
+ end
85
+
79
86
  def ignore?(path)
80
87
  @ignores.any? { |ignore| path.start_with?(ignore) }
81
88
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dotsync
4
- VERSION = "0.1.13"
4
+ VERSION = "0.1.14"
5
5
  end
data/lib/dotsync.rb CHANGED
@@ -8,6 +8,14 @@ require "logger"
8
8
  require "forwardable" # Ruby standard library
9
9
  require "ostruct"
10
10
  require "find"
11
+ require "terminal-table"
12
+
13
+ # Base classes
14
+ require_relative "dotsync/errors"
15
+ require_relative "dotsync/icons"
16
+ require_relative "dotsync/colors"
17
+ require_relative "dotsync/runner"
18
+ require_relative "dotsync/version"
11
19
 
12
20
  # Utils
13
21
  require_relative "dotsync/utils/path_utils"
@@ -37,13 +45,6 @@ require_relative "dotsync/actions/pull_action"
37
45
  require_relative "dotsync/actions/push_action"
38
46
  require_relative "dotsync/actions/watch_action"
39
47
 
40
- # Base classes
41
- require_relative "dotsync/errors"
42
- require_relative "dotsync/icons"
43
- require_relative "dotsync/colors"
44
- require_relative "dotsync/runner"
45
- require_relative "dotsync/version"
46
-
47
48
  module Dotsync
48
49
  class << self
49
50
  attr_writer :config_path
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.13
4
+ version: 0.1.14
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-04 00:00:00.000000000 Z
11
+ date: 2025-11-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: toml-rb
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: 0.2.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: terminal-table
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 4.0.0
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 4.0.0
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: debug
99
113
  requirement: !ruby/object:Gem::Requirement