git_compound 0.1.2 → 0.2.0

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.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/git_compound.gemspec +4 -6
  3. data/lib/git_compound/command/arguments/parser.rb +74 -0
  4. data/lib/git_compound/command/arguments/type/argument/argument.rb +23 -0
  5. data/lib/git_compound/command/arguments/type/argument/string.rb +27 -0
  6. data/lib/git_compound/command/arguments/type/parameter/boolean.rb +27 -0
  7. data/lib/git_compound/command/arguments/type/parameter/parameter.rb +23 -0
  8. data/lib/git_compound/command/arguments/type/parameter/string.rb +23 -0
  9. data/lib/git_compound/command/arguments/type/type.rb +48 -0
  10. data/lib/git_compound/command/options.rb +11 -26
  11. data/lib/git_compound/command/procedure/build.rb +24 -0
  12. data/lib/git_compound/command/procedure/build_lock.rb +40 -0
  13. data/lib/git_compound/command/procedure/build_manifest.rb +44 -0
  14. data/lib/git_compound/command/procedure/check.rb +25 -0
  15. data/lib/git_compound/command/procedure/element/lock.rb +22 -0
  16. data/lib/git_compound/command/procedure/element/manifest.rb +36 -0
  17. data/lib/git_compound/command/procedure/element/option.rb +49 -0
  18. data/lib/git_compound/command/procedure/element/subprocedure.rb +53 -0
  19. data/lib/git_compound/command/procedure/help.rb +55 -0
  20. data/lib/git_compound/command/procedure/procedure.rb +37 -0
  21. data/lib/git_compound/command/procedure/show.rb +22 -0
  22. data/lib/git_compound/command/procedure/tasks.rb +27 -0
  23. data/lib/git_compound/command/procedure/update.rb +66 -0
  24. data/lib/git_compound/command.rb +13 -94
  25. data/lib/git_compound/component/version/version_strategy.rb +1 -1
  26. data/lib/git_compound/component.rb +1 -0
  27. data/lib/git_compound/exceptions.rb +1 -0
  28. data/lib/git_compound/logger/core_ext/string.rb +1 -2
  29. data/lib/git_compound/logger.rb +2 -6
  30. data/lib/git_compound/version.rb +1 -1
  31. data/lib/git_compound.rb +50 -1
  32. metadata +27 -6
  33. data/lib/git_compound/builder.rb +0 -95
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3fcf9e29c1abe4d4c3fe2287e8559cd84035b8a7
4
- data.tar.gz: b2746150e9f9fc1dfe86a5a12287606a85411302
3
+ metadata.gz: 06924151a5c14eac3ffebfc3005358de3e85a7e9
4
+ data.tar.gz: bbb37c1178dea881ad1dbc016fe8047dc028eddd
5
5
  SHA512:
6
- metadata.gz: d0ab07e4b756841e02a71a62043bc67292a6de43b6e8c2abc811c0b6cf05c9f3fa9a2d305db945a7a625c5e563c38263af4de7be899e8b6d133b36edc9bcde21
7
- data.tar.gz: 4b9f4a83e653c1f9c1e6ed5b1c69e558617e9537e29d13f588a7f1c67c7d253a28b59281f81e6831f3a7c3ab5e14915946557655950842f434545f8e0a5b4f2a
6
+ metadata.gz: 84227d3ee9e3bb7abd77b61bab4600bd6a3b0d2fbd05a97c6470ac6f2933ea12700772d0a796cc1703254645997e537f000388ea7f0413a4bb6d94ae007a3c5a
7
+ data.tar.gz: 64797a7958521128971997327b9f23f3ee46fdeafa7e1afe3f45d04b24ec39a9cedec7df20b246abe4a9b7051d67e812722e0e575e5fc3ee7cf784d4dd89c912
data/git_compound.gemspec CHANGED
@@ -6,9 +6,9 @@ require 'git_compound/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'git_compound'
8
8
  spec.version = GitCompound::VERSION
9
- spec.authors = ['Grzegorz Bizon']
10
- spec.email = ['grzegorz.bizon@ntsn.pl']
11
- spec.summary = 'Compose you project using git repositories and ruby tasks'
9
+ spec.authors = ['Grzegorz Bizon', 'Tomasz Maczukin']
10
+ spec.email = ['grzegorz.bizon@ntsn.pl', 'tomasz@maczukin.pl']
11
+ spec.summary = 'Compose you project using Git repositories and ruby tasks'
12
12
  spec.homepage = 'https://github.com/grzesiek/git_compound'
13
13
  spec.license = 'MIT'
14
14
 
@@ -17,14 +17,12 @@ Gem::Specification.new do |spec|
17
17
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
18
  spec.require_paths = ['lib']
19
19
 
20
- # rubocop:disable Style/SingleSpaceBeforeFirstArg
21
20
  spec.add_development_dependency 'bundler', '~> 1.8'
22
21
  spec.add_development_dependency 'rake', '~> 10.0'
