fastlane-plugin-wpmreleasetoolkit 1.0.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) 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/extconf.rb +1 -1
  30. data/ext/drawText/makefile.example +8 -0
  31. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/an_update_metadata_source_action.rb +3 -3
  32. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_betabuild_prechecks.rb +22 -16
  33. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_build_prechecks.rb +15 -9
  34. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_bump_version_beta.rb +26 -26
  35. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_bump_version_final_release.rb +27 -24
  36. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_bump_version_hotfix.rb +21 -23
  37. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_bump_version_release.rb +31 -40
  38. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_codefreeze_prechecks.rb +16 -9
  39. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_completecodefreeze_prechecks.rb +10 -4
  40. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_create_xml_release_notes.rb +2 -2
  41. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_current_branch_is_hotfix.rb +10 -2
  42. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_download_file_by_version.rb +1 -1
  43. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_download_translations_action.rb +2 -2
  44. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_finalize_prechecks.rb +11 -7
  45. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_get_alpha_version.rb +8 -2
  46. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_get_app_version.rb +8 -2
  47. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_get_release_version.rb +8 -2
  48. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_hotifx_prechecks.rb +5 -5
  49. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_merge_translators_strings.rb +1 -1
  50. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_tag_build.rb +11 -5
  51. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_update_metadata.rb +1 -1
  52. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_update_release_notes.rb +3 -3
  53. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/check_for_toolkit_updates_action.rb +99 -0
  54. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/check_translation_progress.rb +147 -0
  55. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/circleci_trigger_job_action.rb +1 -1
  56. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/gp_downloadmetadata_action.rb +1 -1
  57. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/gp_update_metadata_source.rb +6 -5
  58. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/promo_screenshots_action.rb +2 -2
  59. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/removebranchprotection_action.rb +3 -3
  60. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/setbranchprotection_action.rb +3 -3
  61. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/setfrozentag_action.rb +1 -1
  62. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_betabuild_prechecks.rb +5 -5
  63. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_build_prechecks.rb +4 -4
  64. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_bump_version_beta.rb +2 -2
  65. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_bump_version_hotfix.rb +1 -1
  66. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_bump_version_release.rb +5 -5
  67. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_check_beta_deps.rb +2 -2
  68. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_clear_intermediate_tags.rb +1 -1
  69. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_codefreeze_prechecks.rb +4 -4
  70. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_completecodefreeze_prechecks.rb +5 -5
  71. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_current_branch_is_hotfix.rb +1 -1
  72. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_final_tag.rb +2 -2
  73. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_finalize_prechecks.rb +5 -5
  74. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_get_app_version.rb +1 -1
  75. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_get_build_version.rb +1 -1
  76. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_get_store_app_sizes.rb +1 -1
  77. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_hotifx_prechecks.rb +5 -5
  78. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_lint_localizations.rb +1 -1
  79. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_localize_project.rb +1 -1
  80. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_merge_translators_strings.rb +4 -4
  81. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_tag_build.rb +2 -2
  82. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_update_metadata.rb +1 -1
  83. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_update_release_notes.rb +3 -3
  84. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_validate_ci_build.rb +2 -2
  85. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/an_metadata_update_helper.rb +3 -3
  86. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_git_helper.rb +14 -5
  87. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_localize_helper.rb +11 -2
  88. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb +133 -55
  89. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/ci_helper.rb +1 -1
  90. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/configure_helper.rb +2 -2
  91. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/encryption_helper.rb +1 -1
  92. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb +4 -6
  93. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/glotpress_helper.rb +79 -0
  94. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/ios/ios_adc_app_sizes_helper.rb +3 -3
  95. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/ios/ios_l10n_helper.rb +3 -4
  96. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/metadata_update_helper.rb +1 -1
  97. data/lib/fastlane/plugin/wpmreleasetoolkit/models/configuration.rb +2 -2
  98. data/lib/fastlane/plugin/wpmreleasetoolkit/version.rb +1 -1
  99. metadata +45 -15
@@ -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
+ }