robjc 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 95ca6cbe19f575e14789a371ec1a6054dd80a4fa
4
+ data.tar.gz: cc0bd3a7f04c1490914168f3146b9e066f933f51
5
+ SHA512:
6
+ metadata.gz: ccab855731b78a50cdf35e5e93438ba94bb59b314d972fee3a6d53dc7b9a0ad16878a7b99318029a40991f82a4abb56864d51e5aa762b3fc8c0bf9de149f63cd
7
+ data.tar.gz: 2dc0ac0722cb5691a7280e157c7107475a896a7fcc9ad44caa34cd4a0f9023099057a6b41a57a977a998e96c7a5d455a25289a9ef37a6dada042d89f0e60847a
data/.DS_Store ADDED
Binary file
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in robjc.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Caleb Davenport
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,53 @@
1
+ # Objective-C Resources
2
+
3
+ `robjc` turns resources in Objective-C projects into compiled constants. If an image name changes, or a localized string goes away, references to those resources in code will cause build errors.
4
+
5
+ `robjc` watches your project for changes to images and localized strings and automatically generates code that refers to those resources. All generated code is placed in `Resources/CMDResources`.
6
+
7
+ **This is experimental**. I would love to add:
8
+
9
+ - Support for loading nibs, storyboard, json files, and plists
10
+ - Better file name to method conversion
11
+ - Ability for the gem to automatically link the required files into the target project
12
+
13
+ ## Installation
14
+
15
+ Install the gem:
16
+
17
+ ```
18
+ $ gem install robjc
19
+ ```
20
+
21
+ Run the generator:
22
+
23
+ ```
24
+ $ robjc generate
25
+ ```
26
+
27
+ Add `Resources/CMDResources` to your Xcode project. You might also want to add `CMDResources.h` to you prefix header.
28
+
29
+ ## Usage
30
+
31
+ Watch your project for changes:
32
+
33
+ ```
34
+ robjc watch
35
+ ```
36
+
37
+ Use the resource classes to load data into your app:
38
+
39
+ ```
40
+ // This used to be [UIImage imageNamed:@"settings-gear"]
41
+ R.image.settingsGear;
42
+
43
+ // This used to be NSLocalizedString(@"GENERAL_CANCEL", nil)
44
+ R.string.generalCancel;
45
+ ```
46
+
47
+ ## Contributing
48
+
49
+ 1. Fork it ( http://github.com/<my-github-username>/robjc/fork )
50
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
51
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
52
+ 4. Push to the branch (`git push origin my-new-feature`)
53
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/robjc ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path('../../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'robjc/cli'
6
+
7
+ Resources::Cli.start
data/data/.DS_Store ADDED
Binary file
@@ -0,0 +1,14 @@
1
+ //
2
+ // CMDImageResources.h
3
+ // Automatically generated on <%= generated_at.to_s %>
4
+ //
5
+
6
+ @interface CMDImageResources : NSObject
7
+
8
+ <% resources[:asset_catalogs].each do |resource| %>
9
+ <% resource.images.each do |image| %>
10
+ - (UIImage *)<%= resource.method_name(image) %>;
11
+ <% end %>
12
+ <% end %>
13
+
14
+ @end
@@ -0,0 +1,18 @@
1
+ //
2
+ // CMDImageResources.m
3
+ // Automatically generated on <%= generated_at.to_s %>
4
+ //
5
+
6
+ #import "CMDImageResources.h"
7
+
8
+ @implementation CMDImageResources
9
+
10
+ <% resources[:asset_catalogs].each do |resource| %>
11
+ <% resource.images.each do |image| %>
12
+ - (UIImage *)<%= resource.method_name(image) %> {
13
+ return [UIImage imageNamed:@"<%= image %>"];
14
+ }
15
+ <% end %>
16
+ <% end %>
17
+
18
+ @end
@@ -0,0 +1,18 @@
1
+ //
2
+ // CMDResources.h
3
+ // Automatically generated on <%= generated_at.to_s %>
4
+ //
5
+
6
+ #import "CMDImageResources.h"
7
+ #import "CMDStringResources.h"
8
+
9
+ #define R [CMDResources sharedResources]
10
+
11
+ @interface CMDResources : NSObject
12
+
13
+ + (instancetype)sharedResources;
14
+
15
+ - (CMDImageResources *)image;
16
+ - (CMDStringResources *)string;
17
+
18
+ @end
@@ -0,0 +1,38 @@
1
+ //
2
+ // CMDResources.m
3
+ // Automatically generated on <%= generated_at.to_s %>
4
+ //
5
+
6
+ #import "CMDResources.h"
7
+
8
+ @implementation CMDResources {
9
+ CMDImageResources *_image;
10
+ CMDStringResources *_string;
11
+ }
12
+
13
+ + (instancetype)sharedResources {
14
+ static dispatch_once_t token;
15
+ static CMDResources *resources;
16
+ dispatch_once(&token, ^{
17
+ resources = [CMDResources new];
18
+ });
19
+ return resources;
20
+ }
21
+
22
+
23
+ - (CMDImageResources *)image {
24
+ if (!_image) {
25
+ _image = [CMDImageResources new];
26
+ }
27
+ return _image;
28
+ }
29
+
30
+
31
+ - (CMDStringResources *)string {
32
+ if (!_string) {
33
+ _string = [CMDStringResources new];
34
+ }
35
+ return _string;
36
+ }
37
+
38
+ @end
@@ -0,0 +1,14 @@
1
+ //
2
+ // CMDStringResources.h
3
+ // Automatically generated on <%= generated_at.to_s %>
4
+ //
5
+
6
+ @interface CMDStringResources : NSObject
7
+
8
+ <% resources[:strings].each do |resource| %>
9
+ <% resource.strings.each do |string| %>
10
+ - (NSString *)<%= resource.method_name(string) %>;
11
+ <% end %>
12
+ <% end %>
13
+
14
+ @end
@@ -0,0 +1,18 @@
1
+ //
2
+ // CMDStringResources.m
3
+ // Automatically generated on <%= generated_at.to_s %>
4
+ //
5
+
6
+ #import "CMDStringResources.h"
7
+
8
+ @implementation CMDStringResources
9
+
10
+ <% resources[:strings].each do |resource| %>
11
+ <% resource.strings.each do |string| %>
12
+ - (NSString *)<%= resource.method_name(string) %> {
13
+ return NSLocalizedString(@"<%= string %>", nil);
14
+ }
15
+ <% end %>
16
+ <% end %>
17
+
18
+ @end
data/lib/robjc/cli.rb ADDED
@@ -0,0 +1,38 @@
1
+ require 'robjc'
2
+ require 'thor'
3
+ require 'listen'
4
+
5
+ module Resources
6
+ class Cli < Thor
7
+
8
+ desc 'generate', 'Generate resource files for the current directory.'
9
+ def generate
10
+ reader = Resources::Reader.new
11
+ resources = reader.resources
12
+
13
+ writer = Resources::Writer.new(resources)
14
+ writer.write
15
+ end
16
+
17
+ desc 'watch', 'Watch the current folder for changes and update all resources automatically.'
18
+ def watch
19
+ path = File.expand_path('.')
20
+ puts "Listening to changes in #{path}"
21
+ listener = Listen.to(path) do |modified, added, removed|
22
+ puts "Generating resources"
23
+
24
+ reader = Resources::Reader.new
25
+ resources = reader.resources
26
+
27
+ writer = Resources::Writer.new(resources)
28
+ writer.write
29
+ end
30
+ listener.ignore /CMDResources/
31
+ listener.ignore /\.h$/
32
+ listener.ignore /\.m$/
33
+ listener.start
34
+ sleep
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,64 @@
1
+ require 'robjc/resources/string_resource'
2
+ require 'robjc/resources/asset_catalog_resource'
3
+
4
+ module Resources
5
+ class Reader
6
+
7
+ def resources
8
+ @resources ||= {
9
+ images: images,
10
+ strings: strings,
11
+ nibs: nibs,
12
+ storyboards: storyboards,
13
+ asset_catalogs: asset_catalogs
14
+ }
15
+ end
16
+
17
+ private
18
+
19
+ def files
20
+ @files ||= Dir.glob('**/*').select do |f|
21
+ next false if f.match /^pods/i
22
+ next false if f.match /^vendor/i
23
+ next false if f.match /\.bundle/i
24
+ true
25
+ end
26
+ end
27
+
28
+ def images
29
+ @images ||= files.select do |f|
30
+ next false if f.match /\.xcassets/i
31
+ f.match /\.png$/i
32
+ end
33
+ end
34
+
35
+ def strings
36
+ @strings ||= files.select do |f|
37
+ f.match /\.strings$/i
38
+ end.map do |f|
39
+ Resources::StringResource.new(f)
40
+ end
41
+ end
42
+
43
+ def nibs
44
+ @nibs ||= files.select do |f|
45
+ f.match /\.nib$/
46
+ end
47
+ end
48
+
49
+ def storyboards
50
+ @storyboards ||= files.select do |f|
51
+ f.match /\.storyboard$/i
52
+ end
53
+ end
54
+
55
+ def asset_catalogs
56
+ @asset_catalogs ||= files.select do |f|
57
+ f.match /.xcassets$/i
58
+ end.map do |f|
59
+ Resources::AssetCatalogResource.new(f)
60
+ end
61
+ end
62
+
63
+ end
64
+ end
@@ -0,0 +1,38 @@
1
+ require 'robjc/resources/resource'
2
+
3
+ class Resources::AssetCatalogResource < Resources::Resource
4
+ attr_reader :images
5
+
6
+ IMAGE_SET_EXTENSION = "imageset"
7
+
8
+ def images
9
+ @images ||= image_names
10
+ end
11
+
12
+ def method_name(string)
13
+ components = string.split('-')
14
+ string = components.first.downcase
15
+ if components.length == 1
16
+ string
17
+ else
18
+ components.each_with_index do |s, i|
19
+ next if i == 0
20
+ string += s.capitalize
21
+ end
22
+ end
23
+ string
24
+ end
25
+
26
+ private
27
+
28
+ def image_names
29
+ image_sets.map do |f|
30
+ File.basename(f, ".#{IMAGE_SET_EXTENSION}")
31
+ end
32
+ end
33
+
34
+ def image_sets
35
+ Dir.glob(File.join(path, "*.#{IMAGE_SET_EXTENSION}"))
36
+ end
37
+
38
+ end
@@ -0,0 +1,13 @@
1
+ class Resources::Resource
2
+
3
+ attr_reader :path
4
+
5
+ def initialize(path)
6
+ @path = File.expand_path(path)
7
+ end
8
+
9
+ def method_name(string)
10
+ return string
11
+ end
12
+
13
+ end
@@ -0,0 +1,37 @@
1
+ require 'robjc/resources/resource'
2
+ require 'tempfile'
3
+ require 'plist'
4
+
5
+ class Resources::StringResource < Resources::Resource
6
+ attr_reader :strings
7
+
8
+ def strings
9
+ @strings ||= read_strings_file
10
+ end
11
+
12
+ def method_name(string)
13
+ components = string.split('_')
14
+ string = components.first.downcase
15
+ if components.length == 1
16
+ string
17
+ else
18
+ components.each_with_index do |s, i|
19
+ next if i == 0
20
+ string += s.capitalize
21
+ end
22
+ end
23
+ string
24
+ end
25
+
26
+ private
27
+
28
+ def read_strings_file
29
+ keys = []
30
+ Tempfile.create('strings.plist') do |f|
31
+ `plutil -convert xml1 "#{path}" -o "#{f.path}"`
32
+ keys = Plist::parse_xml(f.path).keys
33
+ end
34
+ keys.uniq
35
+ end
36
+
37
+ end
@@ -0,0 +1,3 @@
1
+ module Resources
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,68 @@
1
+ require 'erb'
2
+
3
+ module Resources
4
+ class Writer
5
+
6
+ attr_accessor :generated_at
7
+ attr_accessor :resources
8
+
9
+ def initialize(resources)
10
+ @resources = resources
11
+ end
12
+
13
+ def write
14
+ @generated_at = Time.now
15
+ ensure_directory
16
+ write_resources_class
17
+ write_images_class
18
+ write_strings_class
19
+ end
20
+
21
+ def add_to_target(target)
22
+ references = [ header_file_reference, implementation_file_reference ]
23
+ target.add_file_references
24
+ end
25
+
26
+ private
27
+
28
+ def write_resources_class
29
+ render_template_for_class 'resources', 'CMDResources'
30
+ end
31
+
32
+ def write_images_class
33
+ render_template_for_class 'image_resources', 'CMDImageResources'
34
+ end
35
+
36
+ def write_strings_class
37
+ render_template_for_class 'string_resources', 'CMDStringResources'
38
+ end
39
+
40
+ def render_template_for_class(template, klass)
41
+ [ "h", "m" ].each do |e|
42
+ render_template_to_file "#{template}.#{e}", "#{klass}.#{e}"
43
+ end
44
+ end
45
+
46
+ def render_template_to_file(template, file)
47
+ File.open(File.join(directory_path, file), 'w') do |f|
48
+ result = erb template
49
+ f.write(result)
50
+ end
51
+ end
52
+
53
+ def directory_path
54
+ 'Resources/CMDResources'
55
+ end
56
+
57
+ def ensure_directory
58
+ `mkdir -p #{directory_path}`
59
+ end
60
+
61
+ def erb(template)
62
+ template_path = File.expand_path("../../../data/views/#{template}.erb", __FILE__)
63
+ template = ERB.new(File.read(template_path), nil, nil)
64
+ template.result(binding)
65
+ end
66
+
67
+ end
68
+ end
data/lib/robjc.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'xcodeproj'
2
+ require 'robjc/version'
3
+ require 'robjc/reader'
4
+ require 'robjc/writer'
data/robjc.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'robjc/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "robjc"
8
+ spec.version = Resources::VERSION
9
+ spec.authors = ["Caleb Davenport"]
10
+ spec.email = ["calebmdavenport@gmail.com"]
11
+ spec.summary = %q{robjc turns resources in Objective-C projects into compiled constants.}
12
+ spec.homepage = "https://github.com/calebd/robjc"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_runtime_dependency "plist"
21
+ spec.add_runtime_dependency "thor"
22
+ spec.add_runtime_dependency "listen"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.5"
25
+ spec.add_development_dependency "rake"
26
+ end
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: robjc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Caleb Davenport
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: plist
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: thor
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: listen
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.5'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.5'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description:
84
+ email:
85
+ - calebmdavenport@gmail.com
86
+ executables:
87
+ - robjc
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".DS_Store"
92
+ - ".gitignore"
93
+ - Gemfile
94
+ - LICENSE.txt
95
+ - README.md
96
+ - Rakefile
97
+ - bin/robjc
98
+ - data/.DS_Store
99
+ - data/views/image_resources.h.erb
100
+ - data/views/image_resources.m.erb
101
+ - data/views/resources.h.erb
102
+ - data/views/resources.m.erb
103
+ - data/views/string_resources.h.erb
104
+ - data/views/string_resources.m.erb
105
+ - lib/robjc.rb
106
+ - lib/robjc/cli.rb
107
+ - lib/robjc/reader.rb
108
+ - lib/robjc/resources/asset_catalog_resource.rb
109
+ - lib/robjc/resources/resource.rb
110
+ - lib/robjc/resources/string_resource.rb
111
+ - lib/robjc/version.rb
112
+ - lib/robjc/writer.rb
113
+ - robjc.gemspec
114
+ homepage: https://github.com/calebd/robjc
115
+ licenses:
116
+ - MIT
117
+ metadata: {}
118
+ post_install_message:
119
+ rdoc_options: []
120
+ require_paths:
121
+ - lib
122
+ required_ruby_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ required_rubygems_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ requirements: []
133
+ rubyforge_project:
134
+ rubygems_version: 2.2.0
135
+ signing_key:
136
+ specification_version: 4
137
+ summary: robjc turns resources in Objective-C projects into compiled constants.
138
+ test_files: []