label_weaver 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8d4577814ad253da907628f3c86300dc89c2b362260fa6772af602670ce2aa63
4
+ data.tar.gz: a262362d186dca07c7789baca7cd642c3d9b43e5ea1ca3ec6259ac4a244ef90f
5
+ SHA512:
6
+ metadata.gz: 64c146c67e07cb609d4c7ac458e37d071edd0e592ec460f3b692b559a5121b2dfa12c5294a71eb565cb7d2064d54053aae8a0cf09ccdae2fc94fe48f4970cbcd
7
+ data.tar.gz: 17f74363825bd9115228468d77b175b19c2895a680acd3809e0a7d25f3dda1338cae90e660fd26140fc57b78cd6aff80dd99f405938141d46cfcb5d56104d131
data/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # LabelWeaver
2
+
3
+ [![Ruby Code Style](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://github.com/standardrb/standard)
data/exe/label_weaver ADDED
@@ -0,0 +1,7 @@
1
+ #! /usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "label_weaver"
5
+ require "debug"
6
+
7
+ LabelWeaver::CLI::Shell.new.call
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "label_weaver"
5
+ spec.version = "0.0.3"
6
+ spec.authors = ["Stefan Exner"]
7
+ spec.email = ["stex@stex.codes"]
8
+ spec.homepage = "https://gitlab.com/lopo-tech/label_weaver"
9
+ spec.summary = "Helper tool to manage whitelabel version of base projects"
10
+ spec.license = "MIT"
11
+
12
+ spec.metadata = {
13
+ "label" => "LabelWeaver",
14
+ "rubygems_mfa_required" => "true"
15
+ }
16
+
17
+ spec.required_ruby_version = "~> 3.3"
18
+ spec.add_dependency "cogger", "~> 0.21"
19
+ spec.add_dependency "containable", "~> 0.0"
20
+ spec.add_dependency "dry-monads", "~> 1.6"
21
+ spec.add_dependency "dry-schema", "~> 1.6"
22
+ spec.add_dependency "diffy", "~> 3.4"
23
+ spec.add_dependency "etcher", "~> 1.6"
24
+ spec.add_dependency "git", "~> 2.1.1"
25
+ spec.add_dependency "infusible", "~> 3.5"
26
+ spec.add_dependency "ruby-next-core", "~> 1.0"
27
+ spec.add_dependency "runcom", "~> 11.0"
28
+ spec.add_dependency "sod", "~> 0.8"
29
+ spec.add_dependency "spek", "~> 3.0"
30
+ spec.add_dependency "tty-file", "~> 0.10"
31
+ spec.add_dependency "tty-pager", "~> 0.14"
32
+ spec.add_dependency "zeitwerk", "~> 2.6"
33
+
34
+ spec.bindir = "exe"
35
+ spec.executables << "label_weaver"
36
+ spec.extra_rdoc_files = Dir["README*", "LICENSE*"]
37
+ spec.files = Dir["*.gemspec", "lib/**/*"]
38
+ end
@@ -0,0 +1,65 @@
1
+ require "git"
2
+ require "yaml"
3
+ require "digest"
4
+
5
+ module LabelWeaver
6
+ module CLI
7
+ module Actions
8
+ module Develop
9
+ class Start < Sod::Action
10
+ include Import[:kernel, :configuration, :xdg_config, :logger]
11
+
12
+ using Refinements::Pathname
13
+
14
+ description "Starts whitelabel development mode"
15
+ ancillary "Fetches the latest git changes and syncs them with your local branch."
16
+
17
+ on %w[--start]
18
+
19
+ def call(*args)
20
+ unless xdg_config.active
21
+ logger.error("No configuration found. Are you in the correct directory?")
22
+ kernel.exit(1)
23
+ end
24
+
25
+ repo.clone_or_update
26
+ copy_repository_files
27
+ end
28
+
29
+ private
30
+
31
+ def copy_repository_files
32
+ logger.info "Copying repository files to whitelabel project..."
33
+
34
+ repo.relevant_files.each do |repository_file|
35
+ relative_filename = repo.relative_path(repository_file)
36
+ project_file = context.project_root_dir + relative_filename
37
+
38
+ if project_file.exist?
39
+ if repo.timestamp_for(repository_file) > project_file.mtime
40
+ logger.warn "File '#{relative_filename}' has a newer version in the remote repository (#{repo.timestamp_for(repository_file)} vs #{project_file.mtime})."
41
+ end
42
+
43
+ logger.debug "Skipping '#{relative_filename}'..."
44
+ next
45
+ end
46
+
47
+ FileUtils.mkdir_p(project_file.dirname)
48
+ FileUtils.copy(repository_file, project_file, preserve: true)
49
+ end
50
+ end
51
+
52
+ def repo
53
+ @repo ||= LabelWeaver::TempRepo.new(
54
+ context.repository_dir,
55
+ repository_url: configuration.git_repository,
56
+ branch: configuration.git_branch,
57
+ excludes: configuration.excludes,
58
+ logger: logger
59
+ )
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,77 @@
1
+ require "git"
2
+ require "yaml"
3
+ require "digest"
4
+
5
+ module LabelWeaver
6
+ module CLI
7
+ module Actions
8
+ module Develop
9
+ class Stop < Sod::Action
10
+ include Import[:configuration, :xdg_config, :kernel, :logger]
11
+
12
+ using Refinements::Pathname
13
+
14
+ description "Stops whitelabel development mode"
15
+ ancillary "Removes all unchanged files from the whitelabel project again."
16
+
17
+ on %w[--stop]
18
+
19
+ def call(*args)
20
+ unless xdg_config.active
21
+ logger.error("No configuration found. Are you in the correct directory?")
22
+ kernel.exit(1)
23
+ end
24
+
25
+ remove_base_files
26
+ end
27
+
28
+ private
29
+
30
+ def remove_base_files
31
+ logger.info "Removing unchanged base files from whitelabel project"
32
+
33
+ repo.relevant_files.each do |repository_file|
34
+ relative_filename = repo.relative_path(repository_file)
35
+ project_file = context.project_root_dir + relative_filename
36
+
37
+ if project_file.exist?
38
+ # TODO: Should we get a time component in here to check for possible newer base repo files?
39
+ if digest(project_file) != digest(repository_file)
40
+ logger.info "File '#{relative_filename}' is kept as it was changed in the whitelabel project (r: #{repo.timestamp_for(repository_file)} vs w: #{project_file.mtime})."
41
+ else
42
+ logger.debug "Deleting file '#{relative_filename}'..."
43
+ project_file.unlink
44
+
45
+ remove_empty_tree(project_file.dirname)
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ def remove_empty_tree(dir)
52
+ return unless dir.empty?
53
+
54
+ logger.debug "Deleting empty directory '#{dir}'..."
55
+ dir.unlink
56
+
57
+ remove_empty_tree(dir.parent)
58
+ end
59
+
60
+ def digest(file)
61
+ Digest::SHA1.file(file).hexdigest
62
+ end
63
+
64
+ def repo
65
+ @repo ||= LabelWeaver::TempRepo.new(
66
+ context.repository_dir,
67
+ repository_url: configuration.git_repository,
68
+ branch: configuration.git_branch,
69
+ excludes: configuration.excludes,
70
+ logger: logger
71
+ )
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,19 @@
1
+ module LabelWeaver
2
+ module CLI
3
+ module Actions
4
+ module Diff
5
+ class File < Sod::Action
6
+ using Refinements::Pathname
7
+
8
+ description "Shows a diff for a single chosen file. Expects a path relative to the project root."
9
+
10
+ on %w[-f --file], argument: "PATH", type: String
11
+
12
+ def call(path)
13
+ context.input[:file] = Pathname.new(path)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module LabelWeaver
2
+ module CLI
3
+ module Actions
4
+ module Diff
5
+ class Format < Sod::Action
6
+ using Refinements::Pathname
7
+
8
+ description "Choose the format to be used when displaying the diff."
9
+
10
+ on %w[--format], argument: "FORMAT", type: String, allow: %w[unified patch]
11
+
12
+ def call(diff_format)
13
+ context.input[:format] = diff_format
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,48 @@
1
+ require "tty/file"
2
+
3
+ module LabelWeaver
4
+ module CLI
5
+ module Actions
6
+ class Init < Sod::Action
7
+ include Import[:kernel, :logger]
8
+
9
+ using Refinements::Pathname
10
+
11
+ on "--init"
12
+
13
+ description "Initializes a new whitelabel project"
14
+
15
+ def call(*)
16
+ create_config
17
+ create_gitignore
18
+ end
19
+
20
+ private
21
+
22
+ def create_config
23
+ xdg_config = context[xdg_config, :xdg_config]
24
+ defaults_path = Pathname.new(context[defaults_path, :defaults_path])
25
+
26
+ path = xdg_config.local
27
+ path_info = path.to_s.inspect
28
+
29
+ if path.exist?
30
+ logger.warn { "Skipped. Configuration exists: #{path_info}." }
31
+ else
32
+ defaults_path.copy path.make_ancestors
33
+ logger.info { "Created: #{path_info}." }
34
+ end
35
+ end
36
+
37
+ def create_gitignore
38
+ TTY::File.create_file(gitignore)
39
+ TTY::File.append_to_file(gitignore, "repository", force: false)
40
+ end
41
+
42
+ def gitignore
43
+ context.local_tmp_dir + ".gitignore"
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,30 @@
1
+ require "tty/file"
2
+
3
+ module LabelWeaver
4
+ module CLI
5
+ module Actions
6
+ class PrepareBaseProject < Sod::Action
7
+ include Import[:kernel, :logger]
8
+
9
+ on "--prepare-base-project"
10
+
11
+ description "Adjusts certain files in a project to be used as base for whitelabel projects."
12
+
13
+ def call(*)
14
+ adjust_dockerignore
15
+ end
16
+
17
+ private
18
+
19
+ def adjust_dockerignore
20
+ TTY::File.create_file(dockerignore) unless dockerignore.exist?
21
+ TTY::File.append_to_file(dockerignore, ".config/label_weaver")
22
+ end
23
+
24
+ def dockerignore
25
+ context.project_root_dir + ".dockerignore"
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,16 @@
1
+ module LabelWeaver
2
+ module CLI
3
+ module Commands
4
+ class Develop < Sod::Command
5
+ include Import[:kernel, :logger]
6
+
7
+ handle "develop"
8
+
9
+ description "Start / Stop whitelabel development mode"
10
+
11
+ on(::LabelWeaver::CLI::Actions::Develop::Start)
12
+ on(::LabelWeaver::CLI::Actions::Develop::Stop)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,69 @@
1
+ require "tty/pager"
2
+ require "diffy"
3
+
4
+ module LabelWeaver
5
+ module CLI
6
+ module Commands
7
+ class Diff < Sod::Command
8
+ include Import[:kernel, :logger, :configuration]
9
+
10
+ handle "diff"
11
+
12
+ description "Shows difference between the base repository and the local files "
13
+
14
+ on(::LabelWeaver::CLI::Actions::Diff::Format)
15
+ on(::LabelWeaver::CLI::Actions::Diff::File)
16
+
17
+ def call(*)
18
+ @file_path = context.input[:file]
19
+
20
+ case context.input[:format] || "unified"
21
+ when "unified"
22
+ TTY::Pager.page do |pager|
23
+ changed_files.each do |repository_file, project_file|
24
+ pager.write <<~EOS
25
+
26
+ #{"*" * (project_file.to_s.length + 4)}
27
+ * #{project_file} *
28
+ #{"*" * (project_file.to_s.length + 4)}
29
+
30
+ EOS
31
+
32
+ pager.write Diffy::Diff.new(repository_file.to_s, project_file.to_s, source: "files", context: 3).to_s(:color)
33
+ end
34
+ end
35
+ when "patch"
36
+ changed_files.each do |repository_file, project_file|
37
+ puts Diffy::Diff.new(repository_file.to_s, project_file.to_s, source: "files", context: 0, include_diff_info: true)
38
+ end
39
+ else
40
+ logger.error "Unknown format: #{context.input[:format]}"
41
+ end
42
+ logger.info context.input.inspect
43
+ end
44
+
45
+ private
46
+
47
+ def changed_files
48
+ repo.relevant_files_with_project_files(project_root_dir: context.project_root_dir).filter_map do |repository_file, project_file|
49
+ next unless project_file.exist?
50
+ next unless repo.changed_file?(repository_file, project_root_dir: context.project_root_dir)
51
+ next if @file_path && project_file != context.project_root_dir + @file_path
52
+
53
+ [repository_file, project_file]
54
+ end
55
+ end
56
+
57
+ def repo
58
+ @repo ||= LabelWeaver::TempRepo.new(
59
+ context.repository_dir,
60
+ repository_url: configuration.git_repository,
61
+ branch: configuration.git_branch,
62
+ excludes: configuration.excludes,
63
+ logger: logger
64
+ )
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "sod"
4
+
5
+ module LabelWeaver
6
+ module CLI
7
+ # The main Command Line Interface (CLI) object.
8
+ class Shell
9
+ include Import[:defaults_path, :xdg_config, :specification]
10
+
11
+ def initialize(context: Sod::Context, dsl: Sod, **)
12
+ super(**)
13
+ @context = context
14
+ @dsl = dsl
15
+ end
16
+
17
+ def call(...) = cli.call(...)
18
+
19
+ private
20
+
21
+ attr_reader :context, :dsl
22
+
23
+ def cli
24
+ context = build_context
25
+
26
+ dsl.new :label_weaver, banner: specification.banner do
27
+ on(::LabelWeaver::CLI::Actions::Init, context:)
28
+ on(::LabelWeaver::CLI::Actions::PrepareBaseProject, context:)
29
+ on(::LabelWeaver::CLI::Commands::Develop, context:)
30
+ on(::LabelWeaver::CLI::Commands::Diff, context:)
31
+ on(Sod::Prefabs::Actions::Version, context:)
32
+ on(Sod::Prefabs::Actions::Help, self)
33
+ end
34
+ end
35
+
36
+ def build_context
37
+ context[
38
+ input: {},
39
+ project_root_dir: Pathname.new(Dir.pwd),
40
+ local_tmp_dir: Pathname.new(Dir.pwd).join(".config", "label_weaver"),
41
+ repository_dir: Pathname.new(Dir.pwd).join(".config", "label_weaver", "repository"),
42
+ tracking_file: Pathname.new(Dir.pwd).join(".config", "label_weaver", "files.yml"),
43
+ defaults_path:,
44
+ xdg_config:,
45
+ version_label: specification.labeled_version
46
+ ]
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/schema"
4
+
5
+ Dry::Schema.load_extensions :monads
6
+
7
+ module LabelWeaver
8
+ module Configuration
9
+ Contract = Dry::Schema.Params do
10
+ required(:git_repository).filled :string
11
+ required(:git_branch).filled :string
12
+ optional(:excludes).array :string
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ git:
2
+ repository: "git@gitlab.com:lopo-tech/label_weaver.git"
3
+ branch: "main"
4
+ # Files to exclude from the base repository, they will not be copied over to the whitelabel project.
5
+ # Shell filename globbing rules apply, not regular expressions
6
+ excludes:
7
+ - .git/**
8
+ # Files here will be appended on whitelabel development instead of being skipped if the
9
+ # file already exists in a project
10
+ #append:
11
+ # - .gitignore
12
+ # - .dockerignore
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LabelWeaver
4
+ module Configuration
5
+ # Defines the configuration model for use throughout the gem.
6
+ Model = Data.define(
7
+ :excludes,
8
+ :git_repository,
9
+ :git_branch
10
+ )
11
+ end
12
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cogger"
4
+ require "containable"
5
+ require "etcher"
6
+ require "runcom"
7
+ require "spek"
8
+
9
+ module LabelWeaver
10
+ # Provides a global gem container for injection into other objects.
11
+ module Container
12
+ extend Containable
13
+
14
+ register :configuration do
15
+ self[:defaults].add_loader(:yaml, self[:xdg_config].active)
16
+ .then { |registry| Etcher.call registry }
17
+ end
18
+
19
+ register :defaults do
20
+ Etcher::Registry.new(contract: Configuration::Contract, model: Configuration::Model)
21
+ .add_loader(:yaml, self[:defaults_path])
22
+ end
23
+
24
+ register(:specification) { Spek::Loader.call "#{__dir__}/../../label_weaver.gemspec" }
25
+ register(:defaults_path) { Pathname(__dir__).join("configuration/defaults.yml") }
26
+ register(:xdg_config) { Runcom::Config.new("label_weaver/configuration.yml") }
27
+ register(:logger) { Cogger.new(id: "label_weaver") }
28
+ register :kernel, Kernel
29
+ end
30
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "infusible"
4
+
5
+ module LabelWeaver
6
+ Import = Infusible[Container]
7
+ end
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "git"
4
+ require "digest"
5
+
6
+ module LabelWeaver
7
+ class TempRepo
8
+ using Refinements::Pathname
9
+
10
+ attr_reader :repository_path, :repository_url, :branch, :excludes, :logger
11
+
12
+ def initialize(repository_path, repository_url:, branch: "main", excludes: [], logger: Logger.new($stdout))
13
+ @repository_path = repository_path
14
+ @repository_url = repository_url
15
+ @branch = branch
16
+ @excludes = excludes + %w[. ..]
17
+ @logger = logger
18
+ end
19
+
20
+ #
21
+ # @return [Time] the last time the file was part of a commit, closest we can get to an mtime
22
+ #
23
+ def timestamp_for(file)
24
+ repo.log(1).path(file).first.date
25
+ end
26
+
27
+ def digest_for(file)
28
+ Digest::SHA1.file(file).hexdigest
29
+ end
30
+
31
+ def changed_file?(repository_file, project_root_dir:)
32
+ digest_for(repository_file) != digest_for(project_root_dir + relative_path(repository_file))
33
+ end
34
+
35
+ #
36
+ # Clones the repository if it doesn't exist yet locally or fetches the latest updates
37
+ #
38
+ def clone_or_update
39
+ if repository_path.exist?
40
+ logger.info "Pulling latest changes from remote repository (#{repository_url})..."
41
+
42
+ repo.pull("origin", branch)
43
+ else
44
+ logger.info "Cloning remote repository, this might take a while..."
45
+
46
+ Git.clone(
47
+ repository_url,
48
+ repository_path.basename,
49
+ path: repository_path.parent,
50
+ branch:
51
+ )
52
+ end
53
+ end
54
+
55
+ #
56
+ # @return [Array<Pathname>] All repository files that are not set to be excluded
57
+ #
58
+ def relevant_files
59
+ files.filter do |file|
60
+ # Reject any files that are set up to be excluded. Shell filename globbing rules apply
61
+ next false if excludes.any? { relative_path(file).fnmatch?(_1, File::FNM_DOTMATCH) }
62
+
63
+ true
64
+ end
65
+ end
66
+
67
+ #
68
+ # Updates the atime and mtime of each file in the repository to their latest commit time
69
+ # TODO: Check if still needed
70
+ #
71
+ def update_repository_timestamps
72
+ logger.info "Updating repository timestamps..."
73
+ repository_path.glob("**/*", File::FNM_DOTMATCH).each do |file|
74
+ # Set the file modification times to the last time they were updated in a commit
75
+ time = repo.all.log.path(file).first.date
76
+ file.utime(time, time)
77
+ end
78
+ end
79
+
80
+ #
81
+ # @return [Pathname] the filename relative to the git repository root
82
+ #
83
+ def relative_path(filename)
84
+ filename.relative_path_from(repository_path)
85
+ end
86
+
87
+ #
88
+ # @return [Array<Array<Pathname, Pathname>>] all relevant repository files with their corresponding
89
+ # path within the project
90
+ #
91
+ def relevant_files_with_project_files(project_root_dir:)
92
+ relevant_files.map do |repository_file|
93
+ relative_filename = relative_path(repository_file)
94
+ [repository_file, project_root_dir + relative_filename]
95
+ end
96
+ end
97
+
98
+ private
99
+
100
+ #
101
+ # @return [Array<Pathname>] All files inside the repository, including dotfiles. No folders.
102
+ #
103
+ def files
104
+ repository_path.glob("**/*", File::FNM_DOTMATCH).select(&:file?)
105
+ end
106
+
107
+ def repo
108
+ @repo ||= Git.open(repository_path)
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "zeitwerk"
4
+ require "ruby-next"
5
+
6
+ Zeitwerk::Loader.new.then do |loader|
7
+ loader.inflector.inflect "cli" => "CLI"
8
+ loader.tag = File.basename __FILE__, ".rb"
9
+ loader.push_dir __dir__
10
+ loader.setup
11
+ end
12
+
13
+ # Main namespace.
14
+ module LabelWeaver
15
+ def self.loader(registry = Zeitwerk::Registry)
16
+ @loader ||= registry.loaders.find { |loader| loader.tag == File.basename(__FILE__, ".rb") }
17
+ end
18
+ end
metadata ADDED
@@ -0,0 +1,276 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: label_weaver
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Stefan Exner
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2024-08-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: cogger
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.21'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.21'
27
+ - !ruby/object:Gem::Dependency
28
+ name: containable
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: dry-monads
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.6'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.6'
55
+ - !ruby/object:Gem::Dependency
56
+ name: dry-schema
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.6'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.6'
69
+ - !ruby/object:Gem::Dependency
70
+ name: diffy
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.4'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.4'
83
+ - !ruby/object:Gem::Dependency
84
+ name: etcher
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.6'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.6'
97
+ - !ruby/object:Gem::Dependency
98
+ name: git
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 2.1.1
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 2.1.1
111
+ - !ruby/object:Gem::Dependency
112
+ name: infusible
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '3.5'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '3.5'
125
+ - !ruby/object:Gem::Dependency
126
+ name: ruby-next-core
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '1.0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: runcom
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '11.0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '11.0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: sod
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '0.8'
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '0.8'
167
+ - !ruby/object:Gem::Dependency
168
+ name: spek
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '3.0'
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '3.0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: tty-file
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '0.10'
188
+ type: :runtime
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: '0.10'
195
+ - !ruby/object:Gem::Dependency
196
+ name: tty-pager
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: '0.14'
202
+ type: :runtime
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: '0.14'
209
+ - !ruby/object:Gem::Dependency
210
+ name: zeitwerk
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - "~>"
214
+ - !ruby/object:Gem::Version
215
+ version: '2.6'
216
+ type: :runtime
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - "~>"
221
+ - !ruby/object:Gem::Version
222
+ version: '2.6'
223
+ description:
224
+ email:
225
+ - stex@stex.codes
226
+ executables:
227
+ - label_weaver
228
+ extensions: []
229
+ extra_rdoc_files:
230
+ - README.md
231
+ files:
232
+ - README.md
233
+ - exe/label_weaver
234
+ - label_weaver.gemspec
235
+ - lib/label_weaver.rb
236
+ - lib/label_weaver/cli/actions/develop/start.rb
237
+ - lib/label_weaver/cli/actions/develop/stop.rb
238
+ - lib/label_weaver/cli/actions/diff/file.rb
239
+ - lib/label_weaver/cli/actions/diff/format.rb
240
+ - lib/label_weaver/cli/actions/init.rb
241
+ - lib/label_weaver/cli/actions/prepare_base_project.rb
242
+ - lib/label_weaver/cli/commands/develop.rb
243
+ - lib/label_weaver/cli/commands/diff.rb
244
+ - lib/label_weaver/cli/shell.rb
245
+ - lib/label_weaver/configuration/contract.rb
246
+ - lib/label_weaver/configuration/defaults.yml
247
+ - lib/label_weaver/configuration/model.rb
248
+ - lib/label_weaver/container.rb
249
+ - lib/label_weaver/import.rb
250
+ - lib/label_weaver/temp_repo.rb
251
+ homepage: https://gitlab.com/lopo-tech/label_weaver
252
+ licenses:
253
+ - MIT
254
+ metadata:
255
+ label: LabelWeaver
256
+ rubygems_mfa_required: 'true'
257
+ post_install_message:
258
+ rdoc_options: []
259
+ require_paths:
260
+ - lib
261
+ required_ruby_version: !ruby/object:Gem::Requirement
262
+ requirements:
263
+ - - "~>"
264
+ - !ruby/object:Gem::Version
265
+ version: '3.3'
266
+ required_rubygems_version: !ruby/object:Gem::Requirement
267
+ requirements:
268
+ - - ">="
269
+ - !ruby/object:Gem::Version
270
+ version: '0'
271
+ requirements: []
272
+ rubygems_version: 3.5.14
273
+ signing_key:
274
+ specification_version: 4
275
+ summary: Helper tool to manage whitelabel version of base projects
276
+ test_files: []