off_github 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +10 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/bin/off_github +9 -0
- data/lib/off_github.rb +218 -0
- data/off_github.gemspec +60 -0
- data/test/helper.rb +10 -0
- data/test/test_off_github.rb +30 -0
- metadata +85 -0
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Maxim Chernyak
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "off_github"
|
8
|
+
gem.summary = %Q{Migrate locally installed gems from github to gemcutter.}
|
9
|
+
gem.description = %Q{A simple tool which helps migrate your locally installed gems from github to gemcutter. It will find all the gems installed from github and recognize them on gemcutter using with some recursive string matching. It will then present you with a list of everything it will migrate and ask for permission before touching anything.}
|
10
|
+
gem.email = "max@bitsonnet.com"
|
11
|
+
gem.homepage = "http://github.com/maxim/off_github"
|
12
|
+
gem.authors = ["Maxim Chernyak"]
|
13
|
+
gem.add_dependency "hirb", ">=0.2.4"
|
14
|
+
gem.add_development_dependency "shoulda", ">= 0"
|
15
|
+
gem.files.include %w(lib/*)
|
16
|
+
end
|
17
|
+
Jeweler::GemcutterTasks.new
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'rake/testtask'
|
23
|
+
Rake::TestTask.new(:test) do |test|
|
24
|
+
test.libs << 'lib' << 'test'
|
25
|
+
test.pattern = 'test/**/test_*.rb'
|
26
|
+
test.verbose = true
|
27
|
+
end
|
28
|
+
|
29
|
+
begin
|
30
|
+
require 'rcov/rcovtask'
|
31
|
+
Rcov::RcovTask.new do |test|
|
32
|
+
test.libs << 'test'
|
33
|
+
test.pattern = 'test/**/test_*.rb'
|
34
|
+
test.verbose = true
|
35
|
+
end
|
36
|
+
rescue LoadError
|
37
|
+
task :rcov do
|
38
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
task :test => :check_dependencies
|
43
|
+
|
44
|
+
task :default => :test
|
45
|
+
|
46
|
+
require 'rake/rdoctask'
|
47
|
+
Rake::RDocTask.new do |rdoc|
|
48
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
49
|
+
|
50
|
+
rdoc.rdoc_dir = 'rdoc'
|
51
|
+
rdoc.title = "html_press #{version}"
|
52
|
+
rdoc.rdoc_files.include('README*')
|
53
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
54
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.1
|
data/bin/off_github
ADDED
data/lib/off_github.rb
ADDED
@@ -0,0 +1,218 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'hirb'
|
5
|
+
require 'strscan'
|
6
|
+
|
7
|
+
module VersionSorter
|
8
|
+
extend self
|
9
|
+
|
10
|
+
def sort(list)
|
11
|
+
ss = StringScanner.new ''
|
12
|
+
pad_to = 0
|
13
|
+
list.each { |li| pad_to = li.size if li.size > pad_to }
|
14
|
+
|
15
|
+
list.sort_by do |li|
|
16
|
+
ss.string = li
|
17
|
+
parts = ''
|
18
|
+
|
19
|
+
if match = ss.scan_until(/\d+|[a-z]+/i)
|
20
|
+
parts << match.rjust(pad_to)
|
21
|
+
end until ss.eos?
|
22
|
+
|
23
|
+
parts
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def rsort(list)
|
28
|
+
sort(list).reverse!
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
module OffGithub
|
34
|
+
GITHUB_URL = "http://gems.github.com"
|
35
|
+
GEMCUTTER_URL = "http://gemcutter.org"
|
36
|
+
|
37
|
+
class GemList
|
38
|
+
attr_reader :list, :source, :gems
|
39
|
+
|
40
|
+
def initialize(source = nil)
|
41
|
+
if source.class == Array
|
42
|
+
@source = nil
|
43
|
+
@list = source
|
44
|
+
else
|
45
|
+
@source = source
|
46
|
+
fetch_gem_list
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def versions(gem_name)
|
51
|
+
@gems[gem_name]
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
def fetch_gem_list
|
56
|
+
out = @source ? `gem list -rs #{@source}` : `gem list --local`
|
57
|
+
gems = out.split("\n").select{|l| l =~ /\(/}.inject({}) do |hash, l|
|
58
|
+
elems = l.squeeze(' ').split(' ', 2)
|
59
|
+
hash.merge! elems.first.strip => VersionSorter.rsort(elems[1].strip.gsub(/[\(\)]/, '').split(', '))
|
60
|
+
hash
|
61
|
+
end
|
62
|
+
@list = gems.keys
|
63
|
+
@gems = gems
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class GemInvestigator
|
68
|
+
def initialize( local = GemList.new,
|
69
|
+
other = GemList.new(GEMCUTTER_URL),
|
70
|
+
github = GemList.new(GITHUB_URL))
|
71
|
+
@github = github.list
|
72
|
+
@github_gems = github.gems
|
73
|
+
@github_url = github.source
|
74
|
+
@other = other.list
|
75
|
+
@other_gems = other.gems
|
76
|
+
@other_url = other.source
|
77
|
+
@local = local.list
|
78
|
+
@local_gems = local.gems
|
79
|
+
end
|
80
|
+
|
81
|
+
def github_suspects
|
82
|
+
@github_suspects ||= @local.select{|name| looks_like_github_gem?(name)}
|
83
|
+
end
|
84
|
+
|
85
|
+
def found_matches
|
86
|
+
@found_matches ||= github_suspects.map{|name| find_match(name)}
|
87
|
+
end
|
88
|
+
|
89
|
+
def relations
|
90
|
+
@relations ||= Hash[*github_suspects.map.zip(found_matches).flatten]
|
91
|
+
end
|
92
|
+
|
93
|
+
def will_be_migrated
|
94
|
+
return @will_be_migrated if @will_be_migrated
|
95
|
+
|
96
|
+
targets = relations.select{|k, v| v}
|
97
|
+
@will_be_migrated = targets.map do |names|
|
98
|
+
gh_name, gc_name = names
|
99
|
+
local_gh_versions = @local_gems[gh_name]
|
100
|
+
local_gc_versions = @local_gems[gc_name]
|
101
|
+
gh_versions = @github_gems[gh_name]
|
102
|
+
gc_versions = @other_gems[gc_name]
|
103
|
+
|
104
|
+
action = if @local.include?(gc_name) && !newer_version?(local_gh_versions.first, gc_versions.first)
|
105
|
+
"uninstall"
|
106
|
+
elsif !newer_version?(gc_versions.first, local_gh_versions.first)
|
107
|
+
"skip"
|
108
|
+
else
|
109
|
+
"reinstall"
|
110
|
+
end
|
111
|
+
|
112
|
+
[gh_name, gc_name, action]
|
113
|
+
end.sort{|a,b| a[2] <=> b[2]}
|
114
|
+
end
|
115
|
+
|
116
|
+
def will_be_migrated_with_versions
|
117
|
+
@will_be_migrated_with_versions ||= will_be_migrated.map do |rows|
|
118
|
+
gh_name, gc_name, action = rows
|
119
|
+
[gh_name + " (#{@local_gems[gh_name].join(', ')})",
|
120
|
+
gc_name + " (#{@other_gems[gc_name].join(', ')})",
|
121
|
+
action]
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def will_not_be_migrated
|
126
|
+
@will_not_be_migrated ||= Hash[*relations.select{|k, v| !v}.flatten].keys
|
127
|
+
end
|
128
|
+
|
129
|
+
def stats
|
130
|
+
<<-STATS
|
131
|
+
|
132
|
+
GitHub gems found on #{GEMCUTTER_URL} (will be reinstalled):
|
133
|
+
#{Hirb::Helpers::AutoTable.render will_be_migrated_with_versions, :headers => [GITHUB_URL, GEMCUTTER_URL, "action"]}
|
134
|
+
|
135
|
+
reinstall = Everything ok. Gemcutter has same/newer version, which will replace installed github version.
|
136
|
+
skip = Gemcutter doesn't yet have a version that you need, only older. Not touching anything. Run this again later.
|
137
|
+
uninstall = The non-github version is already installed. Only removing github version.
|
138
|
+
|
139
|
+
GitHub gems not found on #{GEMCUTTER_URL} (won't be touched):
|
140
|
+
|
141
|
+
#{will_not_be_migrated.join("\n")}
|
142
|
+
|
143
|
+
STATS
|
144
|
+
end
|
145
|
+
alias to_s stats
|
146
|
+
|
147
|
+
private
|
148
|
+
def newer_version?(a, b)
|
149
|
+
VersionSorter.rsort([a, b]).first == a
|
150
|
+
end
|
151
|
+
|
152
|
+
def looks_like_github_gem?(name)
|
153
|
+
name =~ /-/ &&
|
154
|
+
@github.include?(name) &&
|
155
|
+
!@other.include?(name)
|
156
|
+
end
|
157
|
+
|
158
|
+
def find_match(name)
|
159
|
+
return nil if !name || name.strip == ""
|
160
|
+
return name if @other.include?(name)
|
161
|
+
find_match name.split('-', 2)[1]
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
class Runner
|
166
|
+
def self.run(wet = false)
|
167
|
+
unless Gem.sources.find{|g| g =~ /gemcutter/}
|
168
|
+
puts "Looks like you don't have gemcutter installed as a source. Follow instructions at #{GEMCUTTER_URL} before running this tool.\n\n"
|
169
|
+
return
|
170
|
+
end
|
171
|
+
|
172
|
+
investigator = GemInvestigator.new
|
173
|
+
puts investigator
|
174
|
+
print "Everything looks good? Want to migrate gems? (It'll take a bit to perform all the actions.) (Y/n) "
|
175
|
+
reply = STDIN.gets.strip
|
176
|
+
if reply == "Y"
|
177
|
+
puts "Okeydoke.\n\n"
|
178
|
+
|
179
|
+
dont_ask = nil
|
180
|
+
investigator.will_be_migrated.each do |args|
|
181
|
+
github_gem, gemcutter_gem, action = args
|
182
|
+
next if action == "skip"
|
183
|
+
|
184
|
+
if action == "reinstall"
|
185
|
+
print "Reinstall#{dont_ask && 'ing'} #{github_gem} to #{gemcutter_gem}#{dont_ask ? '...' : '? (y/n/a) '}"
|
186
|
+
proceed = dont_ask ? "y" : STDIN.gets.strip
|
187
|
+
|
188
|
+
if proceed =~ /^[ya]$/
|
189
|
+
cmd "sudo gem uninstall -axq --user-install #{github_gem}", wet
|
190
|
+
cmd "sudo gem install #{gemcutter_gem} -s #{GEMCUTTER_URL}", wet
|
191
|
+
puts "\n"
|
192
|
+
end
|
193
|
+
else
|
194
|
+
print "Uninstall#{dont_ask && 'ing'} #{github_gem}#{dont_ask ? '...' : '? (y/n/a) '}"
|
195
|
+
proceed = dont_ask ? "y" : STDIN.gets.strip
|
196
|
+
|
197
|
+
if proceed =~ /^[ya]$/
|
198
|
+
cmd "sudo gem uninstall -axq --user-install #{github_gem}", wet
|
199
|
+
puts "\n"
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
dont_ask = true if proceed == "a"
|
204
|
+
end
|
205
|
+
|
206
|
+
puts "Migration finished."
|
207
|
+
else
|
208
|
+
puts "Oh well."
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
private
|
213
|
+
def self.cmd(cmd, wet = false)
|
214
|
+
puts "running: #{cmd}"
|
215
|
+
system(cmd) if wet
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
data/off_github.gemspec
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{off_github}
|
8
|
+
s.version = "1.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Maxim Chernyak"]
|
12
|
+
s.date = %q{2009-10-26}
|
13
|
+
s.default_executable = %q{off_github}
|
14
|
+
s.description = %q{A simple tool which helps migrate your locally installed gems from github to gemcutter. It will find all the gems installed from github and recognize them on gemcutter using with some recursive string matching. It will then present you with a list of everything it will migrate and ask for permission before touching anything.}
|
15
|
+
s.email = %q{max@bitsonnet.com}
|
16
|
+
s.executables = ["off_github"]
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE",
|
19
|
+
"README.rdoc"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
".gitignore",
|
23
|
+
"LICENSE",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"bin/off_github",
|
28
|
+
"lib/off_github.rb",
|
29
|
+
"lib/off_github.rb",
|
30
|
+
"off_github.gemspec",
|
31
|
+
"test/helper.rb",
|
32
|
+
"test/test_off_github.rb"
|
33
|
+
]
|
34
|
+
s.homepage = %q{http://github.com/maxim/off_github}
|
35
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
36
|
+
s.require_paths = ["lib"]
|
37
|
+
s.rubygems_version = %q{1.3.5}
|
38
|
+
s.summary = %q{Migrate locally installed gems from github to gemcutter.}
|
39
|
+
s.test_files = [
|
40
|
+
"test/helper.rb",
|
41
|
+
"test/test_off_github.rb"
|
42
|
+
]
|
43
|
+
|
44
|
+
if s.respond_to? :specification_version then
|
45
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
46
|
+
s.specification_version = 3
|
47
|
+
|
48
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
49
|
+
s.add_runtime_dependency(%q<hirb>, [">= 0.2.4"])
|
50
|
+
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
51
|
+
else
|
52
|
+
s.add_dependency(%q<hirb>, [">= 0.2.4"])
|
53
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
54
|
+
end
|
55
|
+
else
|
56
|
+
s.add_dependency(%q<hirb>, [">= 0.2.4"])
|
57
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
data/test/helper.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestOffGuthub < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@local_list = OffGithub::GemList.new %w(foo-bar qux-quux foo-bar-baz baz-baz corge grault-garble-warg_fred plugh-thud xyzzy)
|
6
|
+
@github_list = OffGithub::GemList.new %w(foo-bar qux-quux xxx-xxx baz-baz grault-garble-warg_fred plugh-thud)
|
7
|
+
@gemcutter_list = OffGithub::GemList.new %w(corge quux xxx bar garble-warg_fred baz xyzzy)
|
8
|
+
@investigator = OffGithub::GemInvestigator.new(@local_list, @gemcutter_list, @github_list)
|
9
|
+
end
|
10
|
+
|
11
|
+
should "identify gems as github gems" do
|
12
|
+
assert_same_elements %w(foo-bar qux-quux baz-baz grault-garble-warg_fred plugh-thud), @investigator.github_suspects
|
13
|
+
end
|
14
|
+
|
15
|
+
should "identify corresponding gemcutter gems" do
|
16
|
+
assert_same_elements %w(bar quux baz garble-warg_fred) + [nil], @investigator.found_matches
|
17
|
+
end
|
18
|
+
|
19
|
+
should "relate gems correctly" do
|
20
|
+
assert_same_elements [["foo-bar", "bar"],
|
21
|
+
["qux-quux", "quux"],
|
22
|
+
["baz-baz", "baz"],
|
23
|
+
["grault-garble-warg_fred", "garble-warg_fred"],
|
24
|
+
["plugh-thud", nil]], @investigator.relations.to_a
|
25
|
+
end
|
26
|
+
|
27
|
+
should "find github gems not found in gemcutter" do
|
28
|
+
assert_same_elements %w(plugh-thud), @investigator.will_not_be_migrated
|
29
|
+
end
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: off_github
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Maxim Chernyak
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-26 00:00:00 -04:00
|
13
|
+
default_executable: off_github
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: hirb
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.2.4
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: shoulda
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
description: A simple tool which helps migrate your locally installed gems from github to gemcutter. It will find all the gems installed from github and recognize them on gemcutter using with some recursive string matching. It will then present you with a list of everything it will migrate and ask for permission before touching anything.
|
36
|
+
email: max@bitsonnet.com
|
37
|
+
executables:
|
38
|
+
- off_github
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- LICENSE
|
43
|
+
- README.rdoc
|
44
|
+
files:
|
45
|
+
- .gitignore
|
46
|
+
- LICENSE
|
47
|
+
- README.rdoc
|
48
|
+
- Rakefile
|
49
|
+
- VERSION
|
50
|
+
- bin/off_github
|
51
|
+
- lib/off_github.rb
|
52
|
+
- off_github.gemspec
|
53
|
+
- test/helper.rb
|
54
|
+
- test/test_off_github.rb
|
55
|
+
has_rdoc: true
|
56
|
+
homepage: http://github.com/maxim/off_github
|
57
|
+
licenses: []
|
58
|
+
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options:
|
61
|
+
- --charset=UTF-8
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
version:
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: "0"
|
75
|
+
version:
|
76
|
+
requirements: []
|
77
|
+
|
78
|
+
rubyforge_project:
|
79
|
+
rubygems_version: 1.3.5
|
80
|
+
signing_key:
|
81
|
+
specification_version: 3
|
82
|
+
summary: Migrate locally installed gems from github to gemcutter.
|
83
|
+
test_files:
|
84
|
+
- test/helper.rb
|
85
|
+
- test/test_off_github.rb
|