dtk-common 0.11.0 → 0.12.0
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.
- checksums.yaml +4 -4
- data/dtk-common.gemspec +2 -2
- data/lib/dtk-common/version.rb +18 -18
- data/lib/gitolite/configuration.rb +35 -35
- data/lib/gitolite/grit/adapter.rb +107 -107
- data/lib/gitolite/repo.rb +191 -191
- data/lib/grit_adapter/file_access/diff.rb +82 -82
- data/lib/require_first.rb +17 -18
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a6ee215bd281a690d770c8ec9d33717d836c84c8
|
4
|
+
data.tar.gz: 00aa11973259a8c7de948e8576a34622358dc2a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1c512a8f08bfe36e5903f5befe69ac2b6c871ef19453ef8e980b430347526d03414da95c8650575251589fd62739e4b6d6c0903c1c7e762914564cce108fb86
|
7
|
+
data.tar.gz: f013a8a42b497211bb91f608b05197fd0d8a6ed05dc4538fa5dc5ba02a51ab2891da77670b9f484cc1f5c4f6da137f5b56be95c2804bfe1b730884d8651909a4
|
data/dtk-common.gemspec
CHANGED
@@ -16,9 +16,9 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.version = DtkCommon::VERSION
|
17
17
|
|
18
18
|
gem.add_dependency 'rugged','~> 0.17.0.b7'
|
19
|
-
gem.add_dependency 'dtk-common-core','0.
|
19
|
+
gem.add_dependency 'dtk-common-core', '0.12.0'
|
20
20
|
gem.add_dependency 'colorize','~> 0.5.8'
|
21
|
-
gem.add_dependency 'grit', '~> 2.
|
21
|
+
gem.add_dependency 'gitlab-grit', '~> 2.8'
|
22
22
|
gem.add_dependency 'erubis', '~> 2.7'
|
23
23
|
# gem.add_dependency 'sequel','~> 3.40.0'
|
24
24
|
# gem.add_dependency 'rdoc','~> 3.12'
|
data/lib/dtk-common/version.rb
CHANGED
@@ -1,20 +1,20 @@
|
|
1
|
-
#
|
2
|
-
# Copyright (C) 2010-2016 dtk contributors
|
3
|
-
#
|
4
|
-
# This file is part of the dtk project.
|
5
|
-
#
|
6
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
-
# you may not use this file except in compliance with the License.
|
8
|
-
# You may obtain a copy of the License at
|
9
|
-
#
|
10
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
12
|
-
# Unless required by applicable law or agreed to in writing, software
|
13
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
-
# See the License for the specific language governing permissions and
|
16
|
-
# limitations under the License.
|
17
|
-
#
|
1
|
+
#
|
2
|
+
# Copyright (C) 2010-2016 dtk contributors
|
3
|
+
#
|
4
|
+
# This file is part of the dtk project.
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
18
|
module DtkCommon
|
19
|
-
VERSION="0.
|
19
|
+
VERSION="0.12.0"
|
20
20
|
end
|
@@ -15,38 +15,38 @@
|
|
15
15
|
# See the License for the specific language governing permissions and
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
|
-
module Gitolite
|
19
|
-
class Configuration
|
20
|
-
|
21
|
-
attr_reader :repositories_path, :user_group_path, :keydir_path, :home_dir
|
22
|
-
|
23
|
-
def initialize(
|
24
|
-
repo_path_ = 'conf/repo-configs',
|
25
|
-
user_group_path_ = 'conf/group-defs',
|
26
|
-
keydir_path_ = 'keydir',
|
27
|
-
home_dir_ = nil
|
28
|
-
)
|
29
|
-
|
30
|
-
@repositories_path = repo_path_
|
31
|
-
@user_group_path = user_group_path_
|
32
|
-
@keydir_path = keydir_path_
|
33
|
-
@home_dir = home_dir_
|
34
|
-
end
|
35
|
-
|
36
|
-
def user_key_path(username)
|
37
|
-
"#{@keydir_path}/#{username}.pub"
|
38
|
-
end
|
39
|
-
|
40
|
-
def user_group_path(group_name)
|
41
|
-
"#{@user_group_path}/#{group_name}.conf"
|
42
|
-
end
|
43
|
-
|
44
|
-
def repo_path(repo_name)
|
45
|
-
"#{@repositories_path}/#{repo_name}.conf"
|
46
|
-
end
|
47
|
-
|
48
|
-
def bare_repo_path(repo_name)
|
49
|
-
"#{@home_dir}/repositories/#{repo_name}.git"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
18
|
+
module Gitolite
|
19
|
+
class Configuration
|
20
|
+
|
21
|
+
attr_reader :repositories_path, :user_group_path, :keydir_path, :home_dir
|
22
|
+
|
23
|
+
def initialize(
|
24
|
+
repo_path_ = 'conf/repo-configs',
|
25
|
+
user_group_path_ = 'conf/group-defs',
|
26
|
+
keydir_path_ = 'keydir',
|
27
|
+
home_dir_ = nil
|
28
|
+
)
|
29
|
+
|
30
|
+
@repositories_path = repo_path_
|
31
|
+
@user_group_path = user_group_path_
|
32
|
+
@keydir_path = keydir_path_
|
33
|
+
@home_dir = home_dir_
|
34
|
+
end
|
35
|
+
|
36
|
+
def user_key_path(username)
|
37
|
+
"#{@keydir_path}/#{username}.pub"
|
38
|
+
end
|
39
|
+
|
40
|
+
def user_group_path(group_name)
|
41
|
+
"#{@user_group_path}/#{group_name}.conf"
|
42
|
+
end
|
43
|
+
|
44
|
+
def repo_path(repo_name)
|
45
|
+
"#{@repositories_path}/#{repo_name}.conf"
|
46
|
+
end
|
47
|
+
|
48
|
+
def bare_repo_path(repo_name)
|
49
|
+
"#{@home_dir}/repositories/#{repo_name}.git"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -15,110 +15,110 @@
|
|
15
15
|
# See the License for the specific language governing permissions and
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
|
-
require 'grit'
|
19
|
-
|
20
|
-
module Gitolite
|
21
|
-
module Git
|
22
|
-
class Adapter
|
23
|
-
|
24
|
-
DEFAULT_BRANCH = 'master'
|
25
|
-
|
26
|
-
def initialize(repo_dir,branch=DEFAULT_BRANCH)
|
27
|
-
@repo_dir = repo_dir
|
28
|
-
@branch = branch
|
29
|
-
@grit_repo = nil
|
30
|
-
begin
|
31
|
-
@grit_repo = ::Grit::Repo.new(repo_dir)
|
32
|
-
rescue ::Grit::NoSuchPathError
|
33
|
-
repo_name = repo_dir.split("/").last.gsub("\.git","")
|
34
|
-
#TODO: change to usage error
|
35
|
-
raise ::Gitolite::NotFound, "Repo (#{repo_name}) - path '#{repo_dir}' does not exist"
|
36
|
-
rescue => e
|
37
|
-
raise e
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def branches()
|
42
|
-
@grit_repo.branches.map{|h|h.name}
|
43
|
-
end
|
44
|
-
|
45
|
-
def ls_r(depth=nil,opts={})
|
46
|
-
tree_contents = tree.contents
|
47
|
-
ls_r_aux(depth,tree_contents,opts)
|
48
|
-
end
|
49
|
-
|
50
|
-
def path_exists?(path)
|
51
|
-
not (tree/path).nil?
|
52
|
-
end
|
53
|
-
|
54
|
-
def file_content(path)
|
55
|
-
tree_or_blob = tree/path
|
56
|
-
tree_or_blob && tree_or_blob.kind_of?(::Grit::Blob) && tree_or_blob.data
|
57
|
-
end
|
58
|
-
|
59
|
-
def file_content_and_size(path)
|
60
|
-
tree_or_blob = tree/path
|
61
|
-
return nil unless tree_or_blob
|
62
|
-
{ :data => tree_or_blob.data, :size => tree_or_blob.size }
|
63
|
-
end
|
64
|
-
|
65
|
-
def push()
|
66
|
-
Git_command__push_mutex.synchronize do
|
67
|
-
git_command(:push,"origin", "#{@branch}:refs/heads/#{@branch}")
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def push_to_mirror_repo(mirror_repo)
|
72
|
-
git_command(:push,"--mirror",mirror_repo)
|
73
|
-
end
|
74
|
-
|
75
|
-
Git_command__push_mutex = Mutex.new
|
76
|
-
|
77
|
-
def pull()
|
78
|
-
git_command(:pull,"origin",@branch)
|
79
|
-
end
|
80
|
-
|
81
|
-
private
|
82
|
-
def tree()
|
83
|
-
@grit_repo.tree(@branch)
|
84
|
-
end
|
85
|
-
|
86
|
-
def ls_r_aux(depth,tree_contents,opts={})
|
87
|
-
ret = Array.new
|
88
|
-
return ret if tree_contents.empty?
|
89
|
-
if depth == 1
|
90
|
-
ret = tree_contents.map do |tc|
|
91
|
-
if opts[:file_only]
|
92
|
-
tc.kind_of?(::Grit::Blob) && tc.name
|
93
|
-
elsif opts[:directory_only]
|
94
|
-
tc.kind_of?(::Grit::Tree) && tc.name
|
95
|
-
else
|
96
|
-
tc.name
|
97
|
-
end
|
98
|
-
end.compact
|
99
|
-
return ret
|
100
|
-
end
|
101
|
-
|
102
|
-
tree_contents.each do |tc|
|
103
|
-
if tc.kind_of?(::Grit::Blob)
|
104
|
-
unless opts[:directory_only]
|
105
|
-
ret << tc.name
|
106
|
-
end
|
107
|
-
else
|
108
|
-
dir_name = tc.name
|
109
|
-
ret += ls_r_aux(depth && depth-1,tc.contents).map{|r|"#{dir_name}/#{r}"}
|
110
|
-
end
|
111
|
-
end
|
112
|
-
ret
|
113
|
-
end
|
114
|
-
|
115
|
-
def git_command(cmd,*args)
|
116
|
-
@grit_repo.git.send(cmd, cmd_opts(),*args)
|
117
|
-
end
|
118
|
-
def cmd_opts()
|
119
|
-
{:raise => true, :timeout => 60}
|
120
|
-
end
|
121
|
-
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
18
|
+
require 'grit'
|
19
|
+
|
20
|
+
module Gitolite
|
21
|
+
module Git
|
22
|
+
class Adapter
|
23
|
+
|
24
|
+
DEFAULT_BRANCH = 'master'
|
25
|
+
|
26
|
+
def initialize(repo_dir,branch=DEFAULT_BRANCH)
|
27
|
+
@repo_dir = repo_dir
|
28
|
+
@branch = branch
|
29
|
+
@grit_repo = nil
|
30
|
+
begin
|
31
|
+
@grit_repo = ::Grit::Repo.new(repo_dir)
|
32
|
+
rescue ::Grit::NoSuchPathError
|
33
|
+
repo_name = repo_dir.split("/").last.gsub("\.git","")
|
34
|
+
#TODO: change to usage error
|
35
|
+
raise ::Gitolite::NotFound, "Repo (#{repo_name}) - path '#{repo_dir}' does not exist"
|
36
|
+
rescue => e
|
37
|
+
raise e
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def branches()
|
42
|
+
@grit_repo.branches.map{|h|h.name}
|
43
|
+
end
|
44
|
+
|
45
|
+
def ls_r(depth=nil,opts={})
|
46
|
+
tree_contents = tree.contents
|
47
|
+
ls_r_aux(depth,tree_contents,opts)
|
48
|
+
end
|
49
|
+
|
50
|
+
def path_exists?(path)
|
51
|
+
not (tree/path).nil?
|
52
|
+
end
|
53
|
+
|
54
|
+
def file_content(path)
|
55
|
+
tree_or_blob = tree/path
|
56
|
+
tree_or_blob && tree_or_blob.kind_of?(::Grit::Blob) && tree_or_blob.data
|
57
|
+
end
|
58
|
+
|
59
|
+
def file_content_and_size(path)
|
60
|
+
tree_or_blob = tree/path
|
61
|
+
return nil unless tree_or_blob
|
62
|
+
{ :data => tree_or_blob.data, :size => tree_or_blob.size }
|
63
|
+
end
|
64
|
+
|
65
|
+
def push()
|
66
|
+
Git_command__push_mutex.synchronize do
|
67
|
+
git_command(:push,"origin", "#{@branch}:refs/heads/#{@branch}")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def push_to_mirror_repo(mirror_repo)
|
72
|
+
git_command(:push,"--mirror",mirror_repo)
|
73
|
+
end
|
74
|
+
|
75
|
+
Git_command__push_mutex = Mutex.new
|
76
|
+
|
77
|
+
def pull()
|
78
|
+
git_command(:pull,"origin",@branch)
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
def tree()
|
83
|
+
@grit_repo.tree(@branch)
|
84
|
+
end
|
85
|
+
|
86
|
+
def ls_r_aux(depth,tree_contents,opts={})
|
87
|
+
ret = Array.new
|
88
|
+
return ret if tree_contents.empty?
|
89
|
+
if depth == 1
|
90
|
+
ret = tree_contents.map do |tc|
|
91
|
+
if opts[:file_only]
|
92
|
+
tc.kind_of?(::Grit::Blob) && tc.name
|
93
|
+
elsif opts[:directory_only]
|
94
|
+
tc.kind_of?(::Grit::Tree) && tc.name
|
95
|
+
else
|
96
|
+
tc.name
|
97
|
+
end
|
98
|
+
end.compact
|
99
|
+
return ret
|
100
|
+
end
|
101
|
+
|
102
|
+
tree_contents.each do |tc|
|
103
|
+
if tc.kind_of?(::Grit::Blob)
|
104
|
+
unless opts[:directory_only]
|
105
|
+
ret << tc.name
|
106
|
+
end
|
107
|
+
else
|
108
|
+
dir_name = tc.name
|
109
|
+
ret += ls_r_aux(depth && depth-1,tc.contents).map{|r|"#{dir_name}/#{r}"}
|
110
|
+
end
|
111
|
+
end
|
112
|
+
ret
|
113
|
+
end
|
114
|
+
|
115
|
+
def git_command(cmd,*args)
|
116
|
+
@grit_repo.git.send(cmd, cmd_opts(),*args)
|
117
|
+
end
|
118
|
+
def cmd_opts()
|
119
|
+
{:raise => true, :timeout => 60}
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
data/lib/gitolite/repo.rb
CHANGED
@@ -15,194 +15,194 @@
|
|
15
15
|
# See the License for the specific language governing permissions and
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
|
-
# This class is used to read gitolite repo config file. File is loaded and paramters are accessible via
|
19
|
-
# class members. After needed manipulation class will be saved as gitolite conf file.
|
20
|
-
|
21
|
-
module Gitolite
|
22
|
-
class Repo
|
23
|
-
|
24
|
-
include Utils
|
25
|
-
|
26
|
-
attr_accessor :repo_name, :rights_hash, :commit_messages, :user_groups, :logger
|
27
|
-
attr_reader :repo_dir_path
|
28
|
-
|
29
|
-
GIOLITE_ALL_GROUP = '@all'
|
30
|
-
|
31
|
-
#
|
32
|
-
# We check if there are users in addition to tenant with line,
|
33
|
-
# (repo_conf.rights_hash.values.flatten.size > 1)
|
34
|
-
# In case no, we do not give permission to tenant even
|
35
|
-
#
|
36
|
-
|
37
|
-
RepoConfTemplate = ::Erubis::Eruby.new <<-eos
|
38
|
-
include "groups-defs/*.conf"
|
39
|
-
repo <%= repo_conf.repo_name %>
|
40
|
-
<% if repo_conf.rights_hash.values.flatten.size > 1 %>
|
41
|
-
<% repo_conf.rights_hash.each do |k, v| %>
|
42
|
-
<% unless v.empty? %>
|
43
|
-
<%=k%> = <%=v.join(' ') %>
|
44
|
-
<% end %>
|
45
|
-
<% end %>
|
46
|
-
<% end %>
|
47
|
-
eos
|
48
|
-
|
49
|
-
class << self
|
50
|
-
|
51
|
-
def get_repo_type(repo_name)
|
52
|
-
repo_name.match(/\-\-cm\-\-/) ? 'component' : 'service'
|
53
|
-
end
|
54
|
-
|
55
|
-
end
|
56
|
-
|
57
|
-
def initialize(repo_name, configuration_, logger_, gitolite_path, gitolite_branch = 'master')
|
58
|
-
@rights_hash = { 'R' => [], 'W' => [], 'RW' => [], 'RW+' => []}
|
59
|
-
@repo_name = repo_name
|
60
|
-
@user_groups = []
|
61
|
-
@commit_messages = []
|
62
|
-
@repo_conf_file_path = configuration_.repo_path(repo_name)
|
63
|
-
@repo_dir_path = configuration_.bare_repo_path(repo_name)
|
64
|
-
@gitolite_admin_repo ||= Git::FileAccess.new(gitolite_path, gitolite_branch)
|
65
|
-
@logger = logger_
|
66
|
-
|
67
|
-
if exists?
|
68
|
-
load_repo()
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def rights_for_username(username)
|
73
|
-
@rights_hash.each do |k,v|
|
74
|
-
if v.include?(username)
|
75
|
-
return k
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
return nil
|
80
|
-
end
|
81
|
-
|
82
|
-
def remove_username(username)
|
83
|
-
@rights_hash.each do |k,v|
|
84
|
-
if v.include?(username)
|
85
|
-
v.delete(username)
|
86
|
-
@commit_messages << "Removed access rights ('#{k}') for user/group '#{username}'"
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
def remove_group(group_name)
|
92
|
-
remove_username("@#{group_name}")
|
93
|
-
end
|
94
|
-
|
95
|
-
def add_username_with_rights(username, access_rights)
|
96
|
-
# if we get nil that means that we have to delete user from its permission stack
|
97
|
-
if access_rights.nil?
|
98
|
-
return remove_username(username)
|
99
|
-
end
|
100
|
-
|
101
|
-
# Only make changes if this is new user/group
|
102
|
-
unless @rights_hash[access_rights.upcase].include?(username)
|
103
|
-
remove_username(username)
|
104
|
-
|
105
|
-
@rights_hash[access_rights.upcase] << username
|
106
|
-
@commit_messages << "Added access rights ('#{access_rights}') for user/group '#{username}', in repo '#{@repo_name}'"
|
107
|
-
|
108
|
-
# add to user groups if user group is added
|
109
|
-
if username.match(/^@/)
|
110
|
-
@user_groups << username
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
def add_user_group_with_rights(group_name, access_rights)
|
116
|
-
add_username_with_rights("@#{group_name}", access_rights)
|
117
|
-
end
|
118
|
-
|
119
|
-
def add_all_with_rights(access_rights)
|
120
|
-
add_username_with_rights(GIOLITE_ALL_GROUP, access_rights)
|
121
|
-
end
|
122
|
-
|
123
|
-
def branches
|
124
|
-
Git::FileAccess.new(@repo_dir_path).branches()
|
125
|
-
end
|
126
|
-
|
127
|
-
def exists?
|
128
|
-
!@gitolite_admin_repo.file_content(@repo_conf_file_path).nil?
|
129
|
-
end
|
130
|
-
|
131
|
-
def any_changes?
|
132
|
-
!@commit_messages.empty?
|
133
|
-
end
|
134
|
-
|
135
|
-
def commit_changes(override_commit_message = nil)
|
136
|
-
unless @commit_messages.empty?
|
137
|
-
content = configuration_content()
|
138
|
-
validate_gitolite_conf_file(content)
|
139
|
-
|
140
|
-
commit_msg = override_commit_message || @commit_messages.join(', ')
|
141
|
-
|
142
|
-
@gitolite_admin_repo.add_file(@repo_conf_file_path,content)
|
143
|
-
@gitolite_admin_repo.commit(commit_msg)
|
144
|
-
|
145
|
-
@logger.info(commit_msg)
|
146
|
-
else
|
147
|
-
@logger.info("There has been no changes on repo '#{@repo_name}' skipping gitolite commit.")
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
def file_content(path, branch=Git::Adapter::DEFAULT_BRANCH)
|
152
|
-
Git::FileAccess.new(@repo_dir_path, branch).file_content(path)
|
153
|
-
end
|
154
|
-
|
155
|
-
def file_content_and_size(path, branch=Git::Adapter::DEFAULT_BRANCH)
|
156
|
-
Git::FileAccess.new(@repo_dir_path, branch).file_content_and_size(path)
|
157
|
-
end
|
158
|
-
|
159
|
-
def file_list(depth=nil, branch=Git::Adapter::DEFAULT_BRANCH)
|
160
|
-
Git::FileAccess.new(@repo_dir_path, branch).ls_r(depth)
|
161
|
-
end
|
162
|
-
|
163
|
-
private
|
164
|
-
|
165
|
-
def configuration_content()
|
166
|
-
RepoConfTemplate.result(:repo_conf => self)
|
167
|
-
end
|
168
|
-
|
169
|
-
def load_repo()
|
170
|
-
raw_content = @gitolite_admin_repo.file_content(@repo_conf_file_path)
|
171
|
-
|
172
|
-
unless raw_content
|
173
|
-
raise ::Error::NotFound, "Configuration file for repo (#{repo_name}) does not exist"
|
174
|
-
end
|
175
|
-
|
176
|
-
raw_content.each_line do |l|
|
177
|
-
l.chomp!()
|
178
|
-
if l =~ /^[ ]*repo[ ]+([^ ]+)/
|
179
|
-
unless $1 == repo_name
|
180
|
-
raise Error::GitoliteParsing, "Parsing error: expected repo to be (${repo_name} in (#{l})"
|
181
|
-
end
|
182
|
-
elsif l =~ /[ ]*([^ ]+)[ ]*=[ ]*(.+)$/
|
183
|
-
access_rights = $1
|
184
|
-
users = $2
|
185
|
-
users.scan(/[^ ]+/) do |user|
|
186
|
-
unless access_rights.match(/R|W|RW|RW+/)
|
187
|
-
raise Error::GitoliteParsing, "Unexpected access rights while parsing file '#{access_rights}'"
|
188
|
-
end
|
189
|
-
|
190
|
-
@rights_hash[access_rights.to_s] << user unless @rights_hash[access_rights.to_s].include?(user)
|
191
|
-
|
192
|
-
# add to user groups if present
|
193
|
-
if user.match(/^@/)
|
194
|
-
@user_groups << user
|
195
|
-
end
|
196
|
-
end
|
197
|
-
elsif l.strip.empty? || l.strip().match(/^include/)
|
198
|
-
#no op
|
199
|
-
else
|
200
|
-
raise ::Error::GitoliteParsing, "Parsing repo error: (#{l})"
|
201
|
-
end
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
|
206
|
-
end
|
207
|
-
|
208
|
-
end
|
18
|
+
# This class is used to read gitolite repo config file. File is loaded and paramters are accessible via
|
19
|
+
# class members. After needed manipulation class will be saved as gitolite conf file.
|
20
|
+
|
21
|
+
module Gitolite
|
22
|
+
class Repo
|
23
|
+
|
24
|
+
include Utils
|
25
|
+
|
26
|
+
attr_accessor :repo_name, :rights_hash, :commit_messages, :user_groups, :logger
|
27
|
+
attr_reader :repo_dir_path
|
28
|
+
|
29
|
+
GIOLITE_ALL_GROUP = '@all'
|
30
|
+
|
31
|
+
#
|
32
|
+
# We check if there are users in addition to tenant with line,
|
33
|
+
# (repo_conf.rights_hash.values.flatten.size > 1)
|
34
|
+
# In case no, we do not give permission to tenant even
|
35
|
+
#
|
36
|
+
|
37
|
+
RepoConfTemplate = ::Erubis::Eruby.new <<-eos
|
38
|
+
include "groups-defs/*.conf"
|
39
|
+
repo <%= repo_conf.repo_name %>
|
40
|
+
<% if repo_conf.rights_hash.values.flatten.size > 1 %>
|
41
|
+
<% repo_conf.rights_hash.each do |k, v| %>
|
42
|
+
<% unless v.empty? %>
|
43
|
+
<%=k%> = <%=v.join(' ') %>
|
44
|
+
<% end %>
|
45
|
+
<% end %>
|
46
|
+
<% end %>
|
47
|
+
eos
|
48
|
+
|
49
|
+
class << self
|
50
|
+
|
51
|
+
def get_repo_type(repo_name)
|
52
|
+
repo_name.match(/\-\-cm\-\-/) ? 'component' : 'service'
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
def initialize(repo_name, configuration_, logger_, gitolite_path, gitolite_branch = 'master')
|
58
|
+
@rights_hash = { 'R' => [], 'W' => [], 'RW' => [], 'RW+' => []}
|
59
|
+
@repo_name = repo_name
|
60
|
+
@user_groups = []
|
61
|
+
@commit_messages = []
|
62
|
+
@repo_conf_file_path = configuration_.repo_path(repo_name)
|
63
|
+
@repo_dir_path = configuration_.bare_repo_path(repo_name)
|
64
|
+
@gitolite_admin_repo ||= Git::FileAccess.new(gitolite_path, gitolite_branch)
|
65
|
+
@logger = logger_
|
66
|
+
|
67
|
+
if exists?
|
68
|
+
load_repo()
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def rights_for_username(username)
|
73
|
+
@rights_hash.each do |k,v|
|
74
|
+
if v.include?(username)
|
75
|
+
return k
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
return nil
|
80
|
+
end
|
81
|
+
|
82
|
+
def remove_username(username)
|
83
|
+
@rights_hash.each do |k,v|
|
84
|
+
if v.include?(username)
|
85
|
+
v.delete(username)
|
86
|
+
@commit_messages << "Removed access rights ('#{k}') for user/group '#{username}'"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def remove_group(group_name)
|
92
|
+
remove_username("@#{group_name}")
|
93
|
+
end
|
94
|
+
|
95
|
+
def add_username_with_rights(username, access_rights)
|
96
|
+
# if we get nil that means that we have to delete user from its permission stack
|
97
|
+
if access_rights.nil?
|
98
|
+
return remove_username(username)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Only make changes if this is new user/group
|
102
|
+
unless @rights_hash[access_rights.upcase].include?(username)
|
103
|
+
remove_username(username)
|
104
|
+
|
105
|
+
@rights_hash[access_rights.upcase] << username
|
106
|
+
@commit_messages << "Added access rights ('#{access_rights}') for user/group '#{username}', in repo '#{@repo_name}'"
|
107
|
+
|
108
|
+
# add to user groups if user group is added
|
109
|
+
if username.match(/^@/)
|
110
|
+
@user_groups << username
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def add_user_group_with_rights(group_name, access_rights)
|
116
|
+
add_username_with_rights("@#{group_name}", access_rights)
|
117
|
+
end
|
118
|
+
|
119
|
+
def add_all_with_rights(access_rights)
|
120
|
+
add_username_with_rights(GIOLITE_ALL_GROUP, access_rights)
|
121
|
+
end
|
122
|
+
|
123
|
+
def branches
|
124
|
+
Git::FileAccess.new(@repo_dir_path).branches()
|
125
|
+
end
|
126
|
+
|
127
|
+
def exists?
|
128
|
+
!@gitolite_admin_repo.file_content(@repo_conf_file_path).nil?
|
129
|
+
end
|
130
|
+
|
131
|
+
def any_changes?
|
132
|
+
!@commit_messages.empty?
|
133
|
+
end
|
134
|
+
|
135
|
+
def commit_changes(override_commit_message = nil)
|
136
|
+
unless @commit_messages.empty?
|
137
|
+
content = configuration_content()
|
138
|
+
validate_gitolite_conf_file(content)
|
139
|
+
|
140
|
+
commit_msg = override_commit_message || @commit_messages.join(', ')
|
141
|
+
|
142
|
+
@gitolite_admin_repo.add_file(@repo_conf_file_path,content)
|
143
|
+
@gitolite_admin_repo.commit(commit_msg)
|
144
|
+
|
145
|
+
@logger.info(commit_msg)
|
146
|
+
else
|
147
|
+
@logger.info("There has been no changes on repo '#{@repo_name}' skipping gitolite commit.")
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def file_content(path, branch=Git::Adapter::DEFAULT_BRANCH)
|
152
|
+
Git::FileAccess.new(@repo_dir_path, branch).file_content(path)
|
153
|
+
end
|
154
|
+
|
155
|
+
def file_content_and_size(path, branch=Git::Adapter::DEFAULT_BRANCH)
|
156
|
+
Git::FileAccess.new(@repo_dir_path, branch).file_content_and_size(path)
|
157
|
+
end
|
158
|
+
|
159
|
+
def file_list(depth=nil, branch=Git::Adapter::DEFAULT_BRANCH)
|
160
|
+
Git::FileAccess.new(@repo_dir_path, branch).ls_r(depth)
|
161
|
+
end
|
162
|
+
|
163
|
+
private
|
164
|
+
|
165
|
+
def configuration_content()
|
166
|
+
RepoConfTemplate.result(:repo_conf => self)
|
167
|
+
end
|
168
|
+
|
169
|
+
def load_repo()
|
170
|
+
raw_content = @gitolite_admin_repo.file_content(@repo_conf_file_path)
|
171
|
+
|
172
|
+
unless raw_content
|
173
|
+
raise ::Error::NotFound, "Configuration file for repo (#{repo_name}) does not exist"
|
174
|
+
end
|
175
|
+
|
176
|
+
raw_content.each_line do |l|
|
177
|
+
l.chomp!()
|
178
|
+
if l =~ /^[ ]*repo[ ]+([^ ]+)/
|
179
|
+
unless $1 == repo_name
|
180
|
+
raise Error::GitoliteParsing, "Parsing error: expected repo to be (${repo_name} in (#{l})"
|
181
|
+
end
|
182
|
+
elsif l =~ /[ ]*([^ ]+)[ ]*=[ ]*(.+)$/
|
183
|
+
access_rights = $1
|
184
|
+
users = $2
|
185
|
+
users.scan(/[^ ]+/) do |user|
|
186
|
+
unless access_rights.match(/R|W|RW|RW+/)
|
187
|
+
raise Error::GitoliteParsing, "Unexpected access rights while parsing file '#{access_rights}'"
|
188
|
+
end
|
189
|
+
|
190
|
+
@rights_hash[access_rights.to_s] << user unless @rights_hash[access_rights.to_s].include?(user)
|
191
|
+
|
192
|
+
# add to user groups if present
|
193
|
+
if user.match(/^@/)
|
194
|
+
@user_groups << user
|
195
|
+
end
|
196
|
+
end
|
197
|
+
elsif l.strip.empty? || l.strip().match(/^include/)
|
198
|
+
#no op
|
199
|
+
else
|
200
|
+
raise ::Error::GitoliteParsing, "Parsing repo error: (#{l})"
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|
@@ -15,85 +15,85 @@
|
|
15
15
|
# See the License for the specific language governing permissions and
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
|
-
class DTK::Common::GritAdapter::FileAccess
|
19
|
-
module DiffMixin
|
20
|
-
def diff(*args)
|
21
|
-
diff_comamnd_args =
|
22
|
-
case args.size
|
23
|
-
when 1 then [@branch,args[0]]
|
24
|
-
when 2 then args
|
25
|
-
else raise Error.new("diff must have 1 or 2 arguments")
|
26
|
-
end
|
27
|
-
grit_diffs = @grit_repo.diff(*diff_comamnd_args)
|
28
|
-
array_diff_hashes = grit_diffs.map do |diff|
|
29
|
-
Diff::Attributes.inject(Hash.new) do |h,a|
|
30
|
-
val = diff.send(a)
|
31
|
-
val ? h.merge(a => val) : h
|
32
|
-
end
|
33
|
-
end
|
34
|
-
Diffs.new(array_diff_hashes)
|
35
|
-
end
|
36
|
-
|
37
|
-
class Diffs < Array
|
38
|
-
|
39
|
-
class Summary < ::DTK::Common::SimpleHashObject
|
40
|
-
def any_diffs?()
|
41
|
-
!keys().empty?
|
42
|
-
end
|
43
|
-
def any_added_or_deleted_files?()
|
44
|
-
!!(self[:files_renamed] or self[:files_added] or self[:files_deleted])
|
45
|
-
end
|
46
|
-
|
47
|
-
def meta_file_changed?()
|
48
|
-
self[:files_modified] and !!self[:files_modified].find{|r|r[:path] =~ /^r8meta/}
|
49
|
-
end
|
50
|
-
|
51
|
-
#note: in paths_to_add and paths_to_delete rename appears both since rename can be accomplsihed by a add + a delete
|
52
|
-
def paths_to_add()
|
53
|
-
(self[:files_added]||[]).map{|r|r[:path]} + (self[:files_renamed]||[]).map{|r|r[:new_path]}
|
54
|
-
end
|
55
|
-
def paths_to_delete()
|
56
|
-
(self[:files_deleted]||[]).map{|r|r[:path]} + (self[:files_renamed]||[]).map{|r|r[:old_path]}
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def initialize(array_diff_hashes)
|
61
|
-
super(array_diff_hashes.map{|hash|Diff.new(hash)})
|
62
|
-
end
|
63
|
-
|
64
|
-
#returns a hash with keys :file_renamed, :file_added, :file_deleted, :file_modified
|
65
|
-
def ret_summary()
|
66
|
-
[:renamed,:added,:deleted,:modified].inject(Summary.new) do |h,cnd|
|
67
|
-
res = map{|diff|diff.send("file_#{cnd}".to_sym)}.compact
|
68
|
-
res.empty? ? h : h.merge("files_#{cnd}".to_sym => res)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
class Diff
|
74
|
-
Attributes = [:new_file,:renamed_file,:deleted_file,:a_path,:b_path,:diff]
|
75
|
-
AttributeAssignFn = Attributes.inject(Hash.new){|h,a|h.merge(a => "#{a}=".to_sym)}
|
76
|
-
def initialize(hash_input)
|
77
|
-
hash_input.each{|a,v|send(AttributeAssignFn[a],v)}
|
78
|
-
end
|
79
|
-
|
80
|
-
def file_added()
|
81
|
-
@new_file && {:path => @a_path}
|
82
|
-
end
|
83
|
-
|
84
|
-
def file_renamed()
|
85
|
-
@renamed_file && {:old_path => @b_path, :new_path => @a_path}
|
86
|
-
end
|
87
|
-
|
88
|
-
def file_deleted()
|
89
|
-
@deleted_file && {:path => @a_path}
|
90
|
-
end
|
91
|
-
|
92
|
-
def file_modified()
|
93
|
-
((@new_file or @deleted_file or @renamed_file) ? nil : true) && {:path => @a_path}
|
94
|
-
end
|
95
|
-
private
|
96
|
-
attr_writer(*Attributes)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
18
|
+
class DTK::Common::GritAdapter::FileAccess
|
19
|
+
module DiffMixin
|
20
|
+
def diff(*args)
|
21
|
+
diff_comamnd_args =
|
22
|
+
case args.size
|
23
|
+
when 1 then [@branch,args[0]]
|
24
|
+
when 2 then args
|
25
|
+
else raise Error.new("diff must have 1 or 2 arguments")
|
26
|
+
end
|
27
|
+
grit_diffs = @grit_repo.diff(*diff_comamnd_args)
|
28
|
+
array_diff_hashes = grit_diffs.map do |diff|
|
29
|
+
Diff::Attributes.inject(Hash.new) do |h,a|
|
30
|
+
val = diff.send(a)
|
31
|
+
val ? h.merge(a => val) : h
|
32
|
+
end
|
33
|
+
end
|
34
|
+
Diffs.new(array_diff_hashes)
|
35
|
+
end
|
36
|
+
|
37
|
+
class Diffs < Array
|
38
|
+
|
39
|
+
class Summary < ::DTK::Common::SimpleHashObject
|
40
|
+
def any_diffs?()
|
41
|
+
!keys().empty?
|
42
|
+
end
|
43
|
+
def any_added_or_deleted_files?()
|
44
|
+
!!(self[:files_renamed] or self[:files_added] or self[:files_deleted])
|
45
|
+
end
|
46
|
+
|
47
|
+
def meta_file_changed?()
|
48
|
+
self[:files_modified] and !!self[:files_modified].find{|r|r[:path] =~ /^r8meta/}
|
49
|
+
end
|
50
|
+
|
51
|
+
#note: in paths_to_add and paths_to_delete rename appears both since rename can be accomplsihed by a add + a delete
|
52
|
+
def paths_to_add()
|
53
|
+
(self[:files_added]||[]).map{|r|r[:path]} + (self[:files_renamed]||[]).map{|r|r[:new_path]}
|
54
|
+
end
|
55
|
+
def paths_to_delete()
|
56
|
+
(self[:files_deleted]||[]).map{|r|r[:path]} + (self[:files_renamed]||[]).map{|r|r[:old_path]}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def initialize(array_diff_hashes)
|
61
|
+
super(array_diff_hashes.map{|hash|Diff.new(hash)})
|
62
|
+
end
|
63
|
+
|
64
|
+
#returns a hash with keys :file_renamed, :file_added, :file_deleted, :file_modified
|
65
|
+
def ret_summary()
|
66
|
+
[:renamed,:added,:deleted,:modified].inject(Summary.new) do |h,cnd|
|
67
|
+
res = map{|diff|diff.send("file_#{cnd}".to_sym)}.compact
|
68
|
+
res.empty? ? h : h.merge("files_#{cnd}".to_sym => res)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class Diff
|
74
|
+
Attributes = [:new_file,:renamed_file,:deleted_file,:a_path,:b_path,:diff]
|
75
|
+
AttributeAssignFn = Attributes.inject(Hash.new){|h,a|h.merge(a => "#{a}=".to_sym)}
|
76
|
+
def initialize(hash_input)
|
77
|
+
hash_input.each{|a,v|send(AttributeAssignFn[a],v)}
|
78
|
+
end
|
79
|
+
|
80
|
+
def file_added()
|
81
|
+
@new_file && {:path => @a_path}
|
82
|
+
end
|
83
|
+
|
84
|
+
def file_renamed()
|
85
|
+
@renamed_file && {:old_path => @b_path, :new_path => @a_path}
|
86
|
+
end
|
87
|
+
|
88
|
+
def file_deleted()
|
89
|
+
@deleted_file && {:path => @a_path}
|
90
|
+
end
|
91
|
+
|
92
|
+
def file_modified()
|
93
|
+
((@new_file or @deleted_file or @renamed_file) ? nil : true) && {:path => @a_path}
|
94
|
+
end
|
95
|
+
private
|
96
|
+
attr_writer(*Attributes)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/require_first.rb
CHANGED
@@ -15,21 +15,20 @@
|
|
15
15
|
# See the License for the specific language governing permissions and
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
|
-
module DTK
|
19
|
-
module Common
|
20
|
-
def self.r8_require_common(path)
|
21
|
-
require File.expand_path(path, File.dirname(__FILE__))
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.is_gem_installed?(gem_name)
|
25
|
-
begin
|
26
|
-
# if no exception gem is found
|
27
|
-
gem gem_name
|
28
|
-
return true
|
29
|
-
rescue Gem::LoadError
|
30
|
-
return false
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
18
|
+
module DTK
|
19
|
+
module Common
|
20
|
+
def self.r8_require_common(path)
|
21
|
+
require File.expand_path(path, File.dirname(__FILE__))
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.is_gem_installed?(gem_name)
|
25
|
+
begin
|
26
|
+
# if no exception gem is found
|
27
|
+
gem gem_name
|
28
|
+
return true
|
29
|
+
rescue Gem::LoadError
|
30
|
+
return false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dtk-common
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rich PELAVIN
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-06-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rugged
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.12.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
40
|
+
version: 0.12.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: colorize
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -53,19 +53,19 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 0.5.8
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name: grit
|
56
|
+
name: gitlab-grit
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '2.
|
61
|
+
version: '2.8'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '2.
|
68
|
+
version: '2.8'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: erubis
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|