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.
Files changed (107) hide show
  1. data/ChangeLog +628 -0
  2. data/History.txt +4 -0
  3. data/License.txt +20 -0
  4. data/Manifest.txt +106 -0
  5. data/README.txt +126 -0
  6. data/Rakefile +32 -0
  7. data/TODO +28 -0
  8. data/app_generators/rucola/USAGE +6 -0
  9. data/app_generators/rucola/rucola_generator.rb +112 -0
  10. data/app_generators/rucola/templates/Rakefile.erb +12 -0
  11. data/app_generators/rucola/templates/Rakefile.erb.old +156 -0
  12. data/app_generators/rucola/templates/app/controllers/application_controller.rb +22 -0
  13. data/app_generators/rucola/templates/config/Info.plist.erb +28 -0
  14. data/app_generators/rucola/templates/config/boot.rb +2 -0
  15. data/app_generators/rucola/templates/config/environment.rb +11 -0
  16. data/app_generators/rucola/templates/config/environments/debug.rb +3 -0
  17. data/app_generators/rucola/templates/config/environments/release.rb +3 -0
  18. data/app_generators/rucola/templates/config/environments/test.rb +3 -0
  19. data/app_generators/rucola/templates/config/ib_external_class_defs.yml +13 -0
  20. data/app_generators/rucola/templates/misc/English.lproj/InfoPlist.strings.erb +3 -0
  21. data/app_generators/rucola/templates/misc/English.lproj/MainMenu.nib/classes.nib +40 -0
  22. data/app_generators/rucola/templates/misc/English.lproj/MainMenu.nib/info.nib +18 -0
  23. data/app_generators/rucola/templates/misc/English.lproj/MainMenu.nib/keyedobjects.nib +0 -0
  24. data/app_generators/rucola/templates/misc/main.m.erb +15 -0
  25. data/app_generators/rucola/templates/misc/rb_main.rb.erb +13 -0
  26. data/app_generators/rucola/templates/project.pbxproj.erb +299 -0
  27. data/app_generators/rucola/templates/script/plugin +84 -0
  28. data/app_generators/rucola/templates/test/controllers/test_application_controller.rb +10 -0
  29. data/app_generators/rucola/templates/test/test_helper.rb +10 -0
  30. data/bin/rucola +12 -0
  31. data/config/hoe.rb +71 -0
  32. data/config/requirements.rb +17 -0
  33. data/lib/rucola.rb +3 -0
  34. data/lib/rucola/info_plist.rb +37 -0
  35. data/lib/rucola/initializer.rb +313 -0
  36. data/lib/rucola/nib.rb +99 -0
  37. data/lib/rucola/rucola_support.rb +9 -0
  38. data/lib/rucola/rucola_support/controllers.rb +2 -0
  39. data/lib/rucola/rucola_support/controllers/rc_controller.rb +7 -0
  40. data/lib/rucola/rucola_support/controllers/rc_window_controller.rb +12 -0
  41. data/lib/rucola/rucola_support/core_ext.rb +2 -0
  42. data/lib/rucola/rucola_support/core_ext/objc.rb +4 -0
  43. data/lib/rucola/rucola_support/core_ext/objc/nsobject.rb +22 -0
  44. data/lib/rucola/rucola_support/core_ext/ruby.rb +4 -0
  45. data/lib/rucola/rucola_support/core_ext/ruby/string.rb +21 -0
  46. data/lib/rucola/rucola_support/initialize_hooks.rb +21 -0
  47. data/lib/rucola/rucola_support/models.rb +1 -0
  48. data/lib/rucola/rucola_support/models/rc_document.rb +10 -0
  49. data/lib/rucola/rucola_support/notifications.rb +1 -0
  50. data/lib/rucola/rucola_support/notifications/notifications.rb +146 -0
  51. data/lib/rucola/rucola_support/rc_app.rb +101 -0
  52. data/lib/rucola/tasks/freeze.rake +44 -0
  53. data/lib/rucola/tasks/interface_builder.rake +80 -0
  54. data/lib/rucola/tasks/main.rake +29 -0
  55. data/lib/rucola/tasks/xcode.rake +43 -0
  56. data/lib/rucola/test_helper.rb +57 -0
  57. data/lib/rucola/version.rb +9 -0
  58. data/lib/rucola/xcode.rb +148 -0
  59. data/log/debug.log +0 -0
  60. data/rucola_generators/controller/USAGE +5 -0
  61. data/rucola_generators/controller/controller_generator.rb +84 -0
  62. data/rucola_generators/controller/templates/controller_template.rb.erb +5 -0
  63. data/rucola_generators/controller/templates/test_controller_template.rb.erb +10 -0
  64. data/rucola_generators/document_model/USAGE +5 -0
  65. data/rucola_generators/document_model/document_model_generator.rb +67 -0
  66. data/rucola_generators/document_model/templates/document_model_template.rb.erb +27 -0
  67. data/rucola_generators/document_model/templates/test_document_model_template.rb.erb +10 -0
  68. data/rucola_generators/window_controller/USAGE +6 -0
  69. data/rucola_generators/window_controller/templates/Window.nib/classes.nib.erb +35 -0
  70. data/rucola_generators/window_controller/templates/Window.nib/info.nib +16 -0
  71. data/rucola_generators/window_controller/templates/Window.nib/keyedobjects.nib +0 -0
  72. data/rucola_generators/window_controller/templates/test_window_controller_template.rb.erb +10 -0
  73. data/rucola_generators/window_controller/templates/window_controller_template.rb.erb +19 -0
  74. data/rucola_generators/window_controller/window_controller_generator.rb +74 -0
  75. data/script/destroy +14 -0
  76. data/script/generate +14 -0
  77. data/script/txt2html +74 -0
  78. data/setup.rb +1585 -0
  79. data/tasks/deployment.rake +27 -0
  80. data/tasks/environment.rake +7 -0
  81. data/tasks/website.rake +17 -0
  82. data/test/fixtures/Info.plist +28 -0
  83. data/test/fixtures/MainMenu.nib/classes.nib +32 -0
  84. data/test/fixtures/MainMenu.nib/info.nib +18 -0
  85. data/test/fixtures/MainMenu.nib/keyedobjects.nib +0 -0
  86. data/test/test_controller_generator.rb +75 -0
  87. data/test/test_core_ext.rb +15 -0
  88. data/test/test_document_model_generator.rb +64 -0
  89. data/test/test_generator_helper.rb +20 -0
  90. data/test/test_helper.rb +13 -0
  91. data/test/test_info_plist.rb +31 -0
  92. data/test/test_nib.rb +73 -0
  93. data/test/test_notifications.rb +75 -0
  94. data/test/test_objc_core_ext.rb +37 -0
  95. data/test/test_rc_app.rb +63 -0
  96. data/test/test_rc_document.rb +18 -0
  97. data/test/test_rc_window_controller.rb +13 -0
  98. data/test/test_rucola.rb +11 -0
  99. data/test/test_rucola_generator.rb +87 -0
  100. data/test/test_window_controller_generator.rb +50 -0
  101. data/test/test_xcode.rb +128 -0
  102. data/website/index.html +199 -0
  103. data/website/index.txt +126 -0
  104. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  105. data/website/stylesheets/screen.css +138 -0
  106. data/website/template.rhtml +48 -0
  107. 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
@@ -0,0 +1,9 @@
1
+ module Rucola #:nodoc:
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ TINY = 1
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
@@ -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
File without changes
@@ -0,0 +1,5 @@
1
+ Description:
2
+ Generate a controller that inherits from NSObject.
3
+
4
+ Usage:
5
+ script/generate controller articles
@@ -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