gitolite-rugged 1.2.pre.devel

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/.gitignore +9 -0
  4. data/.travis.yml +14 -0
  5. data/Gemfile +5 -0
  6. data/Guardfile +13 -0
  7. data/LICENSE.txt +26 -0
  8. data/README.md +108 -0
  9. data/Rakefile +59 -0
  10. data/gitolite.gemspec +36 -0
  11. data/lib/gitolite/config/group.rb +62 -0
  12. data/lib/gitolite/config/repo.rb +107 -0
  13. data/lib/gitolite/config.rb +284 -0
  14. data/lib/gitolite/dirty_proxy.rb +32 -0
  15. data/lib/gitolite/gitolite_admin.rb +276 -0
  16. data/lib/gitolite/ssh_key.rb +103 -0
  17. data/lib/gitolite/version.rb +3 -0
  18. data/lib/gitolite.rb +10 -0
  19. data/spec/config_spec.rb +498 -0
  20. data/spec/dirty_proxy_spec.rb +66 -0
  21. data/spec/fixtures/configs/complicated-output.conf +72 -0
  22. data/spec/fixtures/configs/complicated.conf +311 -0
  23. data/spec/fixtures/configs/simple.conf +5 -0
  24. data/spec/fixtures/keys/bob+joe@test.zilla.com@desktop.pub +1 -0
  25. data/spec/fixtures/keys/bob-ins@zilla-site.com@desktop.pub +1 -0
  26. data/spec/fixtures/keys/bob.joe@test.zilla.com@desktop.pub +1 -0
  27. data/spec/fixtures/keys/bob.pub +1 -0
  28. data/spec/fixtures/keys/bob@desktop.pub +1 -0
  29. data/spec/fixtures/keys/bob@foo-bar.pub +1 -0
  30. data/spec/fixtures/keys/bob@zilla.com.pub +1 -0
  31. data/spec/fixtures/keys/bob@zilla.com@desktop.pub +1 -0
  32. data/spec/fixtures/keys/jakub123.pub +1 -0
  33. data/spec/fixtures/keys/jakub123@foo.net.pub +1 -0
  34. data/spec/fixtures/keys/joe-bob@god-zilla.com@desktop.pub +1 -0
  35. data/spec/fixtures/keys/joe@sch.ool.edu.pub +1 -0
  36. data/spec/fixtures/keys/joe@sch.ool.edu@desktop.pub +1 -0
  37. data/spec/gitolite_admin_spec.rb +40 -0
  38. data/spec/group_spec.rb +125 -0
  39. data/spec/repo_spec.rb +202 -0
  40. data/spec/spec_helper.rb +21 -0
  41. data/spec/ssh_key_spec.rb +355 -0
  42. metadata +280 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: de63cb865336e69a0371a06372f7f55fe1846812
