Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Update index file and gemspec. [admin]

  • Loading branch information...
commit b1eca889c0f220f05e4e11bf9d51ca7d8a65903d 1 parent 8072c2e
7rans authored January 21, 2013
326  .gemspec
... ...
@@ -1,187 +1,307 @@
1 1
 # encoding: utf-8
2 2
 
3 3
 require 'yaml'
  4
+require 'pathname'
4 5
 
5  
-module DotRuby
  6
+module Indexer
6 7
 
  8
+  # Convert index data into a gemspec.
7 9
   #
8  
-  class GemSpec
  10
+  # Notes:
  11
+  #   * Assumes all executables are in bin/.
  12
+  #   * Does not yet handle default_executable setting.
  13
+  #   * Does not yet handle platform setting.
  14
+  #   * Does not yet handle required_ruby_version.
  15
+  #   * Support for rdoc entries is weak.
  16
+  #
  17
+  class GemspecExporter
9 18
 
10  
-    # For which revision of .ruby is this gemspec intended?
11  
-    REVISION = 0 unless defined?(REVISION)
  19
+    # File globs to include in package --unless a manifest file exists.
  20
+    FILES = ".index .yardopts alt bin data demo ext features lib man spec test try* [A-Z]*.*" unless defined?(FILES)
12 21
 
13  
-    #
  22
+    # File globs to omit from FILES.
  23
+    OMIT = "Config.rb" unless defined?(OMIT)
  24
+
  25
+    # Standard file patterns.
14 26
     PATTERNS = {
15  
-      :bin_files  => 'bin/*',
16  
-      :lib_files  => 'lib/{**/}*.rb',
17  
-      :ext_files  => 'ext/{**/}extconf.rb',
18  
-      :doc_files  => '*.{txt,rdoc,md,markdown,tt,textile}',
19  
-      :test_files => '{test/{**/}*_test.rb,spec/{**/}*_spec.rb}'
  27
+      :root => '{.index,Gemfile}',
  28
+      :bin  => 'bin/*',
  29
+      :lib  => 'lib/{**/}*', #.rb',
  30
+      :ext  => 'ext/{**/}extconf.rb',
  31
+      :doc  => '*.{txt,rdoc,md,markdown,tt,textile}',
  32
+      :test => '{test,spec}/{**/}*.rb'
20 33
     } unless defined?(PATTERNS)
21 34
 
  35
+    # For which revision of indexer spec is this converter intended?
  36
+    REVISION = 2013 unless defined?(REVISION)
  37
+
22 38
     #
23  
-    def self.instance
  39
+    def self.gemspec
24 40
       new.to_gemspec
25 41
     end
26 42
 
  43
+    #
27 44
     attr :metadata
28 45
 
29  
-    attr :manifest
30  
-
31 46
     #
32  
-    def initialize
33  
-      @metadata = YAML.load_file('.ruby')
34  
-      @manifest = Dir.glob('manifest{,.txt}', File::FNM_CASEFOLD).first
  47
+    def initialize(metadata=nil)
  48
+      @root_check = false
  49
+
  50
+      if metadata
  51
+        root_dir = metadata.delete(:root)
  52
+        if root_dir
  53
+          @root = root_dir
  54
+          @root_check = true
  55
+        end
  56
+        metadata = nil if metadata.empty?
  57
+      end
  58
+
  59
+      @metadata = metadata || YAML.load_file(root + '.index')
35 60
 
36 61
       if @metadata['revision'].to_i != REVISION
37  
-        warn "You have the wrong revision. Trying anyway..."
  62
+        warn "This gemspec exporter was not designed for this revision of index metadata."
38 63
       end
39 64
     end
40 65
 
41 66
     #
  67
+    def has_root?
  68
+      root ? true : false
  69
+    end
  70
+
  71
+    #
  72
+    def root
  73
+      return @root if @root || @root_check
  74
+      @root_check = true
  75
+      @root = find_root
  76
+    end
  77
+
  78
+    #
  79
+    def manifest
  80
+      return nil unless root
  81
+      @manifest ||= Dir.glob(root + 'manifest{,.txt}', File::FNM_CASEFOLD).first
  82
+    end
  83
+
  84
+    #
42 85
     def scm
