rucola 0.0.1
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/ChangeLog +628 -0
- data/History.txt +4 -0
- data/License.txt +20 -0
- data/Manifest.txt +106 -0
- data/README.txt +126 -0
- data/Rakefile +32 -0
- data/TODO +28 -0
- data/app_generators/rucola/USAGE +6 -0
- data/app_generators/rucola/rucola_generator.rb +112 -0
- data/app_generators/rucola/templates/Rakefile.erb +12 -0
- data/app_generators/rucola/templates/Rakefile.erb.old +156 -0
- data/app_generators/rucola/templates/app/controllers/application_controller.rb +22 -0
- data/app_generators/rucola/templates/config/Info.plist.erb +28 -0
- data/app_generators/rucola/templates/config/boot.rb +2 -0
- data/app_generators/rucola/templates/config/environment.rb +11 -0
- data/app_generators/rucola/templates/config/environments/debug.rb +3 -0
- data/app_generators/rucola/templates/config/environments/release.rb +3 -0
- data/app_generators/rucola/templates/config/environments/test.rb +3 -0
- data/app_generators/rucola/templates/config/ib_external_class_defs.yml +13 -0
- data/app_generators/rucola/templates/misc/English.lproj/InfoPlist.strings.erb +3 -0
- data/app_generators/rucola/templates/misc/English.lproj/MainMenu.nib/classes.nib +40 -0
- data/app_generators/rucola/templates/misc/English.lproj/MainMenu.nib/info.nib +18 -0
- data/app_generators/rucola/templates/misc/English.lproj/MainMenu.nib/keyedobjects.nib +0 -0
- data/app_generators/rucola/templates/misc/main.m.erb +15 -0
- data/app_generators/rucola/templates/misc/rb_main.rb.erb +13 -0
- data/app_generators/rucola/templates/project.pbxproj.erb +299 -0
- data/app_generators/rucola/templates/script/plugin +84 -0
- data/app_generators/rucola/templates/test/controllers/test_application_controller.rb +10 -0
- data/app_generators/rucola/templates/test/test_helper.rb +10 -0
- data/bin/rucola +12 -0
- data/config/hoe.rb +71 -0
- data/config/requirements.rb +17 -0
- data/lib/rucola.rb +3 -0
- data/lib/rucola/info_plist.rb +37 -0
- data/lib/rucola/initializer.rb +313 -0
- data/lib/rucola/nib.rb +99 -0
- data/lib/rucola/rucola_support.rb +9 -0
- data/lib/rucola/rucola_support/controllers.rb +2 -0
- data/lib/rucola/rucola_support/controllers/rc_controller.rb +7 -0
- data/lib/rucola/rucola_support/controllers/rc_window_controller.rb +12 -0
- data/lib/rucola/rucola_support/core_ext.rb +2 -0
- data/lib/rucola/rucola_support/core_ext/objc.rb +4 -0
- data/lib/rucola/rucola_support/core_ext/objc/nsobject.rb +22 -0
- data/lib/rucola/rucola_support/core_ext/ruby.rb +4 -0
- data/lib/rucola/rucola_support/core_ext/ruby/string.rb +21 -0
- data/lib/rucola/rucola_support/initialize_hooks.rb +21 -0
- data/lib/rucola/rucola_support/models.rb +1 -0
- data/lib/rucola/rucola_support/models/rc_document.rb +10 -0
- data/lib/rucola/rucola_support/notifications.rb +1 -0
- data/lib/rucola/rucola_support/notifications/notifications.rb +146 -0
- data/lib/rucola/rucola_support/rc_app.rb +101 -0
- data/lib/rucola/tasks/freeze.rake +44 -0
- data/lib/rucola/tasks/interface_builder.rake +80 -0
- data/lib/rucola/tasks/main.rake +29 -0
- data/lib/rucola/tasks/xcode.rake +43 -0
- data/lib/rucola/test_helper.rb +57 -0
- data/lib/rucola/version.rb +9 -0
- data/lib/rucola/xcode.rb +148 -0
- data/log/debug.log +0 -0
- data/rucola_generators/controller/USAGE +5 -0
- data/rucola_generators/controller/controller_generator.rb +84 -0
- data/rucola_generators/controller/templates/controller_template.rb.erb +5 -0
- data/rucola_generators/controller/templates/test_controller_template.rb.erb +10 -0
- data/rucola_generators/document_model/USAGE +5 -0
- data/rucola_generators/document_model/document_model_generator.rb +67 -0
- data/rucola_generators/document_model/templates/document_model_template.rb.erb +27 -0
- data/rucola_generators/document_model/templates/test_document_model_template.rb.erb +10 -0
- data/rucola_generators/window_controller/USAGE +6 -0
- data/rucola_generators/window_controller/templates/Window.nib/classes.nib.erb +35 -0
- data/rucola_generators/window_controller/templates/Window.nib/info.nib +16 -0
- data/rucola_generators/window_controller/templates/Window.nib/keyedobjects.nib +0 -0
- data/rucola_generators/window_controller/templates/test_window_controller_template.rb.erb +10 -0
- data/rucola_generators/window_controller/templates/window_controller_template.rb.erb +19 -0
- data/rucola_generators/window_controller/window_controller_generator.rb +74 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +74 -0
- data/setup.rb +1585 -0
- data/tasks/deployment.rake +27 -0
- data/tasks/environment.rake +7 -0
- data/tasks/website.rake +17 -0
- data/test/fixtures/Info.plist +28 -0
- data/test/fixtures/MainMenu.nib/classes.nib +32 -0
- data/test/fixtures/MainMenu.nib/info.nib +18 -0
- data/test/fixtures/MainMenu.nib/keyedobjects.nib +0 -0
- data/test/test_controller_generator.rb +75 -0
- data/test/test_core_ext.rb +15 -0
- data/test/test_document_model_generator.rb +64 -0
- data/test/test_generator_helper.rb +20 -0
- data/test/test_helper.rb +13 -0
- data/test/test_info_plist.rb +31 -0
- data/test/test_nib.rb +73 -0
- data/test/test_notifications.rb +75 -0
- data/test/test_objc_core_ext.rb +37 -0
- data/test/test_rc_app.rb +63 -0
- data/test/test_rc_document.rb +18 -0
- data/test/test_rc_window_controller.rb +13 -0
- data/test/test_rucola.rb +11 -0
- data/test/test_rucola_generator.rb +87 -0
- data/test/test_window_controller_generator.rb +50 -0
- data/test/test_xcode.rb +128 -0
- data/website/index.html +199 -0
- data/website/index.txt +126 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +138 -0
- data/website/template.rhtml +48 -0
- metadata +189 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
namespace :rc do
|
|
2
|
+
|
|
3
|
+
namespace :freeze do
|
|
4
|
+
|
|
5
|
+
RUBYCOCOA_FRAMEWORK_PATH_CURRENT = 'vendor/rubycocoa'
|
|
6
|
+
desc "Freezes the current used version of RubyCocoa in #{RUBYCOCOA_FRAMEWORK}"
|
|
7
|
+
task :current do
|
|
8
|
+
mkdir_p RUBYCOCOA_FRAMEWORK_PATH_CURRENT unless File.exist? RUBYCOCOA_FRAMEWORK_PATH_CURRENT
|
|
9
|
+
puts "Copying framework."
|
|
10
|
+
cp_r RUBYCOCOA_FRAMEWORK, RUBYCOCOA_FRAMEWORK_PATH_CURRENT
|
|
11
|
+
# add the new RubyCocoa framework to the project and bundle it when building the application
|
|
12
|
+
Rake::Task['rc:freeze:bundle'].invoke
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
RUBYCOCOA_FRAMEWORK_PATH_EDGE = 'vendor/rubycocoa/framework/build/Default'
|
|
16
|
+
desc 'Freezes the current edge version of RubyCocoa'
|
|
17
|
+
task :edge do
|
|
18
|
+
if File.exist? 'vendor/rubycocoa'
|
|
19
|
+
sh 'cd vendor/rubycocoa && svn up'
|
|
20
|
+
else
|
|
21
|
+
mkdir 'vendor' unless File.exist? 'vendor'
|
|
22
|
+
sh 'cd vendor && svn co https://rubycocoa.svn.sourceforge.net/svnroot/rubycocoa/trunk/src rubycocoa'
|
|
23
|
+
end
|
|
24
|
+
sh 'cd vendor/rubycocoa && rake'
|
|
25
|
+
|
|
26
|
+
# add the new RubyCocoa framework to the project and bundle it when building the application
|
|
27
|
+
Rake::Task['rc:freeze:bundle'].invoke
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
desc 'Bundle the frozen RubyCocoa framework with the application'
|
|
31
|
+
task :bundle do
|
|
32
|
+
if File.exist? RUBYCOCOA_FRAMEWORK_PATH_EDGE
|
|
33
|
+
framework_location = RUBYCOCOA_FRAMEWORK_PATH_EDGE
|
|
34
|
+
else
|
|
35
|
+
framework_location = RUBYCOCOA_FRAMEWORK_PATH_CURRENT
|
|
36
|
+
end
|
|
37
|
+
project = Rucola::Xcode.new File.join(SOURCE_ROOT, "#{APPNAME}.xcodeproj")
|
|
38
|
+
project.change_rubycocoa_framework_location "#{framework_location}/RubyCocoa.framework"
|
|
39
|
+
project.bundle_rubycocoa_framework
|
|
40
|
+
project.save
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
|
|
3
|
+
namespace :ib do
|
|
4
|
+
RB_NIB_TOOL = "#{RUBYCOCOA_FRAMEWORK}/Versions/Current/Tools/rb_nibtool.rb"
|
|
5
|
+
|
|
6
|
+
def helper_file
|
|
7
|
+
"/tmp/#{APPNAME}_helper.rb.tmp"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def create_tmp_helper_file
|
|
11
|
+
# get all the Rucola controller class definition files
|
|
12
|
+
class_defs = FileList["#{File.expand_path('../../rucola_support/controllers', __FILE__)}/*.rb"]
|
|
13
|
+
|
|
14
|
+
# get the optional ib_external_class_defs.yml file in which a user can specify any other
|
|
15
|
+
# classes that might need to be incuded for IB to recognize them.
|
|
16
|
+
user_class_def_string = ''
|
|
17
|
+
user_class_def_file = File.join(SOURCE_ROOT, 'config/ib_external_class_defs.yml')
|
|
18
|
+
user_class_defs = YAML.load_file(user_class_def_file)
|
|
19
|
+
if user_class_defs
|
|
20
|
+
user_class_def_string = create_class_stubs(user_class_defs)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# write the Rucola controllers and the optional ib_external_class_defs.yml to a tmp file
|
|
24
|
+
File.open(helper_file, 'w') do |file|
|
|
25
|
+
file.write class_defs.map{ |class_def| File.read(class_def) }.join("\n\n") << user_class_def_string
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def create_class_stubs(klasses, prev_super = '')
|
|
30
|
+
class_defs = ''
|
|
31
|
+
klasses.each do |klass, subklass|
|
|
32
|
+
unless prev_super == ''
|
|
33
|
+
class_defs += "class #{klass} < #{prev_super}; end\n"
|
|
34
|
+
end
|
|
35
|
+
if subklass.is_a?(Array)
|
|
36
|
+
subklass.each do |sub|
|
|
37
|
+
if sub.is_a?(Hash)
|
|
38
|
+
create_class_stubs(sub, klass)
|
|
39
|
+
else
|
|
40
|
+
class_defs += "class #{sub} < #{klass}; end\n"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
return class_defs
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def create_tmp_controller_file(controller_name)
|
|
49
|
+
tmp_file = "/tmp/#{controller_name.snake_case}.rb.tmp"
|
|
50
|
+
File.open(tmp_file, 'w') do |file|
|
|
51
|
+
file.write( File.read(helper_file) + "\n\n" + File.read("app/controllers/#{controller_name.snake_case}.rb") )
|
|
52
|
+
end
|
|
53
|
+
tmp_file
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def name_for_controller(controller_path)
|
|
57
|
+
File.basename(controller_path)[0..-4].camel_case
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
desc 'Updates the nibs from their corresponding ruby source files'
|
|
61
|
+
task :update do
|
|
62
|
+
create_tmp_helper_file
|
|
63
|
+
|
|
64
|
+
controllers = FileList["#{SOURCE_ROOT}/app/controllers/*.rb"]
|
|
65
|
+
nibs = FileList["#{SOURCE_ROOT}/app/views/*.nib", "#{SOURCE_ROOT}/misc/English.lproj/MainMenu.nib"].reject {|file| File.extname(file) != '.nib' or file.include? '~' }
|
|
66
|
+
|
|
67
|
+
controllers.each do |controller_path|
|
|
68
|
+
controller_name = name_for_controller(controller_path)
|
|
69
|
+
nibs.each do |nib|
|
|
70
|
+
if Rucola::Nib::Classes.open("#{nib}/classes.nib").has_class? controller_name
|
|
71
|
+
@tmp_file ||= create_tmp_controller_file(controller_name)
|
|
72
|
+
puts " update #{nib[(SOURCE_ROOT.length + 1)..-1]}: #{controller_name}"
|
|
73
|
+
`ruby #{RB_NIB_TOOL} --update --nib #{nib} --file #{@tmp_file}`
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
@tmp_file = nil
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'rake/testtask'
|
|
2
|
+
|
|
3
|
+
require 'osx/cocoa'
|
|
4
|
+
require 'rucola/xcode'
|
|
5
|
+
require 'rucola/nib'
|
|
6
|
+
require 'rucola/rucola_support'
|
|
7
|
+
|
|
8
|
+
# set the env, default to debug if we are running a rake task.
|
|
9
|
+
RUBYCOCOA_ENV = ENV['RUBYCOCOA_ENV'].nil? ? 'debug' : ENV['RUBYCOCOA_ENV']
|
|
10
|
+
RUBYCOCOA_ROOT = ENV['RUBYCOCOA_ROOT'].nil? ? SOURCE_ROOT : ENV['RUBYCOCOA_ROOT']
|
|
11
|
+
puts "RUNNING IN MODE: #{RUBYCOCOA_ENV.upcase}\n\n"
|
|
12
|
+
|
|
13
|
+
# FIXME: We also need to check if the user uses a frozen rc framework
|
|
14
|
+
RUBYCOCOA_FRAMEWORK = OSX::NSBundle.bundleWithIdentifier('com.apple.rubycocoa').bundlePath.to_s
|
|
15
|
+
|
|
16
|
+
# TASKS
|
|
17
|
+
|
|
18
|
+
# Get all the tasks
|
|
19
|
+
Dir["#{File.dirname(__FILE__)}/*.rake"].each {|file| load file unless File.basename(file) == 'main.rake' }
|
|
20
|
+
|
|
21
|
+
task :default => 'xcode:build'
|
|
22
|
+
|
|
23
|
+
desc 'Runs all the clean tasks'
|
|
24
|
+
task :clean => 'xcode:clean'
|
|
25
|
+
|
|
26
|
+
Rake::TestTask.new do |t|
|
|
27
|
+
t.test_files = FileList['test/*/test_*.rb']
|
|
28
|
+
t.verbose = true
|
|
29
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
namespace :xcode do
|
|
2
|
+
|
|
3
|
+
def config
|
|
4
|
+
RUBYCOCOA_ENV.capitalize
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def build_dir
|
|
8
|
+
# get the users build dir
|
|
9
|
+
prefs = OSX::NSUserDefaults.standardUserDefaults
|
|
10
|
+
prefs.addSuiteNamed 'com.apple.xcode'
|
|
11
|
+
prefs['PBXApplicationwideBuildSettings']['SYMROOT'] || './build'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def build_root
|
|
15
|
+
File.expand_path("#{build_dir}/#{config}/#{TARGET}")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
desc 'Builds the application'
|
|
19
|
+
task :build do
|
|
20
|
+
executable = "#{build_root}/Contents/MacOS/#{APPNAME}"
|
|
21
|
+
|
|
22
|
+
unless File.exists?(executable)
|
|
23
|
+
sh "xcodebuild -configuration #{config}"
|
|
24
|
+
else
|
|
25
|
+
puts "Build already exists, skipping. (Use clean if you really really want a new build.)\n\n"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Make sure the app is brought to the front once launched.
|
|
29
|
+
Thread.new do
|
|
30
|
+
sleep 0.025 until OSX::NSWorkspace.sharedWorkspace.launchedApplications.any? {|dict| dict['NSApplicationName'] == APPNAME }
|
|
31
|
+
`osascript -e 'tell application "#{executable}" to activate'`
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# launch app with the correct env set
|
|
35
|
+
sh "RUBYCOCOA_ENV='#{RUBYCOCOA_ENV}' RUBYCOCOA_ROOT='#{RUBYCOCOA_ROOT}' #{executable}"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
desc 'Removes the build'
|
|
39
|
+
task :clean do
|
|
40
|
+
puts "Removing #{build_root}"
|
|
41
|
+
FileUtils.rm_rf build_root
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require 'osx/cocoa'
|
|
2
|
+
|
|
3
|
+
module OSX
|
|
4
|
+
# Allows methods to be overriden with a different arity.
|
|
5
|
+
#
|
|
6
|
+
# TODO: Check with Laurent if this is bad?
|
|
7
|
+
# Otherwise we should maybe override the stub method to set this to true
|
|
8
|
+
# when the object is a subclass of OSX::NSObject and set it to false again after the stubbing.
|
|
9
|
+
def self._ignore_ns_override; true; end
|
|
10
|
+
|
|
11
|
+
class NSObject
|
|
12
|
+
# A Mocha helper method which allows to stub alloc.init and return a mock.
|
|
13
|
+
#
|
|
14
|
+
# it "should init and return an instance" do
|
|
15
|
+
# obj_mock = mock("NSObject mock")
|
|
16
|
+
# OSX::NSObject.expects_alloc_init_returns(obj_mock) # performs 2 assertions
|
|
17
|
+
# OSX::NSObject.alloc.init.should == obj_mock
|
|
18
|
+
# end
|
|
19
|
+
#
|
|
20
|
+
# Results in:
|
|
21
|
+
# 1 tests, 3 assertions, 0 failures, 0 errors
|
|
22
|
+
def self.expects_alloc_init_returns(mock)
|
|
23
|
+
mock.expects(:init).returns(mock)
|
|
24
|
+
self.expects(:alloc).returns(mock)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# A Mocha helper method which allocs an instance, yields it and then calls init.
|
|
28
|
+
#
|
|
29
|
+
# class Monkey < OSX::NSObject
|
|
30
|
+
# def init
|
|
31
|
+
# if super_init
|
|
32
|
+
# self.foo
|
|
33
|
+
# self.bar
|
|
34
|
+
# return self
|
|
35
|
+
# end
|
|
36
|
+
# end
|
|
37
|
+
# end
|
|
38
|
+
#
|
|
39
|
+
# it "should alloc, yield and return an instance" do
|
|
40
|
+
# obj = OSX::Monkey.during_init do |instance|
|
|
41
|
+
# instance.expects(:foo)
|
|
42
|
+
# instance.expects(:bar)
|
|
43
|
+
# end
|
|
44
|
+
# p obj # => #<Monkey:0x1a7566 class='Monkey' id=0x1b30a70>
|
|
45
|
+
# end
|
|
46
|
+
#
|
|
47
|
+
# Results in:
|
|
48
|
+
# 1 tests, 2 assertions, 0 failures, 0 errors
|
|
49
|
+
def self.during_init(&block)
|
|
50
|
+
obj = self.alloc
|
|
51
|
+
yield obj
|
|
52
|
+
res = obj.init
|
|
53
|
+
warn " warning: #{self.class.name}#init did not return an instance." if res.nil?
|
|
54
|
+
res
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
data/lib/rucola/xcode.rb
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
require 'osx/cocoa'
|
|
2
|
+
require 'pathname'
|
|
3
|
+
|
|
4
|
+
module Rucola
|
|
5
|
+
class Xcode
|
|
6
|
+
# FIXME: We should probably generate random id keys!
|
|
7
|
+
|
|
8
|
+
attr_reader :project
|
|
9
|
+
attr_reader :project_path
|
|
10
|
+
attr_reader :project_data
|
|
11
|
+
|
|
12
|
+
def initialize(project_path)
|
|
13
|
+
@project_path = Pathname.new(project_path)
|
|
14
|
+
@project = @project_path.basename.to_s.sub(/\.xcodeproj$/, '')
|
|
15
|
+
@project_path_data = @project_path + 'project.pbxproj'
|
|
16
|
+
@project_data = OSX::NSDictionary.dictionaryWithContentsOfFile(@project_path_data.to_s)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Saves the project data atomically.
|
|
20
|
+
# Returns +false+ if it failed.
|
|
21
|
+
def save
|
|
22
|
+
# FIXME: Because we use non generated id's atm (which is bad!)
|
|
23
|
+
# we should first make a bakup of the project.
|
|
24
|
+
unless $TESTING
|
|
25
|
+
puts "\n========================================================================="
|
|
26
|
+
puts "Backing up project #{@project}.xcodeproj to /tmp/#{@project}.xcodeproj.bak"
|
|
27
|
+
puts "Please retrieve that one if for some reason the project was damaged!\n"
|
|
28
|
+
end
|
|
29
|
+
backup = "/tmp/#{@project}.xcodeproj.bak"
|
|
30
|
+
Kernel.system("rm -rf #{backup}") if File.exists?(backup)
|
|
31
|
+
Kernel.system("cp -R #{project_path} #{backup}")
|
|
32
|
+
|
|
33
|
+
# this writes the plist as a new xml style plist,
|
|
34
|
+
# but luckily xcode recognizes it as well and
|
|
35
|
+
# writes it back out as an old style plist.
|
|
36
|
+
@project_data.writeToFile_atomically(@project_path_data.to_s, true)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def nil_if_empty(result)
|
|
40
|
+
result.empty? ? nil : result
|
|
41
|
+
end
|
|
42
|
+
private :nil_if_empty
|
|
43
|
+
|
|
44
|
+
# Get's the id & values for a object which name is the one passed to this method.
|
|
45
|
+
# Returns an array: [id, values]
|
|
46
|
+
def object_for_name(name)
|
|
47
|
+
nil_if_empty @project_data['objects'].select { |object| object.last['name'] == name }.flatten
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Get's the id & values for a object which type and name is the one passed to this method.
|
|
51
|
+
# Returns an array: [id, values]
|
|
52
|
+
def object_for_type_and_name(type, name)
|
|
53
|
+
nil_if_empty @project_data['objects'].select { |object| object.last['isa'] == type and object.last['name'] == name }.flatten
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Returns the object that represents this projects target.
|
|
57
|
+
# Returns an array: [id, values]
|
|
58
|
+
def object_for_project_target
|
|
59
|
+
nil_if_empty object_for_type_and_name('PBXNativeTarget', @project)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Returns the object for a given name.
|
|
63
|
+
# Returns an array: [id, values]
|
|
64
|
+
def object_for_id(object_id)
|
|
65
|
+
@project_data['objects'][object_id].nil? ? nil : [object_id, @project_data['objects'][object_id]]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Adds an object to the objects.
|
|
69
|
+
def add_object(object_id, object_values)
|
|
70
|
+
@project_data['objects'][object_id] = object_values
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Adds a build phase specified by +object_id+ to the build phases of the project target.
|
|
74
|
+
def add_build_phase_to_project_target(object_id)
|
|
75
|
+
# Add the new build phase to the main project target if it doesn't already exist
|
|
76
|
+
build_target_id, build_target_values = object_for_project_target
|
|
77
|
+
build_target_values['buildPhases'].push(object_id) unless build_target_values['buildPhases'].include?(object_id)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def add_object_to_build_phase(object_id, build_phase_id)
|
|
81
|
+
build_phase = object_for_id(build_phase_id).last
|
|
82
|
+
build_phase['files'].push(object_id) unless build_phase['files'].include?(object_id)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
NEW_COPY_FRAMEWORKS_BUILD_PHASE = ['519A79DB0CC8AE6B00CBE85D', {
|
|
86
|
+
'name' => 'Copy Frameworks',
|
|
87
|
+
'isa' => 'PBXCopyFilesBuildPhase',
|
|
88
|
+
'buildActionMask' => '2147483647',
|
|
89
|
+
'dstPath' => '',
|
|
90
|
+
'dstSubfolderSpec' => 10, # TODO: is 10 the number for the location popup choice: Frameworks
|
|
91
|
+
'runOnlyForDeploymentPostprocessing' => 0,
|
|
92
|
+
'files' => []
|
|
93
|
+
}]
|
|
94
|
+
# Creates a new framework copy build phase.
|
|
95
|
+
# It does not add it to the objects nor the build phases,
|
|
96
|
+
# do this with +add_object+ and +add_build_phase_to_project_target+.
|
|
97
|
+
#
|
|
98
|
+
# FIXME: Need to generate the id's instead of static.
|
|
99
|
+
def new_framework_copy_build_phase
|
|
100
|
+
NEW_COPY_FRAMEWORKS_BUILD_PHASE
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Changes the path of the framework +framework_name+ to the path +new_path_to_framework+.
|
|
104
|
+
def change_framework_location(framework_name, new_path_to_framework)
|
|
105
|
+
framework_id, framework_values = object_for_name(framework_name)
|
|
106
|
+
framework_values['path'] = new_path_to_framework
|
|
107
|
+
framework_values['sourceTree'] = '<group>'
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Changes the path of the RubyCocoa framework to +new_path_to_framework+.
|
|
111
|
+
def change_rubycocoa_framework_location(new_path_to_framework)
|
|
112
|
+
change_framework_location 'RubyCocoa.framework', new_path_to_framework
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Bundles the given framework in the application.
|
|
116
|
+
def bundle_framework(framework_name)
|
|
117
|
+
framework_id, framework_values = object_for_name(framework_name)
|
|
118
|
+
|
|
119
|
+
# create a new file wrapper for in the copy build phase
|
|
120
|
+
framework_in_build_phase_id = '511E98590CC8C5940003DED9'
|
|
121
|
+
framework_in_build_phase_values = {
|
|
122
|
+
'isa' => 'PBXBuildFile',
|
|
123
|
+
'fileRef' => framework_id
|
|
124
|
+
}
|
|
125
|
+
add_object(framework_in_build_phase_id, framework_in_build_phase_values)
|
|
126
|
+
|
|
127
|
+
# get or define the Copy Frameworks build phase
|
|
128
|
+
build_phase = object_for_name('Copy Frameworks')
|
|
129
|
+
if build_phase.nil?
|
|
130
|
+
build_phase_id, build_phase_values = new_framework_copy_build_phase
|
|
131
|
+
# add the new build phase to the objects
|
|
132
|
+
add_object(build_phase_id, build_phase_values)
|
|
133
|
+
|
|
134
|
+
# add the new build phase to the project target
|
|
135
|
+
add_build_phase_to_project_target(build_phase_id)
|
|
136
|
+
else
|
|
137
|
+
build_phase_id, build_phase_values = build_phase
|
|
138
|
+
end
|
|
139
|
+
# add the framework to the build phase
|
|
140
|
+
add_object_to_build_phase(framework_in_build_phase_id, build_phase_id)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Bundles the RubyCocoa framework in the application.
|
|
144
|
+
def bundle_rubycocoa_framework
|
|
145
|
+
bundle_framework 'RubyCocoa.framework'
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
data/log/debug.log
ADDED
|
File without changes
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'rucola/rucola_support'
|
|
3
|
+
require 'rucola/nib'
|
|
4
|
+
|
|
5
|
+
class ControllerGenerator < RubiGen::Base
|
|
6
|
+
|
|
7
|
+
default_options :author => nil
|
|
8
|
+
|
|
9
|
+
attr_reader :name
|
|
10
|
+
|
|
11
|
+
def initialize(runtime_args, runtime_options = {})
|
|
12
|
+
super
|
|
13
|
+
usage if args.empty?
|
|
14
|
+
@name = args.shift
|
|
15
|
+
@nibs_to_update = args
|
|
16
|
+
extract_options
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def add_class_to_classes_nib(controller_name, nib_path)
|
|
20
|
+
nib = Rucola::Nib::Classes.open(File.expand_path(destination_path(nib_path)))
|
|
21
|
+
nib.add_class(controller_name)
|
|
22
|
+
nib.save
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def manifest
|
|
26
|
+
record do |m|
|
|
27
|
+
# Ensure appropriate folder(s) exists
|
|
28
|
+
controller_dir = 'app/controllers'
|
|
29
|
+
test_dir = 'test/controllers'
|
|
30
|
+
|
|
31
|
+
m.directory controller_dir
|
|
32
|
+
m.directory test_dir
|
|
33
|
+
|
|
34
|
+
# Create stubs
|
|
35
|
+
m.template 'controller_template.rb.erb', "#{controller_dir}/#{@name.snake_case}_controller.rb"
|
|
36
|
+
m.template 'test_controller_template.rb.erb', "#{test_dir}/test_#{@name.snake_case}_controller.rb"
|
|
37
|
+
|
|
38
|
+
# Optionally add the class to a nib
|
|
39
|
+
controller_name = "#{@name.camel_case}Controller"
|
|
40
|
+
if @nibs_to_update.empty?
|
|
41
|
+
print "\nWould you like me to add the class #{controller_name} to MainMenu.nib? [Y/n]: " unless $TESTING
|
|
42
|
+
result = Kernel.gets.strip
|
|
43
|
+
if result.empty? or result.downcase == 'y'
|
|
44
|
+
add_class_to_classes_nib(controller_name, 'misc/English.lproj/MainMenu.nib/classes.nib')
|
|
45
|
+
end
|
|
46
|
+
else
|
|
47
|
+
@nibs_to_update.each do |nib|
|
|
48
|
+
if nib.camel_case == 'MainMenu'
|
|
49
|
+
add_class_to_classes_nib(controller_name, 'misc/English.lproj/MainMenu.nib/classes.nib')
|
|
50
|
+
else
|
|
51
|
+
add_class_to_classes_nib(controller_name, "app/views/#{nib.camel_case}.nib/classes.nib")
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
protected
|
|
59
|
+
def banner
|
|
60
|
+
<<-EOS
|
|
61
|
+
Creates a ...
|
|
62
|
+
|
|
63
|
+
USAGE: #{$0} #{spec.name} name"
|
|
64
|
+
EOS
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def add_options!(opts)
|
|
68
|
+
# opts.separator ''
|
|
69
|
+
# opts.separator 'Options:'
|
|
70
|
+
# For each option below, place the default
|
|
71
|
+
# at the top of the file next to "default_options"
|
|
72
|
+
# opts.on("-a", "--author=\"Your Name\"", String,
|
|
73
|
+
# "Some comment about this option",
|
|
74
|
+
# "Default: none") { |options[:author]| }
|
|
75
|
+
# opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def extract_options
|
|
79
|
+
# for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
|
|
80
|
+
# Templates can access these value via the attr_reader-generated methods, but not the
|
|
81
|
+
# raw instance variable value.
|
|
82
|
+
# @author = options[:author]
|
|
83
|
+
end
|
|
84
|
+
end
|