xcres 0.4.4 → 0.5.0
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 +4 -4
- data/Gemfile.lock +12 -9
- data/README.md +43 -5
- data/lib/xcres/analyzer/strings_analyzer.rb +1 -1
- data/lib/xcres/builder/resources_builder.rb +77 -12
- data/lib/xcres/command/build_command.rb +6 -1
- data/lib/xcres/command/install_command.rb +23 -16
- data/lib/xcres/command/project_command.rb +1 -0
- data/lib/xcres/version.rb +1 -1
- data/spec/fixtures/Example/Example/en.lproj/Localizable.strings +1 -0
- data/spec/integration.rb +8 -0
- data/spec/integration/build-keyword-clash/after/R.h +1 -3
- data/spec/integration/build-keyword-clash/after/R.m +0 -2
- data/spec/integration/build-swift/after/Example/Example.xcodeproj.yaml +168 -0
- data/spec/integration/build-swift/after/Example/Example/AppDelegate.h +15 -0
- data/spec/integration/build-swift/after/Example/Example/AppDelegate.m +49 -0
- data/spec/integration/build-swift/after/Example/Example/Example-Info.plist +38 -0
- data/spec/integration/build-swift/after/Example/Example/Example-Prefix.pch +16 -0
- data/spec/integration/build-swift/after/Example/Example/Icons.bundle/tab_bar/tabbar_list.png +0 -0
- data/spec/integration/build-swift/after/Example/Example/Icons.bundle/tab_bar/tabbar_list@2x.png +0 -0
- data/spec/integration/build-swift/after/Example/Example/Icons.bundle/tab_bar/tabbar_map.png +0 -0
- data/spec/integration/build-swift/after/Example/Example/Icons.bundle/tab_bar/tabbar_map@2x.png +0 -0
- data/spec/integration/build-swift/after/Example/Example/Images.xcassets/AppIcon.appiconset/Contents.json +28 -0
- data/spec/integration/build-swift/after/Example/Example/Images.xcassets/Cats/GrumpyCat.imageset/Contents.json +23 -0
- data/spec/integration/build-swift/after/Example/Example/Images.xcassets/Cats/GrumpyCat.imageset/GrumpyCat.jpg +0 -0
- data/spec/integration/build-swift/after/Example/Example/Images.xcassets/Cats/GrumpyCat.imageset/GrumpyCat@2x.jpg +0 -0
- data/spec/integration/build-swift/after/Example/Example/Images.xcassets/Cats/GrumpyCat.imageset/GrumpyCat@3x.jpg +0 -0
- data/spec/integration/build-swift/after/Example/Example/Images.xcassets/Doge.imageset/Contents.json +22 -0
- data/spec/integration/build-swift/after/Example/Example/Images.xcassets/Doge.imageset/doge.png +0 -0
- data/spec/integration/build-swift/after/Example/Example/Images.xcassets/Doge.imageset/doge@2x.png +0 -0
- data/spec/integration/build-swift/after/Example/Example/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
- data/spec/integration/build-swift/after/Example/Example/Images/doge.jpeg +0 -0
- data/spec/integration/build-swift/after/Example/Example/Images/nyanCat.png +0 -0
- data/spec/integration/build-swift/after/Example/Example/de.lproj/Localizable.strings +12 -0
- data/spec/integration/build-swift/after/Example/Example/en.lproj/InfoPlist.strings +2 -0
- data/spec/integration/build-swift/after/Example/Example/en.lproj/Localizable.strings +15 -0
- data/spec/integration/build-swift/after/Example/Example/main.m +18 -0
- data/spec/integration/build-swift/after/R.swift +47 -0
- data/spec/integration/build-swift/after/execution_output.txt +19 -0
- data/spec/integration/build-swift/before/Example/Example.xcodeproj/project.pbxproj +453 -0
- data/spec/integration/build-swift/before/Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- data/spec/integration/build-swift/before/Example/Example/AppDelegate.h +15 -0
- data/spec/integration/build-swift/before/Example/Example/AppDelegate.m +49 -0
- data/spec/integration/build-swift/before/Example/Example/Example-Info.plist +38 -0
- data/spec/integration/build-swift/before/Example/Example/Example-Prefix.pch +16 -0
- data/spec/integration/build-swift/before/Example/Example/Icons.bundle/tab_bar/tabbar_list.png +0 -0
- data/spec/integration/build-swift/before/Example/Example/Icons.bundle/tab_bar/tabbar_list@2x.png +0 -0
- data/spec/integration/build-swift/before/Example/Example/Icons.bundle/tab_bar/tabbar_map.png +0 -0
- data/spec/integration/build-swift/before/Example/Example/Icons.bundle/tab_bar/tabbar_map@2x.png +0 -0
- data/spec/integration/build-swift/before/Example/Example/Images.xcassets/AppIcon.appiconset/Contents.json +28 -0
- data/spec/integration/build-swift/before/Example/Example/Images.xcassets/Cats/GrumpyCat.imageset/Contents.json +23 -0
- data/spec/integration/build-swift/before/Example/Example/Images.xcassets/Cats/GrumpyCat.imageset/GrumpyCat.jpg +0 -0
- data/spec/integration/build-swift/before/Example/Example/Images.xcassets/Cats/GrumpyCat.imageset/GrumpyCat@2x.jpg +0 -0
- data/spec/integration/build-swift/before/Example/Example/Images.xcassets/Cats/GrumpyCat.imageset/GrumpyCat@3x.jpg +0 -0
- data/spec/integration/build-swift/before/Example/Example/Images.xcassets/Doge.imageset/Contents.json +22 -0
- data/spec/integration/build-swift/before/Example/Example/Images.xcassets/Doge.imageset/doge.png +0 -0
- data/spec/integration/build-swift/before/Example/Example/Images.xcassets/Doge.imageset/doge@2x.png +0 -0
- data/spec/integration/build-swift/before/Example/Example/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
- data/spec/integration/build-swift/before/Example/Example/Images/doge.jpeg +0 -0
- data/spec/integration/build-swift/before/Example/Example/Images/nyanCat.png +0 -0
- data/spec/integration/build-swift/before/Example/Example/de.lproj/Localizable.strings +12 -0
- data/spec/integration/build-swift/before/Example/Example/en.lproj/InfoPlist.strings +2 -0
- data/spec/integration/build-swift/before/Example/Example/en.lproj/Localizable.strings +15 -0
- data/spec/integration/build-swift/before/Example/Example/main.m +18 -0
- data/spec/integration/build-var-infoplist/after/R.h +1 -1
- data/spec/integration/build/after/R.h +1 -1
- data/spec/integration/install-again/after/Example/Example.xcodeproj.yaml +1 -1
- data/spec/integration/install-again/after/Example/Example/Resources/R.h +1 -3
- data/spec/integration/install-again/after/Example/Example/Resources/R.m +0 -2
- data/spec/integration/install-again/after/execution_output.txt +0 -1
- data/spec/integration/install-again/before/Example/Example/Resources/R.h +1 -1
- data/spec/integration/install-again/before/Example/Example/Resources/R.m +0 -2
- data/spec/integration/install-moved-supporting-files/after/Example/Example.xcodeproj.yaml +1 -1
- data/spec/integration/install-moved-supporting-files/after/Example/Supporting_Files/Resources/R.h +1 -3
- data/spec/integration/install-moved-supporting-files/after/Example/Supporting_Files/Resources/R.m +0 -2
- data/spec/integration/install-no-supporting-files/after/Example/Example.xcodeproj.yaml +1 -1
- data/spec/integration/install-no-supporting-files/after/Example/Resources/R.h +1 -3
- data/spec/integration/install-no-supporting-files/after/Example/Resources/R.m +0 -2
- data/spec/integration/install-swift/after/Example/Example.xcodeproj.yaml +171 -0
- data/spec/integration/install-swift/after/Example/Example.xcodeproj/project.pbxproj +898 -0
- data/spec/integration/install-swift/after/Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- data/spec/integration/install-swift/after/Example/Example/AppDelegate.h +15 -0
- data/spec/integration/install-swift/after/Example/Example/AppDelegate.m +49 -0
- data/spec/integration/install-swift/after/Example/Example/Example-Info.plist +38 -0
- data/spec/integration/install-swift/after/Example/Example/Example-Prefix.pch +16 -0
- data/spec/integration/install-swift/after/Example/Example/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
- data/spec/integration/install-swift/after/Example/Example/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
- data/spec/integration/install-swift/after/Example/Example/Resources/R.swift +23 -0
- data/spec/integration/install-swift/after/Example/Example/en.lproj/InfoPlist.strings +2 -0
- data/spec/integration/install-swift/after/Example/Example/main.m +18 -0
- data/spec/integration/install-swift/after/execution_output.txt +22 -0
- data/spec/integration/install-swift/before/Example/Example.xcodeproj/project.pbxproj +421 -0
- data/spec/integration/install-swift/before/Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- data/spec/integration/install-swift/before/Example/Example/AppDelegate.h +15 -0
- data/spec/integration/install-swift/before/Example/Example/AppDelegate.m +49 -0
- data/spec/integration/install-swift/before/Example/Example/Example-Info.plist +38 -0
- data/spec/integration/install-swift/before/Example/Example/Example-Prefix.pch +16 -0
- data/spec/integration/install-swift/before/Example/Example/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
- data/spec/integration/install-swift/before/Example/Example/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
- data/spec/integration/install-swift/before/Example/Example/en.lproj/InfoPlist.strings +2 -0
- data/spec/integration/install-swift/before/Example/Example/main.m +18 -0
- data/spec/integration/install/after/Example/Example.xcodeproj.yaml +1 -1
- data/spec/integration/install/after/Example/Example/Resources/R.h +1 -3
- data/spec/integration/install/after/Example/Example/Resources/R.m +0 -2
- data/spec/integration/version/after/execution_output.txt +1 -1
- data/spec/unit/analyzer/strings_analyzer_spec.rb +1 -0
- data/spec/unit/builder/resources_builder_spec.rb +43 -4
- data/xcres.gemspec +0 -1
- metadata +151 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 07f166368a1c3c20e976d5cb5dac003e1f0b0e87
|
|
4
|
+
data.tar.gz: 164c9556d5bbf9054c05cd869e349219bd615e64
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ee5805f7a5e36fc235ae813606a5bb738eb19a9ad89f6ccaf578e1996158470e5f76b49f210e25dd80635087af7810aa146df365f85cc8b59d160a7fff992380
|
|
7
|
+
data.tar.gz: f0db23ce61854cbd8ad7095e5884ef057f5031c3524ec1dde941d675fb316cd1ef9f678b92e667add56c6e112c98e40ddc1768ae5ceab5c249d4124a3a38764a
|
data/Gemfile.lock
CHANGED
|
@@ -1,42 +1,41 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
xcres (0.
|
|
4
|
+
xcres (0.5.0)
|
|
5
5
|
activesupport (>= 3.2.15, < 4)
|
|
6
6
|
clamp (~> 0.6.3)
|
|
7
7
|
colored (~> 1.2)
|
|
8
|
-
libxml-ruby
|
|
9
8
|
xcodeproj (~> 0.18)
|
|
10
9
|
|
|
11
10
|
GEM
|
|
12
11
|
remote: https://rubygems.org/
|
|
13
12
|
specs:
|
|
14
|
-
activesupport (3.2.
|
|
13
|
+
activesupport (3.2.22)
|
|
15
14
|
i18n (~> 0.6, >= 0.6.4)
|
|
16
15
|
multi_json (~> 1.0)
|
|
17
16
|
ast (2.0.0)
|
|
18
17
|
bacon (1.2.0)
|
|
19
|
-
|
|
18
|
+
claide (0.9.1)
|
|
19
|
+
clamp (0.6.5)
|
|
20
20
|
clintegracon (0.5.2)
|
|
21
21
|
colored (~> 1.2)
|
|
22
22
|
diffy
|
|
23
23
|
coderay (1.1.0)
|
|
24
24
|
colored (1.2)
|
|
25
25
|
diffy (3.0.6)
|
|
26
|
-
i18n (0.
|
|
26
|
+
i18n (0.7.0)
|
|
27
27
|
inch (0.4.10)
|
|
28
28
|
pry
|
|
29
29
|
sparkr (>= 0.2.0)
|
|
30
30
|
term-ansicolor
|
|
31
31
|
yard (~> 0.8.7)
|
|
32
|
-
libxml-ruby (2.7.0)
|
|
33
32
|
metaclass (0.0.4)
|
|
34
33
|
method_source (0.8.2)
|
|
35
34
|
mocha (1.1.0)
|
|
36
35
|
metaclass (~> 0.0.1)
|
|
37
36
|
mocha-on-bacon (0.2.2)
|
|
38
37
|
mocha (>= 0.13.0)
|
|
39
|
-
multi_json (1.
|
|
38
|
+
multi_json (1.11.2)
|
|
40
39
|
parser (2.2.0.pre.4)
|
|
41
40
|
ast (>= 1.1, < 3.0)
|
|
42
41
|
slop (~> 3.4, >= 3.4.5)
|
|
@@ -61,8 +60,9 @@ GEM
|
|
|
61
60
|
term-ansicolor (1.3.0)
|
|
62
61
|
tins (~> 1.0)
|
|
63
62
|
tins (1.3.2)
|
|
64
|
-
xcodeproj (0.
|
|
65
|
-
activesupport (
|
|
63
|
+
xcodeproj (0.28.2)
|
|
64
|
+
activesupport (>= 3)
|
|
65
|
+
claide (~> 0.9.1)
|
|
66
66
|
colored (~> 1.2)
|
|
67
67
|
yard (0.8.7.4)
|
|
68
68
|
|
|
@@ -81,3 +81,6 @@ DEPENDENCIES
|
|
|
81
81
|
rake
|
|
82
82
|
rubocop
|
|
83
83
|
xcres!
|
|
84
|
+
|
|
85
|
+
BUNDLED WITH
|
|
86
|
+
1.10.6
|
data/README.md
CHANGED
|
@@ -26,18 +26,43 @@ capitalization or converting name scheme from *train-case* or *snake_case* to
|
|
|
26
26
|
*camelCase* and vice versa.
|
|
27
27
|
|
|
28
28
|
It will warn you in Xcode on build, if certain resources or string keys can't be
|
|
29
|
-
|
|
29
|
+
referenced, because their name contain invalid chars, duplicates in the
|
|
30
30
|
*camelCase* variant with another key, or would be equal to a protected compiler
|
|
31
31
|
keyword.
|
|
32
32
|
|
|
33
33
|
The generated index could look like below.
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
project's bridging header.
|
|
35
|
+
`xcres` can generate code both as **Swift** or **Objective-C**.
|
|
36
|
+
If you are using both in your project choose **Objective-C** and add an import to
|
|
37
|
+
the generated header to your project's bridging header.
|
|
38
38
|
|
|
39
|
+
**Swift**
|
|
40
|
+
```swift
|
|
41
|
+
public class R {
|
|
42
|
+
public enum Images: String {
|
|
43
|
+
/// doge.jpeg
|
|
44
|
+
case doge = "doge.jpeg"
|
|
45
|
+
}
|
|
46
|
+
public enum ImagesAssets: String {
|
|
47
|
+
/// AppIcon
|
|
48
|
+
case app = "AppIcon"
|
|
49
|
+
/// LaunchImage
|
|
50
|
+
case launch = "LaunchImage"
|
|
51
|
+
/// DefaultAvatar
|
|
52
|
+
case defaultAvatar = "DefaultAvatar"
|
|
53
|
+
}
|
|
54
|
+
public enum Strings: String {
|
|
55
|
+
/// Title shown if a wrong password was entered.
|
|
56
|
+
case errorTitleWrongPassword = "error_title_wrong_password"
|
|
57
|
+
/// Message shown if a wrong password was entered.
|
|
58
|
+
case errorMessageWrongPassword = "error_message_wrong_password"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Objective-C**
|
|
39
64
|
```objc
|
|
40
|
-
const struct R {
|
|
65
|
+
FOUNDATION_EXTERN const struct R {
|
|
41
66
|
struct Images {
|
|
42
67
|
/// doge.jpeg
|
|
43
68
|
__unsafe_unretained NSString *doge;
|
|
@@ -78,6 +103,12 @@ $ [sudo] gem install xcres
|
|
|
78
103
|
Use the automatic integration to add a build phase to your project,
|
|
79
104
|
by executing the following command:
|
|
80
105
|
|
|
106
|
+
**Swift**
|
|
107
|
+
```bash
|
|
108
|
+
$ xcres install --swift
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Objective-C**
|
|
81
112
|
```bash
|
|
82
113
|
$ xcres install
|
|
83
114
|
```
|
|
@@ -145,6 +176,12 @@ NSLocalizedString(@"error_message_wrong_password", @"Message shown if a wrong pa
|
|
|
145
176
|
|
|
146
177
|
Just write:
|
|
147
178
|
|
|
179
|
+
**Swift**
|
|
180
|
+
```swift
|
|
181
|
+
R.Strings.errorMessageWrongPassword.localizedValue
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Objective-C**
|
|
148
185
|
```objc
|
|
149
186
|
NSLocalizedString(R.Strings.errorMessageWrongPassword, @"Message shown if a wrong password was entered.")
|
|
150
187
|
```
|
|
@@ -179,6 +216,7 @@ your project to non-natural language keys.
|
|
|
179
216
|
## Credits
|
|
180
217
|
|
|
181
218
|
The logo was designed by [@kuchengnom](https://github.com/kuchengnom).
|
|
219
|
+
Swift support was implemented by [@timbodeit](https://github.com/timbodeit).
|
|
182
220
|
|
|
183
221
|
|
|
184
222
|
## License
|
|
@@ -233,7 +233,7 @@ module XCRes
|
|
|
233
233
|
strings = read_strings_file(path)
|
|
234
234
|
|
|
235
235
|
# Reject generated identifiers used by Interface Builder
|
|
236
|
-
strings.reject! { |key, _| /^[a-zA-Z0-9]{3}
|
|
236
|
+
strings.reject! { |key, _| /^[a-zA-Z0-9]{3}-[a-zA-Z0-9]{2,3}-[a-zA-Z0-9]{3}/.match(key) }
|
|
237
237
|
|
|
238
238
|
keys = Hash[strings.map do |key, value|
|
|
239
239
|
[key, { value: key, comment: value.gsub(/[\r\n]/, ' ') }]
|
|
@@ -13,12 +13,29 @@ class XCRes::ResourcesBuilder < XCRes::FileBuilder
|
|
|
13
13
|
//
|
|
14
14
|
EOS
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
OBJC_COMPILER_KEYWORDS = %w{
|
|
17
17
|
auto break case char const continue default do double else enum extern float
|
|
18
18
|
for goto if inline int long register restrict return short signed sizeof
|
|
19
19
|
static struct switch typedef union unsigned void volatile while
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
SWIFT_COMPILER_KEYWORDS = %w{
|
|
23
|
+
class deinit enum extension func import init internal let operator private
|
|
24
|
+
protocol public static struct subscript typealias var break case continue
|
|
25
|
+
default do else fallthrough for if in return switch where while as
|
|
26
|
+
dynamicType false is nil self Self super true
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
SWIFT_EXTENSIONS = <<EOS
|
|
30
|
+
public extension %s.Strings {
|
|
31
|
+
public var localizedValue: String {
|
|
32
|
+
return NSLocalizedString(self.rawValue,
|
|
33
|
+
bundle: NSBundle(forClass: R.self),
|
|
34
|
+
comment: "")
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
EOS
|
|
38
|
+
|
|
22
39
|
# @return [String]
|
|
23
40
|
# the name of the constant in the generated file(s)
|
|
24
41
|
attr_accessor :resources_constant_name
|
|
@@ -29,6 +46,12 @@ EOS
|
|
|
29
46
|
attr_accessor :documented
|
|
30
47
|
alias :documented? :documented
|
|
31
48
|
|
|
49
|
+
# @return [Bool]
|
|
50
|
+
# whether Swift code should be generated,
|
|
51
|
+
# Objective-C used if false, false by default
|
|
52
|
+
attr_accessor :swift
|
|
53
|
+
alias :swift? :swift
|
|
54
|
+
|
|
32
55
|
# @return [Hash{String => {String => String}}]
|
|
33
56
|
# the sections, which will been written to the built files
|
|
34
57
|
attr_reader :sections
|
|
@@ -38,6 +61,7 @@ EOS
|
|
|
38
61
|
def initialize
|
|
39
62
|
@sections = {}
|
|
40
63
|
self.documented = true
|
|
64
|
+
self.swift = false
|
|
41
65
|
end
|
|
42
66
|
|
|
43
67
|
# Extract resource name from #output_path, if not customized
|
|
@@ -63,7 +87,8 @@ EOS
|
|
|
63
87
|
end
|
|
64
88
|
|
|
65
89
|
# Skip compiler keywords
|
|
66
|
-
|
|
90
|
+
compiler_keywords = swift? ? SWIFT_COMPILER_KEYWORDS : OBJC_COMPILER_KEYWORDS
|
|
91
|
+
if compiler_keywords.include? transformed_key
|
|
67
92
|
logger.warn "Skip invalid key: '%s'. (Was transformed to keyword '%s')", key, transformed_key
|
|
68
93
|
next
|
|
69
94
|
end
|
|
@@ -77,14 +102,11 @@ EOS
|
|
|
77
102
|
def build
|
|
78
103
|
super
|
|
79
104
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
write_file_eventually "#{output_path}.m", (build_contents do |m_file|
|
|
86
|
-
build_impl_contents m_file
|
|
87
|
-
end)
|
|
105
|
+
if swift?
|
|
106
|
+
build_and_write_swift
|
|
107
|
+
else
|
|
108
|
+
build_and_write_objc
|
|
109
|
+
end
|
|
88
110
|
end
|
|
89
111
|
|
|
90
112
|
protected
|
|
@@ -118,7 +140,26 @@ EOS
|
|
|
118
140
|
end
|
|
119
141
|
end
|
|
120
142
|
|
|
121
|
-
|
|
143
|
+
# If the first character is not a letter, prefix it with an underscore
|
|
144
|
+
result.gsub(/^[^_a-z]/i, '_\0')
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def build_and_write_swift
|
|
148
|
+
# Build file contents and write them to disk
|
|
149
|
+
write_file_eventually "#{output_path}.swift", (build_contents do |swift_file|
|
|
150
|
+
build_swift_contents swift_file
|
|
151
|
+
end)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def build_and_write_objc
|
|
155
|
+
# Build file contents and write them to disk
|
|
156
|
+
write_file_eventually "#{output_path}.h", (build_contents do |h_file|
|
|
157
|
+
build_header_contents h_file
|
|
158
|
+
end)
|
|
159
|
+
|
|
160
|
+
write_file_eventually "#{output_path}.m", (build_contents do |m_file|
|
|
161
|
+
build_impl_contents m_file
|
|
162
|
+
end)
|
|
122
163
|
end
|
|
123
164
|
|
|
124
165
|
def build_header_contents h_file
|
|
@@ -126,7 +167,7 @@ EOS
|
|
|
126
167
|
h_file.writeln
|
|
127
168
|
h_file.writeln '#import <Foundation/Foundation.h>'
|
|
128
169
|
h_file.writeln
|
|
129
|
-
h_file.writeln '
|
|
170
|
+
h_file.writeln 'FOUNDATION_EXTERN const struct %s {' % resources_constant_name
|
|
130
171
|
h_file.section do |struct|
|
|
131
172
|
enumerate_sections do |section_key, enumerate_keys|
|
|
132
173
|
struct.writeln 'struct %s {' % section_key
|
|
@@ -164,9 +205,33 @@ EOS
|
|
|
164
205
|
m_file.writeln '};'
|
|
165
206
|
end
|
|
166
207
|
|
|
208
|
+
def build_swift_contents swift_file
|
|
209
|
+
swift_file.writeln BANNER
|
|
210
|
+
swift_file.writeln 'public class %s {' % resources_constant_name
|
|
211
|
+
swift_file.section do |struct|
|
|
212
|
+
enumerate_sections do |section_key, enumerate_keys|
|
|
213
|
+
struct.writeln 'public enum %s: String {' % section_key
|
|
214
|
+
struct.section do |section_struct|
|
|
215
|
+
enumerate_keys.call do |key, value, comment|
|
|
216
|
+
if documented?
|
|
217
|
+
section_struct.writeln '/// %s' % (comment || value) #unless comment.nil?
|
|
218
|
+
end
|
|
219
|
+
section_struct.writeln 'case %s = "%s"' % [key, value]
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
struct.writeln '}'
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
swift_file.writeln '}'
|
|
226
|
+
swift_file.writeln
|
|
227
|
+
swift_file.writeln SWIFT_EXTENSIONS % resources_constant_name
|
|
228
|
+
end
|
|
229
|
+
|
|
167
230
|
def enumerate_sections
|
|
168
231
|
# Iterate sections ordered by key
|
|
169
232
|
for section_key, section_content in @sections.sort
|
|
233
|
+
next if section_content.length == 0
|
|
234
|
+
|
|
170
235
|
# Pass section key and block to yield the keys ordered
|
|
171
236
|
proc = Proc.new do |&block|
|
|
172
237
|
for key, value in section_content.sort
|
|
@@ -36,7 +36,11 @@ class XCRes::BuildCommand < XCRes::ProjectCommand
|
|
|
36
36
|
end
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
if swift?
|
|
40
|
+
success 'Successfully updated: %s', "#{output_path}.swift"
|
|
41
|
+
else
|
|
42
|
+
success 'Successfully updated: %s', "#{output_path}.h"
|
|
43
|
+
end
|
|
40
44
|
end
|
|
41
45
|
|
|
42
46
|
def derive_resources_constant_name
|
|
@@ -72,6 +76,7 @@ class XCRes::BuildCommand < XCRes::ProjectCommand
|
|
|
72
76
|
builder.output_path = output_path
|
|
73
77
|
builder.logger = logger
|
|
74
78
|
builder.documented = documented?
|
|
79
|
+
builder.swift = swift?
|
|
75
80
|
builder.resources_constant_name = resources_constant_name
|
|
76
81
|
|
|
77
82
|
yield builder
|
|
@@ -100,28 +100,35 @@ class XCRes::InstallCommand < XCRes::ProjectCommand
|
|
|
100
100
|
|
|
101
101
|
# Set shell script
|
|
102
102
|
script_output_path = output_path.relative_path_from(src_root_path)
|
|
103
|
-
|
|
103
|
+
documented_argument = documented? ? "--documented" : "--no-documented"
|
|
104
|
+
swift_argument = swift? ? "--swift" : "--no-swift"
|
|
105
|
+
build_phase.shell_script = "xcres --no-ansi build #{documented_argument} #{swift_argument} $PROJECT_FILE_PATH $SRCROOT/#{script_output_path}\n"
|
|
104
106
|
build_phase.show_env_vars_in_log = '0'
|
|
105
107
|
|
|
106
108
|
# Find or create 'Resources' group in 'Supporting Files'
|
|
107
109
|
res_group = parent_group.groups.find { |g| g.name == 'Resources' }
|
|
108
110
|
res_group ||= parent_group.new_group('Resources', Pathname('Resources'))
|
|
109
111
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
112
|
+
if swift?
|
|
113
|
+
# Find or create references to resources index files
|
|
114
|
+
swift_file = res_group.find_file_by_path('R.swift') || res_group.new_file('R.swift')
|
|
115
|
+
# Add .swift file to source build phase, if it doesn't not already exist there
|
|
116
|
+
target.source_build_phase.add_file_reference(swift_file, true)
|
|
117
|
+
else
|
|
118
|
+
# Find or create references to resources index files
|
|
119
|
+
h_file = res_group.find_file_by_path('R.h') || res_group.new_file('R.h')
|
|
120
|
+
m_file = res_group.find_file_by_path('R.m') || res_group.new_file('R.m')
|
|
121
|
+
# Add .m file to source build phase, if it doesn't not already exist there
|
|
122
|
+
target.source_build_phase.add_file_reference(m_file, true)
|
|
123
|
+
# Add .h file to prefix header
|
|
124
|
+
prefix_headers.each do |path|
|
|
125
|
+
realpath = src_root_path + path
|
|
126
|
+
next unless File.exist?(realpath)
|
|
127
|
+
File.open(realpath, 'a+') do |f|
|
|
128
|
+
import_snippet = "#import \"#{h_file.path}\"\n"
|
|
129
|
+
unless f.readlines.include?(import_snippet)
|
|
130
|
+
f.write "\n#{import_snippet}"
|
|
131
|
+
end
|
|
125
132
|
end
|
|
126
133
|
end
|
|
127
134
|
end
|
|
@@ -9,6 +9,7 @@ class XCRes::ProjectCommand < XCRes::Command
|
|
|
9
9
|
option ['--[no-]documented'], :flag, 'Add documentation to the generated files', default: true
|
|
10
10
|
#option ['-d', '--dry-run'], :flag, 'Does nothing on the file system'
|
|
11
11
|
|
|
12
|
+
option ['--[no-]swift'], :flag, 'Generate file as Swift code', default: false
|
|
12
13
|
option ['-t', '--target'], 'TARGET', 'Target to search & analyze', attribute_name: :target_name
|
|
13
14
|
option ['-x', '--exclude'], 'FILE_PATTERN', 'File pattern which should be excluded (default: ["InfoPlist.strings"])', multivalued: true, attribute_name: :exclude_file_patterns, default: ['InfoPlist.strings']
|
|
14
15
|
option ['-n', '--name'], 'NAME', 'Name of the resources constant (default: `basename OUTPUT_PATH`)', attribute_name: :resources_constant_name
|
data/lib/xcres/version.rb
CHANGED
data/spec/integration.rb
CHANGED
|
@@ -56,6 +56,10 @@ describe_cli 'xcres' do
|
|
|
56
56
|
describe 'with resource which has a protected name' do
|
|
57
57
|
behaves_like cli_spec('build-keyword-clash', '', 'build Example .')
|
|
58
58
|
end
|
|
59
|
+
|
|
60
|
+
describe 'with swift' do
|
|
61
|
+
behaves_like cli_spec('build-swift', '', 'build --swift Example .')
|
|
62
|
+
end
|
|
59
63
|
end
|
|
60
64
|
|
|
61
65
|
describe 'Install' do
|
|
@@ -74,6 +78,10 @@ describe_cli 'xcres' do
|
|
|
74
78
|
describe 'with moved supporting files' do
|
|
75
79
|
behaves_like cli_spec('install-moved-supporting-files', '', 'install Example')
|
|
76
80
|
end
|
|
81
|
+
|
|
82
|
+
describe 'with Swift' do
|
|
83
|
+
behaves_like cli_spec('install-swift', '', 'install --swift Example')
|
|
84
|
+
end
|
|
77
85
|
end
|
|
78
86
|
|
|
79
87
|
describe 'Get help' do
|