rip 0.0.1 → 0.0.2

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.
Files changed (41) hide show
  1. data/README.markdown +18 -19
  2. data/lib/rip.rb +12 -6
  3. data/lib/rip/commands.rb +23 -8
  4. data/lib/rip/commands/build.rb +12 -3
  5. data/lib/rip/commands/core.rb +1 -3
  6. data/lib/rip/commands/install.rb +3 -1
  7. data/lib/rip/commands/ruby.rb +15 -0
  8. data/lib/rip/commands/setup.rb +21 -0
  9. data/lib/rip/commands/uninstall.rb +8 -1
  10. data/lib/rip/env.rb +18 -2
  11. data/lib/rip/installer.rb +13 -12
  12. data/lib/rip/package.rb +5 -1
  13. data/lib/rip/package_api.rb +8 -0
  14. data/lib/rip/package_manager.rb +21 -5
  15. data/lib/rip/packages/file_package.rb +7 -3
  16. data/lib/rip/packages/gem_package.rb +7 -3
  17. data/lib/rip/packages/git_package.rb +8 -3
  18. data/lib/rip/packages/http_package.rb +0 -1
  19. data/lib/rip/packages/remote_gem_package.rb +5 -1
  20. data/lib/rip/packages/ripfile_package.rb +23 -5
  21. data/lib/rip/setup.rb +120 -36
  22. data/lib/rip/sh/git.rb +6 -2
  23. data/lib/rip/version.rb +1 -1
  24. data/setup.rb +15 -1
  25. data/test/env_test.rb +23 -1
  26. data/test/file_test.rb +34 -0
  27. data/test/git_test.rb +20 -3
  28. data/test/mock_git.rb +7 -3
  29. data/test/repos/simple-file-3.2.1.rb +1 -0
  30. data/test/repos/simple.rip +2 -0
  31. data/test/repos/simple_c/dot_git/index +0 -0
  32. data/test/repos/simple_c/dot_git/logs/HEAD +1 -0
  33. data/test/repos/simple_c/dot_git/logs/refs/heads/master +1 -0
  34. data/test/repos/simple_c/dot_git/objects/4f/3f9a42a24970fb72e8a828d95652c08465b3a4 +0 -0
  35. data/test/repos/simple_c/dot_git/objects/64/38cb2cf06f0a0e96326f4223202bece66540a4 +0 -0
  36. data/test/repos/simple_c/dot_git/objects/9f/88aea8cd1b0da9b4d42188b7cf2014392344e6 +0 -0
  37. data/test/repos/simple_c/dot_git/objects/f1/050d684f583a32338ffd77ec37e1196e0d2cc7 +0 -0
  38. data/test/repos/simple_c/dot_git/refs/heads/master +1 -1
  39. data/test/ripfile_test.rb +19 -0
  40. data/test/test_helper.rb +35 -0
  41. metadata +19 -5
@@ -1,8 +1,8 @@
1
1
  Rip: Ruby's Intelligent Packaging
2
2
  =================================
3
3
 
4
- Rip is an attempt to create an intelligent packaging system
5
- for Ruby.
4
+ Rip is an attempt to create a next generation packaging
5
+ system for Ruby.
6
6
 
7
7
  For more thorough documentation please see the Rip site:
8
8
 
@@ -36,14 +36,14 @@ None. Really? Let's try to require Grit.
36
36
 
37
37
  Whoops. Not found. Let's install the latest using rip.
38
38
 
39
- $ rip install git://github.com/mojombo/grit.git v1.1.1
39
+ $ rip install git://github.com/defunkt/grit.git v1.1.1b
40
40
  Successfully installed grit v1.1.1
41
41
  $ rip list
42
42
  ripenv: base
43
43
 
44
- diff-lcs (5621f02)
44
+ diff-lcs (491fbc0)
45
+ mime-types (v1.16)
45
46
  grit (v1.1.1)
46
- mime-types (0fd8958)
47
47
 
48
48
  Great, now we have Grit and all its dependencies.
49
49
 
@@ -190,12 +190,11 @@ dependents, use `-d` (for dependents).
190
190
  Extensions
191
191
  ----------
192
192
 