23
- spec.add_development_dependency 'rubocop', '~> 0.31.0'
22
+ spec.add_development_dependency 'rubocop', '~> 0.33'
24
23
  spec.add_development_dependency 'rspec', '~> 3.2.0'
25
24
  spec.add_development_dependency 'pry', '~> 0.10.1'
26
25
  spec.add_development_dependency 'simplecov', '~> 0.10.0'
27
- # rubocop:enable Style/SingleSpaceBeforeFirstArg
28
26
 
29
27
  spec.requirements << 'git scm version > 2'
30
28
  spec.requirements << 'gnu tar'
@@ -0,0 +1,74 @@
1
+ module GitCompound
2
+ module Command
3
+ module Arguments
4
+ # Class responsible for parsing ARGV for given procedure
5
+ #
6
+ class Parser
7
+ def initialize(argv, global)
8
+ @global = global
9
+ @args = format_arguments(argv)
10
+ end
11
+
12
+ def procedure
13
+ Command.const_get("Procedure::#{command.capitalize}")
14
+ rescue
15
+ Procedure::Help
16
+ end
17
+
18
+ def options
19
+ arguments = @args - @global - [command]
20
+ found = {}
21
+
22
+ option_each(procedure.options) do |name, type|
23
+ option = type.new(name, arguments)
24
+ next unless option.valid?
25
+
26
+ arguments -= option.used
27
+ found.merge!(option.parse)
28
+ end
29
+
30
+ return found if arguments.empty?
31
+ raise UnknownArgumentError,
32
+ "Unknown arguments `#{arguments.inspect}`"
33
+ end
34
+
35
+ def global
36
+ @args & @global
37
+ end
38
+
39
+ def command
40
+ @args.find { |arg| arg.is_a?(String) }
41
+ end
42
+
43
+ private
44
+
45
+ def format_arguments(argv)
46
+ argv.map do |arg|
47
+ arg.start_with?('--') ? arg.sub(/^--/, '').tr('-', '_').to_sym : arg
48
+ end
49
+ end
50
+
51
+ def option_each(expected)
52
+ # parameters first, arguments last
53
+ opts = expected.sort_by { |_key, value| value[:variant] }.reverse
54
+
55
+ opts.each do |opt|
56
+ name = opt.first
57
+ type = option_type(opt.last)
58
+
59
+ yield name, type
60
+ end
61
+ end
62
+
63
+ def option_type(metadata)
64
+ variant = metadata[:variant].capitalize
65
+ type = metadata[:type].capitalize
66
+ Arguments::Type.const_get("#{variant}::#{type}")
67
+ rescue NameError
68
+ raise GitCompoundError,
69
+ "Unknown option variant or type `#{variant}`, `#{type}`"
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,23 @@
1
+ module GitCompound
2
+ module Command
3
+ module Arguments
4
+ module Type
5
+ module Argument
6
+ # Abstract argument type
7
+ #
8
+ class Argument < Type
9
+ def used
10
+ [value!].compact
11
+ end
12
+
13
+ private
14
+
15
+ def value!
16
+ raise NotImplementedError
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,27 @@
1
+ module GitCompound
2
+ module Command
3
+ module Arguments
4
+ module Type
5
+ module Argument
6
+ # String argument implementation
7
+ #
8
+ class String < Argument
9
+ def valid?
10
+ value!.is_a?(::String)
11
+ end
12
+
13
+ private
14
+
15
+ def value!
16
+ @args.find { |arg| arg.is_a?(::String) }
17
+ end
18
+
19
+ def value
20
+ value!.to_s
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ module GitCompound
2
+ module Command
3
+ module Arguments
4
+ module Type
5
+ module Parameter
6
+ # Boolean parameter implmentation
7
+ #
8
+ class Boolean < Parameter
9
+ def valid?
10
+ @args.include?(@key)
11
+ end
12
+
13
+ private
14
+
15
+ def value!
16
+ nil
17
+ end
18
+
19
+ def value
20
+ true
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,23 @@
1
+ module GitCompound
2
+ module Command
3
+ module Arguments
4
+ module Type
5
+ module Parameter
6
+ # Abstract parameter type
7
+ #
8
+ class Parameter < Type
9
+ def used
10
+ valid? ? [@key, value!].compact : []
11
+ end
12
+
13
+ private
14
+
15
+ def value!
16
+ @args[@args.index(@key) + 1]
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ module GitCompound
2
+ module Command
3
+ module Arguments
4
+ module Type
5
+ module Parameter
6
+ # String parameter implementation
7
+ #
8
+ class String < Parameter
9
+ def valid?
10
+ @args.include?(@key) && value!.is_a?(::String)
11
+ end
12
+
13
+ private
14
+
15
+ def value
16
+ value!.to_s
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,48 @@
1
+ module GitCompound
2
+ module Command
3
+ module Arguments
4
+ module Type
5
+ # Abstract argument type
6
+ #
7
+ class Type
8
+ def initialize(key, args)
9
+ @key = key
10
+ @args = args
11
+ end
12
+
13
+ def parse
14
+ valid? ? { @key => value } : {}
15
+ end
16
+
17
+ # Return true if arguments array contains
18
+ # this parameter/argument, else - return false
19
+ #
20
+ def valid?
21
+ raise NotImplementedError
22
+ end
23
+
24
+ # Returns array of arguments that has been used
25
+ #
26
+ def used
27
+ raise NotImplementedError
28
+ end
29
+
30
+ private
31
+
32
+ # Returns bare value extracted from args
33
+ # or nil if bare arguments is irrelevant
34
+ #
35
+ def value!
36
+ raise NotImplementedError
37
+ end
38
+
39
+ # Return value converted to valid type
40
+ #
41
+ def value
42
+ raise NotImplementedError
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,31 +1,22 @@
1
+ require 'forwardable'
2
+
1
3
  module GitCompound
