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 +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +4 -1
- data/README.md +8 -4
- data/dotsync.gemspec +1 -0
- data/lib/dotsync/actions/base_action.rb +1 -0
- data/lib/dotsync/actions/concerns/mappings_transfer.rb +30 -5
- data/lib/dotsync/actions/pull_action.rb +2 -1
- data/lib/dotsync/actions/push_action.rb +2 -1
- data/lib/dotsync/actions/watch_action.rb +4 -6
- data/lib/dotsync/icons.rb +9 -1
- data/lib/dotsync/models/mapping.rb +41 -14
- data/lib/dotsync/utils/file_transfer.rb +7 -0
- data/lib/dotsync/version.rb +1 -1
- data/lib/dotsync.rb +8 -7
- metadata +16 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1a3bda4bc44a07335f8373e9411b3bf480b3531875e7decf97bd7b8bf013737f
|
|
4
|
+
data.tar.gz: f16173b0468886005524702cf3b808a46c90d6c06d1bef30228b6d3d7cbf08cb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f558392c0c9f8cf336fa7088c99df08e9d390f5e29eb2b2a62286aeae09fd13fde752499dff070bf0cd683195a2514d2b911d6adebcb82247e9430575501e3ae
|
|
7
|
+
data.tar.gz: edb809cda8a1d9c5c2aec1bd9f0588015df1bb2d4ffad14d7fe1761ae8ff30494c8e57f96ca46cbc7a1e2221b395948fad2d42454e6bcea621f05aa9238aaf15
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
dotsync (0.1.
|
|
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
|

|
|
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
|
-
|
|
76
|
-
|
|
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
|
|
@@ -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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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.
|
|
23
|
-
|
|
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("
|
|
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("
|
|
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
|
-
|
|
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
|
|
73
|
-
|
|
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
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
-
|
|
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
|
data/lib/dotsync/version.rb
CHANGED
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.
|
|
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-
|
|
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
|