ti 0.0.6 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +43 -0
- data/Gemfile +2 -19
- data/Gemfile.lock +27 -27
- data/LICENSE.txt +1 -1
- data/README.rdoc +1 -1
- data/Rakefile +0 -28
- data/TODO.mkd +1 -2
- data/lib/ti.rb +10 -10
- data/lib/ti/cli.rb +39 -6
- data/lib/ti/config.rb +22 -0
- data/lib/ti/generate/controller.rb +38 -0
- data/lib/ti/generate/model.rb +13 -7
- data/lib/ti/generate/project.rb +59 -13
- data/lib/ti/generate/view.rb +30 -9
- data/lib/ti/templates/app/controllers/controller.erb +0 -0
- data/lib/ti/templates/app/controllers/window.erb +3 -0
- data/lib/ti/templates/app/views/tabgroup.erb +0 -0
- data/lib/ti/templates/app/views/view.erb +0 -0
- data/lib/ti/templates/app/views/window.erb +3 -0
- data/lib/ti/templates/{guardfile → defaults/Guardfile.erb} +3 -3
- data/lib/ti/templates/defaults/Rakefile.erb +148 -0
- data/lib/ti/templates/defaults/Readme.mkd.erb +1 -0
- data/lib/ti/templates/{config → defaults/config.erb} +1 -1
- data/lib/ti/templates/gitignore +1 -1
- data/lib/ti/templates/specs/app_spec.coffee +2 -2
- data/lib/ti/utils.rb +70 -41
- data/lib/ti/version.rb +3 -0
- data/spec/cli/command_spec.rb +7 -11
- data/spec/fixtures/configs/tiapp.xml +34 -0
- data/spec/lib/config_spec.rb +34 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/ti/generators/model_spec.rb +25 -0
- data/spec/ti/generators/project_spec.rb +121 -0
- data/spec/ti/generators/view_spec.rb +25 -0
- data/spec/ti/logger_spec.rb +25 -0
- data/spec/ti/utils_spec.rb +120 -0
- data/ti.gemspec +32 -103
- metadata +75 -47
- data/VERSION +0 -1
- data/lib/ti/options.rb +0 -64
- data/lib/ti/parse_options.rb +0 -48
- data/lib/ti/templates/readme +0 -1
data/lib/ti/generate/project.rb
CHANGED
@@ -3,7 +3,7 @@ module Ti
|
|
3
3
|
class Project
|
4
4
|
class << self
|
5
5
|
attr_accessor :project_name, :device_platform, :app_id
|
6
|
-
include Utils
|
6
|
+
include ::Ti::Utils
|
7
7
|
|
8
8
|
# Ti::Generate::Project.create('demo', 'org.codewranglers.demo', 'ipad')
|
9
9
|
def create(name, id, platform='iphone')
|
@@ -26,32 +26,68 @@ module Ti
|
|
26
26
|
FileUtils.cp(location.join("Resources/KS_nav_ui.png"), "/tmp/")
|
27
27
|
FileUtils.cp(location.join("Resources/KS_nav_views.png"), "/tmp/")
|
28
28
|
end
|
29
|
+
|
30
|
+
|
31
|
+
def create_config_from_templates(project_name)
|
32
|
+
eruby = Erubis::Eruby.new( File.read(templates("defaults/config.erb")) )
|
33
|
+
File.open(location.join("config/config.rb"), 'w') do |f|
|
34
|
+
f.write(eruby.result(:project_name => project_name))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def create_defaults_with_template(name, contents={})
|
39
|
+
template = templates("defaults/#{name}.erb")
|
40
|
+
eruby = Erubis::Eruby.new(File.read(template))
|
29
41
|
|
42
|
+
File.open(location.join(name), 'w') do |f|
|
43
|
+
f.write(eruby.result(contents))
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
def create_rakefile_from_template(project_name)
|
49
|
+
eruby = Erubis::Eruby.new( File.read(templates("defaults/Rakefile.erb")) )
|
50
|
+
File.open(location.join("Rakefile"), 'w') do |f|
|
51
|
+
f.write( eruby.result({
|
52
|
+
:app_name => project_name,
|
53
|
+
:app_name_underscore => underscore(project_name)
|
54
|
+
}))
|
55
|
+
end
|
56
|
+
end
|
30
57
|
|
31
58
|
def generate_files
|
32
59
|
create_project_directory
|
33
60
|
touch('Readme.mkd')
|
34
61
|
# touch('specs/spec_helper.coffee') # TODO: Necessary? If so, what is in it?
|
35
62
|
|
36
|
-
create_new_file("app/app.coffee",
|
37
|
-
create_new_file(".gitignore",
|
38
|
-
create_new_file("
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
63
|
+
create_new_file("app/app.coffee", templates('app/app.coffee'))
|
64
|
+
create_new_file(".gitignore", templates('gitignore'))
|
65
|
+
create_new_file("spec/app_spec.coffee", templates('specs/app_spec.coffee'))
|
66
|
+
|
67
|
+
|
68
|
+
# TODO: these can be refactored
|
69
|
+
create_config_from_templates(@project_name)
|
70
|
+
create_defaults_with_template("Rakefile", {:app_name => @project_name, :app_name_underscore => underscore(@project_name)})
|
71
|
+
create_defaults_with_template("Readme.mkd", {:app_name => @project_name})
|
72
|
+
create_defaults_with_template("Guardfile", {:app_name => underscore(@project_name)})
|
73
|
+
|
74
|
+
|
75
|
+
|
43
76
|
|
44
77
|
# load default images
|
45
78
|
FileUtils.cp("/tmp/KS_nav_ui.png", location.join("Resources/images/"))
|
46
79
|
FileUtils.cp("/tmp/KS_nav_views.png", location.join("Resources/images/"))
|
47
80
|
end
|
48
81
|
|
82
|
+
|
49
83
|
def create_project_directory
|
50
84
|
create_directories('Resources', 'Resources/images', 'Resources/vendor',
|
51
85
|
'config',
|
52
86
|
'docs',
|
53
|
-
|
54
|
-
|
87
|
+
"app/#{underscore(@project_name)}/models",
|
88
|
+
"app/#{underscore(@project_name)}/views",
|
89
|
+
"app/#{underscore(@project_name)}/stylesheets",
|
90
|
+
'spec/models', 'spec/views')
|
55
91
|
end
|
56
92
|
|
57
93
|
def remove_old_files
|
@@ -63,12 +99,22 @@ module Ti
|
|
63
99
|
base_location.join(@project_name)
|
64
100
|
end
|
65
101
|
|
66
|
-
|
102
|
+
|
67
103
|
def generate_titanium_project
|
68
|
-
|
104
|
+
titanium_platform = case ::Config::CONFIG['host_os']
|
105
|
+
when /linux/i
|
106
|
+
::Ti::LINUX_TITANIUM
|
107
|
+
when /darwin/i
|
108
|
+
File.exists?(::Ti::OSX_TITANIUM.gsub('\\', '')) ? ::Ti::OSX_TITANIUM : ::Ti::OSX_TITANIUM_HOME
|
109
|
+
else
|
110
|
+
error("Currently, your OS (#{::Config::CONFIG['host_os']}) is not supported.")
|
111
|
+
exit(0)
|
112
|
+
end
|
113
|
+
|
114
|
+
"#{titanium_platform} create --name=#{@project_name} --platform=#{@device_platform} --id=#{@app_id}"
|
69
115
|
end
|
70
116
|
|
71
117
|
end
|
72
118
|
end
|
73
119
|
end
|
74
|
-
end
|
120
|
+
end
|
data/lib/ti/generate/view.rb
CHANGED
@@ -2,18 +2,39 @@ module Ti
|
|
2
2
|
module Generate
|
3
3
|
class View
|
4
4
|
class << self
|
5
|
-
include Utils
|
6
|
-
|
7
|
-
def create(name,
|
8
|
-
|
9
|
-
create_new_file("specs/views/#{name}_spec.coffee", File.read(::Ti::ROOT_PATH.join("ti/templates/specs/app_spec.coffee")))
|
5
|
+
include ::Ti::Utils
|
6
|
+
|
7
|
+
def create(name, context={})
|
8
|
+
create_view_template(name, context)
|
10
9
|
end
|
11
10
|
|
12
|
-
|
13
|
-
|
11
|
+
|
12
|
+
def create_view_template(name, context)
|
13
|
+
log "Creating #{name} view using a template."
|
14
|
+
view_directory = "app/#{underscore(get_app_name)}/views"
|
15
|
+
|
16
|
+
case context[:ti_type]
|
17
|
+
when 'window'
|
18
|
+
template = templates("app/views/window.erb")
|
19
|
+
when 'tabgroup'
|
20
|
+
template = templates("app/views/tabgroup.erb")
|
21
|
+
else
|
22
|
+
template = templates("app/views/view.erb")
|
23
|
+
end
|
24
|
+
|
25
|
+
payload = Pathname.new("#{view_directory}/#{context[:domain].downcase}")
|
26
|
+
contents = Erubis::Eruby.new(File.read(template)).result(context) if template
|
27
|
+
|
28
|
+
create_directories(payload) unless File.directory?(payload)
|
29
|
+
create_directories("spec/views") unless File.directory?("spec/views")
|
30
|
+
|
31
|
+
filename = payload.join("#{name.downcase}.coffee")
|
32
|
+
File.open(location.join(filename), 'w') { |f| f.write(contents) }
|
33
|
+
|
34
|
+
create_new_file("spec/views/#{name}_spec.coffee", templates("specs/app_spec.coffee"))
|
14
35
|
end
|
15
|
-
|
36
|
+
|
16
37
|
end
|
17
38
|
end
|
18
39
|
end
|
19
|
-
end
|
40
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
@@ -7,9 +7,9 @@ end
|
|
7
7
|
|
8
8
|
group 'coffee' do
|
9
9
|
guard 'shell' do
|
10
|
-
watch(%r{
|
10
|
+
watch(%r{app/(.+\.coffee)}) do
|
11
11
|
puts 'compiling coffeescript'
|
12
|
-
`coffee -p --bare src > Resources
|
12
|
+
`coffee -p --bare src > Resources/<%= app_name %>.js`
|
13
13
|
end
|
14
14
|
end
|
15
|
-
end
|
15
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'nokogiri'
|
3
|
+
require 'colored'
|
4
|
+
require 'betabuilder'
|
5
|
+
|
6
|
+
PROJECT_NAME = "<%= app_name %>"
|
7
|
+
PROJECT_ROOT = File.dirname(__FILE__)
|
8
|
+
|
9
|
+
IPHONE_SDK_VERSION = "4.3"
|
10
|
+
TI_SDK_VERSION = "1.6.2"
|
11
|
+
TI_DIR = '/Library/Application\ Support/Titanium'
|
12
|
+
TI_ASSET_DIR = "#{TI_DIR}/mobilesdk/osx/#{TI_SDK_VERSION}"
|
13
|
+
TI_IPHONE_DIR = "#{TI_ASSET_DIR}/iphone"
|
14
|
+
TI_BUILD = "#{TI_IPHONE_DIR}/builder.py"
|
15
|
+
APP_DEVICE = "iphone"
|
16
|
+
|
17
|
+
# Get APP parameters from current tiapp.xml
|
18
|
+
config = File.open("tiapp.xml")
|
19
|
+
doc = Nokogiri::XML(config)
|
20
|
+
config.close
|
21
|
+
APP_ID = doc.xpath('ti:app/id').text
|
22
|
+
APP_NAME = doc.xpath('ti:app/name').text
|
23
|
+
|
24
|
+
BetaBuilder::Tasks.new do |config|
|
25
|
+
# App Name
|
26
|
+
config.target = "<%= app_name %>"
|
27
|
+
|
28
|
+
# Xcode configuration profile
|
29
|
+
config.configuration = "Adhoc"
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
task :default => ["build:iphone"]
|
34
|
+
|
35
|
+
namespace :setup do
|
36
|
+
desc "Do all the setup procedures"
|
37
|
+
task :all do
|
38
|
+
Rake::Task['setup:xml'].invoke
|
39
|
+
Rake::Task['setup:entitlements'].invoke
|
40
|
+
Rake::Task['setup:rakefile'].invoke
|
41
|
+
end
|
42
|
+
|
43
|
+
desc "Copy the tiapp.xml file into build/iphone directory"
|
44
|
+
task :xml do
|
45
|
+
copy_xml
|
46
|
+
end
|
47
|
+
|
48
|
+
desc "Create the Entitlements.plist file in build/iphone directory"
|
49
|
+
task :entitlements do
|
50
|
+
create_entitlement_plist
|
51
|
+
end
|
52
|
+
|
53
|
+
desc "Copy the Rakefile to the build/iphone directory"
|
54
|
+
task :rakefile do
|
55
|
+
copy_rakefile
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
namespace :compile do
|
60
|
+
desc "Compile all assets"
|
61
|
+
task :all do
|
62
|
+
compile
|
63
|
+
end
|
64
|
+
|
65
|
+
desc "Compile SASS to JSS"
|
66
|
+
task :styles do
|
67
|
+
compile_sass
|
68
|
+
end
|
69
|
+
|
70
|
+
desc "Compile CoffeeScript into JS"
|
71
|
+
task :coffee do
|
72
|
+
compile_coffee
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
namespace :build do
|
77
|
+
desc "Build the app for iPhone"
|
78
|
+
task :iphone do
|
79
|
+
build
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def compile
|
84
|
+
compile_coffee && compile_sass
|
85
|
+
end
|
86
|
+
|
87
|
+
def copy_xml
|
88
|
+
unless File.exists?(File.join(Dir.pwd, 'build/iphone/tiapp.xml'))
|
89
|
+
puts "Copying tiapp.xml to the build/iphone/ directory.".blue
|
90
|
+
system("ln -s #{File.join(Dir.pwd, 'tiapp.xml')} #{File.join(Dir.pwd, 'build/iphone')}")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def create_entitlement_plist
|
95
|
+
entitlements = File.join(Dir.pwd, 'build/iphone/Entitlements.plist')
|
96
|
+
unless File.exists?(entitlements)
|
97
|
+
puts "Creating an Entitlements.plist (build/iphone) file since it doesn't exist.".blue
|
98
|
+
File.open(entitlements, 'w') do |f|
|
99
|
+
f.puts <<-LINE
|
100
|
+
<?xml versio="1.0" encoding="UTF-8"?>
|
101
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
102
|
+
<plist version="1.0">
|
103
|
+
<dict>
|
104
|
+
<key>get-task-allow</key>
|
105
|
+
<false/>
|
106
|
+
</dict>
|
107
|
+
</plist>
|
108
|
+
LINE
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def copy_rakefile
|
114
|
+
unless File.exists?(File.join(Dir.pwd, 'build/iphone/Rakefile'))
|
115
|
+
puts "Copying Rakefile to the buil/iphone directory.".blue
|
116
|
+
system("ln -s #{File.join(Dir.pwd, 'Rakefile')} #{File.join(Dir.pwd, 'build/iphone')}")
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def compile_sass
|
121
|
+
puts "Compiling stylesheets".blue
|
122
|
+
compilation = system "sass --compass -C -t expand app/<%= app_name_underscore %>/stylesheets/app.sass > Resources/app.jss"
|
123
|
+
end
|
124
|
+
|
125
|
+
def compile_coffee
|
126
|
+
puts "Compiling CoffeeScript".blue
|
127
|
+
paths = `find app/<%= app_name_underscore %> -name '*.coffee'`.split("\n")
|
128
|
+
compilation = (
|
129
|
+
system "coffee -p --join --bare #{paths.join(' ')} > Resources/<%= app_name_underscore%>.js" and
|
130
|
+
system "coffee -p --bare app/app.coffee > Resources/app.js"
|
131
|
+
)
|
132
|
+
|
133
|
+
if compilation
|
134
|
+
puts "Successfully compiled CoffeeScript".green
|
135
|
+
else
|
136
|
+
puts "Error compiling CoffeeScript".red
|
137
|
+
end
|
138
|
+
|
139
|
+
compilation
|
140
|
+
end
|
141
|
+
|
142
|
+
def build(options={})
|
143
|
+
return unless compile
|
144
|
+
options[:device] ||= 'iphone'
|
145
|
+
puts "Building with Titanium... (DEVICE_TYPE: #{options[:device]})".blue
|
146
|
+
sh %Q{bash -c "#{TI_BUILD} run #{PROJECT_ROOT}/ #{IPHONE_SDK_VERSION} #{APP_ID} #{APP_NAME} #{APP_DEVICE} " \
|
147
|
+
| perl -pe 's/^\\[DEBUG\\].*$/\\e[35m$&\\e[0m/g;s/^\\[INFO\\].*$/\\e[36m$&\\e[0m/g;s/^\\[WARN\\].*$/\\e[33m$&\\e[0m/g;s/^\\[ERROR\\].*$/\\e[31m$&\\e[0m/g;'}
|
148
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
# <%= app_name %> - Generated by Ti
|
data/lib/ti/templates/gitignore
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
describe 'Jasmine', ->
|
2
|
-
it 'should require
|
3
|
-
expect(yourCode).toBeLotsBetter()
|
2
|
+
it 'should require you to write your tests', ->
|
3
|
+
expect(yourCode).toBeLotsBetter()
|
data/lib/ti/utils.rb
CHANGED
@@ -1,48 +1,77 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
filenames.each do |filename|
|
9
|
-
log "Creating #{filename} file."
|
10
|
-
FileUtils.touch(location.join(filename))
|
1
|
+
module Ti
|
2
|
+
module Utils
|
3
|
+
|
4
|
+
def create_new_file(name, file=nil)
|
5
|
+
log "Creating #{name}"
|
6
|
+
contents = file.nil? ? '' : File.read(file)
|
7
|
+
File.open(location.join(name), 'w') { |f| f.write(contents) }
|
11
8
|
end
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
9
|
+
|
10
|
+
def get_app_name
|
11
|
+
config = File.open("tiapp.xml")
|
12
|
+
doc = ::Nokogiri::XML(config)
|
13
|
+
config.close
|
14
|
+
doc.xpath('ti:app/name').text
|
18
15
|
end
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
FileUtils.rm_rf(location.join(name))
|
16
|
+
|
17
|
+
def remove_files(*files)
|
18
|
+
files.each do |file|
|
19
|
+
log "Removing #{file} file."
|
20
|
+
FileUtils.rm(location.join(file))
|
21
|
+
end
|
26
22
|
end
|
27
|
-
|
28
|
-
|
29
|
-
def remove_files(*files)
|
30
|
-
files.each do |file|
|
31
|
-
log "Removing #{file} file."
|
32
|
-
FileUtils.rm(location.join(file))
|
33
|
-
end
|
34
|
-
end
|
23
|
+
|
35
24
|
|
36
|
-
|
37
|
-
|
38
|
-
|
25
|
+
def touch(*filenames)
|
26
|
+
filenames.each do |filename|
|
27
|
+
log "Creating #{filename} file."
|
28
|
+
FileUtils.touch(location.join(filename))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
39
32
|
|
40
|
-
|
41
|
-
|
42
|
-
|
33
|
+
def create_directories(*dirs)
|
34
|
+
dirs.each do |dir|
|
35
|
+
log "Creating the #{dir} directory."
|
36
|
+
FileUtils.mkdir_p(location.join(dir))
|
37
|
+
end
|
38
|
+
end
|
43
39
|
|
44
|
-
|
45
|
-
|
40
|
+
|
41
|
+
def remove_directories(*names)
|
42
|
+
names.each do |name|
|
43
|
+
log "Removing #{name} directory."
|
44
|
+
FileUtils.rm_rf(location.join(name))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
def templates(path)
|
50
|
+
::Ti::ROOT_PATH.join('ti/templates').join(path)
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
def log(msg)
|
55
|
+
::Ti::Logger.report(msg)
|
56
|
+
end
|
57
|
+
|
58
|
+
def error(msg)
|
59
|
+
::Ti::Logger.error(msg)
|
60
|
+
end
|
61
|
+
|
62
|
+
def base_location
|
63
|
+
@location ||= Pathname.new(Dir.pwd)
|
64
|
+
end
|
65
|
+
alias_method :location, :base_location
|
66
|
+
|
67
|
+
|
68
|
+
def underscore(string)
|
69
|
+
string.gsub(/::/, '/').
|
70
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
71
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
72
|
+
tr("-", "_").
|
73
|
+
downcase
|
74
|
+
end
|
75
|
+
|
46
76
|
end
|
47
|
-
|
48
|
-
end
|
77
|
+
end
|