2
4
  module Command
3
5
  # Class that parses command arguments
4
6
  #
5
7
  class Options
6
- GLOBAL_OPTIONS = [:verbose, :disable_colors]
8
+ extend Forwardable
7
9
 
8
- def initialize(args)
9
- @command, @args = parse_options(args)
10
+ GLOBAL_OPTIONS = [:verbose, :disable_colors]
11
+ delegate [:procedure, :global, :options, :command] => :@parser
10
12
 
11
- self.class.disable_colors = false
13
+ def initialize(argv)
14
+ @parser = Arguments::Parser.new(argv, GLOBAL_OPTIONS)
12
15
  set_global_options
13
16
  end
14
17
 
15
- def global_options
16
- @args & GLOBAL_OPTIONS
17
- end
18
-
19
- def command_options
20
- @args - GLOBAL_OPTIONS
21
- end
22
-
23
- def command
24
- @command || 'help'
25
- end
26
-
27
18
  def parse
28
- [command, command_options]
19
+ [procedure, options]
29
20
  end
30
21
 
31
22
  def self.verbose=(mode)
@@ -38,16 +29,10 @@ module GitCompound
38
29
 
39
30
  private
40
31
 
41
- def parse_options(args)
42
- opts_dash = args.select { |opt| opt.start_with?('--') }
43
- opts_string = args - opts_dash
44
- command = opts_string.shift
45
- opts_sym = opts_dash.collect { |opt| opt.sub(/^--/, '').gsub('-', '_').to_sym }
46
- [command, opts_string + opts_sym]
47
- end
48
-
49
32
  def set_global_options
50
- global_options.each do |option|
33
+ self.class.disable_colors = false
34
+
35
+ global.each do |option|
51
36
  self.class.public_send("#{option}=", true)
52
37
  end
53
38
  end
