kamaze-project 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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