193
- Installing a package that is not Rip aware but needs an extension
194
- built? Use `rip build`.
193
+ Rip will attempt to build extensions during installation through the
194
+ `rip build` command.
195
195
 
196
- Rip will attempt to run `rake rip:install` in your library if a
197
- Rakefile is found. If you need to compile your C extension or do
198
- any other work, this is the place.
196
+ You can also run `rip build PACKAGE` to try and build a package
197
+ manually.
199
198
 
200
199
  Rip Directory Structure
201
200
  -----------------------
@@ -222,14 +221,14 @@ Here is a typical directory structure for Rip:
222
221
  - lib/
223
222
  - thunderhorse.ripenv
224
223
 
225
- The above contains three ripenvs: `base`, `cheat`, and `thunderhose`. Each
224
+ The above contains three ripenvs: `base`, `cheat`, and `thunderhorse`. Each
226
225
  ripenv contains directories for executable binaries and Ruby source files.
227
226
  They also include a generated `.ripenv` file containing metadata about
228
227
  the ripenev and its packages.
229
228
 
230
229
  This individual may use `base` for general tomfoolery (it's the
231
230
  default), `cheat` for developing their Cheat application, and
232
- `thunderhorse` for working on their new Thunderhose project.
231
+ `thunderhorse` for working on their new Thunderhorse project.
233
232
 
234
233
  `active` is a symlink to the current, active ripenv. We also see a
235
234
  `rip-packages` directory. This is where Rip stores the raw repositories.
@@ -287,13 +286,13 @@ As a result, the setup script expects you to be running bash or zshell.
287
286
  Contributors
288
287
  ------------
289
288
 
