dtk-common 0.5.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +5 -0
  3. data/Gemfile +2 -0
  4. data/Gemfile.lock +16 -0
  5. data/LICENSE +674 -0
  6. data/README.md +36 -0
  7. data/dtk-common.gemspec +23 -0
  8. data/lib/common_patch.rb +16 -0
  9. data/lib/dsl/directory_parser/git.rb +39 -0
  10. data/lib/dsl/directory_parser/linux.rb +21 -0
  11. data/lib/dsl/directory_parser.rb +77 -0
  12. data/lib/dsl/file_parser/file_types/assembly/v2/assembly.rb +53 -0
  13. data/lib/dsl/file_parser/file_types/component_module_refs/v1/component_module_refs.rb +57 -0
  14. data/lib/dsl/file_parser.rb +228 -0
  15. data/lib/dsl.rb +23 -0
  16. data/lib/dtk-common/version.rb +3 -0
  17. data/lib/dtk_common.rb +36 -0
  18. data/lib/dynamic_loader.rb +28 -0
  19. data/lib/git_repo/adapters/rugged/blob.rb +14 -0
  20. data/lib/git_repo/adapters/rugged/commit.rb +14 -0
  21. data/lib/git_repo/adapters/rugged/common.rb +34 -0
  22. data/lib/git_repo/adapters/rugged/tree.rb +40 -0
  23. data/lib/git_repo/adapters/rugged.rb +45 -0
  24. data/lib/git_repo.rb +93 -0
  25. data/lib/gitolite/configuration.rb +35 -0
  26. data/lib/gitolite/errors.rb +5 -0
  27. data/lib/gitolite/grit/adapter.rb +101 -0
  28. data/lib/gitolite/grit/file_access.rb +51 -0
  29. data/lib/gitolite/init.rb +16 -0
  30. data/lib/gitolite/manager.rb +158 -0
  31. data/lib/gitolite/repo.rb +171 -0
  32. data/lib/gitolite/user_group.rb +98 -0
  33. data/lib/gitolite/utils.rb +59 -0
  34. data/lib/grit_adapter/file_access/diff.rb +82 -0
  35. data/lib/grit_adapter/file_access/status.rb +25 -0
  36. data/lib/grit_adapter/file_access.rb +296 -0
  37. data/lib/grit_adapter/object_access.rb +39 -0
  38. data/lib/grit_adapter.rb +212 -0
  39. data/lib/module_version.rb +12 -0
  40. data/lib/require_first.rb +18 -0
  41. data/rich_tests/README.md +1 -0
  42. data/rich_tests/dsl_test1.rb +14 -0
  43. data/rich_tests/dsl_test2.rb +10 -0
  44. data/rich_tests/dsl_test3.rb +17 -0
  45. data/rich_tests/dsl_test4.rb +25 -0
  46. data/rich_tests/fixtures/dsl_test1/sm-dtk-bootstrap/global_module_refs.json +2 -0
  47. data/rich_tests/fixtures/dsl_test1/sm-dtk-dtk/global_module_refs.json +7 -0
  48. data/rich_tests/fixtures/dsl_test1/sm-dtk-test_dtk/global_module_refs.json +8 -0
  49. data/rich_tests/fixtures/dsl_test1/sm-dtk-test_postgres/global_module_refs.json +7 -0
  50. data/rich_tests/fixtures/dsl_test1/sm-dtk-test_service/global_module_refs.json +5 -0
  51. data/rich_tests/fixtures/dsl_test1/sm-dtk-testv1/global_module_refs.json +14 -0
  52. data/rich_tests/fixtures/dsl_test1/sm-rich-app/global_module_refs.json +5 -0
  53. data/rich_tests/fixtures/dsl_test1/sm-rich-hdp/global_module_refs.json +3 -0
  54. data/rich_tests/fixtures/dsl_test1/sm-rich-test_dtk/global_module_refs.json +5 -0
  55. data/rich_tests/fixtures/dsl_test2/sm-dtk-dtk/assemblies/message_bus/assembly.json +23 -0
  56. data/rich_tests/fixtures/dsl_test2/sm-dtk-dtk/assemblies/repo_manager/assembly.json +26 -0
  57. data/rich_tests/fixtures/dsl_test2/sm-dtk-dtk/assemblies/server-nginx/assembly.json +64 -0
  58. data/rich_tests/fixtures/dsl_test2/sm-dtk-dtk/assemblies/server-on-one-node/assembly.json +47 -0
  59. data/rich_tests/fixtures/dsl_test2/sm-dtk-dtk/assemblies/t4/assembly.json +20 -0
  60. data/rich_tests/fixtures/dsl_test2/sm-dtk-dtk/global_module_refs.json +7 -0
  61. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/HEAD +1 -0
  62. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/config +4 -0
  63. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/description +1 -0
  64. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/hooks/applypatch-msg.sample +15 -0
  65. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/hooks/commit-msg.sample +24 -0
  66. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/hooks/post-update.sample +8 -0
  67. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/hooks/pre-applypatch.sample +14 -0
  68. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/hooks/pre-commit.sample +50 -0
  69. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/hooks/pre-rebase.sample +169 -0
  70. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/hooks/prepare-commit-msg.sample +36 -0
  71. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/hooks/update.sample +128 -0
  72. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/info/exclude +6 -0
  73. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/0a/5b6255a87c9e56d91557398aee730a2b3de745 +0 -0
  74. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/15/e78d7675db51c3f9e2cf154a350d82b12abc72 +0 -0
  75. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/18/7c41cd47b9c295da0cee128c888c95cf2bba1c +0 -0
  76. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/2a/17fb5b22b8108790435eb215ffe9d06829b841 +0 -0
  77. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/2e/8c9f8472cb0e9e2421e8b5c86ad981b728cdcf +0 -0
  78. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/3b/4646ef81ef99c0c7aa62c0a97e774761c7de54 +0 -0
  79. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/5c/498a06b1ef830203e4e04c1043c9d846a18a98 +0 -0
  80. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/72/b3afc0c009e42faa235784f29f43e336bceebd +0 -0
  81. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/78/2987dc58fb1f3bea00452b8727957115b51d6f +0 -0
  82. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/9b/7c5e8096a3a871c76ad179bc29c33ac5390683 +0 -0
  83. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/a5/b61c6608349cd87f3d53a13abc2d2f51772082 +0 -0
  84. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/b4/1fb4f136d54fc9277ff16d58d9361a03a91b23 +0 -0
  85. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/be/81c8c44a92dde5139fdd302d75eec027032c8b +0 -0
  86. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/c3/88fbdcfe33840280aa119df6d01a782fdbdd60 +1 -0
  87. data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/refs/heads/master +1 -0
  88. data/rich_tests/fixtures/rugged_test1/repo1.git/HEAD +1 -0
  89. data/rich_tests/fixtures/rugged_test1/repo1.git/config +4 -0
  90. data/rich_tests/fixtures/rugged_test1/repo1.git/description +1 -0
  91. data/rich_tests/fixtures/rugged_test1/repo1.git/hooks/applypatch-msg.sample +15 -0
  92. data/rich_tests/fixtures/rugged_test1/repo1.git/hooks/commit-msg.sample +24 -0
  93. data/rich_tests/fixtures/rugged_test1/repo1.git/hooks/post-update.sample +8 -0
  94. data/rich_tests/fixtures/rugged_test1/repo1.git/hooks/pre-applypatch.sample +14 -0
  95. data/rich_tests/fixtures/rugged_test1/repo1.git/hooks/pre-commit.sample +50 -0
  96. data/rich_tests/fixtures/rugged_test1/repo1.git/hooks/pre-rebase.sample +169 -0
  97. data/rich_tests/fixtures/rugged_test1/repo1.git/hooks/prepare-commit-msg.sample +36 -0
  98. data/rich_tests/fixtures/rugged_test1/repo1.git/hooks/update.sample +128 -0
  99. data/rich_tests/fixtures/rugged_test1/repo1.git/info/exclude +6 -0
  100. data/rich_tests/fixtures/rugged_test1/repo1.git/objects/01/7d2a92efdefb513c266496c836112112c84b54 +0 -0
  101. data/rich_tests/fixtures/rugged_test1/repo1.git/objects/0c/6675dac950c9f2038c899a0026c60bc71b1986 +0 -0
  102. data/rich_tests/fixtures/rugged_test1/repo1.git/objects/12/7d8deca9a49974f887c594fc79804a2490c3c5 +0 -0
  103. data/rich_tests/fixtures/rugged_test1/repo1.git/objects/21/c65148298b7366019013c31ddc9e6c62770277 +0 -0
  104. data/rich_tests/fixtures/rugged_test1/repo1.git/objects/22/2c738a4abaebbd9ea3b6634fac902ae74479c4 +0 -0
  105. data/rich_tests/fixtures/rugged_test1/repo1.git/objects/25/560ef0476ffda4abf20b660955aac645b6ee2f +0 -0
  106. data/rich_tests/fixtures/rugged_test1/repo1.git/objects/4a/e421568785273757fe479236de426b80d1b658 +2 -0
  107. data/rich_tests/fixtures/rugged_test1/repo1.git/objects/60/465cb06c0cde161eff264d4c2a0535fc1e8bb2 +0 -0
  108. data/rich_tests/fixtures/rugged_test1/repo1.git/objects/63/7f0347d31dad180d6fc7f6720c187b05a8754c +0 -0
  109. data/rich_tests/fixtures/rugged_test1/repo1.git/objects/6c/54ab6443f1a24669a99f2ce1b43863be2e9fda +0 -0
  110. data/rich_tests/fixtures/rugged_test1/repo1.git/objects/82/c75b6fa64b746bd7f9cd7afe3c1e5bd53c430c +0 -0
  111. data/rich_tests/fixtures/rugged_test1/repo1.git/objects/86/ec2616845245b9c9355f768a1727bcdfb643ac +0 -0
  112. data/rich_tests/fixtures/rugged_test1/repo1.git/objects/93/ee8545d8f9681db9800cb11ec8aa72a8df8bd1 +0 -0
  113. data/rich_tests/fixtures/rugged_test1/repo1.git/objects/bc/65ddb77fef699933dfe16b79c769f7a9cc0afd +0 -0
  114. data/rich_tests/fixtures/rugged_test1/repo1.git/objects/d4/b1ee93110d823c5161f8cb954a6cf2e41345c1 +2 -0
  115. data/rich_tests/fixtures/rugged_test1/repo1.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4 +0 -0
  116. data/rich_tests/fixtures/rugged_test1/repo1.git/refs/heads/branch1 +1 -0
  117. data/rich_tests/fixtures/rugged_test1/repo1.git/refs/heads/master +1 -0
  118. data/rich_tests/rugged_test1.rb +16 -0
  119. data/test.rb +13 -0
  120. metadata +205 -0
