sbconstants 1.1.2 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +159 -1
- data/lib/sbconstants/cli.rb +14 -13
- data/lib/sbconstants/identifiers.yml +4 -0
- data/lib/sbconstants/objc_constant_writer.rb +1 -1
- data/lib/sbconstants/section.rb +1 -0
- data/lib/sbconstants/swift_constant_writer.rb +17 -5
- data/lib/sbconstants/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c4b50bc26a07daef1fcb4070f8940412f76c849
|
4
|
+
data.tar.gz: 7ed715ee91c3a8b0bee9534671efde59eacb135d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 979b6abf7914096eaf0f0a1f67949024140bf407936028b8069549a5989e4d06796dd59a2e36f5f3fb865237b20bd19629fe65c2c5c792dfb4ee036215904571
|
7
|
+
data.tar.gz: c924cfe629f55a59eb1f15ab5d3cf42a015eff6d2215f15e716c63290386040696fbbe51adb567e200b2896c37721aaaa67b34921b4f15ac551fb5fa842fdc28
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# sbconstants
|
2
2
|
|
3
|
-
Generate a constants file by grabbing identifiers from storyboards in a project.
|
3
|
+
Generate a constants file by grabbing identifiers from storyboards in a project.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -34,6 +34,164 @@ Usage: DESTINATION_FILE [options]
|
|
34
34
|
-w, --swift Output to a Swift File
|
35
35
|
```
|
36
36
|
|
37
|
+
An example usage would look like:
|
38
|
+
|
39
|
+
sbconstants MyApp/Constants/PASStoryboardConstants.h
|
40
|
+
|
41
|
+
**NB** The argument is the destination file to dump the constants into - this needs to be added manually
|
42
|
+
|
43
|
+
Every time `sbconstants` is run it will parse the storyboard files and pull out any constants and then dump them into `PASStoryboardConstants.(h|m)`. This of course means that `PASStoryboardConstants.(h|m)` should not be edited by hand as it will just be clobbered any time we build.
|
44
|
+
|
45
|
+
The output of running this tool will look something like this:
|
46
|
+
|
47
|
+
`PASStoryboardConstants.h`
|
48
|
+
```
|
49
|
+
// Auto generated file - any changes will be lost
|
50
|
+
|
51
|
+
#import <Foundation/Foundation.h>
|
52
|
+
|
53
|
+
#pragma mark - segue.identifier
|
54
|
+
extern NSString * const PSBMasterToDetail;
|
55
|
+
extern NSString * const PSBMasterToSettings;
|
56
|
+
|
57
|
+
#pragma mark - storyboardNames
|
58
|
+
extern NSString * const Main;
|
59
|
+
|
60
|
+
#pragma mark - tableViewCell.reuseIdentifier
|
61
|
+
extern NSString * const PSBAwesomeCell;
|
62
|
+
|
63
|
+
```
|
64
|
+
|
65
|
+
`PASStoryboardConstants.m`
|
66
|
+
```
|
67
|
+
|
68
|
+
// Auto generated file - any changes will be lost
|
69
|
+
|
70
|
+
#import "PASStoryboardConstants.h"
|
71
|
+
|
72
|
+
#pragma mark - segue.identifier
|
73
|
+
NSString * const PSBMasterToDetail = @"PSBMasterToDetail";
|
74
|
+
NSString * const PSBMasterToSettings = @"PSBMasterToSettings";
|
75
|
+
|
76
|
+
#pragma mark - storyboardNames
|
77
|
+
NSString * const Main = @"Main";
|
78
|
+
|
79
|
+
#pragma mark - tableViewCell.reuseIdentifier
|
80
|
+
NSString * const PSBAwesomeCell = @"PSBAwesomeCell";
|
81
|
+
|
82
|
+
```
|
83
|
+
|
84
|
+
Using the `--swift` flag this would produce
|
85
|
+
|
86
|
+
```
|
87
|
+
// Auto generated file from SBConstants - any changes may be lost
|
88
|
+
|
89
|
+
public enum SegueIdentifier : String {
|
90
|
+
case PSBMasterToDetail = "PSBMasterToDetail"
|
91
|
+
case PSBMasterToSettings = "PSBMasterToSettings"
|
92
|
+
}
|
93
|
+
|
94
|
+
public enum StoryboardNames : String {
|
95
|
+
case Main = "Main"
|
96
|
+
}
|
97
|
+
|
98
|
+
public enum TableViewCellreuseIdentifier : String {
|
99
|
+
case PSBAwesomeCell = "PSBAwesomeCell"
|
100
|
+
}
|
101
|
+
```
|
102
|
+
|
103
|
+
The constants are grouped by where they were found in the storyboard xml e.g. `segue.identifier`. This can really help give you some context about where/what/when and why a constant exists.
|
104
|
+
|
105
|
+
##Options
|
106
|
+
|
107
|
+
Options are fun and there are a few to play with - most of these options are really only any good for debugging.
|
108
|
+
|
109
|
+
####`--prefix`
|
110
|
+
-p, --prefix=<prefix> Only match identifiers with <prefix>
|
111
|
+
|
112
|
+
Using the `prefix` option you can specify that you only want to grab identifiers that start with a certain prefix, which is always nice.
|
113
|
+
|
114
|
+
####`--source-dir`
|
115
|
+
-s, --source-dir=<source> Directory containing storyboards
|
116
|
+
|
117
|
+
If you don't want to run the tool from the root of your app for some reason you can specify the source directory to start searching for storyboard files. The search is recursive using a glob something like `<source-dir>/**/*.storyboard`
|
118
|
+
|
119
|
+
####`--dry-run`
|
120
|
+
-d, --dry-run Output to STDOUT
|
121
|
+
|
122
|
+
If you just want to run the tool and not write the output to a file then this option will spit the result out to `$stdout`
|
123
|
+
|
124
|
+
####`--verbose`
|
125
|
+
-v, --verbose Verbose output
|
126
|
+
|
127
|
+
Perhaps you want a little more context about where your identifiers are being grabbed from for debugging purposes. Never fear just use the `--verbose` switch and get output similar to:
|
128
|
+
|
129
|
+
`sample output`
|
130
|
+
```
|
131
|
+
|
132
|
+
#pragma mark - viewController.storyboardIdentifier
|
133
|
+
//
|
134
|
+
// info: MainStoryboard[line:43](viewController.storyboardIdentifier)
|
135
|
+
// context: <viewController restorationIdentifier="asd" storyboardIdentifier="FirstViewController" id="EPD-sv-vrF" sceneMemberID="viewController">
|
136
|
+
//
|
137
|
+
NSString * const FirstViewController = @"FirstViewController";
|
138
|
+
|
139
|
+
```
|
140
|
+
|
141
|
+
####`--queries`
|
142
|
+
-q, --queries=<queries> YAML file containing queries
|
143
|
+
|
144
|
+
Chances are I've missed some identifiers to search for in the storyboard. You don't want to wait for the `gem` to be updated or have to fork it and fix it. Using this option you can provide a YAML file that contains a description of what identifers to search for. The current one looks something like this (NB this is a great starting point for creating your own yaml):
|
145
|
+
|
146
|
+
`queries`
|
147
|
+
```
|
148
|
+
|
149
|
+
---
|
150
|
+
segue: identifier
|
151
|
+
view: restorationIdentifier
|
152
|
+
? - tableViewCell
|
153
|
+
- collectionViewCell
|
154
|
+
: - reuseIdentifier
|
155
|
+
? - navigationController
|
156
|
+
- viewController
|
157
|
+
- tableViewController
|
158
|
+
- collectionViewController
|
159
|
+
: - storyboardIdentifier
|
160
|
+
- restorationIdentifier
|
161
|
+
|
162
|
+
```
|
163
|
+
|
164
|
+
This looks a little funky but it's essentially groups of keys and values (both the key and the value can be an array). This actually gets expanded to the following table:
|
165
|
+
|
166
|
+
+--------------------------+-----------------------+
|
167
|
+
| node | attribute |
|
168
|
+
+ -------------------------+-----------------------+
|
169
|
+
| segue | identifier |
|
170
|
+
| view | restorationIdentifier |
|
171
|
+
| tableViewCell | reuseIdentifier |
|
172
|
+
| collectionViewCell | reuseIdentifier |
|
173
|
+
| navigationController | storyboardIdentifier |
|
174
|
+
| viewController | storyboardIdentifier |
|
175
|
+
| tableViewController | storyboardIdentifier |
|
176
|
+
| collectionViewController | storyboardIdentifier |
|
177
|
+
| viewController | restorationIdentifier |
|
178
|
+
| navigationController | restorationIdentifier |
|
179
|
+
| tableViewController | restorationIdentifier |
|
180
|
+
| collectionViewController | restorationIdentifier |
|
181
|
+
+--------------------------+-----------------------+
|
182
|
+
|
183
|
+
####`--swift`
|
184
|
+
|
185
|
+
-w, --swift Output to a Swift File
|
186
|
+
|
187
|
+
Outputs Swift code rather than Objective-C
|
188
|
+
|
189
|
+
####`--templates-dir`
|
190
|
+
|
191
|
+
-t, --templates-dir=<templates> Directory containing the templates to use for code formatting
|
192
|
+
|
193
|
+
See below
|
194
|
+
|
37
195
|
## Custom formatting
|
38
196
|
|
39
197
|
If you are running tools that verify your team is sticking to coding conventions you might find that the default output might not fit your requirements. Not to fear you can provide your own templates to decide the formatting you require by passing the `--templates-dir` option with the path to the directory containing the templates to use.
|
data/lib/sbconstants/cli.rb
CHANGED
@@ -2,20 +2,20 @@ require 'set'
|
|
2
2
|
|
3
3
|
module SBConstants
|
4
4
|
class CLI
|
5
|
-
attr_accessor :options, :constants, :sections, :
|
5
|
+
attr_accessor :options, :constants, :sections, :xibs
|
6
6
|
|
7
7
|
def self.run argv
|
8
8
|
new(Options.parse(argv)).run
|
9
9
|
end
|
10
10
|
|
11
11
|
def initialize options
|
12
|
-
self.options
|
13
|
-
self.constants
|
14
|
-
self.
|
12
|
+
self.options = options
|
13
|
+
self.constants = Hash.new { |h,k| h[k] = Set.new }
|
14
|
+
self.xibs = Array.new
|
15
15
|
end
|
16
16
|
|
17
17
|
def run
|
18
|
-
|
18
|
+
parse_xibs
|
19
19
|
refute_key_collisions
|
20
20
|
write
|
21
21
|
end
|
@@ -39,7 +39,7 @@ module SBConstants
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def sanitise_key key
|
42
|
-
key.gsub(" ", "").gsub("-", "")
|
42
|
+
key.gsub(" ", "").gsub("-", "").gsub("@", "").gsub(":", "").gsub("~", "_")
|
43
43
|
end
|
44
44
|
|
45
45
|
private
|
@@ -65,16 +65,17 @@ To resolve the issue remove the ambiguity in naming - search your storyboards fo
|
|
65
65
|
# Parse all found storyboards and build a dictionary of constant => locations
|
66
66
|
#
|
67
67
|
# A constant key can potentially exist in many files so locations is a collection
|
68
|
-
def
|
69
|
-
Dir["#{options.source_dir}/**/*.storyboard"].each_with_index do |
|
68
|
+
def parse_xibs
|
69
|
+
Dir["#{options.source_dir}/**/*.{storyboard,xib}"].each_with_index do |xib, xib_index|
|
70
70
|
|
71
|
-
filename = File.basename(
|
72
|
-
|
71
|
+
filename = File.basename(xib, '.*')
|
72
|
+
xibs << filename
|
73
73
|
|
74
|
-
|
74
|
+
group_name = "#{xib.split(".").last}Names"
|
75
75
|
|
76
|
+
constants[filename] << Location.new(group_name, nil, xib, filename, xib_index + 1)
|
76
77
|
|
77
|
-
File.readlines(
|
78
|
+
File.readlines(xib, encoding: 'UTF-8').each_with_index do |line, index|
|
78
79
|
options.queries.each do |query|
|
79
80
|
next unless value = line[query.regex, 1]
|
80
81
|
next if value.strip.empty?
|
@@ -92,7 +93,7 @@ To resolve the issue remove the ambiguity in naming - search your storyboards fo
|
|
92
93
|
|
93
94
|
if options.use_swift
|
94
95
|
swift_out = File.open("#{options.output_path}.swift", 'w') unless dry_run
|
95
|
-
SwiftConstantWriter.new(self, swift_out).write
|
96
|
+
SwiftConstantWriter.new(self, swift_out, options.templates_dir).write
|
96
97
|
swift_out.close
|
97
98
|
else
|
98
99
|
|
@@ -1,12 +1,16 @@
|
|
1
1
|
---
|
2
2
|
segue: identifier
|
3
3
|
view: restorationIdentifier
|
4
|
+
controller: identifier
|
5
|
+
tableRow: identifier
|
4
6
|
? - tableViewCell
|
5
7
|
- collectionViewCell
|
8
|
+
- collectionReusableView
|
6
9
|
: - reuseIdentifier
|
7
10
|
? - navigationController
|
8
11
|
- viewController
|
9
12
|
- tableViewController
|
10
13
|
- collectionViewController
|
14
|
+
- viewControllerPlaceholder
|
11
15
|
: - storyboardIdentifier
|
12
16
|
- restorationIdentifier
|
@@ -22,7 +22,7 @@ module SBConstants
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def header
|
25
|
-
template_with_file "
|
25
|
+
template_with_file "@import Foundation;\n\n", File.open(template_file_path("objc_header.erb")).read
|
26
26
|
end
|
27
27
|
|
28
28
|
def implementation
|
data/lib/sbconstants/section.rb
CHANGED
@@ -3,26 +3,38 @@ require 'erb'
|
|
3
3
|
|
4
4
|
module SBConstants
|
5
5
|
class SwiftConstantWriter < SimpleDelegator
|
6
|
-
|
6
|
+
attr_reader :templates_dir
|
7
|
+
|
8
|
+
def initialize data_source, swift_out, templates_dir
|
7
9
|
super data_source
|
8
10
|
@swift_out = swift_out
|
11
|
+
@templates_dir = templates_dir
|
9
12
|
end
|
10
13
|
|
11
14
|
def write
|
12
15
|
head = %Q{\nimport Foundation"\n}
|
13
|
-
body = %Q{ case <%= sanitise_key(constant)
|
16
|
+
body = %Q{ case <%= sanitise_key(constant) %>\n}
|
14
17
|
@swift_out.puts template_with_file head, body
|
15
18
|
end
|
16
19
|
|
17
|
-
def
|
18
|
-
@
|
20
|
+
def default_templates_dir
|
21
|
+
@default_templates_dir ||= File.dirname(__FILE__) + '/templates'
|
19
22
|
end
|
20
23
|
|
21
24
|
def template_with_file head, body
|
22
25
|
@head = head
|
23
26
|
@body = body
|
24
|
-
pre_processed_template = ERB.new(File.open("
|
27
|
+
pre_processed_template = ERB.new(File.open(template_file_path("swift_body.erb")).read, nil, '<>').result(binding)
|
25
28
|
ERB.new(pre_processed_template, nil, '<>').result(binding)
|
26
29
|
end
|
30
|
+
|
31
|
+
def template_file_path basename
|
32
|
+
if templates_dir && File.exist?("#{templates_dir}/#{basename}")
|
33
|
+
"#{templates_dir}/#{basename}"
|
34
|
+
else
|
35
|
+
"#{default_templates_dir}/#{basename}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
27
39
|
end
|
28
40
|
end
|
data/lib/sbconstants/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sbconstants
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Samuels
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2016-04-06 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Generate constants from storyboards in ObjC and Swift.
|
15
15
|
email:
|
@@ -61,7 +61,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
61
61
|
version: '0'
|
62
62
|
requirements: []
|
63
63
|
rubyforge_project:
|
64
|
-
rubygems_version: 2.
|
64
|
+
rubygems_version: 2.4.8
|
65
65
|
signing_key:
|
66
66
|
specification_version: 4
|
67
67
|
summary: Generate constants from storyboards in Objective-C and Swift.
|