dtk-common 0.5.11

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 (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
@@ -0,0 +1,171 @@
1
+ # This class is used to read gitolite repo config file. File is loaded and paramters are accessible via
2
+ # class members. After needed manipulation class will be saved as gitolite conf file.
3
+
4
+ module Gitolite
5
+ class Repo
6
+
7
+ include Utils
8
+
9
+ attr_accessor :repo_name, :rights_hash, :commit_messages, :user_groups, :logger
10
+
11
+ GIOLITE_ALL_GROUP = '@all'
12
+
13
+
14
+ #
15
+ # We check if there are users in addition to tenant with line,
16
+ # (repo_conf.rights_hash.values.flatten.size > 1)
17
+ # In case no, we do not give permission to tenant even
18
+ #
19
+
20
+ RepoConfTemplate = ::Erubis::Eruby.new <<-eos
21
+ include "groups-defs/*.conf"
22
+ repo <%= repo_conf.repo_name %>
23
+ <% if repo_conf.rights_hash.values.flatten.size > 1 %>
24
+ <% repo_conf.rights_hash.each do |k, v| %>
25
+ <% unless v.empty? %>
26
+ <%=k%> = <%=v.join(' ') %>
27
+ <% end %>
28
+ <% end %>
29
+ <% end %>
30
+ eos
31
+
32
+ class << self
33
+
34
+ def get_repo_type(repo_name)
35
+ repo_name.match(/\-\-cm\-\-/) ? 'component' : 'service'
36
+ end
37
+
38
+ end
39
+
40
+ def initialize(repo_name, configuration_, logger_, gitolite_path, gitolite_branch="master")
41
+ # IMPORTANT! Tenants user are always included with each module
42
+
43
+ @rights_hash = { 'R' => [], 'W' => [], 'RW' => ['@tenants'], 'RW+' => []}
44
+ @repo_name = repo_name
45
+ @user_groups = []
46
+ @commit_messages = []
47
+ @repo_conf_file_path = configuration_.repo_path(repo_name)
48
+ @repo_dir_path = configuration_.bare_repo_path(repo_name)
49
+ @gitolite_admin_repo ||= Git::FileAccess.new(gitolite_path, gitolite_branch)
50
+ @logger = logger_
51
+
52
+ if exists?
53
+ load_repo()
54
+ end
55
+ end
56
+
57
+ def remove_username(username)
58
+ @rights_hash.each do |k,v|
59
+ if v.include?(username)
60
+ v.delete(username)
61
+ @commit_messages << "Removed access rights ('#{k}') for user/group '#{username}'"
62
+ end
63
+ end
64
+ end
65
+
66
+ def remove_group(group_name)
67
+ remove_username("@#{group_name}")
68
+ end
69
+
70
+ def add_username_with_rights(username, access_rights)
71
+ # if we get nil that means that we have to delete user from its permission stack
72
+ if access_rights.nil?
73
+ return remove_username(username)
74
+ end
75
+
76
+ # Only make changes if this is new user/group
77
+ unless @rights_hash[access_rights.upcase].include?(username)
78
+ remove_username(username)
79
+
80
+ @rights_hash[access_rights.upcase] << username
81
+ @commit_messages << "Added access rights ('#{access_rights}') for user/group '#{username}', in repo '#{@repo_name}'"
82
+
83
+ # add to user groups if user group is added
84
+ if username.match(/^@/)
85
+ @user_groups << username
86
+ end
87
+ end
88
+ end
89
+
90
+ def add_user_group_with_rights(group_name, access_rights)
91
+ add_username_with_rights("@#{group_name}", access_rights)
92
+ end
93
+
94
+ def add_all_with_rights(access_rights)
95
+ add_username_with_rights(GIOLITE_ALL_GROUP, access_rights)
96
+ end
97
+
98
+ def branches
99
+ Git::FileAccess.new(@repo_dir_path).branches()
100
+ end
101
+
102
+ def exists?
103
+ !@gitolite_admin_repo.file_content(@repo_conf_file_path).nil?
104
+ end
105
+
106
+ def any_changes?
107
+ !@commit_messages.empty?
108
+ end
109
+
110
+ def commit_changes(override_commit_message = nil)
111
+ unless @commit_messages.empty?
112
+ content = file_content()
113
+ validate_gitolite_conf_file(content)
114
+
115
+ commit_msg = override_commit_message || @commit_messages.join(', ')
116
+
117
+ @gitolite_admin_repo.add_file(@repo_conf_file_path,content)
118
+ @gitolite_admin_repo.commit(commit_msg)
119
+
120
+ @logger.info(commit_msg)
121
+ else
122
+ @logger.info("There has been no changes on repo '#{@repo_name}' skipping gitolite commit.")
123
+ end
124
+ end
125
+
126
+ def file_content()
127
+ RepoConfTemplate.result(:repo_conf => self)
128
+ end
129
+
130
+ private
131
+
132
+ def load_repo()
133
+ raw_content = @gitolite_admin_repo.file_content(@repo_conf_file_path)
134
+
135
+ unless raw_content
136
+ raise ::Error::NotFound, "Configuration file for repo (#{repo_name}) does not exist"
137
+ end
138
+
139
+ raw_content.each_line do |l|
140
+ l.chomp!()
141
+ if l =~ /^[ ]*repo[ ]+([^ ]+)/
142
+ unless $1 == repo_name
143
+ raise Error::GitoliteParsing, "Parsing error: expected repo to be (${repo_name} in (#{l})"
144
+ end
145
+ elsif l =~ /[ ]*([^ ]+)[ ]*=[ ]*(.+)$/
146
+ access_rights = $1
147
+ users = $2
148
+ users.scan(/[^ ]+/) do |user|
149
+ unless access_rights.match(/R|W|RW|RW+/)
150
+ raise Error::GitoliteParsing, "Unexpected access rights while parsing file '#{access_rights}'"
151
+ end
152
+
153
+ @rights_hash[access_rights.to_s] << user unless @rights_hash[access_rights.to_s].include?(user)
154
+
155
+ # add to user groups if present
156
+ if user.match(/^@/)
157
+ @user_groups << user
158
+ end
159
+ end
160
+ elsif l.strip.empty? || l.strip().match(/^include/)
161
+ #no op
162
+ else
163
+ raise ::Error::GitoliteParsing, "Parsing repo error: (#{l})"
164
+ end
165
+ end
166
+ end
167
+
168
+
169
+ end
170
+
171
+ end
@@ -0,0 +1,98 @@
1
+ module Gitolite
2
+ class UserGroup
3
+
4
+ include Utils
5
+
6
+ GROUP_CONFIG_PATH = 'conf/group-defs'
7
+ # we need this to make sure that group is there but dummy name is needed to pass gitolite check
8
+ # DUMMY_USERNAME = 'r8_dummy_group_user'
9
+
10
+ UserGroupTemplate = Erubis::Eruby.new <<-eos
11
+ @<%=user_group.name%> = <%= user_group.members.empty? ? 'r8_dummy_group_user' : user_group.members.join(' ') %>
12
+ eos
13
+
14
+ attr_accessor :name, :members, :logger
15
+
16
+ def initialize(group_name, logger_, gitolite_path, gitolite_branch = "master")
17
+ @name = group_name
18
+ @members = []
19
+ @commit_messages = []
20
+ @group_file_path = File.join(GROUP_CONFIG_PATH, "#{@name}.conf")
21
+ @gitolite_admin_repo ||= Git::FileAccess.new(gitolite_path, gitolite_branch)
22
+ @logger = logger_
23
+
24
+ if exists?
25
+ load_group()
26
+ end
27
+ end
28
+
29
+ def load_group()
30
+ raw_content = @gitolite_admin_repo.file_content(@group_file_path)
31
+
32
+ unless raw_content
33
+ raise Gitolite::NotFound, "Configuration file for user group (#{@name}) does not exist"
34
+ end
35
+
36
+ raw_content.each_line do |l|
37
+ l.chomp!()
38
+ if l =~ /.*=(.+)$/
39
+ raw_members = $1
40
+ @members = raw_members.chomp().split(' ')
41
+ else
42
+ raise ::Error::GitoliteParsing, "Parsing groups error: (#{l})"
43
+ end
44
+ end
45
+ end
46
+
47
+ def exists?
48
+ !@gitolite_admin_repo.file_content(@group_file_path).nil?
49
+ end
50
+
51
+ def any_changes?
52
+ !@commit_messages.empty?
53
+ end
54
+
55
+ def add_git_usernames(array_of_usernames)
56
+ unless is_subset?(@members, array_of_usernames)
57
+ @members.concat(array_of_usernames)
58
+ @members.uniq!
59
+ @commit_messages << "Added users (#{array_of_usernames.join(', ')}) to group '#{@name}'"
60
+ end
61
+ end
62
+
63
+ def set_git_usernames(array_of_usernames)
64
+ # we clean current member since we are setting all gitusernames (not adding)
65
+ @members = []
66
+ add_git_usernames(array_of_usernames)
67
+ end
68
+
69
+ def remove_git_usernames(array_of_usernames)
70
+ if is_subset?(@members, array_of_usernames)
71
+ @members = @members - array_of_usernames
72
+ @commit_messages << "Removed users (#{array_of_usernames.join(', ')}) from group '#{@name}'"
73
+ end
74
+ end
75
+
76
+ def commit_changes(override_commit_message = nil)
77
+ # we check if there were changes
78
+ unless @commit_messages.empty?
79
+ content = file_content()
80
+
81
+ commit_msg = override_commit_message || @commit_messages.join(', ')
82
+
83
+ @gitolite_admin_repo.add_file(@group_file_path,content)
84
+ @gitolite_admin_repo.commit(commit_msg)
85
+
86
+ @logger.info(commit_msg)
87
+ else
88
+ @logger.info("There has been no changes on group '#{@name}' skipping gitolite commit.")
89
+ end
90
+ end
91
+
92
+
93
+ def file_content()
94
+ UserGroupTemplate.result(:user_group => self)
95
+ end
96
+
97
+ end
98
+ end
@@ -0,0 +1,59 @@
1
+ module Gitolite
2
+ module Utils
3
+ def validate_gitolite_conf_file(content)
4
+ # first line that is not empty
5
+ first_line = true
6
+
7
+ content.split(/\n|\r/).each_with_index do |line, i|
8
+ next if line.strip().empty?
9
+ next if line.strip().match(/^include/)
10
+
11
+ if first_line
12
+ raise_gitolite_error("Gitolite conf repo header is not valid", content) unless line.match(/repo *[a-zA-Z\-0-9]+/)
13
+ first_line = !first_line
14
+ next
15
+ end
16
+
17
+ # line must start with R/W/RW+
18
+ raise_gitolite_error("Gitolite conf repo line must start with R/RW/W(+)", content) unless line.match(/^ *(R|W|RW)\+? *=/m)
19
+
20
+ # must be matched only once
21
+ raise_gitolite_error("Gitolite conf repo line must containt ONLY one entry of R/RW/W(+)=", content) if line.scan(/(R|W|RW)\+? *=/).size > 1
22
+ end
23
+
24
+ return content
25
+ end
26
+
27
+ def raise_gitolite_error(msg, content)
28
+ Rails.logger.debug "Gitolite validation failed with: #{msg}"
29
+ Rails.logger.debug content
30
+ raise ::Error::GitoliteValidation.new(msg)
31
+ end
32
+
33
+ #
34
+ # Checks to see if array2 is subset of array1
35
+ #
36
+ def is_subset?(array1, array2)
37
+ result = array1 & array2
38
+ (array2.length == result.length)
39
+ end
40
+
41
+ #
42
+ # Converts permission to gitolite friendly permission
43
+ #
44
+ def gitolite_friendly(permission)
45
+ if permission.empty?
46
+ return nil
47
+ elsif permission.match(/^RWDP?/)
48
+ return "RW+"
49
+ elsif permission.match(/^RW/)
50
+ return "RW"
51
+ elsif permission.match(/^R/)
52
+ return 'R'
53
+ else
54
+ raise ::Error::NotSupported, "Not supported permission '#{permission}'!"
55
+ end
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,82 @@
1
+ class DTK::Common::GritAdapter::FileAccess
2
+ module DiffMixin
3
+ def diff(*args)
4
+ diff_comamnd_args =
5
+ case args.size
6
+ when 1 then [@branch,args[0]]
7
+ when 2 then args
8
+ else raise Error.new("diff must have 1 or 2 arguments")
9
+ end
10
+ grit_diffs = @grit_repo.diff(*diff_comamnd_args)
11
+ array_diff_hashes = grit_diffs.map do |diff|
12
+ Diff::Attributes.inject(Hash.new) do |h,a|
13
+ val = diff.send(a)
14
+ val ? h.merge(a => val) : h
15
+ end
16
+ end
17
+ Diffs.new(array_diff_hashes)
18
+ end
19
+
20
+ class Diffs < Array
21
+
22
+ class Summary < ::DTK::Common::SimpleHashObject
23
+ def any_diffs?()
24
+ !keys().empty?
25
+ end
26
+ def any_added_or_deleted_files?()
27
+ !!(self[:files_renamed] or self[:files_added] or self[:files_deleted])
28
+ end
29
+
30
+ def meta_file_changed?()
31
+ self[:files_modified] and !!self[:files_modified].find{|r|r[:path] =~ /^r8meta/}
32
+ end
33
+
34
+ #note: in paths_to_add and paths_to_delete rename appears both since rename can be accomplsihed by a add + a delete
35
+ def paths_to_add()
36
+ (self[:files_added]||[]).map{|r|r[:path]} + (self[:files_renamed]||[]).map{|r|r[:new_path]}
37
+ end
38
+ def paths_to_delete()
39
+ (self[:files_deleted]||[]).map{|r|r[:path]} + (self[:files_renamed]||[]).map{|r|r[:old_path]}
40
+ end
41
+ end
42
+
43
+ def initialize(array_diff_hashes)
44
+ super(array_diff_hashes.map{|hash|Diff.new(hash)})
45
+ end
46
+
47
+ #returns a hash with keys :file_renamed, :file_added, :file_deleted, :file_modified
48
+ def ret_summary()
49
+ [:renamed,:added,:deleted,:modified].inject(Summary.new) do |h,cnd|
50
+ res = map{|diff|diff.send("file_#{cnd}".to_sym)}.compact
51
+ res.empty? ? h : h.merge("files_#{cnd}".to_sym => res)
52
+ end
53
+ end
54
+ end
55
+
56
+ class Diff
57
+ Attributes = [:new_file,:renamed_file,:deleted_file,:a_path,:b_path,:diff]
58
+ AttributeAssignFn = Attributes.inject(Hash.new){|h,a|h.merge(a => "#{a}=".to_sym)}
59
+ def initialize(hash_input)
60
+ hash_input.each{|a,v|send(AttributeAssignFn[a],v)}
61
+ end
62
+
63
+ def file_added()
64
+ @new_file && {:path => @a_path}
65
+ end
66
+
67
+ def file_renamed()
68
+ @renamed_file && {:old_path => @b_path, :new_path => @a_path}
69
+ end
70
+
71
+ def file_deleted()
72
+ @deleted_file && {:path => @a_path}
73
+ end
74
+
75
+ def file_modified()
76
+ ((@new_file or @deleted_file or @renamed_file) ? nil : true) && {:path => @a_path}
77
+ end
78
+ private
79
+ attr_writer(*Attributes)
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,25 @@
1
+ module DTK::Common; class GritAdapter; class FileAccess
2
+ module StatusMixin
3
+ def status()
4
+ chdir_and_checkout do
5
+ Status.new(@grit_repo.status)
6
+ end
7
+ end
8
+
9
+ class Status < Hash
10
+ def initialize(grit_status_obj)
11
+ super()
12
+ FileStates.each do |file_state|
13
+ paths_with_file_state = grit_status_obj.send(file_state).map{|info|info[1].path}
14
+ self[file_state] = paths_with_file_state unless paths_with_file_state.empty?
15
+ end
16
+ end
17
+
18
+ def any_changes?()
19
+ !!FileStates.find{|fs|self[fs]}
20
+ end
21
+
22
+ FileStates = [:added,:deleted,:changed,:untracked]
23
+ end
24
+ end
25
+ end; end; end