@@ -0,0 +1,24 @@
1
+ module GitCompound
2
+ module Command
3
+ module Procedure
4
+ # Build command class
5
+ #
6
+ class Build < Procedure
7
+ include Element::Lock
8
+ include Element::Option
9
+ include Element::Subprocedure
10
+
11
+ add_subprocedure :build_lock, BuildLock
12
+ add_subprocedure :build_manifest, BuildManifest
13
+
14
+ def execute
15
+ if locked?
16
+ subprocedure(:build_lock)
17
+ else
18
+ subprocedure(:build_manifest)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,40 @@
1
+ module GitCompound
2
+ module Command
3
+ module Procedure
4
+ # BuildLock procedure class
5
+ #
6
+ class BuildLock < Procedure
7
+ include Element::Manifest
8
+ include Element::Lock
9
+ include Element::Subprocedure
10
+
11
+ add_subprocedure :tasks_runner, Tasks
12
+
13
+ def execute
14
+ Logger.info 'Building components from lockfile ...'
15
+
16
+ verify_manifest
17
+ build_locked_components
18
+ execute_tasks
19
+ end
20
+
21
+ private
22
+
23
+ def verify_manifest
24
+ return if @manifest.md5sum == @lock.manifest
25
+
26
+ raise GitCompoundError,
27
+ 'Manifest md5sum has changed ! Use `update` command.'
28
+ end
29
+
30
+ def build_locked_components
31
+ @lock.process(Worker::ComponentDispatcher.new(@lock))
32
+ end
33
+
34
+ def execute_tasks
35
+ subprocedure(:tasks_runner)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,44 @@
1
+ module GitCompound
2
+ module Command
3
+ module Procedure
4
+ # BuildManifest procedure class
5
+ #
6
+ class BuildManifest < Procedure
7
+ include Element::Manifest
8
+ include Element::Lock
9
+ include Element::Subprocedure
10
+
11
+ add_subprocedure :check_dependencies, Check
12
+ add_subprocedure :tasks_runner, Tasks
13
+
14
+ def execute
15
+ Logger.info 'Building components ...'
16
+
17
+ check_dependencies
18
+ build_manifest
19
+ execute_tasks
20
+ lock_manifest
21
+ end
22
+
23
+ private
24
+
25
+ def check_dependencies
26
+ subprocedure(:check_dependencies)
27
+ end
28
+
29
+ def build_manifest
30
+ @manifest.process(Worker::ComponentBuilder.new(@lock))
31
+ end
32
+
33
+ def execute_tasks
34
+ subprocedure(:tasks_runner)
35
+ end
36
+
37
+ def lock_manifest
38
+ @lock.lock_manifest(@manifest)
39
+ @lock.write
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,25 @@
1
+ module GitCompound
2
+ module Command
3
+ module Procedure
4
+ # Check command procedure class
5
+ #
6
+ class Check < Procedure
7
+ include Element::Manifest
8
+
9
+ def execute!
10
+ execute
11
+ Logger.info 'OK'
12
+ end
13
+
14
+ def execute
15
+ Logger.info 'Checking dependencies ...'
16
+
17
+ @manifest.process(
18
+ Worker::CircularDependencyChecker.new,
19
+ Worker::NameConstraintChecker.new,
20
+ Worker::ConflictingDependencyChecker.new)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,22 @@
1
+ module GitCompound
2
+ module Command
3
+ module Procedure
4
+ module Element
5
+ # Lock mixin
6
+ #
7
+ module Lock
8
+ def initialize(opts)
9
+ @lock = GitCompound::Lock.new
10
+ @lock_new = GitCompound::Lock.new.clean
11
+
12
+ super
13
+ end
14
+
15
+ def locked?
16
+ GitCompound::Lock.exist?
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,36 @@
1
+ module GitCompound
2
+ module Command
3
+ module Procedure
4
+ module Element
5
+ # Manifest mixin
6
+ #
7
+ module Manifest
8
+ def initialize(opts)
9
+ super
10
+ @manifest = manifest_load(opts[:manifest])
11
+ end
12
+
13
+ def self.included(parent_class)
14
+ parent_class.class_eval do
15
+ include Element::Option
16
+ add_argument :manifest, type: :string, scope: :global
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def manifest_load(filename)
23
+ files = filename ? [filename] : GitCompound::Manifest::FILENAMES
24
+ found = files.select { |file| File.exist?(file) }
25
+
26
+ raise GitCompoundError,
27
+ "Manifest `#{filename || files.inspect}` not found !" if found.empty?
28
+
29
+ contents = File.read(found.first)
30
+ GitCompound::Manifest.new(contents)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,49 @@
1
+ module GitCompound
2
+ module Command
3
+ module Procedure
4
+ module Element
5
+ # Option mixin
6
+ #
7
+ module Option
8
+ def initialize(opts)
9
+ @opts = opts
10
+ super
11
+ end
12
+
13
+ def self.included(parent_class)
14
+ parent_class.extend(ClassMethods)
15
+ end
16
+
17
+ private
18
+
19
+ # Class methods
20
+ #
21
+ module ClassMethods
22
+ def add_parameter(name, metadata)
23
+ add_option(name, :parameter, metadata)
24
+ end
25
+
26
+ def add_argument(name, metadata)
27
+ add_option(name, :argument, metadata)
28
+ end
29
+
30
+ def options
31
+ (@options || {}).merge(super)
32
+ end
33
+
34
+ private
35
+
36
+ def add_option(name, variant, metadata)
37
+ @options = {} unless @options
38
+
39
+ raise GitCompoundError, 'You need to specify type of an option !' unless
40
+ metadata.include?(:type)
41
+
42
+ @options.store(name, metadata.merge(variant: variant))
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,53 @@
1
+ module GitCompound
2
+ module Command
3
+ module Procedure
4
+ module Element
5
+ # Subprocedure mixin
6
+ #
7
+ module Subprocedure
8
+ def self.included(parent_class)
9
+ parent_class.extend(ClassMethods)
10
+ end
11
+
12
+ def initialize(args)
13
+ @subprocedures = {}
14
+
15
+ self.class.subprocedures.to_h.each_pair do |name, procedure|
16
+ @subprocedures.store(name, procedure.new(args))
17
+ end
18
+
19
+ super
20
+ end
21
+
22
+ def subprocedure(name)
23
+ @subprocedures[name.to_sym].execute
24
+ end
25
+
26
+ # Class methods for extended class
27
+ #
28
+ module ClassMethods
29
+ attr_reader :subprocedures
30
+
31
+ def add_subprocedure(name, procedure)
32
+ @subprocedures = {} unless @subprocedures
33
+ @subprocedures.store(name.to_sym, procedure)
34
+ end
35
+
36
+ def options
37
+ subprocedure_options = {}
38
+ @subprocedures.to_h.each do |_, procedure|
39
+ subprocedure_options.merge!(procedure.options)
40
+ end
41
+
42
+ subprocedure_options.select! do |_param, metadata|
43
+ metadata[:scope] == :global
44
+ end
45
+
46
+ subprocedure_options.merge(super)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,55 @@
1
+ module GitCompound
2
+ module Command
3
+ module Procedure
4
+ # Help command procedure
5
+ #
6
+ class Help < Procedure
7
+ def execute
8
+ Logger.info(message)
9
+ end
10
+
11
+ def message
12
+ self.class.message
13
+ end
14
+
15
+ # rubocop:disable Metrics/AbcSize
16
+ def self.message
17
+ <<-EOS
18
+ #{'GitCompound version'.bold.yellow} #{GitCompound::VERSION.bold}
19
+
20
+ Usage: #{'gitcompound'.bold.green}
21
+ #{'[options]'.green} #{'command'.bold} #{'[manifest_file]'.green}
22
+
23
+ Commands:
24
+ #{'build'.bold}
25
+ builds project from manifest (or lockfile if present)
26
+
27
+ If manifest is not specified it uses one of
28
+ #{Manifest::FILENAMES.inspect}
29
+
30
+ #{'update'.bold}
31
+ updates project
32
+
33
+ #{'check'.bold}
34
+ detects circular depenencies, conflicting dependencies
35
+ and checks for name contraints
36
+
37
+ #{'show'.bold}
38
+ prints structure of project
39
+
40
+ #{'help'.bold}
41
+ prints this help
42
+
43
+ Options:'
44
+ #{'--verbose'.bold}
45
+ prints verbose log info
46
+
47
+ #{'--disable-colors'.bold}
48
+ disable ANSI colors in output
49
+ EOS
50
+ end
51
+ # rubocop:enable Metrics/AbcSize
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,37 @@
1
+ module GitCompound
2
+ module Command
3
+ module Procedure
4
+ # Abstract Procedure class
5
+ #
6
+ class Procedure
7
+ def initialize(_opts)
8
+ end
9
+
10
+ # Method with additional messages etc.
11
+ #
12
+ def execute!
13
+ execute
14
+ end
15
+
16
+ # Main procedure entry point
17
+ #
18
+ def execute
19
+ raise NotImplementedError
20
+ end
21
+
22
+ # Valid options available for this procedure
23
+ # see Element::Option
24
+ #
25
+ def self.options
26
+ {}
27
+ end
28
+
29
+ # Name of procedure
30
+ #
31
+ def self.to_s
32
+ name.split('::').last.downcase
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,22 @@
1
+ module GitCompound
2
+ module Command
3
+ module Procedure
4
+ # Show command procedure class
5
+ #
6
+ class Show < Procedure
7
+ include Element::Manifest
8
+
9
+ def execute!
10
+ Logger.info 'Processing components list ...'
11
+ execute
12
+ end
13
+
14
+ def execute
15
+ @manifest.process(
16
+ Worker::CircularDependencyChecker.new,
17
+ Worker::PrettyPrint.new)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,27 @@
1
+ module GitCompound
2
+ module Command
3
+ module Procedure
4
+ # Check command procedure class
5
+ #
6
+ class Tasks < Procedure
7
+ include Element::Manifest
8
+ include Element::Option
9
+
10
+ add_parameter :allow_nested_subtasks, type: :boolean, scope: :global
11
+ # add_parameter :list, type: Argument::StringBoolean
12
+
13
+ def execute
14
+ Logger.info 'Running tasks ...'
15
+
16
+ if @opts[:allow_nested_subtasks]
17
+ @manifest.process(Worker::TaskRunner.new)
18
+ else
19
+ @manifest.tasks.each_value do |task|
20
+ Worker::TaskRunner.new.visit_task(task)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,66 @@
1
+ module GitCompound
2
+ module Command
3
+ module Procedure
4
+ # Update command procedure class
5
+ #
6
+ class Update < Procedure
7
+ include Element::Manifest
8
+ include Element::Lock
9
+ include Element::Subprocedure
10
+
11
+ add_subprocedure :check_dependencies, Check
12
+ add_subprocedure :tasks_runner, Tasks
13
+
14
+ def execute
15
+ raise GitCompoundError,
16
+ "Lockfile `#{Lock::FILENAME}` does not exist ! " \
17
+ 'You should use `build` command.' unless locked?
18
+
19
+ protect_local_modifications
20
+ check_dependencies
21
+ update
22
+ execute_tasks
23
+ lock_updated_manifest
24
+ remove_dormant_components
25
+ end
26
+
27
+ private
28
+
29
+ def protect_local_modifications
30
+ @lock.process(Worker::LocalChangesGuard.new(@lock))
31
+ end
32
+
33
+ def check_dependencies
34
+ subprocedure(:check_dependencies)
35
+ end
36
+
37
+ def update
38
+ Logger.info 'Updating components ...'
39
+ @manifest.process(Worker::ComponentDispatcher.new(@lock_new))
40
+ end
41
+
42
+ def execute_tasks
43
+ subprocedure(:tasks_runner)
44
+ end
45
+
46
+ def lock_updated_manifest
47
+ @lock_new.lock_manifest(@manifest)
48
+ @lock_new.write
49
+ end
50
+
51
+ def remove_dormant_components
52
+ dormant_components = @lock.components.reject do |component|
53
+ @lock_new.find(component) ? true : false
54
+ end
55
+
56
+ dormant_components.each do |component|
57
+ Logger.warn "Removing dormant component `#{component.name}` " \
58
+ "from `#{component.path}` !"
59
+
60
+ component.remove!
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -2,111 +2,30 @@ module GitCompound
2
2
  # GitCompount command facade
