motion-osx-cli 1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,112 @@
1
+ # motion-osx-cli
2
+
3
+ This gem helps you create command line tools for OSX using RubyMotion.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'motion-osx-cli'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install motion-osx-cli
18
+
19
+ And add this line to your Rakefile:
20
+
21
+ require 'motion-osx-cli'
22
+
23
+ ## Usage
24
+
25
+ Define a `main` method in your AppDelegate class which will be the main entry point for your application.
26
+
27
+ ```Ruby
28
+ class AppDelegate
29
+ def main(argc, argv)
30
+ # your code
31
+ end
32
+ end
33
+ ```
34
+
35
+ You can pass arguments to your app when executing it on the command line. `argc` is an integer repesenting the number of arguments passed to your application, and `argv` is an array containing each of these arguments. Let's see an example:
36
+
37
+ ```Ruby
38
+ class AppDelegate
39
+ def main(argc, argv)
40
+ puts "Number of arguments:"
41
+ p argc
42
+ puts "Arguments:"
43
+ p argv
44
+ end
45
+ end
46
+ ```
47
+
48
+ ```
49
+ $ /Users/me/Desktop/my-app hello world
50
+ Number of arguments:
51
+ 3
52
+ Arguments:
53
+ ["/Users/me/Desktop/my-app", "hello", "world"]
54
+ ```
55
+
56
+ As you can see, even if we don't pass any arguments, the first argument will always be the full path of the file we're executing. This is a standard behaviour for any command line application.
57
+
58
+ ## Frameworks
59
+
60
+ By default, your app will only require the `Foundation` framework, which is required by the Rubymotion runtime. If you want to include other frameworks you can do so in your Rakefile:
61
+
62
+ ```Ruby
63
+ Motion::Project::App.setup do |app|
64
+ app.frameworks << 'AppKit'
65
+ end
66
+ ```
67
+
68
+ If you want to add some UI to your application, you will need to create a NSApplication:
69
+
70
+ ```Ruby
71
+ class AppDelegate
72
+ def main(argc, argv)
73
+ app = NSApplication.sharedApplication
74
+ app.delegate = self
75
+ NSApp.run
76
+ end
77
+
78
+ def applicationDidFinishLaunching(notification)
79
+ # This will be executed after NSApp.run
80
+ end
81
+ end
82
+ ```
83
+
84
+ ## Distribution
85
+
86
+ When the Rubymotion toolchain builds your application, it will generate a .app file. However in the case of a command line application we are only interested in the executable. To retrieve it, right click in the .app file and click `Show Package Contents`. The executable will be located in a path similar to this, inside your `build` directory:
87
+
88
+ build/MacOSX-10.9-Release/my-app.app/Contents/MacOS/my-app
89
+
90
+ You can now copy it somewhere else and execute it on your terminal.
91
+
92
+ ## Testing
93
+
94
+ If your app does does not require require the AppKit framework and doesn't call `NSApp.run` at any point, `rake spec` will fail. Currently, Rubymotion's test framework expects a run loop to be created by a NSApplication.
95
+
96
+ ## TODO
97
+
98
+ - Find a way to make tests work.
99
+ - Create a Rubymotion template.
100
+ - Patch the toolchain to only create the executable and not the .app
101
+
102
+ ## Thanks
103
+
104
+ Thanks to [Jack Chen](http://twitter.com/chendo) for his article [Building a Command Line OS X app with RubyMotion](http://chen.do/blog/2013/10/04/building-a-command-line-os-x-app-with-rubymotion/) which saved me a lot of detective work.
105
+
106
+ ## Contributing
107
+
108
+ 1. Fork it
109
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
110
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
111
+ 4. Push to the branch (`git push origin my-new-feature`)
112
+ 5. Create new Pull Request
@@ -0,0 +1,21 @@
1
+ unless defined?(Motion::Project::Config)
2
+ raise "This file must be required within a RubyMotion project Rakefile."
3
+ end
4
+
5
+ require_relative 'project/motion-osx-cli'
6
+
7
+ lib_dir_path = File.dirname(File.expand_path(__FILE__))
8
+ Motion::Project::App.setup do |app|
9
+ app.frameworks = ['Foundation']
10
+
11
+ platform = app.respond_to?(:template) ? app.template : :ios
12
+ if platform != :osx
13
+ raise <<EOS
14
+ motion-osx-cli helps you create command line apps for OSX and does not work on iOS.
15
+ Make sure you are requiring the OSX template in your Rakefile:
16
+
17
+ require 'motion/project/template/osx'
18
+
19
+ EOS
20
+ end
21
+ end
@@ -0,0 +1,110 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (c) 2012, HipByte SPRL and contributors
4
+ # All rights reserved.
5
+ #
6
+ # Redistribution and use in source and binary forms, with or without
7
+ # modification, are permitted provided that the following conditions are met:
8
+ #
9
+ # 1. Redistributions of source code must retain the above copyright notice, this
10
+ # list of conditions and the following disclaimer.
11
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
19
+ # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
+ # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
+ # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
+ # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+
26
+ module Motion; module Project;
27
+ class OSXConfig < XcodeConfig
28
+ def main_cpp_file_txt(spec_objs)
29
+ main_txt = ""
30
+ if frameworks.include?('AppKit')
31
+ main_txt << "#import <AppKit/AppKit.h>"
32
+ else
33
+ main_txt << "#import <Foundation/Foundation.h>"
34
+ end
35
+ main_txt << <<EOS
36
+
37
+
38
+ extern "C" {
39
+ void rb_define_global_const(const char *, void *);
40
+ void rb_rb2oc_exc_handler(void);
41
+ void rb_exit(int);
42
+ void RubyMotionInit(int argc, char **argv);
43
+ EOS
44
+ if spec_mode
45
+ spec_objs.each do |_, init_func|
46
+ main_txt << "void #{init_func}(void *, void *);\n"
47
+ end
48
+ end
49
+ main_txt << <<EOS
50
+ }
51
+ EOS
52
+ if spec_mode
53
+ main_txt << <<EOS
54
+ @interface SpecLauncher : NSObject
55
+ @end
56
+
57
+ @implementation SpecLauncher
58
+
59
+ - (void)runSpecs
60
+ {
61
+ EOS
62
+ spec_objs.each do |_, init_func|
63
+ main_txt << "#{init_func}(self, 0);\n"
64
+ end
65
+ main_txt << <<EOS
66
+ [NSClassFromString(@\"Bacon\") performSelector:@selector(run)];
67
+ }
68
+
69
+ - (void)appLaunched:(NSNotification *)notification
70
+ {
71
+ [self runSpecs];
72
+ }
73
+
74
+ @end
75
+ EOS
76
+ end
77
+
78
+ main_txt << <<EOS
79
+ int
80
+ main(int argc, char **argv)
81
+ {
82
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
83
+ EOS
84
+ if ENV['ARR_CYCLES_DISABLE']
85
+ main_txt << <<EOS
86
+ setenv("ARR_CYCLES_DISABLE", "1", true);
87
+ EOS
88
+ end
89
+ main_txt << <<EOS
90
+ RubyMotionInit(argc, argv);
91
+ EOS
92
+ if spec_mode && frameworks.include?('AppKit')
93
+ main_txt << "SpecLauncher *specLauncher = [[SpecLauncher alloc] init];\n"
94
+ main_txt << "[[NSNotificationCenter defaultCenter] addObserver:specLauncher selector:@selector(appLaunched:) name:NSApplicationDidFinishLaunchingNotification object:nil];\n"
95
+ end
96
+ main_txt << <<EOS
97
+ NSMutableArray * arguments = [[NSMutableArray alloc] initWithCapacity: argc];
98
+ for (int i = 0; i < argc; i++)
99
+ {
100
+ [arguments addObject: [NSString stringWithUTF8String: argv[i]]];
101
+ }
102
+ [[NSClassFromString(@"#{delegate_class}") new] performSelector:NSSelectorFromString(@"main:") withObject:[NSNumber numberWithInt:argc] withObject:arguments];
103
+ [pool release];
104
+ rb_exit(0);
105
+ return 0;
106
+ }
107
+ EOS
108
+ end
109
+ end
110
+ end; end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: motion-osx-cli
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.0'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mark Villacampa
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-12-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: ! ' Easily create command line utilities for OSX with Rubymotion '
31
+ email:
32
+ - m@markvillacampa.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - README.md
38
+ - lib/motion-osx-cli.rb
39
+ - lib/project/motion-osx-cli.rb
40
+ homepage: ''
41
+ licenses:
42
+ - ''
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ requirements: []
60
+ rubyforge_project:
61
+ rubygems_version: 1.8.25
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: Easily create command line utilities for OSX with Rubymotion
65
+ test_files: []