kamaze-project 1.0.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 (106) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +18 -0
  3. data/bin/plop +5 -0
  4. data/lib/kamaze-project.rb +39 -0
  5. data/lib/kamaze/project.rb +155 -0
  6. data/lib/kamaze/project/boot/core_ext.rb +16 -0
  7. data/lib/kamaze/project/boot/listen.rb +38 -0
  8. data/lib/kamaze/project/concern.rb +13 -0
  9. data/lib/kamaze/project/concern/cli.rb +53 -0
  10. data/lib/kamaze/project/concern/cli/with_exit_on_failure.rb +36 -0
  11. data/lib/kamaze/project/concern/env.rb +63 -0
  12. data/lib/kamaze/project/concern/helper.rb +20 -0
  13. data/lib/kamaze/project/concern/mode.rb +19 -0
  14. data/lib/kamaze/project/concern/observable.rb +132 -0
  15. data/lib/kamaze/project/concern/sh.rb +91 -0
  16. data/lib/kamaze/project/concern/tasks.rb +55 -0
  17. data/lib/kamaze/project/concern/tools.rb +27 -0
  18. data/lib/kamaze/project/config.rb +58 -0
  19. data/lib/kamaze/project/core_ext/object.rb +27 -0
  20. data/lib/kamaze/project/core_ext/pp.rb +28 -0
  21. data/lib/kamaze/project/debug.rb +136 -0
  22. data/lib/kamaze/project/dsl.rb +16 -0
  23. data/lib/kamaze/project/dsl/definition.rb +43 -0
  24. data/lib/kamaze/project/dsl/setup.rb +11 -0
  25. data/lib/kamaze/project/helper.rb +63 -0
  26. data/lib/kamaze/project/helper/inflector.rb +44 -0
  27. data/lib/kamaze/project/helper/project.rb +34 -0
  28. data/lib/kamaze/project/helper/project/config.rb +25 -0
  29. data/lib/kamaze/project/observable.rb +20 -0
  30. data/lib/kamaze/project/observer.rb +37 -0
  31. data/lib/kamaze/project/resources/Vagrantfile +128 -0
  32. data/lib/kamaze/project/resources/config/tools.yml +15 -0
  33. data/lib/kamaze/project/struct.rb +34 -0
  34. data/lib/kamaze/project/tasks/cs.rb +23 -0
  35. data/lib/kamaze/project/tasks/cs/control.rb +17 -0
  36. data/lib/kamaze/project/tasks/cs/correct.rb +17 -0
  37. data/lib/kamaze/project/tasks/cs/pre_commit.rb +66 -0
  38. data/lib/kamaze/project/tasks/doc.rb +21 -0
  39. data/lib/kamaze/project/tasks/doc/watch.rb +41 -0
  40. data/lib/kamaze/project/tasks/gem.rb +14 -0
  41. data/lib/kamaze/project/tasks/gem/build.rb +34 -0
  42. data/lib/kamaze/project/tasks/gem/compile.rb +30 -0
  43. data/lib/kamaze/project/tasks/gem/gemspec.rb +20 -0
  44. data/lib/kamaze/project/tasks/gem/install.rb +32 -0
  45. data/lib/kamaze/project/tasks/gem/push.rb +27 -0
  46. data/lib/kamaze/project/tasks/misc/gitignore.rb +29 -0
  47. data/lib/kamaze/project/tasks/shell.rb +17 -0
  48. data/lib/kamaze/project/tasks/sources.rb +6 -0
  49. data/lib/kamaze/project/tasks/sources/license.rb +35 -0
  50. data/lib/kamaze/project/tasks/test.rb +16 -0
  51. data/lib/kamaze/project/tasks/vagrant.rb +71 -0
  52. data/lib/kamaze/project/tasks/version/edit.rb +16 -0
  53. data/lib/kamaze/project/tools.rb +18 -0
  54. data/lib/kamaze/project/tools/base_tool.rb +55 -0
  55. data/lib/kamaze/project/tools/console.rb +48 -0
  56. data/lib/kamaze/project/tools/console/output.rb +120 -0
  57. data/lib/kamaze/project/tools/console/output/buffer.rb +48 -0
  58. data/lib/kamaze/project/tools/gemspec.rb +33 -0
  59. data/lib/kamaze/project/tools/gemspec/builder.rb +99 -0
  60. data/lib/kamaze/project/tools/gemspec/concern.rb +13 -0
  61. data/lib/kamaze/project/tools/gemspec/concern/reading.rb +49 -0
  62. data/lib/kamaze/project/tools/gemspec/packager.rb +67 -0
  63. data/lib/kamaze/project/tools/gemspec/packer.rb +89 -0
  64. data/lib/kamaze/project/tools/gemspec/packer/command.rb +143 -0
  65. data/lib/kamaze/project/tools/gemspec/reader.rb +70 -0
  66. data/lib/kamaze/project/tools/gemspec/reader/decorator.rb +78 -0
  67. data/lib/kamaze/project/tools/gemspec/writer.rb +127 -0
  68. data/lib/kamaze/project/tools/gemspec/writer/dep_gen.rb +61 -0
  69. data/lib/kamaze/project/tools/gemspec/writer/dependency.rb +104 -0
  70. data/lib/kamaze/project/tools/git.rb +95 -0
  71. data/lib/kamaze/project/tools/git/hooks.rb +66 -0
  72. data/lib/kamaze/project/tools/git/hooks/base_hook.rb +33 -0
  73. data/lib/kamaze/project/tools/git/hooks/pre_commit.rb +81 -0
  74. data/lib/kamaze/project/tools/git/status.rb +101 -0
  75. data/lib/kamaze/project/tools/git/status/decorator.rb +39 -0
  76. data/lib/kamaze/project/tools/git/status/file.rb +180 -0
  77. data/lib/kamaze/project/tools/git/status/files_array.rb +39 -0
  78. data/lib/kamaze/project/tools/git/status/index.rb +77 -0
  79. data/lib/kamaze/project/tools/git/status/worktree.rb +19 -0
  80. data/lib/kamaze/project/tools/git/util.rb +35 -0
  81. data/lib/kamaze/project/tools/licenser.rb +197 -0
  82. data/lib/kamaze/project/tools/packager.rb +86 -0
  83. data/lib/kamaze/project/tools/packager/filesystem.rb +178 -0
  84. data/lib/kamaze/project/tools/packager/filesystem/operator.rb +83 -0
  85. data/lib/kamaze/project/tools/packager/filesystem/operator/utils.rb +77 -0
  86. data/lib/kamaze/project/tools/process_locker.rb +106 -0
  87. data/lib/kamaze/project/tools/rspec.rb +115 -0
  88. data/lib/kamaze/project/tools/rubocop.rb +128 -0
  89. data/lib/kamaze/project/tools/rubocop/arguments.rb +19 -0
  90. data/lib/kamaze/project/tools/rubocop/config.rb +43 -0
  91. data/lib/kamaze/project/tools/shell.rb +85 -0
  92. data/lib/kamaze/project/tools/vagrant.rb +182 -0
  93. data/lib/kamaze/project/tools/vagrant/composer.rb +88 -0
  94. data/lib/kamaze/project/tools/vagrant/composer/file.rb +79 -0
  95. data/lib/kamaze/project/tools/vagrant/remote.rb +79 -0
  96. data/lib/kamaze/project/tools/vagrant/shell.rb +102 -0
  97. data/lib/kamaze/project/tools/vagrant/writer.rb +81 -0
  98. data/lib/kamaze/project/tools/yardoc.rb +75 -0
  99. data/lib/kamaze/project/tools/yardoc/file.rb +55 -0
  100. data/lib/kamaze/project/tools/yardoc/watchable.rb +70 -0
  101. data/lib/kamaze/project/tools/yardoc/watcher.rb +106 -0
  102. data/lib/kamaze/project/tools_provider.rb +161 -0
  103. data/lib/kamaze/project/tools_provider/resolver.rb +42 -0
  104. data/lib/kamaze/project/version.rb +104 -0
  105. data/lib/kamaze/project/version.yml +17 -0
  106. metadata +321 -0
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (C) 2017-2018 Dimitri Arrigoni <dimitri@arrigoni.me>
4
+ # License GPLv3+: GNU GPL version 3 or later
5
+ # <http://www.gnu.org/licenses/gpl.html>.
6
+ # This is free software: you are free to change and redistribute it.
7
+ # There is NO WARRANTY, to the extent permitted by law.
8
+
9
+ require 'fileutils'
10
+ require 'rubygems'
11
+ require 'rubygems/gem_runner'
12
+
13
+ require_relative 'packager'
14
+
15
+ # Package a ``gem`` from its own ``gemspec`` file
16
+ #
17
+ # The build command allows you to create a ``gem`` from a ruby ``gemspec``.
18
+ #
19
+ # The best way to build a gem is to use a Rakefile and the Gem::PackageTask
20
+ # which ships with RubyGems. But, you can also use this class ;).
21
+ #
22
+ # Sample of use:
23
+ #
24
+ # ```ruby
25
+ # builder = Kamaze.project.tools.fetch(:gemspec_builder)
26
+ # builder.build if builder.ready?
27
+ # ```
28
+ class Kamaze::Project::Tools::Gemspec::Builder
29
+ # Build ``.gem`` file
30
+ #
31
+ # @return [self]
32
+ def build
33
+ prepare
34
+
35
+ buildable_dir = self.buildable.dirname.realpath
36
+
37
+ # dive into ``src`` file
38
+ Dir.chdir(gemspec_srcfile.dirname) do
39
+ Gem::GemRunner.new.run(build_args).yield_self do |file|
40
+ FileUtils.mv(file, buildable_dir)
41
+
42
+ buildable_dir.join(file)
43
+ end
44
+ end
45
+
46
+ self
47
+ end
48
+
49
+ # Get buildable (relative path)
50
+ #
51
+ # @return [Pathname]
52
+ def buildable
53
+ full_name = gemspec_reader.read(Hash).fetch(:full_name)
54
+ file_path = fs.package_dirs
55
+ .fetch(:gem)
56
+ .join("#{full_name}.gem")
57
+ .to_s
58
+ .gsub(%r{^\./}, '')
59
+
60
+ ::Pathname.new(file_path)
61
+ end
62
+
63
+ def ready?
64
+ gemspec_reader.read(Hash)[:full_name].nil? ? false : super
65
+ end
66
+
67
+ alias buildable? ready?
68
+
69
+ # Get path do gemspec present in ``src`` dir
70
+ #
71
+ # @return [Pathname]
72
+ def gemspec_srcfile
73
+ (package_dirs.fetch(:src)
74
+ .realpath
75
+ .join(buildable.basename('.*')).to_s
76
+ .gsub(/-([0-9 \.])+$/, '') + '.gemspec').yield_self do |s|
77
+ Pathname.new(s)
78
+ end
79
+ end
80
+
81
+ protected
82
+
83
+ def setup
84
+ super
85
+
86
+ self.package_labels = [:src, :gem]
87
+ self.purgeables = [:gem]
88
+ self.package_name = "ruby/gem-#{Gem::VERSION}"
89
+ end
90
+
91
+ # Get args used by ``gem`` command
92
+ #
93
+ # @return [Array<String>]
94
+ def build_args
95
+ Dir.chdir(pwd) do
96
+ [:build, gemspec_srcfile, '--norc'].map(&:to_s)
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (C) 2017-2018 Dimitri Arrigoni <dimitri@arrigoni.me>
4
+ # License GPLv3+: GNU GPL version 3 or later
5
+ # <http://www.gnu.org/licenses/gpl.html>.
6
+ # This is free software: you are free to change and redistribute it.
7
+ # There is NO WARRANTY, to the extent permitted by law.
8
+
9
+ require_relative '../gemspec'
10
+
11
+ # Concern for ``Gemspec``
12
+ module Kamaze::Project::Tools::Gemspec::Concern
13
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (C) 2017-2018 Dimitri Arrigoni <dimitri@arrigoni.me>
4
+ # License GPLv3+: GNU GPL version 3 or later
5
+ # <http://www.gnu.org/licenses/gpl.html>.
6
+ # This is free software: you are free to change and redistribute it.
7
+ # There is NO WARRANTY, to the extent permitted by law.
8
+
9
+ require_relative '../reader'
10
+ require_relative '../concern'
11
+
12
+ # Provides gemspec reader
13
+ #
14
+ # Base objects using a ``gemspec`` to obtain specification
15
+ #
16
+ # @see Kamaze::Project::Tools::Gemspec::Reader
17
+ module Kamaze::Project::Tools::Gemspec::Concern::Reading
18
+ class << self
19
+ def included(base)
20
+ return if base.respond_to?(:'gemspec_reader=')
21
+
22
+ base.class_eval <<-"ACCESSORS", __FILE__, __LINE__ + 1
23
+ attr_writer :gemspec_reader
24
+ ACCESSORS
25
+ end
26
+ end
27
+
28
+ protected
29
+
30
+ # @return [Kamaze::Project::Tools::Gemspec::Reader]
31
+ def gemspec_reader
32
+ @gemspec_reader ||= Kamaze.project.fetch(:gemspec_reader)
33
+
34
+ @gemspec_reader
35
+ end
36
+
37
+ # Get specification
38
+ #
39
+ # @return [Gem::Specification]
40
+ def specification
41
+ specification = gemspec_reader.read
42
+
43
+ specification.define_singleton_method(:'ready?') do
44
+ gemspec_reader.read(Hash).include?(:full_name)
45
+ end
46
+
47
+ specification
48
+ end
49
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (C) 2017-2018 Dimitri Arrigoni <dimitri@arrigoni.me>
4
+ # License GPLv3+: GNU GPL version 3 or later
5
+ # <http://www.gnu.org/licenses/gpl.html>.
6
+ # This is free software: you are free to change and redistribute it.
7
+ # There is NO WARRANTY, to the extent permitted by law.
8
+
9
+ require_relative '../gemspec'
10
+ require_relative 'concern/reading'
11
+
12
+ # Provide a specialized packager, for ``gemspec`` based projects
13
+ #
14
+ # A ``gemspec`` reader class is used,
15
+ # it can be retrieved through ``project`` tools.
16
+ # This dynamic behaviour is the default one, but a specific reader or
17
+ # a ``project`` can be defined during initialization.
18
+ #
19
+ # Gem ``specification`` (``Gem::Specification``) is retrieved through
20
+ # the gemspec reader. The gemspec reader
21
+ # can be dynamically retrieved through the project.
22
+ #
23
+ # @abstract
24
+ class Kamaze::Project::Tools::Gemspec::Packager
25
+ include Kamaze::Project::Tools::Gemspec::Concern::Reading
26
+
27
+ def mutable_attributes
28
+ [:gemspec_reader]
29
+ end
30
+
31
+ # Denote ready
32
+ #
33
+ # Test to detect if specification seems to be complete,
34
+ # incomplete specification denotes a missing gemspec file
35
+ #
36
+ # @return [Boolean]
37
+ def ready?
38
+ gemspec_reader.read(Hash).include?(:full_name)
39
+ end
40
+
41
+ protected
42
+
43
+ # Get package(d) files
44
+ #
45
+ # @return [Array<String>]
46
+ def package_files
47
+ (Dir.glob([
48
+ '*.gemspec',
49
+ 'Gemfile', 'Gemfile.lock',
50
+ 'gems.rb', 'gems.locked',
51
+ ]) + (gemspec_reader.read&.files).to_a).sort
52
+ end
53
+
54
+ def setup
55
+ @gemspec_reader ||= Kamaze.project.tools.fetch(:gemspec_reader)
56
+
57
+ self.verbose = false
58
+ self.source_files = package_files if self.source_files.to_a.empty?
59
+ end
60
+
61
+ # Get specification
62
+ #
63
+ # @return [Gem::Specification]
64
+ def specification
65
+ gemspec_reader.read
66
+ end
67
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (C) 2017-2018 Dimitri Arrigoni <dimitri@arrigoni.me>
4
+ # License GPLv3+: GNU GPL version 3 or later
5
+ # <http://www.gnu.org/licenses/gpl.html>.
6
+ # This is free software: you are free to change and redistribute it.
7
+ # There is NO WARRANTY, to the extent permitted by law.
8
+
9
+ require 'pathname'
10
+ require 'rubygems'
11
+ require_relative 'reader'
12
+ require_relative 'packer/command'
13
+
14
+ # Provides a ready to use interface based on rubyc (aka ruby-packer)
15
+ #
16
+ # @see https://github.com/pmq20/ruby-packer
17
+ class Kamaze::Project::Tools::Gemspec::Packer
18
+ # Binary (executable) used to pack the project
19
+ #
20
+ # @see https://github.com/pmq20/ruby-packer
21
+ attr_accessor :compiler
22
+
23
+ # Get buildable (relative path)
24
+ #
25
+ # @return [Array<Pathname>]
26
+ def packables
27
+ specification.executables.map do |executable|
28
+ package_dirs.fetch(:bin)
29
+ .join(executable)
30
+ .to_s.gsub(%r{^./}, '')
31
+ .yield_self { |path| ::Pathname.new(path) }
32
+ end
33
+ end
34
+
35
+ # Get host config, retrieved from ``RbConfig::CONFIG``
36
+ #
37
+ # @return [Hash]
38
+ def config
39
+ (RbConfig::CONFIG.map { |k, v| [k.to_sym, v] }).to_h
40
+ end
41
+
42
+ # Pack given packable
43
+ #
44
+ # @param [String] packable
45
+ # @return [Pathname]
46
+ def pack(packable)
47
+ bin_dir = ::Pathname.new(specification.bin_dir)
48
+
49
+ prepare
50
+ command_for(packable).execute
51
+
52
+ bin_dir.join(packable)
53
+ end
54
+
55
+ def mutable_attributes
56
+ super + [:compiler]
57
+ end
58
+
59
+ protected
60
+
61
+ def setup
62
+ super
63
+
64
+ self.package_labels = [:src, :tmp, :bin]
65
+ self.purgeables = [:bin]
66
+ self.package_name = '%<os>s/%<arch>s' % {
67
+ os: config.fetch(:host_os),
68
+ arch: config.fetch(:host_cpu)
69
+ }
70
+ end
71
+
72
+ # Get command for (packing) a given packable
73
+ #
74
+ # @param [String] packable
75
+ # @return [Command]
76
+ def command_for(packable)
77
+ bin_dir = ::Pathname.new(specification.bin_dir)
78
+
79
+ Dir.chdir(pwd) do
80
+ Command.new do |command|
81
+ command.executable = compiler
82
+ command.src_dir = package_dirs.fetch(:src)
83
+ command.tmp_dir = package_dirs.fetch(:tmp)
84
+ command.bin_dir = bin_dir
85
+ command.packable = packable
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,143 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (C) 2017-2018 Dimitri Arrigoni <dimitri@arrigoni.me>
4
+ # License GPLv3+: GNU GPL version 3 or later
5
+ # <http://www.gnu.org/licenses/gpl.html>.
6
+ # This is free software: you are free to change and redistribute it.
7
+ # There is NO WARRANTY, to the extent permitted by law.
8
+
9
+ require 'pathname'
10
+ require 'cliver'
11
+
12
+ require_relative '../packer'
13
+ require_relative '../../../concern/sh'
14
+ require_relative '../../../concern/cli/with_exit_on_failure'
15
+
16
+ # Build/pack a buildable
17
+ #
18
+ # Command is able to execute itself.
19
+ # Command depends on ``FileUtils::sh`` provided by ``rake``.
20
+ #
21
+ # During execution, command ``chdir`` to ``src_dir``.
22
+ class Kamaze::Project::Tools::Gemspec::Packer::Command
23
+ include Kamaze::Project::Concern::Cli::WithExitOnFailure
24
+ include Kamaze::Project::Concern::Sh
25
+
26
+ # Executable used by command
27
+ #
28
+ # @type [String|Symbol]
29
+ attr_writer :executable
30
+
31
+ # Filepath to the product issued by command
32
+ attr_accessor :packable
33
+
34
+ # The directory for temporary files
35
+ attr_accessor :tmp_dir
36
+
37
+ # The directory where "compiled" executable stands
38
+ #
39
+ # @type [String]
40
+ attr_writer :bin_dir
41
+
42
+ # The path to source files
43
+ attr_accessor :src_dir
44
+
45
+ # @return [Pathname]
46
+ attr_reader :pwd
47
+
48
+ class InitializationError < RuntimeError
49
+ end
50
+
51
+ # @raise InitializationError
52
+ def initialize
53
+ yield self
54
+
55
+ @executable ||= :rubyc
56
+ @pwd = ::Pathname.new(Dir.pwd)
57
+
58
+ [:executable, :packable, :tmp_dir, :bin_dir].each do |m|
59
+ self.singleton_class.class_eval { protected "#{m}=" }
60
+
61
+ next unless self.__send__(m).nil?
62
+
63
+ raise InitializationError, "#{m} must be set, got nil"
64
+ end
65
+ end
66
+
67
+ # Executable used by command
68
+ #
69
+ # @return [Pathname]
70
+ def executable
71
+ ::Pathname.new(Cliver.detect!(@executable)).freeze
72
+ end
73
+
74
+ # Get path to "compiled" input file
75
+ #
76
+ # SHOULD like to ``bin`` as seen in gemspec ``bindir``
77
+ #
78
+ # @return [Pathname]
79
+ def bin_dir
80
+ ::Pathname.new(@bin_dir)
81
+ end
82
+
83
+ # @return [Array<String>]
84
+ def to_a
85
+ packable = ::Pathname.new(self.packable)
86
+
87
+ [executable,
88
+ bin_dir.join(packable.basename),
89
+ '-r', '.',
90
+ '-d', pwd.join(tmp_dir),
91
+ '-o', pwd.join(packable)].map(&:to_s)
92
+ end
93
+
94
+ def execute
95
+ env = preserved_env
96
+
97
+ Dir.chdir(pwd.join(src_dir)) do
98
+ with_exit_on_failure do
99
+ Bundler.with_clean_env do
100
+ sh(*[env].concat(self.to_a))
101
+
102
+ self.retcode = self.shell_runner_last_status.exitstatus
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ protected
109
+
110
+ # Process attributes
111
+ #
112
+ # @raise InitializationError
113
+ def process_attrs
114
+ [:executable, :packable, :tmp_dir, :bin_dir].each do |m|
115
+ self.singleton_class.class_eval { protected "#{m}=" }
116
+
117
+ if self.__send__(m).nil?
118
+ raise InitializationError, "#{m} must be set, got nil"
119
+ end
120
+ end
121
+
122
+ self
123
+ end
124
+
125
+ # Get preserved env (from given env)
126
+ #
127
+ # @param [ENV|Hash] from
128
+ # @return [Hash]
129
+ #
130
+ # @todo refactor
131
+ def preserved_env(from = ENV)
132
+ env = {}
133
+ from = from.to_h
134
+
135
+ ['CPPFLAGS'].each do |key|
136
+ next unless from.key?(key)
137
+
138
+ env[key] = from.fetch(key)
139
+ end
140
+
141
+ env
142
+ end
143
+ end