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
@@ -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