rdm 0.2.0 → 0.3.0

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