fastlane-plugin-wpmreleasetoolkit 1.0.0 → 1.0.1

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.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/bin/drawText +1 -0
  3. data/ext/drawText/drawText Tests/DigitParsingTests.swift +21 -0
  4. data/ext/drawText/drawText Tests/ExtensionsTests.swift +5 -0
  5. data/ext/drawText/drawText Tests/Info.plist +22 -0
  6. data/ext/drawText/drawText Tests/StylesheetTests.swift +31 -0
  7. data/ext/drawText/drawText Tests/Test Cases/default-stylesheet.txt +10 -0
  8. data/ext/drawText/drawText Tests/Test Cases/external-styles-sample.css +3 -0
  9. data/ext/drawText/drawText Tests/Test Cases/external-styles-test.txt +13 -0
  10. data/ext/drawText/drawText Tests/Test Cases/large-text-block.txt +1 -0
  11. data/ext/drawText/drawText Tests/Test Cases/regular-text-block.txt +2 -0
  12. data/ext/drawText/drawText Tests/Test Cases/rtl-text-block.txt +2 -0
  13. data/ext/drawText/drawText Tests/Test Cases/text-size-adjustment-test.txt +10 -0
  14. data/ext/drawText/drawText Tests/TextImageTests.swift +99 -0
  15. data/ext/drawText/drawText Tests/drawText_Tests.swift +14 -0
  16. data/ext/drawText/drawText.xcodeproj/project.pbxproj +508 -0
  17. data/ext/drawText/drawText.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  18. data/ext/drawText/drawText.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  19. data/ext/drawText/drawText.xcodeproj/xcshareddata/xcschemes/drawText Tests.xcscheme +57 -0
  20. data/ext/drawText/drawText.xcodeproj/xcshareddata/xcschemes/drawText.xcscheme +109 -0
  21. data/ext/drawText/drawText/Assets/style.css +1 -0
  22. data/ext/drawText/drawText/CoreTextStack.swift +113 -0
  23. data/ext/drawText/drawText/Helpers/CommandLineHelpers.swift +36 -0
  24. data/ext/drawText/drawText/Helpers/Extensions.swift +27 -0
  25. data/ext/drawText/drawText/Helpers/FileSystemHelper.swift +24 -0
  26. data/ext/drawText/drawText/Stylesheet.swift +48 -0
  27. data/ext/drawText/drawText/TextImage.swift +100 -0
  28. data/ext/drawText/drawText/main.swift +61 -0
  29. data/ext/drawText/makefile.example +8 -0
  30. data/lib/fastlane/plugin/wpmreleasetoolkit/version.rb +1 -1
  31. metadata +41 -14
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Workspace
3
+ version = "1.0">
4
+ <FileRef
5
+ location = "self:drawText.xcodeproj">
6
+ </FileRef>
7
+ </Workspace>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>IDEDidComputeMac32BitWarning</key>
6
+ <true/>
7
+ </dict>
8
+ </plist>
@@ -0,0 +1,57 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Scheme
3
+ LastUpgradeVersion = "1030"
4
+ version = "1.3">
5
+ <BuildAction
6
+ parallelizeBuildables = "YES"
7
+ buildImplicitDependencies = "YES">
8
+ </BuildAction>
9
+ <TestAction
10
+ buildConfiguration = "Debug"
11
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
12
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
13
+ codeCoverageEnabled = "YES"
14
+ shouldUseLaunchSchemeArgsEnv = "YES">
15
+ <Testables>
16
+ <TestableReference
17
+ skipped = "NO">
18
+ <BuildableReference
19
+ BuildableIdentifier = "primary"
20
+ BlueprintIdentifier = "F907EA6F22F3736E00196382"
21
+ BuildableName = "drawText Tests.xctest"
22
+ BlueprintName = "drawText Tests"
23
+ ReferencedContainer = "container:drawText.xcodeproj">
24
+ </BuildableReference>
25
+ </TestableReference>
26
+ </Testables>
27
+ <AdditionalOptions>
28
+ </AdditionalOptions>
29
+ </TestAction>
30
+ <LaunchAction
31
+ buildConfiguration = "Debug"
32
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
33
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
34
+ launchStyle = "0"
35
+ useCustomWorkingDirectory = "NO"
36
+ ignoresPersistentStateOnLaunch = "NO"
37
+ debugDocumentVersioning = "YES"
38
+ debugServiceExtension = "internal"
39
+ allowLocationSimulation = "YES">
40
+ <AdditionalOptions>
41
+ </AdditionalOptions>
42
+ </LaunchAction>
43
+ <ProfileAction
44
+ buildConfiguration = "Release"
45
+ shouldUseLaunchSchemeArgsEnv = "YES"
46
+ savedToolIdentifier = ""
47
+ useCustomWorkingDirectory = "NO"
48
+ debugDocumentVersioning = "YES">
49
+ </ProfileAction>
50
+ <AnalyzeAction
51
+ buildConfiguration = "Debug">
52
+ </AnalyzeAction>
53
+ <ArchiveAction
54
+ buildConfiguration = "Release"
55
+ revealArchiveInOrganizer = "YES">
56
+ </ArchiveAction>
57
+ </Scheme>
@@ -0,0 +1,109 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Scheme
3
+ LastUpgradeVersion = "1030"
4
+ version = "1.3">
5
+ <BuildAction
6
+ parallelizeBuildables = "YES"
7
+ buildImplicitDependencies = "YES">
8
+ <BuildActionEntries>
9
+ <BuildActionEntry
10
+ buildForTesting = "YES"
11
+ buildForRunning = "YES"
12
+ buildForProfiling = "YES"
13
+ buildForArchiving = "YES"
14
+ buildForAnalyzing = "YES">
15
+ <BuildableReference
16
+ BuildableIdentifier = "primary"
17
+ BlueprintIdentifier = "F99B0B9722F24329002851D8"
18
+ BuildableName = "drawText"
19
+ BlueprintName = "drawText"
20
+ ReferencedContainer = "container:drawText.xcodeproj">
21
+ </BuildableReference>
22
+ </BuildActionEntry>
23
+ </BuildActionEntries>
24
+ </BuildAction>
25
+ <TestAction
26
+ buildConfiguration = "Debug"
27
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29
+ codeCoverageEnabled = "YES"
30
+ shouldUseLaunchSchemeArgsEnv = "YES">
31
+ <Testables>
32
+ <TestableReference
33
+ skipped = "NO">
34
+ <BuildableReference
35
+ BuildableIdentifier = "primary"
36
+ BlueprintIdentifier = "F907EA6F22F3736E00196382"
37
+ BuildableName = "drawText Tests.xctest"
38
+ BlueprintName = "drawText Tests"
39
+ ReferencedContainer = "container:drawText.xcodeproj">
40
+ </BuildableReference>
41
+ </TestableReference>
42
+ </Testables>
43
+ <MacroExpansion>
44
+ <BuildableReference
45
+ BuildableIdentifier = "primary"
46
+ BlueprintIdentifier = "F99B0B9722F24329002851D8"
47
+ BuildableName = "drawText"
48
+ BlueprintName = "drawText"
49
+ ReferencedContainer = "container:drawText.xcodeproj">
50
+ </BuildableReference>
51
+ </MacroExpansion>
52
+ <AdditionalOptions>
53
+ </AdditionalOptions>
54
+ </TestAction>
55
+ <LaunchAction
56
+ buildConfiguration = "Debug"
57
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
58
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
59
+ launchStyle = "0"
60
+ useCustomWorkingDirectory = "NO"
61
+ ignoresPersistentStateOnLaunch = "NO"
62
+ debugDocumentVersioning = "YES"
63
+ debugServiceExtension = "internal"
64
+ allowLocationSimulation = "YES">
65
+ <BuildableProductRunnable
66
+ runnableDebuggingMode = "0">
67
+ <BuildableReference
68
+ BuildableIdentifier = "primary"
69
+ BlueprintIdentifier = "F99B0B9722F24329002851D8"
70
+ BuildableName = "drawText"
71
+ BlueprintName = "drawText"
72
+ ReferencedContainer = "container:drawText.xcodeproj">
73
+ </BuildableReference>
74
+ </BuildableProductRunnable>
75
+ <EnvironmentVariables>
76
+ <EnvironmentVariable
77
+ key = "CG_CONTEXT_SHOW_BACKTRACE"
78
+ value = ""
79
+ isEnabled = "YES">
80
+ </EnvironmentVariable>
81
+ </EnvironmentVariables>
82
+ <AdditionalOptions>
83
+ </AdditionalOptions>
84
+ </LaunchAction>
85
+ <ProfileAction
86
+ buildConfiguration = "Release"
87
+ shouldUseLaunchSchemeArgsEnv = "YES"
88
+ savedToolIdentifier = ""
89
+ useCustomWorkingDirectory = "NO"
90
+ debugDocumentVersioning = "YES">
91
+ <BuildableProductRunnable
92
+ runnableDebuggingMode = "0">
93
+ <BuildableReference
94
+ BuildableIdentifier = "primary"
95
+ BlueprintIdentifier = "F99B0B9722F24329002851D8"
96
+ BuildableName = "drawText"
97
+ BlueprintName = "drawText"
98
+ ReferencedContainer = "container:drawText.xcodeproj">
99
+ </BuildableReference>
100
+ </BuildableProductRunnable>
101
+ </ProfileAction>
102
+ <AnalyzeAction
103
+ buildConfiguration = "Debug">
104
+ </AnalyzeAction>
105
+ <ArchiveAction
106
+ buildConfiguration = "Release"
107
+ revealArchiveInOrganizer = "YES">
108
+ </ArchiveAction>
109
+ </Scheme>
@@ -0,0 +1,113 @@
1
+ import Cocoa
2
+ import CoreGraphics
3
+
4
+ struct CoreTextStack {
5
+
6
+ let layoutManager: NSLayoutManager
7
+ let textContainer: NSTextContainer
8
+ var textStorage: NSTextStorage
9
+
10
+ let frameSize: CGSize
11
+ var alignment: NSTextAlignment
12
+
13
+ enum Errors: Error {
14
+ case unableToInitializeTextStorage
15
+ }
16
+
17
+ init(html: Data, size: CGSize, alignment: NSTextAlignment = .natural) throws {
18
+
19
+ guard let textStorage = NSTextStorage(html: html, documentAttributes: nil) else {
20
+ throw Errors.unableToInitializeTextStorage
21
+ }
22
+
23
+ ///Storage
24
+ self.textStorage = textStorage
25
+ self.textContainer = NSTextContainer(size: size)
26
+ self.layoutManager = NSLayoutManager()
27
+ self.frameSize = size
28
+ self.alignment = alignment
29
+
30
+ /// Setup
31
+ layoutManager.addTextContainer(textContainer)
32
+ textStorage.addLayoutManager(layoutManager)
33
+
34
+ /// Configuration
35
+ textContainer.lineFragmentPadding = 0
36
+ textContainer.lineBreakMode = .byWordWrapping
37
+ layoutManager.usesFontLeading = true
38
+ layoutManager.typesetter.lineFragmentPadding = 0
39
+
40
+ applyParagraphStyles()
41
+ }
42
+
43
+ func setFontSize(_ size: CGFloat) {
44
+
45
+ /// Process each attribute run separately so that if the first word is bold,
46
+ /// it doesn't make all of the words bold.
47
+ textStorage.attributeRuns.forEach {
48
+
49
+ let range = NSRange(location: 0, length: $0.length)
50
+
51
+ $0.font = NSFont(name: $0.font!.fontName, size: size)
52
+ $0.edited(.editedAttributes, range: range, changeInLength: 0)
53
+ $0.fixAttributes(in: range)
54
+ }
55
+
56
+ applyParagraphStyles()
57
+ }
58
+
59
+ mutating func setAlignment(_ alignment: NSTextAlignment) {
60
+ self.alignment = alignment
61
+ applyParagraphStyles()
62
+ }
63
+
64
+ func applyParagraphStyles() {
65
+
66
+ let paragraphStyle = NSMutableParagraphStyle()
67
+ paragraphStyle.paragraphSpacingBefore = 0
68
+ paragraphStyle.paragraphSpacing = 0
69
+ paragraphStyle.alignment = self.alignment
70
+
71
+ textStorage.addAttributes([
72
+ NSAttributedString.Key.paragraphStyle: paragraphStyle
73
+ ], range: range)
74
+ textStorage.edited(.editedAttributes, range: range, changeInLength: 0)
75
+ textStorage.fixAttributes(in: range)
76
+ }
77
+
78
+ func draw(inContext context: NSGraphicsContext) throws -> CGImage {
79
+ NSGraphicsContext.saveGraphicsState()
80
+
81
+ /// Without the transform, text is drawn upside down and backwards because of
82
+ /// macOS' flipped coordinate system.
83
+ NSGraphicsContext.current = NSGraphicsContext(cgContext: context.cgContext, flipped: true)
84
+ let transform = NSAffineTransform()
85
+ transform.scaleX(by: 1, yBy: -1)
86
+ transform.translateX(by: 0, yBy: frameSize.height * -1)
87
+ transform.concat()
88
+
89
+ layoutManager.drawGlyphs(forGlyphRange: range, at: .zero)
90
+
91
+ guard let image = context.cgContext.makeImage() else {
92
+ throw TextImageProcessingError(kind: .unableToDrawImage)
93
+ }
94
+ NSGraphicsContext.restoreGraphicsState()
95
+
96
+ return image
97
+ }
98
+
99
+ /// `fits` is used to determine whether we should shrink the font size in order to fit the text in
100
+ /// a smaller box. Turns out the best way to do that is to check whether all the characters fit into
101
+ /// the textContainer, rather than trying to measure the drawing area.
102
+ var fits: Bool {
103
+
104
+ let textStorageLength = textStorage.length
105
+ let textContainerRange = layoutManager.glyphRange(for: textContainer)
106
+
107
+ return textStorageLength == textContainerRange.length
108
+ }
109
+
110
+ var range: NSRange {
111
+ return layoutManager.glyphRange(for: textContainer)
112
+ }
113
+ }
@@ -0,0 +1,36 @@
1
+ import Foundation
2
+
3
+ func readCommandLineArguments() -> [String : String] {
4
+
5
+ return CommandLine.arguments
6
+ .filter{ $0.contains("=") }
7
+ .reduce([String : String](), { (dictionary, argument) -> [String : String] in
8
+
9
+ var dictionary = dictionary //shadow for mutability
10
+
11
+ var parts = argument.split(separator: "=")
12
+ dictionary[String(parts.remove(at: 0))] = parts.joined(separator: "=")
13
+
14
+ return dictionary
15
+ })
16
+ }
17
+
18
+ func printUsageAndExit() -> Never {
19
+ print("""
20
+ Usage: ./draw-text
21
+ html={file path or quotes-enclosed HTML string [required]}
22
+ maxWidth={ integer [required] }
23
+ maxHeight={ integer [required] }
24
+ fontSize={ CSS-size compatible string [default = 12px }
25
+ color={ color or hex code [default = white] }
26
+ align={ CSS text-alignment value [default = center] }
27
+ stylesheet={ File Path to a custom stylesheet [default = none] }
28
+ """)
29
+ exit(1)
30
+ }
31
+
32
+ func printError(_ string: String) {
33
+ let redColor = "\u{001B}[0;31m"
34
+ let endColor = "\u{001B}[0;m"
35
+ fputs("\(redColor)Error: \(string)\(endColor)\n", stderr)
36
+ }
@@ -0,0 +1,27 @@
1
+ import Foundation
2
+ import Cocoa
3
+
4
+ extension String {
5
+ var digits: Int? {
6
+ let digits = self
7
+ .components(separatedBy: CharacterSet.decimalDigits.inverted)
8
+ .joined()
9
+
10
+ return Int(digits)
11
+ }
12
+
13
+ var withNewlinesConvertedToBreakTags: String {
14
+ return self.replacingOccurrences(of: "\n", with: "<br />")
15
+ }
16
+ }
17
+
18
+ extension NSTextAlignment {
19
+ static func fromString(_ string: String) -> NSTextAlignment {
20
+ switch string.lowercased() {
21
+ case "left": return .left
22
+ case "center": return .center
23
+ case "right": return .right
24
+ default: return .natural
25
+ }
26
+ }
27
+ }
@@ -0,0 +1,24 @@
1
+ import Foundation
2
+ import Cocoa
3
+
4
+ struct File {
5
+
6
+ static func write(image: CGImage, toFileAtPath path: String) {
7
+
8
+ /// Turn it into a `png`
9
+ let rep = NSBitmapImageRep(cgImage: image)
10
+ let pngData = rep.representation(using: .png, properties: [:])
11
+
12
+ /// Then write it out to the provided path
13
+ do {
14
+ let pathString = NSString(string: path).expandingTildeInPath
15
+ let output = NSURL(fileURLWithPath: pathString)
16
+
17
+ try pngData?.write(to: output as URL)
18
+ }
19
+ catch let err {
20
+ printError("Unable to write image to \(path): \(err.localizedDescription)")
21
+ exit(6)
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,48 @@
1
+ import Cocoa
2
+
3
+ struct Stylesheet {
4
+
5
+ var contents: String = ""
6
+ var externalStyles = "/* EXTERNAL STYLES */"
7
+
8
+ private let color: String
9
+
10
+ init(color: String, fontSize: Int) {
11
+ self.fontSize = fontSize
12
+ self.color = color
13
+
14
+ update()
15
+ }
16
+
17
+ mutating func updateWith(filePath: String) {
18
+
19
+ guard
20
+ FileManager.default.fileExists(atPath: filePath),
21
+ let fileContents = FileManager.default.contents(atPath: filePath),
22
+ let externalStyles = String(bytes: fileContents, encoding: .utf8) else {
23
+ return
24
+ }
25
+
26
+ self.externalStyles = externalStyles
27
+ update()
28
+ }
29
+
30
+ var fontSize: Int {
31
+ didSet { update() }
32
+ }
33
+
34
+ fileprivate mutating func update() {
35
+ self.contents = """
36
+ <style>
37
+ * {
38
+ padding: 0;
39
+ margin: 0;
40
+ color: \(color);
41
+ font-size: \(fontSize)px;
42
+ }
43
+
44
+ \(externalStyles)
45
+ </style>
46
+ """.trimmingCharacters(in: .whitespacesAndNewlines)
47
+ }
48
+ }