dotsync 0.1.14 → 0.1.16

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: 1a3bda4bc44a07335f8373e9411b3bf480b3531875e7decf97bd7b8bf013737f
4
- data.tar.gz: f16173b0468886005524702cf3b808a46c90d6c06d1bef30228b6d3d7cbf08cb
3
+ metadata.gz: 653f18b457e91c025888eb6fca1d14de2718aa0ee7253c30d80e699c6fdc720a
4
+ data.tar.gz: 9c180933f5b35c186fbfaf754a38a9217fcdd459fae3c75d67787d43516f3871
5
5
  SHA512:
6
- metadata.gz: f558392c0c9f8cf336fa7088c99df08e9d390f5e29eb2b2a62286aeae09fd13fde752499dff070bf0cd683195a2514d2b911d6adebcb82247e9430575501e3ae
7
- data.tar.gz: edb809cda8a1d9c5c2aec1bd9f0588015df1bb2d4ffad14d7fe1761ae8ff30494c8e57f96ca46cbc7a1e2221b395948fad2d42454e6bcea621f05aa9238aaf15
6
+ metadata.gz: 0aedae57228a61723b3f4f929e64387dce6fbc227d2f9d68271512eafa7ff15c7ac780fc0f2be80b60868266f309d52403b0ea24d7222770f5ce16edce102df9
7
+ data.tar.gz: 19cb8d65ba7216aa1e2577eb77876a363267e1f7a73f5b5c7dd9ce26c4490988613d30be2199e1580971ac10c45515f86d145bd6565b98edd6d0035dacd352c5
@@ -34,7 +34,7 @@ jobs:
34
34
  bundle exec rubocop
35
35
 
36
36
  - name: Publish to RubyGems
37
- if: matrix.ruby == '3.2'
37
+ if: matrix.ruby == '3.2' && github.ref_name == 'master'
38
38
  run: |
39
39
  mkdir -p $HOME/.gem
40
40
  touch $HOME/.gem/credentials
@@ -44,3 +44,8 @@ jobs:
44
44
  gem push *.gem
45
45
  env:
46
46
  GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
47
+
48
+ - name: Generate release tag
49
+ if: matrix.ruby == '3.2' && github.ref_name == 'master'
50
+ run: |
51
+ bundle exec rake release:tag
data/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ # 0.1.16
2
+
3
+ - DirectoryDiffer: fixes path on removal difference
4
+ - MappingsTransfer: fixes "Differences" label text for clarity
5
+ - Add Difference Legend
6
+ - Show Difference Legend only if there are any difference
7
+ - OutputSections: added new options to hide output
8
+
9
+ # 0.1.15
10
+
11
+ - Readme: update screenshots in docs
12
+ - Consistent order of icons on Legend and Mappings
13
+ - DirectoryDiffer: implements only option
14
+ - Show Flags icons closer
15
+
1
16
  # 0.1.14
2
17
 
3
18
  - Render environment variables and mappings with a table
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dotsync (0.1.14)
4
+ dotsync (0.1.16)
5
5
  fileutils (~> 1.7.3)
6
6
  find (~> 0.2.0)
7
7
  listen (~> 3.9.0)
data/README.md CHANGED
@@ -35,15 +35,37 @@ 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 --apply
38
+ dotsync push --apply [OPTION]
39
39
  ```
40
+ Options:
41
+ - `-q, --quiet`: Hide all non-essential output (only errors or final status).
42
+ - `--no-legend`: Hide all legends for config, mappings, and differences.
43
+ - `--no-config`: Hide the config section in the output.
44
+ - `--no-mappings`: Hide the mappings and their legend.
45
+ - `--no-diff-legend`: Hide the differences legend only.
46
+ - `--no-diff`: Hide the differences section itself.
47
+ - `--only-diff`: Show only the differences section.
48
+ - `--only-config`: Show only the config section.
49
+ - `--only-mappings`: Show only the mappings section.
50
+ - `-v, --verbose`: Force showing all available information.
40
51
 
41
52
  ![dotsync push](docs/images/dotsync_push.png)
42
53
 
43
54
  - **Pull**: Synchronize dotfiles from the repository to your local machine.
44
55
  ```shell