data/README.md ADDED
@@ -0,0 +1,36 @@
1
+ dtk-common
2
+ ==========
3
+
4
+ DTK Common
5
+
6
+
7
+ GITOLITE
8
+ =========
9
+
10
+ Manager takes responsibility of handling all gitolite methods (or at least most of them). Reason is simple, gitolite commit / push are expensive operations and we want to mitigate that fact by using manager, and making sure that all our changes are under one commit / push.
11
+
12
+ * Example: Adding user/user group/all to repo configuration
13
+
14
+ manager = Gitolite::Manager.new('/home/git/gitolite-admin')
15
+
16
+ repo_conf = manager.open_repo('r8--cm--java')
17
+ repo_conf.add_username_with_rights(
18
+ 'dtk-instance-dtk9',
19
+ 'RW+'
20
+ )
21
+
22
+ repo_conf.add_user_group_with_rights(
23
+ 'tenants',
24
+ 'R'
25
+ )
26
+
27
+ repo_conf.add_all_with_rights(
28
+ gitolite_friendly('RW')
29
+ )
30
+
31
+ manager.push()
32
+
33
+
34
+ License
35
+ ----------------------
36
+ DTK Common is released under the GPLv3 license. Please see LICENSE for more details.
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/dtk-common/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Rich PELAVIN"]
6
+ gem.email = ["rich@reactor8.com"]
7
+ gem.description = %q{Dtk common is needed to use dtk-client gem, provides common libraries for running DTK CLI.}
8
+ gem.summary = %q{Common libraries used for DTK CLI client.}
9
+ gem.homepage = "https://github.com/rich-reactor8/dtk-common"
10
+ gem.licenses = ["GPL-3.0"]
11
+
12
+ gem.files = `git ls-files`.split($\)
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "dtk-common"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = "#{DtkCommon::VERSION}.#{ARGV[3]}".chomp(".")
17
+
18
+ gem.add_dependency 'rugged','~> 0.17.0.b7'
19
+ gem.add_dependency 'dtk-common-core','~> 0.5.10'
20
+ gem.add_dependency 'colorize','~> 0.5.8'
21
+ # gem.add_dependency 'sequel','~> 3.40.0'
22
+ # gem.add_dependency 'rdoc','~> 3.12'
23
+ end
@@ -0,0 +1,16 @@
1
+ #TODO: just putting in hooks for errors and logs
2
+ #need to figure out how to hook calling library's errors
3
+
4
+ module DtkCommon
5
+ class Error < NameError
6
+ def initialize(msg,name=nil)
7
+ super(msg,name)
8
+ end
9
+ end
10
+ class ErrorUsage < Error
11
+ end
12
+ Log = ::DTK::Log
13
+ module Aux
14
+ extend ::DTK::Common::AuxMixin
15
+ end
16
+ end
@@ -0,0 +1,39 @@
1
+ require File.expand_path('../../git_repo.rb',File.dirname(__FILE__))
2
+ module DtkCommon; module DSL
3
+ class DirectoryParser
4
+ class Git < self
5
+ # def initialize(repo_path,directory_type,branch='master')
6
+ def initialize(directory_type,repo_path,branch='master')
7
+ super(directory_type)
8
+ # puts repo_path
9
+ @repo_path = repo_path
10
+ @repo_branch = GitRepo::Branch.new(repo_path,branch)
11
+ end
12
+
13
+ def self.implements_method?(method_name)
14
+ if DirectoryParserMethods.include?(method_name)
15
+ case method_name
16
+ when :parse_directory
17
+ GitRepo::Branch.implements_method?(:get_file_content)
18
+ else
19
+ true
20
+ end
21
+ end
22
+ end
23
+
24
+ private
25
+ def all_files_from_root()
26
+ # TODO: Watch version here
27
+ # output = `git --git-dir=#{@repo_path} ls-tree --full-tree -r HEAD`
28
+ @repo_branch.list_files()
29
+ end
30
+ def get_content(file_path)
31
+ # output = `git --git-dir=#{@repo_path} show HEAD:#{file_path}`
32
+ # output = '{}' if output.empty?
33
+ # output
34
+ #If file does not exsist will return nil
35
+ @repo_branch.get_file_content(file_path)
36
+ end
37
+ end
38
+ end
39
+ end; end
@@ -0,0 +1,21 @@
1
+ module DtkCommon; module DSL
2
+ class DirectoryParser
3
+ class Linux < self
4
+ def initialize(directory_type,directory_root)
5
+ super(directory_type)
6
+ @directory_root = directory_root
7
+ end
8
+ private
9
+ def all_files_from_root()
10
+ Dir.chdir(@directory_root) do
11
+ Dir["**/*"]
12
+ end
13
+ end
14
+
15
+ def get_content(rel_file_path)
16
+ file_path = "#{@directory_root}/#{rel_file_path}"
17
+ File.open(file_path).read()
18
+ end
19
+ end
20
+ end
21
+ end; end
@@ -0,0 +1,77 @@
1
+ module DtkCommon
2
+ module DSL
3
+ class DirectoryParser
4
+ require File.expand_path("directory_parser/linux",File.dirname(__FILE__))
5
+ require File.expand_path("directory_parser/git",File.dirname(__FILE__))
6
+
7
+ def initialize(directory_type)
8
+ unless @file_info = file_info(directory_type)
9
+ raise Error.new("Illegal directory type (#{directory_type})")
10
+ end
11
+ @directory_type = directory_type
12
+ end
13
+
14
+ DirectoryParserMethods = [:parse_directory]
15
+ def self.implements_method?(method_name)
16
+ DirectoryParserMethods.include?(method_name)
17
+ end
18
+
19
+ #if file_type is given returns DtkCommon::DSL::FileParser::OutputArray
20
+ #otherwise returns hash at top level taht is indexed by file types found
21
+ def parse_directory(file_type=nil,opts={})
22
+ pruned_file_info =
23
+ if file_type
24
+ matches = @file_info.select{|r|r[:file_type] == file_type}
25
+ if matches.empty?
26
+ raise Error.new("Illegal file type (#{file_type}) for directory_type (#{directory_type})")
27
+ end
28
+ matches
29
+ else
30
+ @file_info
31
+ end
32
+ #instantiate any rel_path_pattern
33
+ pruned_file_instances = instantiate_rel_path_patterns(pruned_file_info)
34
+ ret = Hash.new
35
+ pruned_file_instances.each do |r|
36
+ file_content = get_content(r[:rel_path])
37
+ opts[:file_path] = r[:rel_path]
38
+ new_parsed = FileParser.parse_content(r[:file_type],file_content,opts)
39
+ ret[file_type] = (ret[file_type] ? ret[file_type] + new_parsed : new_parsed)
40
+ end
41
+ file_type.nil? ? ret : ret[file_type]
42
+ end
43
+
44
+ private
45
+ def file_info(directory_type)
46
+ DirectoryTypeFiles[directory_type]
47
+ end
48
+ def instantiate_rel_path_patterns(rel_file_info)
49
+ ret = Array.new
50
+ all_files_from_root = nil
51
+ rel_file_info.each do |r|
52
+ if rel_path = r[:rel_path]
53
+ ret << r
54
+ else
55
+ rel_path_pattern = r[:rel_path_pattern]
56
+
57
+ (all_files_from_root ||= all_files_from_root()).each do |f|
58
+ if f =~ rel_path_pattern
59
+ file_key = $1
60
+ ret << {:rel_path => f, :file_type => r[:file_type], :key => file_key}
61
+ end
62
+ end
63
+ end
64
+ end
65
+ ret
66
+ end
67
+ #TODO: may put version info here too
68
+ DirectoryTypeFiles = {
69
+ :service_module =>
70
+ [
71
+ {:rel_path => "global_module_refs.json", :file_type => :component_module_refs},
72
+ {:rel_path_pattern => /^assemblies\/([^\/]+)\/assembly\.yaml$/, :file_type => :assembly}
73
+ ]
74
+ }
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,53 @@
1
+ module DtkCommon; module DSL; class FileParser
2
+ class Assembly < self
3
+ class OutputArray < FileParser::OutputArray
4
+ def self.keys_for_row()
5
+ [:assembly_name,:components]
6
+ end
7
+ end
8
+
9
+ class V2 < self
10
+ def parse_hash_content(input_hash)
11
+ ret = OutputArray.new
12
+ assembly_hash = OutputHash.new(
13
+ :assembly_name => input_hash[:name],
14
+ :components => Component.parse_hash_content(input_hash[:assembly]||{})
15
+ )
16
+ ret << assembly_hash
17
+ ret
18
+ end
19
+
20
+ class Component
21
+ class OutputArray < FileParser::OutputArray
22
+ def self.keys_for_row()
23
+ [:component_name,:module_name,:node_name]
24
+ end
25
+ end
26
+
27
+ def self.parse_hash_content(input_hash)
28
+ ret = OutputArray.new
29
+ (input_hash[:nodes]||{}).each_pair do |node_name,node_info|
30
+ (node_info[:components]||{}).each do |component|
31
+ mod_component_name = (component.kind_of?(Hash) ? component.keys.first : component)
32
+ module_name,component_name = ret_module_and_component_names(mod_component_name)
33
+ ret << OutputHash.new(:component_name => component_name,:module_name => module_name,:node_name => node_name)
34
+ end
35
+ end
36
+ ret
37
+ end
38
+ private
39
+
40
+ #returns [module_name,component_name]
41
+ def self.ret_module_and_component_names(mod_component_name)
42
+ if mod_component_name =~ /(^[^:]+)::([^:]+$)/
43
+ [$1,$2]
44
+ else
45
+ [mod_component_name,mod_component_name]
46
+ end
47
+ end
48
+ end
49
+
50
+ end
51
+ end
52
+ end; end; end
53
+
@@ -0,0 +1,57 @@
1
+ module DtkCommon; module DSL; class FileParser
2
+ class ComponentModuleRefs < self
3
+ class V1 < self
4
+ def parse_hash_content(input_hash)
5
+ ret = OutputArray.new
6
+ component_modules = input_hash[:component_modules]
7
+ if component_modules.empty?
8
+ return ret
9
+ end
10
+
11
+ component_modules.each do |component_module,v|
12
+ new_el = OutputHash.new(:component_module => component_module)
13
+ parse_error = true
14
+ if v.kind_of?(InputHash) and v.only_has_keys?(:version,:remote_namespace,:namespace) and not v.empty?()
15
+ parse_error = false
16
+ new_el.merge_non_empty!(:version_info => v[:version], :remote_namespace => v[:remote_namespace]||v[:namespace])
17
+ elsif v.kind_of?(String)
18
+ parse_error = false
19
+ new_el.merge_non_empty!(:version_info => v)
20
+ elsif v.nil?
21
+ parse_error = false
22
+ end
23
+ if parse_error
24
+ err_msg = (parse_error.kind_of?(String) ? parse_error : "Ill-formed term (#{v.inspect})")
25
+ raise ErrorUsage::DTKParse.new(err_msg)
26
+ else
27
+ ret << new_el
28
+ end
29
+ end
30
+ ret
31
+ end
32
+
33
+ def generate_hash(output_array)
34
+ component_modules = output_array.inject(Hash.new) do |h,r|
35
+ unless cmp_module = r[:component_module]
36
+ raise Error.new("Missing field (:component_module)")
37
+ end
38
+ h.merge(cmp_module => Aux.hash_subset(r,OutputArrayToParseHashCols,:no_non_nil => true))
39
+ end
40
+ {:component_modules => component_modules}
41
+ end
42
+
43
+ OutputArrayToParseHashCols = [{:version_info => :version},:remote_namespace]
44
+
45
+ end
46
+
47
+ class OutputArray < FileParser::OutputArray
48
+ def self.keys_for_row()
49
+ [:component_module,:version_info,:remote_namespace]
50
+ end
51
+ def self.has_required_keys?(hash_el)
52
+ !hash_el[:component_module].nil?
53
+ end
54
+ end
55
+ end
56
+ end; end; end
57
+
@@ -0,0 +1,228 @@
1
+ require 'singleton'
2
+ require 'json'
3
+ require 'yaml'
4
+
5
+ module DtkCommon
6
+ module DSL
7
+ class Loader
8
+ include Singleton
9
+ def self.file_parser(file_type,version=nil)
10
+ instance.file_parser(file_type,version)
11
+ end
12
+
13
+ def file_parser(file_type,version=nil)
14
+ ret = (@loaded_types[file_type]||{})[version]
15
+ return ret if ret
16
+ unless FileTypes.include?(file_type)
17
+ raise Error.new("Illegal file type (#{file_type})")
18
+ end
19
+
20
+ #load base if no versions loaded already
21
+ base_path = "#{BaseDirForFileTypes}/#{file_type}"
22
+ #if (@loaded_types[file_type]||{}).empty?
23
+ # require File.expand_path(base_path,File.dirname(__FILE__))
24
+ #end
25
+
26
+ version ||= default_version(file_type)
27
+ path = "#{base_path}/v#{version.to_s}/#{file_type}"
28
+ require File.expand_path(path, File.dirname(__FILE__))
29
+
30
+ base_class = FileParser.const_get(Aux.snake_to_camel_case(file_type.to_s))
31
+ ret_class = base_class.const_get("V#{version.to_s}")
32
+ input_hash_class = ret_class.const_get "InputHash"
33
+ ret = ret_class.new(input_hash_class)
34
+ (@loaded_types[file_type] ||= Hash.new)[version] = ret
35
+ ret
36
+ end
37
+ BaseDirForFileTypes = "file_parser/file_types"
38
+ private
39
+ def initialize()
40
+ @loaded_types = Hash.new
41
+ end
42
+
43
+ def default_version(file_type)
44
+ FileTypeVesisonDefaults[file_type] || 1
45
+ end
46
+ FileTypes =
47
+ [
48
+ :component_module_refs,
49
+ :assembly
50
+ ]
51
+ FileTypeVesisonDefaults = {
52
+ :component_module_refs => 1,
53
+ :assembly => 2
54
+ }
55
+ end
56
+ class FileParser
57
+ def initialize(input_hash_class)
58
+ @input_hash_class = input_hash_class
59
+ end
60
+
61
+ def self.implements_method?(method_name)
62
+ [:parse_content,:generate_hash].include?(method_name)
63
+ end
64
+
65
+ def self.parse_content(file_type,file_content,opts={})
66
+ ret = OutputArray.new
67
+ # if there is no content (nil) return empty array as if content was empty
68
+ return ret unless file_content
69
+ file_parser = Loader.file_parser(file_type,opts[:version])
70
+ # raw_hash_content = convert_json_content_to_hash(file_content,opts)
71
+ #TODO: for Rich
72
+ # we need to implement dsl v3 parser, this is just temp fix for autoimport
73
+ # just changed parser to yaml instead of json because new modules/services
74
+ # are in yaml format now
75
+ raw_hash_content = convert_yaml_content_to_hash(file_content,opts)
76
+
77
+ return raw_hash_content if raw_hash_content.is_a?(ErrorUsage::DSLParsing::JSONParsing)
78
+
79
+ file_parser.parse_hash_content_aux(raw_hash_content)
80
+ end
81
+
82
+ def parse_hash_content_aux(raw_hash)
83
+ parse_hash_content(input_form(raw_hash))
84
+ end
85
+
86
+ def self.generate_hash(file_type,output_array,opts={})
87
+ file_parser = Loader.file_parser(file_type,opts[:version])
88
+ file_parser.generate_hash(output_array)
89
+ end
90
+
91
+ class OutputArray < Array
92
+ def <<(hash_el)
93
+ bad_keys = hash_el.keys - self.class.keys_for_row()
94
+ unless bad_keys.empty?
95
+ raise Error.new("Illegal keys being inserted in OutputArray (#{bad_keys.join(',')})")
96
+ end
97
+ super
98
+ end
99
+
100
+ def +(output_obj)
101
+ if output_obj.kind_of?(OutputArray)
102
+ super
103
+ elsif output_obj.kind_of?(OutputHash)
104
+ super(OutputArray.new(OutputHash))
105
+ elsif output_obj.nil?
106
+ self
107
+ else
108
+ raise Error.new("Unexpected object type (#{output_obj.class})")
109
+ end
110
+ end
111
+
112
+ #can be overwritten
113
+ def self.has_required_keys?(hash_el)
114
+ (keys_for_row() - hash_el.keys?).nil?
115
+ end
116
+
117
+ end
118
+ class OutputHash < ::DTK::Common::SimpleHashObject
119
+ def merge_non_empty!(hash)
120
+ hash.each{|k,v| merge!(k => v) unless v.nil? or v.empty?}
121
+ self
122
+ end
123
+
124
+ def +(output_obj)
125
+ if output_obj.kind_of?(OutputArray)
126
+ OutputArray.new(self) + output_obj
127
+ elsif output_obj.kind_of?(OutputHash)
128
+ merge(output_obj)
129
+ elsif output_obj.nil?
130
+ self
131
+ else
132
+ raise Error.new("Unexpected object type (#{output_obj.class})")
133
+ end
134
+ end
135
+ end
136
+
137
+ class InputHash < Hash
138
+ #to provide autovification and use of symbol indexes
139
+ def initialize(hash=nil)
140
+ super()
141
+ return unless hash
142
+ replace_el = hash.inject(Hash.new) do |h,(k,v)|
143
+ processed_v = (v.kind_of?(Hash) ? self.class.new(v) : v)
144
+ h.merge(k => processed_v)
145
+ end
146
+ replace(replace_el)
147
+ end
148
+
149
+ def [](index)
150
+ val = super(internal_key_form(index)) || {}
151
+ (val.kind_of?(Hash) ? self.class.new(val) : val)
152
+ end
153
+ def only_has_keys?(*only_has_keys)
154
+ (keys() - only_has_keys.map{|k|internal_key_form(k)}).empty?
155
+ end
156
+ private
157
+ def internal_key_form(key)
158
+ key.to_s
159
+ end
160
+ end
161
+
162
+ private
163
+ def input_form(raw_hash)
164
+ @input_hash_class.new(raw_hash)
165
+ end
166
+
167
+ def self.convert_yaml_content_to_hash(content, opts={})
168
+ ret = Hash.new
169
+ return ret if content.empty?
170
+
171
+ begin
172
+ YAML.load(content)
173
+ rescue Exception => e
174
+ return ErrorUsage::DSLParsing::JSONParsing.new("YAML parsing error #{e.to_s} in file", opts[:file_path]) if opts[:do_not_raise]
175
+ raise ErrorUsage::DSLParsing::JSONParsing.new("YAML parsing error #{e.to_s} in file", opts[:file_path])
176
+ end
177
+ end
178
+
179
+ def self.convert_json_content_to_hash(json_file_content, opts={})
180
+ ret = Hash.new
181
+ if json_file_content.empty?
182
+ return ret
183
+ end
184
+
185
+ begin
186
+ ::JSON.parse(json_file_content)
187
+ rescue ::JSON::ParserError => e
188
+ # raise ErrorUsage::JSONParse.new(e.to_s)
189
+ return ErrorUsage::DSLParsing::JSONParsing.new("JSON parsing error #{e.to_s} in file", opts[:file_path]) if opts[:do_not_raise]
190
+ raise ErrorUsage::DSLParsing::JSONParsing.new("JSON parsing error #{e.to_s} in file", opts[:file_path])
191
+ end
192
+ end
193
+
194
+ end
195
+
196
+ class ErrorUsage < Error
197
+ class DSLParsing < self
198
+ def initialize(base_error_msg,file_path_or_opts=nil)
199
+ file_path,opts = file_path_and_opts(file_path_or_opts)
200
+ super(local_method_err_msg(base_error_msg,file_path),opts)
201
+ end
202
+ private
203
+ def local_method_err_msg(base_error_msg,file_path=nil)
204
+ file_ref = (file_path && " (in file: #{file_path})")
205
+ "#{base_error_msg}#{file_ref}"
206
+ end
207
+
208
+ def file_path_and_opts(file_path_or_opts)
209
+ file_path = nil
210
+ opts = Hash.new
211
+ if file_path_or_opts.kind_of?(Hash)
212
+ opts = file_path_or_opts
213
+ else
214
+ file_path = file_path_or_opts
215
+ end
216
+ [file_path,opts]
217
+ end
218
+
219
+ class JSONParsing < self
220
+ end
221
+ end
222
+
223
+ #when error is dtk content
224
+ class DTKParse < self
225
+ end
226
+ end
227
+ end
228
+ end
data/lib/dsl.rb ADDED
@@ -0,0 +1,23 @@
1
+
2
+ module DtkCommon
3
+ module DSL
4
+
5
+ #TODO: just putting in hooks for errors and logs
6
+ #need to figure out how to hook calling library's errors
7
+ Error = ::DTK::Error
8
+ ErrorUsage = ::DTK::ErrorUsage
9
+
10
+ Log = ::DTK::Log
11
+ SimpleHashObject = ::DTK::Common::SimpleHashObject
12
+ module Aux
13
+ extend ::DTK::Common::AuxMixin
14
+ end
15
+
16
+ require File.expand_path('dsl/directory_parser', File.dirname(__FILE__))
17
+ require File.expand_path('dsl/file_parser', File.dirname(__FILE__))
18
+ end
19
+ end
20
+
21
+
22
+
23
+
@@ -0,0 +1,3 @@
1
+ module DtkCommon
2
+ VERSION = "0.5.11"
3
+ end
data/lib/dtk_common.rb ADDED
@@ -0,0 +1,36 @@
1
+ module DTK
2
+ module Common
3
+
4
+ # we are refering to dtk-common-repo folder here
5
+ POSSIBLE_COMMON_CORE_FOLDERS = ['dtk-common-repo','dtk-common-core']
6
+
7
+ require File.expand_path('require_first.rb', File.dirname(__FILE__))
8
+
9
+ # this gem needs dtk-common-repo to work we load it
10
+ unless is_gem_installed?('dtk-common-core')
11
+ dtk_common_core_folder = POSSIBLE_COMMON_CORE_FOLDERS.find do |folder|
12
+ path = File.join(File.dirname(__FILE__),'..','..',folder)
13
+ File.directory?(path)
14
+ end
15
+
16
+ if dtk_common_core_folder
17
+ require File.expand_path("../../#{dtk_common_core_folder}/lib/dtk_common_core.rb", File.dirname(__FILE__))
18
+ else
19
+ raise "Not able to find 'dtk-common-core' gem!"
20
+ end
21
+ else
22
+ # gem installed load from here
23
+ require 'dtk_common_core'
24
+ end
25
+
26
+
27
+ # we use sorting to establish deterministic behavior accross systems
28
+ # Dir.glob will not return list of files in same order each time is run, which led to some bug being present
29
+ # on some systems and not on the others
30
+ file_list = Dir.glob("#{File.dirname(__FILE__)}/**/*.rb").sort { |a,b| a <=> b }
31
+
32
+ file_list.each do |file|
33
+ require file unless file.include?('dtk-common.rb') || file.include?('file_access/') || file.include?('require_first.rb') || file.include?('postgres.rb') || file.include?('rugged/')
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,28 @@
1
+ require File.expand_path('common_patch',File.dirname(__FILE__))
2
+ require 'thread'
3
+
4
+ module DtkCommon
5
+ class DynmamicLoader
6
+ def self.load_and_return_adapter_class(adapter_type,adapter_name,opts={})
7
+ begin
8
+ caller_dir = caller.first.gsub(/\/[^\/]+$/,"")
9
+ Lock.synchronize{nested_require_with_caller_dir(caller_dir,"#{adapter_type}/adapters",adapter_name)}
10
+ rescue LoadError
11
+ raise Error.new("cannot find #{adapter_type} adapter (#{adapter_name})")
12
+ end
13
+ base_class = opts[:base_class] || DtkCommon.const_get(camel_case(adapter_type))
14
+ base_class.const_get(camel_case(adapter_name))
15
+ end
16
+
17
+ private
18
+ Lock = Mutex.new
19
+ def self.nested_require_with_caller_dir(caller_dir,dir,*files_x)
20
+ files = (files_x.first.kind_of?(Array) ? files_x.first : files_x)
21
+ files.each{|f|require File.expand_path("#{dir}/#{f}",caller_dir)}
22
+ end
23
+ def self.camel_case(x)
24
+ Aux.snake_to_camel_case(x.to_s)
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,14 @@
1
+ module DtkCommon
2
+ class GitRepo::Adapter::Rugged
3
+ class Blob < Obj
4
+ def initialize(repo_branch,rugged_blob)
5
+ super(repo_branch)
6
+ @rugged_blob = rugged_blob
7
+ end
8
+
9
+ def content()
10
+ lookup(@rugged_blob[:oid]).read_raw.data
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module DtkCommon
2
+ class GitRepo::Adapter::Rugged
3
+ class Commit < Obj
4
+ def initialize(repo_branch,rugged_commit)
5
+ super(repo_branch)
6
+ @rugged_commit = rugged_commit
7
+ end
8
+
9
+ def tree()
10
+ Tree.new(@repo_branch,@rugged_commit.tree)
11
+ end
12
+ end
13
+ end
14
+ end