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
@@ -0,0 +1,51 @@
|
|
1
|
+
module Apimaster::Generators
|
2
|
+
|
3
|
+
# Manifest captures the actions a generator performs. Instantiate
|
4
|
+
# a manifest with an optional target object, hammer it with actions,
|
5
|
+
# then replay or rewind on the object of your choice.
|
6
|
+
#
|
7
|
+
# Example:
|
8
|
+
# manifest = Manifest.new { |m|
|
9
|
+
# m.make_directory '/foo'
|
10
|
+
# m.create_file '/foo/bar.txt'
|
11
|
+
# }
|
12
|
+
# manifest.replay(creator)
|
13
|
+
# manifest.rewind(destroyer)
|
14
|
+
class Manifest
|
15
|
+
attr_reader :target
|
16
|
+
|
17
|
+
# Take a default action target. Yield self if block given.
|
18
|
+
def initialize(target = nil)
|
19
|
+
@target, @actions = target, []
|
20
|
+
yield self if block_given?
|
21
|
+
end
|
22
|
+
|
23
|
+
# Record an action.
|
24
|
+
def method_missing(action, *args, &block)
|
25
|
+
@actions << [action, args, block]
|
26
|
+
end
|
27
|
+
|
28
|
+
# Replay recorded actions.
|
29
|
+
def replay(target = nil)
|
30
|
+
send_actions(target || @target, @actions)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Rewind recorded actions.
|
34
|
+
def rewind(target = nil)
|
35
|
+
send_actions(target || @target, @actions.reverse)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Erase recorded actions.
|
39
|
+
def erase
|
40
|
+
@actions = []
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
def send_actions(target, actions)
|
45
|
+
actions.each do |method, args, block|
|
46
|
+
target.send(method, *args, &block)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module Apimaster::Generators
|
4
|
+
module Options
|
5
|
+
def self.included(base)
|
6
|
+
base.extend(ClassMethods)
|
7
|
+
class << base
|
8
|
+
if respond_to?(:inherited)
|
9
|
+
alias_method :inherited_without_options, :inherited
|
10
|
+
end
|
11
|
+
alias_method :inherited, :inherited_with_options
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
|
17
|
+
EMPTY_INHERITABLE_ATTRIBUTES = {}.freeze
|
18
|
+
|
19
|
+
def inherited_with_options(sub)
|
20
|
+
inherited_without_options(sub) if respond_to?(:inherited_without_options)
|
21
|
+
sub.extend(Apimaster::Generators::Options::ClassMethods)
|
22
|
+
end
|
23
|
+
|
24
|
+
def mandatory_options(options = nil)
|
25
|
+
if options
|
26
|
+
write_inheritable_attribute(:mandatory_options, options)
|
27
|
+
else
|
28
|
+
read_inheritable_attribute(:mandatory_options) or write_inheritable_attribute(:mandatory_options, {})
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def default_options(options = nil)
|
33
|
+
if options
|
34
|
+
write_inheritable_attribute(:default_options, options)
|
35
|
+
else
|
36
|
+
read_inheritable_attribute(:default_options) or write_inheritable_attribute(:default_options, {})
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def read_inheritable_attribute(key)
|
41
|
+
inheritable_attributes[key]
|
42
|
+
end
|
43
|
+
|
44
|
+
def write_inheritable_attribute(key, value)
|
45
|
+
if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
|
46
|
+
@inheritable_attributes = {}
|
47
|
+
end
|
48
|
+
inheritable_attributes[key] = value
|
49
|
+
end
|
50
|
+
|
51
|
+
def inheritable_attributes
|
52
|
+
@inheritable_attributes ||= EMPTY_INHERITABLE_ATTRIBUTES
|
53
|
+
end
|
54
|
+
|
55
|
+
# Merge together our class options. In increasing precedence:
|
56
|
+
# default_options (class default options)
|
57
|
+
# runtime_options (provided as argument)
|
58
|
+
# mandatory_options (class mandatory options)
|
59
|
+
def full_options(runtime_options = {})
|
60
|
+
default_options.merge(runtime_options).merge(mandatory_options)
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
# Each instance has an options hash that's populated by #parse.
|
66
|
+
def options
|
67
|
+
@options ||= {}
|
68
|
+
end
|
69
|
+
attr_writer :options
|
70
|
+
|
71
|
+
protected
|
72
|
+
# Convenient access to class mandatory options.
|
73
|
+
def mandatory_options
|
74
|
+
self.class.mandatory_options
|
75
|
+
end
|
76
|
+
|
77
|
+
# Convenient access to class default options.
|
78
|
+
def default_options
|
79
|
+
self.class.default_options
|
80
|
+
end
|
81
|
+
|
82
|
+
# Merge together our instance options. In increasing precedence:
|
83
|
+
# default_options (class default options)
|
84
|
+
# options (instance options)
|
85
|
+
# runtime_options (provided as argument)
|
86
|
+
# mandatory_options (class mandatory options)
|
87
|
+
def full_options(runtime_options = {})
|
88
|
+
self.class.full_options(options.merge(runtime_options))
|
89
|
+
end
|
90
|
+
|
91
|
+
# Parse arguments into the options hash. Classes may customize
|
92
|
+
# parsing behavior by overriding these methods:
|
93
|
+
# #banner Usage: ./script/generate [options]
|
94
|
+
# #add_options! Options:
|
95
|
+
# some options..
|
96
|
+
# #add_general_options! General Options:
|
97
|
+
# general options..
|
98
|
+
def parse!(args, runtime_options = {})
|
99
|
+
self.options = {}
|
100
|
+
|
101
|
+
@option_parser = OptionParser.new do |opt|
|
102
|
+
opt.banner = banner
|
103
|
+
add_options!(opt)
|
104
|
+
add_general_options!(opt)
|
105
|
+
opt.parse!(args)
|
106
|
+
end
|
107
|
+
|
108
|
+
return args
|
109
|
+
ensure
|
110
|
+
self.options = full_options(runtime_options)
|
111
|
+
end
|
112
|
+
|
113
|
+
# Raise a usage error. Override usage_message to provide a blurb
|
114
|
+
# after the option parser summary.
|
115
|
+
def usage(message = usage_message)
|
116
|
+
#raise UsageError, "#{@option_parser}\n#{message}"
|
117
|
+
puts "#{@option_parser}\n#{message}"
|
118
|
+
end
|
119
|
+
|
120
|
+
def usage_message
|
121
|
+
''
|
122
|
+
end
|
123
|
+
|
124
|
+
# Override with your own usage banner.
|
125
|
+
def banner
|
126
|
+
"Usage: #{$0} [options]"
|
127
|
+
end
|
128
|
+
|
129
|
+
# Override to add your options to the parser:
|
130
|
+
# def add_options!(opt)
|
131
|
+
# opt.on('-v', '--verbose') { |value| options[:verbose] = value }
|
132
|
+
# end
|
133
|
+
def add_options!(opt)
|
134
|
+
end
|
135
|
+
|
136
|
+
# Adds general options like -h and --quiet. Usually don't override.
|
137
|
+
def add_general_options!(opt)
|
138
|
+
opt.separator 'General Options:'
|
139
|
+
|
140
|
+
opt.on('-h', '--help', 'Show this help message and quit.') { |v| options[:help] = v }
|
141
|
+
opt.on('-p', '--pretend', 'Run but do not make any changes.') { |v| options[:pretend] = v }
|
142
|
+
opt.on('-f', '--force', 'Overwrite files that already exist.') { options[:collision] = :force }
|
143
|
+
opt.on('-s', '--skip', 'Skip files that already exist.') { options[:collision] = :skip }
|
144
|
+
opt.on('-q', '--quiet', 'Suppress normal output.') { |v| options[:quiet] = v }
|
145
|
+
opt.on('-t', '--backtrace', 'Debugging: show backtrace on errors.') { |v| options[:backtrace] = v }
|
146
|
+
opt.on('-c', '--svn', 'Modify files with subversion. (Note: svn must be in path)') do
|
147
|
+
options[:svn] = `svn status`.inject({}) do |opt, e|
|
148
|
+
opt[e.chomp[7..-1]] = true
|
149
|
+
opt
|
150
|
+
end
|
151
|
+
end
|
152
|
+
opt.on('-g', '--git', 'Modify files with git. (Note: git must be in path)') do
|
153
|
+
options[:git] = `git status`.inject({:new => {}, :modified => {}}) do |opt, e|
|
154
|
+
opt[:new][e.chomp[14..-1]] = true if e =~ /new file:/
|
155
|
+
opt[:modified][e.chomp[14..-1]] = true if e =~ /modified:/
|
156
|
+
opt
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
|
2
|
+
module Apimaster end
|
3
|
+
|
4
|
+
require File.dirname(__FILE__) + '/options'
|
5
|
+
require File.dirname(__FILE__) + '/manifest'
|
6
|
+
require File.dirname(__FILE__) + '/simple_logger'
|
7
|
+
|
8
|
+
require File.dirname(__FILE__) + '/base'
|
9
|
+
require File.dirname(__FILE__) + '/command'
|
10
|
+
require File.dirname(__FILE__) + '/application'
|
11
|
+
|
12
|
+
module Apimaster::Generators
|
13
|
+
module Scripts
|
14
|
+
|
15
|
+
# Generator scripts handle command-line invocation. Each script
|
16
|
+
# responds to an invoke! class method which handles option parsing
|
17
|
+
# and generator invocation.
|
18
|
+
class Base
|
19
|
+
include Options
|
20
|
+
|
21
|
+
default_options :collision => :ask, :quiet => false
|
22
|
+
|
23
|
+
attr_reader :stdout
|
24
|
+
attr_accessor :commands
|
25
|
+
|
26
|
+
def initialize
|
27
|
+
@commands ||= {}
|
28
|
+
register("new", Application)
|
29
|
+
end
|
30
|
+
|
31
|
+
def register name, klass
|
32
|
+
@commands[name] = klass
|
33
|
+
end
|
34
|
+
|
35
|
+
# Run the generator script. Takes an array of unparsed arguments
|
36
|
+
# and a hash of parsed arguments, takes the generator as an option
|
37
|
+
# or first remaining argument, and invokes the requested command.
|
38
|
+
def run(args = [], runtime_options = {})
|
39
|
+
@stdout = runtime_options[:stdout] || $stdout
|
40
|
+
begin
|
41
|
+
parse!(args.dup, runtime_options)
|
42
|
+
rescue OptionParser::InvalidOption => e
|
43
|
+
# Don't cry, script. Generators want what you think is invalid.
|
44
|
+
end
|
45
|
+
|
46
|
+
# Look up generator instance and invoke command on it.
|
47
|
+
if command = args.shift
|
48
|
+
raise "Invalid command name: #{command}" unless commands.key?(command)
|
49
|
+
commands[command].new(args).run
|
50
|
+
else
|
51
|
+
usage
|
52
|
+
end
|
53
|
+
end
|
54
|
+
rescue => e
|
55
|
+
stdout.puts e
|
56
|
+
stdout.puts " #{e.backtrace.join("\n ")}\n" if options[:backtrace]
|
57
|
+
raise SystemExit unless options[:no_exit]
|
58
|
+
end
|
59
|
+
|
60
|
+
def usage
|
61
|
+
stdout.puts "apimaster new your_app_name"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Apimaster::Generators
|
2
|
+
class SimpleLogger # :nodoc:
|
3
|
+
attr_reader :out
|
4
|
+
attr_accessor :quiet
|
5
|
+
|
6
|
+
def initialize(out = $stdout)
|
7
|
+
@out = out
|
8
|
+
@quiet = false
|
9
|
+
@level = 0
|
10
|
+
end
|
11
|
+
|
12
|
+
def log(status, message, &block)
|
13
|
+
@out.print("%12s %s%s\n" % [status, ' ' * @level, message]) unless quiet
|
14
|
+
indent(&block) if block_given?
|
15
|
+
end
|
16
|
+
|
17
|
+
def indent(&block)
|
18
|
+
@level += 1
|
19
|
+
if block_given?
|
20
|
+
begin
|
21
|
+
block.call
|
22
|
+
ensure
|
23
|
+
outdent
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def outdent
|
29
|
+
@level -= 1
|
30
|
+
if block_given?
|
31
|
+
begin
|
32
|
+
block.call
|
33
|
+
ensure
|
34
|
+
indent
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
def method_missing(method, *args, &block)
|
41
|
+
log(method.to_s, args.first, &block)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#source :gemcutter
|
2
|
+
source "https://rubygems.org"
|
3
|
+
|
4
|
+
gem "sinatra"
|
5
|
+
gem "sinatra-contrib"
|
6
|
+
gem "thin"
|
7
|
+
gem "json"
|
8
|
+
gem "rake"
|
9
|
+
gem "apimaster"
|
10
|
+
|
11
|
+
group :development do
|
12
|
+
end
|
13
|
+
|
14
|
+
group :production do
|
15
|
+
end
|
16
|
+
|
17
|
+
group :test do
|
18
|
+
gem "sqlite3"
|
19
|
+
gem "rack-test"
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) <%= Time.now.year %> YOUR NAME
|
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.
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rake/gempackagetask'
|
2
|
+
require 'rubygems/specification'
|
3
|
+
require 'date'
|
4
|
+
require 'bundler'
|
5
|
+
|
6
|
+
task :default => [:spec]
|
7
|
+
|
8
|
+
require 'spec/rake/spectask'
|
9
|
+
desc "Run specs"
|
10
|
+
Spec::Rake::SpecTask.new do |t|
|
11
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
12
|
+
t.spec_opts = %w(-fs --color)
|
13
|
+
t.spec_opts << '--loadby' << 'random'
|
14
|
+
|
15
|
+
t.rcov_opts << '--exclude' << 'spec,.bundle'
|
16
|
+
t.rcov = ENV.has_key?('NO_RCOV') ? ENV['NO_RCOV'] != 'true' : true
|
17
|
+
t.rcov_opts << '--text-summary'
|
18
|
+
t.rcov_opts << '--sort' << 'coverage' << '--sort-reverse'
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Copyright (C) 2011-2012 AdMaster, Inc.
|
4
|
+
|
5
|
+
module <%= module_name %>
|
6
|
+
class Application < Sinatra::Base
|
7
|
+
|
8
|
+
use Apimaster::Application
|
9
|
+
|
10
|
+
before do
|
11
|
+
# authorize
|
12
|
+
end
|
13
|
+
|
14
|
+
# controllers
|
15
|
+
use IndexController
|
16
|
+
# use YourCountroller
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Copyright (C) 2011-2012 AdMaster, Inc.
|
4
|
+
|
5
|
+
require "rubygems"
|
6
|
+
require "bundler"
|
7
|
+
require "cgi"
|
8
|
+
|
9
|
+
require "./config/patches"
|
10
|
+
require "./config/initializer"
|
11
|
+
require "./lib/<%= app_name %>"
|
12
|
+
|
13
|
+
Dir.glob "./app/{models,helpers,controllers}/**/*.rb" do |f|
|
14
|
+
require f
|
15
|
+
end
|
16
|
+
|
17
|
+
require "./config/application"
|