rdm 0.2.0 → 0.3.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 (95) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/Gemfile.lock +80 -0
  4. data/bin/rdm +78 -10
  5. data/example/.rdm/helpers/render_helper.rb +12 -0
  6. data/example/.rdm/templates/package/.gitignore +1 -0
  7. data/example/.rdm/templates/package/.rspec +2 -0
  8. data/example/.rdm/templates/package/<%=package_subdir_name%>/<%=package_name%>.rb +3 -0
  9. data/example/.rdm/templates/package/<%=package_subdir_name%>/<%=package_name%>/.gitkeep +0 -0
  10. data/{lib/rdm/templates/package/package.rb.erb → example/.rdm/templates/package/Package.rb} +0 -0
  11. data/{lib/rdm/templates/package/bin/console_irb → example/.rdm/templates/package/bin/console} +0 -0
  12. data/example/.rdm/templates/package/spec/spec_helper.rb +10 -0
  13. data/example/.rdm/templates/repository/dao/<%=name%>_dao.rb +4 -0
  14. data/example/.rdm/templates/repository/mapper/<%=name%>_mapper.rb +2 -0
  15. data/example/.rdm/templates/repository/repository/<%=name%>_repository.rb +2 -0
  16. data/example/.rdm/templates/repository/views/users.html.erb +2 -0
  17. data/example/Gemfile.lock +50 -0
  18. data/example/Rdm.packages +1 -0
  19. data/example/tests/diff_run +0 -0
  20. data/example/tests/run +0 -0
  21. data/lib/rdm.rb +40 -8
  22. data/lib/rdm/cli/compile_package.rb +56 -0
  23. data/lib/rdm/cli/dependencies_controller.rb +30 -0
  24. data/lib/rdm/cli/diff_package.rb +21 -0
  25. data/lib/rdm/cli/gen_package.rb +24 -32
  26. data/lib/rdm/cli/init.rb +20 -27
  27. data/lib/rdm/cli/template_generator.rb +38 -0
  28. data/lib/rdm/errors.rb +37 -0
  29. data/lib/rdm/gen/init.rb +29 -44
  30. data/lib/rdm/gen/package.rb +24 -78
  31. data/lib/rdm/git/diff_command.rb +13 -0
  32. data/lib/rdm/git/diff_manager.rb +30 -0
  33. data/lib/rdm/git/repository_locator.rb +23 -0
  34. data/lib/rdm/handlers/dependencies_handler.rb +110 -0
  35. data/lib/rdm/handlers/diff_package_handler.rb +48 -0
  36. data/lib/rdm/handlers/template_handler.rb +118 -0
  37. data/lib/rdm/helpers/path_helper.rb +15 -0
  38. data/lib/rdm/package.rb +6 -0
  39. data/lib/rdm/package_importer.rb +1 -1
  40. data/lib/rdm/packages/compiler_service.rb +78 -0
  41. data/lib/rdm/packages/locator.rb +28 -0
  42. data/lib/rdm/settings.rb +14 -1
  43. data/lib/rdm/spec_runner.rb +5 -0
  44. data/lib/rdm/spec_runner/command_generator.rb +28 -0
  45. data/lib/rdm/spec_runner/command_params.rb +3 -0
  46. data/lib/rdm/spec_runner/package_fetcher.rb +13 -0
  47. data/lib/rdm/spec_runner/runner.rb +122 -0
  48. data/lib/rdm/spec_runner/view.rb +20 -0
  49. data/lib/rdm/templates/init/.rdm/helpers/render_helper.rb +12 -0
  50. data/lib/rdm/templates/init/{Gemfile.erb → Gemfile} +0 -0
  51. data/lib/rdm/templates/init/{Rdm.packages.erb → Rdm.packages} +0 -0
  52. data/lib/rdm/templates/init/{Readme.md.erb → Readme.md} +0 -0
  53. data/lib/rdm/templates/init/tests/diff_run +29 -0
  54. data/lib/rdm/templates/init/tests/run +7 -210
  55. data/lib/rdm/templates/package/<%=package_subdir_name%>/<%=package_name%>.rb +3 -0
  56. data/lib/rdm/templates/package/<%=package_subdir_name%>/<%=package_name%>/.gitkeep +0 -0
  57. data/lib/rdm/templates/package/Package.rb +8 -0
  58. data/lib/rdm/templates/package/bin/console +16 -0
  59. data/lib/rdm/templates/template_detector.rb +32 -0
  60. data/lib/rdm/templates/template_renderer.rb +49 -0
  61. data/lib/rdm/utils/file_utils.rb +20 -0
  62. data/lib/rdm/utils/render_util.rb +24 -0
  63. data/lib/rdm/utils/string_utils.rb +16 -0
  64. data/lib/rdm/version.rb +1 -1
  65. data/rdm.gemspec +1 -1
  66. data/spec/helpers/example_project_helper.rb +217 -0
  67. data/spec/helpers/git_commands_helper.rb +13 -0
  68. data/spec/rdm/cli/compile_package_spec.rb +114 -0
  69. data/spec/rdm/cli/dependencies_controller_spec.rb +50 -0
  70. data/spec/rdm/cli/diff_package_spec.rb +5 -0
  71. data/spec/rdm/cli/gen_package_spec.rb +60 -86
  72. data/spec/rdm/cli/init_spec.rb +53 -70
  73. data/spec/rdm/gen/init_spec.rb +21 -38
  74. data/spec/rdm/gen/package_spec.rb +70 -51
  75. data/spec/rdm/git/diff_manager_spec.rb +81 -0
  76. data/spec/rdm/git/repository_locator_spec.rb +31 -0
  77. data/spec/rdm/handlers/dependencies_handler_spec.rb +84 -0
  78. data/spec/rdm/handlers/diff_package_handler_spec.rb +78 -0
  79. data/spec/rdm/handlers/template_handler_spec.rb +94 -0
  80. data/spec/rdm/helpers/path_helper_spec.rb +52 -0
  81. data/spec/rdm/package/compiler_service_spec.rb +124 -0
  82. data/spec/rdm/package/locator_spec.rb +31 -0
  83. data/spec/rdm/rdm_spec.rb +2 -2
  84. data/spec/rdm/spec_runner/runner_spec.rb +12 -0
  85. data/spec/rdm/templates/template_detector_spec.rb +39 -0
  86. data/spec/rdm/templates/template_renderer_spec.rb +42 -0
  87. data/spec/spec_helper.rb +31 -25
  88. metadata +84 -17
  89. data/lib/rdm/gen/concerns/template_handling.rb +0 -81
  90. data/lib/rdm/support/colorize.rb +0 -106
  91. data/lib/rdm/support/render.rb +0 -17
  92. data/lib/rdm/support/template.rb +0 -30
  93. data/lib/rdm/templates/package/main_module_file.rb.erb +0 -3
  94. data/spec/rdm/support/colorize_spec.rb +0 -24
  95. data/spec/rdm/support/template_spec.rb +0 -20
