label_weaver 0.0.6 → 0.0.8
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/label_weaver.gemspec +2 -1
- data/lib/label_weaver/cli/actions/develop/start.rb +6 -2
- data/lib/label_weaver/cli/actions/develop/stop.rb +8 -8
- data/lib/label_weaver/cli/commands/diff.rb +4 -4
- data/lib/label_weaver/configuration/contract.rb +2 -1
- data/lib/label_weaver/configuration/defaults.yml +16 -7
- data/lib/label_weaver/configuration/model.rb +4 -3
- data/lib/label_weaver/merger.rb +33 -3
- data/lib/label_weaver/temp_repo.rb +31 -7
- data/lib/label_weaver/util.rb +18 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f84d950482825eab6d7306ec2ea04c3434ab0c79cb1ae0b7a836b6ff6fe4208
|
4
|
+
data.tar.gz: 56c21daba6bfd11e1d774efc734ddb03c8867fece5a63181934aef561823cf40
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b2fb78c636d8a63f7617dffe8511b422906b63109a97074cf6f27002b94fc22c49ae8a3b8ee102e72cd0ce782e22bbab3b2c33590919aad1bd125b1c9e2069ac
|
7
|
+
data.tar.gz: 71e54ccbd1de7f76252287427741a1bcbe1af97bfad6904b21c130d226534ec63d86eca5916dbfe18b62fdb1004c64803fd1273feb7e8a64b1605924c0e2e756
|
data/label_weaver.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
4
|
spec.name = "label_weaver"
|
5
|
-
spec.version = "0.0.
|
5
|
+
spec.version = "0.0.8"
|
6
6
|
spec.authors = ["Stefan Exner"]
|
7
7
|
spec.email = ["stex@stex.codes"]
|
8
8
|
spec.homepage = "https://gitlab.com/lopo-tech/label_weaver"
|
@@ -17,6 +17,7 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.required_ruby_version = "~> 3.3"
|
18
18
|
spec.add_dependency "cogger", "~> 0.21"
|
19
19
|
spec.add_dependency "containable", "~> 0.0"
|
20
|
+
spec.add_dependency "dot-properties", "~> 0.1"
|
20
21
|
spec.add_dependency "dry-schema", "~> 1.6"
|
21
22
|
spec.add_dependency "diffy", "~> 3.4"
|
22
23
|
spec.add_dependency "git", "~> 2.1.1"
|
@@ -38,7 +38,10 @@ module LabelWeaver
|
|
38
38
|
relative_filename = repo.relative_path(repository_file)
|
39
39
|
project_file = context.project_root_dir + relative_filename
|
40
40
|
|
41
|
-
if
|
41
|
+
if repo.forced_file?(repository_file)
|
42
|
+
# If the file is forced, we need to delete the existing file if it exists.
|
43
|
+
FileUtils.rm_f(project_file) if project_file.exist?
|
44
|
+
elsif Util.file_exists?(project_file)
|
42
45
|
if repo.timestamp_for(repository_file) > project_file.mtime
|
43
46
|
logger.warn "File '#{relative_filename}' has a newer version in the remote repository (#{repo.timestamp_for(repository_file)} vs #{project_file.mtime})."
|
44
47
|
end
|
@@ -67,7 +70,8 @@ module LabelWeaver
|
|
67
70
|
context.repository_dir,
|
68
71
|
repository_url: configuration.git[:repository],
|
69
72
|
branch: configuration.git[:branch],
|
70
|
-
|
73
|
+
excluded_upstream_files: configuration.excluded_upstream_files,
|
74
|
+
forced_upstream_files: configuration.forced_upstream_files,
|
71
75
|
logger: logger
|
72
76
|
)
|
73
77
|
end
|
@@ -37,13 +37,16 @@ module LabelWeaver
|
|
37
37
|
relative_filename = repo.relative_path(repository_file)
|
38
38
|
project_file = context.project_root_dir + relative_filename
|
39
39
|
|
40
|
-
if
|
41
|
-
|
40
|
+
if repo.forced_file?(repository_file) && Util.file_exists?(project_file)
|
41
|
+
logger.debug "Force-Deleting file '#{relative_filename}'..."
|
42
|
+
project_file.unlink
|
43
|
+
remove_empty_tree(project_file.dirname)
|
44
|
+
elsif Util.file_exists?(project_file)
|
45
|
+
if Util.digest(project_file) != Util.digest(repository_file)
|
42
46
|
logger.debug "File '#{relative_filename}' is kept as it was changed in the whitelabel project (r: #{repo.timestamp_for(repository_file)} vs w: #{project_file.mtime})."
|
43
47
|
else
|
44
48
|
logger.debug "Deleting file '#{relative_filename}'..."
|
45
49
|
project_file.unlink
|
46
|
-
|
47
50
|
remove_empty_tree(project_file.dirname)
|
48
51
|
end
|
49
52
|
end
|
@@ -68,16 +71,13 @@ module LabelWeaver
|
|
68
71
|
end
|
69
72
|
end
|
70
73
|
|
71
|
-
def digest(file)
|
72
|
-
Digest::SHA1.file(file).hexdigest
|
73
|
-
end
|
74
|
-
|
75
74
|
def repo
|
76
75
|
@repo ||= LabelWeaver::TempRepo.new(
|
77
76
|
context.repository_dir,
|
78
77
|
repository_url: configuration.git[:repository],
|
79
78
|
branch: configuration.git[:branch],
|
80
|
-
|
79
|
+
excluded_upstream_files: configuration.excluded_upstream_files,
|
80
|
+
forced_upstream_files: configuration.forced_upstream_files,
|
81
81
|
logger: logger
|
82
82
|
)
|
83
83
|
end
|
@@ -39,7 +39,6 @@ module LabelWeaver
|
|
39
39
|
else
|
40
40
|
logger.error "Unknown format: #{context.input[:format]}"
|
41
41
|
end
|
42
|
-
logger.info context.input.inspect
|
43
42
|
end
|
44
43
|
|
45
44
|
private
|
@@ -57,9 +56,10 @@ module LabelWeaver
|
|
57
56
|
def repo
|
58
57
|
@repo ||= LabelWeaver::TempRepo.new(
|
59
58
|
context.repository_dir,
|
60
|
-
repository_url: configuration.
|
61
|
-
branch: configuration.
|
62
|
-
|
59
|
+
repository_url: configuration.git[:repository],
|
60
|
+
branch: configuration.git[:branch],
|
61
|
+
excluded_upstream_files: configuration.excluded_upstream_files,
|
62
|
+
forced_upstream_files: configuration.forced_upstream_files,
|
63
63
|
logger: logger
|
64
64
|
)
|
65
65
|
end
|
@@ -9,7 +9,8 @@ module LabelWeaver
|
|
9
9
|
required(:repository).filled(:string)
|
10
10
|
required(:branch).filled(:string)
|
11
11
|
end
|
12
|
-
optional(:
|
12
|
+
optional(:excluded_upstream_files).array(:string)
|
13
|
+
optional(:forced_upstream_files).array(:string)
|
13
14
|
optional(:hooks).hash do
|
14
15
|
optional(:develop).hash do
|
15
16
|
optional(:before_start).array(:string)
|
@@ -1,14 +1,16 @@
|
|
1
1
|
git:
|
2
2
|
repository: "git@gitlab.com:lopo-tech/label_weaver.git"
|
3
3
|
branch: "main"
|
4
|
-
|
4
|
+
|
5
|
+
# Files to exclude from the upstream repository, they will not be copied over to the whitelabel project.
|
5
6
|
# Shell filename globbing rules apply, not regular expressions
|
6
|
-
|
7
|
-
- .git/**
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
#excluded_upstream_files:
|
8
|
+
# - .git/**
|
9
|
+
|
10
|
+
#hooks:
|
11
|
+
# develop:
|
12
|
+
# after_start:
|
13
|
+
# - echo "Development Mode Started"
|
12
14
|
|
13
15
|
# Define files from the base and whitelabel projects that should be merged into
|
14
16
|
# a new or existing file.
|
@@ -18,6 +20,13 @@ hooks:
|
|
18
20
|
# target_file: package.json
|
19
21
|
# overrides_file: package.whitelabel.json
|
20
22
|
|
23
|
+
# Files to be **always** taken from the upstream repository.
|
24
|
+
# They will always be copied over on development start and will be removed from the
|
25
|
+
# whitelabel project on stop.
|
26
|
+
# Shell filename globbing rules apply, not regular expressions
|
27
|
+
#forced_upstream_files:
|
28
|
+
# - test/**
|
29
|
+
|
21
30
|
# Files here will be appended on whitelabel development instead of being skipped if the
|
22
31
|
# file already exists in a project
|
23
32
|
#append:
|
@@ -4,12 +4,13 @@ module LabelWeaver
|
|
4
4
|
module Configuration
|
5
5
|
# Defines the configuration model for use throughout the gem.
|
6
6
|
Model = Data.define(
|
7
|
-
:
|
7
|
+
:excluded_upstream_files,
|
8
8
|
:git,
|
9
9
|
:hooks,
|
10
|
-
:merges
|
10
|
+
:merges,
|
11
|
+
:forced_upstream_files
|
11
12
|
) do
|
12
|
-
def initialize(git:, hooks: {},
|
13
|
+
def initialize(git:, hooks: {}, excluded_upstream_files: [], forced_upstream_files: [], merges: [])
|
13
14
|
super
|
14
15
|
end
|
15
16
|
end
|
data/lib/label_weaver/merger.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require "dot_properties"
|
2
|
+
|
1
3
|
module LabelWeaver
|
2
4
|
class Merger
|
3
5
|
include Import[:configuration, :logger]
|
@@ -38,7 +40,17 @@ module LabelWeaver
|
|
38
40
|
source = load_file(source_file)
|
39
41
|
overrides = load_file(overrides_file)
|
40
42
|
|
41
|
-
|
43
|
+
validate_compatibility!(source, overrides)
|
44
|
+
|
45
|
+
case target_file.extname
|
46
|
+
when ".properties"
|
47
|
+
overrides.to_h.each do |k, v|
|
48
|
+
source[k] = v
|
49
|
+
end
|
50
|
+
write_file(target_file, source)
|
51
|
+
else
|
52
|
+
write_file(target_file, source.deep_merge(overrides))
|
53
|
+
end
|
42
54
|
end
|
43
55
|
|
44
56
|
def restore_file(relative_file_path)
|
@@ -52,8 +64,23 @@ module LabelWeaver
|
|
52
64
|
configuration.merges.map { _1.transform_keys(&:to_sym) }
|
53
65
|
end
|
54
66
|
|
67
|
+
def validate_compatibility!(source, overrides)
|
68
|
+
# Check for property files
|
69
|
+
if source.is_a?(DotProperties) || overrides.is_a?(DotProperties)
|
70
|
+
if nested_hash?(source) || nested_hash?(overrides)
|
71
|
+
raise ArgumentError, "Property files can only be merged with other property files or one-dimensional hashes"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def nested_hash?(value)
|
77
|
+
value.is_a?(Hash) && value.values.any? { |v| v.is_a?(Hash) }
|
78
|
+
end
|
79
|
+
|
55
80
|
def load_file(file)
|
56
81
|
case file.extname
|
82
|
+
when ".properties"
|
83
|
+
DotProperties.load(file)
|
57
84
|
when ".yaml", ".yml"
|
58
85
|
YAML.load_file(file)
|
59
86
|
when ".json"
|
@@ -65,10 +92,13 @@ module LabelWeaver
|
|
65
92
|
|
66
93
|
def write_file(file, content)
|
67
94
|
case file.extname
|
95
|
+
when ".properties"
|
96
|
+
# TODO: Handle content that is not already a DotProperties instance
|
97
|
+
File.write(file, content.to_s)
|
68
98
|
when ".yaml", ".yml"
|
69
|
-
File.write(file, content.to_yaml)
|
99
|
+
File.write(file, content.to_h.to_yaml)
|
70
100
|
when ".json"
|
71
|
-
File.write(file, JSON.pretty_generate(content))
|
101
|
+
File.write(file, JSON.pretty_generate(content.to_h))
|
72
102
|
else
|
73
103
|
raise ArgumentError, "Unsupported file type: #{file.extname}"
|
74
104
|
end
|
@@ -7,13 +7,21 @@ module LabelWeaver
|
|
7
7
|
class TempRepo
|
8
8
|
using Refinements::Pathname
|
9
9
|
|
10
|
-
attr_reader :repository_path, :repository_url, :branch, :
|
11
|
-
|
12
|
-
def initialize(
|
10
|
+
attr_reader :repository_path, :repository_url, :branch, :logger, :excluded_upstream_files, :forced_upstream_files
|
11
|
+
|
12
|
+
def initialize(
|
13
|
+
repository_path,
|
14
|
+
repository_url:,
|
15
|
+
branch: "main",
|
16
|
+
excluded_upstream_files: [],
|
17
|
+
forced_upstream_files: [],
|
18
|
+
logger: Logger.new($stdout)
|
19
|
+
)
|
13
20
|
@repository_path = repository_path
|
14
21
|
@repository_url = repository_url
|
15
22
|
@branch = branch
|
16
|
-
@
|
23
|
+
@excluded_upstream_files = excluded_upstream_files + %w[. ..]
|
24
|
+
@forced_upstream_files = forced_upstream_files
|
17
25
|
@logger = logger
|
18
26
|
end
|
19
27
|
|
@@ -27,7 +35,7 @@ module LabelWeaver
|
|
27
35
|
end
|
28
36
|
|
29
37
|
def digest_for(file)
|
30
|
-
|
38
|
+
Util.digest(file)
|
31
39
|
end
|
32
40
|
|
33
41
|
def changed_file?(repository_file, project_root_dir:)
|
@@ -60,12 +68,26 @@ module LabelWeaver
|
|
60
68
|
def relevant_files
|
61
69
|
files.filter do |file|
|
62
70
|
# Reject any files that are set up to be excluded. Shell filename globbing rules apply
|
63
|
-
next false if
|
71
|
+
next false if excluded_file?(file)
|
64
72
|
|
65
73
|
true
|
66
74
|
end
|
67
75
|
end
|
68
76
|
|
77
|
+
#
|
78
|
+
# @return [Boolean] +true+ if the file should never be copied over from the repository
|
79
|
+
#
|
80
|
+
def excluded_file?(repository_file)
|
81
|
+
excluded_upstream_files.any? { relative_path(repository_file).fnmatch?(_1, File::FNM_DOTMATCH) }
|
82
|
+
end
|
83
|
+
|
84
|
+
#
|
85
|
+
# @return [Boolean] +true+ if the file should **always** be copied over from the repository
|
86
|
+
#
|
87
|
+
def forced_file?(repository_file)
|
88
|
+
forced_upstream_files.any? { relative_path(repository_file).fnmatch?(_1, File::FNM_DOTMATCH) }
|
89
|
+
end
|
90
|
+
|
69
91
|
#
|
70
92
|
# Updates the atime and mtime of each file in the repository to their latest commit time
|
71
93
|
# TODO: Check if still needed
|
@@ -103,7 +125,9 @@ module LabelWeaver
|
|
103
125
|
# @return [Array<Pathname>] All files inside the repository, including dotfiles. No folders.
|
104
126
|
#
|
105
127
|
def files
|
106
|
-
|
128
|
+
# The symlink check is necessary to include directory symlinks, but leave out
|
129
|
+
# regular directories
|
130
|
+
repository_path.glob("**/*", File::FNM_DOTMATCH).select { _1.file? || _1.symlink? }
|
107
131
|
end
|
108
132
|
|
109
133
|
def repo
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module LabelWeaver
|
2
|
+
module Util
|
3
|
+
def digest(file)
|
4
|
+
if file.symlink?
|
5
|
+
# for symlinks we just use the target path
|
6
|
+
file.readlink
|
7
|
+
else
|
8
|
+
Digest::SHA1.file(file).hexdigest
|
9
|
+
end
|
10
|
+
end
|
11
|
+
module_function :digest
|
12
|
+
|
13
|
+
def file_exists?(file)
|
14
|
+
file.symlink? || file.exist?
|
15
|
+
end
|
16
|
+
module_function :file_exists?
|
17
|
+
end
|
18
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: label_weaver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stefan Exner
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cogger
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: dot-properties
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.1'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.1'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: dry-schema
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -236,6 +250,7 @@ files:
|
|
236
250
|
- lib/label_weaver/import.rb
|
237
251
|
- lib/label_weaver/merger.rb
|
238
252
|
- lib/label_weaver/temp_repo.rb
|
253
|
+
- lib/label_weaver/util.rb
|
239
254
|
homepage: https://gitlab.com/lopo-tech/label_weaver
|
240
255
|
licenses:
|
241
256
|
- MIT
|