apimaster 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.md +12 -0
- data/apimaster.gemspec +14 -0
- data/bin/apimaster +6 -0
- data/lib/apimaster.rb +21 -0
- data/lib/apimaster/application.rb +28 -0
- data/lib/apimaster/controllers/errors.rb +34 -0
- data/lib/apimaster/error.rb +79 -0
- data/lib/apimaster/generators/application.rb +112 -0
- data/lib/apimaster/generators/base.rb +206 -0
- data/lib/apimaster/generators/command.rb +697 -0
- data/lib/apimaster/generators/manifest.rb +51 -0
- data/lib/apimaster/generators/options.rb +162 -0
- data/lib/apimaster/generators/scripts.rb +64 -0
- data/lib/apimaster/generators/simple_logger.rb +44 -0
- data/lib/apimaster/generators/templates/Gemfile +21 -0
- data/lib/apimaster/generators/templates/LICENSE +20 -0
- data/lib/apimaster/generators/templates/README.md +10 -0
- data/lib/apimaster/generators/templates/Rakefile +19 -0
- data/lib/apimaster/generators/templates/TODO +4 -0
- data/lib/apimaster/generators/templates/app/controllers/index_controller.rb.erb +7 -0
- data/lib/apimaster/generators/templates/config.ru.erb +8 -0
- data/lib/apimaster/generators/templates/config/application.rb.erb +19 -0
- data/lib/apimaster/generators/templates/config/boot.rb.erb +17 -0
- data/lib/apimaster/generators/templates/config/initializer.rb.erb +13 -0
- data/lib/apimaster/generators/templates/config/patches.rb.erb +0 -0
- data/lib/apimaster/generators/templates/config/settings/app.yml.erb +3 -0
- data/lib/apimaster/generators/templates/config/settings/mongoid.yml.erb +66 -0
- data/lib/apimaster/generators/templates/config/settings/oauth.yml.erb +8 -0
- data/lib/apimaster/generators/templates/gitignore +10 -0
- data/lib/apimaster/generators/templates/lib/module.rb.erb +6 -0
- data/lib/apimaster/generators/templates/test/functional_test.rb.erb +2 -0
- data/lib/apimaster/generators/templates/test/test_helper.rb.erb +1 -0
- data/lib/apimaster/generators/templates/test/unit_test.rb.erb +2 -0
- data/lib/apimaster/generators/version.rb +3 -0
- data/lib/apimaster/helpers/headers.rb +30 -0
- data/lib/apimaster/helpers/request.rb +49 -0
- data/lib/apimaster/helpers/session.rb +36 -0
- data/lib/apimaster/mapper.rb +86 -0
- data/lib/apimaster/models/user.rb +33 -0
- data/lib/apimaster/models/user_mock.rb +13 -0
- data/lib/apimaster/setting.rb +68 -0
- metadata +45 -3
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Admaster Inc
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
data/apimaster.gemspec
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'apimaster'
|
3
|
+
s.version = '0.0.2'
|
4
|
+
s.date = '2012-07-06'
|
5
|
+
s.summary = "ApiMaster!"
|
6
|
+
s.description = "A simple restful api framework."
|
7
|
+
s.authors = ["Sun", "Zhang", "Li"]
|
8
|
+
s.email = 'sunxiqiu@admaster.com.cn'
|
9
|
+
s.files = Dir['{bin/*,lib/**/*, test/*}'] +
|
10
|
+
%w(LICENSE README.md apimaster.gemspec)
|
11
|
+
s.homepage = 'http://rubygems.org/gems/apimaster'
|
12
|
+
s.executables << 'apimaster'
|
13
|
+
#s.add_dependency "erb"
|
14
|
+
end
|
data/bin/apimaster
ADDED
data/lib/apimaster.rb
CHANGED
@@ -1 +1,22 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Copyright (C) 2011-2012 AdMaster, Inc.
|
1
4
|
|
5
|
+
module Apimaster end
|
6
|
+
module Apimaster::Helpers end
|
7
|
+
module Apimaster::Controllers end
|
8
|
+
module Apimaster::Models end
|
9
|
+
|
10
|
+
require_relative './apimaster/setting'
|
11
|
+
require_relative './apimaster/error'
|
12
|
+
require_relative './apimaster/mapper'
|
13
|
+
|
14
|
+
require_relative './apimaster/helpers/headers.rb'
|
15
|
+
require_relative './apimaster/helpers/request.rb'
|
16
|
+
require_relative './apimaster/helpers/session.rb'
|
17
|
+
|
18
|
+
require_relative './apimaster/models/user.rb'
|
19
|
+
require_relative './apimaster/models/user_mock.rb'
|
20
|
+
|
21
|
+
require_relative './apimaster/controllers/errors.rb'
|
22
|
+
require_relative './apimaster/application'
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Copyright (C) 2011-2012 AdMaster, Inc.
|
4
|
+
|
5
|
+
module Apimaster
|
6
|
+
class Application < Sinatra::Base
|
7
|
+
|
8
|
+
# Helpers
|
9
|
+
superclass.helpers Sinatra::JSON
|
10
|
+
superclass.helpers Apimaster::Helpers::Request
|
11
|
+
superclass.helpers Apimaster::Helpers::Headers
|
12
|
+
superclass.helpers Apimaster::Helpers::Session
|
13
|
+
|
14
|
+
superclass.configure :development do
|
15
|
+
superclass.register Sinatra::Reloader
|
16
|
+
superclass.also_reload "./app/{controllers,models,helpers}/**/*.rb"
|
17
|
+
end
|
18
|
+
|
19
|
+
superclass.configure do
|
20
|
+
superclass.set :root, ::File.expand_path(".")
|
21
|
+
superclass.set :json_encoder, :to_json
|
22
|
+
superclass.set :show_exceptions, false
|
23
|
+
end
|
24
|
+
|
25
|
+
use Apimaster::Controllers::Errors
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Copyright (C) 2011-2012 AdMaster, Inc.
|
4
|
+
|
5
|
+
module Apimaster::Controllers
|
6
|
+
|
7
|
+
class Errors < Sinatra::Base
|
8
|
+
|
9
|
+
superclass.error Apimaster::NormalError do
|
10
|
+
e = env['sinatra.error']
|
11
|
+
error = [:resource, :code, :field].inject({}) do |err, val|
|
12
|
+
if e.respond_to?(val) and v = e.send(val)
|
13
|
+
err[val] = v
|
14
|
+
end
|
15
|
+
err
|
16
|
+
end
|
17
|
+
|
18
|
+
messages = {:message => e.message}
|
19
|
+
messages[:errors] = [error] unless error.empty?
|
20
|
+
json messages
|
21
|
+
end
|
22
|
+
|
23
|
+
superclass.error do
|
24
|
+
raise env['sinatra.error'] if development?
|
25
|
+
json :message => "Internal Server Error"
|
26
|
+
end
|
27
|
+
|
28
|
+
not_found do
|
29
|
+
json message: "Not Found"
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Copyright (C) 2011-2012 AdMaster, Inc.
|
4
|
+
#
|
5
|
+
# @author: sunxiqiu@admaster.com.cn
|
6
|
+
|
7
|
+
module Apimaster
|
8
|
+
|
9
|
+
class NormalError < StandardError
|
10
|
+
attr_reader :code
|
11
|
+
attr_reader :error
|
12
|
+
attr_reader :resource
|
13
|
+
attr_reader :field
|
14
|
+
|
15
|
+
# error :missing, :missing_field, :invalid, :already_exists
|
16
|
+
def initialize(message = '', code = nil, error = :invalid, resource = nil, field = nil)
|
17
|
+
@code = code
|
18
|
+
@error = error.to_sym
|
19
|
+
@resource = resource
|
20
|
+
@field = field
|
21
|
+
super(message)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class MissingError < NormalError
|
26
|
+
def initialize(resource = nil)
|
27
|
+
super("Resource '#{resource}' does not exist.", 404, :missing, resource)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class MissingFieldError < NormalError
|
32
|
+
def initialize(resource = nil, field = nil)
|
33
|
+
super("Required field '#{field}' on a resource '#{resource}' has not been set.", 422, :missing_field, resource, field)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class InvalidFieldError < NormalError
|
38
|
+
def initialize(resource = nil, field = nil)
|
39
|
+
super("The formatting of the field '#{field}' on a resource '#{resource}' is invalid.", 422, :invalid, resource, field)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class AlreadyExistsError < NormalError
|
44
|
+
def initialize(resource = nil, field = nil)
|
45
|
+
super("Another resource '#{resource}' has the same value as this field '#{field}'. ", 409, :already_exists, resource, field)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class RelationExistsError < NormalError
|
50
|
+
def initialize(resource = nil, field = nil)
|
51
|
+
super("Our results indicate a positive relationship exists.", 409, :relation_exists, resource, field)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class RequestError < StandardError
|
56
|
+
def initialize(resource = nil, field = nil)
|
57
|
+
super("Problems parsing JSON.", 400, :parse_error, resource, field)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class UnauthorizedError < NormalError
|
62
|
+
def initialize(resource = nil, field = nil)
|
63
|
+
super("Your authorization token were invalid.", 401, :unauthorized, resource, field)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class PermissionDeniedError < NormalError
|
68
|
+
def initialize(resource = nil, field = nil)
|
69
|
+
super("Permission denied to access resource '#{resource}'.", 403, :forbidden, resource, field)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class OauthError < NormalError
|
74
|
+
def initialize(message)
|
75
|
+
super(message, 422, :oauth_error)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
|
3
|
+
module Apimaster::Generators
|
4
|
+
class Application < Create
|
5
|
+
|
6
|
+
DEFAULT_SHEBANG = File.join(RbConfig::CONFIG['bindir'],
|
7
|
+
RbConfig::CONFIG['ruby_install_name'])
|
8
|
+
|
9
|
+
default_options :shebang => DEFAULT_SHEBANG,
|
10
|
+
:an_option => 'some_default'
|
11
|
+
|
12
|
+
attr_reader :app_name, :module_name
|
13
|
+
|
14
|
+
def initialize(runtime_args, runtime_options = {})
|
15
|
+
runtime_options[:source] = File.dirname(__FILE__) + '/templates'
|
16
|
+
runtime_options[:destination] = Dir.pwd
|
17
|
+
runtime_options[:collision] = :ask
|
18
|
+
runtime_options[:stdout] = STDOUT
|
19
|
+
super
|
20
|
+
usage if args.empty?
|
21
|
+
#@destination_root = args.shift
|
22
|
+
#@app_name = File.basename(File.expand_path(@destination_root))
|
23
|
+
@app_name = args[0]
|
24
|
+
raise 'Undefined app name.' unless @app_name
|
25
|
+
@module_name = camelize(app_name)
|
26
|
+
extract_options
|
27
|
+
end
|
28
|
+
|
29
|
+
def manifest
|
30
|
+
record do |m|
|
31
|
+
# Ensure appropriate folder(s) exists
|
32
|
+
m.directory ''
|
33
|
+
BASEDIRS.each { |path| m.directory path }
|
34
|
+
m.directory "lib/#{app_name}"
|
35
|
+
|
36
|
+
# config
|
37
|
+
m.template "config/boot.rb.erb", "config/boot.rb"
|
38
|
+
m.template "config/patches.rb.erb", "config/patches.rb"
|
39
|
+
m.template "config/initializer.rb.erb", "config/initializer.rb"
|
40
|
+
m.template "config/application.rb.erb", "config/application.rb"
|
41
|
+
m.template "config/settings/mongoid.yml.erb", "config/settings/mongoid.yml"
|
42
|
+
m.template "config/settings/app.yml.erb", "config/settings/app.yml"
|
43
|
+
m.template "config/settings/oauth.yml.erb", "config/settings/oauth.yml"
|
44
|
+
|
45
|
+
# Create stubs
|
46
|
+
m.template "config.ru.erb", "config.ru"
|
47
|
+
m.template "gitignore", ".gitignore"
|
48
|
+
m.template "lib/module.rb.erb", "lib/#{app_name}.rb"
|
49
|
+
m.template "app/controllers/index_controller.rb.erb", "app/controllers/index_controller.rb"
|
50
|
+
|
51
|
+
# Test stubs
|
52
|
+
m.template "test/test_helper.rb.erb", "test/test_helper.rb"
|
53
|
+
m.template "test/functional_test.rb.erb", "test/functional/index_controller_test.rb"
|
54
|
+
m.template "test/unit_test.rb.erb", "test/unit/#{app_name}_test.rb"
|
55
|
+
|
56
|
+
%w(LICENSE Rakefile README.md Gemfile TODO).each do |file|
|
57
|
+
m.template file, file
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
protected
|
63
|
+
def banner
|
64
|
+
<<-EOS
|
65
|
+
Creates a Apimaster scaffold.
|
66
|
+
|
67
|
+
USAGE: apimaster new your_app_name"
|
68
|
+
EOS
|
69
|
+
end
|
70
|
+
|
71
|
+
def add_options!(opts)
|
72
|
+
opts.separator ''
|
73
|
+
opts.separator 'Options:'
|
74
|
+
# For each option below, place the default
|
75
|
+
# at the top of the file next to "default_options"
|
76
|
+
# opts.on("-a", "--author=\"Your Name\"", String,
|
77
|
+
# "Some comment about this option",
|
78
|
+
# "Default: none") { |x| options[:author] = x }
|
79
|
+
opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
|
80
|
+
end
|
81
|
+
|
82
|
+
def extract_options
|
83
|
+
# for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
|
84
|
+
# Templates can access these value via the attr_reader-generated methods, but not the
|
85
|
+
# raw instance variable value.
|
86
|
+
# @author = options[:author]
|
87
|
+
end
|
88
|
+
|
89
|
+
# Installation skeleton. Intermediate directories are automatically
|
90
|
+
# created so don't sweat their absence here.
|
91
|
+
BASEDIRS = %w(
|
92
|
+
app
|
93
|
+
app/controllers
|
94
|
+
app/views
|
95
|
+
app/models
|
96
|
+
app/helpers
|
97
|
+
bin
|
98
|
+
config
|
99
|
+
config/settings
|
100
|
+
config/locales
|
101
|
+
doc
|
102
|
+
lib
|
103
|
+
log
|
104
|
+
test
|
105
|
+
test/unit
|
106
|
+
test/functional
|
107
|
+
test/factory
|
108
|
+
tmp
|
109
|
+
public
|
110
|
+
)
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,206 @@
|
|
1
|
+
# Apimaster::Generators is a code generation platform Ruby frameworks.
|
2
|
+
# Generators are easily invoked within Ruby framework instances
|
3
|
+
# to add and remove components such as library and test files.
|
4
|
+
#
|
5
|
+
# New generators are easy to create and may be distributed within RubyGems,
|
6
|
+
# user home directory, or within each Ruby framework that uses Apimaster::Generators.
|
7
|
+
#
|
8
|
+
# For example, newgem uses Apimaster::Generators to generate new RubyGems. Those
|
9
|
+
# generated RubyGems can then use Apimaster::Generators (via a generated script/generate
|
10
|
+
# application) to generate tests and executable apps, etc, for the RubyGem.
|
11
|
+
#
|
12
|
+
# Generators may subclass other generators to provide variations that
|
13
|
+
# require little or no new logic but replace the template files.
|
14
|
+
#
|
15
|
+
# For a RubyGem, put your generator classes and templates within subfolders
|
16
|
+
# of the +generators+ directory.
|
17
|
+
#
|
18
|
+
# The layout of generator files can be seen in the built-in
|
19
|
+
# +test_unit+ generator:
|
20
|
+
#
|
21
|
+
# test_unit_generators/
|
22
|
+
# test_unit/
|
23
|
+
# test_unit_generator.rb
|
24
|
+
# templates/
|
25
|
+
# test_unit.rb
|
26
|
+
#
|
27
|
+
# The directory name (+test_unit+) matches the name of the generator file
|
28
|
+
# (test_unit_generator.rb) and class (+TestUnitGenerators+). The files
|
29
|
+
# that will be copied or used as templates are stored in the +templates+
|
30
|
+
# directory.
|
31
|
+
#
|
32
|
+
# The filenames of the templates don't matter, but choose something that
|
33
|
+
# will be self-explanatory since you will be referencing these in the
|
34
|
+
# +manifest+ method inside your generator subclass.
|
35
|
+
#
|
36
|
+
#
|
37
|
+
module Apimaster::Generators
|
38
|
+
class GeneratorsError < StandardError; end
|
39
|
+
class UsageError < GeneratorsError; end
|
40
|
+
|
41
|
+
|
42
|
+
# The base code generator is bare-bones. It sets up the source and
|
43
|
+
# destination paths and tells the logger whether to keep its trap shut.
|
44
|
+
#
|
45
|
+
# It's useful for copying files such as stylesheets, images, or
|
46
|
+
# javascripts.
|
47
|
+
#
|
48
|
+
# For more comprehensive template-based passive code generation with
|
49
|
+
# arguments, you'll want Apimaster::Generators::NamedBase.
|
50
|
+
#
|
51
|
+
# Generators create a manifest of the actions they perform then hand
|
52
|
+
# the manifest to a command which replays the actions to do the heavy
|
53
|
+
# lifting (such as checking for existing files or creating directories
|
54
|
+
# if needed). Create, destroy, and list commands are included. Since a
|
55
|
+
# single manifest may be used by any command, creating new generators is
|
56
|
+
# as simple as writing some code templates and declaring what you'd like
|
57
|
+
# to do with them.
|
58
|
+
#
|
59
|
+
# The manifest method must be implemented by subclasses, returning a
|
60
|
+
# Apimaster::Generators::Manifest. The +record+ method is provided as a
|
61
|
+
# convenience for manifest creation. Example:
|
62
|
+
#
|
63
|
+
# class StylesheetGenerators < Apimaster::Generators::Base
|
64
|
+
# def manifest
|
65
|
+
# record do |m|
|
66
|
+
# m.directory('public/stylesheets')
|
67
|
+
# m.file('application.css', 'public/stylesheets/application.css')
|
68
|
+
# end
|
69
|
+
# end
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
# See Apimaster::Generators::Commands::Create for a list of methods available
|
73
|
+
# to the manifest.
|
74
|
+
class Base
|
75
|
+
include Options
|
76
|
+
|
77
|
+
# Declare default options for the generator. These options
|
78
|
+
# are inherited to subclasses.
|
79
|
+
default_options :collision => :ask, :quiet => false, :stdout => STDOUT
|
80
|
+
|
81
|
+
# A logger instance available everywhere in the generator.
|
82
|
+
attr_accessor :logger
|
83
|
+
|
84
|
+
# Either Apimaster::Generators::Base, or a subclass (e.g. Rails::Generators::Base)
|
85
|
+
# Currently used to determine the lookup paths via the overriden const_missing mechansim
|
86
|
+
# in lookup.rb
|
87
|
+
attr_accessor :active
|
88
|
+
|
89
|
+
# Every generator that is dynamically looked up is tagged with a
|
90
|
+
# Spec describing where it was found.
|
91
|
+
attr_accessor :spec
|
92
|
+
#class_attribute :spec
|
93
|
+
|
94
|
+
attr_reader :source_root, :destination_root, :args, :stdout
|
95
|
+
|
96
|
+
def initialize(runtime_args, runtime_options = {})
|
97
|
+
runtime_options[:backtrace] = true
|
98
|
+
@logger = SimpleLogger.new
|
99
|
+
@args = runtime_args
|
100
|
+
parse!(@args, runtime_options)
|
101
|
+
|
102
|
+
# Derive source and destination paths.
|
103
|
+
@source_root = options[:source] || File.join(spec.path, 'templates')
|
104
|
+
if options[:destination]
|
105
|
+
@destination_root = options[:destination]
|
106
|
+
end
|
107
|
+
|
108
|
+
# Silence the logger if requested.
|
109
|
+
#logger.quiet = options[:quiet]
|
110
|
+
|
111
|
+
@stdout = options[:stdout]
|
112
|
+
|
113
|
+
# Raise usage error if help is requested.
|
114
|
+
usage if options[:help]
|
115
|
+
end
|
116
|
+
|
117
|
+
# Generators must provide a manifest. Use the +record+ method to create
|
118
|
+
# a new manifest and record your generator's actions.
|
119
|
+
def manifest
|
120
|
+
raise NotImplementedError, "No manifest for '#{spec.name}' generator."
|
121
|
+
end
|
122
|
+
|
123
|
+
# Return the full path from the source root for the given path.
|
124
|
+
# Example for source_root = '/source':
|
125
|
+
# source_path('some/path.rb') == '/source/some/path.rb'
|
126
|
+
#
|
127
|
+
# The given path may include a colon ':' character to indicate that
|
128
|
+
# the file belongs to another generator. This notation allows any
|
129
|
+
# generator to borrow files from another. Example:
|
130
|
+
# source_path('model:fixture.yml') = '/model/source/path/fixture.yml'
|
131
|
+
def source_path(relative_source)
|
132
|
+
# Check whether we're referring to another generator's file.
|
133
|
+
name, path = relative_source.split(':', 2)
|
134
|
+
|
135
|
+
# If not, return the full path to our source file.
|
136
|
+
if path.nil?
|
137
|
+
File.join(source_root, name)
|
138
|
+
|
139
|
+
# Otherwise, ask our referral for the file.
|
140
|
+
else
|
141
|
+
# FIXME: this is broken, though almost always true. Others'
|
142
|
+
# source_root are not necessarily the templates dir.
|
143
|
+
File.join(self.class.lookup(name).path, 'templates', path)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
# Return the full path from the destination root for the given path.
|
148
|
+
# Example for destination_root = '/dest':
|
149
|
+
# destination_path('some/path.rb') == '/dest/some/path.rb'
|
150
|
+
def destination_path(relative_destination)
|
151
|
+
File.expand_path(File.join(destination_root, relative_destination))
|
152
|
+
end
|
153
|
+
|
154
|
+
# Return the basename of the destination_root,
|
155
|
+
# BUT, if it is trunk, tags, or branches, it continues to the
|
156
|
+
# parent path for the name
|
157
|
+
def base_name
|
158
|
+
name = File.basename(destination_root)
|
159
|
+
root = destination_root
|
160
|
+
while %w[trunk branches tags].include? name
|
161
|
+
root = File.expand_path(File.join(root, ".."))
|
162
|
+
name = File.basename(root)
|
163
|
+
end
|
164
|
+
name
|
165
|
+
end
|
166
|
+
|
167
|
+
def after_generate
|
168
|
+
end
|
169
|
+
|
170
|
+
# Run the generator script. Takes an array of unparsed arguments
|
171
|
+
# and a hash of parsed arguments, takes the generator as an option
|
172
|
+
# or first remaining argument, and invokes the requested command.
|
173
|
+
def run
|
174
|
+
# Look up generator instance and invoke command on it.
|
175
|
+
manifest.replay(self)
|
176
|
+
after_generate
|
177
|
+
rescue => e
|
178
|
+
puts e
|
179
|
+
puts " #{e.backtrace.join("\n ")}\n" if options[:backtrace]
|
180
|
+
raise SystemExit unless options[:no_exit]
|
181
|
+
end
|
182
|
+
|
183
|
+
def camelize(term, uppercase_first_letter = true)
|
184
|
+
string = term.to_s
|
185
|
+
string = string.sub(/^[a-z\d]*/) { $&.capitalize }
|
186
|
+
string.gsub(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{$2.capitalize}" }.gsub('/', '::')
|
187
|
+
end
|
188
|
+
|
189
|
+
protected
|
190
|
+
# Convenience method for generator subclasses to record a manifest.
|
191
|
+
def record
|
192
|
+
Apimaster::Generators::Manifest.new(self) { |m| yield m }
|
193
|
+
end
|
194
|
+
|
195
|
+
# Override with your own usage banner.
|
196
|
+
def banner
|
197
|
+
"Usage: #{$0} #{spec.name} [options]"
|
198
|
+
end
|
199
|
+
|
200
|
+
# Read USAGE from file in generator base path.
|
201
|
+
def usage_message
|
202
|
+
File.read(File.join(spec.path, 'USAGE')) rescue ''
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|