3
3
  #
4
4
  module Command
5
- def build(*args)
6
- if Lock.exist?
7
- builder(args)
8
- .locked_manifest_verify
9
- .locked_components_build
10
- .tasks_execute
11
- else
12
- builder(args)
13
- .dependencies_check
14
- .manifest_build
15
- .tasks_execute
16
- .manifest_lock
17
- end
5
+ def build(manifest, opts = {})
6
+ run(Procedure::Build, opts.merge(manifest: manifest))
18
7
  end
19
8
 
20
- def update(*args)
21
- raise GitCompoundError,
22
- "Lockfile `#{Lock::FILENAME}` does not exist ! " \
23
- 'You should use `build` command.' unless Lock.exist?
24
-
25
- builder(args)
26
- .locked_components_guard
27
- .dependencies_check
28
- .manifest_update
29
- .tasks_execute
30
- .manifest_lock
31
- .locked_dormant_components_remove
9
+ def update(manifest, opts = {})
10
+ run(Procedure::Update, opts.merge(manifest: manifest))
32
11
  end
33
12
 
34
- def check(*args)
35
- builder(args).dependencies_check
36
- Logger.info 'OK'
13
+ def check(manifest, opts = {})
14
+ run(Procedure::Check, opts.merge(manifest: manifest))
37
15
  end
