Class: Indexer::GemspecExporter

Inherits:
Object
  • Object
show all
Defined in:
lib/indexer/conversion/gemspec_exporter.rb

Overview

Convert index data into a gemspec.

Notes:

  • Assumes all executables are in bin/.
  • Does not yet handle default_executable setting.
  • Does not yet handle platform setting.
  • Does not yet handle required_ruby_version.
  • Support for rdoc entries is weak.

Constant Summary collapse

FILES =

File globs to include in package --unless a manifest file exists.

".index .yardopts alt bin data demo ext features lib man spec test try* [A-Z]*.*"
OMIT =

File globs to omit from FILES.

"Config.rb"
PATTERNS =

Standard file patterns.

{
  :root => '{.index,Gemfile}',
  :bin  => 'bin/*',
  :lib  => 'lib/{**/}*', #.rb',
  :ext  => 'ext/{**/}extconf.rb',
  :doc  => '*.{txt,rdoc,md,markdown,tt,textile}',
  :test => '{test,spec}/{**/}*.rb'
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(metadata = nil) ⇒ GemspecExporter

Returns a new instance of GemspecExporter.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/indexer/conversion/gemspec_exporter.rb', line 47

def initialize(=nil)
  @root_check = false

  if 
    root_dir = .delete(:root)
    if root_dir
      @root = root_dir
      @root_check = true
    end
     = nil if .empty?
  end

  @metadata =  || YAML.load_file(root + '.index')

  if @metadata['revision'].to_i != REVISION
    warn "This gemspec exporter was not designed for this revision of index metadata."
  end
end

Instance Attribute Details

#metadataObject (readonly)

Returns the value of attribute metadata.



44
45
46
# File 'lib/indexer/conversion/gemspec_exporter.rb', line 44

def 
  @metadata
end

Class Method Details

.gemspecObject



39
40
41
# File 'lib/indexer/conversion/gemspec_exporter.rb', line 39

def self.gemspec
  new.to_gemspec
end

.source_codeObject

Return a copy of this file. This is used to generate a local .gemspec file that can automatically read the index file.



263
264
265
# File 'lib/indexer/conversion/gemspec_exporter.rb', line 263

def self.source_code
  File.read(__FILE__)
end

Instance Method Details

#executablesObject



126
127
128
129
130
131
# File 'lib/indexer/conversion/gemspec_exporter.rb', line 126

def executables
  @executables ||= \
    glob_files(patterns[:bin]).map do |path|
      File.basename(path)
    end
end

#extensionsObject



133
134
135
136
137
138
# File 'lib/indexer/conversion/gemspec_exporter.rb', line 133

def extensions
  @extensions ||= \
    glob_files(patterns[:ext]).map do |path|
      File.basename(path)
    end
end

#filesObject



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/indexer/conversion/gemspec_exporter.rb', line 91

def files
  return [] unless root
  @files ||= \
    if manifest
      File.readlines(manifest).
        map{ |line| line.strip }.
        reject{ |line| line.empty? || line[0,1] == '#' }
    else
      list = []
      Dir.chdir(root) do
        FILES.split(/\s+/).each do |pattern|
          list.concat(glob(pattern))
        end
        OMIT.split(/\s+/).each do |pattern|
          list = list - glob(pattern)
        end
      end
      list
    end.select{ |path| File.file?(path) }.uniq
end

#find_rootObject (private)



269
270
271
272
273
274
275
276
277
278
279
280
# File 'lib/indexer/conversion/gemspec_exporter.rb', line 269

def find_root
  root_files = patterns[:root]
  if Dir.glob(root_files).first
    Pathname.new(Dir.pwd)
  elsif Dir.glob("../#{root_files}").first
    Pathname.new(Dir.pwd).parent
  else
    #raise "Can't find root of project containing `#{root_files}'."
    warn "Can't find root of project containing `#{root_files}'."
    nil
  end
end

#gemify_version(version) ⇒ Object (private)



290
291
292
293
294
295
296
297
298
299
300
301
# File 'lib/indexer/conversion/gemspec_exporter.rb', line 290

def gemify_version(version)
  case version
  when /^(.*?)\+$/
    ">= #{$1}"
  when /^(.*?)\-$/
    "< #{$1}"
  when /^(.*?)\~$/
    "~> #{$1}"
  else
    version
  end
end

#glob(pattern) ⇒ Object (private)



282
283
284
285
286
287
288
# File 'lib/indexer/conversion/gemspec_exporter.rb', line 282

def glob(pattern)
  if File.directory?(pattern)
    Dir.glob(File.join(pattern, '**', '*'))
  else
    Dir.glob(pattern)
  end
end

#glob_files(pattern) ⇒ Object



113
114
115
116
117
118
119
120
# File 'lib/indexer/conversion/gemspec_exporter.rb', line 113

def glob_files(pattern)
  return [] unless root
  Dir.chdir(root) do
    Dir.glob(pattern).select do |path|
      File.file?(path) && files.include?(path)
    end
  end
end

#has_root?Boolean

Returns:

  • (Boolean)


67
68
69
# File 'lib/indexer/conversion/gemspec_exporter.rb', line 67

def has_root?
  root ? true : false
end

#homepageObject



144
145
146
147
148
149
150
151
# File 'lib/indexer/conversion/gemspec_exporter.rb', line 144

def homepage
  page = (
    ['resources'].find{ |r| r['type'] =~ /^home/i } ||
    ['resources'].find{ |r| r['name'] =~ /^home/i } ||
    ['resources'].find{ |r| r['name'] =~ /^web/i }
  )
  page ? page['uri'] : false
end

#licensesObject



153
154
155
# File 'lib/indexer/conversion/gemspec_exporter.rb', line 153

def licenses
  ['copyrights'].map{ |c| c['license'] }.compact
end

#manifestObject



79
80
81
82
# File 'lib/indexer/conversion/gemspec_exporter.rb', line 79

def manifest
  return nil unless root
  @manifest ||= Dir.glob(root + 'manifest{,.txt}', File::FNM_CASEFOLD).first
end

#nameObject



140
141
142
# File 'lib/indexer/conversion/gemspec_exporter.rb', line 140

def name
  ['name'] || ['title'].downcase.gsub(/\W+/,'_')
end

#patternsObject



122
123
124
# File 'lib/indexer/conversion/gemspec_exporter.rb', line 122

def patterns
  PATTERNS
end

#require_pathsObject



157
158
159
160
# File 'lib/indexer/conversion/gemspec_exporter.rb', line 157

def require_paths
  paths = ['paths'] || {}
  paths['load'] || ['lib']
end

#rootObject



72
73
74
75
76
# File 'lib/indexer/conversion/gemspec_exporter.rb', line 72

def root
  return @root if @root || @root_check
  @root_check = true
  @root = find_root
end

#scmObject



85
86
87
88
# File 'lib/indexer/conversion/gemspec_exporter.rb', line 85

def scm
  return nil unless root
  @scm ||= %w{git hg}.find{ |m| (root + ".#{m}").directory? }.to_sym
end

#to_gemspecObject

Convert to gemnspec.



165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/indexer/conversion/gemspec_exporter.rb', line 165

def to_gemspec
  if has_root?
    Gem::Specification.new do |gemspec|
      to_gemspec_data(gemspec)
      to_gemspec_paths(gemspec)
    end
  else
    Gem::Specification.new do |gemspec|
      to_gemspec_data(gemspec)
      to_gemspec_paths(gemspec)
    end
  end
end

#to_gemspec_data(gemspec) ⇒ Object

Convert pure data settings.



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/indexer/conversion/gemspec_exporter.rb', line 182

def to_gemspec_data(gemspec)
  gemspec.name        = name
  gemspec.version     = ['version']
  gemspec.summary     = ['summary']
  gemspec.description = ['description']

  ['authors'].each do |author|
    gemspec.authors << author['name']

    if author.has_key?('email')
      if gemspec.email
        gemspec.email << author['email']
      else
        gemspec.email = [author['email']]
      end
    end
  end

  gemspec.licenses = licenses

  requirements = ['requirements'] || []
  requirements.each do |req|
    next if req['optional']
    next if req['external']

    name    = req['name']
    groups  = req['groups'] || []

    version = gemify_version(req['version'])

    if groups.empty? or groups.include?('runtime')
      # populate runtime dependencies  
      if gemspec.respond_to?(:add_runtime_dependency)
        gemspec.add_runtime_dependency(name,*version)
      else
        gemspec.add_dependency(name,*version)
      end
    else
      # populate development dependencies
      if gemspec.respond_to?(:add_development_dependency)
        gemspec.add_development_dependency(name,*version)
      else
        gemspec.add_dependency(name,*version)
      end
    end
  end

  # convert external dependencies into gemspec requirements
  requirements.each do |req|
    next unless req['external']
    gemspec.requirements << ("%s-%s" % req.values_at('name', 'version'))
  end

  gemspec.homepage = homepage
  gemspec.require_paths = require_paths
  gemspec.post_install_message = ['install_message']
end

#to_gemspec_paths(gemspec) ⇒ Object

Set gemspec settings that require a root directory path.



243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/indexer/conversion/gemspec_exporter.rb', line 243

def to_gemspec_paths(gemspec)
  gemspec.files       = files
  gemspec.extensions  = extensions
  gemspec.executables = executables

  if Gem::VERSION < '1.7.'
    gemspec.default_executable = gemspec.executables.first
  end

  gemspec.test_files = glob_files(patterns[:test])

  unless gemspec.files.include?('.document')
    gemspec.extra_rdoc_files = glob_files(patterns[:doc])
  end
end