ovaltine 1.0.2 → 1.0.4
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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +11 -0
- data/Gemfile.lock +19 -0
- data/README.md +14 -4
- data/Rakefile +1 -1
- data/TODO.md +1 -2
- data/bin/ovaltine +6 -3
- data/lib/ovaltine/objc/storyboard_formatter.rb +1 -1
- data/lib/ovaltine/objc/storyboard_templates.rb +2 -2
- data/lib/ovaltine/version.rb +1 -1
- data/lib/ovaltine/xcode_project/ext/stdlib.rb +19 -0
- data/lib/ovaltine/xcode_project/pbxfilereference.rb +14 -0
- data/lib/ovaltine/xcode_project/pbxgroup.rb +41 -0
- data/lib/ovaltine/xcode_project/pbxobject.rb +32 -0
- data/lib/ovaltine/xcode_project.rb +104 -0
- data/lib/ovaltine.rb +30 -8
- data/specs/storyboard_formatter_spec.rb +2 -1
- data/vendor/json_pure/COPYING +57 -0
- data/vendor/json_pure/LICENSE +340 -0
- data/vendor/json_pure/generator.rb +443 -0
- data/vendor/json_pure/parser.rb +366 -0
- metadata +11 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: bf29e84c1f9fcf6bf4121916abd32252f21bcf11
|
4
|
-
data.tar.gz: 45c7913c46c4044da01ea1910ac0223177ab63b7
|
5
2
|
SHA512:
|
6
|
-
|
7
|
-
|
3
|
+
data.tar.gz: f76c243272bd421a5635d495d6796d4820688d624d322d7c2a3994e920c65d3b3ddea40f08fe6fcec1fe66973c963c1ca830cf6a1f5c91a64192c56d461f6442
|
4
|
+
metadata.gz: da7d8f1f5a64d059b5b62bc76847df9d3ff7c595c2df30147b9747aacaed3e4b60391f61c0b0b72bdf8f07688dc00ef8e9b761bcde085b898409eedb506daac1
|
5
|
+
SHA1:
|
6
|
+
data.tar.gz: 88b8b643bcc95048a2e41e9e970bbe10d68311be
|
7
|
+
metadata.gz: 96b9c29b9c0754d1065ddc765524a428a409978a
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
# 1.0.4
|
2
|
+
|
3
|
+
- Hotfix for failed error handling in Ruby 1.8.7
|
4
|
+
- Avoid writing xcode project files when no files added
|
5
|
+
- Add language argument for potentially generating templates in other languages
|
6
|
+
- Prefix identifier constants
|
7
|
+
|
8
|
+
# 1.0.3
|
9
|
+
|
10
|
+
- Experimental support for adding generated files to Xcode project
|
11
|
+
|
1
12
|
# 1.0.2
|
2
13
|
|
3
14
|
- Hotfix for Ruby 1.8.7
|
data/Gemfile.lock
ADDED
data/README.md
CHANGED
@@ -1,15 +1,25 @@
|
|
1
|
-
# Ovaltine
|
1
|
+
# Ovaltine [](https://travis-ci.org/kattrali/ovaltine)
|
2
2
|
|
3
3
|
The chocolatey treat which makes your code clean! Yum!
|
4
4
|
|
5
5
|
`Ovaltine` scans your `storyboard` files and generates constant files for view controller, segue, and reuse identifiers. For instance, if you have a storyboard called `Main` and a view controller with the Storyboard ID `authenticationViewController`, then you can instantiate that controller with something like `[ABCMainStoryboard instantiateAuthenticationViewController]`. No mistyping, plenty of chocolately goodness.
|
6
6
|
|
7
|
-
|
7
|
+
## Installation
|
8
8
|
|
9
9
|
```
|
10
10
|
gem install ovaltine
|
11
11
|
```
|
12
12
|
|
13
|
-
|
13
|
+
## Example Usage
|
14
14
|
|
15
|
-
|
15
|
+
```
|
16
|
+
ovaltine --prefix ABC --auto-replace --auto-add --project path/to/project.xcodeproj path/to/project/files
|
17
|
+
```
|
18
|
+
|
19
|
+
Run from the command line or as a build step (if you are brave!) [Here](https://gist.github.com/kattrali/bbe9e2464d02a8ca4cb1) are some example files generated using `ovaltine`.
|
20
|
+
|
21
|
+
## Additional Documentation
|
22
|
+
|
23
|
+
```
|
24
|
+
ovaltine --help
|
25
|
+
```
|
data/Rakefile
CHANGED
data/TODO.md
CHANGED
data/bin/ovaltine
CHANGED
@@ -12,8 +12,8 @@ require 'ovaltine'
|
|
12
12
|
require 'optparse'
|
13
13
|
|
14
14
|
parser_options = {
|
15
|
-
:
|
16
|
-
:
|
15
|
+
:prefix => '',
|
16
|
+
:language => 'objc'
|
17
17
|
}
|
18
18
|
|
19
19
|
def exit_with_error(message)
|
@@ -29,7 +29,7 @@ OptionParser.new do |opts|
|
|
29
29
|
opts.on('-o', '--output DIR', 'Specify output directory. Default is pwd') do |path|
|
30
30
|
parser_options[:output_directory] = path
|
31
31
|
end
|
32
|
-
opts.on('--prefix PREFIX', '
|
32
|
+
opts.on('--prefix PREFIX', 'Specify class prefix for generated files') do |prefix|
|
33
33
|
parser_options[:prefix] = prefix
|
34
34
|
end
|
35
35
|
opts.on('--auto-add', 'Automatically add generated files to the Xcode project') do
|
@@ -38,6 +38,9 @@ OptionParser.new do |opts|
|
|
38
38
|
opts.on('--auto-replace', 'Automatically replace files with the same name as generated files') do
|
39
39
|
parser_options[:auto_replace] = true
|
40
40
|
end
|
41
|
+
opts.on('--objc', 'Specify Objective-C as the template language (Default)') do
|
42
|
+
parser_options[:language] = 'objc'
|
43
|
+
end
|
41
44
|
opts.on_tail('-h', '--help', 'Show this message') { puts opts; exit }
|
42
45
|
opts.on_tail("-v", "--version", "Show version") { puts Ovaltine::VERSION; exit }
|
43
46
|
opts.parse!
|
@@ -20,7 +20,7 @@ module Ovaltine
|
|
20
20
|
|
21
21
|
#import <Foundation/Foundation.h>
|
22
22
|
|
23
|
-
@interface {CLASS_NAME}
|
23
|
+
@interface {CLASS_NAME} : NSObject
|
24
24
|
|
25
25
|
+(UIStoryboard *)storyboard;
|
26
26
|
|
@@ -40,7 +40,7 @@ module Ovaltine
|
|
40
40
|
#import <UIKit/UIKit.h>
|
41
41
|
#import "{CLASS_NAME}.h"
|
42
42
|
|
43
|
-
static UIStoryboard*
|
43
|
+
static UIStoryboard *_storyboard = nil;
|
44
44
|
{STATIC_VARIABLES}
|
45
45
|
|
46
46
|
@implementation {CLASS_NAME}
|
data/lib/ovaltine/version.rb
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
class String
|
2
|
+
def to_plist
|
3
|
+
to_json
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
class Array
|
8
|
+
def to_plist
|
9
|
+
items = map { |item| "#{item.to_plist}" }
|
10
|
+
"( #{items.join ","} )"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Hash
|
15
|
+
def to_plist
|
16
|
+
items = map { |key, value| "#{key.to_plist} = #{value.to_plist};\n" }
|
17
|
+
"{ #{items.join} }"
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
|
2
|
+
module Ovaltine
|
3
|
+
class XcodeProject
|
4
|
+
class PBXFileReference < PBXObject
|
5
|
+
def self.create path, file_type
|
6
|
+
self.new PBXObject.create_uuid, {
|
7
|
+
"sourceTree" => "<group>",
|
8
|
+
"path" => path,
|
9
|
+
"lastKnownFileType" => file_type
|
10
|
+
}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
module Ovaltine
|
3
|
+
class XcodeProject
|
4
|
+
class PBXGroup < PBXObject
|
5
|
+
|
6
|
+
def self.create name
|
7
|
+
self.new(PBXObject.create_uuid, {
|
8
|
+
"children" => [],
|
9
|
+
"name" => name,
|
10
|
+
"sourceTree" => "<group>"
|
11
|
+
})
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_object obj
|
15
|
+
unless self["children"].include?(obj.uuid)
|
16
|
+
self["children"] << obj.uuid
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def children recursive=false
|
21
|
+
children = self.project_file.objects_with_uuids self["children"]
|
22
|
+
|
23
|
+
if recursive
|
24
|
+
subgroups = PBXObject.filter children, { "isa" => "PBXGroup" }
|
25
|
+
subgroups.each { |subgroup| children << subgroup.children(true) }
|
26
|
+
end
|
27
|
+
|
28
|
+
children.flatten
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class PBXSourcesBuildPhase < PBXObject; end
|
33
|
+
class PBXFrameworksBuildPhase < PBXObject; end
|
34
|
+
class PBXResourcesBuildPhase < PBXObject; end
|
35
|
+
class PBXNativeTarget < PBXObject; end
|
36
|
+
class PBXProject < PBXObject; end
|
37
|
+
class PBXContainerItemProxy < PBXObject; end
|
38
|
+
class PBXReferenceProxy < PBXObject; end
|
39
|
+
class XCBuildConfiguration < PBXObject; end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
|
2
|
+
module Ovaltine
|
3
|
+
class XcodeProject
|
4
|
+
class PBXObject < Hash
|
5
|
+
attr_accessor :project_file
|
6
|
+
attr_reader :uuid
|
7
|
+
|
8
|
+
def self.filter array, attrs
|
9
|
+
array.select do |obj|
|
10
|
+
attrs.select { |k,v| obj[k] == v }.length == attrs.length
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.create_uuid
|
15
|
+
uuid = ""
|
16
|
+
24.times { uuid += "0123456789ABCDEF"[rand(16),1] }
|
17
|
+
uuid
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize uuid, hash
|
21
|
+
@project = nil
|
22
|
+
@uuid = uuid
|
23
|
+
self["isa"] = self.class.to_s.split('::').last
|
24
|
+
hash.each { |k,v| self[k] = v }
|
25
|
+
end
|
26
|
+
|
27
|
+
def inspect
|
28
|
+
@uuid + "=" + super
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
|
2
|
+
module Ovaltine
|
3
|
+
class XcodeProject
|
4
|
+
|
5
|
+
def load_dependencies
|
6
|
+
unless @@loaded ||= false
|
7
|
+
unless Object.const_defined?(:JSON)
|
8
|
+
begin
|
9
|
+
require 'json'
|
10
|
+
rescue LoadError
|
11
|
+
require File.expand_path(File.join(File.dirname(__FILE__),'../../vendor/json_pure/parser'))
|
12
|
+
require File.expand_path(File.join(File.dirname(__FILE__),'../../vendor/json_pure/generator'))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
@@loaded = true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize path
|
20
|
+
load_dependencies
|
21
|
+
if path =~ /\.xcodeproj$/
|
22
|
+
@path = File.join(path, 'project.pbxproj')
|
23
|
+
else
|
24
|
+
@path = path
|
25
|
+
end
|
26
|
+
@json = JSON.parse(`plutil -convert json -o - "#{@path}"`)
|
27
|
+
|
28
|
+
@json["objects"].each do |uuid, hash|
|
29
|
+
klass = PBXObject
|
30
|
+
begin
|
31
|
+
klass = Ovaltine::XcodeProject.const_get "#{hash['isa']}"
|
32
|
+
rescue
|
33
|
+
end
|
34
|
+
|
35
|
+
obj = klass.new uuid, hash
|
36
|
+
obj.project_file = self
|
37
|
+
|
38
|
+
@json["objects"][uuid] = obj
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def save
|
43
|
+
File.open(@path, "w") { |f| f.write @json.to_plist }
|
44
|
+
end
|
45
|
+
|
46
|
+
def objects
|
47
|
+
@json["objects"].values
|
48
|
+
end
|
49
|
+
|
50
|
+
def groups
|
51
|
+
objects_of_class(PBXGroup)
|
52
|
+
end
|
53
|
+
|
54
|
+
def files
|
55
|
+
objects_of_class(PBXFileReference)
|
56
|
+
end
|
57
|
+
|
58
|
+
def objects_of_class klass
|
59
|
+
str = klass.to_s.split('::').last
|
60
|
+
objects.select {|obj| obj["isa"] == str }
|
61
|
+
end
|
62
|
+
|
63
|
+
def objects_with_uuids uuids
|
64
|
+
uuids.map {|uuid| self.object_with_uuid uuid }
|
65
|
+
end
|
66
|
+
|
67
|
+
def object_with_uuid uuid
|
68
|
+
@json["objects"][uuid]
|
69
|
+
end
|
70
|
+
|
71
|
+
def add_file_ref path
|
72
|
+
relpath = File.expand_path(path).gsub(File.dirname(File.dirname(File.expand_path(@path))), '')[1..-1]
|
73
|
+
relpath = relpath[(relpath.index('/') + 1)..-1]
|
74
|
+
return nil if files.detect {|ref| ref["path"] == relpath}
|
75
|
+
ref = PBXFileReference.create(relpath, file_type(path))
|
76
|
+
add_object(ref)
|
77
|
+
main_group = groups.detect do |g|
|
78
|
+
!g["name"] && g["path"] && !g["path"].include?("Test")
|
79
|
+
end
|
80
|
+
unless group = groups.detect {|g| g["name"] == "Generated Files"}
|
81
|
+
group = PBXGroup.create("Generated Files")
|
82
|
+
add_object(group)
|
83
|
+
main_group.add_object(group)
|
84
|
+
end
|
85
|
+
group.add_object(ref)
|
86
|
+
ref
|
87
|
+
end
|
88
|
+
|
89
|
+
def add_object obj
|
90
|
+
obj.project_file = self
|
91
|
+
@json["objects"][obj.uuid] = obj
|
92
|
+
end
|
93
|
+
|
94
|
+
def file_type path
|
95
|
+
file_type = 'sourcecode'
|
96
|
+
if path =~ /\.m$/
|
97
|
+
file_type = 'sourcecode.c.objc'
|
98
|
+
elsif path =~ /\.h$/
|
99
|
+
file_type = 'sourcecode.c.h'
|
100
|
+
end
|
101
|
+
file_type
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
data/lib/ovaltine.rb
CHANGED
@@ -1,25 +1,38 @@
|
|
1
1
|
|
2
2
|
require 'ovaltine/storyboard'
|
3
|
-
require 'ovaltine/objc/storyboard_formatter'
|
4
|
-
require 'ovaltine/objc/storyboard_templates'
|
5
3
|
require 'ovaltine/version'
|
4
|
+
require 'ovaltine/xcode_project'
|
5
|
+
require 'ovaltine/xcode_project/pbxobject'
|
6
|
+
require 'ovaltine/xcode_project/pbxgroup'
|
7
|
+
require 'ovaltine/xcode_project/pbxfilereference'
|
8
|
+
require 'ovaltine/xcode_project/ext/stdlib'
|
6
9
|
|
7
10
|
module Ovaltine
|
8
11
|
|
9
12
|
def self.create_constant_files(path, options)
|
13
|
+
require_formatter(options[:language])
|
10
14
|
files = Dir.glob("#{path}/**/*.storyboard")
|
11
15
|
groups = files.group_by {|f| File.basename(f).sub('.storyboard','')}
|
12
16
|
formatters = groups.map do |name, paths|
|
13
17
|
storyboard = Storyboard.new(name, paths)
|
14
|
-
StoryboardFormatter.new(storyboard, options[:prefix], options[:output_directory])
|
18
|
+
StoryboardFormatter.new(storyboard, options[:prefix], (options[:output_directory] || path))
|
15
19
|
end
|
16
20
|
generated_paths = formatters.map(&:output_paths).flatten
|
17
|
-
if
|
18
|
-
|
19
|
-
|
21
|
+
if existing_path = generated_paths.detect {|p| File.exist?(p)} and !options[:auto_replace]
|
22
|
+
return unless prompt("Some generated files already exist. Overwrite? (Y/n)", 'y')
|
23
|
+
end
|
24
|
+
|
25
|
+
paths = write_files(formatters)
|
26
|
+
|
27
|
+
if project_filepath = options[:project] || Dir.glob("#{File.dirname(path)}/**/*.xcodeproj").first
|
28
|
+
return unless options[:auto_add] or prompt("[Experimental] Add files to project? (y/N)", 'n')
|
29
|
+
project = XcodeProject.new(project_filepath)
|
30
|
+
if paths.sort.map {|p| project.add_file_ref(p)}.compact.size > 0
|
31
|
+
project.save
|
32
|
+
puts "#{File.basename(project_filepath)} updated"
|
33
|
+
else
|
34
|
+
puts "All files already added"
|
20
35
|
end
|
21
|
-
else
|
22
|
-
write_files(formatters)
|
23
36
|
end
|
24
37
|
end
|
25
38
|
|
@@ -35,6 +48,7 @@ module Ovaltine
|
|
35
48
|
puts " * #{File.basename(path)}"
|
36
49
|
end
|
37
50
|
puts "\n#{files.size} files generated"
|
51
|
+
files
|
38
52
|
end
|
39
53
|
|
40
54
|
def self.prompt title, default_answer
|
@@ -48,4 +62,12 @@ module Ovaltine
|
|
48
62
|
answer.downcase == 'y'
|
49
63
|
end
|
50
64
|
end
|
65
|
+
|
66
|
+
def self.require_formatter(language='objc')
|
67
|
+
case language
|
68
|
+
when 'objc'
|
69
|
+
require 'ovaltine/objc/storyboard_formatter'
|
70
|
+
require 'ovaltine/objc/storyboard_templates'
|
71
|
+
end
|
72
|
+
end
|
51
73
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.co.jp>.
|
2
|
+
You can redistribute it and/or modify it under either the terms of the GPL
|
3
|
+
(see GPL file), or the conditions below:
|
4
|
+
|
5
|
+
1. You may make and give away verbatim copies of the source form of the
|
6
|
+
software without restriction, provided that you duplicate all of the
|
7
|
+
original copyright notices and associated disclaimers.
|
8
|
+
|
9
|
+
2. You may modify your copy of the software in any way, provided that
|
10
|
+
you do at least ONE of the following:
|
11
|
+
|
12
|
+
a) place your modifications in the Public Domain or otherwise
|
13
|
+
make them Freely Available, such as by posting said
|
14
|
+
modifications to Usenet or an equivalent medium, or by allowing
|
15
|
+
the author to include your modifications in the software.
|
16
|
+
|
17
|
+
b) use the modified software only within your corporation or
|
18
|
+
organization.
|
19
|
+
|
20
|
+
c) rename any non-standard executables so the names do not conflict
|
21
|
+
with standard executables, which must also be provided.
|
22
|
+
|
23
|
+
d) make other distribution arrangements with the author.
|
24
|
+
|
25
|
+
3. You may distribute the software in object code or executable
|
26
|
+
form, provided that you do at least ONE of the following:
|
27
|
+
|
28
|
+
a) distribute the executables and library files of the software,
|
29
|
+
together with instructions (in the manual page or equivalent)
|
30
|
+
on where to get the original distribution.
|
31
|
+
|
32
|
+
b) accompany the distribution with the machine-readable source of
|
33
|
+
the software.
|
34
|
+
|
35
|
+
c) give non-standard executables non-standard names, with
|
36
|
+
instructions on where to get the original software distribution.
|
37
|
+
|
38
|
+
d) make other distribution arrangements with the author.
|
39
|
+
|
40
|
+
4. You may modify and include the part of the software into any other
|
41
|
+
software (possibly commercial). But some files in the distribution
|
42
|
+
are not written by the author, so that they are not under this terms.
|
43
|
+
|
44
|
+
They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some
|
45
|
+
files under the ./missing directory. See each file for the copying
|
46
|
+
condition.
|
47
|
+
|
48
|
+
5. The scripts and library files supplied as input to or produced as
|
49
|
+
output from the software do not automatically fall under the
|
50
|
+
copyright of the software, but belong to whomever generated them,
|
51
|
+
and may be sold commercially, and may be aggregated with this
|
52
|
+
software.
|
53
|
+
|
54
|
+
6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
55
|
+
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
56
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
57
|
+
PURPOSE.
|