salmon 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5681ea3270506cddee79f40f08fd07bd8009eca9
4
+ data.tar.gz: 2da30d59aa8238977a2d3d47dfbf4953d5b9c6f3
5
+ SHA512:
6
+ metadata.gz: a4d107edb4b86e0c8fda197cae89d251ed05cc217daf05ac45f92d66fb9c3494a10f1f53d3d88a63fc1c67ca58d1f82db1e492892028a850061af78951664c67
7
+ data.tar.gz: 3d17cb4e642499b2c1ffd2f630dcf80d7ab022e55f294e2d53aa05108baac01cb296109ed62c0ccb409b83c9d84d0dc35264b3eb0b5a0288f35757d9a1a640d8
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Johnny Sheeley
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,24 @@
1
+ # Salmon
2
+ A Ruby tool for migrating a collection of repositories from one Github instance to another.
3
+
4
+ ## Usage
5
+ - Create ```~/.salmon``` with YAML data for the Github site(s) you plan on using so that your tokens/passwords aren't in bash history
6
+ ```
7
+ #defaults to github.com
8
+ github:
9
+ basic_auth: 'sheeley:password'
10
+
11
+ # your enterprise install
12
+ enterprise:
13
+ basic_auth: TOKENTOKENTOKEN
14
+ endpoint: https://github.enterprise.com/api/v3
15
+ ```
16
+ For a list of supported settings, check out the [Github API gem](https://github.com/peter-murach/github)
17
+ - Run salmon
18
+ ```
19
+ # copy from one Github account to another
20
+ salmon -s github:sheeley -t github:sheeley2
21
+
22
+ # copy from Github.com to an enterprise Github, include tags and git output
23
+ salmon -p -v -s github:sheeley -t enterprise:sheeley
24
+ ```
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'salmon'
3
+
4
+ Salmon::Application.run
@@ -0,0 +1,3 @@
1
+ require 'salmon/config'
2
+ require 'salmon/salmon'
3
+ require 'salmon/version'
@@ -0,0 +1,63 @@
1
+ require 'yaml'
2
+
3
+ module Salmon
4
+ class Config
5
+ def self.parse_options(args)
6
+ options = OpenStruct.new
7
+
8
+ path = File.expand_path('~/.salmon')
9
+ abort("Please create a YAML server config file at ~/.salmon") if not File.readable?(path)
10
+ githubs = YAML.load(File.read(path))
11
+
12
+ options.temp_path = 'salmon'
13
+ options.push_tags = true
14
+ options.push_branches = ['*']
15
+ options.verbose = true
16
+
17
+ OptionParser.new do |opts|
18
+ opts.banner = "Usage: salmon [options]"
19
+
20
+ opts.separator ""
21
+ opts.separator "Available sites:"
22
+ opts.separator githubs.keys.join(", ")
23
+ opts.separator ""
24
+
25
+ opts.on("-s", "--source [SITE:ACCOUNT]", "Site name or source:destination string. Available: #{githubs.keys.join(', ')}") do |source|
26
+ source = source.split(":")
27
+ options.source = OpenStruct.new(githubs[source.first])
28
+ options.source.name = source.last
29
+ end
30
+
31
+ opts.on("-t", "--target [SITE:ACCOUNT]", "Organization or user name(s). Source only or source:destination.") do |source|
32
+ source = source.split(":")
33
+ options.dest = OpenStruct.new(githubs[source.first])
34
+ options.dest.name = source.last
35
+ end
36
+
37
+ #TODO: clone only might be nice
38
+
39
+ opts.on("-p", "--tags", "Include tags when pushing") do |v|
40
+ options.push_tags = v
41
+ end
42
+
43
+ opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
44
+ options[:verbose] = v
45
+ end
46
+
47
+ opts.on_tail("--version", "Show version") do
48
+ puts Salmon::VERSION
49
+ exit
50
+ end
51
+ end.parse!(args)
52
+ self.validate!(options)
53
+ options
54
+ end
55
+
56
+ def self.validate!(options)
57
+ {source: options.source, destination: options.dest}.each do |title, settings|
58
+ abort("You must include #{title.to_s} settings") if settings.nil?
59
+ abort("Please include name for both #{title.to_s} account") if settings.name.nil?
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,96 @@
1
+ require 'github_api'
2
+ require 'optparse'
3
+ require 'ostruct'
4
+
5
+ module Salmon
6
+ class Application
7
+
8
+ def self.run
9
+ app = Application.new
10
+ @options = app.parse_options(ARGV)
11
+ source_github = app.config_github(@options.source)
12
+ destination_github = app.config_github(@options.dest)
13
+
14
+ repos = app.get_source_repos(source_github)
15
+
16
+ abort("Retrieved no repositories") if repos.nil? or repos.empty?
17
+
18
+ app.clone_repositories(destination_github, repos)
19
+ end
20
+
21
+ def parse_options(args)
22
+ @options = Salmon::Config.parse_options(args)
23
+ end
24
+
25
+ def config_github(user_config)
26
+ gh = Github.new do |config|
27
+ user_config.marshal_dump.each do |key, value|
28
+ config.send("#{key}=", value) if config.respond_to? "#{key}="
29
+ end
30
+ config.auto_pagination = true
31
+ config.per_page = 100
32
+ end
33
+ account = gh.users.get(user: user_config.name)
34
+ user_config.type = account.type.downcase.to_sym
35
+ gh
36
+ end
37
+
38
+ def get_source_repos(github)
39
+ puts "Getting list of repos for #{@options.source.type}: #{@options.source.name}" if @options.verbose
40
+ begin
41
+ key = @options.source.type == :user ? :user : :org
42
+ repos = github.repos.list("#{key}" => @options.source.name)
43
+ rescue StandardError => e
44
+ abort("Error getting list: #{e}")
45
+ end
46
+ repos
47
+ end
48
+
49
+ def clone_repositories(github, repos)
50
+ temp_dir = Dir.mktmpdir(@options.temp_path)
51
+ i = 1
52
+
53
+ repos.each do |repo|
54
+ repo.org = (@options.dest.type == :organization) ? @options.dest.name : nil
55
+ repo.user = (@options.dest.type == :user) ? @options.dest.name : nil
56
+ repo.created = false
57
+ # TODO: error handling
58
+ puts "Working on #{repo.name}: #{i}/#{repos.length}"
59
+ local_repo = "#{temp_dir}/#{repo.name}"
60
+ eat_output = @options.verbose ? '' : ' > /dev/null'
61
+ clone_cmd = "git clone #{repo.ssh_url} #{local_repo}#{eat_output}"
62
+
63
+ system(clone_cmd)
64
+ abort('Clone failed!') if $? != 0
65
+
66
+ puts "Creating repo on #{github.site}" if @options.verbose
67
+ begin
68
+ new_repo = github.repos.create(repo)
69
+ repo.created = true
70
+ rescue Github::Error::UnprocessableEntity => ue
71
+ if ue.http_status_code == 422
72
+ puts "Repo already exists." if @options.verbose
73
+ new_repo = github.repos.get(@options.dest.name, repo.name)
74
+ else
75
+ puts(ue)
76
+ end
77
+ rescue StandardError => se
78
+ puts(se)
79
+ end
80
+
81
+ if not new_repo.nil?
82
+ Dir.chdir(local_repo) do
83
+ system("git remote add clone #{new_repo['ssh_url']} #{eat_output}")
84
+ system("git push --all clone #{eat_output}")
85
+ system("git push --tags clone #{eat_output}") if @options.push_tags
86
+ puts "Pushed" if !@options.verbose
87
+ end
88
+ else
89
+ puts "Repo wasn't created, can't push. :("
90
+ end
91
+
92
+ i += 1
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,3 @@
1
+ module Salmon
2
+ VERSION = '0.0.2'
3
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: salmon
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Johnny Sheeley
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-10-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: github_api
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 0.10.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 0.10.2
27
+ description: A migration tool for Github accounts and organizations.
28
+ email: jsheeley@aigee.org
29
+ executables:
30
+ - salmon
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - README.md
35
+ - LICENSE
36
+ - lib/salmon.rb
37
+ - bin/salmon
38
+ - lib/salmon/config.rb
39
+ - lib/salmon/salmon.rb
40
+ - lib/salmon/version.rb
41
+ homepage: https://github.com/sheeley/Salmon
42
+ licenses:
43
+ - MIT
44
+ metadata: {}
45
+ post_install_message:
46
+ rdoc_options: []
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ requirements: []
60
+ rubyforge_project:
61
+ rubygems_version: 2.1.10
62
+ signing_key:
63
+ specification_version: 4
64
+ summary: A migration tool for Github accounts and organizations.
65
+ test_files: []