290
- * Chris Wanstrath (that's me!)
291
- * Jeff Hodges
292
- * Tom Preston-Werner
293
- * John Barnette
294
- * Blake Mizerany
295
- * Ryan Tomayko
296
- * Pat Nakajima
289
+ * [Chris Wanstrath](http://github.com/defunkt) (that's me!)
290
+ * [Jeff Hodges](http://github.com/jmhodges/)
291
+ * [Tom Preston-Werner](http://github.com/mojombo/)
292
+ * [John Barnette](http://github.com/jbarnette)
293
+ * [Blake Mizerany](http://github.com/bmizerany)
294
+ * [Ryan Tomayko](http://github.com/rtomayko)
295
+ * [Pat Nakajima](http://github.com/nakajima)
297
296
 
298
297
  Special Thanks
299
298
  --------------
data/lib/rip.rb CHANGED
@@ -1,16 +1,18 @@
1
1
  require 'fileutils'
2
2
 
3
3
  module Rip
4
+ # Returns the Rip data directory. That is, the directory which contains
5
+ # all the Rip environment directories.
4
6
  def self.dir
5
7
  return @dir if @dir
6
8
 
7
- dir = ENV['RIPDIR'].to_s
8
-
9
- if dir.empty?
10
- abort "RIPDIR env variable not found. did you run setup.rb?"
9
+ env = ENV['RIPDIR'].to_s
10
+ if env.empty?
11
+ dir = File.join(user_home, ".rip")
12
+ else
13
+ dir = File.expand_path(env)
11
14
  end
12
-
13
- dir = File.expand_path(dir)
15
+
14
16
  FileUtils.mkdir_p dir unless File.exists? dir
15
17
  @dir = dir
16
18
  end
@@ -26,6 +28,10 @@ module Rip
26
28
  def self.ui=(io)
27
29
  @ui = Rip::UI.new(io)
28
30
  end
31
+
32
+ def self.user_home
33
+ @home ||= ENV['HOME']
34
+ end
29
35
  end
30
36
 
31
37
  # load rip files
@@ -5,7 +5,11 @@ module Rip
5
5
  def invoke(args)
6
6
  command, options, args = parse_args(args)
7
7
 
8
- if command.nil? || command == ''
8
+ if command.nil? && (options[:v] || options[:version])
9
+ command = :version
10
+ end
11
+
12
+ if command.nil? || command == '' || options[:h] || options[:help]
9
13
  command = :help
10
14
  end
11
15
 
@@ -23,8 +27,17 @@ module Rip
23
27
  end
24
28
  end
25
29
 
30
+ def load_plugin(file)
31
+ begin
32
+ require file
33
+ rescue Exception => e
34
+ ui.puts "rip: plugin not loaded (#{file})"
35
+ ui.puts "-> #{e.message}", ''
36
+ end
37
+ end
38
+
26
39
  def public_instance_methods
27
- super - %w( invoke public_instance_methods )
40
+ super - %w( invoke load_plugin public_instance_methods )
28
41
  end
29
42
 
30
43
  private
@@ -35,7 +48,7 @@ module Rip
35
48
  @next_usage = usage
36
49
  end
37
50
 
38
- def x(help)
51
+ def x(help = '')
39
52
  @help ||= {}
40
53
  @next_help ||= []
41
54
  @next_help.push help
@@ -62,6 +75,8 @@ module Rip
62
75
  end
63
76
 
64
77
  if matches.size == 0
78
+ ui.puts "Could not find the command: #{command.inspect}"
79
+ ui.puts
65
80
  :help
66
81
  elsif matches.size == 1
67
82
  matches.first
@@ -71,16 +86,16 @@ module Rip
71
86
  end
72
87
 
73
88
  def parse_args(args)
74
- command = args.shift
75
89
  options = args.select { |piece| piece =~ /^-/ }
76
90
  args -= options
91
+ command = args.shift
77
92
  options = options.inject({}) do |hash, flag|
78
93
  key, value = flag.split('=')
79
94
  hash[key.sub(/^--?/,'').intern] = value.nil? ? true : value
80
95
  hash
81
96
  end
82
97
 
83
- [command, options, args]
98
+ [ command, options, args ]
84
99
  end
85
100
  end
86
101
  end
@@ -93,14 +108,14 @@ end
93
108
  # load ~/.rip/rip-commands/*.rb
94
109
  if File.exists? dir = File.join(Rip.dir, 'rip-commands')
95
110
  Dir[dir + '/*.rb'].each do |file|
96
- require file
111
+ Rip::Commands.load_plugin(file)
97
112
  end
98
113
  end
99
114
 
100
115
  # load lib/rip/commands/*.rb from the active ripenv
101
116
  if File.exists? dir = File.join(Rip::Env.active_dir, 'lib', 'rip', 'commands')
102
117
  Dir[dir + '/*.rb'].each do |file|
103
- require file
118
+ Rip::Commands.load_plugin(file)
104
119
  end
105
120
  end
106
121
 
@@ -108,6 +123,6 @@ end
108
123
  # load lib/rip/commands/*.rb from rip itself
109
124
  if File.exists? dir = File.join(File.dirname(__FILE__), 'commands')
110
125
  Dir[dir + '/*.rb'].each do |file|
111
- require file
126
+ Rip::Commands.load_plugin(file)
112
127
  end
113
128
  end
@@ -7,15 +7,24 @@ module Rip
7
7
  module Commands
8
8
  def build(options={}, *packages)
9
9
  packages.each do |package_name|
10
- ui.puts "rip: building package: #{package_name}"
11
10
  package = manager.package(package_name)
11
+ alerted = false
12
12
 
13
13
  Dir["#{package.cache_path}/**/extconf.rb"].each do |build_file|
14
+ if !alerted
15
+ ui.puts "rip: building #{package_name}"
16
+ alerted = true
17
+ end
18
+
14
19
  build_dir = File.dirname(build_file)
15
- Dir.chdir(build_dir) {
20
+ Dir.chdir(build_dir) do
16
21
  system "ruby extconf.rb"
17
22
  system "make install RUBYARCHDIR=#{manager.dir}/lib"
18
- }
23
+ end
24
+ end
25
+
26
+ if !alerted && !options[:quiet]
27
+ ui.puts "rip: don't know how to build #{package_name}"
19
28
  end
20
29
  end
21
30
  end
@@ -27,7 +27,7 @@ module Rip
27
27
  x 'Commands for managing your ripenvs.'
28
28
  x 'Type rip env to see valid options.'
29
29
  def env(options = {}, command = nil, *args)
30
- if command && Rip::Env.respond_to?(command)
30
+ if command && Rip::Env.commands.include?(command)
31
31
  ui.puts 'ripenv: ' + Rip::Env.call(command, *args).to_s
32
32
  else
33
33
  show_help :env, Rip::Env.commands
@@ -48,8 +48,6 @@ module Rip
48
48
  def version(options = {}, *args)
49
49
  ui.puts "Rip #{Rip::Version}"
50
50
  end
51
- alias_method "-v", :version
52
- alias_method "--version", :version
53
51
 
54
52
  private
55
53
  def show_help(command, commands)
@@ -4,8 +4,10 @@ module Rip
4
4
  def check(*args)
5
5
  Setup.check_installation
6
6
  ui.puts "All systems go."
7
+ rescue Setup::StaleEnvironmentError, Setup::InstallationError => e
8
+ ui.puts e.message
7
9
  rescue => e
8
- ui.abort "Installation failed: #{e.message}"
10
+ ui.puts "Installation failed: #{e.message}"
9
11
  end
10
12
 
11
13
  o 'rip install SOURCE [options]'
@@ -0,0 +1,15 @@
1
+ module Rip
2
+ module Commands
3
+ o 'ruby ENV ARGS'
4
+ x 'Runs a Ruby instance in a particular environment.'
5
+ def ruby(options={}, *args)
6
+ selected_env = File.join(Rip.dir, ARGV.shift, "lib")
7
+ path = (ENV["RUBYLIB"] || "").split(":")
8
+ active_env = File.join(Rip.dir, "active", "lib")
9
+ path -= [active_env]
10
+ path += [selected_env]
11
+ ENV["RUBYLIB"] = path.join(":")
12
+ exec(ENV['RUBYBIN'] || "ruby", *ARGV)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ module Rip
2
+ module Commands
3
+
4
+ # Generate necessary envs etc. in ~/.{bash,zsh,...}rc.
5
+ #
6
+ o "rip setup [script to modify]"
7
+ x "Inserts required environment variables into your startup script."
8
+ x
9
+ x "Pass it the startup script you want to modify, otherwise it will"
10
+ x "guess one."
11
+ def setup(options = {}, script = nil)
12
+ require "rip/setup"
13
+
14
+ if Setup.setup_startup_script(script)
15
+ ui.puts "rip: Your #{Setup.startup_script} script has been modified."
16
+ ui.puts "rip: Please restart your shell or type `source #{Rip::Setup.startup_script}` for the changes to become effective."
17
+ end
18
+ end
19
+
20
+ end
21
+ end
@@ -1,7 +1,7 @@
1
1
  module Rip
2
2
  module Commands
3
3
  o 'rip uninstall PACKAGE [options]'
4
- x 'Uninstalls a single Rip package.'
4
+ x 'Uninstalls a single Rip package (or rip itself).'
5
5
  x '-y removes the package no matter what.'
6
6
  x '-d removes the package and its dependents.'
7
7
  def uninstall(options = {}, name = nil, *args)
@@ -9,6 +9,13 @@ module Rip
9
9
  ui.abort "Please tell me what to uninstall."
10
10
  end
11
11
 
12
+ if name == 'rip' && !options[:y]
13
+ ui.abort "Are you sure you want to uninstall rip? Pass -y if so."
14
+ elsif name == 'rip' && options[:y]
15
+ require 'rip/setup'
16
+ return Rip::Setup.uninstall(true)
17
+ end
18
+
12
19
  force = options[:y] || options[:d]
13
20
  package = manager.package(name)
14
21
 
@@ -1,6 +1,7 @@
1
1
  module Rip
2
2
  module Env
3
3
  extend self
4
+ PRIVATE_ENV = /^(rip-|active)/i
4
5
 
5
6
  def commands
6
7
  instance_methods - %w( call active_dir commands ui )
@@ -13,6 +14,10 @@ module Rip
13
14
  return "must give a ripenv to create"
14
15
  end
15
16
 
17
+ if env.strip =~ PRIVATE_ENV
18
+ return "invalid environment name"
19
+ end
20
+
16
21
  if File.exists? dir
17
22
  "#{env} exists"
18
23
  else
@@ -29,6 +34,10 @@ module Rip
29
34
  return "must give a ripenv to use"
30
35
  end
31
36
 
37
+ if env.strip =~ PRIVATE_ENV
38
+ return "invalid environment name"
39
+ end
40
+
32
41
  if !File.exists?(target = File.join(Rip.dir, env))
33
42
  return "#{env} doesn't exist"
34
43
  end
@@ -51,6 +60,10 @@ module Rip
51
60
  return "must give a ripenv to delete"
52
61
  end
53
62
 
63
+ if env.strip =~ PRIVATE_ENV
64
+ return "invalid environment name"
65
+ end
66
+
54
67
  if File.exists?(target = File.join(Rip.dir, env))
55
68
  FileUtils.rm_rf target
56
69
  "deleted #{env}"
@@ -64,7 +77,7 @@ module Rip
64
77
  env.split('/').last
65
78
  end
66
79
 
67
- envs.reject! { |env| env =~ /^(rip-|active)/ }
80
+ envs.reject! { |env| env =~ PRIVATE_ENV }
68
81
 
69
82
  if envs.empty?
70
83
  "none. make one with `rip env create <env>`"
@@ -95,6 +108,7 @@ module Rip
95
108
 
96
109
  if File.exists? ripfile = File.join(dest, "#{env}.ripenv")
97
110
  FileUtils.cp ripfile, File.join(dest, "#{new}.ripenv")
111
+ FileUtils.rm ripfile
98
112
  end
99
113
 
100
114
  use new
@@ -112,8 +126,10 @@ module Rip
112
126
  send(meth, *args)
113
127
  elsif arity == 0
114
128
  send(meth)
129
+ elsif args.empty?
130
+ send(meth, '')
115
131
  else
116
- send(meth, args[0, arity])
132
+ send(meth, *args[0, arity])
117
133
  end
118
134
  end
119
135
 
@@ -15,7 +15,7 @@ module Rip
15
15
 
16
16
  def install(package, parent = nil)
17
17
  if !package.exists?
18
- error = package.name
18
+ error = package.to_s
19
19
  error += " requested by #{parent} but" if parent
20
20
  error += " not found at #{package.source}"
21
21
  ui.abort error
@@ -30,17 +30,18 @@ module Rip
30
30
  return if installed
31
31
  @installed[package.name] = package
32
32
 
33
- if !package.version
33
+ if !package.meta_package? && !package.version
34
34
  ui.abort "can't install #{package} - it has no version"
35
35
  end
36
36
 
37
37
  package.fetch
38
38
  package.unpack
39
39
  install_dependencies(package)
40
- run_install_hook(package)
40
+ build_extensions(package)
41
41
  copy_files(package)
42
42
  cleanup(package)
43
43
  ui.puts "Successfully installed #{package}" unless package.meta_package?
44
+ true
44
45
 
45
46
  rescue VersionConflict => e
46
47
  ui.puts e.message
@@ -56,17 +57,13 @@ module Rip
56
57
 
57
58
  def install_dependencies(package)
58
59
  package.dependencies.each do |dependency|
59
- install(dependency, package)
60
+ success = install(dependency, package)
61
+ package.run_hook(:dependency_installed, dependency, success)
60
62
  end
61
63
  end
62
64
 
63
- def run_install_hook(package)
64
- return unless File.exists? File.join(package.cache_path, 'Rakefile')
65
-
66
- Dir.chdir package.cache_path do
67
- ui.puts "running install hook for #{package.name}"
68
- system "rake -s rip:install >& /dev/null"
69
- end
65
+ def build_extensions(package)
66
+ Rip::Commands.build({:quiet => true}, package)
70
67
  end
71
68
 
72
69
  def copy_files(package)
@@ -82,7 +79,7 @@ module Rip
82
79
  end
83
80
 
84
81
  if File.exists? package_bin
85
- FileUtils.cp_r package_bin + '/.', dest_bin
82
+ FileUtils.cp_r package_bin + '/.', dest_bin, :preserve => true
86
83
  end
87
84
  end
88
85
 
@@ -123,6 +120,10 @@ module Rip
123
120
  end
124
121
  end
125
122
 
123
+ def rakebin
124
+ ENV['RAKEBIN'] || 'rake'
125
+ end
126
+
126
127
  def ui
127
128
  Rip.ui
128
129
  end