38
16
 
39
- def show(*args)
40
- builder(args).components_show
17
+ def show(manifest, opts = {})
18
+ run(Procedure::Show, opts.merge(manifest: manifest))
41
19
  end
42
20
 
43
- def help(*_args)
44
- Logger.info(usage)
21
+ def help(opts = {})
22
+ run(Procedure::Help, opts)
45
23
  end
46
24
 
47
- def run(command, args)
48
- abort(usage) unless methods.include?(command.to_sym)
49
- public_send(command, *args)
25
+ def run(procedure, opts)
26
+ procedure.new(opts).execute!
50
27
  rescue GitCompoundError => e
51
- abort Logger.parse("Error: #{e.message}".on_red.white.bold)
52
- end
53
-
54
- private
55
-
56
- def builder(args)
57
- filename = args.find { |arg| arg.is_a? String }
58
- Builder.new(manifest(filename), Lock.new, args)
59
- end
60
-
61
- def manifest(filename)
62
- files = filename ? [filename] : Manifest::FILENAMES
63
- found = files.select { |file| File.exist?(file) }
64
-
65
- raise GitCompoundError,
66
- "Manifest `#{filename || files.inspect}` not found !" if found.empty?
67
-
68
- contents = File.read(found.first)
69
- Manifest.new(contents)
70
- end
71
-
72
- # rubocop:disable Metrics/AbcSize
73
- def usage
74
- msg = <<-EOS
75
- #{'GitCompound version'.bold.yellow} #{GitCompound::VERSION.bold}
76
-
77
- Usage: #{'gitcompound'.bold.green} #{
78
- '[options]'.green} #{'command'.bold} #{'[manifest_file]'.green}
79
-
80
- Commands:
81
- #{'build'.bold}
82
- builds project from manifest (or lockfile if present)
83
-
84
- If manifest is not specified it uses one of
85
- #{Manifest::FILENAMES.inspect}
86
-
87
- #{'update'.bold}
88
- updates project
89
-
90
- #{'check'.bold}
91
- detects circular depenencies, conflicting dependencies
92
- and checks for name contraints
93
-
94
- #{'show'.bold}
95
- prints structure of project
96
-
97
- #{'help'.bold}
98
- prints this help
99
-
100
- Options:'
101
- #{'--verbose'.bold}
102
- prints verbose log info
103
-
104
- #{'--disable-colors'.bold}
105
- disable ANSI colors in output
106
- EOS
107
-
108
- Logger.parse(msg)
28
+ abort "Error: #{e.message}".on_red.white.bold
109
29
  end
110
- # rubocop:enable Metrics/AbcSize
111
30
  end
112
31
  end
@@ -37,7 +37,7 @@ module GitCompound
37
37
  end
38
38
 
39
39
  def ==(other)
40
- to_s == other.to_s
40
+ sha == other.sha
41
41
  end
42
42
  end
43
43
  end
@@ -44,6 +44,7 @@ module GitCompound
44
44
  @destination.repository do |repo|
45
45
  repo.fetch
46
46
  repo.checkout(@source.ref)
47
+ repo.fetch
47
48
  repo.merge if repo.branch?(@source.ref)
48
49
  end
49
50
  end
@@ -13,4 +13,5 @@ module GitCompound
13
13
  class ConflictingDependencyError < GitCompoundError; end
14
14
  class NameConstraintError < GitCompoundError; end
15
15
  class LocalChangesError < GitCompoundError; end
16
+ class UnknownArgumentError < GitCompoundError; end
16
17
  end
@@ -1,5 +1,4 @@
1
- # rubocop:disable Style/Documentation
2
- class String
1
+ class String # rubocop:disable Style/Documentation
3
2
  include GitCompound::Logger::Colors
4
3
  end
5
4
  # rubocop:enable Style/Documentation
