gemi 0.0.5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ features/tmp/
@@ -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 = "Installing gems for multiple rubys"
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 = gemspec.summary
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.5
1
+ 0.1.0
data/bin/gemi CHANGED
@@ -1,91 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- require 'optparse'
3
- require 'fileutils'
4
- require 'yaml'
2
+ $LOAD_PATH.unshift File.expand_path("../lib", File.dirname(__FILE__))
3
+ require 'gemi'
5
4
 
6
- class Gemi
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
@@ -5,40 +5,74 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{gemi}
8
- s.version = "0.0.5"
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{2009-10-03}
12
+ s.date = %q{2010-01-13}
13
13
  s.default_executable = %q{gemi}
14
- s.description = %q{Installing gems for multiple rubys}
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
- "History.txt",
22
- "README",
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{Installing gems for multiple rubys}
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
- - :name: 'MRI 1.8' # used just for showing messages
2
- :command: 'sudo gem' # gem command to install
3
- :options: # options for 'gem install'
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,5 @@
1
+ module Gemi
2
+ Ruby = Struct.new(:name, :gem_command, :gem_home, :options)
3
+
4
+ Ruby::Default = Ruby.new("Ruby", "gem", nil, {})
5
+ end
@@ -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.5
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: 2009-10-03 00:00:00 +09:00
12
+ date: 2010-01-13 00:00:00 +09:00
13
13
  default_executable: gemi
14
- dependencies: []
15
-
16
- description: Installing gems for multiple rubys
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: Installing gems for multiple rubys
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/