43  
-      @scm ||= \
44  
-        case
45  
-        when File.directory?('.git')
46  
-          :git
47  
-        end
  86
+      return nil unless root
  87
+      @scm ||= %w{git hg}.find{ |m| (root + ".#{m}").directory? }.to_sym
48 88
     end
49 89
 
50 90
     #
51 91
     def files
  92
+      return [] unless root
52 93
       @files ||= \
53  
-        #glob_files[patterns[:files]]
54  
-        case
55  
-        when manifest
  94
+        if manifest
56 95
           File.readlines(manifest).
57 96
             map{ |line| line.strip }.
58 97
             reject{ |line| line.empty? || line[0,1] == '#' }
59  
-        when scm == :git
60  
-         `git ls-files -z`.split("\0")
61 98
         else
62  
-          Dir.glob('{**/}{.*,*}')  # TODO: be more specific using standard locations ?
63  
-        end.select{ |path| File.file?(path) }
  99
+          list = []
  100
+          Dir.chdir(root) do
  101
+            FILES.split(/\s+/).each do |pattern|
  102
+              list.concat(glob(pattern))
  103
+            end
  104
+            OMIT.split(/\s+/).each do |pattern|
  105
+              list = list - glob(pattern)
  106
+            end
  107
+          end
  108
+          list
  109
+        end.select{ |path| File.file?(path) }.uniq
64 110
     end
65 111
 
66 112
     #
67 113
     def glob_files(pattern)
68  
-      Dir.glob(pattern).select { |path|
69  
-        File.file?(path) && files.include?(path)
70  
-      }
  114
+      return [] unless root
  115
+      Dir.chdir(root) do
  116
+        Dir.glob(pattern).select do |path|
  117
+          File.file?(path) && files.include?(path)
  118
+        end
  119
+      end
71 120
     end
72 121
 
73  
-    #
74 122
     def patterns
75 123
       PATTERNS
76 124
     end
77 125
 
78  
-    #
79 126
     def executables
80 127
       @executables ||= \
81  
-        glob_files(patterns[:bin_files]).map do |path|
  128
+        glob_files(patterns[:bin]).map do |path|
82 129
           File.basename(path)
83 130
         end
84 131
     end
85 132
 
86 133
     def extensions
87 134
       @extensions ||= \
88  
-        glob_files(patterns[:ext_files]).map do |path|
  135
+        glob_files(patterns[:ext]).map do |path|
89 136
           File.basename(path)
90 137
         end
91 138
     end
92 139
 
93  
-    #
94 140
     def name
95 141
       metadata['name'] || metadata['title'].downcase.gsub(/\W+/,'_')
96 142
     end
97 143
 
  144
+    def homepage
  145
+      page = (
  146
+        metadata['resources'].find{ |r| r['type'] =~ /^home/i } ||
  147
+        metadata['resources'].find{ |r| r['name'] =~ /^home/i } ||
  148
+        metadata['resources'].find{ |r| r['name'] =~ /^web/i }
  149
+      )
  150
+      page ? page['uri'] : false
  151
+    end
  152
+
  153
+    def licenses
  154
+      metadata['copyrights'].map{ |c| c['license'] }.compact
  155
+    end
  156
+
  157
+    def require_paths
  158
+      paths = metadata['paths'] || {}
  159
+      paths['load'] || ['lib']
  160
+    end
  161
+
  162
+    #
  163
+    # Convert to gemnspec.
98 164
     #
99 165
     def to_gemspec
100  
-      Gem::Specification.new do |gemspec|
101  
-        gemspec.name        = name
102  
-        gemspec.version     = metadata['version']
103  
-        gemspec.summary     = metadata['summary']
104  
-        gemspec.description = metadata['description']
105  
-
106  
-        metadata['authors'].each do |author|
107  
-          gemspec.authors << author['name']
108  
-
109  
-          if author.has_key?('email')
110  
-            if gemspec.email
111  
-              gemspec.email << author['email']
112  
-            else
113  
-              gemspec.email = [author['email']]
114  
-            end
  166
+      if has_root?
  167
+        Gem::Specification.new do |gemspec|
  168
+          to_gemspec_data(gemspec)
  169
+          to_gemspec_paths(gemspec)
  170
+        end
  171
+      else
  172