@@ -10,7 +10,7 @@ module GitCompound
10
10
  end
11
11
 
12
12
  def verbose
13
- @verbose ||= false
13
+ @verbose.nil? ? false : @verbose
14
14
  end
15
15
 
16
16
  def colors=(value)
@@ -18,7 +18,7 @@ module GitCompound
18
18
  end
19
19
 
20
20
  def colors
21
- @colors ||= true
21
+ @colors.nil? ? true : @colors
22
22
  end
23
23
 
24
24
  def inline(inline_message)
@@ -42,10 +42,6 @@ module GitCompound
42
42
  log error_message.on_red.white.bold
43
43
  end
44
44
 
45
- def parse(message)
46
- message
47
- end
48
-
49
45
  private
50
46
 
51
47
  def log(message)
@@ -1,5 +1,5 @@
1
1
  # GitCompound
2
2
  #
3
3
  module GitCompound
4
- VERSION = '0.1.2'
4
+ VERSION = '0.2.0'
5
5
  end
data/lib/git_compound.rb CHANGED
@@ -4,7 +4,6 @@ require 'git_compound/version'
4
4
  # Git Compound module
5
5
  #
6
6
  module GitCompound
7
- autoload :Builder, 'git_compound/builder'
8
7
  autoload :Command, 'git_compound/command'
9
8
  autoload :Component, 'git_compound/component'
10
9
  autoload :Lock, 'git_compound/lock'
@@ -42,6 +41,56 @@ module GitCompound
42
41
  #
43
42
  module Command
44
43
  autoload :Options, 'git_compound/command/options'
44
+
45
+ # Command Arguments module
46
+ #
47
+ module Arguments
48
+ autoload :Parser, 'git_compound/command/arguments/parser'
49
+
50
+ # Argument Type module
51
+ #
52
+ module Type
53
+ autoload :Type, 'git_compound/command/arguments/type/type'
54
+
55
+ # Parameter module
56
+ #
57
+ module Parameter
58
+ autoload :Parameter, 'git_compound/command/arguments/type/parameter/parameter'
59
+ autoload :Boolean, 'git_compound/command/arguments/type/parameter/boolean'
60
+ autoload :String, 'git_compound/command/arguments/type/parameter/string'
61
+ end
62
+
63
+ # Argument module
64
+ #
65
+ module Argument
66
+ autoload :Argument, 'git_compound/command/arguments/type/argument/argument'
67
+ autoload :String, 'git_compound/command/arguments/type/argument/string'
68
+ end
69
+ end
70
+ end
71
+
72
+ # Command Procedure
73
+ #
74
+ module Procedure
75
+ autoload :Procedure, 'git_compound/command/procedure/procedure'
76
+ autoload :Build, 'git_compound/command/procedure/build'
77
+ autoload :BuildLock, 'git_compound/command/procedure/build_lock'
78
+ autoload :BuildManifest, 'git_compound/command/procedure/build_manifest'
79
+ autoload :Check, 'git_compound/command/procedure/check'
80
+ autoload :Help, 'git_compound/command/procedure/help'
81
+ autoload :Show, 'git_compound/command/procedure/show'
82
+ autoload :Tasks, 'git_compound/command/procedure/tasks'
83
+ autoload :Update, 'git_compound/command/procedure/update'
84
+
85
+ # Procedure Element
86
+ #
87
+ module Element
88
+ autoload :Lock, 'git_compound/command/procedure/element/lock'
89
+ autoload :Manifest, 'git_compound/command/procedure/element/manifest'
90
+ autoload :Option, 'git_compound/command/procedure/element/option'
91
+ autoload :Subprocedure, 'git_compound/command/procedure/element/subprocedure'
92
+ end
93
+ end
45
94
  end
46
95
 
47
96
  # GitCompound Logger
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git_compound
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Grzegorz Bizon
8
+ - Tomasz Maczukin
8
9
  autorequire:
9
10
  bindir: exe
10
11
  cert_chain: []
11
- date: 2015-08-04 00:00:00.000000000 Z
12
+ date: 2015-08-21 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: bundler
@@ -44,14 +45,14 @@ dependencies:
44
45
  requirements:
45
46
  - - "~>"
46
47
  - !ruby/object:Gem::Version
47
- version: 0.31.0
48
+ version: '0.33'
48
49
  type: :development
49
50
  prerelease: false
50
51
  version_requirements: !ruby/object:Gem::Requirement
51
52
  requirements:
52
53
  - - "~>"
53
54
  - !ruby/object:Gem::Version
54
- version: 0.31.0
55
+ version: '0.33'
55
56
  - !ruby/object:Gem::Dependency
56
57
  name: rspec
57
58
  requirement: !ruby/object:Gem::Requirement
@@ -97,6 +98,7 @@ dependencies:
97
98
  description:
98
99
  email:
99
100
  - grzegorz.bizon@ntsn.pl
101
+ - tomasz@maczukin.pl
100
102
  executables:
101
103
  - gitcompound
102
104
  extensions: []
