indexer 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|