45
- dotsync pull --apply
56
+ dotsync pull --apply [OPTION]
46
57
  ```
58
+ Options:
59
+ - `-q, --quiet`: Hide all non-essential output (only errors or final status).
60
+ - `--no-legend`: Hide all legends for config, mappings, and differences.
61
+ - `--no-config`: Hide the config section in the output.
62
+ - `--no-mappings`: Hide the mappings and their legend.
63
+ - `--no-diff-legend`: Hide the differences legend only.
64
+ - `--no-diff`: Hide the differences section itself.
65
+ - `--only-diff`: Show only the differences section.
66
+ - `--only-config`: Show only the config section.
67
+ - `--only-mappings`: Show only the mappings section.
68
+ - `-v, --verbose`: Force showing all available information.
47
69
 
48
70
  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.
49
71
 
@@ -114,6 +136,14 @@ dest = "$DOTFILES_DIR/config/alacritty"
114
136
  Each mapping entry supports the following options:
115
137
 
116
138
  - **`force`**: A boolean (true/false) value. When set to `true`, it forces deletion of the destination folder before transferring files from the source. This is particularly useful when you need to ensure that the destination is clean before a transfer.
139
+ - **`only`**: An array of files or folders. This option ensures that only the specified files or folders from the `src` directory are transferred to the `dest` directory. Example:
140
+ ```toml
141
+ [[push.mappings]]
142
+ src = "$XDG_CONFIG_HOME"
143
+ dest = "$DOTFILES_DIR/config"
144
+ only = ["config.yml", "themes"]
145
+
146
+ ```
117
147
  - **`ignore`**: An array of patterns or file names to exclude during the transfer. This allows you to specify files or folders that should not be copied from the source to the destination.
118
148
 
119
149
  These options apply when the source is a directory and are relevant for both `push` and `pull` operations.
@@ -157,9 +187,14 @@ When running `push` or `pull` actions, the mappings are rendered in the console
157
187
 
158
188
  ## Development
159
189
 
160
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
190
+ - After checking out the repo, run `bin/setup` to install dependencies.
191
+ - Then, run `rake spec` to run the tests.
192
+ - You can also run `bin/console` for an interactive prompt that will allow you to experiment.
193
+ - To install this gem onto your local machine, run `bundle exec rake install`.
161
194
 
162
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
195
+ ### Releasing a new version
196
+ - Update the version number in `version.rb`.
197
+ - Run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
163
198
 
164
199
  ## Contributing
165
200
 
data/Rakefile CHANGED
@@ -14,11 +14,28 @@ end
14
14
 
15
15
  task default: :spec
16
16
 
17
- desc "hello task"
18
- task :hello do
19
- puts "hello world"
17
+ namespace :release do
18
+ desc "Tag git with the current Dotsync::VERSION"
19
+ task :tag do
20
+ require_relative "./lib/dotsync/version"
21
+ version = Dotsync::VERSION
22
+ tag_name = "v#{version}"
23
+
24
+ # Check if tag already exists
25
+ if `git tag --list`.split.include?(tag_name)
26
+ puts "Tag #{tag_name} already exists."
27
+ exit(1)
28
+ end
29
+
30
+ puts "Tagging commit as #{tag_name}..."
31
+ sh "git tag -a #{tag_name} -m 'Release #{tag_name}'"
32
+ puts "Pushing tag #{tag_name} to origin..."
33
+ sh "git push origin #{tag_name}"
34
+ puts "Done!"
35
+ end
20
36
  end
21
37
 
38
+
22
39
  namespace :dotsync do
23
40
  desc "Pull Dotfiles"
24
41
  task :pull do
Binary file
Binary file
data/exe/dotsync CHANGED
@@ -18,12 +18,58 @@ opt_parser = OptionParser.new do |opts|
18
18
  setup Initialize a default configuration file
19
19
 
20
20
  Options:
21
- -a, --apply Apply changes (push or pull)
22
- -h, --help Show this help message
21
+ -a, --apply Apply changes (push or pull)
22
+ -q, --quiet Hide all non-essential output (only errors or final status)
23
+ --no-legend Hide all legends for config, mappings, and differences
24
+ --no-config Hide the config section in the output
25
+ --no-mappings Hide the mappings and their legend
26
+ --no-diff-legend Hide the differences legend only
27
+ --no-diff Hide the differences section itself
28
+ --only-diff Show only the differences section
29
+ --only-config Show only the config section
30
+ --only-mappings Show only the mappings section
31
+ -v, --verbose Force showing all available information
32
+ -h, --help Show this help message
23
33
  BANNER
24
34
 
25
- opts.on("-a", "--apply", "Apply changes (push or pull)") do
26
- options[:apply] = true
35
+ opts.on("-q", "--quiet", "Hide all non-essential output (only errors or final status)") do
36
+ options[:quiet] = true
37
+ end
38
+
39
+ opts.on("--no-legend", "Hide all legends for config, mappings, and differences") do
40
+ options[:no_legend] = true
41
+ end
42
+
43
+ opts.on("--no-config", "Hide the config section in the output") do
44
+ options[:no_config] = true
45
+ end
46
+
47
+ opts.on("--no-mappings", "Hide the mappings and their legend") do
48
+ options[:no_mappings] = true
49
+ end
50
+
51
+ opts.on("--no-diff-legend", "Hide the differences legend only") do
52
+ options[:no_diff_legend] = true
53
+ end
54
+
55
+ opts.on("--no-diff", "Hide the differences section itself") do
56
+ options[:no_diff] = true
57
+ end
58
+
59
+ opts.on("--only-diff", "Show only the differences section") do
60
+ options[:only_diff] = true
61
+ end
62
+
63
+ opts.on("--only-config", "Show only the config section") do
64
+ options[:only_config] = true
65
+ end
66
+
67
+ opts.on("--only-mappings", "Show only the mappings section") do
68
+ options[:only_mappings] = true
69
+ end
70
+
71
+ opts.on("-v", "--verbose", "Force showing all available information") do
72
+ options[:verbose] = true
27
73
  end
28
74
 
29
75
  opts.on("-h", "--help", "Show this help message") do
@@ -4,11 +4,17 @@ module Dotsync
4
4
  module MappingsTransfer
5
5
  include Dotsync::PathUtils
6
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"]
7
+ MAPPINGS_LEGEND = [
8
+ [Icons.force, "The source will overwrite the destination"],
9
+ [Icons.only, "Paths designated explicitly as source only"],
10
+ [Icons.ignore, "Paths configured to be ignored in the destination"],
11
+ [Icons.invalid, "Invalid paths detected in the source or destination"]
12
+ ]
13
+
14
+ DIFFERENCES_LEGEND = [
15
+ [Icons.diff_created, "Created/added file"],
16
+ [Icons.diff_updated, "Updated/modified file"],
17
+ [Icons.diff_removed, "Removed/deleted file"]
12
18
  ]
13
19
 
14
20
  extend Forwardable # def_delegator
@@ -28,8 +34,8 @@ module Dotsync
28
34
  end
29
35
 
30
36
  def show_mappings_legend
31
- info("Legend:", icon: :legend)
32
- table = Terminal::Table.new(rows: LEGEND)
37
+ info("Mappings Legend:", icon: :legend)
38
+ table = Terminal::Table.new(rows: MAPPINGS_LEGEND)
33
39
  logger.log(table)
34
40
  logger.log("")
35
41
  end
@@ -49,25 +55,26 @@ module Dotsync
49
55
  logger.log("")
50
56
  end
51
57
 
52
- def show_changes
53
- diffs = valid_mappings.map do |mapping|
54
- Dotsync::DirectoryDiffer.new(mapping).diff
55
- end
56
- has_diff = false
57
- info("Diff:", icon: :diff)
58
- diffs.flat_map(&:additions).sort.each do |path|
59
- logger.log(" #{path}", color: Dotsync::Colors.diff_additions)
60
- has_diff = true
58
+ def show_differences_legend
59
+ info("Differences Legend:", icon: :legend)
60
+ table = Terminal::Table.new(rows: DIFFERENCES_LEGEND)
61
+ logger.log(table)
62
+ logger.log("")
63
+ end
64
+
65
+ def show_differences
66
+ info("Differences:", icon: :diff)
67
+ differs.flat_map(&:additions).sort.each do |path|
68
+ logger.log("#{Icons.diff_created}#{path}", color: Colors.diff_additions)
61
69
  end
62
- diffs.flat_map(&:modifications).sort.each do |path|
63
- logger.log(" #{path}", color: Dotsync::Colors.diff_modifications)
64
- has_diff = true
70
+ differs.flat_map(&:modifications).sort.each do |path|
71
+ logger.log("#{Icons.diff_updated}#{path}", color: Colors.diff_modifications)
65
72
  end
66
- diffs.flat_map(&:removals).sort.each do |path|
67
- logger.log(" #{path}", color: Dotsync::Colors.diff_removals)
68
- has_diff = true
73
+ differs.flat_map(&:removals).sort.each do |path|
74
+ logger.log("#{Icons.diff_removed}#{path}", color: Colors.diff_removals)
69
75
  end
70
- logger.log(" No differences") unless has_diff
76
+ logger.log(" No differences") unless has_differences?
77
+ logger.log("")
71
78
  end
72
79
 
73
80
  def transfer_mappings
@@ -77,6 +84,16 @@ module Dotsync
77
84
  end
78
85
 
79
86
  private
87
+ def differs
88
+ @differs ||= valid_mappings.map do |mapping|
89
+ Dotsync::DirectoryDiffer.new(mapping).diff
90
+ end
91
+ end
92
+
93
+ def has_differences?
94
+ differs.any? { |differ| differ.any? }
95
+ end
96
+
80
97
  def mappings_env_vars
81
98
  paths = mappings.flat_map do |mapping|
82
99
  [mapping.original_src, mapping.original_dest]
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dotsync
4
+ module OutputSections
5
+ def compute_output_sections(options)
6
+ quiet = options[:quiet]
7
+ verbose = options[:verbose]
8
+
9
+ output_sections = {
10
+ options: !(quiet || options[:only_diff] || options[:only_mappings]),
11
+ env_vars: !(quiet || options[:only_diff] || options[:only_mappings]),
12
+ mappings_legend: !(quiet || options[:no_legend] || options[:no_mappings] || options[:only_diff]),
13
+ mappings: !(quiet || options[:no_mappings] || options[:only_diff]),
14
+ differences_legend: !(quiet || options[:no_legend] || options[:no_diff_legend] || options[:no_diff] || options[:only_config]),
15
+ differences: !(quiet || options[:no_diff] || options[:only_mappings] || options[:only_config])
16
+ }
17
+
18
+ if verbose
19
+ output_sections.transform_values! { |_| true }
20
+ end
21
+
22
+ output_sections
23
+ end
24
+ end
25
+ end
@@ -3,15 +3,20 @@
3
3
  module Dotsync
4
4
  class PullAction < BaseAction
5
5
  include MappingsTransfer
6
+ include OutputSections
6
7
 
7
8
  def_delegator :@config, :backups_root
8
9
 
9
10
  def execute(options = {})
10
- show_options(options)
11
- show_env_vars
12
- show_mappings_legend
13
- show_mappings
14
- show_changes
11
+ output_sections = compute_output_sections(options)
12
+
13
+ show_options(options) if output_sections[:options]
14
+ show_env_vars if output_sections[:env_vars]
15
+ show_mappings_legend if output_sections[:mappings_legend]
16
+ show_mappings if output_sections[:mappings]
17
+ show_differences_legend if has_differences? && output_sections[:differences_legend]
18
+ show_differences if output_sections[:differences]
19
+
15
20
  return unless options[:apply]
16
21
 
17
22
  if create_backup
@@ -3,13 +3,18 @@
3
3
  module Dotsync
4
4
  class PushAction < BaseAction
5
5
  include MappingsTransfer
6
+ include OutputSections
6
7
 
7
8
  def execute(options = {})
8
- show_options(options)
9
- show_env_vars
10
- show_mappings_legend
11
- show_mappings
12
- show_changes
9
+ output_sections = compute_output_sections(options)
10
+
11
+ show_options(options) if output_sections[:options]
12
+ show_env_vars if output_sections[:env_vars]
13
+ show_mappings_legend if output_sections[:mappings_legend]
14
+ show_mappings if output_sections[:mappings]
15
+ show_differences_legend if has_differences? && output_sections[:differences_legend]
16
+ show_differences if output_sections[:differences]
17
+
13
18
  return unless options[:apply]
14
19
 
15
20
  transfer_mappings
data/lib/dotsync/icons.rb CHANGED
@@ -13,12 +13,17 @@ module Dotsync
13
13
  CONFIG = " "
14
14
  DIFF = " "
15
15
 
16
- # Default Mapping Flags icons
16
+ # Default Mappings Legend icons
17
17
  DEFAULT_FORCE = "󰁪 "
18
18
  DEFAULT_ONLY = " "
19
19
  DEFAULT_IGNORE = "󰈉 "
20
20
  DEFAULT_INVALID = "󱏏 "
21
21
 
22
+ # Default Mappings Differences icons
23
+ DEFAULT_DIFF_CREATED = " "
24
+ DEFAULT_DIFF_UPDATED = " "
25
+ DEFAULT_DIFF_REMOVED = " "
26
+
22
27
  # Action icons
23
28
  PULL = " "
24
29
  PUSH = " "
@@ -39,13 +44,20 @@ module Dotsync
39
44
 
40
45
  def self.load_custom_icons(config)
41
46
  @custom_icons = {
47
+ # Mappings Legend
42
48
  force: config.dig("icons", "force") || DEFAULT_FORCE,
43
49
  only: config.dig("icons", "only") || DEFAULT_ONLY,
44
50
  ignore: config.dig("icons", "ignore") || DEFAULT_IGNORE,
45
- invalid: config.dig("icons", "invalid") || DEFAULT_INVALID
51
+ invalid: config.dig("icons", "invalid") || DEFAULT_INVALID,
52
+ # Differences Legend
53
+ diff_created: config.dig("icons", "diff_created") || DEFAULT_DIFF_CREATED,
54
+ diff_updated: config.dig("icons", "diff_updated") || DEFAULT_DIFF_UPDATED,
55
+ diff_removed: config.dig("icons", "diff_removed") || DEFAULT_DIFF_REMOVED,
46
56
  }
47
57
  end
48
58
 
59
+ # Mappings Legend methods
60
+
49
61
  def self.force
50
62
  @custom_icons[:force] || DEFAULT_FORCE
51
63
  end
@@ -62,6 +74,20 @@ module Dotsync
62
74
  @custom_icons[:invalid] || DEFAULT_INVALID
63
75
  end
64
76
 
77
+ # Differences Legend methods
78
+
79
+ def self.diff_created
80
+ @custom_icons[:diff_created] || DEFAULT_DIFF_CREATED
81
+ end
82
+
83
+ def self.diff_updated
84
+ @custom_icons[:diff_updated] || DEFAULT_DIFF_UPDATED
85
+ end
86
+
87
+ def self.diff_removed
88
+ @custom_icons[:diff_removed] || DEFAULT_DIFF_REMOVED
89
+ end
90
+
65
91
  # https://www.nerdfonts.com
66
92
  MAPPINGS = {
67
93
  info: INFO,
@@ -11,6 +11,10 @@ module Dotsync
11
11
  @removals = removals
12
12
  end
13
13
 
14
+ def any?
15
+ @additions.any? || @modifications.any? || @removals.any?
16
+ end
17
+
14
18
  def empty?
15
19
  @additions.empty? && @modifications.empty? && @removals.empty?
16
20
  end
@@ -13,7 +13,7 @@ module Dotsync
13
13
  @original_only = Array(attributes["only"])
14
14
  @force = attributes["force"] || false
15
15
 
16
- @sanitized_src, @sanitized_dest, @sanitized_ignore, @sanitized_only = process_paths(
16
+ @sanitized_src, @sanitized_dest, @sanitized_ignores, @sanitized_only = process_paths(
17
17
  @original_src,
18
18
  @original_dest,
19
19
  @original_ignores,
@@ -30,7 +30,7 @@ module Dotsync
30
30
  end
31
31
 
32
32
  def ignores
33
- @sanitized_ignore
33
+ @sanitized_ignores
34
34
  end
35
35
 
36
36
  def inclusions
@@ -77,11 +77,11 @@ module Dotsync
77
77
 
78
78
  def icons
79
79
  msg = []
80
- msg << Icons.invalid unless valid?
81
- msg << Icons.only if only?
82
- msg << Icons.ignore if ignores?
83
80
  msg << Icons.force if force?
84
- msg.join(" ")
81
+ msg << Icons.only if has_inclusions?
82
+ msg << Icons.ignore if has_ignores?
83
+ msg << Icons.invalid unless valid?
84
+ msg.join
85
85
  end
86
86
 
87
87
  def to_s
@@ -114,25 +114,41 @@ module Dotsync
114
114
  )
115
115
  end
116
116
 
117
+ def include?(path)
118
+ return true unless has_inclusions?
119
+ return true if path == src
120
+ inclusions.any? { |inclusion| path_is_parent_or_same?(inclusion, path) }
121
+ end
122
+
123
+ def bidirectional_include?(path)
124
+ return true unless has_inclusions?
125
+ return true if path == src
126
+ inclusions.any? { |inclusion| path_is_parent_or_same?(inclusion, path) || path_is_parent_or_same?(path, inclusion) }
127
+ end
128
+
129
+ def ignore?(path)
130
+ ignores.any? { |ignore| path.start_with?(ignore) }
131
+ end
132
+
117
133
  private
118
- def ignores?
134
+ def has_ignores?
119
135
  @original_ignores.any?
120
136
  end
121
137
 
122
- def only?
138
+ def has_inclusions?
123
139
  @original_only.any?
124
140
  end
125
141
 
126
142
  def process_paths(raw_src, raw_dest, raw_ignores, raw_only)
127
143
  sanitized_src = sanitize_path(raw_src)
128
144
  sanitized_dest = sanitize_path(raw_dest)
129
- sanitized_ignore = raw_ignores.flat_map do |path|
145
+ sanitized_ignores = raw_ignores.flat_map do |path|
130
146
  [File.join(sanitized_src, path), File.join(sanitized_dest, path)]
131
147
  end
132
148
  sanitized_only = raw_only.map do |path|
133
149
  File.join(sanitized_src, path)
134
150
  end
135
- [sanitized_src, sanitized_dest, sanitized_ignore, sanitized_only]
151
+ [sanitized_src, sanitized_dest, sanitized_ignores, sanitized_only]
136
152
  end
137
153
  end
138
154
  end
@@ -36,6 +36,11 @@ module Dotsync
36
36
  Find.find(mapping_src) do |src_path|
37
37
  rel_path = src_path.sub(/^#{Regexp.escape(mapping_src)}\/?/, "")
38
38
 
39
+ unless @mapping.include?(src_path)
40
+ Find.prune
41
+ next
42
+ end
43
+
39
44
  dest_path = File.join(mapping_dest, rel_path)
40
45
 
41
46
  if !File.exist?(dest_path)
@@ -62,7 +67,7 @@ module Dotsync
62
67
 
63
68
  additions = relative_to_absolute(filter_ignores(additions), mapping_original_dest)
64
69
  modifications = relative_to_absolute(filter_ignores(modifications), mapping_original_dest)
65
- removals = relative_to_absolute(filter_ignores(removals), mapping_original_src)
70
+ removals = relative_to_absolute(filter_ignores(removals), mapping_original_dest)
66
71
 
67
72
  Dotsync::Diff.new(additions: additions, modifications: modifications, removals: removals)
68
73
  end
@@ -2,8 +2,6 @@
2
2
 
3
3
  module Dotsync
4
4
  class FileTransfer
5
- attr_reader :ignores
6
-
7
5
  # Initializes a new FileTransfer instance
8
6
  #
9
7
  # @param mapping [Dotsync::Mapping] the mapping object containing source, destination, force, and ignore details
@@ -12,6 +10,7 @@ module Dotsync
12
10
  # @option mapping [Boolean] :force? optional flag to force actions
13
11
  # @option mapping [Array<String>] :ignores optional list of files/directories to ignore
14
12
  def initialize(mapping)
13
+ @mapping = mapping
15
14
  @src = mapping.src
16
15
  @dest = mapping.dest
17
16
  @force = mapping.force?
@@ -29,6 +28,8 @@ module Dotsync
29
28
  end
30
29
 
31
30
  private
31
+ attr_reader :mapping, :ignores
32
+
32
33
  def transfer_file(file_src, file_dest)
33
34
  FileUtils.mkdir_p(File.dirname(file_dest))
34
35
  FileUtils.cp(file_src, file_dest)
@@ -36,12 +37,17 @@ module Dotsync
36
37
 
37
38
  def transfer_folder(folder_src, folder_dest)
38
39
  FileUtils.mkdir_p(folder_dest)
40
+
41
+ # `Dir.glob("#{folder_src}/*")` retrieves only the immediate contents
42
+ # (files and directories) within the specified directory (`folder_src`),
43
+ # without descending into subdirectories.
44
+
39
45
  Dir.glob("#{folder_src}/*", File::FNM_DOTMATCH).each do |path|
40
46
  next if [".", ".."].include?(File.basename(path))
41
47
 
42
48
  full_path = File.expand_path(path)
43
- next unless inclusion?(full_path)
44
- next if ignore?(full_path)
49
+ next unless mapping.bidirectional_include?(full_path)
50
+ next if mapping.ignore?(full_path)
45
51
 
46
52
  target = File.join(folder_dest, File.basename(path))
47
53
  if File.file?(full_path)
@@ -77,14 +83,5 @@ module Dotsync
77
83
  end
78
84
  end
79
85
  end
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
-
86
- def ignore?(path)
87
- @ignores.any? { |ignore| path.start_with?(ignore) }
88
- end
89
86
  end
90
87
  end
@@ -24,6 +24,12 @@ module Dotsync
24
24
  paths.map { |path| File.join(base_path, path) }
25
25
  end
26
26
 
27
+ def path_is_parent_or_same?(parent, child)
28
+ parent = Pathname.new(parent).expand_path
29
+ child = Pathname.new(child).expand_path
30
+ child.ascend.any? { |ancestor| ancestor == parent }
31
+ end
32
+
27
33
  # Translates /tmp paths to /private/tmp paths on macOS
28
34
  # Retains other paths as-is
29
35
  # @param [String] path The input path to translate
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dotsync
4
- VERSION = "0.1.14"
4
+ VERSION = "0.1.16"
5
5
  end
data/lib/dotsync.rb CHANGED
@@ -38,6 +38,7 @@ require_relative "dotsync/config/watch_action_config"
38
38
 
39
39
  # Actions Concerns
40
40
  require_relative "dotsync/actions/concerns/mappings_transfer"
41
+ require_relative "dotsync/actions/concerns/output_sections"
41
42
 
42
43
  # Actions
43
44
  require_relative "dotsync/actions/base_action"
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.14
4
+ version: 0.1.16
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-05 00:00:00.000000000 Z
11
+ date: 2025-11-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: toml-rb
@@ -252,9 +252,7 @@ description: Keep in sync your dotfiles across machines with a single TOML file
252
252
  email:
253
253
  - david.saenz.tagarro@gmail.com
254
254
  executables:
255
- - console
256
255
  - dotsync
257
- - setup
258
256
  extensions: []
259
257
  extra_rdoc_files: []
260
258
  files:
@@ -272,16 +270,17 @@ files:
272
270
  - README.md
273
271
  - RELEASING.md
274
272
  - Rakefile
273
+ - bin/console
274
+ - bin/setup
275
275
  - docs/images/dotsync_pull.png
276
276
  - docs/images/dotsync_push.png
277
277
  - docs/images/dotsync_push_apply.png
278
278
  - dotsync.gemspec
279
- - exe/console
280
279
  - exe/dotsync
281
- - exe/setup
282
280
  - lib/dotsync.rb
283
281
  - lib/dotsync/actions/base_action.rb
284
282
  - lib/dotsync/actions/concerns/mappings_transfer.rb
283
+ - lib/dotsync/actions/concerns/output_sections.rb
285
284
  - lib/dotsync/actions/pull_action.rb
286
285
  - lib/dotsync/actions/push_action.rb
287
286
  - lib/dotsync/actions/watch_action.rb
File without changes
/data/{exe → bin}/setup RENAMED
File without changes