+        Gem::Specification.new do |gemspec|
  173
+          to_gemspec_data(gemspec)
  174
+          to_gemspec_paths(gemspec)
  175
+        end
  176
+      end
  177
+    end
  178
+
  179
+    #
  180
+    # Convert pure data settings.
  181
+    #
  182
+    def to_gemspec_data(gemspec)
  183
+      gemspec.name        = name
  184
+      gemspec.version     = metadata['version']
  185
+      gemspec.summary     = metadata['summary']
  186
+      gemspec.description = metadata['description']
  187
+
  188
+      metadata['authors'].each do |author|
  189
+        gemspec.authors << author['name']
  190
+
  191
+        if author.has_key?('email')
  192
+          if gemspec.email
  193
+            gemspec.email << author['email']
  194
+          else
  195
+            gemspec.email = [author['email']]
115 196
           end
116 197
         end
  198
+      end
117 199
 
118  
-        gemspec.licenses = metadata['copyrights'].map{ |c| c['license'] }.compact
  200
+      gemspec.licenses = licenses
119 201
 
120  
-        metadata['requirements'].each do |req|
121  
-          name    = req['name']
122  
-          version = req['version']
123  
-          groups  = req['groups'] || []
  202
+      requirements = metadata['requirements'] || []
  203
+      requirements.each do |req|
  204
+        next if req['optional']
  205
+        next if req['external']
124 206
 
125  
-          case version
126  
-          when /^(.*?)\+$/
127  
-            version = ">= #{$1}"
128  
-          when /^(.*?)\-$/
129  
-            version = "< #{$1}"
130  
-          when /^(.*?)\~$/
131  
-            version = "~> #{$1}"
132  
-          end
  207
+        name    = req['name']
  208
+        groups  = req['groups'] || []
133 209
 
134  
-          if groups.empty? or groups.include?('runtime')
135  
-            # populate runtime dependencies  
136  
-            if gemspec.respond_to?(:add_runtime_dependency)
137  
-              gemspec.add_runtime_dependency(name,*version)
138  
-            else
139  
-              gemspec.add_dependency(name,*version)
140  
-            end
  210
+        version = gemify_version(req['version'])
  211
+
  212
+        if groups.empty? or groups.include?('runtime')
  213
+          # populate runtime dependencies  
  214
+          if gemspec.respond_to?(:add_runtime_dependency)
  215
+            gemspec.add_runtime_dependency(name,*version)
141 216
           else
142  
-            # populate development dependencies
143  
-            if gemspec.respond_to?(:add_development_dependency)
144  
-              gemspec.add_development_dependency(name,*version)
145  
-            else
146  
-              gemspec.add_dependency(name,*version)
147  
-            end
  217
+            gemspec.add_dependency(name,*version)
148 218
           end
149  
-        end
150  
-
151  
-        # convert external dependencies into a requirements
152  
-        if metadata['external_dependencies']
153  
-          ##gemspec.requirements = [] unless metadata['external_dependencies'].empty?
154  
-          metadata['external_dependencies'].each do |req|
155  
-            gemspec.requirements << req.to_s
  219
+        else
  220
+          # populate development dependencies
  221
+          if gemspec.respond_to?(:add_development_dependency)
  222
+            gemspec.add_development_dependency(name,*version)
  223
+          else
  224
+            gemspec.add_dependency(name,*version)
156 225
           end
157 226
         end
  227
+      end
  228
+
  229
+      # convert external dependencies into gemspec requirements
  230
+      requirements.each do |req|
  231
+        next unless req['external']
  232
+        gemspec.requirements << ("%s-%s" % req.values_at('name', 'version'))
  233
+      end
158 234
 
159  
-        # determine homepage from resources
160  
-        homepage = metadata['resources'].find{ |r| r['type'] =~ /^home/ || r['name'] =~ /^(home|web)/ }
161  
-        gemspec.homepage = homepage['uri'] if homepage
  235
+      gemspec.homepage = homepage
  236
+      gemspec.require_paths = require_paths
  237
+      gemspec.post_install_message = metadata['install_message']
  238
+    end
162 239
 
163  
-        gemspec.require_paths        = metadata['load_path'] || ['lib']
164  
-        gemspec.post_install_message = metadata['install_message']
  240
