dtk-common 0.5.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +5 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +16 -0
- data/LICENSE +674 -0
- data/README.md +36 -0
- data/dtk-common.gemspec +23 -0
- data/lib/common_patch.rb +16 -0
- data/lib/dsl/directory_parser/git.rb +39 -0
- data/lib/dsl/directory_parser/linux.rb +21 -0
- data/lib/dsl/directory_parser.rb +77 -0
- data/lib/dsl/file_parser/file_types/assembly/v2/assembly.rb +53 -0
- data/lib/dsl/file_parser/file_types/component_module_refs/v1/component_module_refs.rb +57 -0
- data/lib/dsl/file_parser.rb +228 -0
- data/lib/dsl.rb +23 -0
- data/lib/dtk-common/version.rb +3 -0
- data/lib/dtk_common.rb +36 -0
- data/lib/dynamic_loader.rb +28 -0
- data/lib/git_repo/adapters/rugged/blob.rb +14 -0
- data/lib/git_repo/adapters/rugged/commit.rb +14 -0
- data/lib/git_repo/adapters/rugged/common.rb +34 -0
- data/lib/git_repo/adapters/rugged/tree.rb +40 -0
- data/lib/git_repo/adapters/rugged.rb +45 -0
- data/lib/git_repo.rb +93 -0
- data/lib/gitolite/configuration.rb +35 -0
- data/lib/gitolite/errors.rb +5 -0
- data/lib/gitolite/grit/adapter.rb +101 -0
- data/lib/gitolite/grit/file_access.rb +51 -0
- data/lib/gitolite/init.rb +16 -0
- data/lib/gitolite/manager.rb +158 -0
- data/lib/gitolite/repo.rb +171 -0
- data/lib/gitolite/user_group.rb +98 -0
- data/lib/gitolite/utils.rb +59 -0
- data/lib/grit_adapter/file_access/diff.rb +82 -0
- data/lib/grit_adapter/file_access/status.rb +25 -0
- data/lib/grit_adapter/file_access.rb +296 -0
- data/lib/grit_adapter/object_access.rb +39 -0
- data/lib/grit_adapter.rb +212 -0
- data/lib/module_version.rb +12 -0
- data/lib/require_first.rb +18 -0
- data/rich_tests/README.md +1 -0
- data/rich_tests/dsl_test1.rb +14 -0
- data/rich_tests/dsl_test2.rb +10 -0
- data/rich_tests/dsl_test3.rb +17 -0
- data/rich_tests/dsl_test4.rb +25 -0
- data/rich_tests/fixtures/dsl_test1/sm-dtk-bootstrap/global_module_refs.json +2 -0
- data/rich_tests/fixtures/dsl_test1/sm-dtk-dtk/global_module_refs.json +7 -0
- data/rich_tests/fixtures/dsl_test1/sm-dtk-test_dtk/global_module_refs.json +8 -0
- data/rich_tests/fixtures/dsl_test1/sm-dtk-test_postgres/global_module_refs.json +7 -0
- data/rich_tests/fixtures/dsl_test1/sm-dtk-test_service/global_module_refs.json +5 -0
- data/rich_tests/fixtures/dsl_test1/sm-dtk-testv1/global_module_refs.json +14 -0
- data/rich_tests/fixtures/dsl_test1/sm-rich-app/global_module_refs.json +5 -0
- data/rich_tests/fixtures/dsl_test1/sm-rich-hdp/global_module_refs.json +3 -0
- data/rich_tests/fixtures/dsl_test1/sm-rich-test_dtk/global_module_refs.json +5 -0
- data/rich_tests/fixtures/dsl_test2/sm-dtk-dtk/assemblies/message_bus/assembly.json +23 -0
- data/rich_tests/fixtures/dsl_test2/sm-dtk-dtk/assemblies/repo_manager/assembly.json +26 -0
- data/rich_tests/fixtures/dsl_test2/sm-dtk-dtk/assemblies/server-nginx/assembly.json +64 -0
- data/rich_tests/fixtures/dsl_test2/sm-dtk-dtk/assemblies/server-on-one-node/assembly.json +47 -0
- data/rich_tests/fixtures/dsl_test2/sm-dtk-dtk/assemblies/t4/assembly.json +20 -0
- data/rich_tests/fixtures/dsl_test2/sm-dtk-dtk/global_module_refs.json +7 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/HEAD +1 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/config +4 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/description +1 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/hooks/applypatch-msg.sample +15 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/hooks/commit-msg.sample +24 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/hooks/post-update.sample +8 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/hooks/pre-applypatch.sample +14 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/hooks/pre-commit.sample +50 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/hooks/pre-rebase.sample +169 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/hooks/prepare-commit-msg.sample +36 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/hooks/update.sample +128 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/info/exclude +6 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/0a/5b6255a87c9e56d91557398aee730a2b3de745 +0 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/15/e78d7675db51c3f9e2cf154a350d82b12abc72 +0 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/18/7c41cd47b9c295da0cee128c888c95cf2bba1c +0 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/2a/17fb5b22b8108790435eb215ffe9d06829b841 +0 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/2e/8c9f8472cb0e9e2421e8b5c86ad981b728cdcf +0 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/3b/4646ef81ef99c0c7aa62c0a97e774761c7de54 +0 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/5c/498a06b1ef830203e4e04c1043c9d846a18a98 +0 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/72/b3afc0c009e42faa235784f29f43e336bceebd +0 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/78/2987dc58fb1f3bea00452b8727957115b51d6f +0 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/9b/7c5e8096a3a871c76ad179bc29c33ac5390683 +0 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/a5/b61c6608349cd87f3d53a13abc2d2f51772082 +0 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/b4/1fb4f136d54fc9277ff16d58d9361a03a91b23 +0 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/be/81c8c44a92dde5139fdd302d75eec027032c8b +0 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/objects/c3/88fbdcfe33840280aa119df6d01a782fdbdd60 +1 -0
- data/rich_tests/fixtures/dsl_test4/sm-dtk-dtk.git/refs/heads/master +1 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/HEAD +1 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/config +4 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/description +1 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/hooks/applypatch-msg.sample +15 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/hooks/commit-msg.sample +24 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/hooks/post-update.sample +8 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/hooks/pre-applypatch.sample +14 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/hooks/pre-commit.sample +50 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/hooks/pre-rebase.sample +169 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/hooks/prepare-commit-msg.sample +36 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/hooks/update.sample +128 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/info/exclude +6 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/objects/01/7d2a92efdefb513c266496c836112112c84b54 +0 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/objects/0c/6675dac950c9f2038c899a0026c60bc71b1986 +0 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/objects/12/7d8deca9a49974f887c594fc79804a2490c3c5 +0 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/objects/21/c65148298b7366019013c31ddc9e6c62770277 +0 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/objects/22/2c738a4abaebbd9ea3b6634fac902ae74479c4 +0 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/objects/25/560ef0476ffda4abf20b660955aac645b6ee2f +0 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/objects/4a/e421568785273757fe479236de426b80d1b658 +2 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/objects/60/465cb06c0cde161eff264d4c2a0535fc1e8bb2 +0 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/objects/63/7f0347d31dad180d6fc7f6720c187b05a8754c +0 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/objects/6c/54ab6443f1a24669a99f2ce1b43863be2e9fda +0 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/objects/82/c75b6fa64b746bd7f9cd7afe3c1e5bd53c430c +0 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/objects/86/ec2616845245b9c9355f768a1727bcdfb643ac +0 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/objects/93/ee8545d8f9681db9800cb11ec8aa72a8df8bd1 +0 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/objects/bc/65ddb77fef699933dfe16b79c769f7a9cc0afd +0 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/objects/d4/b1ee93110d823c5161f8cb954a6cf2e41345c1 +2 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4 +0 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/refs/heads/branch1 +1 -0
- data/rich_tests/fixtures/rugged_test1/repo1.git/refs/heads/master +1 -0
- data/rich_tests/rugged_test1.rb +16 -0
- data/test.rb +13 -0
- 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
|