rip 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/.gitignore +4 -0
  2. data/LICENSE +20 -0
  3. data/README.markdown +306 -0
  4. data/Rakefile +51 -0
  5. data/bin/rip +6 -0
  6. data/examples/debug.rb +13 -0
  7. data/examples/reverse.rb +21 -0
  8. data/ext/extconf.rb +11 -0
  9. data/lib/rip.rb +53 -0
  10. data/lib/rip/commands.rb +113 -0
  11. data/lib/rip/commands/build.rb +23 -0
  12. data/lib/rip/commands/core.rb +82 -0
  13. data/lib/rip/commands/install.rb +37 -0
  14. data/lib/rip/commands/uninstall.rb +43 -0
  15. data/lib/rip/env.rb +128 -0
  16. data/lib/rip/installer.rb +130 -0
  17. data/lib/rip/memoize.rb +111 -0
  18. data/lib/rip/package.rb +126 -0
  19. data/lib/rip/package_api.rb +94 -0
  20. data/lib/rip/package_manager.rb +175 -0
  21. data/lib/rip/packages/dir_package.rb +34 -0
  22. data/lib/rip/packages/file_package.rb +60 -0
  23. data/lib/rip/packages/gem_package.rb +44 -0
  24. data/lib/rip/packages/git_package.rb +62 -0
  25. data/lib/rip/packages/http_package.rb +46 -0
  26. data/lib/rip/packages/remote_gem_package.rb +64 -0
  27. data/lib/rip/packages/ripfile_package.rb +46 -0
  28. data/lib/rip/setup.rb +205 -0
  29. data/lib/rip/sh/git.rb +35 -0
  30. data/lib/rip/ui.rb +24 -0
  31. data/lib/rip/version.rb +9 -0
  32. data/setup.rb +27 -0
  33. data/test/commands_test.rb +15 -0
  34. data/test/dev.rip +2 -0
  35. data/test/dir_test.rb +25 -0
  36. data/test/env_test.rb +173 -0
  37. data/test/git_test.rb +36 -0
  38. data/test/mock_git.rb +51 -0
  39. data/test/repos/simple_c/dot_git/HEAD +1 -0
  40. data/test/repos/simple_c/dot_git/config +6 -0
  41. data/test/repos/simple_c/dot_git/description +1 -0
  42. data/test/repos/simple_c/dot_git/hooks/applypatch-msg.sample +15 -0
  43. data/test/repos/simple_c/dot_git/hooks/commit-msg.sample +24 -0
  44. data/test/repos/simple_c/dot_git/hooks/post-commit.sample +8 -0
  45. data/test/repos/simple_c/dot_git/hooks/post-receive.sample +15 -0
  46. data/test/repos/simple_c/dot_git/hooks/post-update.sample +8 -0
  47. data/test/repos/simple_c/dot_git/hooks/pre-applypatch.sample +14 -0
  48. data/test/repos/simple_c/dot_git/hooks/pre-commit.sample +18 -0
  49. data/test/repos/simple_c/dot_git/hooks/pre-rebase.sample +169 -0
  50. data/test/repos/simple_c/dot_git/hooks/prepare-commit-msg.sample +36 -0
  51. data/test/repos/simple_c/dot_git/hooks/update.sample +107 -0
  52. data/test/repos/simple_c/dot_git/index +0 -0
  53. data/test/repos/simple_c/dot_git/info/exclude +6 -0
  54. data/test/repos/simple_c/dot_git/logs/HEAD +1 -0
  55. data/test/repos/simple_c/dot_git/logs/refs/heads/master +1 -0
  56. data/test/repos/simple_c/dot_git/objects/2d/94227280db3ac66875f52592c6a736b4526084 +0 -0
  57. data/test/repos/simple_c/dot_git/objects/3f/1d6dacdedf75058e9edf23f48de03fa451f7ce +1 -0
  58. data/test/repos/simple_c/dot_git/objects/53/23e9a7ff897fe7bfc3357d9274775b67f9ade4 +0 -0
  59. data/test/repos/simple_c/dot_git/objects/55/31db58bd71148661c400dc48815bf06b366128 +0 -0
  60. data/test/repos/simple_c/dot_git/objects/d7/55c6f119520808609a8d79bac1a8dbe0c57424 +0 -0
  61. data/test/repos/simple_c/dot_git/objects/d7/58739ea968ac8e8fe0cbbf1f6451af47f04964 +0 -0
  62. data/test/repos/simple_c/dot_git/objects/e6/7b81a24f0ce4bff84c3599b5c9ba7093f554d8 +0 -0
  63. data/test/repos/simple_c/dot_git/objects/ec/be0a80dc841c16beb2c733bbdd320b45565d89 +0 -0
  64. data/test/repos/simple_c/dot_git/refs/heads/master +1 -0
  65. data/test/repos/simple_c/ext/simp/extconf.rb +6 -0
  66. data/test/repos/simple_c/ext/simp/simp.c +17 -0
  67. data/test/repos/simple_c/lib/simple_c.rb +1 -0
  68. data/test/repos/simple_d-1.2.3/lib/simple_d.rb +1 -0
  69. data/test/rip_test.rb +8 -0
  70. data/test/test_helper.rb +79 -0
  71. data/test/ui_test.rb +36 -0
  72. metadata +149 -0
