ovaltine 1.0.2 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: bf29e84c1f9fcf6bf4121916abd32252f21bcf11
4
- data.tar.gz: 45c7913c46c4044da01ea1910ac0223177ab63b7
5
2
  SHA512:
6
- metadata.gz: 94aac6bb2aff88696a796823c8a2caf5f9899d63a154da2b93cd354740365a98ad4e725bd9a10a8d5742861314693080439a24c1012fac9613eeecab9f3651c5
7
- data.tar.gz: ebf734f231c593d20dbccbaec111744af471beb63524479efe86a2781ec6c1cbc587444d3c3a10cbc83678a9c6fffccc231f596a8a2704300832abb58e0eb9e7
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
@@ -0,0 +1,19 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ovaltine (1.0.3)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ bacon (1.2.0)
10
+ rake (10.3.2)
11
+
12
+ PLATFORMS
13
+ ruby
14
+
15
+ DEPENDENCIES
16
+ bacon (~> 1.2)
17
+ bundler (~> 1.3)
18
+ ovaltine!
19
+ rake (~> 10.0)
data/README.md CHANGED
@@ -1,15 +1,25 @@
1
- # Ovaltine
1
+ # Ovaltine [![Build Status](https://travis-ci.org/kattrali/ovaltine.svg?branch=master)](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
- # Installation
7
+ ## Installation
8
8
 
9
9
  ```
10
10
  gem install ovaltine
11
11
  ```
12
12
 
13
- # Usage
13
+ ## Example Usage
14
14
 
15
- Run `ovaltine` from the command line
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
@@ -2,4 +2,4 @@
2
2
  desc "Run unit tests"
3
3
  task :spec do
4
4
  sh 'bacon specs/*_spec.rb'
5
- end
5
+ end
data/TODO.md CHANGED
@@ -1,6 +1,5 @@
1
1
 
2
2
  ## TODO
3
3
 
4
- * Support adding generated files to projects (with minimal dependencies, for easier tool integration)
5
4
  * Add switch for language preferences
6
- * Add support for OS X storyboards
5
+ * Add support for OS X storyboards
data/bin/ovaltine CHANGED
@@ -12,8 +12,8 @@ require 'ovaltine'
12
12
  require 'optparse'
13
13
 
14
14
  parser_options = {
15
- :output_directory => '.',
16
- :prefix => ''
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', 'Class prefix for generated files') do |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!
@@ -103,7 +103,7 @@ module Ovaltine
103
103
  end
104
104
 
105
105
  def variable_name identifier
106
- "_#{identifier.gsub(/\W/,'').gsub(/\b\w/){ $&.downcase }}"
106
+ "_#{@prefix}#{identifier.gsub(/\W/,'').gsub(/\b\w/){ $&.downcase }}"
107
107
  end
108
108
 
109
109
 
@@ -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* _storyboard = nil;
43
+ static UIStoryboard *_storyboard = nil;
44
44
  {STATIC_VARIABLES}
45
45
 
46
46
  @implementation {CLASS_NAME}
@@ -1,3 +1,3 @@
1
1
  module Ovaltine
2
- VERSION = "1.0.2"
2
+ VERSION = "1.0.4"
3
3
  end
@@ -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 path = generated_paths.detect {|p| File.exist?(p)} and !options[:auto_replace]
18
- if prompt("Some generated files already exist. Overwrite? (Y/n)", 'y')
19
- write_files(formatters)
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
@@ -1,7 +1,8 @@
1
1
  $:.unshift File.expand_path('../../lib', __FILE__)
2
2
 
3
3
  require 'bacon'
4
- require 'ovaltine'
4
+ require 'ovaltine/storyboard'
5
+ require 'ovaltine/objc/storyboard_formatter'
5
6
 
6
7
  describe 'StoryboardFormatter' do
7
8
 
@@ -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.