gitolite-rugged 1.2.pre.devel → 1.2.1.pre.devel
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/README.md +6 -10
- data/gitolite.gemspec +12 -12
- data/lib/gitolite/config/repo.rb +2 -2
- data/lib/gitolite/config.rb +5 -1
- data/lib/gitolite/gitolite_admin.rb +100 -37
- data/lib/gitolite/ssh_key.rb +70 -16
- data/lib/gitolite/version.rb +1 -1
- data/spec/config_spec.rb +7 -8
- data/spec/fixtures/gitolite-admin/.gitted/COMMIT_EDITMSG +1 -0
- data/spec/fixtures/gitolite-admin/.gitted/HEAD +1 -0
- data/spec/fixtures/gitolite-admin/.gitted/config +8 -0
- data/spec/fixtures/gitolite-admin/.gitted/description +1 -0
- data/spec/fixtures/gitolite-admin/.gitted/hooks/applypatch-msg.sample +15 -0
- data/spec/fixtures/gitolite-admin/.gitted/hooks/commit-msg.sample +24 -0
- data/spec/fixtures/gitolite-admin/.gitted/hooks/post-update.sample +8 -0
- data/spec/fixtures/gitolite-admin/.gitted/hooks/pre-applypatch.sample +14 -0
- data/spec/fixtures/gitolite-admin/.gitted/hooks/pre-commit.sample +49 -0
- data/spec/fixtures/gitolite-admin/.gitted/hooks/pre-push.sample +54 -0
- data/spec/fixtures/gitolite-admin/.gitted/hooks/pre-rebase.sample +169 -0
- data/spec/fixtures/gitolite-admin/.gitted/hooks/prepare-commit-msg.sample +36 -0
- data/spec/fixtures/gitolite-admin/.gitted/hooks/update.sample +128 -0
- data/spec/fixtures/gitolite-admin/.gitted/index +0 -0
- data/spec/fixtures/gitolite-admin/.gitted/info/exclude +6 -0
- data/spec/fixtures/gitolite-admin/.gitted/logs/HEAD +19 -0
- data/spec/fixtures/gitolite-admin/.gitted/logs/refs/heads/master +19 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/04/6aa40bf1f4fbef8fe915274bd8af30784f4974 +0 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/06/3a0c108a0a431fff7d9ea819e55653c6fda14c +3 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/0a/0493ecd1ef1102cc11211b95d19ef7c4823a23 +0 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/0b/8ae0021fafc32dbecbbcdf82bfe1ec3728432b +3 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/0b/9ea7db8498c31c36567cc7dc528e9a06587ef9 +0 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/13/81680579c7e0626544e28bbca00b0c3b5004e2 +2 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/25/2a0e969ccca06c8258f811d2a6f01d883c2a0c +0 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/39/5dfadc8dd72c4d0ab5d28a3cdd83500a41fb1b +0 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/3b/8c81ac4b6d9276920ec06139d959b9aeb25456 +0 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/41/1a9fa047b7c928939882769d2fac89a1c87dd0 +0 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/42/333c37a7910bff07c7e7a95a3d09b3f9966571 +4 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/43/cb5e7b11750c16f2196bd8548e7b6277b372ca +0 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/5c/f57acca019629fd98a3d9014cd63580a74f4ac +2 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/68/b71afffb0b6781d974af6cb93ef076ded21bb5 +1 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/74/0ef5222fcd51ad7eba4a559396fdf856b20482 +0 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/86/692711b922198563496a69cf30ca772f6a6af3 +0 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/94/f2765eb76820309b11de0018dd2a6bc53ae8f7 +2 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/9c/c84c9d97b8fa8d4cb6c52d6495eca4bff04130 +0 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/9d/248211ad73f2fd188f75988dfd9e66431f2e8a +0 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/9d/ce718e57053022f2e184ba94e2b5131fcbe551 +0 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/ac/b157e4a3d567d42132d608db26143b91c4789c +0 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/ad/91cc1d968ad5fdcb8bd0df04db3523d0b98156 +0 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/b3/178d7dfddbc3df3e03eb271f0cdbe864aa902f +0 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/b6/de0801eb994701c5a55a0793796aebc2440372 +0 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/c9/0707f5301413f121360c9b26784167652a3d2a +2 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/c9/3d2aaacc82cb05a88994d2b44691d07477bde9 +2 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/d9/3bb9a696d405af34d9dcafc2e4611e1d5959dd +2 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/df/cd7e43b90664b02a7765c54d45277f54bcd2ee +0 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/e1/57cf40f5a30aa527d77c10840010c4654b4eab +3 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/e3/c37d85f4800ed4fe4a3f4ca49e3b4a85a88ae1 +2 -0
- data/spec/fixtures/gitolite-admin/.gitted/objects/f4/a351cf0debfb5ac18061f7cb4e7ff2e5916719 +0 -0
- data/spec/fixtures/gitolite-admin/.gitted/refs/heads/master +1 -0
- data/spec/fixtures/gitolite-admin/conf/gitolite.conf +5 -0
- data/spec/fixtures/gitolite-admin/keydir/admin.pub +1 -0
- data/spec/fixtures/gitolite-admin/keydir/bob.pub +1 -0
- data/spec/fixtures/keys/{bob.pub → bob/bob.pub} +0 -0
- data/spec/fixtures/keys/bob/bob@example.com.pub +1 -0
- data/spec/fixtures/keys/bob/desktop/bob.pub +1 -0
- data/spec/fixtures/keys/bob/school/bob.pub +1 -0
- data/spec/gitolite_admin_spec.rb +0 -1
- data/spec/ssh_key_spec.rb +19 -137
- metadata +186 -28
- data/spec/fixtures/keys/bob+joe@test.zilla.com@desktop.pub +0 -1
- data/spec/fixtures/keys/bob-ins@zilla-site.com@desktop.pub +0 -1
- data/spec/fixtures/keys/bob.joe@test.zilla.com@desktop.pub +0 -1
- data/spec/fixtures/keys/bob@desktop.pub +0 -1
- data/spec/fixtures/keys/bob@foo-bar.pub +0 -1
- data/spec/fixtures/keys/bob@zilla.com.pub +0 -1
- data/spec/fixtures/keys/bob@zilla.com@desktop.pub +0 -1
- data/spec/fixtures/keys/jakub123.pub +0 -1
- data/spec/fixtures/keys/jakub123@foo.net.pub +0 -1
- data/spec/fixtures/keys/joe-bob@god-zilla.com@desktop.pub +0 -1
- data/spec/fixtures/keys/joe@sch.ool.edu.pub +0 -1
- data/spec/fixtures/keys/joe@sch.ool.edu@desktop.pub +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: af594539d972d1b2f8d7a30e493e83fabec75f01
|
4
|
+
data.tar.gz: 1eb4ec207defe5014819bcaf4c0e66cebb367a10
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 129b807992315d1d3dbcfaa2fddc18ac674d5d0f25f77d8a1d1ae3527a70635bdc048471e57559be1980c02db6f78a41540e58d0145c61e83b144fd4f15561f0
|
7
|
+
data.tar.gz: 60817e257935d2854fcab2466af48494360888f008dcac676078a65e4ae431133e5f897289a5ab0c4289bf48a1545b121fb6df4c37bec170ce4f48181e067b47
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
## gitolite-rugged
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/gitolite-rugged.svg)](http://badge.fury.io/rb/gitolite-rugged)
|
3
|
+
[![Build Status](https://travis-ci.org/oliverguenther/gitolite-rugged.svg?branch=devel)](https://travis-ci.org/oliverguenther/gitolite-rugged)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/oliverguenther/gitolite-rugged.png)](https://codeclimate.com/github/oliverguenther/gitolite-rugged)
|
5
|
+
|
6
|
+
### This gem is a fork from the [jbox-gitolite](https://github.com/jbox-web/gitolite) gem employing [libgit2/rugged](https://github.com/libgit2/rugged).
|
2
7
|
|
3
|
-
**This gem is a fork from the [jbox-gitolite](https://raw.github.com/jbox-web/gitolite) gem employing [libgit2/rugged](https://github.com/libgit2/rugged).**
|
4
8
|
|
5
9
|
This gem is designed to provide a Ruby interface to the [Gitolite](https://github.com/sitaramc/gitolite) Git backend system.
|
6
10
|
|
@@ -10,14 +14,6 @@ It provides these functionalities :
|
|
10
14
|
* Repositories Management
|
11
15
|
* Gitolite Admin Repository Bootstrapping
|
12
16
|
|
13
|
-
## Code status
|
14
|
-
|
15
|
-
* [![Gem Version](https://badge.fury.io/rb/gitolite-rugged.svg)](http://badge.fury.io/rb/gitolite-rugged)
|
16
|
-
* [![Build Status](https://travis-ci.org/oliverguenther/gitolite-rugged.svg?branch=devel)](https://travis-ci.org/oliverguenther/gitolite-rugged)
|
17
|
-
* [![Code Climate](https://codeclimate.com/github/oliverguenther/gitolite-rugged.png)](https://codeclimate.com/github/oliverguenther/gitolite-rugged)
|
18
|
-
* [![Dependency Status](https://gemnasium.com/oliverguenther/gitolite-rugged.svg)](https://gemnasium.com/oliverguenther/gitolite-rugged)
|
19
|
-
|
20
|
-
|
21
17
|
## Requirements ##
|
22
18
|
* Ruby 1.9.x or 2.0.x
|
23
19
|
* a working [gitolite](https://github.com/sitaramc/gitolite) installation
|
@@ -103,6 +99,6 @@ Copyright (c) 2014 Oliver Günther (mail@oliverguenther.de)
|
|
103
99
|
|
104
100
|
Based on the jbox-gitolite fork by Nicolas Rodriguez, which itself is based on the original gitolite gem by Stafford Brunk.
|
105
101
|
|
106
|
-
Copyright (c) 2013-2014 Nicolas Rodriguez (nrodriguez@jbox-web.com), JBox Web (http://www.jbox-web.com)
|
102
|
+
Copyright (c) 2013-2014 Nicolas Rodriguez (nrodriguez@jbox-web.com), JBox Web (http://www.jbox-web.com)
|
107
103
|
|
108
104
|
Copyright (c) 2011-2013 Stafford Brunk (stafford.brunk@gmail.com)
|
data/gitolite.gemspec
CHANGED
@@ -13,21 +13,21 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.description = %q{This gem is designed to provide a Ruby interface to the Gitolite Git backend system using libgit2/rugged. This gem aims to provide all management functionality that is available via the gitolite-admin repository (like SSH keys, repository permissions, etc)}
|
14
14
|
s.license = 'MIT'
|
15
15
|
|
16
|
-
s.add_development_dependency "rake", "~> 10.3.1"
|
17
|
-
s.add_development_dependency "rdoc", "~> 4.1.1"
|
18
|
-
s.add_development_dependency "rspec", "~> 2.14.1"
|
19
|
-
s.add_development_dependency "guard-rspec", "~> 4.2.8"
|
20
|
-
s.add_development_dependency "guard-spork", "~> 1.5.1"
|
21
|
-
s.add_development_dependency "forgery", "~> 0.6.0"
|
22
|
-
s.add_development_dependency "travis-lint", "~> 1.8.0"
|
16
|
+
s.add_development_dependency "rake", "~> 10.3", ">= 10.3.1"
|
17
|
+
s.add_development_dependency "rdoc", "~> 4.1", ">= 4.1.1"
|
18
|
+
s.add_development_dependency "rspec", "~> 2.14", ">= 2.14.1"
|
19
|
+
s.add_development_dependency "guard-rspec", "~> 4.2", ">= 4.2.8"
|
20
|
+
s.add_development_dependency "guard-spork", "~> 1.5", ">= 1.5.1"
|
21
|
+
s.add_development_dependency "forgery", "~> 0.6", ">= 0.6.0"
|
22
|
+
s.add_development_dependency "travis-lint", "~> 1.8", ">= 1.8.0"
|
23
23
|
|
24
|
-
s.add_development_dependency "simplecov", "~> 0.8.2"
|
25
|
-
s.add_development_dependency "simplecov-rcov", "~> 0.2.3"
|
24
|
+
s.add_development_dependency "simplecov", "~> 0.8", ">= 0.8.2"
|
25
|
+
s.add_development_dependency "simplecov-rcov", "~> 0.2", ">= 0.2.3"
|
26
26
|
|
27
|
-
s.add_development_dependency "rspec_junit_formatter", "~> 0.1.6"
|
27
|
+
s.add_development_dependency "rspec_junit_formatter", "~> 0.1", ">= 0.1.6"
|
28
28
|
|
29
|
-
s.add_dependency "rugged", ">= 0.19.0"
|
30
|
-
s.add_dependency "gratr19", "~> 0.4.4.1"
|
29
|
+
s.add_dependency "rugged", "~> 0.19", ">= 0.19.0"
|
30
|
+
s.add_dependency "gratr19", "~> 0.4.4", ">= 0.4.4.1"
|
31
31
|
|
32
32
|
s.files = `git ls-files`.split("\n")
|
33
33
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
data/lib/gitolite/config/repo.rb
CHANGED
@@ -74,11 +74,11 @@ module Gitolite
|
|
74
74
|
end
|
75
75
|
|
76
76
|
@config.each do |k, v|
|
77
|
-
repo += " config " + k + " = " + v + "\n"
|
77
|
+
repo += " config " + k + " = " + v.to_s + "\n"
|
78
78
|
end
|
79
79
|
|
80
80
|
@options.each do |k, v|
|
81
|
-
repo += " option " + k + " = " + v + "\n"
|
81
|
+
repo += " option " + k + " = " + v.to_s + "\n"
|
82
82
|
end
|
83
83
|
|
84
84
|
repo
|
data/lib/gitolite/config.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'tempfile'
|
2
|
+
require 'fileutils'
|
2
3
|
|
3
4
|
module Gitolite
|
4
5
|
|
@@ -73,7 +74,7 @@ module Gitolite
|
|
73
74
|
|
74
75
|
|
75
76
|
def to_file(path=".", filename=@filename)
|
76
|
-
|
77
|
+
FileUtils.mkdir_p(path) unless File.directory?(path)
|
77
78
|
|
78
79
|
new_conf = File.join(path, filename)
|
79
80
|
File.open(new_conf, "w") do |f|
|
@@ -119,6 +120,9 @@ module Gitolite
|
|
119
120
|
def process_config(config)
|
120
121
|
context = [] #will store our context for permissions or config declarations
|
121
122
|
|
123
|
+
# On first call with a custom *.conf, the config might not yet exist
|
124
|
+
return unless File.exists?(config)
|
125
|
+
|
122
126
|
#Read each line of our config
|
123
127
|
File.open(config, 'r').each do |l|
|
124
128
|
|
@@ -1,25 +1,26 @@
|
|
1
|
+
require 'pathname'
|
1
2
|
module Gitolite
|
2
3
|
class GitoliteAdmin
|
3
4
|
|
4
5
|
attr_accessor :repo
|
5
6
|
|
6
|
-
CONF_DIR = "conf"
|
7
|
-
KEY_DIR = "keydir"
|
8
|
-
|
9
|
-
CONFIG_FILE = "gitolite.conf"
|
10
|
-
CONFIG_PATH = File.join(CONF_DIR, "gitolite.conf")
|
11
|
-
|
12
|
-
|
13
7
|
# Default settings
|
14
|
-
|
8
|
+
DEFAULTS = {
|
15
9
|
# clone/push url settings
|
16
|
-
git_user: 'git',
|
10
|
+
git_user: 'git',
|
17
11
|
hostname: 'localhost',
|
18
12
|
|
19
13
|
# Commit settings
|
20
14
|
author_name: 'gitolite-rugged gem',
|
21
15
|
author_email: 'gitolite-rugged@localhost',
|
22
|
-
commit_msg: 'Commited by the gitolite-rugged gem'
|
16
|
+
commit_msg: 'Commited by the gitolite-rugged gem',
|
17
|
+
|
18
|
+
# Gitolite-Admin settings
|
19
|
+
config_dir: "conf",
|
20
|
+
key_dir: "keydir",
|
21
|
+
key_subdir: "",
|
22
|
+
config_file: "gitolite.conf",
|
23
|
+
lock_file_path: '.lock'
|
23
24
|
}
|
24
25
|
|
25
26
|
class << self
|
@@ -37,8 +38,8 @@ module Gitolite
|
|
37
38
|
end
|
38
39
|
|
39
40
|
# Check if config file, key directory exist
|
40
|
-
[ File.join(dir,
|
41
|
-
File.join(dir,
|
41
|
+
[ File.join(dir, DEFAULTS[:config_dir]), File.join(dir, DEFAULTS[:key_dir]),
|
42
|
+
File.join(dir, DEFAULTS[:config_dir], DEFAULTS[:config_file])
|
42
43
|
].each { |f| return false unless File.exists?(f) }
|
43
44
|
|
44
45
|
true
|
@@ -53,14 +54,24 @@ module Gitolite
|
|
53
54
|
# the gitolite-admin repository
|
54
55
|
#
|
55
56
|
# Settings:
|
57
|
+
# [Connection]
|
56
58
|
# :git_user: The git user to SSH to (:git_user@localhost:gitolite-admin.git), defaults to 'git'
|
57
59
|
# :private_key: The key file containing the private SSH key for :git_user
|
58
60
|
# :public_key: The key file containing the public SSH key for :git_user
|
59
61
|
# :host: Hostname for clone url. Defaults to 'localhost'
|
62
|
+
#
|
63
|
+
# [Gitolite-Admin]
|
64
|
+
# :config_dir: Config directory within gitolite repository (defaults to 'conf')
|
65
|
+
# :key_dir: Public key directory within gitolite repository (defaults to 'keydir')
|
66
|
+
# :config_file: Config file to parse (default: 'gitolite.conf')
|
67
|
+
# **use only when you use the 'include' directive of gitolite)**
|
68
|
+
# :key_subdir: Where to store gitolite-rugged known keys, defaults to '' (i.e., directly in keydir)
|
69
|
+
# :lock_file_path: location of the transaction lockfile, defaults to <gitolite-admin.git>/.lock
|
70
|
+
#
|
60
71
|
# The settings hash is forwarded to +GitoliteAdmin.new+ as options.
|
61
72
|
def initialize(path, settings = {})
|
62
73
|
@path = path
|
63
|
-
@settings =
|
74
|
+
@settings = DEFAULTS.merge(settings)
|
64
75
|
|
65
76
|
# Ensure SSH key settings exist
|
66
77
|
@settings.fetch(:public_key)
|
@@ -71,22 +82,39 @@ module Gitolite
|
|
71
82
|
username: settings[:git_user], publickey: settings[:public_key],
|
72
83
|
privatekey: settings[:private_key] )
|
73
84
|
|
74
|
-
@repo =
|
85
|
+
@repo =
|
75
86
|
if self.class.is_gitolite_admin_repo?(path)
|
76
|
-
Rugged::Repository.new(path)
|
87
|
+
Rugged::Repository.new(path, credentials: @credentials)
|
77
88
|
else
|
78
89
|
clone
|
79
90
|
end
|
80
91
|
|
81
|
-
@
|
82
|
-
@
|
83
|
-
@key_dir_path = File.join(@path,
|
92
|
+
@config_dir_path = File.join(@path, @settings[:config_dir])
|
93
|
+
@config_file_path = File.join(@config_dir_path, @settings[:config_file])
|
94
|
+
@key_dir_path = File.join(@path, relative_key_dir)
|
84
95
|
|
85
96
|
@commit_author = { email: settings[:author_email], name: settings[:author_name] }
|
86
97
|
|
87
98
|
reload!
|
88
99
|
end
|
89
100
|
|
101
|
+
|
102
|
+
#
|
103
|
+
# Returns the relative directory to the gitolite config file location.
|
104
|
+
# I.e., settings[config_dir]/settings[config_file]
|
105
|
+
# Defaults to 'conf/gitolite.conf'
|
106
|
+
def relative_config_file
|
107
|
+
File.join(@settings[:config_dir], @settings[:config_file])
|
108
|
+
end
|
109
|
+
|
110
|
+
#
|
111
|
+
# Returns the relative directory to the public key location.
|
112
|
+
# I.e., settings[key_dir]/settings[key_subdir]
|
113
|
+
# Defaults to 'keydir/'
|
114
|
+
def relative_key_dir
|
115
|
+
File.join(@settings[:key_dir], @settings[:key_subdir])
|
116
|
+
end
|
117
|
+
|
90
118
|
def config
|
91
119
|
@config ||= load_config
|
92
120
|
end
|
@@ -138,28 +166,25 @@ module Gitolite
|
|
138
166
|
|
139
167
|
# Writes all changed aspects out to the file system
|
140
168
|
# will also stage all changes then commit
|
141
|
-
def save()
|
169
|
+
def save(commit_msg = nil)
|
142
170
|
|
143
171
|
# Add all changes to index (staging area)
|
144
172
|
index = @repo.index
|
145
173
|
|
146
174
|
#Process config file (if loaded, i.e. may be modified)
|
147
175
|
if @config
|
148
|
-
new_conf = @config.to_file(
|
149
|
-
|
150
|
-
# Rugged wants relative paths
|
151
|
-
index.add(CONFIG_PATH)
|
176
|
+
new_conf = @config.to_file(path=@config_dir_path)
|
177
|
+
index.add(relative_config_file)
|
152
178
|
end
|
153
179
|
|
154
180
|
#Process ssh keys (if loaded, i.e. may be modified)
|
155
181
|
if @ssh_keys
|
156
|
-
files = list_keys.map{|f|
|
157
|
-
keys = @ssh_keys.values.map{|f| f.map {|t| t.
|
182
|
+
files = list_keys.map{|f| relative_key_path(f) }
|
183
|
+
keys = @ssh_keys.values.map{|f| f.map {|t| t.relative_path}}.flatten
|
158
184
|
|
159
|
-
to_remove = (files - keys).
|
160
|
-
|
161
|
-
File.
|
162
|
-
index.remove key
|
185
|
+
to_remove = (files - keys).each do |key|
|
186
|
+
SSHKey.remove(key, @key_dir_path)
|
187
|
+
index.remove File.join(relative_key_dir, key)
|
163
188
|
end
|
164
189
|
|
165
190
|
@ssh_keys.each_value do |key|
|
@@ -167,7 +192,7 @@ module Gitolite
|
|
167
192
|
next if key.respond_to?(:dirty?) && !key.dirty?
|
168
193
|
key.each do |k|
|
169
194
|
new_key = k.to_file(@key_dir_path)
|
170
|
-
index.add
|
195
|
+
index.add File.join(relative_key_dir, k.relative_path)
|
171
196
|
end
|
172
197
|
end
|
173
198
|
end
|
@@ -181,7 +206,7 @@ module Gitolite
|
|
181
206
|
Rugged::Commit.create(@repo,
|
182
207
|
author: commit_author,
|
183
208
|
committer: commit_author,
|
184
|
-
message: @settings[:commit_msg],
|
209
|
+
message: commit_msg || @settings[:commit_msg],
|
185
210
|
parents: [repo.head.target],
|
186
211
|
tree: commit_tree,
|
187
212
|
update_ref: 'HEAD'
|
@@ -191,7 +216,7 @@ module Gitolite
|
|
191
216
|
|
192
217
|
# Push back to origin
|
193
218
|
def apply
|
194
|
-
@repo.push
|
219
|
+
@repo.push('origin', ['refs/heads/master'], credentials: @credentials)
|
195
220
|
end
|
196
221
|
|
197
222
|
|
@@ -202,6 +227,19 @@ module Gitolite
|
|
202
227
|
end
|
203
228
|
|
204
229
|
|
230
|
+
# Lock the gitolite-admin directory and yield.
|
231
|
+
# After the block is completed, calls +apply+ only.
|
232
|
+
# You have to commit your changes within the transaction block
|
233
|
+
def transaction
|
234
|
+
get_lock do
|
235
|
+
yield
|
236
|
+
|
237
|
+
# Push all changes
|
238
|
+
apply
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
|
205
243
|
# Updates the repo with changes from remote master
|
206
244
|
# Warning: This resets the repo before pulling in the changes.
|
207
245
|
def update(settings = {})
|
@@ -215,7 +253,7 @@ module Gitolite
|
|
215
253
|
merge_index = repo.merge_commits(master, origin_master)
|
216
254
|
|
217
255
|
# Complete the merge by comitting it
|
218
|
-
merge_commit = Rugged::Commit.create(@repo,
|
256
|
+
merge_commit = Rugged::Commit.create(@repo,
|
219
257
|
parents: [ master, origin_master ],
|
220
258
|
tree: merge_index.write_tree(@repo),
|
221
259
|
message: '[gitolite-rugged] Merged `origin/master` into `master`',
|
@@ -232,8 +270,8 @@ module Gitolite
|
|
232
270
|
|
233
271
|
|
234
272
|
# Clone the gitolite-admin repo
|
235
|
-
# to the given path.
|
236
|
-
#
|
273
|
+
# to the given path.
|
274
|
+
#
|
237
275
|
# The repo is cloned from the url
|
238
276
|
# +(:git_user)@(:hostname)/gitolite-admin.git+
|
239
277
|
#
|
@@ -241,8 +279,8 @@ module Gitolite
|
|
241
279
|
# E.g., +git@localhost:2222/gitolite-admin.git+
|
242
280
|
#
|
243
281
|
def clone()
|
244
|
-
Rugged::Repository.clone_at(admin_url(@settings), File.expand_path(@path), credentials: @
|
245
|
-
end
|
282
|
+
Rugged::Repository.clone_at(admin_url(@settings), File.expand_path(@path), credentials: @credentials)
|
283
|
+
end
|
246
284
|
|
247
285
|
|
248
286
|
def load_config
|
@@ -254,6 +292,13 @@ module Gitolite
|
|
254
292
|
Dir.glob(@key_dir_path + '/**/*.pub')
|
255
293
|
end
|
256
294
|
|
295
|
+
# Returns the relative key path
|
296
|
+
# <owner>/<location>/<owner> given an absolute path
|
297
|
+
# below the keydir.
|
298
|
+
def relative_key_path(key_path)
|
299
|
+
Pathname.new(key_path).relative_path_from(Pathname.new(@key_dir_path)).to_s
|
300
|
+
end
|
301
|
+
|
257
302
|
|
258
303
|
# Loads all .pub files in the gitolite-admin
|
259
304
|
# keydir directory
|
@@ -272,5 +317,23 @@ module Gitolite
|
|
272
317
|
|
273
318
|
keys
|
274
319
|
end
|
320
|
+
|
321
|
+
def lock_file_path
|
322
|
+
File.expand_path(@settings[:lock_file_path], @path)
|
323
|
+
end
|
324
|
+
|
325
|
+
|
326
|
+
# Aquire LOCK_EX on the gitolite-admin.git directory .
|
327
|
+
# Use +GitoliteAdmin.transaction+ to modify with flock.
|
328
|
+
def get_lock
|
329
|
+
File.open(lock_file_path, File::RDWR|File::CREAT, 0644) do |file|
|
330
|
+
file.sync = true
|
331
|
+
file.flock(File::LOCK_EX)
|
332
|
+
|
333
|
+
yield
|
334
|
+
|
335
|
+
file.flock(File::LOCK_UN)
|
336
|
+
end
|
337
|
+
end
|
275
338
|
end
|
276
339
|
end
|
data/lib/gitolite/ssh_key.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
|
+
require 'fileutils'
|
1
2
|
module Gitolite
|
2
3
|
|
3
4
|
# Models an SSH key within gitolite
|
4
5
|
# provides support for multikeys
|
5
6
|
#
|
6
7
|
# Types of multi keys:
|
7
|
-
# bob
|
8
|
-
#
|
9
|
-
# bob@email.com.pub => username: bob@email.com
|
10
|
-
# bob@email.com@desktop.pub => username: bob@email.com, location: desktop
|
8
|
+
# username: bob => <keydir>/bob/bob.pub
|
9
|
+
# username: bob, location: desktop => <keydir>/bob/desktop/bob.pub
|
11
10
|
|
12
11
|
class SSHKey
|
13
12
|
|
@@ -18,17 +17,17 @@ module Gitolite
|
|
18
17
|
def from_file(key)
|
19
18
|
raise "#{key} does not exist!" unless File.exists?(key)
|
20
19
|
|
21
|
-
#
|
22
|
-
#
|
23
|
-
File.basename(key
|
24
|
-
|
25
|
-
|
20
|
+
# Owner is the basename of the key
|
21
|
+
# i.e., <owner>/<location>/<owner>.pub
|
22
|
+
owner = File.basename(key, ".pub")
|
23
|
+
|
24
|
+
# Location is the middle section of the path, if any
|
25
|
+
location = self.location_from_path(File.dirname(key), owner)
|
26
26
|
|
27
27
|
# Use string key constructor
|
28
28
|
self.from_string(File.read(key), owner, location)
|
29
29
|
end
|
30
30
|
|
31
|
-
|
32
31
|
# Construct a SSHKey from a string
|
33
32
|
def from_string(key_string, owner, location = "")
|
34
33
|
if owner.nil?
|
@@ -51,10 +50,58 @@ module Gitolite
|
|
51
50
|
self.new(type, blob, email, owner, location)
|
52
51
|
end
|
53
52
|
|
53
|
+
# Parse the key path above the key to be read.
|
54
|
+
# As we can omit the location, there are two possible options:
|
55
|
+
#
|
56
|
+
# 1. Location is empty. Path is <keydir>/<owner>/
|
57
|
+
# 2. Location is non-empty. Path is <keydir>/<owner>/<location>
|
58
|
+
#
|
59
|
+
# We test this by checking the parent of the given path.
|
60
|
+
# If it equals owner, a location was set.
|
61
|
+
# This allows the daft case of e.g., using <keydir>/bob/bob/bob.pub.
|
62
|
+
def location_from_path(path, owner)
|
63
|
+
keyroot = File.dirname(path)
|
64
|
+
if File.basename(keyroot) == owner
|
65
|
+
File.basename(path)
|
66
|
+
else
|
67
|
+
''
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def delete_dir_if_empty(dir)
|
72
|
+
if File.directory?(dir) && Dir["#{dir}/*"].empty?
|
73
|
+
Dir.rmdir(dir)
|
74
|
+
end
|
75
|
+
rescue => e
|
76
|
+
STDERR.puts("Warning: Couldn't delete empty directory: #{e.message}")
|
77
|
+
end
|
78
|
+
|
79
|
+
# Remove a key given a relative path
|
80
|
+
#
|
81
|
+
# Unlinks the key file and removes any empty parent directory
|
82
|
+
# below key_dir
|
83
|
+
def remove(key_file, key_dir_path)
|
84
|
+
|
85
|
+
abs_key_path = File.join(key_dir_path, key_file)
|
86
|
+
key = self.from_file(abs_key_path)
|
87
|
+
|
88
|
+
# Remove the file itself
|
89
|
+
File.unlink(abs_key_path)
|
90
|
+
|
91
|
+
key_owner_dir = File.join(key_dir_path, key.owner)
|
92
|
+
|
93
|
+
# Remove the location, if it exists and is empty
|
94
|
+
if key.location
|
95
|
+
self.delete_dir_if_empty(File.join(key_owner_dir, key.location))
|
96
|
+
end
|
97
|
+
|
98
|
+
# Remove the owner dir, if empty
|
99
|
+
self.delete_dir_if_empty(key_owner_dir)
|
100
|
+
end
|
54
101
|
end
|
55
102
|
|
56
103
|
|
57
|
-
def initialize(type, blob, email, owner
|
104
|
+
def initialize(type, blob, email, owner=nil, location = "")
|
58
105
|
@type = type
|
59
106
|
@blob = blob
|
60
107
|
@email = email
|
@@ -70,7 +117,14 @@ module Gitolite
|
|
70
117
|
|
71
118
|
|
72
119
|
def to_file(path)
|
73
|
-
|
120
|
+
# Ensure multi-key directory structure
|
121
|
+
# <keydir>/<owner>/<location?>/<owner>.pub
|
122
|
+
key_dir = File.join(path, @owner, @location)
|
123
|
+
key_file = File.join(key_dir, self.filename)
|
124
|
+
|
125
|
+
# Ensure subdirs exist
|
126
|
+
FileUtils.mkdir_p(key_dir) unless File.directory?(key_dir)
|
127
|
+
|
74
128
|
File.open(key_file, "w") do |f|
|
75
129
|
f.sync = true
|
76
130
|
f.write(self.to_s)
|
@@ -78,11 +132,12 @@ module Gitolite
|
|
78
132
|
key_file
|
79
133
|
end
|
80
134
|
|
135
|
+
def relative_path
|
136
|
+
File.join(@owner, @location, self.filename)
|
137
|
+
end
|
81
138
|
|
82
139
|
def filename
|
83
|
-
|
84
|
-
file += "@#{@location}" unless @location.empty?
|
85
|
-
file += ".pub"
|
140
|
+
[@owner, '.pub'].join
|
86
141
|
end
|
87
142
|
|
88
143
|
|
@@ -98,6 +153,5 @@ module Gitolite
|
|
98
153
|
def hash
|
99
154
|
[@owner, @location, @type, @blob, @email].hash
|
100
155
|
end
|
101
|
-
|
102
156
|
end
|
103
157
|
end
|
data/lib/gitolite/version.rb
CHANGED
data/spec/config_spec.rb
CHANGED
@@ -4,7 +4,6 @@ describe Gitolite::Config do
|
|
4
4
|
|
5
5
|
conf_dir = File.join(File.dirname(__FILE__), 'fixtures', 'configs')
|
6
6
|
output_dir = '/tmp'
|
7
|
-
# output_dir = File.join(File.dirname(File.dirname(__FILE__)), 'tmp')
|
8
7
|
|
9
8
|
describe "#new" do
|
10
9
|
it 'should read a simple configuration' do
|
@@ -348,14 +347,14 @@ describe Gitolite::Config do
|
|
348
347
|
File.unlink(file)
|
349
348
|
end
|
350
349
|
|
351
|
-
it 'should
|
350
|
+
it 'should create the given directory if it does not exist' do
|
352
351
|
c = Gitolite::Config.init
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
352
|
+
Dir.mktmpdir("foo") do |dir|
|
353
|
+
target = File.join(dir, "someconfigfile")
|
354
|
+
File.exists?(target).should eql(false)
|
355
|
+
c.to_file(target)
|
356
|
+
File.exists?(target).should eql(true)
|
357
|
+
end
|
359
358
|
end
|
360
359
|
|
361
360
|
it 'should resolve group dependencies such that all groups are defined before they are used' do
|
@@ -0,0 +1 @@
|
|
1
|
+
Initial repos w/ admin+bob
|
@@ -0,0 +1 @@
|
|
1
|
+
ref: refs/heads/master
|
@@ -0,0 +1 @@
|
|
1
|
+
Unnamed repository; edit this file 'description' to name the repository.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
#
|
3
|
+
# An example hook script to check the commit log message taken by
|
4
|
+
# applypatch from an e-mail message.
|
5
|
+
#
|
6
|
+
# The hook should exit with non-zero status after issuing an
|
7
|
+
# appropriate message if it wants to stop the commit. The hook is
|
8
|
+
# allowed to edit the commit message file.
|
9
|
+
#
|
10
|
+
# To enable this hook, rename this file to "applypatch-msg".
|
11
|
+
|
12
|
+
. git-sh-setup
|
13
|
+
test -x "$GIT_DIR/hooks/commit-msg" &&
|
14
|
+
exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
|
15
|
+
:
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
#
|
3
|
+
# An example hook script to check the commit log message.
|
4
|
+
# Called by "git commit" with one argument, the name of the file
|
5
|
+
# that has the commit message. The hook should exit with non-zero
|
6
|
+
# status after issuing an appropriate message if it wants to stop the
|
7
|
+
# commit. The hook is allowed to edit the commit message file.
|
8
|
+
#
|
9
|
+
# To enable this hook, rename this file to "commit-msg".
|
10
|
+
|
11
|
+
# Uncomment the below to add a Signed-off-by line to the message.
|
12
|
+
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
|
13
|
+
# hook is more suited to it.
|
14
|
+
#
|
15
|
+
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
|
16
|
+
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
|
17
|
+
|
18
|
+
# This example catches duplicate Signed-off-by lines.
|
19
|
+
|
20
|
+
test "" = "$(grep '^Signed-off-by: ' "$1" |
|
21
|
+
sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || {
|
22
|
+
echo >&2 Duplicate Signed-off-by lines.
|
23
|
+
exit 1
|
24
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
#
|
3
|
+
# An example hook script to verify what is about to be committed
|
4
|
+
# by applypatch from an e-mail message.
|
5
|
+
#
|
6
|
+
# The hook should exit with non-zero status after issuing an
|
7
|
+
# appropriate message if it wants to stop the commit.
|
8
|
+
#
|
9
|
+
# To enable this hook, rename this file to "pre-applypatch".
|
10
|
+
|
11
|
+
. git-sh-setup
|
12
|
+
test -x "$GIT_DIR/hooks/pre-commit" &&
|
13
|
+
exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
|
14
|
+
:
|