@@ -115,9 +117,28 @@ files:
115
117
  - exe/gitcompound
116
118
  - git_compound.gemspec
117
119
  - lib/git_compound.rb
118
- - lib/git_compound/builder.rb
119
120
  - lib/git_compound/command.rb
121
+ - lib/git_compound/command/arguments/parser.rb
122
+ - lib/git_compound/command/arguments/type/argument/argument.rb
123
+ - lib/git_compound/command/arguments/type/argument/string.rb
124
+ - lib/git_compound/command/arguments/type/parameter/boolean.rb
125
+ - lib/git_compound/command/arguments/type/parameter/parameter.rb
126
+ - lib/git_compound/command/arguments/type/parameter/string.rb
127
+ - lib/git_compound/command/arguments/type/type.rb
120
128
  - lib/git_compound/command/options.rb
129
+ - lib/git_compound/command/procedure/build.rb
130
+ - lib/git_compound/command/procedure/build_lock.rb
131
+ - lib/git_compound/command/procedure/build_manifest.rb
132
+ - lib/git_compound/command/procedure/check.rb
133
+ - lib/git_compound/command/procedure/element/lock.rb
134
+ - lib/git_compound/command/procedure/element/manifest.rb
135
+ - lib/git_compound/command/procedure/element/option.rb
136
+ - lib/git_compound/command/procedure/element/subprocedure.rb
137
+ - lib/git_compound/command/procedure/help.rb
138
+ - lib/git_compound/command/procedure/procedure.rb
139
+ - lib/git_compound/command/procedure/show.rb
140
+ - lib/git_compound/command/procedure/tasks.rb
141
+ - lib/git_compound/command/procedure/update.rb
121
142
  - lib/git_compound/component.rb
122
143
  - lib/git_compound/component/destination.rb
123
144
  - lib/git_compound/component/source.rb
@@ -192,6 +213,6 @@ rubyforge_project:
192
213
  rubygems_version: 2.4.5
193
214
  signing_key:
194
215
  specification_version: 4
195
- summary: Compose you project using git repositories and ruby tasks
216
+ summary: Compose you project using Git repositories and ruby tasks
196
217
  test_files: []
197
218
  has_rdoc:
@@ -1,95 +0,0 @@
1
- module GitCompound
2
- # Builder class, responsible for building project
3
- # from manifest or lockfile
4
- #
5
- class Builder
6
- def initialize(manifest, lock, opts)
7
- @manifest = manifest
8
- @lock = lock
9
- @opts = opts
10
- end
11
-
12
- def manifest_build
13
- Logger.info 'Building components ...'
14
- @manifest.process(Worker::ComponentBuilder.new(@lock))
15
- self
16
- end
17
-
18
- def manifest_update
19
- Logger.info 'Updating components ...'
20
- @lock_new = Lock.new.clean
21
- @manifest.process(Worker::ComponentDispatcher.new(@lock_new))
22
- self
23
- end
24
-
25
- def manifest_lock
26
- lock = @lock_new ? @lock_new : @lock
27
- lock.lock_manifest(@manifest)
28
- lock.write
29
- self
30
- end
31
-
32
- def dependencies_check
33
- Logger.info 'Checking dependencies ...'
34
-
35
- @manifest.process(
36
- Worker::CircularDependencyChecker.new,
37
- Worker::NameConstraintChecker.new,
38
- Worker::ConflictingDependencyChecker.new)
39
- self
40
- end
41
-
42
- def components_show
43
- Logger.info 'Processing components list ...'
44
- @manifest.process(
45
- Worker::CircularDependencyChecker.new,
46
- Worker::PrettyPrint.new)
47
- self
48
- end
49
-
50
- def tasks_execute
51
- Logger.info 'Running tasks ...'
52
-
53
- if @opts.include?(:allow_nested_subtasks)
54
- @manifest.process(Worker::TaskRunner.new)
55
- else
56
- @manifest.tasks.each_value do |task|
57
- Worker::TaskRunner.new.visit_task(task)
58
- end
59
- end
60
- self
61
- end
62
-
63
- def locked_manifest_verify
64
- return self if @manifest.md5sum == @lock.manifest
65
- raise GitCompoundError,
66
- 'Manifest md5sum has changed ! Use `update` command.'
67
- end
68
-
69
- def locked_components_build
70
- Logger.info 'Building components from lockfile ...'
71
- @lock.process(Worker::ComponentDispatcher.new(@lock))
72
- self
73
- end
74
-
75
- def locked_components_guard
76
- @lock.process(Worker::LocalChangesGuard.new(@lock))
77
- self
78
- end
79
-
80
- def locked_dormant_components_remove
81
- raise GitCompoundError, 'No new lockfile !' unless @lock_new
82
-
83
- dormant_components = @lock.components.reject do |component|
84
- @lock_new.find(component) ? true : false
85
- end
86
-
87
- dormant_components.each do |component|
88
- Logger.warn "Removing dormant component `#{component.name}` " \
89
- "from `#{component.path}` !"
90
-
91
- component.remove!
92
- end
93
- end
94
- end
95
- end