gemi 0.0.5 → 0.1.0
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 +1 -0
- data/README.mkd +151 -0
- data/Rakefile +18 -2
- data/VERSION +1 -1
- data/bin/gemi +3 -89
- data/features/basic_commands.feature +40 -0
- data/features/command_specific_options.feature +25 -0
- data/features/config_file.feature +27 -0
- data/features/gems_yaml.feature +52 -0
- data/features/multiple_rubys.feature +21 -0
- data/features/step_definitions/gemi_steps.rb +45 -0
- data/features/support/env.rb +24 -0
- data/gemi.gemspec +42 -8
- data/gemirc.yml +6 -13
- data/lib/gemi.rb +14 -0
- data/lib/gemi/commands.rb +40 -0
- data/lib/gemi/conf.rb +53 -0
- data/lib/gemi/gem.rb +38 -0
- data/lib/gemi/options.rb +69 -0
- data/lib/gemi/ruby.rb +5 -0
- data/lib/gemi/runner.rb +89 -0
- metadata +44 -9
- data/README +0 -35
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
features/tmp/
|
data/README.mkd
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
gemi
|
2
|
+
====
|
3
|
+
|
4
|
+
Gemi is a simple tool for installing gems for multiple rubys.
|
5
|
+
It also can install specific versions of the gems listed in a YAML file.
|
6
|
+
|
7
|
+
without gemi, you need to type 'install' for all your rubys:
|
8
|
+
|
9
|
+
$ gem install foo bar baz quux
|
10
|
+
$ gem-1.9 install foo bar baz quux
|
11
|
+
|
12
|
+
with gemi, it's just:
|
13
|
+
|
14
|
+
$ gemi foo bar baz quux
|
15
|
+
|
16
|
+
or even:
|
17
|
+
|
18
|
+
$ gemi gems.yml
|
19
|
+
|
20
|
+
Install
|
21
|
+
-------
|
22
|
+
|
23
|
+
$ gem install gemi
|
24
|
+
|
25
|
+
Setup
|
26
|
+
-----
|
27
|
+
|
28
|
+
First, execute gemi without any options:
|
29
|
+
|
30
|
+
$ gemi
|
31
|
+
|
32
|
+
then ~/.gemirc is created. Edit it for your environment.
|
33
|
+
|
34
|
+
Example:
|
35
|
+
|
36
|
+
rubys:
|
37
|
+
- name: 'MRI 1.8'
|
38
|
+
command: 'gem'
|
39
|
+
install_options: '--no-format-executable --user-install'
|
40
|
+
- name: 'MRI 1.9'
|
41
|
+
command: 'gem-1.9'
|
42
|
+
install_options: '--format-executable --user-install'
|
43
|
+
|
44
|
+
Usage
|
45
|
+
-----
|
46
|
+
|
47
|
+
First of all,
|
48
|
+
|
49
|
+
$ gemi foo
|
50
|
+
|
51
|
+
will install the gem 'foo' for all your rubys.
|
52
|
+
|
53
|
+
gemi can also uninstall, update, or cleanup the gems.
|
54
|
+
|
55
|
+
### Install gems
|
56
|
+
|
57
|
+
Just give the names of the gems to gemi.
|
58
|
+
|
59
|
+
$ gemi foo bar (= gem install foo bar)
|
60
|
+
|
61
|
+
You can also install gems defined in a YAML file:
|
62
|
+
|
63
|
+
$ gemi gems.yml
|
64
|
+
|
65
|
+
Example of gems.yml:
|
66
|
+
|
67
|
+
gems:
|
68
|
+
- name: 'ruby-openid'
|
69
|
+
version: '2.1.4'
|
70
|
+
|
71
|
+
- name: 'nokogiri'
|
72
|
+
version: '1.4.0'
|
73
|
+
install_options: --with-foo
|
74
|
+
|
75
|
+
### Uninstall gems
|
76
|
+
|
77
|
+
Specify '-d' for "gem uninstall".
|
78
|
+
|
79
|
+
$ gemi -d foo bar (= gem uninstall foo bar)
|
80
|
+
|
81
|
+
### Update gems
|
82
|
+
|
83
|
+
Specify '-u' for "gem upgrade".
|
84
|
+
|
85
|
+
$ gemi -u foo bar (= gem upgrade foo bar)
|
86
|
+
|
87
|
+
### Cleanup old gems
|
88
|
+
|
89
|
+
Specify '-c' for "gem cleanup".
|
90
|
+
|
91
|
+
$ gemi -c foo bar (= gem cleanup foo bar)
|
92
|
+
|
93
|
+
### Other gem commands
|
94
|
+
|
95
|
+
With '--', you can run any gem commands for rubys:
|
96
|
+
|
97
|
+
$ gemi -- list --local (= gem list --local)
|
98
|
+
|
99
|
+
The arguments after '--' are passed to each gem command.
|
100
|
+
(Note that 'gemi list' is expanded to 'gem install list'!)
|
101
|
+
|
102
|
+
Configuration
|
103
|
+
-------------
|
104
|
+
|
105
|
+
### .gemirc
|
106
|
+
|
107
|
+
~/.gemirc contains the information about each gem commands.
|
108
|
+
|
109
|
+
Example:
|
110
|
+
|
111
|
+
rubys:
|
112
|
+
- name: Ruby 1.8
|
113
|
+
command: gem
|
114
|
+
- name: Ruby 1.9
|
115
|
+
command: gem-1.9
|
116
|
+
install_options: --foo
|
117
|
+
uninstall_options: --bar
|
118
|
+
update_options: --baz
|
119
|
+
clean_options: --quux
|
120
|
+
|
121
|
+
{install,uninstall,update,clean}_options will be appended to the
|
122
|
+
arguments. In this case, the command:
|
123
|
+
|
124
|
+
$ gemi a b c
|
125
|
+
|
126
|
+
resuls in running these two gem commands.
|
127
|
+
|
128
|
+
$ gem install a b c --foo
|
129
|
+
$ gem-1.9 install a b c --foo
|
130
|
+
|
131
|
+
### Alternative .gemirc
|
132
|
+
|
133
|
+
You can specify an alternative gemirc with '-r' (or '--rc').
|
134
|
+
|
135
|
+
Example: use myconf.yml instead of ~/.gemirc
|
136
|
+
|
137
|
+
$ gemi -r myconf.yml foo bar
|
138
|
+
|
139
|
+
Repository
|
140
|
+
----------
|
141
|
+
|
142
|
+
http://github.com/yhara/gemi
|
143
|
+
|
144
|
+
Authors
|
145
|
+
-------
|
146
|
+
|
147
|
+
yhara (Yutaka HARA) yutaka.hara.gmail.com
|
148
|
+
http://route477.net/
|
149
|
+
|
150
|
+
Kazuyoshi Tlacaelel
|
151
|
+
http://github.com/ktlacaelel
|
data/Rakefile
CHANGED
@@ -8,9 +8,25 @@ end
|
|
8
8
|
|
9
9
|
Jeweler::Tasks.new do |gemspec|
|
10
10
|
gemspec.name = "#{PROJECT_NAME}"
|
11
|
-
gemspec.summary = "
|
11
|
+
gemspec.summary = "gem command for multiple rubys"
|
12
12
|
gemspec.email = "yutaka.hara/at/gmail.com"
|
13
13
|
gemspec.homepage = "http://github.com/yhara/#{PROJECT_NAME}"
|
14
|
-
gemspec.description =
|
14
|
+
gemspec.description = <<-EOD
|
15
|
+
gemi runs 'gem install' for each your rubys.
|
16
|
+
Example:
|
17
|
+
without gemi:
|
18
|
+
$ gem install foo bar
|
19
|
+
$ gem-1.9 install foo bar
|
20
|
+
with gemi:
|
21
|
+
$ gemi foo bar
|
22
|
+
EOD
|
15
23
|
gemspec.authors = ["Yutaka HARA"]
|
24
|
+
gemspec.add_development_dependency('cucumber', '>= 0.4.2')
|
25
|
+
gemspec.add_development_dependency('kagemusha')
|
26
|
+
gemspec.post_install_message = <<-EOD
|
27
|
+
Thank you for installing gemi!
|
28
|
+
The format of ~/.gemirc is changed in gemi 0.1.0.
|
29
|
+
If you have been using gemi 0.0.x,
|
30
|
+
please modify it (see gemirc.yml)
|
31
|
+
EOD
|
16
32
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
data/bin/gemi
CHANGED
@@ -1,91 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require '
|
4
|
-
require 'yaml'
|
2
|
+
$LOAD_PATH.unshift File.expand_path("../lib", File.dirname(__FILE__))
|
3
|
+
require 'gemi'
|
5
4
|
|
6
|
-
|
7
|
-
GEMIRC = File.expand_path("~/.gemirc")
|
8
|
-
|
9
|
-
def initialize(arg)
|
10
|
-
@arg = arg
|
11
|
-
@rubys = []
|
12
|
-
end
|
13
|
-
|
14
|
-
def run
|
15
|
-
if gemirc_exists?
|
16
|
-
Gemi.usage! if @arg.empty?
|
17
|
-
|
18
|
-
@rubys = load_gemirc
|
19
|
-
install_gems
|
20
|
-
else
|
21
|
-
setup
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def gemirc_exists?
|
28
|
-
File.exist?(GEMIRC)
|
29
|
-
end
|
30
|
-
|
31
|
-
def load_gemirc
|
32
|
-
YAML.load_file(GEMIRC)
|
33
|
-
end
|
34
|
-
|
35
|
-
def install_gems
|
36
|
-
@rubys.each do |ruby|
|
37
|
-
puts "------- installing for #{ruby[:name]} ..."
|
38
|
-
cmd = "#{gem_home(ruby)} #{ruby[:command]} install #{@arg} #{ruby[:options]}"
|
39
|
-
puts cmd
|
40
|
-
system cmd
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def gem_home(ruby)
|
45
|
-
if ruby[:gem_home]
|
46
|
-
# Note: single quote(') is needed to run the command in shell
|
47
|
-
# see the reference of Kernel#system
|
48
|
-
"GEM_HOME='#{File.expand_path ruby[:gem_home]}'"
|
49
|
-
else
|
50
|
-
""
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def setup
|
55
|
-
create_gemirc
|
56
|
-
puts "Created #{GEMIRC}"
|
57
|
-
puts "please edit it before using gemi."
|
58
|
-
end
|
59
|
-
|
60
|
-
def create_gemirc
|
61
|
-
template_path = File.expand_path("../gemirc.yml", File.dirname(__FILE__))
|
62
|
-
FileUtils.cp(template_path, GEMIRC)
|
63
|
-
end
|
64
|
-
|
65
|
-
# command line options
|
66
|
-
|
67
|
-
@opt = OptionParser.new{|o|
|
68
|
-
o.banner = "Usage: #$0 [gemi-options] foo bar [gem-options]\n" +
|
69
|
-
"Gemi Options:"
|
70
|
-
o.on("-h", "--help", "show this message"){
|
71
|
-
Gemi.usage!
|
72
|
-
}
|
73
|
-
}
|
74
|
-
|
75
|
-
def self.parse_argv
|
76
|
-
gemi_opts = []
|
77
|
-
while ARGV[0] =~ /\A-/
|
78
|
-
gemi_opts.push ARGV.shift
|
79
|
-
end
|
80
|
-
@opt.parse!(gemi_opts)
|
81
|
-
|
82
|
-
return ARGV.join(" ")
|
83
|
-
end
|
84
|
-
|
85
|
-
def self.usage!
|
86
|
-
puts @opt.to_s
|
87
|
-
exit
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
Gemi.new(Gemi.parse_argv).run
|
5
|
+
Gemi::Runner.new(ARGV).run
|
@@ -0,0 +1,40 @@
|
|
1
|
+
Feature: Basic commands
|
2
|
+
Background:
|
3
|
+
Given I have the config file with:
|
4
|
+
"""
|
5
|
+
rubys:
|
6
|
+
- name: MRI 1.8
|
7
|
+
command: 'gem'
|
8
|
+
"""
|
9
|
+
|
10
|
+
Scenario Outline: Simple cases
|
11
|
+
When I run gemi with '<args>'
|
12
|
+
Then it should execute '<gem_command>'
|
13
|
+
|
14
|
+
Examples:
|
15
|
+
| args | gem_command |
|
16
|
+
| foo bar | gem install foo bar |
|
17
|
+
| -u foo bar | gem uninstall foo bar |
|
18
|
+
| --uninstall foo bar | gem uninstall foo bar |
|
19
|
+
| -n foo bar | gem update foo bar |
|
20
|
+
| --update foo bar | gem update foo bar |
|
21
|
+
| -c foo bar | gem clean foo bar |
|
22
|
+
| --clean foo bar | gem clean foo bar |
|
23
|
+
|
24
|
+
Scenario Outline: With options for gem command
|
25
|
+
When I run gemi with '<args>'
|
26
|
+
Then it should execute '<gem_command>'
|
27
|
+
|
28
|
+
Examples:
|
29
|
+
| args | gem_command |
|
30
|
+
| foo bar -n ~/bin | gem install foo bar -n ~/bin |
|
31
|
+
| -u foo --user-install | gem uninstall foo --user-install |
|
32
|
+
|
33
|
+
Scenario Outline: With verbatim args
|
34
|
+
When I run gemi with '<args>'
|
35
|
+
Then it should execute '<gem_command>'
|
36
|
+
|
37
|
+
Examples:
|
38
|
+
| args | gem_command |
|
39
|
+
| -- stale | gem stale |
|
40
|
+
| -- list -l | gem list -l |
|
@@ -0,0 +1,25 @@
|
|
1
|
+
Feature: Command specific options
|
2
|
+
Background:
|
3
|
+
Given I have the config file with:
|
4
|
+
"""
|
5
|
+
rubys:
|
6
|
+
- name: MRI 1.8
|
7
|
+
command: 'gem'
|
8
|
+
install_options: --foo
|
9
|
+
uninstall_options: --bar
|
10
|
+
update_options: --baz
|
11
|
+
clean_options: --quux
|
12
|
+
"""
|
13
|
+
# Note: these options are just example.
|
14
|
+
# The real gem command does not have such options!
|
15
|
+
|
16
|
+
Scenario Outline:
|
17
|
+
When I run gemi with '<args>'
|
18
|
+
Then it should execute '<gem_command>'
|
19
|
+
|
20
|
+
Examples:
|
21
|
+
| args | gem_command |
|
22
|
+
| a b | gem install a b --foo |
|
23
|
+
| -u a b | gem uninstall a b --bar |
|
24
|
+
| -n a b | gem update a b --baz |
|
25
|
+
| -c a b | gem clean a b --quux |
|
@@ -0,0 +1,27 @@
|
|
1
|
+
Feature: Config file
|
2
|
+
|
3
|
+
Scenario: Load from default path
|
4
|
+
# Note: this is tested in basic_commands.feature
|
5
|
+
|
6
|
+
Scenario: Create config if none
|
7
|
+
|
8
|
+
Scenario Outline: Specifying alternative config file path
|
9
|
+
Given a yaml file named "myconf.yml" with:
|
10
|
+
"""
|
11
|
+
rubys:
|
12
|
+
- name: myruby
|
13
|
+
command: mygem
|
14
|
+
install_options: --myoption
|
15
|
+
"""
|
16
|
+
When I run gemi with '<args>'
|
17
|
+
Then it should execute '<gem_command>'
|
18
|
+
|
19
|
+
Examples:
|
20
|
+
| args | gem_command |
|
21
|
+
| -r myconf.yml foo bar | mygem install foo bar --myoption |
|
22
|
+
| --rc myconf.yml -u foo bar | mygem uninstall foo bar |
|
23
|
+
| --rc myconf.yml -- stale | mygem stale |
|
24
|
+
|
25
|
+
Scenario: Use default settings if yaml is given
|
26
|
+
# Note: this is tested in gems_yaml.feature
|
27
|
+
|
@@ -0,0 +1,52 @@
|
|
1
|
+
Feature: With gems.yaml
|
2
|
+
|
3
|
+
Scenario Outline: Yaml containing names only
|
4
|
+
Given a yaml file named "names.yml" with:
|
5
|
+
"""
|
6
|
+
gems:
|
7
|
+
- name: foo
|
8
|
+
- name: bar
|
9
|
+
"""
|
10
|
+
When I run gemi with '<args>'
|
11
|
+
Then it should execute '<gem_command>'
|
12
|
+
|
13
|
+
Examples:
|
14
|
+
| args | gem_command |
|
15
|
+
| names.yml | gem install foo bar |
|
16
|
+
| -u names.yml | gem uninstall foo bar |
|
17
|
+
| -n names.yml | *ERROR* |
|
18
|
+
| -c names.yml | *ERROR* |
|
19
|
+
|
20
|
+
Scenario Outline: Yaml containing versions
|
21
|
+
Given a yaml file named "names_and_versions.yml" with:
|
22
|
+
"""
|
23
|
+
gems:
|
24
|
+
- name: foo
|
25
|
+
version: 0.1
|
26
|
+
- name: bar
|
27
|
+
version: 0.2
|
28
|
+
"""
|
29
|
+
When I run gemi with '<args>'
|
30
|
+
Then it should execute '<gem_command>'
|
31
|
+
|
32
|
+
Examples:
|
33
|
+
| args | gem_command |
|
34
|
+
| names_and_versions.yml | gem install foo -v 0.1 ; gem install bar -v 0.2 |
|
35
|
+
| -u names_and_versions.yml | gem uninstall foo -v 0.1 ; gem uninstall bar -v 0.2 |
|
36
|
+
|
37
|
+
Scenario Outline: Yaml containing options
|
38
|
+
Given a yaml file named "names_and_options.yml" with:
|
39
|
+
"""
|
40
|
+
gems:
|
41
|
+
- name: foo
|
42
|
+
install_options: --with-foo
|
43
|
+
- name: bar
|
44
|
+
version: 0.2
|
45
|
+
"""
|
46
|
+
When I run gemi with '<args>'
|
47
|
+
Then it should execute '<gem_command>'
|
48
|
+
|
49
|
+
Examples:
|
50
|
+
| args | gem_command |
|
51
|
+
| names_and_options.yml | gem install foo --with-foo ; gem install bar -v 0.2 |
|
52
|
+
| -u names_and_options.yml | gem uninstall foo ; gem uninstall bar -v 0.2 |
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Feature: Multiple Rubys
|
2
|
+
Background:
|
3
|
+
Given I have the config file with:
|
4
|
+
"""
|
5
|
+
rubys:
|
6
|
+
- name: MRI 1.8
|
7
|
+
command: 'gem'
|
8
|
+
- name: MRI 1.9
|
9
|
+
command: 'gem-1.9'
|
10
|
+
"""
|
11
|
+
|
12
|
+
Scenario Outline:
|
13
|
+
When I run gemi with '<args>'
|
14
|
+
Then it should execute the commands '<gem_commands>'
|
15
|
+
|
16
|
+
Examples:
|
17
|
+
| args | gem_commands |
|
18
|
+
| a b | gem install a b , gem-1.9 install a b |
|
19
|
+
| -u a b | gem uninstall a b , gem-1.9 uninstall a b |
|
20
|
+
| -n a b | gem update a b , gem-1.9 update a b |
|
21
|
+
| -c a b | gem clean a b , gem-1.9 clean a b |
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'kagemusha'
|
2
|
+
|
3
|
+
Given /^I have the config file with:$/ do |string|
|
4
|
+
File.open(GemiWorld::GEMIRC_TMP, "wb"){|f|
|
5
|
+
f.write string
|
6
|
+
}
|
7
|
+
end
|
8
|
+
|
9
|
+
Given /^a yaml file named "([^\"]*)" with:$/ do |filename, content|
|
10
|
+
File.open(File.join(GemiWorld::TMP_DIR, filename), "wb"){|f|
|
11
|
+
f.write content
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
When /^I run gemi with '(.*)'$/ do |args_str|
|
16
|
+
argv = args_str.split.map{|arg|
|
17
|
+
if arg =~ Gemi::REXP_YAML
|
18
|
+
File.join(GemiWorld::TMP_DIR, arg)
|
19
|
+
else
|
20
|
+
arg
|
21
|
+
end
|
22
|
+
}
|
23
|
+
|
24
|
+
cmds = []
|
25
|
+
Kagemusha.new(Gemi::Runner).def(:execute){|cmd|
|
26
|
+
cmds << cmd
|
27
|
+
}.swap {
|
28
|
+
begin
|
29
|
+
Gemi::Runner.new(argv).main
|
30
|
+
rescue Gemi::Error
|
31
|
+
cmds << "*ERROR*"
|
32
|
+
end
|
33
|
+
}
|
34
|
+
@cmds = cmds
|
35
|
+
end
|
36
|
+
|
37
|
+
Then /^it should execute the commands '(.*)'$/ do |cmds|
|
38
|
+
@cmds.should == cmds.split(/\s*,\s*/)
|
39
|
+
end
|
40
|
+
|
41
|
+
Then /^it should execute '(.*)'$/ do |cmd|
|
42
|
+
@cmds.first.rstrip.should == cmd
|
43
|
+
end
|
44
|
+
|
45
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path("../../lib", File.dirname(__FILE__))
|
2
|
+
require 'gemi'
|
3
|
+
|
4
|
+
class GemiWorld
|
5
|
+
# Path to make Temporary files
|
6
|
+
TMP_DIR = File.expand_path("../tmp/", File.dirname(__FILE__))
|
7
|
+
|
8
|
+
# Path of config file to use temporarily
|
9
|
+
GEMIRC_TMP = File.join(TMP_DIR, "gemirc")
|
10
|
+
|
11
|
+
# Replace the content of the constant (hack!)
|
12
|
+
Gemi::GEMIRC.replace GEMIRC_TMP
|
13
|
+
end
|
14
|
+
|
15
|
+
Before do
|
16
|
+
File.unlink GemiWorld::GEMIRC_TMP if File.exist? GemiWorld::GEMIRC_TMP
|
17
|
+
end
|
18
|
+
|
19
|
+
World do
|
20
|
+
GemiWorld.new
|
21
|
+
end
|
22
|
+
|
23
|
+
After do
|
24
|
+
end
|
data/gemi.gemspec
CHANGED
@@ -5,40 +5,74 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{gemi}
|
8
|
-
s.version = "0.0
|
8
|
+
s.version = "0.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Yutaka HARA"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2010-01-13}
|
13
13
|
s.default_executable = %q{gemi}
|
14
|
-
s.description = %q{
|
14
|
+
s.description = %q{ gemi runs 'gem install' for each your rubys.
|
15
|
+
Example:
|
16
|
+
without gemi:
|
17
|
+
$ gem install foo bar
|
18
|
+
$ gem-1.9 install foo bar
|
19
|
+
with gemi:
|
20
|
+
$ gemi foo bar
|
21
|
+
}
|
15
22
|
s.email = %q{yutaka.hara/at/gmail.com}
|
16
23
|
s.executables = ["gemi"]
|
17
24
|
s.extra_rdoc_files = [
|
18
|
-
"README"
|
25
|
+
"README.mkd"
|
19
26
|
]
|
20
27
|
s.files = [
|
21
|
-
"
|
22
|
-
"
|
28
|
+
".gitignore",
|
29
|
+
"History.txt",
|
30
|
+
"README.mkd",
|
23
31
|
"Rakefile",
|
24
32
|
"VERSION",
|
25
33
|
"bin/gemi",
|
34
|
+
"features/basic_commands.feature",
|
35
|
+
"features/command_specific_options.feature",
|
36
|
+
"features/config_file.feature",
|
37
|
+
"features/gems_yaml.feature",
|
38
|
+
"features/multiple_rubys.feature",
|
39
|
+
"features/step_definitions/gemi_steps.rb",
|
40
|
+
"features/support/env.rb",
|
41
|
+
"features/tmp/.gitignore",
|
26
42
|
"gemi.gemspec",
|
27
|
-
"gemirc.yml"
|
43
|
+
"gemirc.yml",
|
44
|
+
"lib/gemi.rb",
|
45
|
+
"lib/gemi/commands.rb",
|
46
|
+
"lib/gemi/conf.rb",
|
47
|
+
"lib/gemi/gem.rb",
|
48
|
+
"lib/gemi/options.rb",
|
49
|
+
"lib/gemi/ruby.rb",
|
50
|
+
"lib/gemi/runner.rb"
|
28
51
|
]
|
29
52
|
s.homepage = %q{http://github.com/yhara/gemi}
|
53
|
+
s.post_install_message = %q{ Thank you for installing gemi!
|
54
|
+
The format of ~/.gemirc is changed in gemi 0.1.0.
|
55
|
+
If you have been using gemi 0.0.x,
|
56
|
+
please modify it (see gemirc.yml)
|
57
|
+
}
|
30
58
|
s.rdoc_options = ["--charset=UTF-8"]
|
31
59
|
s.require_paths = ["lib"]
|
32
60
|
s.rubygems_version = %q{1.3.5}
|
33
|
-
s.summary = %q{
|
61
|
+
s.summary = %q{gem command for multiple rubys}
|
34
62
|
|
35
63
|
if s.respond_to? :specification_version then
|
36
64
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
37
65
|
s.specification_version = 3
|
38
66
|
|
39
67
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
68
|
+
s.add_development_dependency(%q<cucumber>, [">= 0.4.2"])
|
69
|
+
s.add_development_dependency(%q<kagemusha>, [">= 0"])
|
40
70
|
else
|
71
|
+
s.add_dependency(%q<cucumber>, [">= 0.4.2"])
|
72
|
+
s.add_dependency(%q<kagemusha>, [">= 0"])
|
41
73
|
end
|
42
74
|
else
|
75
|
+
s.add_dependency(%q<cucumber>, [">= 0.4.2"])
|
76
|
+
s.add_dependency(%q<kagemusha>, [">= 0"])
|
43
77
|
end
|
44
78
|
end
|
data/gemirc.yml
CHANGED
@@ -1,14 +1,7 @@
|
|
1
|
-
|
2
|
-
:
|
3
|
-
|
4
|
-
# :gem_home: ~/.gem1.8
|
5
|
-
|
6
|
-
- :name: 'MRI 1.9'
|
7
|
-
:command: 'gem-1.9'
|
8
|
-
:options: '--format-executable' # install bin/foobar as foobar-1.9
|
9
|
-
# :gem_home: ~/.gem1.9
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
1
|
+
rubys:
|
2
|
+
- name: 'MRI 1.8' # used just for showing messages
|
3
|
+
command: 'sudo gem' # gem command to install
|
14
4
|
|
5
|
+
- name: 'MRI 1.9'
|
6
|
+
command: 'gem-1.9'
|
7
|
+
install_options: '--format-executable' # install bin/foo as foo-1.9
|
data/lib/gemi.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
module Gemi
|
2
|
+
GEMIRC = File.expand_path("~/.gemirc")
|
3
|
+
REXP_YAML = /.ya?ml\z/i
|
4
|
+
|
5
|
+
class Error < StandardError; end
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'gemi/commands.rb'
|
9
|
+
require 'gemi/conf.rb'
|
10
|
+
require 'gemi/gem.rb'
|
11
|
+
require 'gemi/options.rb'
|
12
|
+
require 'gemi/ruby.rb'
|
13
|
+
require 'gemi/runner.rb'
|
14
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Gemi
|
2
|
+
class Command
|
3
|
+
|
4
|
+
def initialize(type, gem_names, yamls)
|
5
|
+
@type = type
|
6
|
+
|
7
|
+
@gems = [
|
8
|
+
gem_names.map{|s| Gem.new(s)},
|
9
|
+
yamls.map{|path| Gem.from_yaml(YAML.load_file(path))}
|
10
|
+
].flatten
|
11
|
+
end
|
12
|
+
|
13
|
+
def build(ruby)
|
14
|
+
if @gems.any?{|gem| gem.version or gem.options[@type]}
|
15
|
+
@gems.map{|gem|
|
16
|
+
build_command(gem.to_command(@type), ruby)
|
17
|
+
}.join(" ; ")
|
18
|
+
else
|
19
|
+
gem_names = @gems.map(&:name).join(" ")
|
20
|
+
build_command(gem_names, ruby)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def build_command(gem_opts, ruby)
|
27
|
+
return [
|
28
|
+
# gem, gem-1.8, gem-1.9, etc.
|
29
|
+
ruby.gem_command,
|
30
|
+
# install, update, etc.
|
31
|
+
@type.to_s,
|
32
|
+
# gem names and a version, if any
|
33
|
+
gem_opts,
|
34
|
+
# user options specific to installing, uninstalling, etc.
|
35
|
+
(ruby.options[@type] || ""),
|
36
|
+
].reject(&:empty?).join(" ")
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
data/lib/gemi/conf.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Gemi
|
4
|
+
class Conf
|
5
|
+
|
6
|
+
class GemircError < StandardError
|
7
|
+
def initialize(attr)
|
8
|
+
super("you must give '#{attr}' in your gemirc")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.create
|
13
|
+
unless File.exist?(GEMIRC)
|
14
|
+
here = File.dirname(__FILE__)
|
15
|
+
template_path = File.expand_path("../../gemirc.yml", here)
|
16
|
+
FileUtils.cp(template_path, GEMIRC)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(yaml_path)
|
21
|
+
if yaml_path
|
22
|
+
yaml = YAML.load_file(yaml_path)
|
23
|
+
@rubys = parse_rubys(yaml["rubys"])
|
24
|
+
else
|
25
|
+
@rubys = [Ruby::Default]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
attr_reader :rubys
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def parse_rubys(rubys)
|
33
|
+
rubys.map{|ruby|
|
34
|
+
name = ruby["name"]
|
35
|
+
raise GemircError.new("name") unless name
|
36
|
+
|
37
|
+
command = ruby["command"]
|
38
|
+
raise GemircError.new("command") unless command
|
39
|
+
|
40
|
+
gem_home = ruby["gem_home"]
|
41
|
+
|
42
|
+
options = {
|
43
|
+
:install => ruby["install_options"],
|
44
|
+
:uninstall => ruby["uninstall_options"],
|
45
|
+
:update => ruby["update_options"],
|
46
|
+
:clean => ruby["clean_options"],
|
47
|
+
}
|
48
|
+
|
49
|
+
Ruby.new(name, command, gem_home, options)
|
50
|
+
}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/gemi/gem.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
module Gemi
|
2
|
+
class Gem
|
3
|
+
|
4
|
+
class OptionNotSupported < Gemi::Error; end
|
5
|
+
|
6
|
+
# Returns an array of Gem
|
7
|
+
def self.from_yaml(yaml)
|
8
|
+
return [] unless yaml["gems"]
|
9
|
+
|
10
|
+
yaml["gems"].map{|spec|
|
11
|
+
options = {
|
12
|
+
:install => spec["install_options"],
|
13
|
+
:uninstall => spec["uninstall_options"],
|
14
|
+
}
|
15
|
+
%w(update_options clean_options).each do |key|
|
16
|
+
if spec[key]
|
17
|
+
raise OptionNotSupported, "you cannot specify #{key} in YAML file"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
new(spec["name"], spec["version"], options)
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(name, version=nil, options={})
|
25
|
+
@name, @version, @options = name, version, options
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :name, :version, :options
|
29
|
+
|
30
|
+
def to_command(type)
|
31
|
+
s = @name
|
32
|
+
s << " -v #{@version}" if @version
|
33
|
+
s << " #{@options[type]}" if @options[type]
|
34
|
+
s
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
data/lib/gemi/options.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
module Gemi
|
2
|
+
class Options
|
3
|
+
|
4
|
+
class YamlGivenError < Gemi::Error; end
|
5
|
+
|
6
|
+
def self.parse(argv)
|
7
|
+
new(argv)
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(argv)
|
11
|
+
@confpath, @type, @gem_names, @yamls = parse(argv)
|
12
|
+
end
|
13
|
+
attr_reader :confpath, :type, :gem_names, :yamls
|
14
|
+
|
15
|
+
def empty?
|
16
|
+
@yamls.empty? and @gem_names.empty?
|
17
|
+
end
|
18
|
+
|
19
|
+
TYPES = {
|
20
|
+
"-u" => :uninstall,
|
21
|
+
"--uninstall" => :uninstall,
|
22
|
+
"-n" => :update,
|
23
|
+
"--update" => :update,
|
24
|
+
"-c" => :clean,
|
25
|
+
"--clean" => :clean,
|
26
|
+
}
|
27
|
+
|
28
|
+
def parse(argv)
|
29
|
+
confpath = GEMIRC
|
30
|
+
|
31
|
+
if %w(-r --rc).include?(argv.first)
|
32
|
+
confpath = argv[1]
|
33
|
+
if not File.exist?(confpath)
|
34
|
+
raise ConfNotFound, "config file not found in #{confpath}"
|
35
|
+
exit
|
36
|
+
end
|
37
|
+
argv.shift
|
38
|
+
argv.shift
|
39
|
+
end
|
40
|
+
|
41
|
+
case
|
42
|
+
when TYPES.key?(argv.first)
|
43
|
+
type = TYPES[argv.first]
|
44
|
+
args = argv[1..-1]
|
45
|
+
|
46
|
+
when argv.first == "--"
|
47
|
+
type = nil
|
48
|
+
args = argv[1..-1]
|
49
|
+
|
50
|
+
else # gem names only
|
51
|
+
type = :install
|
52
|
+
args = argv
|
53
|
+
end
|
54
|
+
|
55
|
+
case type
|
56
|
+
when nil # verbatim(--)
|
57
|
+
yamls = []
|
58
|
+
gem_names = args
|
59
|
+
else
|
60
|
+
yamls, gem_names = args.partition{|s| s =~ REXP_YAML}
|
61
|
+
if [:update, :clean].include?(type) and not yamls.empty?
|
62
|
+
raise YamlGivenError, "You cannot give yaml files with #{argv.first}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
return confpath, type, gem_names, yamls
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/gemi/ruby.rb
ADDED
data/lib/gemi/runner.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
module Gemi
|
2
|
+
class Runner
|
3
|
+
|
4
|
+
class ConfNotFound < Gemi::Error; end
|
5
|
+
|
6
|
+
def initialize(argv)
|
7
|
+
@argv = argv.dup
|
8
|
+
end
|
9
|
+
|
10
|
+
def run
|
11
|
+
begin
|
12
|
+
main
|
13
|
+
rescue => e
|
14
|
+
$stderr.puts "Error: #{e.message}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def main
|
19
|
+
@opt = Options.parse(@argv)
|
20
|
+
|
21
|
+
if @opt.empty?
|
22
|
+
usage
|
23
|
+
return
|
24
|
+
end
|
25
|
+
|
26
|
+
conf = load_conf
|
27
|
+
execute_commands(conf)
|
28
|
+
end
|
29
|
+
|
30
|
+
def load_conf
|
31
|
+
conf_exist = File.exist?(@opt.confpath)
|
32
|
+
yaml_given = !@opt.yamls.empty?
|
33
|
+
|
34
|
+
if conf_exist
|
35
|
+
Conf.new(@opt.confpath)
|
36
|
+
else
|
37
|
+
if yaml_given
|
38
|
+
Conf.new(nil)
|
39
|
+
elsif @opt.confpath == GEMIRC
|
40
|
+
create_conf
|
41
|
+
return
|
42
|
+
else
|
43
|
+
raise ConfNotFound, "config file not found in #{@opt.confpath}"
|
44
|
+
return
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def execute_commands(conf)
|
50
|
+
conf.rubys.each do |ruby|
|
51
|
+
puts "------- installing for #{ruby[:name]} ..."
|
52
|
+
cmd = Command.new(@opt.type, @opt.gem_names, @opt.yamls).build(ruby)
|
53
|
+
execute(cmd)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def execute(cmd)
|
58
|
+
puts cmd
|
59
|
+
system cmd
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def usage
|
65
|
+
$stderr.puts [
|
66
|
+
"Usage: gemi -unc GEM1 GEM2 YAML1.yml",
|
67
|
+
"Options:",
|
68
|
+
" -u, --uninstall : gem uninstall",
|
69
|
+
" -n, --update : gem update",
|
70
|
+
" -c, --clean : gem clean",
|
71
|
+
" -- : pass the arguments to gem commands",
|
72
|
+
" -r PATH : specify the path of gemirc",
|
73
|
+
].join("\n")
|
74
|
+
end
|
75
|
+
|
76
|
+
def create_conf
|
77
|
+
$stderr.puts "Error: config file not found in #{GEMIRC}"
|
78
|
+
$stderr.print "May I create a new one? [Y/n]"
|
79
|
+
ans = gets.chomp
|
80
|
+
$stderr.puts
|
81
|
+
|
82
|
+
if ["Y", "YES", ""].include?(ans.upcase)
|
83
|
+
Conf.create
|
84
|
+
$stderr.puts "Done. Please edit #{GEMIRC} for your environment."
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gemi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yutaka HARA
|
@@ -9,31 +9,66 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-01-13 00:00:00 +09:00
|
13
13
|
default_executable: gemi
|
14
|
-
dependencies:
|
15
|
-
|
16
|
-
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: cucumber
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.4.2
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: kagemusha
|
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: " gemi runs 'gem install' for each your rubys.\n Example:\n without gemi:\n $ gem install foo bar\n $ gem-1.9 install foo bar\n with gemi:\n $ gemi foo bar\n"
|
17
36
|
email: yutaka.hara/at/gmail.com
|
18
37
|
executables:
|
19
38
|
- gemi
|
20
39
|
extensions: []
|
21
40
|
|
22
41
|
extra_rdoc_files:
|
23
|
-
- README
|
42
|
+
- README.mkd
|
24
43
|
files:
|
44
|
+
- .gitignore
|
25
45
|
- History.txt
|
26
|
-
- README
|
46
|
+
- README.mkd
|
27
47
|
- Rakefile
|
28
48
|
- VERSION
|
29
49
|
- bin/gemi
|
50
|
+
- features/basic_commands.feature
|
51
|
+
- features/command_specific_options.feature
|
52
|
+
- features/config_file.feature
|
53
|
+
- features/gems_yaml.feature
|
54
|
+
- features/multiple_rubys.feature
|
55
|
+
- features/step_definitions/gemi_steps.rb
|
56
|
+
- features/support/env.rb
|
57
|
+
- features/tmp/.gitignore
|
30
58
|
- gemi.gemspec
|
31
59
|
- gemirc.yml
|
60
|
+
- lib/gemi.rb
|
61
|
+
- lib/gemi/commands.rb
|
62
|
+
- lib/gemi/conf.rb
|
63
|
+
- lib/gemi/gem.rb
|
64
|
+
- lib/gemi/options.rb
|
65
|
+
- lib/gemi/ruby.rb
|
66
|
+
- lib/gemi/runner.rb
|
32
67
|
has_rdoc: true
|
33
68
|
homepage: http://github.com/yhara/gemi
|
34
69
|
licenses: []
|
35
70
|
|
36
|
-
post_install_message:
|
71
|
+
post_install_message: " Thank you for installing gemi!\n The format of ~/.gemirc is changed in gemi 0.1.0.\n If you have been using gemi 0.0.x,\n please modify it (see gemirc.yml)\n"
|
37
72
|
rdoc_options:
|
38
73
|
- --charset=UTF-8
|
39
74
|
require_paths:
|
@@ -56,6 +91,6 @@ rubyforge_project:
|
|
56
91
|
rubygems_version: 1.3.5
|
57
92
|
signing_key:
|
58
93
|
specification_version: 3
|
59
|
-
summary:
|
94
|
+
summary: gem command for multiple rubys
|
60
95
|
test_files: []
|
61
96
|
|
data/README
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
= gemi
|
2
|
-
|
3
|
-
gemi is a simple tool for installing gems for multiple rubys.
|
4
|
-
|
5
|
-
== Install
|
6
|
-
|
7
|
-
1. gem install gemcutter
|
8
|
-
|
9
|
-
2. gem tumble
|
10
|
-
|
11
|
-
3. gem install gemi
|
12
|
-
|
13
|
-
or:
|
14
|
-
|
15
|
-
gem install gemi --source=http://gemcutter.org
|
16
|
-
|
17
|
-
== Setup
|
18
|
-
|
19
|
-
$ gemi
|
20
|
-
|
21
|
-
then edit ~/.gemirc
|
22
|
-
|
23
|
-
== Usage
|
24
|
-
|
25
|
-
$ gemi foobar
|
26
|
-
|
27
|
-
installs the gem 'foobar' for your rubys.
|
28
|
-
|
29
|
-
== Contact
|
30
|
-
|
31
|
-
http://github.com/yhara/gemi
|
32
|
-
|
33
|
-
yhara (Yutaka HARA)
|
34
|
-
yutaka.hara.gmail.com
|
35
|
-
http://route477.net/
|