Skip to content
This repository
Browse code

Add more stuff for git

  • Loading branch information...
commit 0d2492d6832ca881487e4dac5f339104c508506e 1 parent 6a31eba
authored January 13, 2010
6  lib/bubble.rb
@@ -35,9 +35,11 @@ def self.home
35 35
     Pathname.new(Gem.user_home).join(".bbl")
36 36
   end
37 37
 
  38
+  def self.install_path
  39
+    home.join("gems")
  40
+  end
  41
+
38 42
   def self.cache
39 43
     home.join("cache")
40 44
   end
41  
-
42  
-
43 45
 end
86  lib/bubble/source.rb
@@ -83,17 +83,89 @@ def install(spec)
83 83
     end
84 84
 
85 85
     class Git < Path
  86
+      attr_reader :uri, :ref
  87
+
86 88
       def initialize(options)
87  
-        @uri = options[:uri]
88  
-        sha = Digest::SHA1.hexdigest(URI.parse(@uri).normalize.to_s.sub(%r{/$}, ''))
89  
-        @location = Bubble.cache.join("git", "#{File.basename(@uri, ".git")}-#{sha}")
90  
-        @branch   = options[:branch] || 'master'
91  
-        @ref      = options[:ref] || "origin/#{@branch}"
  89
+        @glob = options[:glob] || "{,*/}*.gemspec"
  90
+        @uri  = options[:uri]
  91
+        @ref  = options[:ref] || options[:branch] || 'master'
  92
+      end
  93
+
  94
+      def path
  95
+        Bubble.install_path.join("#{base_name}-#{uri_hash}-#{ref}")
92 96
       end
93 97
 
94 98
       def specs
95  
-        FileUtils.mkdir_p(@location.dirname)
96  
-        `git clone #{@uri} #{@location} --bare --no-hardlinks`
  99
+        @specs ||= begin
  100
+          index = Index.new
  101
+          # Start by making sure the git cache is up to date
  102
+          cache
  103
+          # Find all gemspecs in the repo
  104
+          in_cache do
  105
+            out   = %x(git ls-tree -r #{revision}).strip
  106
+            lines = out.split("\n").select { |l| l =~ /\.gemspec$/ }
  107
+            # Loop over the lines and extract the relative path and the
  108
+            # git hash
  109
+            lines.each do |line|
  110
+              next unless line =~ %r{^(\d+) (blob|tree) ([a-zf0-9]+)\t(.*)$}
  111
+              hash, file = $3, $4
  112
+              # Read the gemspec
  113
+              if spec = eval(%x(git cat-file blob #{$3}))
  114
+                spec = Specification.from_gemspec(spec)
  115
+                spec.relative_loaded_from = file
  116
+                spec.source = self
  117
+                index << spec
  118
+              end
  119
+            end
  120
+          end
  121
+          index
  122
+        end
  123
+      end
  124
+
  125
+      def install(spec)
  126
+        @installed ||= begin
  127
+          FileUtils.mkdir_p(path)
  128
+          Dir.chdir(path) do
  129
+            unless File.exist?(".git")
  130
+              %x(git clone --recursive --no-checkout #{cache_path} #{path})
  131
+            end
  132
+            %x(git reset --hard #{revision})
  133
+            %x(git submodule init)
  134
+            %x(git submodule update)
  135
+          end
  136
+          true
  137
+        end
  138
+      end
  139
+
  140
+    private
  141
+
  142
+      def base_name
  143
+        File.basename(uri, ".git")
  144
+      end
  145
+
  146
+      def uri_hash
  147
+        Digest::SHA1.hexdigest(URI.parse(uri).normalize.to_s.sub(%r{/$}, ''))
  148
+      end
  149
+
  150
+      def cache_path
  151
+        @cache_path ||= Bubble.cache.join("git", "#{base_name}-#{uri_hash}")
  152
+      end
  153
+
  154
+      def cache
  155
+        if cache_path.exist?
  156
+          in_cache { `git fetch --quiet #{uri}` }
  157
+        else
  158
+          FileUtils.mkdir_p(cache_path.dirname)
  159
+          `git clone #{uri} #{cache_path} --bare --no-hardlinks`
  160
+        end
  161
+      end
  162
+
  163
+      def revision
  164
+        @revision ||= in_cache { `git rev-parse #{ref}`.strip }
  165
+      end
  166
+
  167
+      def in_cache(&blk)
  168
+        Dir.chdir(cache_path, &blk)
97 169
       end
98 170
     end
99 171
   end
9  lib/bubble/specification.rb
... ...
@@ -1,5 +1,7 @@
1 1
 module Bubble
2 2
   class Specification < Gem::Specification
  3
+    attr_accessor :relative_loaded_from
  4
+
3 5
     def self.from_gemspec(gemspec)
4 6
       spec = allocate
5 7
       gemspec.instance_variables.each do |ivar|
@@ -8,8 +10,13 @@ def self.from_gemspec(gemspec)
8 10
       spec
9 11
     end
10 12
 
  13
+    def loaded_from
  14
+      return super unless relative_loaded_from
  15
+      source.path.join(relative_loaded_from)
  16
+    end
  17
+
11 18
     def full_gem_path
12  
-      @loaded_from.dirname.expand_path
  19
+      loaded_from.dirname.expand_path
13 20
     end
14 21
   end
15 22
 end
1  spec/install/git_spec.rb
@@ -2,7 +2,6 @@
2 2
 
3 3
 describe "bbl install with git sources" do
4 4
   before :each do
5  
-    pending
6 5
     in_app_root
7 6
   end
8 7
 

0 notes on commit 0d2492d

Please sign in to comment.
Something went wrong with that request. Please try again.