mirror_github 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ config.yml
2
+ *.gem
3
+ .bundle
4
+ Gemfile.lock
5
+ pkg/*
6
+
data/BSD-LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ Copyright 2011 Singlebrook Technology, Inc. All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without modification, are
4
+ permitted provided that the following conditions are met:
5
+
6
+ 1. Redistributions of source code must retain the above copyright notice, this list of
7
+ conditions and the following disclaimer.
8
+
9
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list
10
+ of conditions and the following disclaimer in the documentation and/or other materials
11
+ provided with the distribution.
12
+
13
+ THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND ANY EXPRESS OR IMPLIED
14
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
15
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
16
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
18
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
19
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
20
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
21
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22
+
23
+ The views and conclusions contained in the software and documentation are those of the
24
+ authors and should not be interpreted as representing official policies, either expressed
25
+ or implied, of Singlebrook Technology.
26
+
27
+ ===============
28
+ This Simplified BSD License courtesy of http://en.wikipedia.org/wiki/BSD_license
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "http://rubygems.org"
2
+ gemspec
data/README.rdoc ADDED
@@ -0,0 +1,23 @@
1
+ = Mirror Github
2
+
3
+ This script will cycle through all repositories belonging to an organization and clone a mirror of them to a specified directory.
4
+
5
+ A mirror is a bare repository that is suitable for future cloning, if necessary.
6
+
7
+ == Installation
8
+
9
+ gem install mirror_github
10
+
11
+ Create a mirror_github_config.yml that contains your GitHub username, password, and organization name. There is a config_example.yml file that demonstrates the structure. It will look something like this:
12
+
13
+ github:
14
+ username: johnnytest
15
+ password: sOOperSecret
16
+ org: my_orgs_github_account_name
17
+
18
+ Obviously, the user credentials you define in this file need to have access to the specified organization.
19
+
20
+ Then:
21
+
22
+ mirror_github --config-file=/path/to/your/mirror_github_config.yml --backup-dir=/path/to/github/mirror/directory
23
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
data/bin/mirror_github ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib_dir = File.join(File.dirname(__FILE__), '..', 'lib')
4
+ $LOAD_PATH.unshift lib_dir if File.directory?(lib_dir)
5
+
6
+ require 'mirror_github'
7
+
8
+ github_mirror = MirrorGithub::Base.new(ARGV)
9
+ github_mirror.mirror_all
@@ -0,0 +1,49 @@
1
+ module MirrorGithub
2
+
3
+ class Base
4
+
5
+ def initialize(args = nil)
6
+ parse_arguments(args)
7
+ end
8
+
9
+ # Backs up all repositories from the organization defined in the config.
10
+ def mirror_all
11
+ puts "Mirroring #{github_connection.repositories.size} repositories..."
12
+ github_connection.repositories.each do |repo|
13
+ puts "Beginning #{repo.name}"
14
+ mirror repo
15
+ puts "Finished #{repo.name}"
16
+ puts ""
17
+ end
18
+ end
19
+
20
+ # Creates a new mirroir repository at the target directory (if necessary)
21
+ # and fetches any updates.
22
+ def mirror(repository)
23
+ git = Git.new(config.backup_directory, repository)
24
+ git.create_mirror unless git.mirror_exists?
25
+ git.update_mirror
26
+ end
27
+
28
+ def config
29
+ @config ||= Configuration.new
30
+ end
31
+
32
+ def github_connection
33
+ @github_connection ||= Github.new(config.username, config.password, config.org)
34
+ end
35
+
36
+ def parse_arguments(args)
37
+ args.each do |arg|
38
+ option, value = arg.split('=').map { |v| v.chomp.strip }
39
+ next unless option && value
40
+ case option
41
+ when "--config-file" then Configuration.config_file_path = value
42
+ when "--backup-dir" then config.backup_directory = value
43
+ end
44
+ end
45
+ end
46
+
47
+ end
48
+
49
+ end
@@ -0,0 +1,42 @@
1
+ require 'yaml'
2
+
3
+ module MirrorGithub
4
+ class Configuration
5
+
6
+ class << self
7
+ def config_file_path
8
+ @config_file_path ||= File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'config.yml'))
9
+ end
10
+
11
+ def config_file_path=(val)
12
+ @config_file_path = File.expand_path(val)
13
+ end
14
+ end
15
+
16
+ attr_accessor :username, :password, :org, :backup_directory
17
+
18
+ def initialize
19
+ load_config
20
+ end
21
+
22
+ def backup_directory=(val)
23
+ @backup_directory = File.expand_path(val)
24
+ end
25
+
26
+ private
27
+
28
+ def load_config
29
+ raise "Please create a config.yml file at #{Configuration.config_file_path}, see test/config_example.yml for an example." unless File.exists?(Configuration.config_file_path)
30
+ config_file = YAML::load_file(Configuration.config_file_path)
31
+ if config_file['github']
32
+ self.username = config_file['github']['username']
33
+ self.password = config_file['github']['password']
34
+ self.org = config_file['github']['org']
35
+ end
36
+ if config_file['system']
37
+ self.backup_directory = config_file['system']['backup_directory']
38
+ end
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,45 @@
1
+ module MirrorGithub
2
+
3
+ class Git
4
+ attr_accessor :repository
5
+ attr_writer :target_dir
6
+
7
+ # Takes a target_dir string and a Repository class
8
+ def initialize(target_dir, repository)
9
+ self.target_dir = target_dir
10
+ raise "GitHub backup directory, #{self.target_dir}, does not exist!" unless File.directory?(self.target_dir)
11
+
12
+ self.repository = repository
13
+ end
14
+
15
+ def create_mirror
16
+ `#{go_to_target_dir} && git clone --mirror #{repository.ssh_url} #{mirror_directory}`
17
+ end
18
+
19
+ def go_to_target_dir
20
+ "cd #{target_dir}"
21
+ end
22
+
23
+ def go_to_mirror_dir
24
+ "cd #{File.join(target_dir, mirror_directory)}"
25
+ end
26
+
27
+ def mirror_directory
28
+ "#{repository.name}.git"
29
+ end
30
+
31
+ def mirror_exists?
32
+ File.exists? File.join(target_dir, "#{mirror_directory}")
33
+ end
34
+
35
+ def target_dir
36
+ File.expand_path(@target_dir)
37
+ end
38
+
39
+ def update_mirror
40
+ `#{go_to_mirror_dir} && git fetch`
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,37 @@
1
+ require 'rest_client'
2
+ require 'json'
3
+
4
+ module MirrorGithub
5
+ class Github
6
+
7
+ class << self
8
+ def api_url
9
+ 'https://api.github.com'
10
+ end
11
+ end
12
+
13
+ attr_accessor :connection, :username, :password, :org
14
+
15
+ def initialize(username, password, org = nil)
16
+ self.username = username
17
+ self.password = password
18
+ self.org = org
19
+ self.connection = RestClient::Resource.new Github.api_url, :user => username, :password => password
20
+ end
21
+
22
+ # Return a list of the current repositories for an organization
23
+ def repositories
24
+ return [] unless org
25
+ JSON::parse(connection["orgs/#{org}/repos"].get).collect do |repo_hash|
26
+ Repository.new(:ssh_url => repo_hash['ssh_url'],
27
+ :private => repo_hash['private'],
28
+ :created_at => repo_hash["created_at"],
29
+ :pushed_at => repo_hash["pushed_at"],
30
+ :name => repo_hash["name"])
31
+ end
32
+ end
33
+
34
+
35
+
36
+ end
37
+ end
@@ -0,0 +1,13 @@
1
+ module MirrorGithub
2
+ class Repository
3
+ attr_accessor :ssh_url, :html_url, :private, :created_at, :pushed_at, :name
4
+ alias :private? :private
5
+
6
+ def initialize(input = {})
7
+ input.each do |k, v|
8
+ self.send("#{k}=", v)
9
+ end
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module MirrorGithub
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,9 @@
1
+ # Make sure our lib is in our load path
2
+ $: << File.expand_path(File.dirname(__FILE__))
3
+
4
+ require 'rubygems'
5
+ require 'mirror_github/base'
6
+ require 'mirror_github/configuration'
7
+ require 'mirror_github/repository'
8
+ require 'mirror_github/github'
9
+ require 'mirror_github/git'
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "mirror_github/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "mirror_github"
7
+ s.version = MirrorGithub::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Casey Dreier"]
10
+ s.email = ["casey.dreier@gmail.com"]
11
+ s.homepage = "https://github.com/singlebrook/mirror_github"
12
+ s.summary = %q{Command-line library for mirroring an Organization's GitHub repositories}
13
+ s.description = %q{Command-line library for mirroring an Organization's GitHub repositories}
14
+ s.license = 'BSD'
15
+
16
+ s.rubyforge_project = "mirror_github"
17
+
18
+ s.add_dependency 'rest-client'
19
+
20
+ s.add_development_dependency 'fakeweb'
21
+
22
+ s.files = `git ls-files`.split("\n")
23
+ s.test_files = `git ls-files -- {test}/*`.split("\n")
24
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
25
+ s.require_paths = ["lib"]
26
+ end
@@ -0,0 +1,7 @@
1
+ github:
2
+ username: johnnytest
3
+ password: sOOperSecret
4
+ org: singlebrook
5
+
6
+ system:
7
+ backup_directory: /var/backups/github
@@ -0,0 +1,17 @@
1
+ require 'test_helper'
2
+
3
+ class MirrorGithub::ConfigurationTest < Test::Unit::TestCase
4
+
5
+ def test_config_file_default
6
+ assert_not_nil MirrorGithub::Configuration.config_file_path
7
+ end
8
+
9
+ def test_loads_config_file
10
+ MirrorGithub::Configuration.config_file_path = File.join(File.expand_path(File.dirname(__FILE__)), 'config_example.yml')
11
+ config = MirrorGithub::Configuration.new
12
+ assert config.username
13
+ assert config.password
14
+ assert config.org
15
+ end
16
+
17
+ end
@@ -0,0 +1,56 @@
1
+ [
2
+ {
3
+ "html_url": "https://github.com/test/project_proposal_application",
4
+ "url": "https://api.github.com/repos/test/project_proposal_application",
5
+ "homepage": "",
6
+ "watchers": 2,
7
+ "language": "Ruby",
8
+ "clone_url": "https://github.com/test/project_proposal_application.git",
9
+ "git_url": "git://github.com/test/project_proposal_application.git",
10
+ "master_branch": null,
11
+ "fork": false,
12
+ "pushed_at": "2011-01-19T22:18:40Z",
13
+ "created_at": "2011-01-04T20:28:33Z",
14
+ "open_issues": 0,
15
+ "private": true,
16
+ "size": 380,
17
+ "ssh_url": "git@github.com:test/project_proposal_application.git",
18
+ "owner": {
19
+ "url": "https://api.github.com/users/test",
20
+ "avatar_url": "https://secure.gravatar.com/avatar/3.png",
21
+ "login": "test",
22
+ "id": 99999
23
+ },
24
+ "forks": 0,
25
+ "description": "An interactive proposal application for potential clients",
26
+ "name": "project_proposal_application",
27
+ "svn_url": "https://svn.github.com/test/project_proposal_application"
28
+ },
29
+ {
30
+ "html_url": "https://github.com/test/capistrano_drupal",
31
+ "url": "https://api.github.com/repos/test/capistrano_drupal",
32
+ "homepage": "",
33
+ "watchers": 4,
34
+ "language": "Ruby",
35
+ "clone_url": "https://github.com/test/capistrano_drupal.git",
36
+ "git_url": "git://github.com/test/capistrano_drupal.git",
37
+ "master_branch": null,
38
+ "fork": false,
39
+ "pushed_at": "2011-02-04T22:18:54Z",
40
+ "created_at": "2011-02-03T01:44:44Z",
41
+ "open_issues": 0,
42
+ "private": false,
43
+ "size": 156,
44
+ "ssh_url": "git@github.com:test/capistrano_drupal.git",
45
+ "owner": {
46
+ "url": "https://api.github.com/users/test",
47
+ "avatar_url": "https://secure.gravatar.com/avatar/343cbf1f96d4fe3b85.png",
48
+ "login": "test",
49
+ "id": 99999
50
+ },
51
+ "forks": 1,
52
+ "description": "A Capistrano deployment setup for Drupal projects.",
53
+ "name": "capistrano_drupal",
54
+ "svn_url": "https://svn.github.com/test/capistrano_drupal"
55
+ }
56
+ ]
data/test/git_test.rb ADDED
@@ -0,0 +1,26 @@
1
+ require 'test_helper'
2
+
3
+ class MirrorGithub::GitTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @tmp_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'tmp'))
7
+ Dir.mkdir(@tmp_dir) unless File.directory?(@tmp_dir)
8
+ end
9
+
10
+ def test_initialize
11
+ r = MirrorGithub::Repository.new(:ssh_url => 'ssh://git@github.com:test')
12
+ git = MirrorGithub::Git.new(@tmp_dir, r)
13
+ end
14
+
15
+ def test_initialize_raises_error_if_directory_does_not_exist
16
+ r = MirrorGithub::Repository.new(:ssh_url => 'ssh://git@github.com:test')
17
+ assert_raise RuntimeError do
18
+ MirrorGithub::Git.new('sdfl9ij390', r)
19
+ end
20
+ end
21
+
22
+ def teardown
23
+ Dir.delete(@tmp_dir)
24
+ end
25
+
26
+ end
@@ -0,0 +1,27 @@
1
+ require 'test_helper'
2
+ require 'fakeweb'
3
+
4
+ class MirrorGithub::GithubTest < Test::Unit::TestCase
5
+
6
+ def setup
7
+ FakeWeb.allow_net_connect = false
8
+ FakeWeb.register_uri(:get, MirrorGithub::Github.api_url, :body => "Unauthorized", :status => ["401", "Unauthorized"])
9
+ FakeWeb.register_uri(:get, 'https://johnnytest:sOOperSecret@api.github.com/orgs/parent_org/repos', :body => organization_json, :content_type => "application/json")
10
+ end
11
+
12
+ def teardown
13
+ FakeWeb.allow_net_connect = true
14
+ end
15
+
16
+ def test_repositories
17
+ github = MirrorGithub::Github.new('johnnytest', 'sOOperSecret', 'parent_org')
18
+ assert github.repositories.respond_to?(:size)
19
+ assert github.repositories.size > 0
20
+ assert !github.repositories.map {|r| r.ssh_url }.compact.empty?
21
+ end
22
+
23
+ def organization_json
24
+ @org_contents ||= File.open(File.join(File.expand_path(File.dirname(__FILE__)), 'fixtures', 'repositories_listing.json')).read
25
+ end
26
+
27
+ end
@@ -0,0 +1,11 @@
1
+ require 'test_helper'
2
+
3
+ class MirrorGithub::RepositoryTest < Test::Unit::TestCase
4
+
5
+ def test_initialize
6
+ r = MirrorGithub::Repository.new(:ssh_url => "ssh_url", :private => true)
7
+ assert_equal "ssh_url", r.ssh_url
8
+ assert_equal true, r.private?
9
+ end
10
+
11
+ end
@@ -0,0 +1,6 @@
1
+ # Make sure our lib is in our load path
2
+ $: << File.expand_path(File.dirname(__FILE__))
3
+
4
+ require 'rubygems'
5
+ require 'test/unit'
6
+ require 'lib/mirror_github'
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mirror_github
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Casey Dreier
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-07-12 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rest-client
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: fakeweb
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id002
49
+ description: Command-line library for mirroring an Organization's GitHub repositories
50
+ email:
51
+ - casey.dreier@gmail.com
52
+ executables:
53
+ - mirror_github
54
+ extensions: []
55
+
56
+ extra_rdoc_files: []
57
+
58
+ files:
59
+ - .gitignore
60
+ - BSD-LICENSE
61
+ - Gemfile
62
+ - README.rdoc
63
+ - Rakefile
64
+ - bin/mirror_github
65
+ - lib/mirror_github.rb
66
+ - lib/mirror_github/base.rb
67
+ - lib/mirror_github/configuration.rb
68
+ - lib/mirror_github/git.rb
69
+ - lib/mirror_github/github.rb
70
+ - lib/mirror_github/repository.rb
71
+ - lib/mirror_github/version.rb
72
+ - mirror_github.gemspec
73
+ - test/config_example.yml
74
+ - test/configuration_test.rb
75
+ - test/fixtures/repositories_listing.json
76
+ - test/git_test.rb
77
+ - test/github_test.rb
78
+ - test/repository_test.rb
79
+ - test/test_helper.rb
80
+ has_rdoc: true
81
+ homepage: https://github.com/singlebrook/mirror_github
82
+ licenses:
83
+ - BSD
84
+ post_install_message:
85
+ rdoc_options: []
86
+
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: 3
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ hash: 3
104
+ segments:
105
+ - 0
106
+ version: "0"
107
+ requirements: []
108
+
109
+ rubyforge_project: mirror_github
110
+ rubygems_version: 1.6.2
111
+ signing_key:
112
+ specification_version: 3
113
+ summary: Command-line library for mirroring an Organization's GitHub repositories
114
+ test_files: []
115
+