+    #
  241
+    # Set gemspec settings that require a root directory path.
  242
+    #
  243
+    def to_gemspec_paths(gemspec)
  244
+      gemspec.files       = files
  245
+      gemspec.extensions  = extensions
  246
+      gemspec.executables = executables
165 247
 
166  
-        # RubyGems specific metadata
167  
-        gemspec.files       = files
168  
-        gemspec.extensions  = extensions
169  
-        gemspec.executables = executables
  248
+      if Gem::VERSION < '1.7.'
  249
+        gemspec.default_executable = gemspec.executables.first
  250
+      end
170 251
 
171  
-        if Gem::VERSION < '1.7.'
172  
-          gemspec.default_executable = gemspec.executables.first
173  
-        end
  252
+      gemspec.test_files = glob_files(patterns[:test])
174 253
 
175  
-        gemspec.test_files = glob_files(patterns[:test_files])
  254
+      unless gemspec.files.include?('.document')
  255
+        gemspec.extra_rdoc_files = glob_files(patterns[:doc])
  256
+      end
  257
+    end
176 258
 
177  
-        unless gemspec.files.include?('.document')
178  
-          gemspec.extra_rdoc_files = glob_files(patterns[:doc_files])
179  
-        end
  259
+    #
  260
+    # Return a copy of this file. This is used to generate a local
  261
+    # .gemspec file that can automatically read the index file.
  262
+    #
  263
+    def self.source_code
  264
+      File.read(__FILE__)
  265
+    end
  266
+
  267
+  private
  268
+
  269
+    def find_root
  270
+      root_files = patterns[:root]
  271
+      if Dir.glob(root_files).first
  272
+        Pathname.new(Dir.pwd)
  273
+      elsif Dir.glob("../#{root_files}").first
  274
+        Pathname.new(Dir.pwd).parent
  275
+      else
  276
+        #raise "Can't find root of project containing `#{root_files}'."
  277
+        warn "Can't find root of project containing `#{root_files}'."
  278
+        nil
  279
+      end
  280
+    end
  281
+
  282
+    def glob(pattern)
  283
+      if File.directory?(pattern)
  284
+        Dir.glob(File.join(pattern, '**', '*'))
  285
+      else
  286
+        Dir.glob(pattern)
  287
+      end
  288
+    end
  289
+
  290
+    def gemify_version(version)
  291
+      case version
  292
+      when /^(.*?)\+$/
  293
+        ">= #{$1}"
  294
+      when /^(.*?)\-$/
  295
+        "< #{$1}"
  296
+      when /^(.*?)\~$/
  297
+        "~> #{$1}"
  298
+      else
  299
+        version
180 300
       end
181 301
     end
182 302
 
183  
-  end #class GemSpec
  303
+  end
184 304
 
185 305
 end
186 306
 
187  
-DotRuby::GemSpec.instance
  307
+Indexer::GemspecExporter.gemspec
1  .gitignore
@@ -5,3 +5,4 @@ log
5 5
 tmp
6 6
 web
7 7
 work/sandbox
  8
+*.lock
10  .index
... ...
@@ -1,6 +1,6 @@
1 1
 ---
2  
-type: ruby
3 2
 revision: 2013
  3
+type: ruby
4 4
 sources:
5 5
 - Index.yml
6 6
 authors:
@@ -41,8 +41,6 @@ resources:
41 41
   label: Documentation
42 42
 repositories: []
43 43
 categories: []
44  
-load_path:
45  
-- lib
46 44
 copyrights:
47 45
 - holder: Rubyworks
48 46
   year: '2012'
@@ -50,10 +48,14 @@ copyrights:
50 48
 - holder: Loren Segal
51 49
   year: '2010'
52 50
   license: MIT
  51
+customs: []
  52
+paths:
  53
+  lib:
  54
+  - lib
53 55
 version: 0.5.0
54 56
 name: yard-tomdoc
55 57
 title: YARD TomDoc
56 58
 summary: TomDoc for YARD
57 59
 description: Use TomDoc documentation format with YARD.
58 60
 webcvs: https://github.com/rubyworks/yard-tomdoc/tree/master
59  
-date: '2012-12-09'
  61
+date: '2013-01-21'

0 notes on commit b1eca88

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