appjam 0.1.0.pre6 → 0.1.0.pre9
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/README.rdoc +1 -1
- data/bin/appjam +2 -7
- data/lib/appjam.rb +9 -1
- data/lib/appjam/command.rb +27 -0
- data/lib/appjam/generators/actions.rb +170 -0
- data/lib/appjam/generators/cli.rb +42 -0
- data/lib/appjam/generators/model.rb +51 -0
- data/lib/appjam/generators/project.rb +9 -6
- data/lib/appjam/generators/project/Classes/{users → contacts}/ApplicationFacade.h.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/ApplicationFacade.m.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/controller/CreateUserCommand.h.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/controller/CreateUserCommand.m.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/controller/DeleteUserCommand.h.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/controller/DeleteUserCommand.m.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/controller/GetUsersCommand.h.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/controller/GetUsersCommand.m.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/controller/StartupCommand.h.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/controller/StartupCommand.m.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/controller/UpdateUserCommand.h.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/controller/UpdateUserCommand.m.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/model/UserProxy.h.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/model/UserProxy.m.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/model/vo/UserVO.h.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/model/vo/UserVO.m.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/view/ContactsMediator.h.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/view/ContactsMediator.m.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/view/UserFormMediator.h.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/view/UserFormMediator.m.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/view/UserListMediator.h.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/view/UserListMediator.m.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/view/components/Contacts.h.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/view/components/Contacts.m.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/view/components/UserForm.h.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/view/components/UserForm.m.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/view/components/UserList.h.tt +0 -0
- data/lib/appjam/generators/project/Classes/{users → contacts}/view/components/UserList.m.tt +0 -0
- data/lib/appjam/generators/project/Contacts.xcodeproj/eiffel.pbxuser +185 -41
- data/lib/appjam/generators/project/Contacts.xcodeproj/eiffel.perspectivev3 +23 -22
- data/lib/appjam/generators/project/Contacts.xcodeproj/project.pbxproj +102 -102
- data/lib/appjam/version.rb +1 -1
- data/test/helper.rb +132 -0
- data/test/test_project_generator.rb +38 -0
- metadata +263 -56
- data/spec/appjam_spec.rb +0 -7
- data/spec/spec_helper.rb +0 -12
data/README.rdoc
CHANGED
data/bin/appjam
CHANGED
@@ -7,11 +7,6 @@ unless $LOAD_PATH.include?(lib_dir)
|
|
7
7
|
end
|
8
8
|
|
9
9
|
require 'appjam'
|
10
|
-
require File.expand_path(File.dirname(__FILE__) + '/../lib/appjam/generators/
|
10
|
+
require File.expand_path(File.dirname(__FILE__) + '/../lib/appjam/generators/cli')
|
11
11
|
|
12
|
-
|
13
|
-
Appjam::Generators::Project.start(ARGV)
|
14
|
-
rescue => e
|
15
|
-
STDERR.puts "Error: #{e}"
|
16
|
-
exit -1
|
17
|
-
end
|
12
|
+
Appjam::Generators::Cli.start(ARGV)
|
data/lib/appjam.rb
CHANGED
@@ -40,6 +40,14 @@ module Appjam
|
|
40
40
|
def add_generator(name, klass)
|
41
41
|
mappings[name] = klass
|
42
42
|
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Load Global Actions and Component Actions then all files in +load_path+.
|
46
|
+
#
|
47
|
+
def load_components!
|
48
|
+
require 'appjam/generators/actions'
|
49
|
+
load_paths.flatten.each { |file| require file }
|
50
|
+
end
|
43
51
|
end
|
44
52
|
end # Generators
|
45
53
|
end # IphoneMvc
|
@@ -47,4 +55,4 @@ end # IphoneMvc
|
|
47
55
|
##
|
48
56
|
# We add our generators to Appjam::Genererator
|
49
57
|
#
|
50
|
-
Appjam::Generators.load_paths << Dir[File.dirname(__FILE__) + '/appjam/generators/project.rb']
|
58
|
+
Appjam::Generators.load_paths << Dir[File.dirname(__FILE__) + '/appjam/generators/{project,model}.rb']
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
|
3
|
+
module Appjam
|
4
|
+
##
|
5
|
+
# This method return the correct location of appjam bin or
|
6
|
+
# exec it using Kernel#system with the given args
|
7
|
+
#
|
8
|
+
def self.bin(*args)
|
9
|
+
@_appjam_bin ||= [self.ruby_command, File.expand_path("../../../bin/appjam", __FILE__)]
|
10
|
+
args.empty? ? @_appjam_bin : system(args.unshift(@_appjam_bin).join(" "))
|
11
|
+
end
|
12
|
+
|
13
|
+
##
|
14
|
+
# Return the path to the ruby interpreter taking into account multiple
|
15
|
+
# installations and windows extensions.
|
16
|
+
#
|
17
|
+
def self.ruby_command
|
18
|
+
@ruby_command ||= begin
|
19
|
+
ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
|
20
|
+
ruby << Config::CONFIG['EXEEXT']
|
21
|
+
|
22
|
+
# escape string in case path to ruby executable contain spaces.
|
23
|
+
ruby.sub!(/.*\s.*/m, '"\&"')
|
24
|
+
ruby
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end # Appjam
|
@@ -0,0 +1,170 @@
|
|
1
|
+
module Appjam
|
2
|
+
module Generators
|
3
|
+
class AppRootNotFound < RuntimeError; end
|
4
|
+
|
5
|
+
module Actions
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
base.extend(ClassMethods)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Performs the necessary generator for a given component choice
|
12
|
+
# execute_component_setup(:mock, 'rr')
|
13
|
+
def execute_component_setup(component, choice)
|
14
|
+
return true && say("Skipping generator for #{component} component...", :yellow) if choice.to_s == 'none'
|
15
|
+
say "Applying '#{choice}' (#{component})...", :yellow
|
16
|
+
apply_component_for(choice, component)
|
17
|
+
send("setup_#{component}") if respond_to?("setup_#{component}")
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns the related module for a given component and option
|
21
|
+
# generator_module_for('rr', :mock)
|
22
|
+
def apply_component_for(choice, component)
|
23
|
+
# I need to override Thor#apply because for unknow reason :verobse => false break tasks.
|
24
|
+
path = File.expand_path(File.dirname(__FILE__) + "/components/#{component.to_s.pluralize}/#{choice}.rb")
|
25
|
+
say_status :apply, "#{component.to_s.pluralize}/#{choice}"
|
26
|
+
shell.padding += 1
|
27
|
+
instance_eval(open(path).read)
|
28
|
+
shell.padding -= 1
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns the component choice stored within the .component file of an application
|
32
|
+
# fetch_component_choice(:mock)
|
33
|
+
def fetch_component_choice(component)
|
34
|
+
retrieve_component_config(destination_root('.components'))[component]
|
35
|
+
end
|
36
|
+
|
37
|
+
# Set the component choice and store it in the .component file of the application
|
38
|
+
# store_component_choice(:renderer, :haml)
|
39
|
+
def store_component_choice(key, value)
|
40
|
+
path = destination_root('.components')
|
41
|
+
config = retrieve_component_config(path)
|
42
|
+
config[key] = value
|
43
|
+
create_file(path, :force => true) { config.to_yaml }
|
44
|
+
value
|
45
|
+
end
|
46
|
+
|
47
|
+
# Loads the component config back into a hash
|
48
|
+
# i.e retrieve_component_config(...) => { :mock => 'rr', :test => 'riot', ... }
|
49
|
+
def retrieve_component_config(target)
|
50
|
+
YAML.load_file(target)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Prompts the user if necessary until a valid choice is returned for the component
|
54
|
+
# resolve_valid_choice(:mock) => 'rr'
|
55
|
+
def resolve_valid_choice(component)
|
56
|
+
available_string = self.class.available_choices_for(component).join(", ")
|
57
|
+
choice = options[component]
|
58
|
+
until valid_choice?(component, choice)
|
59
|
+
say("Option for --#{component} '#{choice}' is not available.", :red)
|
60
|
+
choice = ask("Please enter a valid option for #{component} (#{available_string}):")
|
61
|
+
end
|
62
|
+
choice
|
63
|
+
end
|
64
|
+
|
65
|
+
# Returns true if the option passed is a valid choice for component
|
66
|
+
# valid_option?(:mock, 'rr')
|
67
|
+
def valid_choice?(component, choice)
|
68
|
+
choice.present? && self.class.available_choices_for(component).include?(choice.to_sym)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Creates a component_config file at the destination containing all component options
|
72
|
+
# Content is a yamlized version of a hash containing component name mapping to chosen value
|
73
|
+
def store_component_config(destination)
|
74
|
+
components = @_components || options
|
75
|
+
create_file(destination) do
|
76
|
+
self.class.component_types.inject({}) { |result, comp|
|
77
|
+
result[comp] = components[comp].to_s; result
|
78
|
+
}.to_yaml
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns the root for this thor class (also aliased as destination root).
|
83
|
+
def destination_root(*paths)
|
84
|
+
File.expand_path(File.join(@destination_stack.last, paths))
|
85
|
+
end
|
86
|
+
|
87
|
+
# Returns true if inside a Appjam application
|
88
|
+
def in_app_root?
|
89
|
+
File.exist?(destination_root('Classes'))
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns the field with an unacceptable name(for symbol) else returns nil
|
93
|
+
def invalid_fields(fields)
|
94
|
+
results = fields.select { |field| field.split(":").first =~ /\W/ }
|
95
|
+
results.empty? ? nil : results
|
96
|
+
end
|
97
|
+
|
98
|
+
# Returns the app_name for the application at root
|
99
|
+
def fetch_app_name(app='app')
|
100
|
+
app_path = destination_root(app, 'app.rb')
|
101
|
+
@app_name ||= File.read(app_path).scan(/class\s(.*?)\s</).flatten[0]
|
102
|
+
end
|
103
|
+
|
104
|
+
# Ask something to the user and receives a response.
|
105
|
+
#
|
106
|
+
# ==== Example
|
107
|
+
#
|
108
|
+
# ask("What is your app name?")
|
109
|
+
def ask(statement, default=nil, color=nil)
|
110
|
+
default_text = default ? " (leave blank for #{default}):" : nil
|
111
|
+
say("#{statement}#{default_text} ", color)
|
112
|
+
result = $stdin.gets.strip
|
113
|
+
result.blank? ? default : result
|
114
|
+
end
|
115
|
+
|
116
|
+
# Raise SystemExit if the app is inexistent
|
117
|
+
def check_app_existence(app)
|
118
|
+
unless File.exist?(destination_root(app))
|
119
|
+
say
|
120
|
+
say "================================================================="
|
121
|
+
say "We didn't found #{app.underscore.downcase}! "
|
122
|
+
say "================================================================="
|
123
|
+
say
|
124
|
+
# raise SystemExit
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# Ensure that project name is valid, else raise an NameError
|
129
|
+
def valid_constant?(name)
|
130
|
+
if name =~ /^\d/
|
131
|
+
raise ::NameError, "Project name #{name} cannot start with numbers"
|
132
|
+
elsif name =~ /^\W/
|
133
|
+
raise ::NameError, "Project name #{name} cannot start with non-word character"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
module ClassMethods
|
138
|
+
# Defines a class option to allow a component to be chosen and add to component type list
|
139
|
+
# Also builds the available_choices hash of which component choices are supported
|
140
|
+
# component_option :test, "Testing framework", :aliases => '-t', :choices => [:bacon, :shoulda]
|
141
|
+
def component_option(name, caption, options = {})
|
142
|
+
(@component_types ||= []) << name # TODO use ordered hash and combine with choices below
|
143
|
+
(@available_choices ||= Hash.new)[name] = options[:choices]
|
144
|
+
description = "The #{caption} component (#{options[:choices].join(', ')}, none)"
|
145
|
+
class_option name, :default => options[:default] || options[:choices].first, :aliases => options[:aliases], :desc => description
|
146
|
+
end
|
147
|
+
|
148
|
+
# Tell to Appjam that for this Thor::Group is necessary a task to run
|
149
|
+
def require_arguments!
|
150
|
+
@require_arguments = true
|
151
|
+
end
|
152
|
+
|
153
|
+
# Return true if we need an arguments for our Thor::Group
|
154
|
+
def require_arguments?
|
155
|
+
@require_arguments
|
156
|
+
end
|
157
|
+
|
158
|
+
# Returns the compiled list of component types which can be specified
|
159
|
+
def component_types
|
160
|
+
@component_types
|
161
|
+
end
|
162
|
+
|
163
|
+
# Returns the list of available choices for the given component (including none)
|
164
|
+
def available_choices_for(component)
|
165
|
+
@available_choices[component] + [:none]
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end # Actions
|
169
|
+
end # Generators
|
170
|
+
end # Appjam
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'thor/group'
|
2
|
+
|
3
|
+
module Appjam
|
4
|
+
module Generators
|
5
|
+
##
|
6
|
+
# This class bootstrap +config/boot+ and perform +Appjam::Generators.load_components!+ for handle
|
7
|
+
# 3rd party generators
|
8
|
+
#
|
9
|
+
class Cli < Thor::Group
|
10
|
+
|
11
|
+
# Include related modules
|
12
|
+
include Thor::Actions
|
13
|
+
|
14
|
+
class_option :root, :desc => "The root destination", :aliases => '-r', :default => ".", :type => :string
|
15
|
+
|
16
|
+
# We need to TRY to load boot because some of our app dependencies maybe have
|
17
|
+
# custom generators, so is necessary know who are.
|
18
|
+
def load_boot
|
19
|
+
begin
|
20
|
+
ENV['BUNDLE_GEMFILE'] = File.join(options[:root], "Gemfile") if options[:root]
|
21
|
+
rescue Exception => e
|
22
|
+
puts "=> Problem loading #{boot}"
|
23
|
+
puts ["=> #{e.message}", *e.backtrace].join("\n ")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def setup
|
28
|
+
Appjam::Generators.load_components!
|
29
|
+
|
30
|
+
generator_kind = ARGV.delete_at(0).to_s.downcase.to_sym if ARGV[0].present?
|
31
|
+
generator_class = Appjam::Generators.mappings[generator_kind]
|
32
|
+
|
33
|
+
if generator_class
|
34
|
+
args = ARGV.empty? && generator_class.require_arguments? ? ["-h"] : ARGV
|
35
|
+
generator_class.start(args)
|
36
|
+
else
|
37
|
+
puts "Please specify generator to use (#{Appjam::Generators.mappings.keys.join(", ")})"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end # Cli
|
41
|
+
end # Generators
|
42
|
+
end # Appjam
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'thor/group'
|
3
|
+
require 'thor/actions'
|
4
|
+
require 'active_support/core_ext/string'
|
5
|
+
|
6
|
+
module Appjam
|
7
|
+
module Generators
|
8
|
+
class Model < Thor::Group
|
9
|
+
|
10
|
+
# Add this generator to our appjam
|
11
|
+
Appjam::Generators.add_generator(:model, self)
|
12
|
+
|
13
|
+
# Define the source template root
|
14
|
+
def self.source_root; File.expand_path(File.dirname(__FILE__)); end
|
15
|
+
def self.banner; "appjam model [name]"; end
|
16
|
+
|
17
|
+
# Include related modules
|
18
|
+
include Thor::Actions
|
19
|
+
|
20
|
+
desc "Description:\n\n\tappjam will generates an new PureMvc Model for iphone"
|
21
|
+
|
22
|
+
argument :name, :desc => "The name of your puremvc model"
|
23
|
+
|
24
|
+
class_option :root, :desc => "The root destination", :aliases => '-r', :default => ".", :type => :string
|
25
|
+
class_option :destroy, :aliases => '-d', :default => false, :type => :boolean
|
26
|
+
|
27
|
+
# Show help if no argv given
|
28
|
+
#require_arguments!
|
29
|
+
|
30
|
+
def in_app_root?
|
31
|
+
File.exist?('Classes')
|
32
|
+
end
|
33
|
+
|
34
|
+
def create_app
|
35
|
+
self.destination_root = options[:root]
|
36
|
+
@project_name = name.gsub(/\W/, "_").downcase
|
37
|
+
@class_name = name.gsub(/\W/, "_").capitalize
|
38
|
+
app = options[:model]
|
39
|
+
self.behavior = :revoke if options[:destroy]
|
40
|
+
|
41
|
+
say (<<-TEXT).gsub(/ {10}/,'')
|
42
|
+
|
43
|
+
=================================================================
|
44
|
+
Your #{@class_name} Model app has been generated.
|
45
|
+
=================================================================
|
46
|
+
|
47
|
+
TEXT
|
48
|
+
end
|
49
|
+
end # Model
|
50
|
+
end # Generators
|
51
|
+
end # Appjam
|
@@ -2,13 +2,14 @@ require 'thor'
|
|
2
2
|
require 'thor/group'
|
3
3
|
require 'thor/actions'
|
4
4
|
require 'active_support/core_ext/string'
|
5
|
+
require File.dirname(__FILE__) + '/actions'
|
5
6
|
|
6
7
|
module Appjam
|
7
8
|
module Generators
|
8
9
|
class Project < Thor::Group
|
9
10
|
|
10
11
|
# Add this generator to our appjam
|
11
|
-
Appjam::Generators.add_generator(:
|
12
|
+
Appjam::Generators.add_generator(:project, self)
|
12
13
|
|
13
14
|
# Define the source template root
|
14
15
|
def self.source_root; File.expand_path(File.dirname(__FILE__)); end
|
@@ -16,6 +17,7 @@ module Appjam
|
|
16
17
|
|
17
18
|
# Include related modules
|
18
19
|
include Thor::Actions
|
20
|
+
include Appjam::Generators::Actions
|
19
21
|
|
20
22
|
desc "Description:\n\n\tappjam will generates an new PureMvc application for iphone"
|
21
23
|
|
@@ -32,10 +34,11 @@ module Appjam
|
|
32
34
|
end
|
33
35
|
|
34
36
|
def create_app
|
35
|
-
|
36
|
-
@project_name = name.gsub(/\W/, "_").downcase
|
37
|
+
valid_constant?(options[:project] || name)
|
38
|
+
@project_name = (options[:app] || name).gsub(/\W/, "_").downcase
|
37
39
|
@class_name = name.gsub(/\W/, "_").capitalize
|
38
|
-
|
40
|
+
self.destination_root = options[:root]
|
41
|
+
project = options[:project]
|
39
42
|
self.behavior = :revoke if options[:destroy]
|
40
43
|
|
41
44
|
empty_directory "#{@project_name}"
|
@@ -63,6 +66,6 @@ module Appjam
|
|
63
66
|
|
64
67
|
TEXT
|
65
68
|
end
|
66
|
-
end #
|
69
|
+
end # Project
|
67
70
|
end # Generators
|
68
|
-
end #
|
71
|
+
end # Appjam
|
File without changes
|
File without changes
|
data/lib/appjam/generators/project/Classes/{users → contacts}/controller/CreateUserCommand.h.tt
RENAMED
File without changes
|
data/lib/appjam/generators/project/Classes/{users → contacts}/controller/CreateUserCommand.m.tt
RENAMED
File without changes
|
data/lib/appjam/generators/project/Classes/{users → contacts}/controller/DeleteUserCommand.h.tt
RENAMED
File without changes
|
data/lib/appjam/generators/project/Classes/{users → contacts}/controller/DeleteUserCommand.m.tt
RENAMED
File without changes
|
data/lib/appjam/generators/project/Classes/{users → contacts}/controller/GetUsersCommand.h.tt
RENAMED
File without changes
|
data/lib/appjam/generators/project/Classes/{users → contacts}/controller/GetUsersCommand.m.tt
RENAMED
File without changes
|
data/lib/appjam/generators/project/Classes/{users → contacts}/controller/StartupCommand.h.tt
RENAMED
File without changes
|
data/lib/appjam/generators/project/Classes/{users → contacts}/controller/StartupCommand.m.tt
RENAMED
File without changes
|
data/lib/appjam/generators/project/Classes/{users → contacts}/controller/UpdateUserCommand.h.tt
RENAMED
File without changes
|
data/lib/appjam/generators/project/Classes/{users → contacts}/controller/UpdateUserCommand.m.tt
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|