4
+ data.tar.gz: 2b3334e0163d1665b56cfb9825880804e1accf0e
5
+ SHA512:
6
+ metadata.gz: a562980bc44bbf4708c231f7e54b0c29507a9898d0f516fcdf25c3d68a76e2bec304f6bf026951acf640b3cd7d99b5ec9a602183f9a4c9aa1bb5a54a8e9bdd9a
7
+ data.tar.gz: a6cc767c3ce52c671793188f4b6eacb200adbd92c069debdcb3d9c16d16b3af9aa80173eb2002e306fa995060312c814fcd9bb30ce91c0061f80608ed9a8dbc1
data/.gemtest ADDED
File without changes
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ *.gem
2
+ *.lock
3
+ *.log
4
+ .bundle
5
+ /pkg
6
+ /rdoc
7
+ /coverage
8
+ /junit
9
+ /tmp
data/.travis.yml ADDED
@@ -0,0 +1,14 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.0
4
+ - 2.0.0
5
+ - 1.9.3
6
+ gemfile:
7
+ - Gemfile
8
+ branches:
9
+ only:
10
+ - devel
11
+ - /^v1\..*$/
12
+ before_install:
13
+ - sudo apt-get update -qq
14
+ - sudo apt-get install -qq libicu-dev
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in gitolite.gemspec
4
+ gemspec
5
+ gem 'rugged', git: 'git://github.com/libgit2/rugged.git', branch: 'development', submodules: true
data/Guardfile ADDED
@@ -0,0 +1,13 @@
1
+ # More info at https://github.com/guard/guard#readme
2
+
3
+ guard :rspec, :cmd => "bundle exec rspec --color --format nested --fail-fast" do
4
+ watch(%r{^spec/.+_spec\.rb$})
5
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
6
+ watch('spec/spec_helper.rb') { "spec" }
7
+ end
8
+
9
+ guard :spork, :rspec_env => { 'RAILS_ENV' => 'test' }, :rspec_port => 9090 do
10
+ watch(%r{^lib/(.+)\.rb$})
11
+ watch('Gemfile.lock')
12
+ watch('spec/spec_helper.rb') { :rspec }
13
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,26 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2011-2013 Stafford Brunk (stafford.brunk@gmail.com)
4
+
5
+ Copyright (c) 2013-2014 Nicolas Rodriguez (nrodriguez@jbox-web.com), JBox Web (http://www.jbox-web.com)
6
+
7
+ Copyright (c) 2014 Oliver Günther (mail@oliverguenther.de)
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining
10
+ a copy of this software and associated documentation files (the
11
+ 'Software'), to deal in the Software without restriction, including
12
+ without limitation the rights to use, copy, modify, merge, publish,
13
+ distribute, sublicense, and/or sell copies of the Software, and to
14
+ permit persons to whom the Software is furnished to do so, subject to
15
+ the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be
18
+ included in all copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
21
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,108 @@
1
+ ## gitolite-rugged
2
+
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
+
5
+ This gem is designed to provide a Ruby interface to the [Gitolite](https://github.com/sitaramc/gitolite) Git backend system.
6
+
7
+ It provides these functionalities :
8
+
9
+ * SSH Public Keys Management
10
+ * Repositories Management
11
+ * Gitolite Admin Repository Bootstrapping
12
+
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
+ ## Requirements ##
22
+ * Ruby 1.9.x or 2.0.x
23
+ * a working [gitolite](https://github.com/sitaramc/gitolite) installation
24
+ * The [rugged](https://github.com/libgit2/rugged) bindings to libgit2 with SSH-key credentials added (currently on devel-branch).
25
+
26
+ ## Installation ##
27
+
28
+ gem install gitolite-rugged
29
+
30
+
31
+ ## Usage ##
32
+
33
+ ### Bootstrapping the gitolite-admin.git repository ###
34
+
35
+ You can have `gitolite-rugged` clone the repository for you on demand, however I would recommend cloning it manually.
36
+ See it as a basic check that your gitolite installation was correctly set up.
37
+
38
+ In both cases, use the following code to create an instance of the manager:
39
+
40
+ settings = { :public_key => '~/.ssh/id_rsa.pub', :private_key => '~/.ssh/id_rsa' }
41
+ admin = Gitolite::GitoliteAdmin.new('/home/myuser/gitolite-admin', settings)
42
+
43
+ For cloning and pushing to the gitolite-admin.git, you have to provide several options to `GitoliteAdmin` in the settings hash. The following keys are used.
44
+
45
+ * **:git_user** The git user to SSH to (:git_user@localhost:gitolite-admin.git), defaults to 'git'
46
+ * **:host** Hostname for clone url. Defaults to 'localhost'
47
+ * **:private_key** The key file containing the private SSH key for :git_user
48
+ * **:public_key** The key file containing the public SSH key for :git_user
49
+ * **:author_name:** The git author name to commit with (default: 'gitolite-rugged gem')
50
+ * **:author_email** The git author e-mail address to commit with (default: 'gitolite-rugged@localhost')
51
+ * **:commit_msg** The commit message to use when updating the repo (default: 'Commited by the gitolite-rugged gem')
52
+
53
+ ### Managing Public Keys ###
54
+
55
+ To add a key, create a `SSHKey` object and use the `add_key(key)` method of GitoliteAdmin.
56
+
57
+ # From filesystem
58
+ key_from_file = SSHKey.from_file("/home/alice/.ssh/id_rsa.pub")
59
+
60
+ # From String, which requires us to add an owner manually
61
+ key_from_string = SSHKey.from_string('ssh-rsa AAAAB3N/* .... */JjZ5SgfIKab bob@localhost', 'bob')
62
+
63
+ admin.add_key(key_from_string)
64
+ admin.add_key(key_from_file)
65
+
66
+ Note that you can add a *location* using the syntax described in [the Gitolite documentation](http://gitolite.com/gitolite/users.html#old-style-multi-keys).
67
+
68
+
69
+ To write out the changes to the keys to the filesystem and push them to gitolite, call `admin.save_and_apply`.
70
+ You can also manually call `admin.save` to commit the changes locally, but not push them.
71
+
72
+
73
+ ### Managing Repositories ###
74
+
75
+ To add a new repository, we first create and configure it, and then add it to the memory representation of gitolite:
76
+
77
+ repo = Gitolite::Config::Repo.new('foobar')
78
+ repo.add_permission("RW+", "alice", "bob")
79
+
80
+ # Add the repo
81
+ admin.config.add_repo(repo)
82
+
83
+ To remove a repository called 'foobar', execute `config.rm_repo('foobar')`.
84
+
85
+
86
+ ### Groups ###
87
+
88
+ As in the [Gitolite Config](http://gitolite.com/gitolite/groups.html) you can define groups as an alias to repos or users.
89
+
90
+ # Creating a group
91
+ devs = Gitolite::Config::Group.new('developers')
92
+ devs.add_users("alice", "bob")
93
+
94
+ # Adding a group to config
95
+ admin.config.add_group(devs)
96
+
97
+
98
+
99
+ ## Copyrights & License
100
+ gitolite-rugged is completely free and open source and released under the [MIT License](https://github.com/oliverguenther/gitolite/blob/devel/LICENSE.txt).
101
+
102
+ Copyright (c) 2014 Oliver Günther (mail@oliverguenther.de)
103
+
104
+ Based on the jbox-gitolite fork by Nicolas Rodriguez, which itself is based on the original gitolite gem by Stafford Brunk.
105
+
106
+ Copyright (c) 2013-2014 Nicolas Rodriguez (nrodriguez@jbox-web.com), JBox Web (http://www.jbox-web.com) [![endorse](https://api.coderwall.com/n-rodriguez/endorsecount.png)](https://coderwall.com/n-rodriguez)
107
+
108
+ Copyright (c) 2011-2013 Stafford Brunk (stafford.brunk@gmail.com)
data/Rakefile ADDED
@@ -0,0 +1,59 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake'
5
+ require 'rspec/core/rake_task'
6
+ require 'rdoc/task'
7
+
8
+
9
+ ## Helper Functions
10
+ def name
11
+ @name ||= Dir['*.gemspec'].first.split('.').first
12
+ end
13
+
14
+
15
+ def version
16
+ line = File.read("lib/#{name}/version.rb")[/^\s*VERSION\s*=\s*.*/]
17
+ line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
18
+ end
19
+
20
+
21
+ ## RDoc Task
22
+ Rake::RDocTask.new do |rdoc|
23
+ rdoc.rdoc_dir = 'rdoc'
24
+ rdoc.title = "#{name} #{version}"
25
+ rdoc.rdoc_files.include('README*')
26
+ rdoc.rdoc_files.include('lib/**/*.rb')
27
+ end
28
+
29
+
30
+ ## Other Tasks
31
+ desc "Open an irb session preloaded with this library"
32
+ task :console do
33
+ sh "irb -rubygems -r ./lib/#{name}.rb"
34
+ end
35
+
36
+
37
+ desc "Show library version"
38
+ task :version do
39
+ puts "#{name} #{version}"
40
+ end
41
+
42
+
43
+ desc "Start unit tests"
44
+ task :test => :default
45
+ task :default do
46
+ RSpec::Core::RakeTask.new(:spec) do |config|
47
+ config.rspec_opts = "--color --format nested --fail-fast"
48
+ end
49
+ Rake::Task["spec"].invoke
50
+ end
51
+
52
+
53
+ desc "Start unit tests in JUnit format"
54
+ task :test_junit do
55
+ RSpec::Core::RakeTask.new(:spec) do |config|
56
+ config.rspec_opts = "--format RspecJunitFormatter --out junit/rspec.xml"
57
+ end
58
+ Rake::Task["spec"].invoke
59
+ end
data/gitolite.gemspec ADDED
@@ -0,0 +1,36 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "gitolite/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "gitolite-rugged"
7
+ s.version = Gitolite::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Oliver Günther"]
10
+ s.email = ["mail@oliverguenther.de"]
11
+ s.homepage = "https://github.com/oliverguenther/gitolite-rugged"
12
+ s.summary = %q{A Ruby gem for manipulating the Gitolite Git backend via the gitolite-admin repository.}
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
+ s.license = 'MIT'
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"
23
+
24
+ s.add_development_dependency "simplecov", "~> 0.8.2"
25
+ s.add_development_dependency "simplecov-rcov", "~> 0.2.3"
26
+
27
+ s.add_development_dependency "rspec_junit_formatter", "~> 0.1.6"
28
+
29
+ s.add_dependency "rugged", ">= 0.19.0"
30
+ s.add_dependency "gratr19", "~> 0.4.4.1"
31
+
32
+ s.files = `git ls-files`.split("\n")
33
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
34
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
35
+ s.require_paths = ["lib"]
36
+ end
@@ -0,0 +1,62 @@
1
+ module Gitolite
2
+ class Config
3
+
4
+ # Represents a group inside the gitolite configuration. The name and users
5
+ # options are all encapsulated in this class. All users are stored as
6
+ # Strings!
7
+ class Group
8
+
9
+ attr_accessor :name, :users
10
+
11
+ PREPEND_CHAR = '@'
12
+
13
+ def initialize(name)
14
+ # naively remove the prepend char
15
+ # I don't think you can have two of them in a group name
16
+ @name = name.gsub(PREPEND_CHAR, '')
17
+ @users = []
18
+ end
19
+
20
+
21
+ def empty!
22
+ @users.clear
23
+ end
24
+
25
+
26
+ def add_user(user)
27
+ return if has_user?(user)
28
+ @users.push(user.to_s).sort!
29
+ end
30
+
31
+
32
+ def add_users(*users)
33
+ fixed_users = users.flatten.map{ |u| u.to_s }
34
+ @users.concat(fixed_users).sort!.uniq!
35
+ end
36
+
37
+
38
+ def rm_user(user)
39
+ @users.delete(user.to_s)
40
+ end
41
+
42
+
43
+ def has_user?(user)
44
+ @users.include? user.to_s
45
+ end
46
+
47
+
48
+ def size
49
+ @users.length
50
+ end
51
+
52
+
53
+ def to_s
54
+ members = @users.join(' ')
55
+ name = "#{PREPEND_CHAR}#{@name}"
56
+ "#{name.ljust(20)}= #{members}\n"
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,107 @@
1
+ module Gitolite
2
+ class Config
3
+
4
+ # Represents a repo inside the gitolite configuration. The name, permissions, and git config
5
+ # options are all encapsulated in this class
6
+ class Repo
7
+
8
+ ALLOWED_PERMISSIONS = /-|C|R|RW\+?(?:C?D?|D?C?)M?/
9
+
10
+ attr_accessor :permissions, :name, :config, :options, :owner, :description
11
+
12
+ def initialize(name)
13
+ # Store the perm hash in a lambda since we have to create a new one on every deny rule
14
+ # The perm hash is stored as a 2D hash, with individual permissions being the first
15
+ # degree and individual refexes being the second degree. Both Hashes must respect order
16
+ @perm_hash_lambda = lambda { Hash.new {|k,v| k[v] = Hash.new{|k2, v2| k2[v2] = [] }} }
17
+ @permissions = Array.new.push(@perm_hash_lambda.call)
18
+
19
+ @name = name
20
+ @config = {} # git config
21
+ @options = {} # gitolite config
22
+ end
23
+
24
+
25
+ def clean_permissions
26
+ @permissions = Array.new.push(@perm_hash_lambda.call)
27
+ end
28
+
29
+
30
+ def add_permission(perm, refex = "", *users)
31
+ if perm =~ ALLOWED_PERMISSIONS
32
+ #Handle deny rules
33
+ if perm == '-'
34
+ @permissions.push(@perm_hash_lambda.call)
35
+ end
36
+
37
+ @permissions.last[perm][refex].concat users.flatten
38
+ @permissions.last[perm][refex].uniq!
39
+ else
40
+ raise InvalidPermissionError, "#{perm} is not in the allowed list of permissions!"
41
+ end
42
+ end
43
+
44
+
45
+ def set_git_config(key, value)
46
+ @config[key] = value
47
+ end
48
+
49
+
50
+ def unset_git_config(key)
51
+ @config.delete(key)
52
+ end
53
+
54
+
55
+ def set_gitolite_option(key, value)
56
+ @options[key] = value
57
+ end
58
+
59
+
60
+ def unset_gitolite_option(key)
61
+ @options.delete(key)
62
+ end
63
+
64
+
65
+ def to_s
66
+ repo = "repo #{@name}\n"
67
+
68
+ @permissions.each do |perm_hash|
69
+ perm_hash.each do |perm, list|
70
+ list.each do |refex, users|
71
+ repo += " " + perm.ljust(6) + refex.ljust(25) + "= " + users.join(' ') + "\n"
72
+ end
73
+ end
74
+ end
75
+
76
+ @config.each do |k, v|
77
+ repo += " config " + k + " = " + v + "\n"
78
+ end
79
+
80
+ @options.each do |k, v|
81
+ repo += " option " + k + " = " + v + "\n"
82
+ end
83
+
84
+ repo
85
+ end
86
+
87
+
88
+ def gitweb_description
89
+ if @description.nil?
90
+ nil
91
+ else
92
+ desc = "#{@name} "
93
+ desc += "\"#{@owner}\" " unless @owner.nil?
94
+ desc += "= \"#{@description}\""
95
+ end
96
+ end
97
+
98
+
99
+ # Gets raised if a permission that isn't in the allowed
100
+ # list is passed in
101
+ class InvalidPermissionError < ArgumentError
102
+ end
103
+
104
+ end
105
+
106
+ end
107
+ end