@@ -0,0 +1,13 @@
1
+ require 'open3'
2
+
3
+ class Rdm::Git::DiffCommand
4
+ class << self
5
+ def get_only_diff_filenames(revision:, path:)
6
+ command = `cd #{path} && git diff --name-only #{revision}`
7
+
8
+ raise Rdm::Errors::GitCommandError, command unless $?.success?
9
+
10
+ command.split("\n")
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,30 @@
1
+ require 'fileutils'
2
+
3
+ module Rdm
4
+ module Git
5
+ class DiffManager
6
+ GIT_ERROR_MESSAGE = "fatal: Not a git repository (or any of the parent directories): .git"
7
+ DEFAULT_REVISION = 'HEAD'
8
+
9
+ class << self
10
+ def run(path:, revision: nil)
11
+ abs_path = Rdm::Git::RepositoryLocator.locate(path)
12
+
13
+ check_repository_initialized!(abs_path)
14
+
15
+ return Rdm::Git::DiffCommand
16
+ .get_only_diff_filenames(revision: revision, path: path)
17
+ .map { |filename| File.expand_path(File.join(abs_path, filename)) }
18
+ end
19
+
20
+ private
21
+
22
+ def check_repository_initialized!(folder)
23
+ unless %x( cd #{folder} && git status 2>&1 >/dev/null ).empty?
24
+ raise Rdm::Errors::GitRepositoryNotInitialized
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ class Rdm::Git::RepositoryLocator
2
+ GIT_FOLDER = '.git'
3
+
4
+ class << self
5
+ def locate(path)
6
+ raise Rdm::Errors::GitRepositoryNotInitialized, path if root_reached?(path)
7
+
8
+ return path if git_present?(path)
9
+
10
+ locate(File.dirname(path))
11
+ end
12
+
13
+ def root_reached?(path)
14
+ File.expand_path(path) == '/'
15
+ end
16
+
17
+ def git_present?(path)
18
+ expected_source_file = File.join(path, GIT_FOLDER)
19
+
20
+ File.exist?(expected_source_file)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,110 @@
1
+ module Rdm
2
+ module Handlers
3
+ class DependenciesHandler
4
+ ALREADY_MENTIONED_DEPS = '...'
5
+
6
+ class << self
7
+ def show_names(package_name:, project_path:)
8
+ new(package_name, project_path).show_names
9
+ end
10
+
11
+ def show_packages(package_name:, project_path:)
12
+ new(package_name, project_path).show_packages
13
+ end
14
+
15
+ def draw(package_name:, project_path:)
16
+ new(package_name, project_path).draw
17
+ end
18
+ end
19
+
20
+ def initialize(package_name, project_path)
21
+ @package_name = package_name
22
+ @project_path = project_path
23
+ end
24
+
25
+ def show_names
26
+ if @package_name.nil? || @package_name.empty?
27
+ raise Rdm::Errors::InvalidParams, "Package name should be specified"
28
+ end
29
+
30
+ if @project_path.nil? || @project_path.empty?
31
+ raise Rdm::Errors::InvalidParams, "Project directory should be specified"
32
+ end
33
+
34
+ recursive_find_dependencies([@package_name])
35
+ end
36
+
37
+ def show_packages
38
+ names = show_names
39
+
40
+ source.packages.values.select do |p|
41
+ names.include?(p.name)
42
+ end
43
+ end
44
+
45
+ def draw(pkg_name = @package_name, uniq_packages = [], self_predicate = '', child_predicate = '')
46
+ raise Rdm::Errors::InvalidParams, "Type package name, ex: rdm gen.deps repository" if pkg_name.to_s.empty?
47
+ raise Rdm::Errors::PackageHasNoDependencies, @package_name if source.packages[@package_name].local_dependencies.empty?
48
+
49
+ node = [format(pkg_name, self_predicate)]
50
+
51
+ return node if pkg_name == ALREADY_MENTIONED_DEPS
52
+
53
+ local_dependencies = source.packages[pkg_name].local_dependencies.dup
54
+
55
+ if uniq_packages.include?(pkg_name)
56
+ local_dependencies = local_dependencies.count == 0 ? [] : [ALREADY_MENTIONED_DEPS]
57
+ else
58
+ uniq_packages.push(pkg_name)
59
+ end
60
+
61
+ local_dependencies.count.times do
62
+ dependency = local_dependencies.pop
63
+
64
+ if local_dependencies.empty?
65
+ tmp_self_predicate = child_predicate + '2'
66
+ tmp_child_predicate = child_predicate + '0'
67
+ else
68
+ tmp_self_predicate = child_predicate + '1'
69
+ tmp_child_predicate = child_predicate + '3'
70
+ end
71
+
72
+ node.push(*draw(dependency, uniq_packages, tmp_self_predicate, tmp_child_predicate))
73
+ end
74
+
75
+ node
76
+ end
77
+
78
+ private
79
+
80
+ def source
81
+ @source ||= Rdm::SourceParser.read_and_init_source(Rdm::SourceLocator.locate(@project_path))
82
+ end
83
+
84
+ def format(pkg_name, predicate)
85
+ predicate
86
+ .concat(pkg_name)
87
+ .gsub(/0/, ' ')
88
+ .gsub(/1/, '├── ')
89
+ .gsub(/2/, '└── ')
90
+ .gsub(/3/, '| ')
91
+ end
92
+
93
+ def recursive_find_dependencies(package_names)
94
+ all_packages = source.packages.values
95
+
96
+ deps_package_names = all_packages
97
+ .select {|pkg| package_names.include?(pkg.name)}
98
+ .map(&:local_dependencies)
99
+ .flatten
100
+ .uniq
101
+
102
+ extended_package_names = deps_package_names | package_names
103
+
104
+ return package_names if package_names == extended_package_names
105
+
106
+ recursive_find_dependencies(extended_package_names)
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,48 @@
1
+ module Rdm
2
+ module Handlers
3
+ class DiffPackageHandler
4
+ class << self
5
+ def handle(path:, revision: 'HEAD')
6
+ return Rdm::Handlers::DiffPackageHandler.new(path: path, revision: revision).handle
7
+ end
8
+ end
9
+
10
+ attr_reader :path, :revision, :all_packages
11
+ def initialize(path:, revision:)
12
+ @path = path
13
+ @revision = revision
14
+
15
+ source_path = Rdm::SourceLocator.locate(path)
16
+ @all_packages = Rdm::SourceParser.read_and_init_source(source_path).packages.values
17
+ end
18
+
19
+ def handle
20
+ @revision = 'HEAD' if @revision.nil? || @revision.empty?
21
+
22
+ modified_packages = Rdm::Git::DiffManager
23
+ .run(path: path, revision: revision)
24
+ .map { |file| Rdm::Packages::Locator.locate(file) rescue nil }
25
+ .map { |path_to_package| Rdm::PackageParser.parse_file(path_to_package).name rescue nil }
26
+ .reject(&:blank?)
27
+ .uniq
28
+
29
+ return get_dependencies(modified_packages) || []
30
+ end
31
+
32
+ private
33
+ def get_dependencies(base_packages)
34
+ base_packages.sort!
35
+
36
+ new_packages = all_packages
37
+ .select {|p| (p.local_dependencies & base_packages).any?}
38
+ .map(&:name)
39
+
40
+ extended_dependencies = (base_packages | new_packages).sort
41
+
42
+ return extended_dependencies if extended_dependencies == base_packages
43
+
44
+ get_dependencies(extended_dependencies) || []
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,118 @@
1
+ require 'pathname'
2
+ require 'fileutils'
3
+
4
+ module Rdm
5
+ module Handlers
6
+ class TemplateHandler
7
+ class << self
8
+ def generate(template_name:, local_path:, current_path:, locals: {},
9
+ ignore_source_file: false, stdout: STDOUT, stdin: STDIN)
10
+
11
+ Rdm::Handlers::TemplateHandler.new(
12
+ template_name: template_name.to_s,
13
+ local_path: local_path,
14
+ current_path: current_path,
15
+ ignore_source_file: ignore_source_file,
16
+ locals: locals,
17
+ stdout: stdout,
18
+ stdin: stdin
19
+ ).generate
20
+ end
21
+ end
22
+
23
+ def initialize(template_name:, local_path:, current_path:,
24
+ locals:, ignore_source_file:, stdout:, stdin:)
25
+
26
+ @template_name = template_name
27
+ @local_path = local_path
28
+ @current_path = current_path
29
+ @ignore_source_file = ignore_source_file
30
+ @missing_variables = []
31
+ @stdout = stdout
32
+ @stdin = stdin
33
+
34
+ @locals = default_locals.merge(locals)
35
+ end
36
+
37
+ def generate
38
+ project_path = @ignore_source_file ? @current_path : File.dirname(Rdm::SourceLocator.locate(@current_path))
39
+ template_detector = Rdm::Templates::TemplateDetector.new(project_path)
40
+
41
+ @template_directory = template_detector.detect_template_folder(@template_name)
42
+ @destination_directory = File.join(project_path, @local_path)
43
+
44
+ template_files_list = Dir[
45
+ File.join(@template_directory, '**', '.?*'),
46
+ File.join(@template_directory, '**', '*')
47
+ ]
48
+ .select { |p| File.file?(p) }
49
+ .reject { |p| File.basename(p) == '.DS_Store' }
50
+
51
+ template_dir_list = Dir[ File.join(@template_directory, '**', '*') ].select { |p| File.directory? p }
52
+
53
+ template_files_list.each do |file|
54
+ missings = Rdm::Templates::TemplateRenderer.get_undefined_variables(get_destination_path(file), @locals)
55
+
56
+ if File.extname(file) != '.erb'
57
+ missings.push(
58
+ *Rdm::Templates::TemplateRenderer.get_undefined_variables(File.read(file), @locals)
59
+ )
60
+ end
61
+
62
+ @missing_variables.push(*missings)
63
+ end
64
+
65
+ template_dir_list.each do |dir|
66
+ @missing_variables.push(
67
+ *Rdm::Templates::TemplateRenderer.get_undefined_variables(get_destination_path(dir), @locals)
68
+ )
69
+ end
70
+
71
+ @missing_variables.uniq!
72
+ if @missing_variables.any?
73
+ @stdout.puts "Undefined variables were found:"
74
+ @missing_variables.size.times {|t| @stdout.puts " #{t+1}. #{@missing_variables[t]}"}
75
+
76
+ @missing_variables.each do |var|
77
+ @stdout.print "Type value for '#{var}': "
78
+ @locals[var] = @stdin.gets.chomp
79
+ end
80
+ end
81
+
82
+ template_dir_list.each do |dir|
83
+ rendered_abs_path = Rdm::Templates::TemplateRenderer.handle(get_destination_path(dir), @locals)
84
+ FileUtils.mkdir_p rendered_abs_path
85
+ end
86
+
87
+ template_files_list.map do |file|
88
+ rendered_abs_path = Rdm::Templates::TemplateRenderer.handle(get_destination_path(file), @locals)
89
+ raise Rdm::Errors::TemplateFileExists.new(rendered_abs_path) if File.exists?(rendered_abs_path)
90
+
91
+ rendered_file_content = File.extname(file) == '.erb' ?
92
+ File.read(file) :
93
+ Rdm::Templates::TemplateRenderer.handle(File.read(file), @locals)
94
+
95
+ FileUtils.mkdir_p(File.dirname(rendered_abs_path))
96
+ File.open(rendered_abs_path, 'w') { |f| f.write rendered_file_content }
97
+
98
+ Pathname.new(rendered_abs_path).relative_path_from Pathname.new(project_path)
99
+ end
100
+ end
101
+
102
+ private
103
+
104
+ def get_destination_path(file)
105
+ return nil unless defined? @template_directory && defined? @destination_directory
106
+
107
+ template_rel_path = Pathname.new(file).relative_path_from Pathname.new(@template_directory)
108
+ File.join(@destination_directory, template_rel_path)
109
+ end
110
+
111
+ def default_locals
112
+ {
113
+ package_subdir_name: Rdm.settings.send(:package_subdir_name)
114
+ }
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,15 @@
1
+ module Rdm
2
+ module Helpers
3
+ module PathHelper
4
+ def package_path(package_name, current_file: nil)
5
+ current_file ||= caller[0].split(':').first
6
+
7
+ source = Rdm::SourceParser.read_and_init_source(Rdm::SourceLocator.locate(current_file))
8
+
9
+ raise Rdm::Errors::PackageDoesNotExist unless source.packages.keys.include?(package_name.to_s)
10
+
11
+ return source.packages.fetch(package_name.to_s).path
12
+ end
13
+ end
14
+ end
15
+ end
@@ -69,6 +69,12 @@ class Rdm::Package
69
69
  exec_metadata :version, value
70
70
  end
71
71
 
72
+ def ==(other_package)
73
+ return false if other_package.class != self.class
74
+
75
+ other_package.name == name
76
+ end
77
+
72
78
  private
73
79
 
74
80
  def current_group
@@ -69,7 +69,7 @@ class Rdm::PackageImporter
69
69
  package.config_dependencies(group).each do |dependency|
70
70
  import_config(dependency, source: source)
71
71
  end
72
-
72
+
73
73
  # only after importing dependencies - require package itself
74
74
  begin
75
75
  require package_name
@@ -0,0 +1,78 @@
1
+ require 'fileutils'
2
+
3
+ module Rdm
4
+ module Packages
5
+ class CompilerService
6
+ class << self
7
+ def compile(compile_path:, project_path:, package_name:)
8
+ Rdm::Packages::CompilerService.new(
9
+ compile_path: compile_path,
10
+ project_path: project_path,
11
+ package_name: package_name
12
+ ).compile
13
+ end
14
+ end
15
+
16
+ def initialize(compile_path:, project_path:, package_name:)
17
+ @compile_path = compile_path
18
+ @project_path = project_path
19
+ @package_name = package_name
20
+ end
21
+
22
+ def compile
23
+ render_helper_path = "#{@project_path}/.rdm/helpers/render_helper.rb"
24
+ require_relative render_helper_path if File.exist?(render_helper_path)
25
+
26
+ FileUtils.rm_rf(@compile_path) if Dir.exists?(@compile_path)
27
+ FileUtils.mkdir_p(@compile_path)
28
+
29
+ dependent_packages = Rdm::Handlers::DependenciesHandler.show_packages(
30
+ package_name: @package_name,
31
+ project_path: @project_path
32
+ )
33
+
34
+ dependent_packages.each do |pkg|
35
+ rel_path = Pathname.new(pkg.path).relative_path_from(Pathname.new(@project_path))
36
+ new_path = File.dirname(File.join(@compile_path, rel_path))
37
+
38
+ FileUtils.mkdir_p(new_path)
39
+ FileUtils.cp_r(pkg.path, new_path)
40
+ end
41
+
42
+
43
+ source_rdm_path = File.join(@project_path, Rdm::SOURCE_FILENAME)
44
+ dest_rdm_path = File.join(@compile_path, Rdm::SOURCE_FILENAME)
45
+ package_definition_regex = /package\s+['"]([\w\/]+)['"]/i
46
+
47
+ File.open(dest_rdm_path, "w") do |out_file|
48
+ File.foreach(source_rdm_path) do |line|
49
+ package_line = package_definition_regex.match(line)
50
+ if package_line.nil?
51
+ out_file.puts line
52
+ else
53
+ dependent_package_definition = dependent_packages.detect do |pkg|
54
+ package_line[1] == Pathname.new(pkg.path).relative_path_from(Pathname.new(@project_path)).to_s
55
+ end
56
+
57
+ out_file.puts line if dependent_package_definition.present?
58
+ end
59
+ end
60
+ end
61
+
62
+ FileUtils.cp_r(File.join(@project_path, 'configs'), File.join(@compile_path, 'configs'))
63
+
64
+ Rdm.settings.compile_ignore_files.each do |file|
65
+ Dir["#{@compile_path}/**/#{file}"].each do |file_to_remove|
66
+ FileUtils.rm_rf(file_to_remove)
67
+ end
68
+ end
69
+
70
+ Rdm.settings.compile_add_files.each do |file|
71
+ FileUtils.cp(File.join(@project_path, file), File.join(@compile_path, file))
72
+ end
73
+
74
+ return dependent_packages.map(&:name)
75
+ end
76
+ end
77
+ end
78
+ end