@@ -0,0 +1,35 @@
1
+ module Rip
2
+ module Sh
3
+ module Git
4
+ extend self
5
+
6
+ def git_ls_remote(source, version)
7
+ `git ls-remote #{source} #{version} 2> /dev/null`
8
+ end
9
+
10
+ def git_clone(source, cache_name)
11
+ `git clone #{source} #{cache_name}`
12
+ end
13
+
14
+ def git_fetch(remote)
15
+ `git fetch #{remote}`
16
+ end
17
+
18
+ def git_reset_hard(version)
19
+ `git reset --hard #{version}`
20
+ end
21
+
22
+ def git_submodule_init
23
+ `git submodule init`
24
+ end
25
+
26
+ def git_submodule_update
27
+ `git submodule update`
28
+ end
29
+
30
+ def git_revparse(repothing)
31
+ `git rev-parse #{repothing}`
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,24 @@
1
+ module Rip
2
+ class UI
3
+ def initialize(io=nil)
4
+ @io = io
5
+ end
6
+
7
+ def puts(*args)
8
+ return unless @io
9
+
10
+ if args.empty?
11
+ @io.puts ""
12
+ else
13
+ args.each { |msg| @io.puts(msg) }
14
+ end
15
+
16
+ @io.flush
17
+ nil
18
+ end
19
+
20
+ def abort(msg)
21
+ @io && Kernel.abort("rip: #{msg}")
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,9 @@
1
+ module Rip
2
+ module Version
3
+ VERSION = "0.0.1"
4
+
5
+ def self.to_s
6
+ VERSION
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ #
2
+ # installs rip like so:
3
+ # ruby setup.rb
4
+ #
5
+ # also uninstalls rip like so:
6
+ # ruby setup.rb uninstall
7
+ #
8
+ # probably requires sudo.
9
+ #
10
+
11
+ __DIR__ = File.expand_path(File.dirname(__FILE__))
12
+ $LOAD_PATH.unshift File.join(__DIR__, 'lib')
13
+
14
+ require 'rip'
15
+
16
+ include Rip::Setup
17
+
18
+ if ARGV.include? 'uninstall'
19
+ uninstall :verbose
20
+ elsif ARGV.include? 'reinstall'
21
+ uninstall
22
+ install
23
+ elsif installed?
24
+ puts "rip: already installed"
25
+ else
26
+ install
27
+ end
@@ -0,0 +1,15 @@
1
+ $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__))
2
+ require 'test_helper'
3
+
4
+ context 'Parsing command line args' do
5
+ setup do
6
+ Rip::Commands.send(:public, :parse_args)
7
+ end
8
+
9
+ test "works" do
10
+ assert_equal ["install", { :f => true }, []], Rip::Commands.parse_args(%w( install -f ))
11
+ assert_equal ["install", { :f => "force" }, []], Rip::Commands.parse_args(%w( install -f=force ))
12
+ assert_equal ["install", { :f => true }, [ "force", "name" ]], Rip::Commands.parse_args(%w( install -f force name ))
13
+ assert_equal ["install", {}, [ "something" ]], Rip::Commands.parse_args(%w( install something ))
14
+ end
15
+ end
@@ -0,0 +1,2 @@
1
+ http://gist.github.com/raw/25455/8f592eaeaa3b1563df16fbaf5f56378c4cbda146/test-spec-mini.rb
2
+ git://github.com/defunkt/fakefs.git
@@ -0,0 +1,25 @@
1
+ $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__))
2
+ require 'test_helper'
3
+
4
+ context 'Installing from a directory' do
5
+ setup_with_fs do
6
+ @source = fresh_local_dir('simple_d-1.2.3').source
7
+ end
8
+
9
+ test "installs the lib files" do
10
+ Rip::Commands.install({}, @source)
11
+
12
+ libpath = Rip.dir + '/active/lib/simple_d.rb'
13
+ assert File.exists?(libpath), 'simple_d.rb should be installed'
14
+ end
15
+
16
+ test "finds version from name suffix" do
17
+ assert_equal '1.2', fresh_local_dir('simple_d-1.2').version
18
+ assert_equal '1.2.3', fresh_local_dir('simple_d-1.2.3').version
19
+ assert_equal '1.2.3.4', fresh_local_dir('simple_d-1.2.3.4').version
20
+ end
21
+
22
+ test "defaults to unversioned if not named properly" do
23
+ assert_equal 'unversioned', fresh_local_dir('simple_d').version
24
+ end
25
+ end
@@ -0,0 +1,173 @@
1
+ $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__))
2
+ require 'test_helper'
3
+
4
+ context "Creating a ripenv" do
5
+ setup_with_fs do
6
+ @active_dir = File.join(Rip.dir, 'active')
7
+ @name = 'new_env'
8
+ @ripenv = File.join(Rip.dir, @name)
9
+ assert !File.exists?(@ripenv)
10
+ end
11
+
12
+ test "creates the directories on disk" do
13
+ Rip::Env.create(@name)
14
+ assert File.exists?(File.join(@ripenv, 'bin'))
15
+ assert File.exists?(File.join(@ripenv, 'lib'))
16
+ end
17
+
18
+ test "confirms creation" do
19
+ assert_equal "created new_env", Rip::Env.create(@name)
20
+ end
21
+
22
+ test "fails if the ripenv exists" do
23
+ assert_equal "base exists", Rip::Env.create('base')
24
+ end
25
+
26
+ test "switches to the new ripenv" do
27
+ Rip::Env.create(@name)
28
+ assert_equal @name, Rip::Env.active
29
+ end
30
+
31
+ test 'fails if no ripenv is given' do
32
+ assert_equal 'must give a ripenv to create', Rip::Env.create('')
33
+ assert_not_equal '', Rip::Env.active
34
+ assert_equal 'must give a ripenv to create', Rip::Env.create(' ')
35
+ assert_equal 'must give a ripenv to create', Rip::Env.create("\t")
36
+ assert_equal 'must give a ripenv to create', Rip::Env.create("\t ")
37
+ end
38
+ end
39
+
40
+ context "Using a ripenv" do
41
+ setup_with_fs do
42
+ @active_dir = File.join(Rip.dir, 'active')
43
+ @name = 'other'
44
+ @ripenv = File.join(Rip.dir, @name)
45
+ @base = 'base'
46
+ @old_ripenv = File.join(Rip.dir, @base)
47
+ end
48
+
49
+ test "switches the active symlink" do
50
+ Rip::Env.use(@name)
51
+ assert_equal @name, Rip::Env.active
52
+ end
53
+
54
+ test "confirms the change" do
55
+ assert_equal "using #{@name}", Rip::Env.use(@name)
56
+ end
57
+
58
+ test "fails if the new env doesn't exist" do
59
+ assert_equal "fake doesn't exist", Rip::Env.use("fake")
60
+ end
61
+
62
+ test 'fails if no ripenv is given' do
63
+ assert_equal "must give a ripenv to use", Rip::Env.use('')
64
+ assert_not_equal '', Rip::Env.active
65
+ assert_equal 'must give a ripenv to use', Rip::Env.use(' ')
66
+ assert_equal 'must give a ripenv to use', Rip::Env.use("\t")
67
+ assert_equal 'must give a ripenv to use', Rip::Env.use("\t ")
68
+
69
+ end
70
+ end
71
+
72
+ context "Deleting a ripenv" do
73
+ setup_with_fs do
74
+ @name = "other"
75
+ @ripenv = File.join(Rip.dir, @name)
76
+ end
77
+
78
+ test "removes the ripenv" do
79
+ assert File.exists?(@ripenv)
80
+ Rip::Env.delete(@name)
81
+ assert !File.exists?(@ripenv)
82
+ end
83
+
84
+ test "confirms removal" do
85
+ assert_equal "deleted #{@name}", Rip::Env.delete(@name)
86
+ end
87
+
88
+ test "fails if it's the active ripenv" do
89
+ assert_equal "can't delete active environment", Rip::Env.delete('base')
90
+ end
91
+
92
+ test "fails if it doesn't exist" do
93
+ name = 'fake_env'
94
+ assert_equal "can't find #{name}", Rip::Env.delete(name)
95
+ assert File.exists?(Rip.dir)
96
+ end
97
+
98
+ test "fails if no name is provided" do
99
+ assert_equal "must give a ripenv to delete", Rip::Env.delete('')
100
+ assert_equal 'must give a ripenv to delete', Rip::Env.delete(' ')
101
+ assert_equal 'must give a ripenv to delete', Rip::Env.delete("\t")
102
+ assert_equal 'must give a ripenv to delete', Rip::Env.delete("\t ")
103
+ assert File.exists?(Rip.dir)
104
+ end
105
+ end
106
+
107
+ context "Listing ripenvs" do
108
+ setup_with_fs do
109
+ @ripenvs = Rip::Env.list
110
+ end
111
+
112
+ test "prints ripenvs" do
113
+ assert_equal 2, @ripenvs.split(' ').size
114
+ assert @ripenvs.include?('base')
115
+ end
116
+
117
+ test "ignores the active symlink" do
118
+ assert !@ripenvs.include?('active')
119
+ end
120
+
121
+ test "ignores rip-* directories" do
122
+ assert !@ripenvs.include?('rip-packages')
123
+ end
124
+ end
125
+
126
+ context "Displaying the active ripenv" do
127
+ setup_with_fs do
128
+ # no setup
129
+ end
130
+
131
+ test "works" do
132
+ assert_equal 'base', Rip::Env.active
133
+ end
134
+
135
+ test "works across env changes" do
136
+ Rip::Env.use('other')
137
+ assert_equal 'other', Rip::Env.active
138
+ end
139
+ end
140
+
141
+ context "Copying the current ripenv" do
142
+ setup_with_fs do
143
+ @name = 'new_env'
144
+ @ripenv = File.join(Rip.dir, @name)
145
+ end
146
+
147
+ test "creates a new env" do
148
+ Rip::Env.copy(@name)
149
+ assert File.exists?(@ripenv)
150
+ end
151
+
152
+ test "switches to the new env" do
153
+ Rip::Env.copy(@name)
154
+ assert_equal @name, Rip::Env.active
155
+ end
156
+
157
+ test "makes the new env a copy of the active env"
158
+
159
+ test "fails if the new env exists" do
160
+ assert_equal "other exists", Rip::Env.copy('other')
161
+ end
162
+
163
+ test "confirms the creation" do
164
+ assert_equal "cloned base to #{@name}", Rip::Env.copy(@name)
165
+ end
166
+
167
+ test 'fails if no new ripenv is given' do
168
+ assert_equal 'must give a ripenv to copy to', Rip::Env.copy('')
169
+ assert_equal 'must give a ripenv to copy to', Rip::Env.copy(' ')
170
+ assert_equal 'must give a ripenv to copy to', Rip::Env.copy("\t")
171
+ assert_equal 'must give a ripenv to copy to', Rip::Env.copy("\t ")
172
+ end
173
+ end
@@ -0,0 +1,36 @@
1
+ $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__))
2
+ require 'test_helper'
3
+
4
+ context 'Installing from a remote git repo' do
5
+ setup_with_fs do
6
+ @source = fresh_remote_git('simple_c')
7
+ end
8
+
9
+ teardown do
10
+ Rip::GitPackage.unmock_git
11
+ end
12
+
13
+ test "installs the lib files" do
14
+ Rip::Commands.install({}, @source)
15
+
16
+ libpath = Rip.dir + '/active/lib/simple_c.rb'
17
+ assert File.exists?(libpath), 'simple_c.rb should be installed'
18
+ end
19
+ end
20
+
21
+ context 'Installing from a local git repo' do
22
+ setup_with_fs do
23
+ @sources = fresh_local_git('simple_c')
24
+ end
25
+
26
+ teardown do
27
+ Rip::GitPackage.unmock_git
28
+ end
29
+
30
+ test 'local installs the lib files' do
31
+ Rip::Commands.install({}, @sources)
32
+ libpath = Rip.dir + '/active/lib/simple_c.rb'
33
+ assert File.exists?(libpath), 'simple_c.rb should be installed'
34
+ end
35
+ end
36
+
@@ -0,0 +1,51 @@
1
+ module Rip
2
+ module Sh
3
+ module MockGit
4
+ def git_ls_remote(source, version)
5
+ match_errors = []
6
+ if source != real_source
7
+ match_errors << "source was #{source} instead of #{real_source}"
8
+ end
9
+
10
+ if !match_errors.empty?
11
+ raise match_errors.join(" and ")
12
+ end
13
+
14
+ "67be542ddad55c502daf12fde4f784d88a248617\tHEAD\n67be542ddad55c502daf12fde4f784d88a248617\trefs/heads/master"
15
+ end
16
+
17
+ def git_fetch(repothing)
18
+ end
19
+
20
+ def git_clone(source, cache_name)
21
+ match_errors = []
22
+ if source != real_source
23
+ match_errors << "source was #{source} instead of #{real_source}"
24
+ end
25
+ if !match_errors.empty?
26
+ raise match_errors.join(" and ")
27
+ end
28
+
29
+ FakeFS::FileSystem.clone(repo_path(real_repo_name))
30
+ FileUtils.mv(repo_path(real_repo_name), cache_name)
31
+ end
32
+
33
+ def git_submodule_init
34
+ end
35
+
36
+ def git_submodule_update
37
+ end
38
+
39
+ def git_reset_hard(version)
40
+ end
41
+
42
+ def real_repo_name
43
+ raise NotImplementedError
44
+ end
45
+
46
+ def real_source
47
+ raise NotImplementedError
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1 @@
1
+ ref: refs/heads/master
@@ -0,0 +1,6 @@
1
+ [core]
2
+ repositoryformatversion = 0
3
+ filemode = true
4
+ bare = false
5
+ logallrefupdates = true
6
+ ignorecase = true
@@ -0,0 +1 @@
1
+ Unnamed repository; edit this file to name it for gitweb.
@@ -0,0 +1,15 @@
1
+ #!/bin/sh
2
+ #
3
+ # An example hook script to check the commit log message taken by
4
+ # applypatch from an e-mail message.
5
+ #
6
+ # The hook should exit with non-zero status after issuing an
7
+ # appropriate message if it wants to stop the commit. The hook is
8
+ # allowed to edit the commit message file.
9
+ #
10
+ # To enable this hook, rename this file to "applypatch-msg".
11
+
12
+ . git-sh-setup
13
+ test -x "$GIT_DIR/hooks/commit-msg" &&
14
+ exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
15
+ :
@@ -0,0 +1,24 @@
1
+ #!/bin/sh
2
+ #
3
+ # An example hook script to check the commit log message.
4
+ # Called by git-commit with one argument, the name of the file
5
+ # that has the commit message. The hook should exit with non-zero
6
+ # status after issuing an appropriate message if it wants to stop the
7
+ # commit. The hook is allowed to edit the commit message file.
8
+ #
9
+ # To enable this hook, rename this file to "commit-msg".
10
+
11
+ # Uncomment the below to add a Signed-off-by line to the message.
12
+ # Doing this in a hook is a bad idea in general, but the prepare-commit-msg
13
+ # hook is more suited to it.
14
+ #
15
+ # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
16
+ # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
17
+
18
+ # This example catches duplicate Signed-off-by lines.
19
+
20
+ test "" = "$(grep '^Signed-off-by: ' "$1" |
21
+ sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || {
22
+ echo >&2 Duplicate Signed-off-by lines.
23
+ exit 1
24
+ }