dotsync 0.1.23 → 0.1.24
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 +25 -0
- data/Gemfile.lock +1 -1
- data/exe/dotsync +8 -1
- data/lib/dotsync/config/base_config.rb +11 -1
- data/lib/dotsync/core.rb +35 -0
- data/lib/dotsync/loaders/pull_loader.rb +29 -0
- data/lib/dotsync/loaders/push_loader.rb +29 -0
- data/lib/dotsync/loaders/setup_loader.rb +20 -0
- data/lib/dotsync/loaders/watch_loader.rb +26 -0
- data/lib/dotsync/utils/config_cache.rb +86 -0
- data/lib/dotsync/version.rb +1 -1
- data/lib/dotsync.rb +4 -0
- metadata +7 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4ee97490d95db52087796f0da0615d71e3dacf7ac7a89834864abac834006b36
|
|
4
|
+
data.tar.gz: c0f9ad979444a1ba28fdf7397fa7660e140dd483f8c5e7062d14cfc86852471a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c66534cc5d286e4fe7e85a4bff3edecd323db8ad30e653d4bee9d73dfde7277c46305f3c740626223ee302f171ae5f3bddca390805a4af366057a1a17da10a31
|
|
7
|
+
data.tar.gz: 4fc6b7b11d3e8086292d85d53cdb54de1d0ddcb11d77761c6e834f915d0db1fdd2cb7a95b56753ddbf426eb8170e697df15c86a4c4a51eb01b945ccc5191b6b8
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,28 @@
|
|
|
1
|
+
# 0.1.24
|
|
2
|
+
|
|
3
|
+
**Performance Optimizations:**
|
|
4
|
+
- Implement lazy loading to defer library loading until after argument parsing
|
|
5
|
+
- Reduces `--version` and `--help` startup time from ~900ms to ~380ms (2.4x faster)
|
|
6
|
+
- Full library only loaded when executing actual commands
|
|
7
|
+
- Add action-specific loaders to reduce memory footprint
|
|
8
|
+
- Each command loads only its required dependencies
|
|
9
|
+
- Push/pull skip loading 'listen' gem (only needed for watch)
|
|
10
|
+
- Watch skips terminal-table and diff logic
|
|
11
|
+
- Setup uses minimal dependencies for near-instant execution
|
|
12
|
+
- Add config caching with XDG_DATA_HOME integration
|
|
13
|
+
- Caches parsed TOML as Marshal binary (~180x faster to load)
|
|
14
|
+
- Automatic cache invalidation based on mtime, size, and version
|
|
15
|
+
- Graceful fallback to TOML parsing on errors
|
|
16
|
+
- Disable with `DOTSYNC_NO_CACHE=1` environment variable
|
|
17
|
+
- Saves ~14ms per invocation on typical configs
|
|
18
|
+
|
|
19
|
+
**Combined Performance Impact:**
|
|
20
|
+
- `--version`: 900ms → 380ms (2.4x faster)
|
|
21
|
+
- `--help`: 900ms → 380ms (2.4x faster)
|
|
22
|
+
- Setup: Near-instant with minimal loading
|
|
23
|
+
- Push/pull: ~15% faster with cached config
|
|
24
|
+
- Watch: ~40% faster without unnecessary dependencies
|
|
25
|
+
|
|
1
26
|
# 0.1.23
|
|
2
27
|
|
|
3
28
|
**Critical Bug Fix:**
|
data/Gemfile.lock
CHANGED
data/exe/dotsync
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
require_relative "../lib/dotsync"
|
|
5
4
|
require "optparse"
|
|
5
|
+
require_relative "../lib/dotsync/version"
|
|
6
6
|
|
|
7
7
|
options = { apply: false, config_path: nil }
|
|
8
8
|
|
|
@@ -121,16 +121,22 @@ opt_parser.parse!
|
|
|
121
121
|
|
|
122
122
|
command = ARGV.shift
|
|
123
123
|
|
|
124
|
+
# Load only the dependencies needed for the specific command
|
|
124
125
|
case command
|
|
125
126
|
when "push"
|
|
127
|
+
require_relative "../lib/dotsync/loaders/push_loader"
|
|
126
128
|
Dotsync::Runner.new(config_path: options[:config_path]).run(:push, options)
|
|
127
129
|
when "pull"
|
|
130
|
+
require_relative "../lib/dotsync/loaders/pull_loader"
|
|
128
131
|
Dotsync::Runner.new(config_path: options[:config_path]).run(:pull, options)
|
|
129
132
|
when "watch"
|
|
133
|
+
require_relative "../lib/dotsync/loaders/watch_loader"
|
|
130
134
|
Dotsync::Runner.new(config_path: options[:config_path]).run(:watch, options)
|
|
131
135
|
when "setup", "init"
|
|
136
|
+
require_relative "../lib/dotsync/loaders/setup_loader"
|
|
132
137
|
Dotsync::Runner.new(config_path: options[:config_path]).run(:setup)
|
|
133
138
|
when "status"
|
|
139
|
+
require_relative "../lib/dotsync/loaders/push_loader"
|
|
134
140
|
# Show config and mappings without executing any action
|
|
135
141
|
# Use push action with only-config and only-mappings to display info
|
|
136
142
|
status_options = options.merge(
|
|
@@ -141,6 +147,7 @@ when "status"
|
|
|
141
147
|
)
|
|
142
148
|
Dotsync::Runner.new(config_path: options[:config_path]).run(:push, status_options)
|
|
143
149
|
when "diff"
|
|
150
|
+
require_relative "../lib/dotsync/loaders/push_loader"
|
|
144
151
|
# Alias for push in preview mode (default behavior)
|
|
145
152
|
diff_options = options.merge(apply: false)
|
|
146
153
|
Dotsync::Runner.new(config_path: options[:config_path]).run(:push, diff_options)
|
|
@@ -8,6 +8,7 @@ module Dotsync
|
|
|
8
8
|
|
|
9
9
|
# Initialize the BaseConfig with the provided path.
|
|
10
10
|
# Loads the TOML configuration file and validates it.
|
|
11
|
+
# Uses ConfigCache for improved performance.
|
|
11
12
|
#
|
|
12
13
|
# @param [String] path The file path to the configuration file.
|
|
13
14
|
def initialize(path = Dotsync.config_path)
|
|
@@ -20,7 +21,7 @@ module Dotsync
|
|
|
20
21
|
" dotsync setup"
|
|
21
22
|
end
|
|
22
23
|
|
|
23
|
-
@config =
|
|
24
|
+
@config = load_config(absolute_path)
|
|
24
25
|
validate!
|
|
25
26
|
end
|
|
26
27
|
|
|
@@ -29,6 +30,15 @@ module Dotsync
|
|
|
29
30
|
end
|
|
30
31
|
|
|
31
32
|
private
|
|
33
|
+
# Loads configuration from file, using cache when possible
|
|
34
|
+
#
|
|
35
|
+
# @param [String] path The file path to the configuration file.
|
|
36
|
+
# @return [Hash] The parsed configuration
|
|
37
|
+
def load_config(path)
|
|
38
|
+
require_relative "../utils/config_cache"
|
|
39
|
+
ConfigCache.new(path).load
|
|
40
|
+
end
|
|
41
|
+
|
|
32
42
|
# Validates the configuration file.
|
|
33
43
|
#
|
|
34
44
|
# @raise [NotImplementedError] if not implemented by a subclass.
|
data/lib/dotsync/core.rb
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Core dependencies needed by all actions
|
|
4
|
+
require "fileutils"
|
|
5
|
+
require "logger"
|
|
6
|
+
require "forwardable"
|
|
7
|
+
require "ostruct"
|
|
8
|
+
require "find"
|
|
9
|
+
|
|
10
|
+
# Base classes and utilities
|
|
11
|
+
require_relative "errors"
|
|
12
|
+
require_relative "icons"
|
|
13
|
+
require_relative "colors"
|
|
14
|
+
require_relative "version"
|
|
15
|
+
|
|
16
|
+
# Config Concerns (loaded early as they're used by other modules)
|
|
17
|
+
require_relative "config/concerns/xdg_base_directory"
|
|
18
|
+
|
|
19
|
+
# Utils (common utilities)
|
|
20
|
+
require_relative "utils/path_utils"
|
|
21
|
+
require_relative "utils/logger"
|
|
22
|
+
require_relative "utils/version_checker"
|
|
23
|
+
|
|
24
|
+
# Runner
|
|
25
|
+
require_relative "runner"
|
|
26
|
+
|
|
27
|
+
module Dotsync
|
|
28
|
+
class << self
|
|
29
|
+
attr_writer :config_path
|
|
30
|
+
|
|
31
|
+
def config_path
|
|
32
|
+
@config_path ||= ENV["DOTSYNC_CONFIG"] || "~/.config/dotsync.toml"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Load core dependencies
|
|
4
|
+
require_relative "../core"
|
|
5
|
+
|
|
6
|
+
# Gems needed for pull
|
|
7
|
+
require "toml-rb"
|
|
8
|
+
require "terminal-table"
|
|
9
|
+
|
|
10
|
+
# Utils needed for pull
|
|
11
|
+
require_relative "../utils/file_transfer"
|
|
12
|
+
require_relative "../utils/directory_differ"
|
|
13
|
+
require_relative "../utils/config_cache"
|
|
14
|
+
|
|
15
|
+
# Models
|
|
16
|
+
require_relative "../models/mapping"
|
|
17
|
+
require_relative "../models/diff"
|
|
18
|
+
|
|
19
|
+
# Config
|
|
20
|
+
require_relative "../config/base_config"
|
|
21
|
+
require_relative "../config/pull_action_config"
|
|
22
|
+
|
|
23
|
+
# Actions Concerns
|
|
24
|
+
require_relative "../actions/concerns/mappings_transfer"
|
|
25
|
+
require_relative "../actions/concerns/output_sections"
|
|
26
|
+
|
|
27
|
+
# Actions
|
|
28
|
+
require_relative "../actions/base_action"
|
|
29
|
+
require_relative "../actions/pull_action"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Load core dependencies
|
|
4
|
+
require_relative "../core"
|
|
5
|
+
|
|
6
|
+
# Gems needed for push
|
|
7
|
+
require "toml-rb"
|
|
8
|
+
require "terminal-table"
|
|
9
|
+
|
|
10
|
+
# Utils needed for push
|
|
11
|
+
require_relative "../utils/file_transfer"
|
|
12
|
+
require_relative "../utils/directory_differ"
|
|
13
|
+
require_relative "../utils/config_cache"
|
|
14
|
+
|
|
15
|
+
# Models
|
|
16
|
+
require_relative "../models/mapping"
|
|
17
|
+
require_relative "../models/diff"
|
|
18
|
+
|
|
19
|
+
# Config
|
|
20
|
+
require_relative "../config/base_config"
|
|
21
|
+
require_relative "../config/push_action_config"
|
|
22
|
+
|
|
23
|
+
# Actions Concerns
|
|
24
|
+
require_relative "../actions/concerns/mappings_transfer"
|
|
25
|
+
require_relative "../actions/concerns/output_sections"
|
|
26
|
+
|
|
27
|
+
# Actions
|
|
28
|
+
require_relative "../actions/base_action"
|
|
29
|
+
require_relative "../actions/push_action"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Setup only needs minimal dependencies
|
|
4
|
+
require "toml-rb"
|
|
5
|
+
require "fileutils"
|
|
6
|
+
|
|
7
|
+
# Load only what's needed
|
|
8
|
+
require_relative "../version"
|
|
9
|
+
require_relative "../utils/logger"
|
|
10
|
+
require_relative "../runner"
|
|
11
|
+
|
|
12
|
+
module Dotsync
|
|
13
|
+
class << self
|
|
14
|
+
attr_writer :config_path
|
|
15
|
+
|
|
16
|
+
def config_path
|
|
17
|
+
@config_path ||= ENV["DOTSYNC_CONFIG"] || "~/.config/dotsync.toml"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Load core dependencies
|
|
4
|
+
require_relative "../core"
|
|
5
|
+
|
|
6
|
+
# Gems needed for watch (includes listen)
|
|
7
|
+
require "listen"
|
|
8
|
+
require "toml-rb"
|
|
9
|
+
|
|
10
|
+
# Utils needed for watch
|
|
11
|
+
require_relative "../utils/file_transfer"
|
|
12
|
+
require_relative "../utils/config_cache"
|
|
13
|
+
|
|
14
|
+
# Models
|
|
15
|
+
require_relative "../models/mapping"
|
|
16
|
+
|
|
17
|
+
# Config
|
|
18
|
+
require_relative "../config/base_config"
|
|
19
|
+
require_relative "../config/watch_action_config"
|
|
20
|
+
|
|
21
|
+
# Actions Concerns
|
|
22
|
+
require_relative "../actions/concerns/mappings_transfer"
|
|
23
|
+
|
|
24
|
+
# Actions
|
|
25
|
+
require_relative "../actions/base_action"
|
|
26
|
+
require_relative "../actions/watch_action"
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require "digest"
|
|
5
|
+
|
|
6
|
+
module Dotsync
|
|
7
|
+
class ConfigCache
|
|
8
|
+
include Dotsync::XDGBaseDirectory
|
|
9
|
+
|
|
10
|
+
def initialize(config_path)
|
|
11
|
+
@config_path = File.expand_path(config_path)
|
|
12
|
+
@cache_dir = File.join(xdg_data_home, "dotsync", "config_cache")
|
|
13
|
+
|
|
14
|
+
# Use hash of real path for cache filename to support multiple configs
|
|
15
|
+
cache_key = Digest::SHA256.hexdigest(File.realpath(@config_path))
|
|
16
|
+
@cache_file = File.join(@cache_dir, "#{cache_key}.cache")
|
|
17
|
+
@meta_file = File.join(@cache_dir, "#{cache_key}.meta")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def load
|
|
21
|
+
# Skip cache if disabled via environment variable
|
|
22
|
+
return parse_toml if ENV["DOTSYNC_NO_CACHE"]
|
|
23
|
+
|
|
24
|
+
return parse_and_cache unless valid_cache?
|
|
25
|
+
|
|
26
|
+
# Fast path: load from cache
|
|
27
|
+
Marshal.load(File.binread(@cache_file))
|
|
28
|
+
rescue StandardError
|
|
29
|
+
# Fallback: reparse if cache corrupted or any error
|
|
30
|
+
parse_and_cache
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
def valid_cache?
|
|
35
|
+
return false unless File.exist?(@cache_file)
|
|
36
|
+
return false unless File.exist?(@meta_file)
|
|
37
|
+
|
|
38
|
+
meta = JSON.parse(File.read(@meta_file))
|
|
39
|
+
source_stat = File.stat(@config_path)
|
|
40
|
+
|
|
41
|
+
# Quick validation checks
|
|
42
|
+
return false if source_stat.mtime.to_f != meta["source_mtime"]
|
|
43
|
+
return false if source_stat.size != meta["source_size"]
|
|
44
|
+
return false if Dotsync::VERSION != meta["dotsync_version"]
|
|
45
|
+
|
|
46
|
+
# Age check (invalidate cache older than 7 days for safety)
|
|
47
|
+
cache_age_days = (Time.now.to_f - meta["cached_at"]) / 86400
|
|
48
|
+
return false if cache_age_days > 7
|
|
49
|
+
|
|
50
|
+
true
|
|
51
|
+
rescue StandardError
|
|
52
|
+
# Any error in validation means invalid cache
|
|
53
|
+
false
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def parse_and_cache
|
|
57
|
+
config = parse_toml
|
|
58
|
+
|
|
59
|
+
# Write cache files
|
|
60
|
+
FileUtils.mkdir_p(@cache_dir)
|
|
61
|
+
File.binwrite(@cache_file, Marshal.dump(config))
|
|
62
|
+
File.write(@meta_file, JSON.generate(build_metadata))
|
|
63
|
+
|
|
64
|
+
config
|
|
65
|
+
rescue StandardError
|
|
66
|
+
# If caching fails, still return the parsed config
|
|
67
|
+
config
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def parse_toml
|
|
71
|
+
require "toml-rb"
|
|
72
|
+
TomlRB.load_file(@config_path)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def build_metadata
|
|
76
|
+
source_stat = File.stat(@config_path)
|
|
77
|
+
{
|
|
78
|
+
source_path: @config_path,
|
|
79
|
+
source_size: source_stat.size,
|
|
80
|
+
source_mtime: source_stat.mtime.to_f,
|
|
81
|
+
cached_at: Time.now.to_f,
|
|
82
|
+
dotsync_version: Dotsync::VERSION
|
|
83
|
+
}
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
data/lib/dotsync/version.rb
CHANGED
data/lib/dotsync.rb
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# Full library load for backward compatibility
|
|
4
|
+
# For optimized loading, use specific loaders in lib/dotsync/loaders/
|
|
5
|
+
|
|
3
6
|
# Libs dependencies
|
|
4
7
|
require "fileutils"
|
|
5
8
|
require "listen"
|
|
@@ -26,6 +29,7 @@ require_relative "dotsync/utils/logger"
|
|
|
26
29
|
require_relative "dotsync/utils/file_transfer"
|
|
27
30
|
require_relative "dotsync/utils/directory_differ"
|
|
28
31
|
require_relative "dotsync/utils/version_checker"
|
|
32
|
+
require_relative "dotsync/utils/config_cache"
|
|
29
33
|
|
|
30
34
|
# Models
|
|
31
35
|
require_relative "dotsync/models/mapping"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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.24
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Sáenz
|
|
@@ -321,12 +321,18 @@ files:
|
|
|
321
321
|
- lib/dotsync/config/pull_action_config.rb
|
|
322
322
|
- lib/dotsync/config/push_action_config.rb
|
|
323
323
|
- lib/dotsync/config/watch_action_config.rb
|
|
324
|
+
- lib/dotsync/core.rb
|
|
324
325
|
- lib/dotsync/errors.rb
|
|
325
326
|
- lib/dotsync/icons.rb
|
|
327
|
+
- lib/dotsync/loaders/pull_loader.rb
|
|
328
|
+
- lib/dotsync/loaders/push_loader.rb
|
|
329
|
+
- lib/dotsync/loaders/setup_loader.rb
|
|
330
|
+
- lib/dotsync/loaders/watch_loader.rb
|
|
326
331
|
- lib/dotsync/models/diff.rb
|
|
327
332
|
- lib/dotsync/models/mapping.rb
|
|
328
333
|
- lib/dotsync/runner.rb
|
|
329
334
|
- lib/dotsync/tasks/actions.rake
|
|
335
|
+
- lib/dotsync/utils/config_cache.rb
|
|
330
336
|
- lib/dotsync/utils/directory_differ.rb
|
|
331
337
|
- lib/dotsync/utils/file_transfer.rb
|
|
332
338
|
- lib/dotsync/utils/logger.rb
|