indexer 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.index +54 -0
- data/HISTORY.md +9 -0
- data/README.md +145 -0
- data/bin/index +7 -0
- data/data/indexer/r2013/index.kwalify +175 -0
- data/data/indexer/r2013/index.yes +172 -0
- data/data/indexer/r2013/index.yesi +67 -0
- data/data/indexer/r2013/ruby.txt +35 -0
- data/data/indexer/r2013/yaml.txt +30 -0
- data/lib/indexer.rb +65 -0
- data/lib/indexer/attributes.rb +171 -0
- data/lib/indexer/command.rb +260 -0
- data/lib/indexer/components.rb +8 -0
- data/lib/indexer/components/author.rb +140 -0
- data/lib/indexer/components/conflict.rb +78 -0
- data/lib/indexer/components/copyright.rb +95 -0
- data/lib/indexer/components/dependency.rb +18 -0
- data/lib/indexer/components/organization.rb +133 -0
- data/lib/indexer/components/repository.rb +140 -0
- data/lib/indexer/components/requirement.rb +360 -0
- data/lib/indexer/components/resource.rb +209 -0
- data/lib/indexer/conversion.rb +14 -0
- data/lib/indexer/conversion/gemfile.rb +44 -0
- data/lib/indexer/conversion/gemspec.rb +114 -0
- data/lib/indexer/conversion/gemspec_exporter.rb +304 -0
- data/lib/indexer/core_ext.rb +4 -0
- data/lib/indexer/error.rb +23 -0
- data/lib/indexer/gemfile.rb +75 -0
- data/lib/indexer/importer.rb +144 -0
- data/lib/indexer/importer/file.rb +94 -0
- data/lib/indexer/importer/gemfile.rb +27 -0
- data/lib/indexer/importer/gemspec.rb +43 -0
- data/lib/indexer/importer/html.rb +289 -0
- data/lib/indexer/importer/markdown.rb +45 -0
- data/lib/indexer/importer/ruby.rb +47 -0
- data/lib/indexer/importer/version.rb +38 -0
- data/lib/indexer/importer/yaml.rb +46 -0
- data/lib/indexer/loadable.rb +159 -0
- data/lib/indexer/metadata.rb +879 -0
- data/lib/indexer/model.rb +237 -0
- data/lib/indexer/revision.rb +43 -0
- data/lib/indexer/valid.rb +287 -0
- data/lib/indexer/validator.rb +313 -0
- data/lib/indexer/version/constraint.rb +124 -0
- data/lib/indexer/version/exceptions.rb +11 -0
- data/lib/indexer/version/number.rb +497 -0
- metadata +141 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
---
|
2
|
+
HEADER-DIVISION:
|
3
|
+
apply-tag: "!http://rubyworks.github.org/dotruby"
|
4
|
+
description:
|
5
|
+
Specification for canonical .ruby files.
|
6
|
+
author: trans <transfire@gmail.com>
|
7
|
+
|
8
|
+
TEMPLATE-DIVISION:
|
9
|
+
revision : PIC ZZ9; TAG !!int; REQ true
|
10
|
+
name : PIC AW[29]; REQ true
|
11
|
+
version : PIC ZZ9{.ZZ9}[5]; REX semver
|
12
|
+
codename : PIC X[30]
|
13
|
+
title : PIC X[30]
|
14
|
+
date : PIC 9999-99-99{_99:99:99}[0,1]
|
15
|
+
created : PIC 9999-99-99{_99:99:99}[0,1]
|
16
|
+
summary : PIC X[79]
|
17
|
+
description: PIC X[1000]
|
18
|
+
authors:
|
19
|
+
- name : PIC X[30]
|
20
|
+
email : REX email
|
21
|
+
url : REX url
|
22
|
+
roles :
|
23
|
+
- PIC X[30]
|
24
|
+
suite: PIC X[30]
|
25
|
+
organization: PIC X[30]
|
26
|
+
copyrights:
|
27
|
+
- holder : PIC X[30]
|
28
|
+
year : PIC 9999{-9999}[0,1]
|
29
|
+
license : PIC W[30]
|
30
|
+
requirements: &r
|
31
|
+
- name: PIC W[30]
|
32
|
+
version: REX //
|
33
|
+
groups:
|
34
|
+
- PIC W[30]
|
35
|
+
development: TAG !!bool
|
36
|
+
optional: TAG !!bool
|
37
|
+
engine:
|
38
|
+
- name: PIC W[30]
|
39
|
+
version: PIC W[30]
|
40
|
+
platform:
|
41
|
+
- PIC W[30]
|
42
|
+
repository:
|
43
|
+
name: PIC W[30]
|
44
|
+
uri: REX uri
|
45
|
+
scm: PIC W[15]
|
46
|
+
dependencies: *r
|
47
|
+
conflicts:
|
48
|
+
- name: PIC W[30]
|
49
|
+
version: PIC X[30]
|
50
|
+
substitues:
|
51
|
+
- PIC W[30]
|
52
|
+
replaces:
|
53
|
+
- PIC W[30]
|
54
|
+
resources:
|
55
|
+
- name: PIC X[30]
|
56
|
+
uri: REX uri
|
57
|
+
repositories:
|
58
|
+
- name: PIC X[30]
|
59
|
+
uri: REX uri
|
60
|
+
scm: PIC W[30]
|
61
|
+
load_path:
|
62
|
+
- REX file; DEF 'lib'
|
63
|
+
install_message: PIC X[1000]
|
64
|
+
extra: {}
|
65
|
+
|
66
|
+
CONSTRAINTS-DIVISION: {}
|
67
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
name <%= name.inspect %>
|
4
|
+
version <%= version.inspect %>
|
5
|
+
title <%= title.inspect %>
|
6
|
+
summary <%= summary.inspect %>
|
7
|
+
|
8
|
+
description \
|
9
|
+
<% description.inspect %>
|
10
|
+
|
11
|
+
authors [
|
12
|
+
'you <you@foomail.com>'
|
13
|
+
]
|
14
|
+
|
15
|
+
requirements [
|
16
|
+
'foo 1.0~',
|
17
|
+
'rake (build)',
|
18
|
+
'test (test)'
|
19
|
+
]
|
20
|
+
|
21
|
+
repositories {
|
22
|
+
'upstream' => 'http://github.com/organization/app_name/<%= name %>.git'
|
23
|
+
}
|
24
|
+
|
25
|
+
resources {
|
26
|
+
'home' => 'http://organization.github.org/<%= name %>',
|
27
|
+
'code' => 'http://github.com/organization/<%= name %>'
|
28
|
+
}
|
29
|
+
|
30
|
+
categories ['foo']
|
31
|
+
|
32
|
+
copyrights: [
|
33
|
+
'2012 Your Name (MIT)'
|
34
|
+
]
|
35
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
---
|
2
|
+
name: <%= name %>
|
3
|
+
version: <%= version %>
|
4
|
+
title: <%= title %>
|
5
|
+
summary: <%= summary %>
|
6
|
+
|
7
|
+
description:
|
8
|
+
<%= description %>
|
9
|
+
|
10
|
+
authors:
|
11
|
+
- you <you@foomail.com>
|
12
|
+
|
13
|
+
requirements:
|
14
|
+
- dependency 1.0~
|
15
|
+
- rake (build)
|
16
|
+
- test (test)
|
17
|
+
|
18
|
+
repositories:
|
19
|
+
upstream: http://github.com/organization/app_name/app_name.git
|
20
|
+
|
21
|
+
resources:
|
22
|
+
home: http://organization.github.org/app_name
|
23
|
+
code: http://github.com/organization/app_name
|
24
|
+
|
25
|
+
categories:
|
26
|
+
- foo
|
27
|
+
|
28
|
+
copyrights:
|
29
|
+
- 2012 Your Name (MIT)
|
30
|
+
|
data/lib/indexer.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
module Indexer
|
2
|
+
# Name of this program.
|
3
|
+
NAME = 'indexer'
|
4
|
+
|
5
|
+
# Current stable revision of the specification (by year).
|
6
|
+
REVISION = 2013
|
7
|
+
|
8
|
+
# File name of locked metadata file.
|
9
|
+
LOCK_FILE = '.index'
|
10
|
+
|
11
|
+
# Default metadata file name for use by end-developer.
|
12
|
+
USER_FILES = '{Indexfile,Indexfile.rb,Metadata,Metadata.yml,Metadata.yaml}'
|
13
|
+
|
14
|
+
# Indexer library directory.
|
15
|
+
LIBDIR = File.dirname(__FILE__) + '/indexer'
|
16
|
+
|
17
|
+
# Indexer library directory.
|
18
|
+
DATADIR = File.dirname(__FILE__) + '/../data/indexer'
|
19
|
+
|
20
|
+
# Metadata from the project's `indexer.yml` index file.
|
21
|
+
# This is used as a fallback for #const_missing.
|
22
|
+
#
|
23
|
+
# Returns [Hash] of metadata.
|
24
|
+
def self.index
|
25
|
+
@index ||= (
|
26
|
+
require 'yaml'
|
27
|
+
dir = File.dirname(__FILE__)
|
28
|
+
file = Dir[File.join(dir, "{#{NAME}.yml,../.index}")].first
|
29
|
+
file ? YAML.load_file(file) : {}
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Project metadata via RubyGems, fallback to index file.
|
34
|
+
#
|
35
|
+
# TODO: The #to_s on the gemspec return value is a bit too simplistic. But how to fix?
|
36
|
+
# The goal is reduce the value to a basic type (String, Hash, Array, Numeric).
|
37
|
+
#
|
38
|
+
def self.const_missing(const_name)
|
39
|
+
name = const_name.to_s.downcase
|
40
|
+
begin
|
41
|
+
Gem.loaded_specs[NAME].send(name).to_s
|
42
|
+
rescue StandardError
|
43
|
+
index[name] || super(const_name)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
require 'yaml'
|
49
|
+
require 'time'
|
50
|
+
|
51
|
+
require 'indexer/version/exceptions'
|
52
|
+
require 'indexer/version/number'
|
53
|
+
require 'indexer/version/constraint'
|
54
|
+
|
55
|
+
require 'indexer/core_ext'
|
56
|
+
require 'indexer/command'
|
57
|
+
require 'indexer/error'
|
58
|
+
require 'indexer/valid'
|
59
|
+
require 'indexer/revision'
|
60
|
+
|
61
|
+
require 'indexer/model'
|
62
|
+
require 'indexer/components'
|
63
|
+
require 'indexer/metadata'
|
64
|
+
require 'indexer/importer'
|
65
|
+
|
@@ -0,0 +1,171 @@
|
|
1
|
+
module Indexer
|
2
|
+
|
3
|
+
# Tracks supported attributes.
|
4
|
+
def self.attributes
|
5
|
+
@attributes ||= []
|
6
|
+
end
|
7
|
+
|
8
|
+
# The Attributes module defines all of the accepted metadata fields.
|
9
|
+
module Attributes
|
10
|
+
|
11
|
+
# Define attribute, plus track it.
|
12
|
+
def self.attr_accessor(name)
|
13
|
+
Indexer.attributes << name.to_sym
|
14
|
+
|
15
|
+
class_eval %{
|
16
|
+
def #{name}
|
17
|
+
@data[:#{name}]
|
18
|
+
end
|
19
|
+
def #{name}=(val)
|
20
|
+
@data[:#{name}] = val
|
21
|
+
end
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
def attributes
|
27
|
+
Indexer.attributes
|
28
|
+
end
|
29
|
+
|
30
|
+
# The revision of ruby meta specification.
|
31
|
+
attr_accessor :revision
|
32
|
+
|
33
|
+
#def revision
|
34
|
+
# REVISION
|
35
|
+
#end
|
36
|
+
|
37
|
+
# The type of ruby meta specification.
|
38
|
+
attr_accessor :type
|
39
|
+
|
40
|
+
# Files from which to import metadata.
|
41
|
+
attr_accessor :sources
|
42
|
+
|
43
|
+
# The name of the project
|
44
|
+
attr_accessor :name
|
45
|
+
|
46
|
+
# The version of the project
|
47
|
+
attr_accessor :version
|
48
|
+
|
49
|
+
# The nick name for the particular version, e.g. "Lucid Lynx".
|
50
|
+
attr_accessor :codename
|
51
|
+
|
52
|
+
# The date of this version.
|
53
|
+
attr_accessor :date
|
54
|
+
|
55
|
+
# The project title
|
56
|
+
attr_accessor :title
|
57
|
+
|
58
|
+
# The project summary
|
59
|
+
attr_accessor :summary
|
60
|
+
|
61
|
+
# The project description
|
62
|
+
attr_accessor :description
|
63
|
+
|
64
|
+
# The suite to which the project belongs.
|
65
|
+
attr_accessor :suite
|
66
|
+
|
67
|
+
# The copyrights and licenses of the project.
|
68
|
+
attr_accessor :copyrights
|
69
|
+
|
70
|
+
# The authors of the project
|
71
|
+
# The first author should be the primary contact.
|
72
|
+
attr_accessor :authors
|
73
|
+
|
74
|
+
# The organizations involved with the project.
|
75
|
+
attr_accessor :organizations
|
76
|
+
|
77
|
+
# The resource locators for the project.
|
78
|
+
attr_accessor :resources
|
79
|
+
|
80
|
+
# The repository URLs for the project.
|
81
|
+
attr_accessor :repositories
|
82
|
+
|
83
|
+
# TODO: Might webcvs simply be taken from the first repository instead?
|
84
|
+
|
85
|
+
# URI for linking to source code.
|
86
|
+
attr_accessor :webcvs
|
87
|
+
|
88
|
+
# The directories to search within the project when requiring files
|
89
|
+
attr_accessor :load_path # :loadpath or :require_paths ?
|
90
|
+
|
91
|
+
# List of language engine/version family supported.
|
92
|
+
attr_accessor :engines
|
93
|
+
|
94
|
+
# List of platforms supported.
|
95
|
+
attr_accessor :platforms
|
96
|
+
|
97
|
+
# The names of the executable scripts
|
98
|
+
# NOTE: Do not need, executable should alwasy by in bin/, right?
|
99
|
+
#attr_accessor :executables
|
100
|
+
|
101
|
+
# The packages this package requires to function.
|
102
|
+
attr_accessor :requirements #:dependencies
|
103
|
+
|
104
|
+
# A list of packages that provide more or less the same functionality.
|
105
|
+
# A good example is for a markdown library.
|
106
|
+
#
|
107
|
+
# alternatives:
|
108
|
+
# - rdiscount
|
109
|
+
# - redcarpet
|
110
|
+
# - BlueCloth
|
111
|
+
#
|
112
|
+
attr_accessor :alternatives
|
113
|
+
|
114
|
+
# The packages with which this project cannot function.
|
115
|
+
attr_accessor :conflicts
|
116
|
+
|
117
|
+
#
|
118
|
+
# NOTE: This is a Debian concept. Is it useful?
|
119
|
+
#attr_accessor :provides
|
120
|
+
|
121
|
+
# Categories can be used to help clarify the purpose of
|
122
|
+
# a project, e.g. `testing` or `rest`. There are no standard
|
123
|
+
# categories, just use common sense. Categories must be single-line
|
124
|
+
# strings. When comparisons are made they will be downcased.
|
125
|
+
attr_accessor :categories
|
126
|
+
|
127
|
+
# The version of Ruby required by the project
|
128
|
+
# NOTE: is it possible to to makes this a part of ordinary requirements?
|
129
|
+
#attr_accessor :required_ruby_version
|
130
|
+
|
131
|
+
# The post-installation message.
|
132
|
+
attr_accessor :install_message
|
133
|
+
|
134
|
+
# The date the project was started.
|
135
|
+
attr_accessor :created
|
136
|
+
|
137
|
+
# The toplevel namespace of API, e.g. `module Foo` or `class Bar`.
|
138
|
+
# NOTE: how to best handle this?
|
139
|
+
attr_accessor :namespace
|
140
|
+
|
141
|
+
# Any user-defined extraneous metadata.
|
142
|
+
#attr_accessor :extra
|
143
|
+
|
144
|
+
protected
|
145
|
+
|
146
|
+
#
|
147
|
+
# Initializes the {Metadata} attributes.
|
148
|
+
#
|
149
|
+
# @todo Is it okay to default type to `ruby`?
|
150
|
+
#
|
151
|
+
def initialize_attributes
|
152
|
+
@data = {
|
153
|
+
:revision => REVISION,
|
154
|
+
:type => 'ruby',
|
155
|
+
:sources => [],
|
156
|
+
:authors => [],
|
157
|
+
:organizations => [],
|
158
|
+
:copyrights => [],
|
159
|
+
:alternatives => [],
|
160
|
+
:requirements => [],
|
161
|
+
:conflicts => [],
|
162
|
+
:repositories => [],
|
163
|
+
:resources => [],
|
164
|
+
:categories => [],
|
165
|
+
:load_path => ['lib']
|
166
|
+
}
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
@@ -0,0 +1,260 @@
|
|
1
|
+
module Indexer
|
2
|
+
|
3
|
+
# Command line interface.
|
4
|
+
#
|
5
|
+
class Command
|
6
|
+
|
7
|
+
#
|
8
|
+
# Shortcut to `new.run(argv)`.
|
9
|
+
#
|
10
|
+
def self.run(argv=ARGV)
|
11
|
+
new.run(argv)
|
12
|
+
end
|
13
|
+
|
14
|
+
#
|
15
|
+
#
|
16
|
+
#
|
17
|
+
def initialize
|
18
|
+
@force = false
|
19
|
+
@stdout = false
|
20
|
+
@static = false
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
#
|
25
|
+
#
|
26
|
+
def run(argv=ARGV)
|
27
|
+
cmd = nil
|
28
|
+
args = cli(argv,
|
29
|
+
'-d --debug' => lambda{ $DEBUG = true },
|
30
|
+
'-w --warn' => lambda{ $VERBOSE = true },
|
31
|
+
'-f --force' => lambda{ @force = true },
|
32
|
+
'-o --stdout' => lambda{ @stdout = true },
|
33
|
+
'-s --static' => lambda{ @static = true },
|
34
|
+
'-u --using' => lambda{ no_cmd!(cmd); cmd = :using },
|
35
|
+
'-a --adding' => lambda{ no_cmd!(cmd); cmd = :adding },
|
36
|
+
'-g --generate' => lambda{ no_cmd!(cmd); cmd = :generate },
|
37
|
+
'-h --help' => lambda{ no_cmd!(cmd); cmd = :help }
|
38
|
+
)
|
39
|
+
send(cmd || :show, *args)
|
40
|
+
rescue => error
|
41
|
+
raise error if $DEBUG
|
42
|
+
$stderr.puts "#{File.basename($0)} error: #{error}"
|
43
|
+
exit -1
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# Show returns information from the `.index` file. Before doing so
|
48
|
+
# it always ensures the `.index` file is up to date. To suppress
|
49
|
+
# this update use the `-S/--static` option.
|
50
|
+
#
|
51
|
+
def show(*fields)
|
52
|
+
if @static
|
53
|
+
if Metadata.exists?
|
54
|
+
metadata = Metadata.open
|
55
|
+
puts metadata.about(*fields)
|
56
|
+
else
|
57
|
+
raise Error.exception(".index file not found", IOError)
|
58
|
+
end
|
59
|
+
else
|
60
|
+
Metadata.lock!(:force=>@force)
|
61
|
+
unless fields.empty?
|
62
|
+
metadata = Metadata.open
|
63
|
+
puts metadata.about(*fields)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
def using(*sources)
|
70
|
+
raise Error.exception("no sources given") if sources.empty?
|
71
|
+
metadata = Metadata.lock(sources, :force=>true)
|
72
|
+
if @stdout
|
73
|
+
puts metadata.to_yaml
|
74
|
+
else
|
75
|
+
metadata.save!
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
def adding(*sources)
|
81
|
+
raise Error.exception("no sources given") if sources.empty?
|
82
|
+
metadata = Metadata.open
|
83
|
+
metadata = Metadata.lock((metadata.sources & sources), :force=>true)
|
84
|
+
if @stdout
|
85
|
+
puts metadata.to_yaml
|
86
|
+
else
|
87
|
+
metadata.save!
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
#
|
92
|
+
def generate(type, outfile=nil)
|
93
|
+
case type.downcase
|
94
|
+
when 'gemspec'
|
95
|
+
create_gemspec(outfile)
|
96
|
+
when 'ruby', 'index.rb', 'indexfile'
|
97
|
+
create_ruby(outfile)
|
98
|
+
when 'yaml', 'index.yml', 'index.yaml'
|
99
|
+
create_yaml(outfile)
|
100
|
+
else
|
101
|
+
raise Error.exception("unknown file type")
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
def help
|
107
|
+
puts <<-END
|
108
|
+
index [command-option] [options...] [arguments...]
|
109
|
+
|
110
|
+
(none) [fields...] update index and provide information from index
|
111
|
+
-u --using <sources...> create index using given information sources
|
112
|
+
-a --adding <sources...> update index appending additional information sources
|
113
|
+
-r --remove <sources...> update index removing given information sources
|
114
|
+
-g --generate <type> [fname] generate a file (gemspec, indexfile, metadata)
|
115
|
+
-h --help show this help message
|
116
|
+
|
117
|
+
-o --stdout output to console instead of saving to file
|
118
|
+
-f --force force protected file overwrite if file already exists or is up to date
|
119
|
+
-s --static keep index as is or generate static format if generator supports it
|
120
|
+
END
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
#
|
126
|
+
def create_ruby(outfile=nil)
|
127
|
+
require 'erb'
|
128
|
+
|
129
|
+
outfile = "Indexfile" unless outfile
|
130
|
+
|
131
|
+
if File.exist?(outfile) && !(@stdout or @force)
|
132
|
+
raise Error.exception("#{outfile} file already exists", IOError)
|
133
|
+
end
|
134
|
+
|
135
|
+
template_dir = File.join(DATADIR, "r#{REVISION}")
|
136
|
+
template_file = File.join(template_dir, 'ruby.txt')
|
137
|
+
|
138
|
+
if Metadata.exists?
|
139
|
+
metadata = Metadata.open
|
140
|
+
else
|
141
|
+
metadata = Metadata.new
|
142
|
+
end
|
143
|
+
|
144
|
+
# this is a little weak, but...
|
145
|
+
if gemspec = Dir['{,pkg/}*.gemspec'].first
|
146
|
+
metadata.import_gemspec(gemspec)
|
147
|
+
end
|
148
|
+
|
149
|
+
template = ERB.new(File.read(template_file))
|
150
|
+
result = template.result(Form.new(metadata).get_binding)
|
151
|
+
|
152
|
+
if @stdout
|
153
|
+
puts result
|
154
|
+
else
|
155
|
+
File.open(outfile, 'w') do |f|
|
156
|
+
f << result
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
#
|
162
|
+
def create_yaml(outfile)
|
163
|
+
require 'erb'
|
164
|
+
|
165
|
+
outfile = "Index.yml" unless outfile
|
166
|
+
|
167
|
+
if File.exist?(outfile) && !(@stdout or @force)
|
168
|
+
raise Error.exception("#{outfile} file already exists", IOError)
|
169
|
+
end
|
170
|
+
|
171
|
+
template_dir = File.join(DATADIR, "r#{REVISION}")
|
172
|
+
template_file = File.join(template_dir, 'yaml.txt')
|
173
|
+
|
174
|
+
if Metadata.exists?
|
175
|
+
metadata = Metadata.open
|
176
|
+
else
|
177
|
+
metadata = Metadata.new
|
178
|
+
end
|
179
|
+
|
180
|
+
# this is a little weak, but...
|
181
|
+
if gemspec = Dir['{,pkg/}*.gemspec'].first
|
182
|
+
metadata.import_gemspec(gemspec)
|
183
|
+
end
|
184
|
+
|
185
|
+
template = ERB.new(File.read(template_file))
|
186
|
+
result = template.result(Form.new(metadata).get_binding)
|
187
|
+
|
188
|
+
if @stdout
|
189
|
+
puts result
|
190
|
+
else
|
191
|
+
File.open(outfile, 'w') do |f|
|
192
|
+
f << result
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
#
|
198
|
+
# Create a .gemspec file for use with indexer. Or a static one if `--static` option is used.
|
199
|
+
#
|
200
|
+
def create_gemspec(file=nil)
|
201
|
+
if file
|
202
|
+
if File.extname(file) != '.gemspec'
|
203
|
+
warn "gemspec file without .gemspec extension"
|
204
|
+
end
|
205
|
+
else
|
206
|
+
# TODO: look for pre-existent gemspec, but to do that right we should get
|
207
|
+
# the name from the .index file if it eixts.
|
208
|
+
file = Dir['{,*,pkg/*}.gemspec'].first || '.gemspec'
|
209
|
+
end
|
210
|
+
|
211
|
+
#lib_file = File.join(DIR, "v#{which}", "gemspec.rb")
|
212
|
+
|
213
|
+
if file && File.exist?(file) && !@force && !@stdout
|
214
|
+
raise Error.exception("`#{file}' already exists, use -f/--force to overwrite.")
|
215
|
+
end
|
216
|
+
|
217
|
+
text = GemspecExporter.source_code + "\nIndexer::GemspecExporter.gemspec"
|
218
|
+
|
219
|
+
if @static
|
220
|
+
spec = eval(text, CleanBinding.new, file)
|
221
|
+
text = spec.to_yaml
|
222
|
+
end
|
223
|
+
|
224
|
+
if @stdout
|
225
|
+
puts text
|
226
|
+
else
|
227
|
+
File.open(file, 'w') do |f|
|
228
|
+
f << text
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
#
|
234
|
+
def no_cmd!(cmd)
|
235
|
+
raise Error.exception("more than one command flag") if cmd
|
236
|
+
end
|
237
|
+
|
238
|
+
# Helper class for generating template.
|
239
|
+
#
|
240
|
+
class Form
|
241
|
+
def initialize(metadata)
|
242
|
+
@metadata = metadata
|
243
|
+
end
|
244
|
+
def method_missing(s, *a, &b)
|
245
|
+
@metadata.public_send(s, *a, &b) || '<fill-out #{s}>'
|
246
|
+
end
|
247
|
+
def get_binding; binding; end
|
248
|
+
end
|
249
|
+
|
250
|
+
#
|
251
|
+
#
|
252
|
+
module CleanBinding
|
253
|
+
def self.new
|
254
|
+
binding
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
end
|
259
|
+
|
260
|
+
end
|