Compare commits
3 Commits
master
...
ab91c1c277
Author | SHA1 | Date | |
---|---|---|---|
ab91c1c277 | |||
aa64ce5cf7 | |||
23bf3c3a82 |
309
.swiftlint.yml
@ -1,276 +1,43 @@
|
|||||||
# All rules here : https://realm.github.io/SwiftLint/rule-directory.html
|
disabled_rules: # rule identifiers to exclude from running
|
||||||
|
|
||||||
analyzer_rules:
|
|
||||||
- capture_variable
|
|
||||||
- typesafe_array_init
|
|
||||||
- unused_declaration
|
|
||||||
- unused_import
|
|
||||||
|
|
||||||
included:
|
|
||||||
- Sources
|
|
||||||
|
|
||||||
## Rules configuration
|
|
||||||
|
|
||||||
attributes:
|
|
||||||
always_on_line_above: ["@InjectedValue", "@ViewBuilder", "@IBOutlet"]
|
|
||||||
always_on_same_line: ["@Environment", "@EnvironmentObject", "@StateObject", "@State"]
|
|
||||||
|
|
||||||
identifier_name:
|
|
||||||
min_length:
|
|
||||||
- 2
|
|
||||||
max_length:
|
|
||||||
- 60
|
|
||||||
excluded:
|
|
||||||
- x
|
|
||||||
- y
|
|
||||||
|
|
||||||
type_name:
|
|
||||||
min_length: 3
|
|
||||||
max_length: 60
|
|
||||||
excluded:
|
|
||||||
- T
|
|
||||||
allowed_symbols:
|
|
||||||
- _
|
|
||||||
|
|
||||||
# line_length:
|
|
||||||
# warning: 150
|
|
||||||
|
|
||||||
disabled_rules:
|
|
||||||
- blanket_disable_command # do not warn when rule is not re-enable later in the file
|
|
||||||
- type_contents_order
|
|
||||||
- legacy_objc_type
|
|
||||||
- indentation_width
|
|
||||||
- function_parameter_count
|
|
||||||
- line_length
|
|
||||||
- function_body_length
|
|
||||||
- cyclomatic_complexity
|
|
||||||
- optional_data_string_conversion
|
|
||||||
|
|
||||||
opt_in_rules:
|
|
||||||
# Default rules :
|
|
||||||
- block_based_kvo
|
|
||||||
- class_delegate_protocol
|
|
||||||
- closing_brace
|
|
||||||
- closure_parameter_position
|
|
||||||
- colon
|
|
||||||
- comma
|
|
||||||
- comment_spacing
|
|
||||||
- compiler_protocol_init
|
|
||||||
- computed_accessors_order
|
|
||||||
- control_statement
|
|
||||||
- custom_rules
|
|
||||||
# - cyclomatic_complexity
|
|
||||||
- deployment_target
|
|
||||||
- discouraged_direct_init
|
|
||||||
- duplicate_enum_cases
|
|
||||||
- duplicate_imports
|
|
||||||
- duplicated_key_in_dictionary_literal
|
|
||||||
- dynamic_inline
|
|
||||||
- empty_enum_arguments
|
|
||||||
- empty_parameters
|
|
||||||
- empty_parentheses_with_trailing_closure
|
|
||||||
- file_length
|
|
||||||
- for_where
|
|
||||||
- force_unwrapping
|
|
||||||
- force_cast
|
|
||||||
- force_try
|
|
||||||
- trailing_whitespace
|
|
||||||
# - function_body_length
|
|
||||||
# - function_parameter_count
|
|
||||||
- generic_type_name
|
|
||||||
- identifier_name
|
|
||||||
- implicit_getter
|
|
||||||
- inclusive_language
|
|
||||||
- is_disjoint
|
|
||||||
- large_tuple
|
|
||||||
- leading_whitespace
|
- leading_whitespace
|
||||||
- legacy_cggeometry_functions
|
- trailing_whitespace
|
||||||
- legacy_constant
|
- identifier_name
|
||||||
- legacy_constructor
|
- large_tuple
|
||||||
- legacy_hashing
|
- file_length
|
||||||
- legacy_nsgeometry_functions
|
- line_length
|
||||||
- legacy_random
|
- force_try
|
||||||
# - line_length
|
|
||||||
- mark
|
|
||||||
- multiple_closures_with_trailing_closure
|
|
||||||
- nesting
|
|
||||||
- no_fallthrough_only
|
|
||||||
- no_space_in_method_call
|
|
||||||
- notification_center_detachment
|
|
||||||
- ns_number_init_as_function_reference
|
|
||||||
- nsobject_prefer_isequal
|
|
||||||
- opening_brace
|
|
||||||
- operator_whitespace
|
|
||||||
- orphaned_doc_comment
|
|
||||||
- private_over_fileprivate
|
|
||||||
- private_unit_test
|
|
||||||
- protocol_property_accessors_order
|
|
||||||
- reduce_boolean
|
|
||||||
- redundant_discardable_let
|
|
||||||
- redundant_objc_attribute
|
|
||||||
- redundant_optional_initialization
|
|
||||||
- redundant_set_access_control
|
|
||||||
- redundant_string_enum_value
|
|
||||||
- redundant_void_return
|
|
||||||
- return_arrow_whitespace
|
|
||||||
- self_in_property_initialization
|
|
||||||
- shorthand_operator
|
- shorthand_operator
|
||||||
- statement_position
|
|
||||||
- superfluous_disable_command
|
|
||||||
- switch_case_alignment
|
|
||||||
- syntactic_sugar
|
|
||||||
- todo
|
|
||||||
- trailing_comma
|
|
||||||
- trailing_newline
|
|
||||||
- trailing_semicolon
|
|
||||||
- type_body_length
|
- type_body_length
|
||||||
- type_name
|
- function_body_length
|
||||||
- unavailable_condition
|
- function_parameter_count
|
||||||
- unneeded_break_in_switch
|
- redundant_string_enum_value
|
||||||
- unused_closure_parameter
|
- unused_closure_parameter
|
||||||
- unused_control_flow_label
|
- cyclomatic_complexity
|
||||||
- unused_enumerated
|
- syntactic_sugar
|
||||||
- unused_optional_binding
|
- empty_enum_arguments
|
||||||
- unused_setter_value
|
- force_cast
|
||||||
- valid_ibinspectable
|
- multiple_closures_with_trailing_closure
|
||||||
- vertical_parameter_alignment
|
- private_over_fileprivate
|
||||||
- vertical_whitespace
|
- trailing_comma
|
||||||
- void_function_in_ternary
|
- comment_spacing
|
||||||
- void_return
|
excluded: # paths to ignore during linting. Takes precedence over `included`.
|
||||||
- xctfail_message
|
- DerivedData
|
||||||
- accessibility_trait_for_button
|
- Carthage
|
||||||
- array_init
|
- Pods
|
||||||
- attributes
|
- vendor
|
||||||
- closure_body_length
|
- Vendor
|
||||||
- closure_end_indentation
|
- "*/R2Tag+tags.swift"
|
||||||
- closure_spacing
|
type_name:
|
||||||
- collection_alignment
|
min_length: 1 # only warning
|
||||||
- comma_inheritance
|
max_length: # warning and error
|
||||||
- contains_over_filter_count
|
warning: 50
|
||||||
- contains_over_filter_is_empty
|
error: 60
|
||||||
- contains_over_first_not_nil
|
allowed_symbols: ["_"]
|
||||||
- contains_over_range_nil_comparison
|
nesting:
|
||||||
- convenience_type
|
type_level:
|
||||||
- discarded_notification_center_observer
|
warning: 3
|
||||||
- discouraged_assert
|
error: 6
|
||||||
- empty_count
|
statement_level:
|
||||||
- empty_string
|
warning: 5
|
||||||
- empty_xctest_method
|
error: 10
|
||||||
- enum_case_associated_values_count
|
|
||||||
- explicit_init
|
|
||||||
- fallthrough
|
|
||||||
- fatal_error_message
|
|
||||||
- file_header
|
|
||||||
- first_where
|
|
||||||
- flatmap_over_map_reduce
|
|
||||||
- ibinspectable_in_extension
|
|
||||||
- implicit_return
|
|
||||||
- implicitly_unwrapped_optional
|
|
||||||
- joined_default_parameter
|
|
||||||
- last_where
|
|
||||||
- legacy_multiple
|
|
||||||
- let_var_whitespace
|
|
||||||
- literal_expression_end_indentation
|
|
||||||
- lower_acl_than_parent
|
|
||||||
# - missing_docs
|
|
||||||
- modifier_order
|
|
||||||
- multiline_arguments
|
|
||||||
- multiline_arguments_brackets
|
|
||||||
- multiline_function_chains
|
|
||||||
- multiline_literal_brackets
|
|
||||||
- multiline_parameters
|
|
||||||
- multiline_parameters_brackets
|
|
||||||
- nimble_operator
|
|
||||||
- no_extension_access_modifier
|
|
||||||
- no_grouping_extension
|
|
||||||
- nslocalizedstring_key
|
|
||||||
- nslocalizedstring_require_bundle
|
|
||||||
- number_separator
|
|
||||||
- operator_usage_whitespace
|
|
||||||
- optional_enum_case_matching
|
|
||||||
- overridden_super_call
|
|
||||||
- override_in_extension
|
|
||||||
- pattern_matching_keywords
|
|
||||||
- prefer_self_in_static_references
|
|
||||||
- prefer_self_type_over_type_of_self
|
|
||||||
- prefer_zero_over_explicit_init
|
|
||||||
- prefixed_toplevel_constant
|
|
||||||
- private_action
|
|
||||||
- private_outlet
|
|
||||||
- prohibited_interface_builder
|
|
||||||
- prohibited_super_call
|
|
||||||
- quick_discouraged_call
|
|
||||||
- quick_discouraged_focused_test
|
|
||||||
- quick_discouraged_pending_test
|
|
||||||
- redundant_nil_coalescing
|
|
||||||
- redundant_type_annotation
|
|
||||||
- required_enum_case
|
|
||||||
- return_value_from_void_function
|
|
||||||
- self_binding
|
|
||||||
- shorthand_optional_binding
|
|
||||||
- single_test_class
|
|
||||||
- sorted_first_last
|
|
||||||
- sorted_imports
|
|
||||||
- strong_iboutlet
|
|
||||||
- test_case_accessibility
|
|
||||||
- toggle_bool
|
|
||||||
- trailing_closure
|
|
||||||
- unavailable_function
|
|
||||||
- unneeded_parentheses_in_closure_argument
|
|
||||||
- unowned_variable_capture
|
|
||||||
- untyped_error_in_catch
|
|
||||||
- vertical_parameter_alignment_on_call
|
|
||||||
- vertical_whitespace_between_cases
|
|
||||||
- vertical_whitespace_closing_braces
|
|
||||||
- weak_delegate
|
|
||||||
- xct_specific_matcher
|
|
||||||
|
|
||||||
custom_rules:
|
|
||||||
|
|
||||||
# Empty line before and after MARK -------------------------------------------
|
|
||||||
# mark_spacing:
|
|
||||||
# name: "Surround MARK by empty lines"
|
|
||||||
# regex: '\n[^\n]([^\n]*\/\/ MARK[^\n]*)\n[^\n]'
|
|
||||||
# message: "Surround MARK by empty lines"
|
|
||||||
# severity: warning
|
|
||||||
|
|
||||||
# Empty line -----------------------------------------------------------------
|
|
||||||
# no_empty_line_after_func:
|
|
||||||
# name: "No empty line after init or func"
|
|
||||||
# regex: '(func|init|let\s|var\s)[^\n]*\{[^\n\{\}]*\n\n'
|
|
||||||
# message: "No empty line after init or func"
|
|
||||||
# severity: warning
|
|
||||||
|
|
||||||
# Empty line after canImport -----------------------------------------------------------------
|
|
||||||
no_empty_line_after_can_import:
|
|
||||||
name: "Add empty line after #if canImport"
|
|
||||||
regex: '#if canImport\(.*\)\n[^\n]*(import|class|struct|enum|extension|protocol)'
|
|
||||||
message: "Add empty line after #if canImport"
|
|
||||||
severity: warning
|
|
||||||
|
|
||||||
# Spacings -------------------------------------------------------------------
|
|
||||||
empty_line_required:
|
|
||||||
name: "Add empty line after class, struct, enum, extension or protocol"
|
|
||||||
regex: '(class |struct |enum |extension |protocol )[^\n]*\{\n[^\n]*(class|struct|enum|extension|protocol|func|let|var|weak|private|internal|public|open|static|final|\/\/|init|case|@)'
|
|
||||||
message: "Add empty line after class, struct, enum, extension or protocol"
|
|
||||||
severity: warning
|
|
||||||
match_kinds:
|
|
||||||
- argument
|
|
||||||
- attribute.builtin
|
|
||||||
- attribute.id
|
|
||||||
- buildconfig.id
|
|
||||||
- buildconfig.keyword
|
|
||||||
- comment
|
|
||||||
- comment.mark
|
|
||||||
- comment.url
|
|
||||||
- identifier
|
|
||||||
- keyword
|
|
||||||
- number
|
|
||||||
- objectliteral
|
|
||||||
- parameter
|
|
||||||
- placeholder
|
|
||||||
- string
|
|
||||||
- string_interpolation_anchor
|
|
||||||
- typeidentifier
|
|
||||||
|
|
||||||
|
|
||||||
|
6
Jenkinsfile
vendored
@ -1,10 +1,8 @@
|
|||||||
library "openiumpipeline"
|
library "openiumpipeline"
|
||||||
|
|
||||||
env.DEVELOPER_DIR="/Applications/Xcode-16.3.0.app/Contents/Developer"
|
env.DEVELOPER_DIR="/Applications/Xcode-15.4.0.app/Contents/Developer"
|
||||||
// env.SIMULATOR_DEVICE_TYPES="iPhone-14-Pro"
|
//env.SIMULATOR_DEVICE_TYPES="iPad--7th-generation-"
|
||||||
// env.SLACK_CHANNEL = "prj-skdevkit"
|
|
||||||
env.IS_PACKAGE_SWIFT=1
|
env.IS_PACKAGE_SWIFT=1
|
||||||
env.TARGETS_MACOS=1
|
env.TARGETS_MACOS=1
|
||||||
env.PACKAGE_NAME="ResgenSwift" // xcodebuild -list => Only 1 scheme
|
|
||||||
|
|
||||||
iOSpipeline()
|
iOSpipeline()
|
||||||
|
@ -1,21 +1,75 @@
|
|||||||
{
|
{
|
||||||
"pins" : [
|
"pins" : [
|
||||||
|
{
|
||||||
|
"identity" : "collectionconcurrencykit",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/JohnSundell/CollectionConcurrencyKit.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "b4f23e24b5a1bff301efc5e70871083ca029ff95",
|
||||||
|
"version" : "0.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "cryptoswift",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/krzyzanowskim/CryptoSwift.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "c9c3df6ab812de32bae61fc0cd1bf6d45170ebf0",
|
||||||
|
"version" : "1.8.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "sourcekitten",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/jpsim/SourceKitten.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "b6dc09ee51dfb0c66e042d2328c017483a1a5d56",
|
||||||
|
"version" : "0.34.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"identity" : "swift-argument-parser",
|
"identity" : "swift-argument-parser",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/apple/swift-argument-parser",
|
"location" : "https://github.com/apple/swift-argument-parser",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "41982a3656a71c768319979febd796c6fd111d5c",
|
"revision" : "8f4d2753f0e4778c76d5f05ad16c74f707390531",
|
||||||
"version" : "1.5.0"
|
"version" : "1.2.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"identity" : "swiftlintplugin",
|
"identity" : "swift-syntax",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/lukepistrol/SwiftLintPlugin",
|
"location" : "https://github.com/apple/swift-syntax.git",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "87454f5c9ff4d644086aec2a0df1ffba678e7f3c",
|
"revision" : "6ad4ea24b01559dde0773e3d091f1b9e36175036",
|
||||||
"version" : "0.57.1"
|
"version" : "509.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swiftlint",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/realm/SwiftLint.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "f17a4f9dfb6a6afb0408426354e4180daaf49cee",
|
||||||
|
"version" : "0.54.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swiftytexttable",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/scottrhoyt/SwiftyTextTable.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "c6df6cf533d120716bff38f8ff9885e1ce2a4ac3",
|
||||||
|
"version" : "0.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swxmlhash",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/drmohundro/SWXMLHash.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "a853604c9e9a83ad9954c7e3d2a565273982471f",
|
||||||
|
"version" : "7.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1,25 +1,16 @@
|
|||||||
// swift-tools-version:5.9
|
// swift-tools-version:5.6
|
||||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||||
|
|
||||||
import PackageDescription
|
import PackageDescription
|
||||||
|
|
||||||
let package = Package(
|
let package = Package(
|
||||||
name: "ResgenSwift",
|
name: "ResgenSwift",
|
||||||
platforms: [.macOS(.v14), .iOS(.v15)],
|
platforms: [.macOS(.v12)],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
// Dependencies declare other packages that this package depends on.
|
// Dependencies declare other packages that this package depends on.
|
||||||
.package(
|
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.0.0"),
|
||||||
url: "https://github.com/apple/swift-argument-parser",
|
.package(url: "https://github.com/jpsim/Yams.git", from: "5.0.1"),
|
||||||
from: "1.5.0"
|
.package(url: "https://github.com/realm/SwiftLint.git", .upToNextMajor(from: "0.54.0")),
|
||||||
),
|
|
||||||
.package(
|
|
||||||
url: "https://github.com/jpsim/Yams.git",
|
|
||||||
from: "5.0.1"
|
|
||||||
),
|
|
||||||
.package(
|
|
||||||
url: "https://github.com/lukepistrol/SwiftLintPlugin",
|
|
||||||
exact: "0.57.1"
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
||||||
@ -28,15 +19,10 @@ let package = Package(
|
|||||||
name: "ResgenSwift",
|
name: "ResgenSwift",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
"ToolCore",
|
"ToolCore",
|
||||||
"Yams",
|
.product(name: "ArgumentParser", package: "swift-argument-parser"),
|
||||||
.product(
|
"Yams"
|
||||||
name: "ArgumentParser",
|
|
||||||
package: "swift-argument-parser"
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
plugins: [
|
plugins: [.plugin(name: "SwiftLintPlugin", package: "SwiftLint")]
|
||||||
// .plugin(name: "SwiftLint", package: "SwiftLintPlugin")
|
|
||||||
]
|
|
||||||
),
|
),
|
||||||
|
|
||||||
// Helper targets
|
// Helper targets
|
||||||
|
35
README.md
@ -133,7 +133,7 @@ swift run -c release ResgenSwift strings tags $FORCE_FLAG "./Tags/tags.txt" \
|
|||||||
6. `--extension-suffix` *(optional)* : additional text which is added to filename (ex: `AppTags+GreatApp.swift`)
|
6. `--extension-suffix` *(optional)* : additional text which is added to filename (ex: `AppTags+GreatApp.swift`)
|
||||||
7. `--static-members` *(optional)*: generate static properties or not
|
7. `--static-members` *(optional)*: generate static properties or not
|
||||||
|
|
||||||
> ⚠️ If extension name is not set or is `Tags`, it will generate the following typaloas `typealias Tags = String`.
|
> ⚠️ If extension name is not set or is `Tags`, it will generate the following typealias `typealias Tags = String`.
|
||||||
|
|
||||||
|
|
||||||
## Analytics
|
## Analytics
|
||||||
@ -141,7 +141,7 @@ swift run -c release ResgenSwift strings tags $FORCE_FLAG "./Tags/tags.txt" \
|
|||||||
Analytics will generate all you need to analyze UX with Matomo or Firebase Analytics. Input files are formatted in YAML. This command will generate a manager for each target and an AnalyticsManager. This is this one you will need to use. And it will generate a method for all tags you have declared in the YAML file. Next, you will need to use the `configure()` method of AnalyticsManager and if you want to use matomo to set up the `siteId` and the `url` of the site.
|
Analytics will generate all you need to analyze UX with Matomo or Firebase Analytics. Input files are formatted in YAML. This command will generate a manager for each target and an AnalyticsManager. This is this one you will need to use. And it will generate a method for all tags you have declared in the YAML file. Next, you will need to use the `configure()` method of AnalyticsManager and if you want to use matomo to set up the `siteId` and the `url` of the site.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
swift run -c release ResgenSwift strings tags $FORCE_FLAG "./Tags/tags.txt" \
|
swift run -c release ResgenSwift analytics $FORCE_FLAG "./Tags/analytics.yml" \
|
||||||
--target "matomo firebase" \
|
--target "matomo firebase" \
|
||||||
--extension-output-path "./Analytics/Generated" \
|
--extension-output-path "./Analytics/Generated" \
|
||||||
--extension-name "AppAnalytics" \
|
--extension-name "AppAnalytics" \
|
||||||
@ -159,7 +159,7 @@ swift run -c release ResgenSwift strings tags $FORCE_FLAG "./Tags/tags.txt" \
|
|||||||
6. `--extension-suffix` *(optional)* : additional text which is added to filename (ex: `AppAnalytics+GreatApp.swift`)
|
6. `--extension-suffix` *(optional)* : additional text which is added to filename (ex: `AppAnalytics+GreatApp.swift`)
|
||||||
7. `--static-members` *(optional)*: generate static properties or not
|
7. `--static-members` *(optional)*: generate static properties or not
|
||||||
|
|
||||||
> ⚠️ If extension name is not set or is `Analytics`, it will generate the following typaloas `typealias Analytics = String`.
|
> ⚠️ If extension name is not set or is `Analytics`, it will generate the following typealias `typealias Analytics = String`.
|
||||||
|
|
||||||
### YAML
|
### YAML
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ swift run -c release ResgenSwift strings tags $FORCE_FLAG "./Tags/tags.txt" \
|
|||||||
7. `comments` *(optional)*
|
7. `comments` *(optional)*
|
||||||
8. `parameters` *(optional)*
|
8. `parameters` *(optional)*
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
You can use parameters in generate methods.
|
You can use parameters in generate methods.
|
||||||
|
|
||||||
@ -199,6 +199,24 @@ You can use parameters in generate methods.
|
|||||||
This is section is equivalent of `%s | %d | %f | %@`. You can put the content of the parameter in *name*, *path*, *action*, *category*.
|
This is section is equivalent of `%s | %d | %f | %@`. You can put the content of the parameter in *name*, *path*, *action*, *category*.
|
||||||
You need to put `_` + `NAME OF THE PARAMETER` + `_` in the target and which target you want in the value of `replaceIn`. (name need to be in uppercase)
|
You need to put `_` + `NAME OF THE PARAMETER` + `_` in the target and which target you want in the value of `replaceIn`. (name need to be in uppercase)
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
events:
|
||||||
|
id: id_of_tag
|
||||||
|
name: _TITLE_
|
||||||
|
tags: ios,droid
|
||||||
|
parameters:
|
||||||
|
- name: title
|
||||||
|
type: String
|
||||||
|
replaceIn: name
|
||||||
|
```
|
||||||
|
|
||||||
|
In this sample, we want to add the parameter `title` in the field `name`. So, we need to place `_TITLE_` in the field `name`.
|
||||||
|
|
||||||
|
The generated method will be:
|
||||||
|
```
|
||||||
|
logIdOfTag(title: String)
|
||||||
|
```
|
||||||
|
|
||||||
## Images
|
## Images
|
||||||
|
|
||||||
@ -287,6 +305,15 @@ tags:
|
|||||||
extensionName: String?
|
extensionName: String?
|
||||||
extensionSuffix: String?
|
extensionSuffix: String?
|
||||||
staticMembers: Bool?
|
staticMembers: Bool?
|
||||||
|
|
||||||
|
analytics:
|
||||||
|
-
|
||||||
|
inputFile: String
|
||||||
|
target: String
|
||||||
|
extensionOutputPath: String
|
||||||
|
extensionName: String?
|
||||||
|
extensionSuffix: String?
|
||||||
|
staticMembers: Bool?
|
||||||
```
|
```
|
||||||
|
|
||||||
### Multiple configurations
|
### Multiple configurations
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Generated by ResgenSwift.Color 2.1.0
|
// Generated by ResgenSwift.Color 1.2
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
// Generated by ResgenSwift.Color 2.1.0
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
extension UIhkjhkColorYolo {
|
|
||||||
|
|
||||||
/// Color red is #FF0000 (light) or #FF0000 (dark)"
|
|
||||||
@objc var red: UIColor {
|
|
||||||
UIColor(named: "red")!
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Color green_alpha_50 is #A000FF00 (light) or #A000FF00 (dark)"
|
|
||||||
@objc var green_alpha_50: UIColor {
|
|
||||||
UIColor(named: "green_alpha_50")!
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Color blue_light_dark is #0000FF (light) or #0000AA (dark)"
|
|
||||||
@objc var blue_light_dark: UIColor {
|
|
||||||
UIColor(named: "blue_light_dark")!
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
// Generated by ResgenSwift.Fonts 2.1.0
|
// Generated by ResgenSwift.Fonts 1.2
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Generated by ResgenSwift.Fonts 2.1.0
|
// Generated by ResgenSwift.Fonts 1.2
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
|
@ -6,16 +6,16 @@
|
|||||||
<array/>
|
<array/>
|
||||||
<key>UIAppFonts</key>
|
<key>UIAppFonts</key>
|
||||||
<array>
|
<array>
|
||||||
<string>Lato-Italic.ttf</string>
|
<string>Lato-Italic</string>
|
||||||
<string>Lato-LightItalic.ttf</string>
|
<string>Lato-LightItalic</string>
|
||||||
<string>Lato-Thin.ttf</string>
|
<string>Lato-Hairline</string>
|
||||||
<string>Lato-Bold.ttf</string>
|
<string>Lato-Bold</string>
|
||||||
<string>Lato-Black.ttf</string>
|
<string>Lato-Black</string>
|
||||||
<string>Lato-Regular.ttf</string>
|
<string>Lato-Regular</string>
|
||||||
<string>Lato-BlackItalic.ttf</string>
|
<string>Lato-BlackItalic</string>
|
||||||
<string>Lato-BoldItalic.ttf</string>
|
<string>Lato-BoldItalic</string>
|
||||||
<string>Lato-Light.ttf</string>
|
<string>Lato-Light</string>
|
||||||
<string>Lato-ThinItalic.ttf</string>
|
<string>Lato-HairlineItalic</string>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
@ -6,16 +6,16 @@
|
|||||||
<array/>
|
<array/>
|
||||||
<key>UIAppFonts</key>
|
<key>UIAppFonts</key>
|
||||||
<array>
|
<array>
|
||||||
<string>Lato-Italic.ttf</string>
|
<string>Lato-Italic</string>
|
||||||
<string>Lato-LightItalic.ttf</string>
|
<string>Lato-LightItalic</string>
|
||||||
<string>Lato-Thin.ttf</string>
|
<string>Lato-Hairline</string>
|
||||||
<string>Lato-Bold.ttf</string>
|
<string>Lato-Bold</string>
|
||||||
<string>Lato-Black.ttf</string>
|
<string>Lato-Black</string>
|
||||||
<string>Lato-Regular.ttf</string>
|
<string>Lato-Regular</string>
|
||||||
<string>Lato-BlackItalic.ttf</string>
|
<string>Lato-BlackItalic</string>
|
||||||
<string>Lato-BoldItalic.ttf</string>
|
<string>Lato-BoldItalic</string>
|
||||||
<string>Lato-Light.ttf</string>
|
<string>Lato-Light</string>
|
||||||
<string>Lato-ThinItalic.ttf</string>
|
<string>Lato-HairlineItalic</string>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Generated by ResgenSwift.Images 2.1.0
|
// Generated by ResgenSwift.Images 1.2
|
||||||
// Images from sampleImages
|
// Images from sampleImages
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
// Generated by ResgenSwift.Images 2.1.0
|
|
||||||
// Images from sampleImages
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
extension UIImageYolo {
|
|
||||||
|
|
||||||
var article_notification_pull_detail: UIImage {
|
|
||||||
UIImage(named: "article_notification_pull_detail")!
|
|
||||||
}
|
|
||||||
|
|
||||||
var article_notification_pull: UIImage {
|
|
||||||
UIImage(named: "article_notification_pull")!
|
|
||||||
}
|
|
||||||
|
|
||||||
var new_article: UIImage {
|
|
||||||
UIImage(named: "new_article")!
|
|
||||||
}
|
|
||||||
|
|
||||||
var welcome_background: UIImage {
|
|
||||||
UIImage(named: "welcome_background")!
|
|
||||||
}
|
|
||||||
|
|
||||||
var article_trash: UIImage {
|
|
||||||
UIImage(named: "article_trash")!
|
|
||||||
}
|
|
||||||
|
|
||||||
var ic_close_article: UIImage {
|
|
||||||
UIImage(named: "ic_close_article")!
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,16 +1,23 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "article_notification_pull.svg",
|
"idiom" : "universal",
|
||||||
"idiom" : "universal"
|
"scale" : "1x",
|
||||||
|
"filename" : "article_notification_pull.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x",
|
||||||
|
"filename" : "article_notification_pull@2x.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x",
|
||||||
|
"filename" : "article_notification_pull@3x.png"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"info" : {
|
"info" : {
|
||||||
"author" : "ResgenSwift-Imagium",
|
"version" : 1,
|
||||||
"version" : 1
|
"author" : "ResgenSwift-Imagium"
|
||||||
},
|
|
||||||
"properties" : {
|
|
||||||
"preserves-vector-representation" : true,
|
|
||||||
"template-rendering-intent" : "original"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
BIN
SampleFiles/Images/imagium.xcassets/article_notification_pull.imageset/article_notification_pull.png
vendored
Normal file
After Width: | Height: | Size: 5.4 KiB |
@ -1,21 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<svg width="111px" height="69px" viewBox="0 0 111 69" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
||||||
<title>article_notification_pull</title>
|
|
||||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
||||||
<g id="article_notification_pull">
|
|
||||||
<path d="M81.130223,39.5772 C81.130223,39.5772 99.360223,32.4231 102.116223,33.2806 C104.871223,34.1381 111.204223,51.339 110.013223,51.8526 C108.758223,52.4481 102.001223,47.0974 102.001223,47.0974 C102.001223,47.0974 100.834223,50.2797 98.387023,49.5337 C95.939623,48.7877 92.897623,44.9219 92.897623,44.9219 C92.897623,44.9219 92.488923,47.0487 89.986323,46.4577 C87.483723,45.8667 83.726623,41.567 83.726623,41.567 L81.130223,39.5772 Z" id="Path" fill="#FFFFFF" fill-rule="nonzero"></path>
|
|
||||||
<path d="M99.259223,10.5629 C97.894023,10.5629 96.788623,9.4412 96.788623,8.0557 C96.788623,7.4619 96.333423,7 95.748223,7 C95.163023,7 94.707823,7.4619 94.707823,8.0557 C94.707823,9.4412 93.602423,10.5629 92.237023,10.5629 C91.651723,10.5629 91.196623,11.0247 91.196623,11.6185 C91.196623,12.2124 91.651723,12.6742 92.237023,12.6742 C93.602423,12.6742 94.707823,13.7959 94.707823,15.1814 C94.707823,15.7752 95.163023,16.2371 95.748223,16.2371 C96.333423,16.2371 96.788623,15.7752 96.788623,15.1814 C96.788623,13.7959 97.894023,12.6742 99.259223,12.6742 C99.844223,12.6742 100.300223,12.2124 100.300223,11.6185 C100.365223,11.0907 99.844223,10.5629 99.259223,10.5629 Z" id="Path" fill="#FFFFFF" fill-rule="nonzero"></path>
|
|
||||||
<path d="M81.193523,11.2243 C80.403523,10.8878 79.962423,9.9515 80.333423,9.0805 C80.502023,8.6847 80.287223,8.3125 79.971223,8.1779 C79.576223,8.0096 79.204323,8.2254 79.069423,8.5421 C78.732123,9.3338 77.796523,9.7772 76.927523,9.407 C76.532523,9.2387 76.160623,9.4544 76.025723,9.7711 C75.857023,10.167 76.071823,10.5391 76.387823,10.6738 C77.177923,11.0103 77.619023,11.9466 77.248023,12.8175 C77.079423,13.2134 77.294223,13.5855 77.610223,13.7201 C78.005223,13.8884 78.377123,13.6727 78.512023,13.356 C78.849323,12.5642 79.784923,12.1209 80.653923,12.4911 C81.048923,12.6594 81.420823,12.4436 81.555723,12.1269 C81.769623,11.8439 81.588623,11.3926 81.193523,11.2243 Z" id="Path" fill="#FFFFFF" fill-rule="nonzero"></path>
|
|
||||||
<line x1="12.845223" y1="48.192" x2="16.110123" y2="42" id="Path" stroke-opacity="0.8" stroke="#FFFFFF" stroke-width="2" stroke-linecap="round"></line>
|
|
||||||
<ellipse id="Oval" fill-opacity="0.1" fill="#000000" fill-rule="nonzero" cx="50.345223" cy="67.5" rx="17.5" ry="1.5"></ellipse>
|
|
||||||
<line x1="14.517923" y1="53.5959" x2="17.782723" y2="47.404" id="Path" stroke-opacity="0.8" stroke="#FFFFFF" stroke-width="2" stroke-linecap="round"></line>
|
|
||||||
<line x1="20.806323" y1="52.3897" x2="23.604823" y2="47.0823" id="Path" stroke-opacity="0.8" stroke="#FFFFFF" stroke-width="2" stroke-linecap="round"></line>
|
|
||||||
<path d="M79.876623,1.78144 C79.226423,1.78144 78.641223,1.2536 78.641223,0.52783 C78.641223,0.19794 78.381123,0 78.121023,0 C77.795923,0 77.600823,0.26392 77.600823,0.52783 C77.600823,1.18763 77.080623,1.78144 76.365423,1.78144 C76.040323,1.78144 75.845223,2.04535 75.845223,2.30927 C75.845223,2.63917 76.105323,2.8371 76.365423,2.8371 C77.015623,2.8371 77.600823,3.3649 77.600823,4.0907 C77.600823,4.4206 77.860923,4.6185 78.121023,4.6185 C78.446123,4.6185 78.641223,4.3546 78.641223,4.0907 C78.641223,3.4309 79.161423,2.8371 79.876623,2.8371 C80.201823,2.8371 80.396823,2.57319 80.396823,2.30927 C80.461923,2.04535 80.201823,1.78144 79.876623,1.78144 Z" id="Path" fill="#FFFFFF" fill-rule="nonzero"></path>
|
|
||||||
<path d="M31.021323,19.8983 C31.021323,19.8983 19.126423,4.2537 16.379623,3.4694 C13.568923,2.76686 -0.694914027,14.1215 0.0264229726,15.2225 C0.756502973,16.3967 9.32942297,15.3706 9.32942297,15.3706 C9.32942297,15.3706 8.62499297,18.7201 11.136323,19.3843 C13.647723,20.0484 18.238723,18.3857 18.238723,18.3857 C18.238723,18.3857 17.521923,20.401 19.905523,21.2288 C22.289123,22.0567 27.760723,20.3628 27.760723,20.3628 L31.021323,19.8983 Z" id="Path" fill="#E0EDF3" fill-rule="nonzero"></path>
|
|
||||||
<path d="M89.710223,24.4503 L77.707723,58.391 C77.385623,59.3943 76.267023,59.8992 75.270023,59.5733 L21.900823,40.3589 C20.903823,40.033 20.400423,38.9059 20.722523,37.9026 L32.788923,3.88 C32.835323,3.6518 32.954323,3.4149 33.154823,3.2425 C33.674723,2.66083 34.456323,2.41884 35.299323,2.689 L88.604623,21.9853 C89.374923,22.2641 89.834523,23.0254 89.849423,23.7658 C89.875623,23.9852 89.829323,24.2134 89.710223,24.4503 Z" id="Path" fill="#FFD100" fill-rule="nonzero"></path>
|
|
||||||
<path d="M23.390523,38.0285 L52.772523,31.6916 C54.280623,31.3626 55.821223,31.9203 56.778023,33.1416 L75.925523,57.0459 L57.901923,31.4487 C56.910123,29.9348 55.061323,29.2655 53.361523,29.84 L23.390523,38.0285 Z" id="Path" fill="#DA9135" fill-rule="nonzero"></path>
|
|
||||||
<path d="M89.803023,23.9939 L54.122423,34.35 L33.108423,3.4707 C33.610823,2.74268 34.529023,2.41014 35.299323,2.68899 L88.604623,21.9853 C89.374923,22.2641 89.770623,23.1073 89.803023,23.9939 Z" id="Path" fill="#FFDF4F" fill-rule="nonzero"></path>
|
|
||||||
<path d="M34.370723,5.3975 L52.679723,32.148 C53.572623,33.4511 55.113223,34.0088 56.685323,33.598 L87.402923,24.8749 L56.375623,35.9356 C54.611823,36.592 52.771823,35.9959 51.835123,34.327 L34.370723,5.3975 Z" id="Path" fill="#DA9135" fill-rule="nonzero"></path>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 5.4 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 18 KiB |
@ -1,16 +1,23 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "article_notification_pull_detail.svg",
|
"idiom" : "universal",
|
||||||
"idiom" : "universal"
|
"scale" : "1x",
|
||||||
|
"filename" : "article_notification_pull_detail.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x",
|
||||||
|
"filename" : "article_notification_pull_detail@2x.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x",
|
||||||
|
"filename" : "article_notification_pull_detail@3x.png"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"info" : {
|
"info" : {
|
||||||
"author" : "ResgenSwift-Imagium",
|
"version" : 1,
|
||||||
"version" : 1
|
"author" : "ResgenSwift-Imagium"
|
||||||
},
|
|
||||||
"properties" : {
|
|
||||||
"preserves-vector-representation" : true,
|
|
||||||
"template-rendering-intent" : "original"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
After Width: | Height: | Size: 5.9 KiB |
@ -1,21 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<svg width="111px" height="69px" viewBox="0 0 111 69" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
||||||
<title>article_notification_pull_detail</title>
|
|
||||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
||||||
<g id="article_notification_pull_detail" transform="translate(0.000000, 0.000000)">
|
|
||||||
<path d="M81.1301131,39.5772 C81.1301131,39.5772 99.3602131,32.4231 102.116213,33.2806 C104.871213,34.1381 111.204213,51.339 110.013213,51.8526 C108.758213,52.4481 102.001213,47.0974 102.001213,47.0974 C102.001213,47.0974 100.834213,50.2797 98.3869131,49.5337 C95.9395131,48.7877 92.8975131,44.9219 92.8975131,44.9219 C92.8975131,44.9219 92.4888131,47.0487 89.9862131,46.4577 C87.4836131,45.8667 83.7265131,41.567 83.7265131,41.567 L81.1301131,39.5772 Z" id="Path" fill="#E0EDF3" fill-rule="nonzero"></path>
|
|
||||||
<path d="M99.2592131,10.5629 C97.8940131,10.5629 96.7886131,9.4412 96.7886131,8.0557 C96.7886131,7.4619 96.3334131,7 95.7482131,7 C95.1630131,7 94.7078131,7.4619 94.7078131,8.0557 C94.7078131,9.4412 93.6024131,10.5629 92.2370131,10.5629 C91.6517131,10.5629 91.1966131,11.0247 91.1966131,11.6185 C91.1966131,12.2124 91.6517131,12.6742 92.2370131,12.6742 C93.6024131,12.6742 94.7078131,13.7959 94.7078131,15.1814 C94.7078131,15.7752 95.1630131,16.2371 95.7482131,16.2371 C96.3334131,16.2371 96.7886131,15.7752 96.7886131,15.1814 C96.7886131,13.7959 97.8940131,12.6742 99.2592131,12.6742 C99.8442131,12.6742 100.300213,12.2124 100.300213,11.6185 C100.365213,11.0907 99.8442131,10.5629 99.2592131,10.5629 Z" id="Path" fill="#E0EDF3" fill-rule="nonzero"></path>
|
|
||||||
<path d="M81.1934131,11.2243 C80.4034131,10.8878 79.9623131,9.9515 80.3333131,9.0805 C80.5019131,8.6847 80.2871131,8.3125 79.9711131,8.1779 C79.5761131,8.0096 79.2042131,8.2254 79.0693131,8.5421 C78.7320131,9.3338 77.7964131,9.7772 76.9274131,9.407 C76.5324131,9.2387 76.1605131,9.4544 76.0256131,9.7711 C75.8569131,10.167 76.0717131,10.5391 76.3877131,10.6738 C77.1778131,11.0103 77.6189131,11.9466 77.2479131,12.8175 C77.0793131,13.2134 77.2941131,13.5855 77.6101131,13.7201 C78.0051131,13.8884 78.3770131,13.6727 78.5119131,13.356 C78.8492131,12.5642 79.7848131,12.1209 80.6538131,12.4911 C81.0488131,12.6594 81.4207131,12.4436 81.5556131,12.1269 C81.7695131,11.8439 81.5885131,11.3926 81.1934131,11.2243 Z" id="Path" fill="#E0EDF3" fill-rule="nonzero"></path>
|
|
||||||
<line x1="12.8452131" y1="48.192" x2="16.1101131" y2="42" id="Path" stroke-opacity="0.8" stroke="#E0EDF3" stroke-width="2" stroke-linecap="round"></line>
|
|
||||||
<path d="M50.3452131,69 C60.0102131,69 67.8452131,68.3284 67.8452131,67.5 C67.8452131,66.6716 60.0102131,66 50.3452131,66 C40.6802131,66 32.8452131,66.6716 32.8452131,67.5 C32.8452131,68.3284 40.6802131,69 50.3452131,69 Z" id="Path" fill-opacity="0.1" fill="#000000" fill-rule="nonzero"></path>
|
|
||||||
<line x1="14.5178131" y1="53.5959" x2="17.7826131" y2="47.404" id="Path" stroke-opacity="0.8" stroke="#E0EDF3" stroke-width="2" stroke-linecap="round"></line>
|
|
||||||
<line x1="20.8064131" y1="52.3897" x2="23.6049131" y2="47.0823" id="Path" stroke-opacity="0.8" stroke="#E0EDF3" stroke-width="2" stroke-linecap="round"></line>
|
|
||||||
<path d="M79.8766131,1.78144 C79.2264131,1.78144 78.6412131,1.2536 78.6412131,0.52783 C78.6412131,0.19794 78.3811131,0 78.1210131,0 C77.7959131,0 77.6008131,0.26392 77.6008131,0.52783 C77.6008131,1.18763 77.0806131,1.78144 76.3654131,1.78144 C76.0403131,1.78144 75.8452131,2.04535 75.8452131,2.30927 C75.8452131,2.63917 76.1053131,2.8371 76.3654131,2.8371 C77.0156131,2.8371 77.6008131,3.3649 77.6008131,4.0907 C77.6008131,4.4206 77.8609131,4.6185 78.1210131,4.6185 C78.4461131,4.6185 78.6412131,4.3546 78.6412131,4.0907 C78.6412131,3.4309 79.1614131,2.8371 79.8766131,2.8371 C80.2018131,2.8371 80.3968131,2.57319 80.3968131,2.30927 C80.4619131,2.04535 80.2018131,1.78144 79.8766131,1.78144 Z" id="Path" fill="#E0EDF3" fill-rule="nonzero"></path>
|
|
||||||
<path d="M31.0213131,19.8983 C31.0213131,19.8983 19.1264131,4.2537 16.3796131,3.4694 C13.5689131,2.76686 -0.694915869,14.1215 0.0264231309,15.2225 C0.756503131,16.3967 9.32941313,15.3706 9.32941313,15.3706 C9.32941313,15.3706 8.62499313,18.7201 11.1363131,19.3843 C13.6477131,20.0484 18.2387131,18.3857 18.2387131,18.3857 C18.2387131,18.3857 17.5219131,20.401 19.9055131,21.2288 C22.2891131,22.0567 27.7607131,20.3628 27.7607131,20.3628 L31.0213131,19.8983 Z" id="Path" fill="#E0EDF3" fill-rule="nonzero"></path>
|
|
||||||
<path d="M89.7103131,24.4503 L77.7078131,58.391 C77.3857131,59.3943 76.2671131,59.8992 75.2701131,59.5733 L21.9009131,40.3589 C20.9039131,40.033 20.4005131,38.9059 20.7226131,37.9026 L32.7890131,3.88 C32.8354131,3.6518 32.9544131,3.4149 33.1549131,3.2425 C33.6748131,2.66083 34.4564131,2.41884 35.2994131,2.689 L88.6047131,21.9853 C89.3750131,22.2641 89.8346131,23.0254 89.8495131,23.7658 C89.8757131,23.9852 89.8294131,24.2134 89.7103131,24.4503 Z" id="Path" fill="#FFD100" fill-rule="nonzero"></path>
|
|
||||||
<path d="M23.3906131,38.0285 L52.7726131,31.6916 C54.2807131,31.3626 55.8213131,31.9203 56.7781131,33.1416 L75.9256131,57.0459 L57.9020131,31.4487 C56.9102131,29.9348 55.0614131,29.2655 53.3616131,29.84 L23.3906131,38.0285 Z" id="Path" fill="#DA9135" fill-rule="nonzero"></path>
|
|
||||||
<path d="M89.8030131,23.9939 L54.1224131,34.35 L33.1084131,3.4707 C33.6108131,2.74268 34.5290131,2.41014 35.2993131,2.68899 L88.6046131,21.9853 C89.3749131,22.2641 89.7706131,23.1073 89.8030131,23.9939 Z" id="Path" fill="#FFDF4F" fill-rule="nonzero"></path>
|
|
||||||
<path d="M34.3706131,5.3975 L52.6796131,32.148 C53.5725131,33.4511 55.1131131,34.0088 56.6852131,33.598 L87.4028131,24.8749 L56.3755131,35.9356 C54.6117131,36.592 52.7717131,35.9959 51.8350131,34.327 L34.3706131,5.3975 Z" id="Path" fill="#DA9135" fill-rule="nonzero"></path>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 19 KiB |
@ -1,16 +1,23 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "article_trash.svg",
|
"idiom" : "universal",
|
||||||
"idiom" : "universal"
|
"scale" : "1x",
|
||||||
|
"filename" : "article_trash.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x",
|
||||||
|
"filename" : "article_trash@2x.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x",
|
||||||
|
"filename" : "article_trash@3x.png"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"info" : {
|
"info" : {
|
||||||
"author" : "ResgenSwift-Imagium",
|
"version" : 1,
|
||||||
"version" : 1
|
"author" : "ResgenSwift-Imagium"
|
||||||
},
|
|
||||||
"properties" : {
|
|
||||||
"preserves-vector-representation" : true,
|
|
||||||
"template-rendering-intent" : "original"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
BIN
SampleFiles/Images/imagium.xcassets/article_trash.imageset/article_trash.png
vendored
Normal file
After Width: | Height: | Size: 977 B |
@ -1,4 +0,0 @@
|
|||||||
<svg width="37" height="41" viewBox="0 0 37 41" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M1 4.87183L5.45856 32.1227C5.68952 33.5346 6.30709 34.8549 7.24275 35.9371C8.17841 37.0194 9.3956 37.8213 10.7593 38.2539L11.3943 38.4553C15.9682 39.9073 20.8795 39.9073 25.4534 38.4553L26.0884 38.2539C27.4518 37.8215 28.6688 37.0199 29.6044 35.938C30.5401 34.8561 31.1578 33.5362 31.3891 32.1246L35.8476 4.87183" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
<path d="M18.4238 8.74392C28.0467 8.74392 35.8476 7.01039 35.8476 4.87196C35.8476 2.73354 28.0467 1 18.4238 1C8.80091 1 1 2.73354 1 4.87196C1 7.01039 8.80091 8.74392 18.4238 8.74392Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 772 B |
BIN
SampleFiles/Images/imagium.xcassets/article_trash.imageset/article_trash@2x.png
vendored
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
SampleFiles/Images/imagium.xcassets/article_trash.imageset/article_trash@3x.png
vendored
Normal file
After Width: | Height: | Size: 2.9 KiB |
@ -1,16 +1,23 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "ic_close_article.svg",
|
"idiom" : "universal",
|
||||||
"idiom" : "universal"
|
"scale" : "1x",
|
||||||
|
"filename" : "ic_close_article.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x",
|
||||||
|
"filename" : "ic_close_article@2x.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x",
|
||||||
|
"filename" : "ic_close_article@3x.png"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"info" : {
|
"info" : {
|
||||||
"author" : "ResgenSwift-Imagium",
|
"version" : 1,
|
||||||
"version" : 1
|
"author" : "ResgenSwift-Imagium"
|
||||||
},
|
|
||||||
"properties" : {
|
|
||||||
"preserves-vector-representation" : true,
|
|
||||||
"template-rendering-intent" : "original"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
BIN
SampleFiles/Images/imagium.xcassets/ic_close_article.imageset/ic_close_article.png
vendored
Normal file
After Width: | Height: | Size: 330 B |
@ -1,4 +0,0 @@
|
|||||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M11.41 1.41L10 0L5.705 4.295L1.41 0L0 1.41L4.295 5.705L0 10L1.41 11.41L5.705 7.115L10 11.41L11.41 10L7.115 5.705L11.41 1.41Z"
|
|
||||||
fill="#EFF2F4" />
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 268 B |
BIN
SampleFiles/Images/imagium.xcassets/ic_close_article.imageset/ic_close_article@2x.png
vendored
Normal file
After Width: | Height: | Size: 513 B |
BIN
SampleFiles/Images/imagium.xcassets/ic_close_article.imageset/ic_close_article@3x.png
vendored
Normal file
After Width: | Height: | Size: 647 B |
@ -1,16 +1,23 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "new_article.svg",
|
"idiom" : "universal",
|
||||||
"idiom" : "universal"
|
"scale" : "1x",
|
||||||
|
"filename" : "new_article.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x",
|
||||||
|
"filename" : "new_article@2x.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x",
|
||||||
|
"filename" : "new_article@3x.png"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"info" : {
|
"info" : {
|
||||||
"author" : "ResgenSwift-Imagium",
|
"version" : 1,
|
||||||
"version" : 1
|
"author" : "ResgenSwift-Imagium"
|
||||||
},
|
|
||||||
"properties" : {
|
|
||||||
"preserves-vector-representation" : true,
|
|
||||||
"template-rendering-intent" : "original"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
BIN
SampleFiles/Images/imagium.xcassets/new_article.imageset/new_article.png
vendored
Normal file
After Width: | Height: | Size: 6.0 KiB |
@ -1,54 +0,0 @@
|
|||||||
<svg width="102" height="69" viewBox="0 0 102 69" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M100.089 35.765H72.7522V66.626H100.089V35.765Z" fill="#DEF1F8"/>
|
|
||||||
<path d="M89.1215 46.2884H56.9285V66.6806H89.1215V46.2884Z" fill="#FAFAFA"/>
|
|
||||||
<path d="M100.089 46.2883H89.1216V66.6805H100.089V46.2883Z" fill="#DEF1F8"/>
|
|
||||||
<path d="M84.9199 49.5053H82.8464V53.1039H84.9199V49.5053Z" fill="#DEF1F8"/>
|
|
||||||
<path d="M80.8276 49.5053H78.7542V53.1039H80.8276V49.5053Z" fill="#DEF1F8"/>
|
|
||||||
<path d="M62.8759 60.3557H60.8025V63.9543H62.8759V60.3557Z" fill="#DEF1F8"/>
|
|
||||||
<path d="M97.7973 37.7279H95.7239V41.3266H97.7973V37.7279Z" fill="#FAFAFA"/>
|
|
||||||
<path d="M76.9538 37.7279H74.8804V41.3266H76.9538V37.7279Z" fill="#FAFAFA"/>
|
|
||||||
<path d="M36.4457 27.1985H101.509C101.728 25.2457 100.03 23.1303 98.1679 22.4794C96.251 21.8285 94.1699 21.72 92.4721 20.6351C90.3362 19.2791 89.1861 16.5127 86.7216 15.8076C84.3666 15.1566 82.0117 16.7839 79.5472 16.8924C74.5086 17.1094 70.6202 10.8715 65.6364 11.7394C62.2956 12.336 60.3788 15.8076 57.3666 17.3263C54.8473 18.6282 51.8352 18.3569 48.9873 18.7366C44.1678 19.4418 39.2388 23.3472 36.4457 27.1985Z" fill="#DEF1F8"/>
|
|
||||||
<path d="M0.455092 25.2296L32.2995 0.974118C33.9893 -0.324706 36.3288 -0.324706 38.0185 0.974118L69.8305 25.2296C70.1229 25.4569 70.2854 25.8141 70.2854 26.1713V67.7661C70.2854 68.4155 69.7655 68.9351 69.1156 68.9351H1.20246C0.552574 68.9351 0.0326646 68.4155 0.0326646 67.7661V26.1713C0.0001703 25.8141 0.162643 25.4569 0.455092 25.2296Z" fill="url(#paint0_linear)"/>
|
|
||||||
<path d="M53.973 13.183H16.3121L10.5281 17.5666V68.935H59.7245V17.5666L53.973 13.183Z" fill="#FDB918"/>
|
|
||||||
<path d="M55.9878 6.55914H14.2651C12.8353 6.55914 11.6655 7.72808 11.6655 9.15679V64.7789C11.6655 66.2076 12.8353 67.3765 14.2651 67.3765H55.9878C57.4176 67.3765 58.5874 66.2076 58.5874 64.7789V9.15679C58.5874 7.72808 57.4176 6.55914 55.9878 6.55914Z" fill="#FAFAFA"/>
|
|
||||||
<path d="M35.1265 47.2773L68.4657 67.8312C69.2455 68.3182 70.2528 67.7662 70.2528 66.8246V27.6975C70.2528 26.7883 69.2455 26.2039 68.4657 26.6909L35.1265 47.2773Z" fill="url(#paint1_linear)"/>
|
|
||||||
<path d="M0 27.6974V66.8245C0 67.7336 1.00732 68.3181 1.78719 67.831L35.1264 47.2772L1.78719 26.6908C1.00732 26.2038 0 26.7882 0 27.6974Z" fill="url(#paint2_linear)"/>
|
|
||||||
<path d="M40.3255 44.0627L38.1808 42.4392C36.3611 41.0429 33.8591 41.0429 32.0394 42.4392L29.8948 44.0627L35.0939 47.2773L40.3255 44.0627Z" fill="#E6E6E6"/>
|
|
||||||
<path d="M0 67.1491L35.1264 47.2771L29.9273 44.0626L0 67.1491Z" fill="#FDB918"/>
|
|
||||||
<path d="M70.2528 67.1491L35.1265 47.2771L40.3256 44.0626L70.2528 67.1491Z" fill="#FDB918"/>
|
|
||||||
<path d="M29.1147 17.3064C29.1147 17.3064 28.8872 19.969 35.1262 21.4627L33.7939 21.3977C33.7939 21.3977 29.6996 20.9756 28.7573 19.2547C27.8149 17.5337 29.1147 17.3064 29.1147 17.3064Z" fill="#FDB918"/>
|
|
||||||
<path d="M30.1545 15.9104C33.079 13.053 34.9312 21.4304 34.9637 21.4629C35.0287 21.4629 35.0937 21.4629 35.1587 21.4629C35.1587 21.4629 33.014 9.90333 29.4396 14.709C25.6053 19.7744 30.0245 21.3654 35.1262 21.4629C30.7719 21.333 26.8076 19.1574 30.1545 15.9104Z" fill="#FFE368"/>
|
|
||||||
<path d="M40.9753 17.3064C40.9753 17.3064 41.2028 19.969 34.9639 21.4627L36.2961 21.3977C36.2961 21.3977 40.3904 20.9756 41.3328 19.2547C42.2426 17.5337 40.9753 17.3064 40.9753 17.3064Z" fill="#FDB918"/>
|
|
||||||
<path d="M39.9353 15.9104C37.0108 13.053 35.1586 21.4304 35.1261 21.4629C35.0611 21.4629 34.9961 21.4629 34.9312 21.4629C34.9312 21.4629 37.0758 9.90333 40.6502 14.709C44.452 19.7744 40.0328 21.3654 34.9312 21.4629C39.3179 21.333 43.2497 19.1574 39.9353 15.9104Z" fill="#FFE368"/>
|
|
||||||
<path d="M27.3926 36.237V22.0798C27.3926 21.7226 27.685 21.4304 28.0425 21.4304H42.21C42.5674 21.4304 42.8599 21.7226 42.8599 22.0798V36.237C42.8599 36.5941 42.5674 36.8864 42.21 36.8864H28.0425C27.685 36.8864 27.3926 36.5941 27.3926 36.237Z" fill="#063881"/>
|
|
||||||
<path d="M26.3528 24.645V22.0798C26.3528 21.7226 26.6452 21.4304 27.0027 21.4304H43.2499C43.6073 21.4304 43.8997 21.7226 43.8997 22.0798V24.645C43.8997 25.0021 43.6073 25.2944 43.2499 25.2944H27.0027C26.6452 25.2944 26.3528 25.0021 26.3528 24.645Z" fill="#0B559E"/>
|
|
||||||
<path d="M37.5959 21.4304H32.6567V25.2944H37.5959V21.4304Z" fill="#FFE368"/>
|
|
||||||
<path d="M37.3035 25.2943H32.9492V36.8863H37.3035V25.2943Z" fill="#FDB918"/>
|
|
||||||
<path d="M1.5437 69H68.8777C70.1371 69 70.6539 67.4136 69.6204 66.6839L38.0042 44.6961C36.3248 43.427 33.9673 43.427 32.2557 44.6961L0.736338 66.6839C-0.232496 67.4136 0.284216 69 1.5437 69Z" fill="url(#paint3_linear)"/>
|
|
||||||
<defs>
|
|
||||||
<linearGradient id="paint0_linear" x1="-0.00678347" y1="34.4878" x2="70.2659" y2="34.4878" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#FFE368"/>
|
|
||||||
<stop offset="0.3174" stop-color="#FFE265"/>
|
|
||||||
<stop offset="0.5172" stop-color="#FFDD5D"/>
|
|
||||||
<stop offset="0.6845" stop-color="#FED54E"/>
|
|
||||||
<stop offset="0.8339" stop-color="#FECB39"/>
|
|
||||||
<stop offset="0.9701" stop-color="#FDBD1F"/>
|
|
||||||
<stop offset="1" stop-color="#FDB918"/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="paint1_linear" x1="9.77743" y1="11.1302" x2="102.999" y2="68.0143" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#FFE368"/>
|
|
||||||
<stop offset="0.3387" stop-color="#FED750"/>
|
|
||||||
<stop offset="1" stop-color="#FDB918"/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="paint2_linear" x1="-8.63037" y1="41.2967" x2="84.5914" y2="98.1808" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#FFE368"/>
|
|
||||||
<stop offset="0.3387" stop-color="#FED750"/>
|
|
||||||
<stop offset="1" stop-color="#FDB918"/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="paint3_linear" x1="-10.5945" y1="38.7503" x2="87.7585" y2="99.7918" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#FFE368"/>
|
|
||||||
<stop offset="0.3387" stop-color="#FED750"/>
|
|
||||||
<stop offset="1" stop-color="#FDB918"/>
|
|
||||||
</linearGradient>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 5.5 KiB |
BIN
SampleFiles/Images/imagium.xcassets/new_article.imageset/new_article@2x.png
vendored
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
SampleFiles/Images/imagium.xcassets/new_article.imageset/new_article@3x.png
vendored
Normal file
After Width: | Height: | Size: 20 KiB |
@ -1,23 +1,23 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "welcome_background.png",
|
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "1x"
|
"scale" : "1x",
|
||||||
|
"filename" : "welcome_background.png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "welcome_background@2x.png",
|
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "2x"
|
"scale" : "2x",
|
||||||
|
"filename" : "welcome_background@2x.png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "welcome_background@3x.png",
|
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "3x"
|
"scale" : "3x",
|
||||||
|
"filename" : "welcome_background@3x.png"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"info" : {
|
"info" : {
|
||||||
"author" : "ResgenSwift-Imagium",
|
"version" : 1,
|
||||||
"version" : 1
|
"author" : "ResgenSwift-Imagium"
|
||||||
}
|
}
|
||||||
}
|
}
|
Before Width: | Height: | Size: 281 KiB After Width: | Height: | Size: 281 KiB |
Before Width: | Height: | Size: 813 KiB After Width: | Height: | Size: 813 KiB |
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
@ -1,4 +1,4 @@
|
|||||||
// Generated by ResgenSwift.Strings.Stringium 2.1.0
|
// Generated by ResgenSwift.Strings.Stringium 1.2
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
@ -30,9 +30,6 @@ extension String {
|
|||||||
|
|
||||||
/// Translation in en :
|
/// Translation in en :
|
||||||
/// en
|
/// en
|
||||||
///
|
|
||||||
/// Comment :
|
|
||||||
/// No comment
|
|
||||||
var param_lang: String {
|
var param_lang: String {
|
||||||
NSLocalizedString("param_lang", tableName: kStringsFileName, bundle: Bundle.main, value: "en", comment: "")
|
NSLocalizedString("param_lang", tableName: kStringsFileName, bundle: Bundle.main, value: "en", comment: "")
|
||||||
}
|
}
|
||||||
@ -41,35 +38,24 @@ extension String {
|
|||||||
|
|
||||||
/// Translation in en :
|
/// Translation in en :
|
||||||
/// Back
|
/// Back
|
||||||
///
|
|
||||||
/// Comment :
|
|
||||||
/// No comment
|
|
||||||
var generic_back: String {
|
var generic_back: String {
|
||||||
NSLocalizedString("generic_back", tableName: kStringsFileName, bundle: Bundle.main, value: "Back", comment: "")
|
NSLocalizedString("generic_back", tableName: kStringsFileName, bundle: Bundle.main, value: "Back", comment: "")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Translation in en :
|
/// Translation in en :
|
||||||
/// Loading data...
|
/// Loading data...
|
||||||
///
|
|
||||||
/// Comment :
|
|
||||||
/// No comment
|
|
||||||
var generic_loading_data: String {
|
var generic_loading_data: String {
|
||||||
NSLocalizedString("generic_loading_data", tableName: kStringsFileName, bundle: Bundle.main, value: "Loading data...", comment: "")
|
NSLocalizedString("generic_loading_data", tableName: kStringsFileName, bundle: Bundle.main, value: "Loading data...", comment: "")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Translation in en :
|
/// Translation in en :
|
||||||
/// Welcome \"%@\" !
|
/// Welcome \"%@\" !
|
||||||
///
|
|
||||||
/// Comment :
|
|
||||||
/// No comment
|
|
||||||
var generic_welcome_firstname_format: String {
|
var generic_welcome_firstname_format: String {
|
||||||
NSLocalizedString("generic_welcome_firstname_format", tableName: kStringsFileName, bundle: Bundle.main, value: "Welcome \"%@\" !", comment: "")
|
NSLocalizedString("generic_welcome_firstname_format", tableName: kStringsFileName, bundle: Bundle.main, value: "Welcome \"%@\" !", comment: "")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Translation in en :
|
/// Translation in en :
|
||||||
/// Welcome \"%@\" !
|
/// Welcome \"%@\" !
|
||||||
///
|
|
||||||
/// Comment :
|
|
||||||
/// No comment
|
|
||||||
func generic_welcome_firstname_format(arg0: String) -> String {
|
func generic_welcome_firstname_format(arg0: String) -> String {
|
||||||
String(format: self.generic_welcome_firstname_format, arg0)
|
String(format: self.generic_welcome_firstname_format, arg0)
|
||||||
}
|
}
|
||||||
@ -78,9 +64,6 @@ extension String {
|
|||||||
|
|
||||||
/// Translation in en :
|
/// Translation in en :
|
||||||
/// 1€ = 1 point !
|
/// 1€ = 1 point !
|
||||||
///
|
|
||||||
/// Comment :
|
|
||||||
/// No comment
|
|
||||||
var test_equal_symbol: String {
|
var test_equal_symbol: String {
|
||||||
NSLocalizedString("test_equal_symbol", tableName: kStringsFileName, bundle: Bundle.main, value: "1€ = 1 point !", comment: "")
|
NSLocalizedString("test_equal_symbol", tableName: kStringsFileName, bundle: Bundle.main, value: "1€ = 1 point !", comment: "")
|
||||||
}
|
}
|
||||||
@ -89,17 +72,12 @@ extension String {
|
|||||||
|
|
||||||
/// Translation in en :
|
/// Translation in en :
|
||||||
/// You %%: %2$@ %1$@ Age: %3$d
|
/// You %%: %2$@ %1$@ Age: %3$d
|
||||||
///
|
|
||||||
/// Comment :
|
|
||||||
/// No comment
|
|
||||||
var placeholders_test_one: String {
|
var placeholders_test_one: String {
|
||||||
NSLocalizedString("placeholders_test_one", tableName: kStringsFileName, bundle: Bundle.main, value: "You %%: %2$@ %1$@ Age: %3$d", comment: "")
|
NSLocalizedString("placeholders_test_one", tableName: kStringsFileName, bundle: Bundle.main, value: "You %%: %2$@ %1$@ Age: %3$d", comment: "")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Translation in en :
|
/// Translation in en :
|
||||||
/// You %%: %2$@ %1$@ Age: %3$d
|
/// You %%: %2$@ %1$@ Age: %3$d
|
||||||
///
|
|
||||||
/// Comment :
|
|
||||||
/// No comment
|
|
||||||
func placeholders_test_one(arg0: String, arg1: String, arg2: Int) -> String {
|
func placeholders_test_one(arg0: String, arg1: String, arg2: Int) -> String {
|
||||||
String(format: self.placeholders_test_one, arg0, arg1, arg2)
|
String(format: self.placeholders_test_one, arg0, arg1, arg2)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Apple Strings File
|
* Apple Strings File
|
||||||
* Generated by ResgenSwift 2.1.0
|
* Generated by ResgenSwift 1.2
|
||||||
* Language: en-us
|
* Language: en-us
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Apple Strings File
|
* Apple Strings File
|
||||||
* Generated by ResgenSwift 2.1.0
|
* Generated by ResgenSwift 1.2
|
||||||
* Language: en
|
* Language: en
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Apple Strings File
|
* Apple Strings File
|
||||||
* Generated by ResgenSwift 2.1.0
|
* Generated by ResgenSwift 1.2
|
||||||
* Language: fr
|
* Language: fr
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
// Generated by ResgenSwift.Analytics 2.1.0
|
// Generated by ResgenSwift.Analytics 1.2
|
||||||
|
|
||||||
import MatomoTracker
|
|
||||||
import FirebaseAnalytics
|
import FirebaseAnalytics
|
||||||
|
|
||||||
// MARK: - Protocol
|
// MARK: - Protocol
|
||||||
|
|
||||||
protocol AnalyticsManagerProtocol {
|
protocol AnalyticsManagerProtocol {
|
||||||
|
|
||||||
func logScreen(name: String, path: String)
|
func logScreen(name: String, path: String)
|
||||||
func logEvent(
|
func logEvent(
|
||||||
name: String,
|
name: String,
|
||||||
@ -16,72 +14,11 @@ protocol AnalyticsManagerProtocol {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Matomo
|
|
||||||
|
|
||||||
class MatomoAnalyticsManager: AnalyticsManagerProtocol {
|
|
||||||
|
|
||||||
// MARK: - Properties
|
|
||||||
|
|
||||||
private var tracker: MatomoTracker
|
|
||||||
|
|
||||||
// MARK: - Init
|
|
||||||
|
|
||||||
init(siteId: String, url: String) {
|
|
||||||
debugPrint("[Matomo service] Server URL: \(url)")
|
|
||||||
debugPrint("[Matomo service] Site ID: \(siteId)")
|
|
||||||
tracker = MatomoTracker(
|
|
||||||
siteId: siteId,
|
|
||||||
baseURL: URL(string: url)!
|
|
||||||
)
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
tracker.dispatchInterval = 5
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
tracker.logger = DefaultLogger(minLevel: .verbose)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
debugPrint("[Matomo service] Configured with content base: \(tracker.contentBase?.absoluteString ?? "-")")
|
|
||||||
debugPrint("[Matomo service] Opt out: \(tracker.isOptedOut)")
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Methods
|
|
||||||
|
|
||||||
func logScreen(name: String, path: String) {
|
|
||||||
guard !tracker.isOptedOut else { return }
|
|
||||||
guard let trackerUrl = tracker.contentBase?.absoluteString else { return }
|
|
||||||
|
|
||||||
let urlString = URL(string: "\(trackerUrl)" + "/" + "\(path)" + "iOS")
|
|
||||||
tracker.track(
|
|
||||||
view: [name],
|
|
||||||
url: urlString
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func logEvent(
|
|
||||||
name: String,
|
|
||||||
action: String,
|
|
||||||
category: String,
|
|
||||||
params: [String: Any]?
|
|
||||||
) {
|
|
||||||
guard !tracker.isOptedOut else { return }
|
|
||||||
|
|
||||||
tracker.track(
|
|
||||||
eventWithCategory: category,
|
|
||||||
action: action,
|
|
||||||
name: name,
|
|
||||||
number: nil,
|
|
||||||
url: nil
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Firebase
|
// MARK: - Firebase
|
||||||
|
|
||||||
class FirebaseAnalyticsManager: AnalyticsManagerProtocol {
|
class FirebaseAnalyticsManager: AnalyticsManagerProtocol {
|
||||||
func logScreen(name: String, path: String) {
|
func logScreen(name: String, path: String) {
|
||||||
var parameters = [
|
let parameters = [
|
||||||
AnalyticsParameterScreenName: name as NSObject
|
AnalyticsParameterScreenName: name as NSObject
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -98,8 +35,9 @@ class FirebaseAnalyticsManager: AnalyticsManagerProtocol {
|
|||||||
params: [String: Any]?
|
params: [String: Any]?
|
||||||
) {
|
) {
|
||||||
var parameters: [String:NSObject] = [
|
var parameters: [String:NSObject] = [
|
||||||
|
AnalyticsParameterItemName: name.replacingOccurrences(of: " ", with: "_") as NSObject,
|
||||||
|
AnalyticsParameterItemCategory: category as NSObject,
|
||||||
"action": action as NSObject,
|
"action": action as NSObject,
|
||||||
"category": category as NSObject,
|
|
||||||
]
|
]
|
||||||
|
|
||||||
if let supplementaryParameters = params {
|
if let supplementaryParameters = params {
|
||||||
@ -115,7 +53,7 @@ class FirebaseAnalyticsManager: AnalyticsManagerProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Analytics.logEvent(
|
Analytics.logEvent(
|
||||||
name.replacingOccurrences(of: [" "], with: "_"),
|
AnalyticsEventSelectContent,
|
||||||
parameters: parameters
|
parameters: parameters
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -124,7 +62,6 @@ class FirebaseAnalyticsManager: AnalyticsManagerProtocol {
|
|||||||
// MARK: - Manager
|
// MARK: - Manager
|
||||||
|
|
||||||
class AnalyticsManager {
|
class AnalyticsManager {
|
||||||
|
|
||||||
static var shared = AnalyticsManager()
|
static var shared = AnalyticsManager()
|
||||||
|
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
@ -139,13 +76,7 @@ class AnalyticsManager {
|
|||||||
isEnabled = enable
|
isEnabled = enable
|
||||||
}
|
}
|
||||||
|
|
||||||
func configure(siteId: String, url: String) {
|
func configure() {
|
||||||
managers.append(
|
|
||||||
MatomoAnalyticsManager(
|
|
||||||
siteId: siteId,
|
|
||||||
url: url
|
|
||||||
)
|
|
||||||
)
|
|
||||||
managers.append(FirebaseAnalyticsManager())
|
managers.append(FirebaseAnalyticsManager())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,7 +111,7 @@ class AnalyticsManager {
|
|||||||
func logScreenS1DefOne(title: String) {
|
func logScreenS1DefOne(title: String) {
|
||||||
logScreen(
|
logScreen(
|
||||||
name: "s1 def one \(title)",
|
name: "s1 def one \(title)",
|
||||||
path: "s1_def_one/\(title)"
|
path: ""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,7 +132,7 @@ class AnalyticsManager {
|
|||||||
func logScreenS2DefOne() {
|
func logScreenS2DefOne() {
|
||||||
logScreen(
|
logScreen(
|
||||||
name: "s2 def one",
|
name: "s2 def one",
|
||||||
path: "s2_def_one/"
|
path: ""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Generated by ResgenSwift.Strings.Tags 2.1.0
|
// Generated by ResgenSwift.Strings.Tags 1.2
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
@ -8,20 +8,12 @@ extension Tags {
|
|||||||
|
|
||||||
/// Translation in ium :
|
/// Translation in ium :
|
||||||
/// Ecran un
|
/// Ecran un
|
||||||
///
|
|
||||||
/// Comment :
|
|
||||||
/// No comment
|
|
||||||
|
|
||||||
var screen_one: String {
|
var screen_one: String {
|
||||||
"Ecran un"
|
"Ecran un"
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Translation in ium :
|
/// Translation in ium :
|
||||||
/// Ecran deux
|
/// Ecran deux
|
||||||
///
|
|
||||||
/// Comment :
|
|
||||||
/// No comment
|
|
||||||
|
|
||||||
var screen_two: String {
|
var screen_two: String {
|
||||||
"Ecran deux"
|
"Ecran deux"
|
||||||
}
|
}
|
||||||
|
@ -3,68 +3,69 @@
|
|||||||
FORCE_FLAG="$1"
|
FORCE_FLAG="$1"
|
||||||
|
|
||||||
## Font
|
## Font
|
||||||
swift run -c release ResgenSwift fonts $FORCE_FLAG "./Fonts/sampleFontsAll.txt" \
|
#swift run -c release ResgenSwift fonts $FORCE_FLAG "./Fonts/sampleFontsAll.txt" \
|
||||||
--extension-output-path "./Fonts/Generated" \
|
# --extension-output-path "./Fonts/Generated" \
|
||||||
--extension-name "FontYolo" \
|
# --extension-name "FontYolo" \
|
||||||
--extension-name-ui-kit "UIFontYolo" \
|
# --extension-name-ui-kit "UIFontYolo" \
|
||||||
--extension-suffix "GenAllScript" \
|
# --extension-suffix "GenAllScript" \
|
||||||
--info-plist-paths "./Fonts/Generated/test.plist ./Fonts/Generated/test2.plist"
|
# --info-plist-paths "./Fonts/Generated/test.plist ./Fonts/Generated/test2.plist"
|
||||||
|
#
|
||||||
echo "\n-------------------------\n"
|
#echo "\n-------------------------\n"
|
||||||
|
#
|
||||||
## Color
|
## Color
|
||||||
swift run -c release ResgenSwift colors $FORCE_FLAG "./Colors/sampleColors1.txt" \
|
#swift run -c release ResgenSwift colors $FORCE_FLAG "./Colors/sampleColors1.txt" \
|
||||||
--style all \
|
# --style all \
|
||||||
--xcassets-path "./Colors/colors.xcassets" \
|
# --xcassets-path "./Colors/colors.xcassets" \
|
||||||
--extension-output-path "./Colors/Generated/" \
|
# --extension-output-path "./Colors/Generated/" \
|
||||||
--extension-name "ColorYolo" \
|
# --extension-name "ColorYolo" \
|
||||||
--extension-name-ui-kit "UIhkjhkColorYolo" \
|
# --extension-name-ui-kit "UIhkjhkColorYolo" \
|
||||||
--extension-suffix "GenAllScript"
|
# --extension-suffix "GenAllScript"
|
||||||
|
#
|
||||||
echo "\n-------------------------\n"
|
#echo "\n-------------------------\n"
|
||||||
|
#
|
||||||
## Twine
|
## Twine
|
||||||
swift run -c release ResgenSwift strings twine $FORCE_FLAG "./Twine/sampleStrings.txt" \
|
#swift run -c release ResgenSwift strings twine $FORCE_FLAG "./Twine/sampleStrings.txt" \
|
||||||
--output-path "./Twine/Generated" \
|
# --output-path "./Twine/Generated" \
|
||||||
--langs "fr en en-us" \
|
# --langs "fr en en-us" \
|
||||||
--default-lang "en" \
|
# --default-lang "en" \
|
||||||
--extension-output-path "./Twine/Generated"
|
# --extension-output-path "./Twine/Generated"
|
||||||
|
|
||||||
echo "\n-------------------------\n"
|
#echo "\n-------------------------\n"
|
||||||
|
|
||||||
## Strings
|
## Strings
|
||||||
swift run -c release ResgenSwift strings stringium $FORCE_FLAG "./Strings/sampleStrings.txt" \
|
#swift run -c release ResgenSwift strings stringium $FORCE_FLAG "./Strings/sampleStrings.txt" \
|
||||||
--output-path "./Strings/Generated" \
|
# --output-path "./Strings/Generated" \
|
||||||
--langs "fr en en-us" \
|
# --langs "fr en en-us" \
|
||||||
--default-lang "en" \
|
# --default-lang "en" \
|
||||||
--extension-output-path "./Strings/Generated" \
|
# --extension-output-path "./Strings/Generated" \
|
||||||
--extension-name "String" \
|
# --extension-name "String" \
|
||||||
--extension-suffix "GenAllScript"
|
# --extension-suffix "GenAllScript"
|
||||||
|
|
||||||
echo "\n-------------------------\n"
|
#echo "\n-------------------------\n"
|
||||||
|
|
||||||
## Tags
|
## Tags
|
||||||
swift run -c release ResgenSwift strings tags $FORCE_FLAG "./Tags/sampleTags.txt" \
|
#swift run -c release ResgenSwift strings tags $FORCE_FLAG "./Tags/sampleTags.txt" \
|
||||||
--lang "ium" \
|
# --lang "ium" \
|
||||||
--extension-output-path "./Tags/Generated" \
|
# --extension-output-path "./Tags/Generated" \
|
||||||
--extension-name "Tags" \
|
# --extension-name "Tags" \
|
||||||
--extension-suffix "GenAllScript"
|
# --extension-suffix "GenAllScript"
|
||||||
|
|
||||||
#echo "\n-------------------------\n"
|
#echo "\n-------------------------\n"
|
||||||
|
|
||||||
# Analytics
|
# Analytics
|
||||||
swift run -c release ResgenSwift analytics $FORCE_FLAG "./Tags/sampleTags.yml" \
|
swift run -c release ResgenSwift analytics $FORCE_FLAG "./Tags/sampleTags.yml" \
|
||||||
--target "matomo firebase" \
|
--target "firebase" \
|
||||||
--extension-output-path "./Tags/Generated" \
|
--extension-output-path "./Tags/Generated" \
|
||||||
--extension-name "Analytics" \
|
--extension-name "Analytics" \
|
||||||
--extension-suffix "GenAllScript"
|
--extension-suffix "GenAllScript" \
|
||||||
|
--static-members true
|
||||||
echo "\n-------------------------\n"
|
|
||||||
|
|
||||||
|
#echo "\n-------------------------\n"
|
||||||
|
#
|
||||||
## Images
|
## Images
|
||||||
swift run -c release ResgenSwift images $FORCE_FLAG "./Images/sampleImages.txt" \
|
#swift run -c release ResgenSwift images $FORCE_FLAG "./Images/sampleImages.txt" \
|
||||||
--xcassets-path "./Images/imagium.xcassets" \
|
# --xcassets-path "./Images/imagium.xcassets" \
|
||||||
--extension-output-path "./Images/Generated" \
|
# --extension-output-path "./Images/Generated" \
|
||||||
--extension-name "ImageYolo" \
|
# --extension-name "ImageYolo" \
|
||||||
--extension-name-ui-kit "UIImageYolo" \
|
# --extension-name-ui-kit "UIImageYolo" \
|
||||||
--extension-suffix "GenAllScript"
|
# --extension-suffix "GenAllScript"
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
// Created by Loris Perret on 08/12/2023.
|
// Created by Loris Perret on 08/12/2023.
|
||||||
//
|
//
|
||||||
|
|
||||||
import ArgumentParser
|
|
||||||
import Foundation
|
|
||||||
import ToolCore
|
import ToolCore
|
||||||
|
import Foundation
|
||||||
|
import ArgumentParser
|
||||||
|
|
||||||
struct Analytics: ParsableCommand {
|
struct Analytics: ParsableCommand {
|
||||||
|
|
||||||
@ -42,17 +42,15 @@ struct Analytics: ParsableCommand {
|
|||||||
guard checkRequirements() else { return }
|
guard checkRequirements() else { return }
|
||||||
|
|
||||||
// Parse input file
|
// Parse input file
|
||||||
let sections = AnalyticsFileParser().parse(options.inputFile, target: options.target)
|
let sections = AnalyticsFileParser.parse(options.inputFile, target: options.target)
|
||||||
|
|
||||||
// Generate extension
|
// Generate extension
|
||||||
AnalyticsGenerator.writeExtensionFiles(
|
AnalyticsGenerator.writeExtensionFiles(sections: sections,
|
||||||
sections: sections,
|
|
||||||
target: options.target,
|
target: options.target,
|
||||||
tags: ["ios", "iosonly"],
|
tags: ["ios", "iosonly"],
|
||||||
staticVar: options.staticMembers,
|
staticVar: options.staticMembers,
|
||||||
extensionName: options.extensionName,
|
extensionName: options.extensionName,
|
||||||
extensionFilePath: options.extensionFilePath
|
extensionFilePath: options.extensionFilePath)
|
||||||
)
|
|
||||||
|
|
||||||
print("[\(Self.toolName)] Analytics generated")
|
print("[\(Self.toolName)] Analytics generated")
|
||||||
}
|
}
|
||||||
@ -66,21 +64,19 @@ struct Analytics: ParsableCommand {
|
|||||||
guard fileManager.fileExists(atPath: options.inputFile) else {
|
guard fileManager.fileExists(atPath: options.inputFile) else {
|
||||||
let error = AnalyticsError.fileNotExists(options.inputFile)
|
let error = AnalyticsError.fileNotExists(options.inputFile)
|
||||||
print(error.description)
|
print(error.description)
|
||||||
Self.exit(withError: error)
|
Analytics.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
guard TrackerType.hasValidTarget(in: options.target) else {
|
guard TrackerType.hasValidTarget(in: options.target) else {
|
||||||
let error = AnalyticsError.noValidTracker(options.target)
|
let error = AnalyticsError.noValidTracker(options.target)
|
||||||
print(error.description)
|
print(error.description)
|
||||||
Self.exit(withError: error)
|
Analytics.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if needed to regenerate
|
// Check if needed to regenerate
|
||||||
guard GeneratorChecker.shouldGenerate(
|
guard GeneratorChecker.shouldGenerate(force: options.forceGeneration,
|
||||||
force: options.forceGeneration,
|
|
||||||
inputFilePath: options.inputFile,
|
inputFilePath: options.inputFile,
|
||||||
extensionFilePath: options.extensionFilePath
|
extensionFilePath: options.extensionFilePath) else {
|
||||||
) else {
|
|
||||||
print("[\(Self.toolName)] Analytics are already up to date :) ")
|
print("[\(Self.toolName)] Analytics are already up to date :) ")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum AnalyticsError: Error {
|
enum AnalyticsError: Error {
|
||||||
|
|
||||||
case noValidTracker(String)
|
case noValidTracker(String)
|
||||||
case fileNotExists(String)
|
case fileNotExists(String)
|
||||||
case missingElement(String)
|
case missingElement(String)
|
||||||
@ -33,7 +32,7 @@ enum AnalyticsError: Error {
|
|||||||
case .parseFailed(let baseError):
|
case .parseFailed(let baseError):
|
||||||
return "error: [\(Analytics.toolName)] Parse input file failed: \(baseError)"
|
return "error: [\(Analytics.toolName)] Parse input file failed: \(baseError)"
|
||||||
|
|
||||||
case let .writeFile(subErrorDescription, filename):
|
case .writeFile(let subErrorDescription, let filename):
|
||||||
return "error: [\(Analytics.toolName)] An error occured while writing content to \(filename): \(subErrorDescription)"
|
return "error: [\(Analytics.toolName)] An error occured while writing content to \(filename): \(subErrorDescription)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,13 +5,10 @@
|
|||||||
// Created by Loris Perret on 08/12/2023.
|
// Created by Loris Perret on 08/12/2023.
|
||||||
//
|
//
|
||||||
|
|
||||||
import ArgumentParser
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import ArgumentParser
|
||||||
// swiftlint:disable no_grouping_extension
|
|
||||||
|
|
||||||
struct AnalyticsOptions: ParsableArguments {
|
struct AnalyticsOptions: ParsableArguments {
|
||||||
|
|
||||||
@Flag(name: [.customShort("f"), .customShort("F")], help: "Should force generation")
|
@Flag(name: [.customShort("f"), .customShort("F")], help: "Should force generation")
|
||||||
var forceGeneration = false
|
var forceGeneration = false
|
||||||
|
|
||||||
@ -37,9 +34,8 @@ struct AnalyticsOptions: ParsableArguments {
|
|||||||
// MARK: - Computed var
|
// MARK: - Computed var
|
||||||
|
|
||||||
extension AnalyticsOptions {
|
extension AnalyticsOptions {
|
||||||
|
|
||||||
var extensionFileName: String {
|
var extensionFileName: String {
|
||||||
if let extensionSuffix {
|
if let extensionSuffix = extensionSuffix {
|
||||||
return "\(extensionName)+\(extensionSuffix).swift"
|
return "\(extensionName)+\(extensionSuffix).swift"
|
||||||
}
|
}
|
||||||
return "\(extensionName).swift"
|
return "\(extensionName).swift"
|
||||||
|
@ -5,50 +5,34 @@
|
|||||||
// Created by Loris Perret on 08/12/2023.
|
// Created by Loris Perret on 08/12/2023.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CoreVideo
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import ToolCore
|
import ToolCore
|
||||||
|
import CoreVideo
|
||||||
|
|
||||||
// Disabled cause it's a pain to handle in generated string
|
class AnalyticsGenerator {
|
||||||
|
static var targets: [TrackerType] = []
|
||||||
|
|
||||||
enum AnalyticsGenerator {
|
static func writeExtensionFiles(sections: [AnalyticsCategory], target: String, tags: [String], staticVar: Bool, extensionName: String, extensionFilePath: String) {
|
||||||
|
|
||||||
// MARK: - Write content
|
|
||||||
|
|
||||||
static func writeExtensionFiles(
|
|
||||||
sections: [AnalyticsCategory],
|
|
||||||
target: String,
|
|
||||||
tags: [String],
|
|
||||||
staticVar: Bool,
|
|
||||||
extensionName: String,
|
|
||||||
extensionFilePath: String
|
|
||||||
) {
|
|
||||||
// Get target type from enum
|
// Get target type from enum
|
||||||
let targetsString: [String] = target.components(separatedBy: " ")
|
let targetsString: [String] = target.components(separatedBy: " ")
|
||||||
let targets = {
|
|
||||||
var targets = [TrackerType]()
|
|
||||||
TrackerType.allCases.forEach { enumTarget in
|
TrackerType.allCases.forEach { enumTarget in
|
||||||
if targetsString.contains(enumTarget.value) {
|
if targetsString.contains(enumTarget.value) {
|
||||||
targets.append(enumTarget)
|
targets.append(enumTarget)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return targets
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Get extension content
|
// Get extension content
|
||||||
let extensionFileContent = getExtensionContent(
|
let extensionFileContent = Self.getExtensionContent(sections: sections,
|
||||||
targets: targets,
|
|
||||||
sections: sections,
|
|
||||||
tags: tags,
|
tags: tags,
|
||||||
staticVar: staticVar,
|
staticVar: staticVar,
|
||||||
extensionName: extensionName
|
extensionName: extensionName)
|
||||||
)
|
|
||||||
|
|
||||||
// Write content
|
// Write content
|
||||||
let extensionFilePathURL = URL(fileURLWithPath: extensionFilePath)
|
let extensionFilePathURL = URL(fileURLWithPath: extensionFilePath)
|
||||||
do {
|
do {
|
||||||
try extensionFileContent.write(to: extensionFilePathURL, atomically: false, encoding: .utf8)
|
try extensionFileContent.write(to: extensionFilePathURL, atomically: false, encoding: .utf8)
|
||||||
} catch {
|
} catch let error {
|
||||||
let error = AnalyticsError.writeFile(extensionFilePath, error.localizedDescription)
|
let error = AnalyticsError.writeFile(extensionFilePath, error.localizedDescription)
|
||||||
print(error.description)
|
print(error.description)
|
||||||
Analytics.exit(withError: error)
|
Analytics.exit(withError: error)
|
||||||
@ -57,57 +41,38 @@ enum AnalyticsGenerator {
|
|||||||
|
|
||||||
// MARK: - Extension content
|
// MARK: - Extension content
|
||||||
|
|
||||||
static func getExtensionContent(
|
static func getExtensionContent(sections: [AnalyticsCategory], tags: [String], staticVar: Bool, extensionName: String) -> String {
|
||||||
targets: [TrackerType],
|
|
||||||
sections: [AnalyticsCategory],
|
|
||||||
tags: [String],
|
|
||||||
staticVar: Bool,
|
|
||||||
extensionName: String
|
|
||||||
) -> String {
|
|
||||||
[
|
[
|
||||||
getHeader(
|
Self.getHeader(extensionClassname: extensionName, staticVar: staticVar),
|
||||||
targets: targets,
|
Self.getProperties(sections: sections, tags: tags, staticVar: staticVar),
|
||||||
extensionClassname: extensionName,
|
Self.getFooter()
|
||||||
staticVar: staticVar
|
|
||||||
),
|
|
||||||
getProperties(
|
|
||||||
sections: sections,
|
|
||||||
tags: tags,
|
|
||||||
staticVar: staticVar
|
|
||||||
),
|
|
||||||
getFooter()
|
|
||||||
]
|
]
|
||||||
.joined(separator: "\n")
|
.joined(separator: "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Extension part
|
// MARK: - Extension part
|
||||||
|
|
||||||
private static func getHeader(
|
private static func getHeader(extensionClassname: String, staticVar: Bool) -> String {
|
||||||
targets: [TrackerType],
|
|
||||||
extensionClassname: String,
|
|
||||||
staticVar: Bool
|
|
||||||
) -> String {
|
|
||||||
"""
|
"""
|
||||||
// Generated by ResgenSwift.\(Analytics.toolName) \(ResgenSwiftVersion)
|
// Generated by ResgenSwift.\(Analytics.toolName) \(ResgenSwiftVersion)
|
||||||
|
|
||||||
\(getImport(targets: targets))
|
\(Self.getImport())
|
||||||
|
|
||||||
\(getAnalyticsProtocol(targets: targets))
|
\(Self.getAnalyticsProtocol())
|
||||||
// MARK: - Manager
|
// MARK: - Manager
|
||||||
|
|
||||||
class AnalyticsManager {
|
class AnalyticsManager {
|
||||||
|
|
||||||
static var shared = AnalyticsManager()
|
static var shared = AnalyticsManager()
|
||||||
|
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
|
|
||||||
var managers: [AnalyticsManagerProtocol] = []
|
var managers: [AnalyticsManagerProtocol] = []
|
||||||
|
|
||||||
\(getEnabledContent())
|
\(Self.getEnabledContent())
|
||||||
|
|
||||||
\(getAnalyticsProperties(targets: targets))
|
\(Self.getAnalyticsProperties())
|
||||||
|
|
||||||
\(getPrivateLogFunction())
|
\(Self.getPrivateLogFunction())
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +88,7 @@ enum AnalyticsGenerator {
|
|||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func getImport(targets: [TrackerType]) -> String {
|
private static func getImport() -> String {
|
||||||
var result: [String] = []
|
var result: [String] = []
|
||||||
|
|
||||||
if targets.contains(TrackerType.matomo) {
|
if targets.contains(TrackerType.matomo) {
|
||||||
@ -166,7 +131,7 @@ enum AnalyticsGenerator {
|
|||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func getAnalyticsProperties(targets: [TrackerType]) -> String {
|
private static func getAnalyticsProperties() -> String {
|
||||||
var header = ""
|
var header = ""
|
||||||
var content: [String] = []
|
var content: [String] = []
|
||||||
let footer = " }"
|
let footer = " }"
|
||||||
@ -199,12 +164,11 @@ enum AnalyticsGenerator {
|
|||||||
.joined(separator: "\n")
|
.joined(separator: "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func getAnalyticsProtocol(targets: [TrackerType]) -> String {
|
private static func getAnalyticsProtocol() -> String {
|
||||||
let proto = """
|
let proto = """
|
||||||
// MARK: - Protocol
|
// MARK: - Protocol
|
||||||
|
|
||||||
protocol AnalyticsManagerProtocol {
|
protocol AnalyticsManagerProtocol {
|
||||||
|
|
||||||
func logScreen(name: String, path: String)
|
func logScreen(name: String, path: String)
|
||||||
func logEvent(
|
func logEvent(
|
||||||
name: String,
|
name: String,
|
||||||
@ -229,11 +193,7 @@ enum AnalyticsGenerator {
|
|||||||
return result.joined(separator: "\n")
|
return result.joined(separator: "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func getProperties(
|
private static func getProperties(sections: [AnalyticsCategory], tags: [String], staticVar: Bool) -> String {
|
||||||
sections: [AnalyticsCategory],
|
|
||||||
tags: [String],
|
|
||||||
staticVar: Bool
|
|
||||||
) -> String {
|
|
||||||
sections
|
sections
|
||||||
.compactMap { section in
|
.compactMap { section in
|
||||||
// Check that at least one string will be generated
|
// Check that at least one string will be generated
|
||||||
|
@ -5,18 +5,16 @@
|
|||||||
// Created by Loris Perret on 05/12/2023.
|
// Created by Loris Perret on 05/12/2023.
|
||||||
//
|
//
|
||||||
|
|
||||||
// CPD-OFF
|
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum FirebaseGenerator {
|
enum FirebaseGenerator {
|
||||||
|
|
||||||
static var service: String {
|
static var service: String {
|
||||||
[
|
[
|
||||||
Self.header,
|
FirebaseGenerator.header,
|
||||||
Self.logScreen,
|
FirebaseGenerator.logScreen,
|
||||||
Self.logEvent,
|
FirebaseGenerator.logEvent,
|
||||||
Self.footer
|
FirebaseGenerator.footer
|
||||||
]
|
]
|
||||||
.joined(separator: "\n")
|
.joined(separator: "\n")
|
||||||
}
|
}
|
||||||
@ -34,7 +32,7 @@ enum FirebaseGenerator {
|
|||||||
private static var logScreen: String {
|
private static var logScreen: String {
|
||||||
"""
|
"""
|
||||||
func logScreen(name: String, path: String) {
|
func logScreen(name: String, path: String) {
|
||||||
var parameters = [
|
let parameters = [
|
||||||
AnalyticsParameterScreenName: name as NSObject
|
AnalyticsParameterScreenName: name as NSObject
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -56,8 +54,9 @@ enum FirebaseGenerator {
|
|||||||
params: [String: Any]?
|
params: [String: Any]?
|
||||||
) {
|
) {
|
||||||
var parameters: [String:NSObject] = [
|
var parameters: [String:NSObject] = [
|
||||||
|
AnalyticsParameterItemName: name.replacingOccurrences(of: " ", with: "_") as NSObject,
|
||||||
|
AnalyticsParameterItemCategory: category as NSObject,
|
||||||
"action": action as NSObject,
|
"action": action as NSObject,
|
||||||
"category": category as NSObject,
|
|
||||||
]
|
]
|
||||||
|
|
||||||
if let supplementaryParameters = params {
|
if let supplementaryParameters = params {
|
||||||
@ -73,7 +72,7 @@ enum FirebaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Analytics.logEvent(
|
Analytics.logEvent(
|
||||||
name.replacingOccurrences(of: [" "], with: "_"),
|
AnalyticsEventSelectContent,
|
||||||
parameters: parameters
|
parameters: parameters
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -87,5 +86,3 @@ enum FirebaseGenerator {
|
|||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CPD-ON
|
|
||||||
|
@ -11,11 +11,11 @@ enum MatomoGenerator {
|
|||||||
|
|
||||||
static var service: String {
|
static var service: String {
|
||||||
[
|
[
|
||||||
Self.header,
|
MatomoGenerator.header,
|
||||||
Self.setup,
|
MatomoGenerator.setup,
|
||||||
Self.logScreen,
|
MatomoGenerator.logScreen,
|
||||||
Self.logEvent,
|
MatomoGenerator.logEvent,
|
||||||
Self.footer
|
MatomoGenerator.footer
|
||||||
]
|
]
|
||||||
.joined(separator: "\n")
|
.joined(separator: "\n")
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
class AnalyticsCategory {
|
class AnalyticsCategory {
|
||||||
|
|
||||||
// MARK: - Properties
|
|
||||||
|
|
||||||
let id: String // OnBoarding
|
let id: String // OnBoarding
|
||||||
var definitions = [AnalyticsDefinition]()
|
var definitions = [AnalyticsDefinition]()
|
||||||
|
|
||||||
|
@ -9,9 +9,6 @@ import Foundation
|
|||||||
import ToolCore
|
import ToolCore
|
||||||
|
|
||||||
class AnalyticsDefinition {
|
class AnalyticsDefinition {
|
||||||
|
|
||||||
// MARK: - Properties
|
|
||||||
|
|
||||||
let id: String
|
let id: String
|
||||||
var name: String
|
var name: String
|
||||||
var path: String = ""
|
var path: String = ""
|
||||||
@ -153,7 +150,7 @@ class AnalyticsDefinition {
|
|||||||
replaceIn()
|
replaceIn()
|
||||||
return """
|
return """
|
||||||
static func \(getFuncName())\(getParameters()) {
|
static func \(getFuncName())\(getParameters()) {
|
||||||
\(getlogFunction())
|
AnalyticsManager.shared.\(getlogFunction())
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
|
@ -8,19 +8,16 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
struct AnalyticsFile: Codable {
|
struct AnalyticsFile: Codable {
|
||||||
|
|
||||||
var categories: [AnalyticsCategoryDTO]
|
var categories: [AnalyticsCategoryDTO]
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AnalyticsCategoryDTO: Codable {
|
struct AnalyticsCategoryDTO: Codable {
|
||||||
|
|
||||||
var id: String
|
var id: String
|
||||||
var screens: [AnalyticsDefinitionScreenDTO]?
|
var screens: [AnalyticsDefinitionScreenDTO]?
|
||||||
var events: [AnalyticsDefinitionEventDTO]?
|
var events: [AnalyticsDefinitionEventDTO]?
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AnalyticsDefinitionScreenDTO: Codable {
|
struct AnalyticsDefinitionScreenDTO: Codable {
|
||||||
|
|
||||||
var id: String
|
var id: String
|
||||||
var name: String
|
var name: String
|
||||||
var tags: String
|
var tags: String
|
||||||
@ -31,7 +28,6 @@ struct AnalyticsDefinitionScreenDTO: Codable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct AnalyticsDefinitionEventDTO: Codable {
|
struct AnalyticsDefinitionEventDTO: Codable {
|
||||||
|
|
||||||
var id: String
|
var id: String
|
||||||
var name: String
|
var name: String
|
||||||
var tags: String
|
var tags: String
|
||||||
@ -43,7 +39,6 @@ struct AnalyticsDefinitionEventDTO: Codable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct AnalyticsParameterDTO: Codable {
|
struct AnalyticsParameterDTO: Codable {
|
||||||
|
|
||||||
var name: String
|
var name: String
|
||||||
var type: String
|
var type: String
|
||||||
var replaceIn: String?
|
var replaceIn: String?
|
||||||
|
@ -8,9 +8,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
class AnalyticsParameter {
|
class AnalyticsParameter {
|
||||||
|
|
||||||
// MARK: - Properties
|
|
||||||
|
|
||||||
var name: String
|
var name: String
|
||||||
var type: String
|
var type: String
|
||||||
var replaceIn: [String] = []
|
var replaceIn: [String] = []
|
||||||
|
@ -10,7 +10,6 @@ import Foundation
|
|||||||
extension AnalyticsDefinition {
|
extension AnalyticsDefinition {
|
||||||
|
|
||||||
enum TagType {
|
enum TagType {
|
||||||
|
|
||||||
case screen
|
case screen
|
||||||
case event
|
case event
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum TrackerType: CaseIterable, Sendable {
|
enum TrackerType: CaseIterable {
|
||||||
|
|
||||||
case matomo
|
case matomo
|
||||||
case firebase
|
case firebase
|
||||||
|
|
||||||
@ -16,7 +15,6 @@ enum TrackerType: CaseIterable, Sendable {
|
|||||||
switch self {
|
switch self {
|
||||||
case .matomo:
|
case .matomo:
|
||||||
"matomo"
|
"matomo"
|
||||||
|
|
||||||
case .firebase:
|
case .firebase:
|
||||||
"firebase"
|
"firebase"
|
||||||
}
|
}
|
||||||
|
@ -9,48 +9,10 @@ import Foundation
|
|||||||
import Yams
|
import Yams
|
||||||
|
|
||||||
class AnalyticsFileParser {
|
class AnalyticsFileParser {
|
||||||
|
private static var inputFile: String = ""
|
||||||
|
private static var target: String = ""
|
||||||
|
|
||||||
// MARK: - Properties
|
private static func parseYaml() -> AnalyticsFile {
|
||||||
|
|
||||||
private var inputFile: String = ""
|
|
||||||
private var target: String = ""
|
|
||||||
|
|
||||||
// MARK: - Methods
|
|
||||||
|
|
||||||
func parse(_ inputFile: String, target: String) -> [AnalyticsCategory] {
|
|
||||||
self.inputFile = inputFile
|
|
||||||
self.target = target
|
|
||||||
|
|
||||||
let tagFile = parseYaml()
|
|
||||||
|
|
||||||
return tagFile
|
|
||||||
.categories
|
|
||||||
.map { categorie in
|
|
||||||
let section = AnalyticsCategory(id: categorie.id)
|
|
||||||
|
|
||||||
if let screens = categorie.screens {
|
|
||||||
section
|
|
||||||
.definitions
|
|
||||||
.append(
|
|
||||||
contentsOf: getTagDefinitionScreen(from: screens)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let events = categorie.events {
|
|
||||||
section
|
|
||||||
.definitions
|
|
||||||
.append(
|
|
||||||
contentsOf: getTagDefinitionEvent(from: events)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return section
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Private methods
|
|
||||||
|
|
||||||
private func parseYaml() -> AnalyticsFile {
|
|
||||||
guard let data = FileManager().contents(atPath: inputFile) else {
|
guard let data = FileManager().contents(atPath: inputFile) else {
|
||||||
let error = AnalyticsError.fileNotExists(inputFile)
|
let error = AnalyticsError.fileNotExists(inputFile)
|
||||||
print(error.description)
|
print(error.description)
|
||||||
@ -67,9 +29,10 @@ class AnalyticsFileParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func getParameters(from parameters: [AnalyticsParameterDTO]) -> [AnalyticsParameter] {
|
private static func getParameters(from parameters: [AnalyticsParameterDTO]) -> [AnalyticsParameter] {
|
||||||
parameters.map { dtoParameter in
|
parameters.map { dtoParameter in
|
||||||
// Type
|
// Type
|
||||||
|
|
||||||
let type = dtoParameter.type.uppercasedFirst()
|
let type = dtoParameter.type.uppercasedFirst()
|
||||||
|
|
||||||
guard
|
guard
|
||||||
@ -96,7 +59,7 @@ class AnalyticsFileParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func getTagDefinition(
|
private static func getTagDefinition(
|
||||||
id: String,
|
id: String,
|
||||||
name: String,
|
name: String,
|
||||||
type: AnalyticsDefinition.TagType,
|
type: AnalyticsDefinition.TagType,
|
||||||
@ -109,20 +72,20 @@ class AnalyticsFileParser {
|
|||||||
.components(separatedBy: ",")
|
.components(separatedBy: ",")
|
||||||
.map { $0.removeLeadingTrailingWhitespace() }
|
.map { $0.removeLeadingTrailingWhitespace() }
|
||||||
|
|
||||||
if let comments {
|
if let comments = comments {
|
||||||
definition.comments = comments
|
definition.comments = comments
|
||||||
}
|
}
|
||||||
|
|
||||||
if let parameters {
|
if let parameters = parameters {
|
||||||
definition.parameters = getParameters(from: parameters)
|
definition.parameters = Self.getParameters(from: parameters)
|
||||||
}
|
}
|
||||||
|
|
||||||
return definition
|
return definition
|
||||||
}
|
}
|
||||||
|
|
||||||
private func getTagDefinitionScreen(from screens: [AnalyticsDefinitionScreenDTO]) -> [AnalyticsDefinition] {
|
private static func getTagDefinitionScreen(from screens: [AnalyticsDefinitionScreenDTO]) -> [AnalyticsDefinition] {
|
||||||
screens.map { screen in
|
screens.map { screen in
|
||||||
let definition: AnalyticsDefinition = getTagDefinition(
|
let definition: AnalyticsDefinition = Self.getTagDefinition(
|
||||||
id: screen.id,
|
id: screen.id,
|
||||||
name: screen.name,
|
name: screen.name,
|
||||||
type: .screen,
|
type: .screen,
|
||||||
@ -147,9 +110,9 @@ class AnalyticsFileParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func getTagDefinitionEvent(from events: [AnalyticsDefinitionEventDTO]) -> [AnalyticsDefinition] {
|
private static func getTagDefinitionEvent(from events: [AnalyticsDefinitionEventDTO]) -> [AnalyticsDefinition] {
|
||||||
events.map { event in
|
events.map { event in
|
||||||
let definition: AnalyticsDefinition = getTagDefinition(
|
let definition: AnalyticsDefinition = Self.getTagDefinition(
|
||||||
id: event.id,
|
id: event.id,
|
||||||
name: event.name,
|
name: event.name,
|
||||||
type: .event,
|
type: .event,
|
||||||
@ -176,9 +139,48 @@ class AnalyticsFileParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
definition.action = action
|
definition.action = action
|
||||||
|
} else {
|
||||||
|
if let category = event.category {
|
||||||
|
definition.category = category
|
||||||
|
}
|
||||||
|
|
||||||
|
if let action = event.action {
|
||||||
|
definition.action = action
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return definition
|
return definition
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func parse(_ inputFile: String, target: String) -> [AnalyticsCategory] {
|
||||||
|
self.inputFile = inputFile
|
||||||
|
self.target = target
|
||||||
|
|
||||||
|
let tagFile = Self.parseYaml()
|
||||||
|
|
||||||
|
return tagFile
|
||||||
|
.categories
|
||||||
|
.map { categorie in
|
||||||
|
let section: AnalyticsCategory = AnalyticsCategory(id: categorie.id)
|
||||||
|
|
||||||
|
if let screens = categorie.screens {
|
||||||
|
section
|
||||||
|
.definitions
|
||||||
|
.append(
|
||||||
|
contentsOf: Self.getTagDefinitionScreen(from: screens)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if let events = categorie.events {
|
||||||
|
section
|
||||||
|
.definitions
|
||||||
|
.append(
|
||||||
|
contentsOf: Self.getTagDefinitionEvent(from: events)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return section
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,15 +5,15 @@
|
|||||||
// Created by Thibaut Schmitt on 20/12/2021.
|
// Created by Thibaut Schmitt on 20/12/2021.
|
||||||
//
|
//
|
||||||
|
|
||||||
@preconcurrency import ArgumentParser
|
|
||||||
import Foundation
|
|
||||||
import ToolCore
|
import ToolCore
|
||||||
|
import Foundation
|
||||||
|
import ArgumentParser
|
||||||
|
|
||||||
struct Colors: ParsableCommand {
|
struct Colors: ParsableCommand {
|
||||||
|
|
||||||
// MARK: - CommandConfiguration
|
// MARK: - CommandConfiguration
|
||||||
|
|
||||||
static let configuration = CommandConfiguration(
|
static var configuration = CommandConfiguration(
|
||||||
abstract: "A utility for generate colors assets and their getters.",
|
abstract: "A utility for generate colors assets and their getters.",
|
||||||
version: ResgenSwiftVersion
|
version: ResgenSwiftVersion
|
||||||
)
|
)
|
||||||
@ -31,7 +31,7 @@ struct Colors: ParsableCommand {
|
|||||||
|
|
||||||
// MARK: - Run
|
// MARK: - Run
|
||||||
|
|
||||||
func run() throws {
|
public func run() throws {
|
||||||
print("[\(Self.toolName)] Starting colors generation")
|
print("[\(Self.toolName)] Starting colors generation")
|
||||||
|
|
||||||
// Check requirements
|
// Check requirements
|
||||||
@ -43,36 +43,28 @@ struct Colors: ParsableCommand {
|
|||||||
deleteCurrentColors()
|
deleteCurrentColors()
|
||||||
|
|
||||||
// Get colors to generate
|
// Get colors to generate
|
||||||
let parsedColors = ColorFileParser.parse(
|
let parsedColors = ColorFileParser.parse(options.inputFile,
|
||||||
options.inputFile,
|
colorStyle: options.style)
|
||||||
colorStyle: options.style
|
|
||||||
)
|
|
||||||
// -> Time: 0.0020350217819213867 seconds
|
// -> Time: 0.0020350217819213867 seconds
|
||||||
|
|
||||||
// Generate all colors in xcassets
|
// Generate all colors in xcassets
|
||||||
ColorXcassetHelper.generateXcassetColors(
|
ColorXcassetHelper.generateXcassetColors(colors: parsedColors,
|
||||||
colors: parsedColors,
|
to: options.xcassetsPath)
|
||||||
to: options.xcassetsPath
|
|
||||||
)
|
|
||||||
// -> Time: 3.4505380392074585 seconds
|
// -> Time: 3.4505380392074585 seconds
|
||||||
|
|
||||||
// Generate extension
|
// Generate extension
|
||||||
ColorExtensionGenerator.writeExtensionFile(
|
ColorExtensionGenerator.writeExtensionFile(colors: parsedColors,
|
||||||
colors: parsedColors,
|
|
||||||
staticVar: options.staticMembers,
|
staticVar: options.staticMembers,
|
||||||
extensionName: options.extensionName,
|
extensionName: options.extensionName,
|
||||||
extensionFilePath: options.extensionFilePath,
|
extensionFilePath: options.extensionFilePath,
|
||||||
isSwiftUI: true
|
isSwiftUI: true)
|
||||||
)
|
|
||||||
|
|
||||||
// Generate extension
|
// Generate extension
|
||||||
ColorExtensionGenerator.writeExtensionFile(
|
ColorExtensionGenerator.writeExtensionFile(colors: parsedColors,
|
||||||
colors: parsedColors,
|
|
||||||
staticVar: options.staticMembers,
|
staticVar: options.staticMembers,
|
||||||
extensionName: options.extensionNameUIKit,
|
extensionName: options.extensionNameUIKit,
|
||||||
extensionFilePath: options.extensionFilePathUIKit,
|
extensionFilePath: options.extensionFilePathUIKit,
|
||||||
isSwiftUI: false
|
isSwiftUI: false)
|
||||||
)
|
|
||||||
|
|
||||||
print("[\(Self.toolName)] Colors generated")
|
print("[\(Self.toolName)] Colors generated")
|
||||||
}
|
}
|
||||||
@ -86,29 +78,27 @@ struct Colors: ParsableCommand {
|
|||||||
guard fileManager.fileExists(atPath: options.inputFile) else {
|
guard fileManager.fileExists(atPath: options.inputFile) else {
|
||||||
let error = ColorsToolError.fileNotExists(options.inputFile)
|
let error = ColorsToolError.fileNotExists(options.inputFile)
|
||||||
print(error.description)
|
print(error.description)
|
||||||
Self.exit(withError: error)
|
Colors.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if xcassets file exists
|
// Check if xcassets file exists
|
||||||
guard fileManager.fileExists(atPath: options.xcassetsPath) else {
|
guard fileManager.fileExists(atPath: options.xcassetsPath) else {
|
||||||
let error = ColorsToolError.fileNotExists(options.xcassetsPath)
|
let error = ColorsToolError.fileNotExists(options.xcassetsPath)
|
||||||
print(error.description)
|
print(error.description)
|
||||||
Self.exit(withError: error)
|
Colors.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extension for UIKit and SwiftUI should have different name
|
// Extension for UIKit and SwiftUI should have different name
|
||||||
guard options.extensionName != options.extensionNameUIKit else {
|
guard options.extensionName != options.extensionNameUIKit else {
|
||||||
let error = ColorsToolError.extensionNamesCollision(options.extensionName)
|
let error = ColorsToolError.extensionNamesCollision(options.extensionName)
|
||||||
print(error.description)
|
print(error.description)
|
||||||
Self.exit(withError: error)
|
Colors.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if needed to regenerate
|
// Check if needed to regenerate
|
||||||
guard GeneratorChecker.shouldGenerate(
|
guard GeneratorChecker.shouldGenerate(force: options.forceGeneration,
|
||||||
force: options.forceGeneration,
|
|
||||||
inputFilePath: options.inputFile,
|
inputFilePath: options.inputFile,
|
||||||
extensionFilePath: options.extensionFilePath
|
extensionFilePath: options.extensionFilePath) else {
|
||||||
) else {
|
|
||||||
print("[\(Self.toolName)] Colors are already up to date :) ")
|
print("[\(Self.toolName)] Colors are already up to date :) ")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -128,7 +118,7 @@ struct Colors: ParsableCommand {
|
|||||||
} catch {
|
} catch {
|
||||||
let error = ColorsToolError.deleteExistingColors("\(options.xcassetsPath)/Colors")
|
let error = ColorsToolError.deleteExistingColors("\(options.xcassetsPath)/Colors")
|
||||||
print(error.description)
|
print(error.description)
|
||||||
Self.exit(withError: error)
|
Colors.exit(withError: error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum ColorsToolError: Error {
|
enum ColorsToolError: Error {
|
||||||
|
|
||||||
case extensionNamesCollision(String)
|
case extensionNamesCollision(String)
|
||||||
case badFormat(String)
|
case badFormat(String)
|
||||||
case writeAsset(String)
|
case writeAsset(String)
|
||||||
@ -32,13 +31,13 @@ enum ColorsToolError: Error {
|
|||||||
case .createAssetFolder(let assetsFolder):
|
case .createAssetFolder(let assetsFolder):
|
||||||
return "error: [\(Colors.toolName)] An error occured while creating colors folder `\(assetsFolder)`"
|
return "error: [\(Colors.toolName)] An error occured while creating colors folder `\(assetsFolder)`"
|
||||||
|
|
||||||
case let .writeExtension(filename, info):
|
case .writeExtension(let filename, let info):
|
||||||
return "error: [\(Colors.toolName)] An error occured while writing extension in \(filename): \(info)"
|
return "error: [\(Colors.toolName)] An error occured while writing extension in \(filename): \(info)"
|
||||||
|
|
||||||
case .fileNotExists(let filename):
|
case .fileNotExists(let filename):
|
||||||
return "error: [\(Colors.toolName)] File \(filename) does not exists"
|
return "error: [\(Colors.toolName)] File \(filename) does not exists"
|
||||||
|
|
||||||
case let .badColorDefinition(lightColor, darkColor):
|
case .badColorDefinition(let lightColor, let darkColor):
|
||||||
return "error: [\(Colors.toolName)] One of these two colors has invalid synthax: -\(lightColor)- or -\(darkColor)-"
|
return "error: [\(Colors.toolName)] One of these two colors has invalid synthax: -\(lightColor)- or -\(darkColor)-"
|
||||||
|
|
||||||
case .deleteExistingColors(let assetsFolder):
|
case .deleteExistingColors(let assetsFolder):
|
||||||
|
@ -5,13 +5,10 @@
|
|||||||
// Created by Thibaut Schmitt on 17/01/2022.
|
// Created by Thibaut Schmitt on 17/01/2022.
|
||||||
//
|
//
|
||||||
|
|
||||||
import ArgumentParser
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import ArgumentParser
|
||||||
// swiftlint:disable no_grouping_extension
|
|
||||||
|
|
||||||
struct ColorsToolOptions: ParsableArguments {
|
struct ColorsToolOptions: ParsableArguments {
|
||||||
|
|
||||||
@Flag(name: [.customShort("f"), .customShort("F")], help: "Should force generation")
|
@Flag(name: [.customShort("f"), .customShort("F")], help: "Should force generation")
|
||||||
var forceGeneration = false
|
var forceGeneration = false
|
||||||
|
|
||||||
@ -47,7 +44,7 @@ extension ColorsToolOptions {
|
|||||||
// MARK: - SwiftUI
|
// MARK: - SwiftUI
|
||||||
|
|
||||||
var extensionFileName: String {
|
var extensionFileName: String {
|
||||||
if let extensionSuffix {
|
if let extensionSuffix = extensionSuffix {
|
||||||
return "\(extensionName)+\(extensionSuffix).swift"
|
return "\(extensionName)+\(extensionSuffix).swift"
|
||||||
}
|
}
|
||||||
return "\(extensionName).swift"
|
return "\(extensionName).swift"
|
||||||
@ -60,7 +57,7 @@ extension ColorsToolOptions {
|
|||||||
// MARK: - UIKit
|
// MARK: - UIKit
|
||||||
|
|
||||||
var extensionFileNameUIKit: String {
|
var extensionFileNameUIKit: String {
|
||||||
if let extensionSuffix {
|
if let extensionSuffix = extensionSuffix {
|
||||||
return "\(extensionNameUIKit)+\(extensionSuffix).swift"
|
return "\(extensionNameUIKit)+\(extensionSuffix).swift"
|
||||||
}
|
}
|
||||||
return "\(extensionNameUIKit).swift"
|
return "\(extensionNameUIKit).swift"
|
||||||
|
@ -15,38 +15,32 @@ struct ColorExtensionGenerator {
|
|||||||
|
|
||||||
// MARK: - UIKit
|
// MARK: - UIKit
|
||||||
|
|
||||||
static func writeExtensionFile(
|
static func writeExtensionFile(colors: [ParsedColor],
|
||||||
colors: [ParsedColor],
|
|
||||||
staticVar: Bool,
|
staticVar: Bool,
|
||||||
extensionName: String,
|
extensionName: String,
|
||||||
extensionFilePath: String,
|
extensionFilePath: String,
|
||||||
isSwiftUI: Bool
|
isSwiftUI: Bool) {
|
||||||
) {
|
|
||||||
// Create extension content
|
// Create extension content
|
||||||
let extensionContent = Self.getExtensionContent(
|
let extensionContent = Self.getExtensionContent(colors: colors,
|
||||||
colors: colors,
|
|
||||||
staticVar: staticVar,
|
staticVar: staticVar,
|
||||||
extensionName: extensionName,
|
extensionName: extensionName,
|
||||||
isSwiftUI: isSwiftUI
|
isSwiftUI: isSwiftUI)
|
||||||
)
|
|
||||||
|
|
||||||
// Write content
|
// Write content
|
||||||
let extensionFilePathURL = URL(fileURLWithPath: extensionFilePath)
|
let extensionFilePathURL = URL(fileURLWithPath: extensionFilePath)
|
||||||
do {
|
do {
|
||||||
try extensionContent.write(to: extensionFilePathURL, atomically: false, encoding: .utf8)
|
try extensionContent.write(to: extensionFilePathURL, atomically: false, encoding: .utf8)
|
||||||
} catch {
|
} catch let error {
|
||||||
let error = ColorsToolError.writeExtension(extensionFilePath, error.localizedDescription)
|
let error = ColorsToolError.writeExtension(extensionFilePath, error.localizedDescription)
|
||||||
print(error.description)
|
print(error.description)
|
||||||
Colors.exit(withError: error)
|
Colors.exit(withError: error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static func getExtensionContent(
|
static func getExtensionContent(colors: [ParsedColor],
|
||||||
colors: [ParsedColor],
|
|
||||||
staticVar: Bool,
|
staticVar: Bool,
|
||||||
extensionName: String,
|
extensionName: String,
|
||||||
isSwiftUI: Bool
|
isSwiftUI: Bool) -> String {
|
||||||
) -> String {
|
|
||||||
[
|
[
|
||||||
Self.getHeader(extensionClassname: extensionName, isSwiftUI: isSwiftUI),
|
Self.getHeader(extensionClassname: extensionName, isSwiftUI: isSwiftUI),
|
||||||
Self.getProperties(for: colors, withStaticVar: staticVar, isSwiftUI: isSwiftUI),
|
Self.getProperties(for: colors, withStaticVar: staticVar, isSwiftUI: isSwiftUI),
|
||||||
@ -72,11 +66,9 @@ struct ColorExtensionGenerator {
|
|||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func getProperties(
|
private static func getProperties(for colors: [ParsedColor],
|
||||||
for colors: [ParsedColor],
|
|
||||||
withStaticVar staticVar: Bool,
|
withStaticVar staticVar: Bool,
|
||||||
isSwiftUI: Bool
|
isSwiftUI: Bool) -> String {
|
||||||
) -> String {
|
|
||||||
colors.map {
|
colors.map {
|
||||||
$0.getColorProperty(isStatic: staticVar, isSwiftUI: isSwiftUI)
|
$0.getColorProperty(isStatic: staticVar, isSwiftUI: isSwiftUI)
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import ToolCore
|
import ToolCore
|
||||||
|
|
||||||
enum ColorXcassetHelper {
|
struct ColorXcassetHelper {
|
||||||
|
|
||||||
static func generateXcassetColors(colors: [ParsedColor], to xcassetsPath: String) {
|
static func generateXcassetColors(colors: [ParsedColor], to xcassetsPath: String) {
|
||||||
colors.forEach {
|
colors.forEach {
|
||||||
@ -25,10 +25,8 @@ enum ColorXcassetHelper {
|
|||||||
let fileManager = FileManager()
|
let fileManager = FileManager()
|
||||||
if fileManager.fileExists(atPath: colorSetPath) == false {
|
if fileManager.fileExists(atPath: colorSetPath) == false {
|
||||||
do {
|
do {
|
||||||
try fileManager.createDirectory(
|
try fileManager.createDirectory(atPath: colorSetPath,
|
||||||
atPath: colorSetPath,
|
withIntermediateDirectories: true)
|
||||||
withIntermediateDirectories: true
|
|
||||||
)
|
|
||||||
} catch {
|
} catch {
|
||||||
let error = ColorsToolError.createAssetFolder(colorSetPath)
|
let error = ColorsToolError.createAssetFolder(colorSetPath)
|
||||||
print(error.description)
|
print(error.description)
|
||||||
@ -40,7 +38,7 @@ enum ColorXcassetHelper {
|
|||||||
let contentsJsonPathURL = URL(fileURLWithPath: contentsJsonPath)
|
let contentsJsonPathURL = URL(fileURLWithPath: contentsJsonPath)
|
||||||
do {
|
do {
|
||||||
try color.contentsJSON().write(to: contentsJsonPathURL, atomically: false, encoding: .utf8)
|
try color.contentsJSON().write(to: contentsJsonPathURL, atomically: false, encoding: .utf8)
|
||||||
} catch {
|
} catch let error {
|
||||||
let error = ColorsToolError.writeAsset(error.localizedDescription)
|
let error = ColorsToolError.writeAsset(error.localizedDescription)
|
||||||
print(error.description)
|
print(error.description)
|
||||||
Colors.exit(withError: error)
|
Colors.exit(withError: error)
|
||||||
|
@ -5,11 +5,10 @@
|
|||||||
// Created by Thibaut Schmitt on 29/08/2022.
|
// Created by Thibaut Schmitt on 29/08/2022.
|
||||||
//
|
//
|
||||||
|
|
||||||
import ArgumentParser
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import ArgumentParser
|
||||||
|
|
||||||
enum ColorStyle: String, Decodable, ExpressibleByArgument {
|
enum ColorStyle: String, Decodable, ExpressibleByArgument {
|
||||||
|
|
||||||
case light
|
case light
|
||||||
case all
|
case all
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
struct ParsedColor {
|
struct ParsedColor {
|
||||||
|
|
||||||
let name: String
|
let name: String
|
||||||
let light: String
|
let light: String
|
||||||
let dark: String
|
let dark: String
|
||||||
|
@ -7,11 +7,10 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum ColorFileParser {
|
class ColorFileParser {
|
||||||
|
|
||||||
static func parse(_ inputFile: String, colorStyle: ColorStyle) -> [ParsedColor] {
|
static func parse(_ inputFile: String, colorStyle: ColorStyle) -> [ParsedColor] {
|
||||||
// Get content of input file
|
// Get content of input file
|
||||||
let inputFileContent = try! String(contentsOfFile: inputFile, encoding: .utf8) // swiftlint:disable:this force_try
|
let inputFileContent = try! String(contentsOfFile: inputFile, encoding: .utf8)
|
||||||
let colorsByLines = inputFileContent.components(separatedBy: CharacterSet.newlines)
|
let colorsByLines = inputFileContent.components(separatedBy: CharacterSet.newlines)
|
||||||
|
|
||||||
// Iterate on each line of input file
|
// Iterate on each line of input file
|
||||||
@ -21,7 +20,7 @@ enum ColorFileParser {
|
|||||||
static func parseLines(lines: [String], colorStyle: ColorStyle) -> [ParsedColor] {
|
static func parseLines(lines: [String], colorStyle: ColorStyle) -> [ParsedColor] {
|
||||||
lines
|
lines
|
||||||
.enumerated()
|
.enumerated()
|
||||||
.compactMap { _, colorLine in // swiftlint:disable:this unused_enumerated
|
.compactMap { lineNumber, colorLine in
|
||||||
// Required format:
|
// Required format:
|
||||||
// colorName = "#RGB/#ARGB", colorName "#RGB/#ARGB", colorName "#RGB/#ARGB" "#RGB/#ARGB"
|
// colorName = "#RGB/#ARGB", colorName "#RGB/#ARGB", colorName "#RGB/#ARGB" "#RGB/#ARGB"
|
||||||
let colorLineCleanedUp = colorLine
|
let colorLineCleanedUp = colorLine
|
||||||
|
@ -5,13 +5,10 @@
|
|||||||
// Created by Thibaut Schmitt on 17/01/2022.
|
// Created by Thibaut Schmitt on 17/01/2022.
|
||||||
//
|
//
|
||||||
|
|
||||||
import ArgumentParser
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import ArgumentParser
|
||||||
// swiftlint:disable no_grouping_extension
|
|
||||||
|
|
||||||
struct FontsOptions: ParsableArguments {
|
struct FontsOptions: ParsableArguments {
|
||||||
|
|
||||||
@Flag(name: [.customShort("f"), .customShort("F")], help: "Should force generation")
|
@Flag(name: [.customShort("f"), .customShort("F")], help: "Should force generation")
|
||||||
var forceGeneration = false
|
var forceGeneration = false
|
||||||
|
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
// Created by Thibaut Schmitt on 13/12/2021.
|
// Created by Thibaut Schmitt on 13/12/2021.
|
||||||
//
|
//
|
||||||
|
|
||||||
import ArgumentParser
|
|
||||||
import Foundation
|
|
||||||
import ToolCore
|
import ToolCore
|
||||||
|
import Foundation
|
||||||
|
import ArgumentParser
|
||||||
|
|
||||||
struct Fonts: ParsableCommand {
|
struct Fonts: ParsableCommand {
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ struct Fonts: ParsableCommand {
|
|||||||
|
|
||||||
// MARK: - Run
|
// MARK: - Run
|
||||||
|
|
||||||
func run() throws {
|
public func run() throws {
|
||||||
print("[\(Self.toolName)] Starting fonts generation")
|
print("[\(Self.toolName)] Starting fonts generation")
|
||||||
print("[\(Self.toolName)] Will use inputFile \(options.inputFile) to generate fonts")
|
print("[\(Self.toolName)] Will use inputFile \(options.inputFile) to generate fonts")
|
||||||
|
|
||||||
@ -43,31 +43,22 @@ struct Fonts: ParsableCommand {
|
|||||||
let fontsToGenerate = FontFileParser.parse(options.inputFile)
|
let fontsToGenerate = FontFileParser.parse(options.inputFile)
|
||||||
|
|
||||||
// Get real font names
|
// Get real font names
|
||||||
let inputFolder = URL(fileURLWithPath: options.inputFile)
|
let inputFolder = URL(fileURLWithPath: options.inputFile).deletingLastPathComponent().relativePath
|
||||||
.deletingLastPathComponent()
|
let fontsNames = FontsToolHelper.getFontPostScriptName(for: fontsToGenerate,
|
||||||
.relativePath
|
inputFolder: inputFolder)
|
||||||
|
|
||||||
let fontsNames = FontsToolHelper.getFontPostScriptName(
|
|
||||||
for: fontsToGenerate,
|
|
||||||
inputFolder: inputFolder
|
|
||||||
)
|
|
||||||
|
|
||||||
// Generate extension
|
// Generate extension
|
||||||
FontExtensionGenerator.writeExtensionFile(
|
FontExtensionGenerator.writeExtensionFile(fontsNames: fontsNames,
|
||||||
fontsNames: fontsNames,
|
|
||||||
staticVar: options.staticMembers,
|
staticVar: options.staticMembers,
|
||||||
extensionName: options.extensionName,
|
extensionName: options.extensionName,
|
||||||
extensionFilePath: options.extensionFilePath,
|
extensionFilePath: options.extensionFilePath,
|
||||||
isSwiftUI: true
|
isSwiftUI: true)
|
||||||
)
|
|
||||||
|
|
||||||
FontExtensionGenerator.writeExtensionFile(
|
FontExtensionGenerator.writeExtensionFile(fontsNames: fontsNames,
|
||||||
fontsNames: fontsNames,
|
|
||||||
staticVar: options.staticMembers,
|
staticVar: options.staticMembers,
|
||||||
extensionName: options.extensionNameUIKit,
|
extensionName: options.extensionNameUIKit,
|
||||||
extensionFilePath: options.extensionFilePathUIKit,
|
extensionFilePath: options.extensionFilePathUIKit,
|
||||||
isSwiftUI: false
|
isSwiftUI: false)
|
||||||
)
|
|
||||||
|
|
||||||
print("Info.plist has been updated with:")
|
print("Info.plist has been updated with:")
|
||||||
print("\(FontPlistGenerator.generatePlistUIAppsFontContent(for: fontsNames, infoPlistPaths: options.infoPlistPaths))")
|
print("\(FontPlistGenerator.generatePlistUIAppsFontContent(for: fontsNames, infoPlistPaths: options.infoPlistPaths))")
|
||||||
@ -84,22 +75,20 @@ struct Fonts: ParsableCommand {
|
|||||||
guard fileManager.fileExists(atPath: options.inputFile) else {
|
guard fileManager.fileExists(atPath: options.inputFile) else {
|
||||||
let error = FontsToolError.fileNotExists(options.inputFile)
|
let error = FontsToolError.fileNotExists(options.inputFile)
|
||||||
print(error.description)
|
print(error.description)
|
||||||
Self.exit(withError: error)
|
Fonts.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extension for UIKit and SwiftUI should have different name
|
// Extension for UIKit and SwiftUI should have different name
|
||||||
guard options.extensionName != options.extensionNameUIKit else {
|
guard options.extensionName != options.extensionNameUIKit else {
|
||||||
let error = FontsToolError.extensionNamesCollision(options.extensionName)
|
let error = FontsToolError.extensionNamesCollision(options.extensionName)
|
||||||
print(error.description)
|
print(error.description)
|
||||||
Self.exit(withError: error)
|
Fonts.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if needed to regenerate
|
// Check if needed to regenerate
|
||||||
guard GeneratorChecker.shouldGenerate(
|
guard GeneratorChecker.shouldGenerate(force: options.forceGeneration,
|
||||||
force: options.forceGeneration,
|
|
||||||
inputFilePath: options.inputFile,
|
inputFilePath: options.inputFile,
|
||||||
extensionFilePath: options.extensionFilePath
|
extensionFilePath: options.extensionFilePath) else {
|
||||||
) else {
|
|
||||||
print("[\(Self.toolName)] Fonts are already up to date :) ")
|
print("[\(Self.toolName)] Fonts are already up to date :) ")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum FontsToolError: Error {
|
enum FontsToolError: Error {
|
||||||
|
|
||||||
case extensionNamesCollision(String)
|
case extensionNamesCollision(String)
|
||||||
case fcScan(String, Int32, String?)
|
case fcScan(String, Int32, String?)
|
||||||
case inputFolderNotFound(String)
|
case inputFolderNotFound(String)
|
||||||
@ -20,7 +19,7 @@ enum FontsToolError: Error {
|
|||||||
case .extensionNamesCollision(let extensionName):
|
case .extensionNamesCollision(let extensionName):
|
||||||
return "error: [\(Fonts.toolName)] Error on extension names, extension name and SwiftUI extension name should be different (\(extensionName) is used on both)"
|
return "error: [\(Fonts.toolName)] Error on extension names, extension name and SwiftUI extension name should be different (\(extensionName) is used on both)"
|
||||||
|
|
||||||
case let .fcScan(path, code, output):
|
case .fcScan(let path, let code, let output):
|
||||||
return "error: [\(Fonts.toolName)] Error while getting fontName (fc-scan --format %{postscriptname} \(path). fc-scan exit with \(code) and output is: \(output ?? "no output")"
|
return "error: [\(Fonts.toolName)] Error while getting fontName (fc-scan --format %{postscriptname} \(path). fc-scan exit with \(code) and output is: \(output ?? "no output")"
|
||||||
|
|
||||||
case .inputFolderNotFound(let inputFolder):
|
case .inputFolderNotFound(let inputFolder):
|
||||||
@ -29,7 +28,7 @@ enum FontsToolError: Error {
|
|||||||
case .fileNotExists(let filename):
|
case .fileNotExists(let filename):
|
||||||
return "error: [\(Fonts.toolName)] File \(filename) does not exists"
|
return "error: [\(Fonts.toolName)] File \(filename) does not exists"
|
||||||
|
|
||||||
case let .writeExtension(filename, info):
|
case .writeExtension(let filename, let info):
|
||||||
return "error: [\(Fonts.toolName)] An error occured while writing extension in \(filename): \(info)"
|
return "error: [\(Fonts.toolName)] An error occured while writing extension in \(filename): \(info)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import ToolCore
|
import ToolCore
|
||||||
|
|
||||||
enum FontsToolHelper {
|
class FontsToolHelper {
|
||||||
|
|
||||||
static func getFontPostScriptName(for fonts: [String], inputFolder: String) -> [FontName] {
|
static func getFontPostScriptName(for fonts: [String], inputFolder: String) -> [FontName] {
|
||||||
let fontsFilenames = Self.getFontsFilenames(fromInputFolder: inputFolder)
|
let fontsFilenames = Self.getFontsFilenames(fromInputFolder: inputFolder)
|
||||||
@ -43,10 +43,10 @@ enum FontsToolHelper {
|
|||||||
Fonts.exit(withError: error)
|
Fonts.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
let enumerator: FileManager.DirectoryEnumerator = fileManager.enumerator(atPath: inputFolder)! // swiftlint:disable:this force_unwrapping
|
let enumerator: FileManager.DirectoryEnumerator = fileManager.enumerator(atPath: inputFolder)!
|
||||||
|
|
||||||
// Filters font files
|
// Filters font files
|
||||||
let fontsFileNames: [String] = (enumerator.allObjects as! [String]) // swiftlint:disable:this force_cast
|
let fontsFileNames: [String] = (enumerator.allObjects as! [String])
|
||||||
.filter {
|
.filter {
|
||||||
if $0.hasSuffix(".ttf") || $0.hasSuffix(".otf") {
|
if $0.hasSuffix(".ttf") || $0.hasSuffix(".otf") {
|
||||||
return true
|
return true
|
||||||
@ -57,26 +57,17 @@ enum FontsToolHelper {
|
|||||||
return fontsFileNames
|
return fontsFileNames
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func getFontName(atPath path: String) -> FontName {
|
private static func getFontName(atPath path: String) -> String {
|
||||||
// print("fc-scan --format %{postscriptname} \(path)")
|
//print("fc-scan --format %{postscriptname} \(path)")
|
||||||
// Get real font name
|
// Get real font name
|
||||||
let task = Shell.shell(["fc-scan", "--format", "%{postscriptname}", path])
|
let task = Shell.shell(["fc-scan", "--format", "%{postscriptname}", path])
|
||||||
|
|
||||||
guard let postscriptName = task.output, task.terminationStatus == 0 else {
|
guard let fontName = task.output, task.terminationStatus == 0 else {
|
||||||
let error = FontsToolError.fcScan(path, task.terminationStatus, task.output)
|
let error = FontsToolError.fcScan(path, task.terminationStatus, task.output)
|
||||||
print(error.description)
|
print(error.description)
|
||||||
Fonts.exit(withError: error)
|
Fonts.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
let pathURL = URL(fileURLWithPath: path)
|
return fontName
|
||||||
let filename = pathURL
|
|
||||||
.deletingPathExtension()
|
|
||||||
.lastPathComponent
|
|
||||||
|
|
||||||
return FontName(
|
|
||||||
postscriptName: postscriptName,
|
|
||||||
filename: filename,
|
|
||||||
fileExtension: pathURL.pathExtension
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import ToolCore
|
import ToolCore
|
||||||
|
|
||||||
enum FontPlistGenerator {
|
class FontPlistGenerator {
|
||||||
|
|
||||||
static func generatePlistUIAppsFontContent(for fonts: [FontName], infoPlistPaths: [String]) -> String {
|
static func generatePlistUIAppsFontContent(for fonts: [FontName], infoPlistPaths: [String]) -> String {
|
||||||
let fontsToAddToPlist = fonts
|
let fontsToAddToPlist = fonts
|
||||||
.compactMap { $0 }
|
.compactMap { $0 }
|
||||||
@ -17,32 +16,26 @@ enum FontPlistGenerator {
|
|||||||
// Update each plist
|
// Update each plist
|
||||||
infoPlistPaths.forEach { infoPlist in
|
infoPlistPaths.forEach { infoPlist in
|
||||||
// Remove UIAppFonts value
|
// Remove UIAppFonts value
|
||||||
Shell.shell(
|
Shell.shell(launchPath: "/usr/libexec/PlistBuddy",
|
||||||
launchPath: "/usr/libexec/PlistBuddy",
|
["-c", "delete :UIAppFonts", infoPlist])
|
||||||
["-c", "delete :UIAppFonts", infoPlist]
|
|
||||||
)
|
|
||||||
|
|
||||||
// Add UIAppFonts empty array
|
// Add UIAppFonts empty array
|
||||||
debugPrint("Will PlistBuddy -c add :UIAppFonts array \(infoPlist)")
|
debugPrint("Will PlistBuddy -c add :UIAppFonts array \(infoPlist)")
|
||||||
Shell.shell(
|
Shell.shell(launchPath: "/usr/libexec/PlistBuddy",
|
||||||
launchPath: "/usr/libexec/PlistBuddy",
|
["-c", "add :UIAppFonts array", infoPlist])
|
||||||
["-c", "add :UIAppFonts array", infoPlist]
|
|
||||||
)
|
|
||||||
|
|
||||||
// Fill array with fonts
|
// Fill array with fonts
|
||||||
fontsToAddToPlist
|
fontsToAddToPlist
|
||||||
.forEach { fontName in
|
.forEach {
|
||||||
Shell.shell(
|
Shell.shell(launchPath: "/usr/libexec/PlistBuddy",
|
||||||
launchPath: "/usr/libexec/PlistBuddy",
|
["-c", "add :UIAppFonts: string \($0)", infoPlist])
|
||||||
["-c", "add :UIAppFonts: string \(fontName.filename).\(fontName.fileExtension)", infoPlist]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var plistData = "<key>UIAppFonts</key>\n\t<array>\n"
|
var plistData = "<key>UIAppFonts</key>\n\t<array>\n"
|
||||||
fontsToAddToPlist
|
fontsToAddToPlist
|
||||||
.forEach { fontName in
|
.forEach {
|
||||||
plistData += "\t\t<string>\(fontName.filename).\(fontName.fileExtension)</string>\n"
|
plistData += "\t\t<string>\($0)</string>\n"
|
||||||
}
|
}
|
||||||
plistData += "\t</array>"
|
plistData += "\t</array>"
|
||||||
|
|
||||||
|
@ -8,51 +8,45 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import ToolCore
|
import ToolCore
|
||||||
|
|
||||||
enum FontExtensionGenerator {
|
class FontExtensionGenerator {
|
||||||
|
|
||||||
private static func getFontNameEnum(fontsNames: [FontName]) -> String {
|
private static func getFontNameEnum(fontsNames: [String]) -> String {
|
||||||
var enumDefinition = " enum FontName: String {\n"
|
var enumDefinition = " enum FontName: String {\n"
|
||||||
|
|
||||||
fontsNames.forEach {
|
fontsNames.forEach {
|
||||||
enumDefinition += " case \($0.fontNameSanitize) = \"\($0.postscriptName)\"\n"
|
enumDefinition += " case \($0.fontNameSanitize) = \"\($0)\"\n"
|
||||||
}
|
}
|
||||||
enumDefinition += " }\n"
|
enumDefinition += " }\n"
|
||||||
|
|
||||||
return enumDefinition
|
return enumDefinition
|
||||||
}
|
}
|
||||||
|
|
||||||
static func writeExtensionFile(
|
static func writeExtensionFile(fontsNames: [String],
|
||||||
fontsNames: [FontName],
|
|
||||||
staticVar: Bool,
|
staticVar: Bool,
|
||||||
extensionName: String,
|
extensionName: String,
|
||||||
extensionFilePath: String,
|
extensionFilePath: String,
|
||||||
isSwiftUI: Bool
|
isSwiftUI: Bool) {
|
||||||
) {
|
|
||||||
// Create extension content
|
// Create extension content
|
||||||
let extensionContent = Self.getExtensionContent(
|
let extensionContent = Self.getExtensionContent(fontsNames: fontsNames,
|
||||||
fontsNames: fontsNames,
|
|
||||||
staticVar: staticVar,
|
staticVar: staticVar,
|
||||||
extensionName: extensionName,
|
extensionName: extensionName,
|
||||||
isSwiftUI: isSwiftUI
|
isSwiftUI: isSwiftUI)
|
||||||
)
|
|
||||||
|
|
||||||
// Write content
|
// Write content
|
||||||
let extensionFilePathURL = URL(fileURLWithPath: extensionFilePath)
|
let extensionFilePathURL = URL(fileURLWithPath: extensionFilePath)
|
||||||
do {
|
do {
|
||||||
try extensionContent.write(to: extensionFilePathURL, atomically: false, encoding: .utf8)
|
try extensionContent.write(to: extensionFilePathURL, atomically: false, encoding: .utf8)
|
||||||
} catch {
|
} catch let error {
|
||||||
let error = FontsToolError.writeExtension(extensionFilePath, error.localizedDescription)
|
let error = FontsToolError.writeExtension(extensionFilePath, error.localizedDescription)
|
||||||
print(error.description)
|
print(error.description)
|
||||||
Fonts.exit(withError: error)
|
Fonts.exit(withError: error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static func getExtensionContent(
|
static func getExtensionContent(fontsNames: [String],
|
||||||
fontsNames: [FontName],
|
|
||||||
staticVar: Bool,
|
staticVar: Bool,
|
||||||
extensionName: String,
|
extensionName: String,
|
||||||
isSwiftUI: Bool
|
isSwiftUI: Bool) -> String {
|
||||||
) -> String {
|
|
||||||
[
|
[
|
||||||
Self.getHeader(extensionClassname: extensionName, isSwiftUI: isSwiftUI),
|
Self.getHeader(extensionClassname: extensionName, isSwiftUI: isSwiftUI),
|
||||||
Self.getFontNameEnum(fontsNames: fontsNames),
|
Self.getFontNameEnum(fontsNames: fontsNames),
|
||||||
|
@ -7,19 +7,11 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
// swiftlint:disable no_grouping_extension
|
typealias FontName = String
|
||||||
|
|
||||||
struct FontName: Hashable {
|
|
||||||
|
|
||||||
let postscriptName: String
|
|
||||||
let filename: String
|
|
||||||
let fileExtension: String
|
|
||||||
}
|
|
||||||
|
|
||||||
extension FontName {
|
extension FontName {
|
||||||
|
|
||||||
var fontNameSanitize: String {
|
var fontNameSanitize: String {
|
||||||
postscriptName.removeCharacters(from: "[]+-_")
|
self.removeCharacters(from: "[]+-_")
|
||||||
}
|
}
|
||||||
|
|
||||||
func getProperty(isStatic: Bool, isSwiftUI: Bool) -> String {
|
func getProperty(isStatic: Bool, isSwiftUI: Bool) -> String {
|
||||||
|
@ -7,13 +7,10 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum FontFileParser {
|
class FontFileParser {
|
||||||
|
|
||||||
static func parse(_ inputFile: String) -> [String] {
|
static func parse(_ inputFile: String) -> [String] {
|
||||||
let inputFileContent = try! String( // swiftlint:disable:this force_try
|
let inputFileContent = try! String(contentsOfFile: inputFile,
|
||||||
contentsOfFile: inputFile,
|
encoding: .utf8)
|
||||||
encoding: .utf8
|
|
||||||
)
|
|
||||||
return inputFileContent.components(separatedBy: CharacterSet.newlines)
|
return inputFileContent.components(separatedBy: CharacterSet.newlines)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
// Created by Thibaut Schmitt on 30/08/2022.
|
// Created by Thibaut Schmitt on 30/08/2022.
|
||||||
//
|
//
|
||||||
|
|
||||||
import ArgumentParser
|
|
||||||
import Foundation
|
|
||||||
import ToolCore
|
import ToolCore
|
||||||
|
import Foundation
|
||||||
|
import ArgumentParser
|
||||||
|
|
||||||
struct Generate: ParsableCommand {
|
struct Generate: ParsableCommand {
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ struct Generate: ParsableCommand {
|
|||||||
|
|
||||||
// MARK: - Run
|
// MARK: - Run
|
||||||
|
|
||||||
func run() throws {
|
public func run() throws {
|
||||||
print("[\(Self.toolName)] Starting Resgen with configuration: \(options.configurationFile)")
|
print("[\(Self.toolName)] Starting Resgen with configuration: \(options.configurationFile)")
|
||||||
|
|
||||||
// Parse
|
// Parse
|
||||||
@ -43,20 +43,16 @@ struct Generate: ParsableCommand {
|
|||||||
print()
|
print()
|
||||||
|
|
||||||
if let architecture = configuration.architecture {
|
if let architecture = configuration.architecture {
|
||||||
ArchitectureGenerator.writeArchitecture(
|
ArchitectureGenerator.writeArchitecture(architecture,
|
||||||
architecture,
|
projectDirectory: options.projectDirectory)
|
||||||
projectDirectory: options.projectDirectory
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute commands
|
// Execute commands
|
||||||
configuration.runnableConfigurations
|
configuration.runnableConfigurations
|
||||||
.forEach {
|
.forEach {
|
||||||
let begin = Date()
|
let begin = Date()
|
||||||
$0.run(
|
$0.run(projectDirectory: options.projectDirectory,
|
||||||
projectDirectory: options.projectDirectory,
|
force: options.forceGeneration)
|
||||||
force: options.forceGeneration
|
|
||||||
)
|
|
||||||
print("Took: \(Date().timeIntervalSince(begin))s\n")
|
print("Took: \(Date().timeIntervalSince(begin))s\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum GenerateError: Error {
|
enum GenerateError: Error {
|
||||||
|
|
||||||
case fileNotExists(String)
|
case fileNotExists(String)
|
||||||
case invalidConfigurationFile(String, String)
|
case invalidConfigurationFile(String, String)
|
||||||
case commandError([String], String)
|
case commandError([String], String)
|
||||||
@ -19,15 +18,16 @@ enum GenerateError: Error {
|
|||||||
case .fileNotExists(let filename):
|
case .fileNotExists(let filename):
|
||||||
return "error: [\(Generate.toolName)] File \(filename) does not exists"
|
return "error: [\(Generate.toolName)] File \(filename) does not exists"
|
||||||
|
|
||||||
case let .invalidConfigurationFile(filename, underneathErrorDescription):
|
case .invalidConfigurationFile(let filename, let underneathErrorDescription):
|
||||||
return "error: [\(Generate.toolName)] File \(filename) is not a valid configuration file. Underneath error: \(underneathErrorDescription)"
|
return "error: [\(Generate.toolName)] File \(filename) is not a valid configuration file. Underneath error: \(underneathErrorDescription)"
|
||||||
|
|
||||||
case let .commandError(command, terminationStatus):
|
case .commandError(let command, let terminationStatus):
|
||||||
let readableCommand = command
|
let readableCommand = command
|
||||||
|
.map { $0 }
|
||||||
.joined(separator: " ")
|
.joined(separator: " ")
|
||||||
return "error: [\(Generate.toolName)] An error occured while running command '\(readableCommand)'. Command terminate with status code: \(terminationStatus)"
|
return "error: [\(Generate.toolName)] An error occured while running command '\(readableCommand)'. Command terminate with status code: \(terminationStatus)"
|
||||||
|
|
||||||
case let .writeFile(filename, info):
|
case .writeFile(let filename, let info):
|
||||||
return "error: [\(Generate.toolName)] An error occured while writing file in \(filename): \(info)"
|
return "error: [\(Generate.toolName)] An error occured while writing file in \(filename): \(info)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,10 @@
|
|||||||
// Created by Thibaut Schmitt on 30/08/2022.
|
// Created by Thibaut Schmitt on 30/08/2022.
|
||||||
//
|
//
|
||||||
|
|
||||||
import ArgumentParser
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import ArgumentParser
|
||||||
|
|
||||||
struct GenerateOptions: ParsableArguments {
|
struct GenerateOptions: ParsableArguments {
|
||||||
|
|
||||||
@Flag(name: [.customShort("f"), .customShort("F")], help: "Should force generation")
|
@Flag(name: [.customShort("f"), .customShort("F")], help: "Should force generation")
|
||||||
var forceGeneration = false
|
var forceGeneration = false
|
||||||
|
|
||||||
|
@ -5,11 +5,10 @@
|
|||||||
// Created by Thibaut Schmitt on 18/11/2022.
|
// Created by Thibaut Schmitt on 18/11/2022.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import ToolCore
|
import ToolCore
|
||||||
|
import Foundation
|
||||||
|
|
||||||
enum ArchitectureGenerator {
|
struct ArchitectureGenerator {
|
||||||
|
|
||||||
static func writeArchitecture(_ architecture: ConfigurationArchitecture, projectDirectory: String) {
|
static func writeArchitecture(_ architecture: ConfigurationArchitecture, projectDirectory: String) {
|
||||||
// Create extension content
|
// Create extension content
|
||||||
var architectureContent = [
|
var architectureContent = [
|
||||||
@ -31,7 +30,7 @@ enum ArchitectureGenerator {
|
|||||||
let architectureFilePathURL = URL(fileURLWithPath: "\(filePath)/\(filename)")
|
let architectureFilePathURL = URL(fileURLWithPath: "\(filePath)/\(filename)")
|
||||||
do {
|
do {
|
||||||
try architectureContent.write(to: architectureFilePathURL, atomically: false, encoding: .utf8)
|
try architectureContent.write(to: architectureFilePathURL, atomically: false, encoding: .utf8)
|
||||||
} catch {
|
} catch let error {
|
||||||
let error = GenerateError.writeFile(filename, error.localizedDescription)
|
let error = GenerateError.writeFile(filename, error.localizedDescription)
|
||||||
print(error.description)
|
print(error.description)
|
||||||
Generate.exit(withError: error)
|
Generate.exit(withError: error)
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
struct ConfigurationFile: Codable, CustomDebugStringConvertible {
|
struct ConfigurationFile: Codable, CustomDebugStringConvertible {
|
||||||
|
|
||||||
var architecture: ConfigurationArchitecture?
|
var architecture: ConfigurationArchitecture?
|
||||||
var analytics: [AnalyticsConfiguration]
|
var analytics: [AnalyticsConfiguration]
|
||||||
var colors: [ColorsConfiguration]
|
var colors: [ColorsConfiguration]
|
||||||
@ -45,11 +44,10 @@ struct ConfigurationFile: Codable, CustomDebugStringConvertible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct ConfigurationArchitecture: Codable {
|
struct ConfigurationArchitecture: Codable {
|
||||||
|
|
||||||
let property: String
|
let property: String
|
||||||
let classname: String
|
let classname: String
|
||||||
let path: String?
|
let path: String?
|
||||||
let children: [Self]?
|
let children: [ConfigurationArchitecture]?
|
||||||
|
|
||||||
func getProperty(isStatic: Bool) -> String {
|
func getProperty(isStatic: Bool) -> String {
|
||||||
" \(isStatic ? "static " : "")let \(property) = \(classname)()"
|
" \(isStatic ? "static " : "")let \(property) = \(classname)()"
|
||||||
@ -57,7 +55,7 @@ struct ConfigurationArchitecture: Codable {
|
|||||||
|
|
||||||
func getClass(generateStaticProperty: Bool = true) -> String {
|
func getClass(generateStaticProperty: Bool = true) -> String {
|
||||||
guard children?.isEmpty == false else {
|
guard children?.isEmpty == false else {
|
||||||
return "final class \(classname): Sendable {}"
|
return "class \(classname) {}"
|
||||||
}
|
}
|
||||||
|
|
||||||
let classDefinition = [
|
let classDefinition = [
|
||||||
@ -83,7 +81,6 @@ struct ConfigurationArchitecture: Codable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct AnalyticsConfiguration: Codable, CustomDebugStringConvertible {
|
struct AnalyticsConfiguration: Codable, CustomDebugStringConvertible {
|
||||||
|
|
||||||
let inputFile: String
|
let inputFile: String
|
||||||
let target: String
|
let target: String
|
||||||
let extensionOutputPath: String
|
let extensionOutputPath: String
|
||||||
@ -92,20 +89,18 @@ struct AnalyticsConfiguration: Codable, CustomDebugStringConvertible {
|
|||||||
private let staticMembers: Bool?
|
private let staticMembers: Bool?
|
||||||
|
|
||||||
var staticMembersOptions: Bool {
|
var staticMembersOptions: Bool {
|
||||||
if let staticMembers {
|
if let staticMembers = staticMembers {
|
||||||
return staticMembers
|
return staticMembers
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
internal init(
|
internal init(inputFile: String,
|
||||||
inputFile: String,
|
|
||||||
target: String,
|
target: String,
|
||||||
extensionOutputPath: String,
|
extensionOutputPath: String,
|
||||||
extensionName: String?,
|
extensionName: String?,
|
||||||
extensionSuffix: String?,
|
extensionSuffix: String?,
|
||||||
staticMembers: Bool?
|
staticMembers: Bool?) {
|
||||||
) {
|
|
||||||
self.inputFile = inputFile
|
self.inputFile = inputFile
|
||||||
self.target = target
|
self.target = target
|
||||||
self.extensionOutputPath = extensionOutputPath
|
self.extensionOutputPath = extensionOutputPath
|
||||||
@ -127,7 +122,6 @@ struct AnalyticsConfiguration: Codable, CustomDebugStringConvertible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct ColorsConfiguration: Codable, CustomDebugStringConvertible {
|
struct ColorsConfiguration: Codable, CustomDebugStringConvertible {
|
||||||
|
|
||||||
let inputFile: String
|
let inputFile: String
|
||||||
let style: String
|
let style: String
|
||||||
let xcassetsPath: String
|
let xcassetsPath: String
|
||||||
@ -138,22 +132,20 @@ struct ColorsConfiguration: Codable, CustomDebugStringConvertible {
|
|||||||
private let staticMembers: Bool?
|
private let staticMembers: Bool?
|
||||||
|
|
||||||
var staticMembersOptions: Bool {
|
var staticMembersOptions: Bool {
|
||||||
if let staticMembers {
|
if let staticMembers = staticMembers {
|
||||||
return staticMembers
|
return staticMembers
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
internal init(
|
internal init(inputFile: String,
|
||||||
inputFile: String,
|
|
||||||
style: String,
|
style: String,
|
||||||
xcassetsPath: String,
|
xcassetsPath: String,
|
||||||
extensionOutputPath: String,
|
extensionOutputPath: String,
|
||||||
extensionName: String?,
|
extensionName: String?,
|
||||||
extensionNameUIKit: String?,
|
extensionNameUIKit: String?,
|
||||||
extensionSuffix: String?,
|
extensionSuffix: String?,
|
||||||
staticMembers: Bool?
|
staticMembers: Bool?) {
|
||||||
) {
|
|
||||||
self.inputFile = inputFile
|
self.inputFile = inputFile
|
||||||
self.style = style
|
self.style = style
|
||||||
self.xcassetsPath = xcassetsPath
|
self.xcassetsPath = xcassetsPath
|
||||||
@ -179,7 +171,6 @@ struct ColorsConfiguration: Codable, CustomDebugStringConvertible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct FontsConfiguration: Codable, CustomDebugStringConvertible {
|
struct FontsConfiguration: Codable, CustomDebugStringConvertible {
|
||||||
|
|
||||||
let inputFile: String
|
let inputFile: String
|
||||||
let extensionOutputPath: String
|
let extensionOutputPath: String
|
||||||
let extensionName: String?
|
let extensionName: String?
|
||||||
@ -189,21 +180,19 @@ struct FontsConfiguration: Codable, CustomDebugStringConvertible {
|
|||||||
private let staticMembers: Bool?
|
private let staticMembers: Bool?
|
||||||
|
|
||||||
var staticMembersOptions: Bool {
|
var staticMembersOptions: Bool {
|
||||||
if let staticMembers {
|
if let staticMembers = staticMembers {
|
||||||
return staticMembers
|
return staticMembers
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
internal init(
|
internal init(inputFile: String,
|
||||||
inputFile: String,
|
|
||||||
extensionOutputPath: String,
|
extensionOutputPath: String,
|
||||||
extensionName: String?,
|
extensionName: String?,
|
||||||
extensionNameUIKit: String?,
|
extensionNameUIKit: String?,
|
||||||
extensionSuffix: String?,
|
extensionSuffix: String?,
|
||||||
infoPlistPaths: String?,
|
infoPlistPaths: String?,
|
||||||
staticMembers: Bool?
|
staticMembers: Bool?) {
|
||||||
) {
|
|
||||||
self.inputFile = inputFile
|
self.inputFile = inputFile
|
||||||
self.extensionOutputPath = extensionOutputPath
|
self.extensionOutputPath = extensionOutputPath
|
||||||
self.extensionName = extensionName
|
self.extensionName = extensionName
|
||||||
@ -227,7 +216,6 @@ struct FontsConfiguration: Codable, CustomDebugStringConvertible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct ImagesConfiguration: Codable, CustomDebugStringConvertible {
|
struct ImagesConfiguration: Codable, CustomDebugStringConvertible {
|
||||||
|
|
||||||
let inputFile: String
|
let inputFile: String
|
||||||
let xcassetsPath: String
|
let xcassetsPath: String
|
||||||
let extensionOutputPath: String
|
let extensionOutputPath: String
|
||||||
@ -237,21 +225,19 @@ struct ImagesConfiguration: Codable, CustomDebugStringConvertible {
|
|||||||
private let staticMembers: Bool?
|
private let staticMembers: Bool?
|
||||||
|
|
||||||
var staticMembersOptions: Bool {
|
var staticMembersOptions: Bool {
|
||||||
if let staticMembers {
|
if let staticMembers = staticMembers {
|
||||||
return staticMembers
|
return staticMembers
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
internal init(
|
internal init(inputFile: String,
|
||||||
inputFile: String,
|
|
||||||
xcassetsPath: String,
|
xcassetsPath: String,
|
||||||
extensionOutputPath: String,
|
extensionOutputPath: String,
|
||||||
extensionName: String?,
|
extensionName: String?,
|
||||||
extensionNameUIKit: String?,
|
extensionNameUIKit: String?,
|
||||||
extensionSuffix: String?,
|
extensionSuffix: String?,
|
||||||
staticMembers: Bool?
|
staticMembers: Bool?) {
|
||||||
) {
|
|
||||||
self.inputFile = inputFile
|
self.inputFile = inputFile
|
||||||
self.xcassetsPath = xcassetsPath
|
self.xcassetsPath = xcassetsPath
|
||||||
self.extensionOutputPath = extensionOutputPath
|
self.extensionOutputPath = extensionOutputPath
|
||||||
@ -275,7 +261,6 @@ struct ImagesConfiguration: Codable, CustomDebugStringConvertible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct StringsConfiguration: Codable, CustomDebugStringConvertible {
|
struct StringsConfiguration: Codable, CustomDebugStringConvertible {
|
||||||
|
|
||||||
let inputFile: String
|
let inputFile: String
|
||||||
let outputPath: String
|
let outputPath: String
|
||||||
let langs: String
|
let langs: String
|
||||||
@ -287,21 +272,20 @@ struct StringsConfiguration: Codable, CustomDebugStringConvertible {
|
|||||||
private let xcStrings: Bool?
|
private let xcStrings: Bool?
|
||||||
|
|
||||||
var staticMembersOptions: Bool {
|
var staticMembersOptions: Bool {
|
||||||
if let staticMembers {
|
if let staticMembers = staticMembers {
|
||||||
return staticMembers
|
return staticMembers
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
var xcStringsOptions: Bool {
|
var xcStringsOptions: Bool {
|
||||||
if let xcStrings {
|
if let xcStrings = xcStrings {
|
||||||
return xcStrings
|
return xcStrings
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
internal init(
|
internal init(inputFile: String,
|
||||||
inputFile: String,
|
|
||||||
outputPath: String,
|
outputPath: String,
|
||||||
langs: String,
|
langs: String,
|
||||||
defaultLang: String,
|
defaultLang: String,
|
||||||
@ -309,8 +293,7 @@ struct StringsConfiguration: Codable, CustomDebugStringConvertible {
|
|||||||
extensionName: String?,
|
extensionName: String?,
|
||||||
extensionSuffix: String?,
|
extensionSuffix: String?,
|
||||||
staticMembers: Bool?,
|
staticMembers: Bool?,
|
||||||
xcStrings: Bool?
|
xcStrings: Bool?) {
|
||||||
) {
|
|
||||||
self.inputFile = inputFile
|
self.inputFile = inputFile
|
||||||
self.outputPath = outputPath
|
self.outputPath = outputPath
|
||||||
self.langs = langs
|
self.langs = langs
|
||||||
@ -337,7 +320,6 @@ struct StringsConfiguration: Codable, CustomDebugStringConvertible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct TagsConfiguration: Codable, CustomDebugStringConvertible {
|
struct TagsConfiguration: Codable, CustomDebugStringConvertible {
|
||||||
|
|
||||||
let inputFile: String
|
let inputFile: String
|
||||||
let lang: String
|
let lang: String
|
||||||
let extensionOutputPath: String
|
let extensionOutputPath: String
|
||||||
@ -346,20 +328,18 @@ struct TagsConfiguration: Codable, CustomDebugStringConvertible {
|
|||||||
private let staticMembers: Bool?
|
private let staticMembers: Bool?
|
||||||
|
|
||||||
var staticMembersOptions: Bool {
|
var staticMembersOptions: Bool {
|
||||||
if let staticMembers {
|
if let staticMembers = staticMembers {
|
||||||
return staticMembers
|
return staticMembers
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
internal init(
|
internal init(inputFile: String,
|
||||||
inputFile: String,
|
|
||||||
lang: String,
|
lang: String,
|
||||||
extensionOutputPath: String,
|
extensionOutputPath: String,
|
||||||
extensionName: String?,
|
extensionName: String?,
|
||||||
extensionSuffix: String?,
|
extensionSuffix: String?,
|
||||||
staticMembers: Bool?
|
staticMembers: Bool?) {
|
||||||
) {
|
|
||||||
self.inputFile = inputFile
|
self.inputFile = inputFile
|
||||||
self.lang = lang
|
self.lang = lang
|
||||||
self.extensionOutputPath = extensionOutputPath
|
self.extensionOutputPath = extensionOutputPath
|
||||||
|
@ -8,8 +8,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import Yams
|
import Yams
|
||||||
|
|
||||||
enum ConfigurationFileParser {
|
class ConfigurationFileParser {
|
||||||
|
|
||||||
static func parse(_ configurationFile: String) -> ConfigurationFile {
|
static func parse(_ configurationFile: String) -> ConfigurationFile {
|
||||||
guard let data = FileManager().contents(atPath: configurationFile) else {
|
guard let data = FileManager().contents(atPath: configurationFile) else {
|
||||||
let error = GenerateError.fileNotExists(configurationFile)
|
let error = GenerateError.fileNotExists(configurationFile)
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
extension AnalyticsConfiguration: Runnable {
|
extension AnalyticsConfiguration: Runnable {
|
||||||
|
|
||||||
func run(projectDirectory: String, force: Bool) {
|
func run(projectDirectory: String, force: Bool) {
|
||||||
var args = [String]()
|
var args = [String]()
|
||||||
|
|
||||||
@ -26,13 +25,13 @@ extension AnalyticsConfiguration: Runnable {
|
|||||||
"\(staticMembersOptions)"
|
"\(staticMembersOptions)"
|
||||||
]
|
]
|
||||||
|
|
||||||
if let extensionName {
|
if let extensionName = extensionName {
|
||||||
args += [
|
args += [
|
||||||
"--extension-name",
|
"--extension-name",
|
||||||
extensionName
|
extensionName
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
if let extensionSuffix {
|
if let extensionSuffix = extensionSuffix {
|
||||||
args += [
|
args += [
|
||||||
"--extension-suffix",
|
"--extension-suffix",
|
||||||
extensionSuffix
|
extensionSuffix
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
extension ColorsConfiguration: Runnable {
|
extension ColorsConfiguration: Runnable {
|
||||||
|
|
||||||
func run(projectDirectory: String, force: Bool) {
|
func run(projectDirectory: String, force: Bool) {
|
||||||
let args = getArguments(projectDirectory: projectDirectory, force: force)
|
let args = getArguments(projectDirectory: projectDirectory, force: force)
|
||||||
Colors.main(args)
|
Colors.main(args)
|
||||||
@ -33,19 +32,19 @@ extension ColorsConfiguration: Runnable {
|
|||||||
"\(staticMembersOptions)"
|
"\(staticMembersOptions)"
|
||||||
]
|
]
|
||||||
|
|
||||||
if let extensionName {
|
if let extensionName = extensionName {
|
||||||
args += [
|
args += [
|
||||||
"--extension-name",
|
"--extension-name",
|
||||||
extensionName
|
extensionName
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
if let extensionNameUIKit {
|
if let extensionNameUIKit = extensionNameUIKit {
|
||||||
args += [
|
args += [
|
||||||
"--extension-name-ui-kit",
|
"--extension-name-ui-kit",
|
||||||
extensionNameUIKit
|
extensionNameUIKit
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
if let extensionSuffix {
|
if let extensionSuffix = extensionSuffix {
|
||||||
args += [
|
args += [
|
||||||
"--extension-suffix",
|
"--extension-suffix",
|
||||||
extensionSuffix
|
extensionSuffix
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
extension FontsConfiguration: Runnable {
|
extension FontsConfiguration: Runnable {
|
||||||
|
|
||||||
func run(projectDirectory: String, force: Bool) {
|
func run(projectDirectory: String, force: Bool) {
|
||||||
let args = getArguments(projectDirectory: projectDirectory, force: force)
|
let args = getArguments(projectDirectory: projectDirectory, force: force)
|
||||||
Fonts.main(args)
|
Fonts.main(args)
|
||||||
@ -29,27 +28,27 @@ extension FontsConfiguration: Runnable {
|
|||||||
"\(staticMembersOptions)"
|
"\(staticMembersOptions)"
|
||||||
]
|
]
|
||||||
|
|
||||||
if let extensionName {
|
if let extensionName = extensionName {
|
||||||
args += [
|
args += [
|
||||||
"--extension-name",
|
"--extension-name",
|
||||||
extensionName
|
extensionName
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
if let extensionNameUIKit {
|
if let extensionNameUIKit = extensionNameUIKit {
|
||||||
args += [
|
args += [
|
||||||
"--extension-name-ui-kit",
|
"--extension-name-ui-kit",
|
||||||
extensionNameUIKit
|
extensionNameUIKit
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
if let extensionSuffix {
|
if let extensionSuffix = extensionSuffix {
|
||||||
args += [
|
args += [
|
||||||
"--extension-suffix",
|
"--extension-suffix",
|
||||||
extensionSuffix
|
extensionSuffix
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
if let infoPlistPaths {
|
if let infoPlistPaths = infoPlistPaths {
|
||||||
let adjustedPlistPaths = infoPlistPaths
|
let adjustedPlistPaths = infoPlistPaths
|
||||||
.split(separator: " ")
|
.split(separator: " ")
|
||||||
.map { String($0).prependIfRelativePath(projectDirectory) }
|
.map { String($0).prependIfRelativePath(projectDirectory) }
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
extension ImagesConfiguration: Runnable {
|
extension ImagesConfiguration: Runnable {
|
||||||
|
|
||||||
func run(projectDirectory: String, force: Bool) {
|
func run(projectDirectory: String, force: Bool) {
|
||||||
let args = getArguments(projectDirectory: projectDirectory, force: force)
|
let args = getArguments(projectDirectory: projectDirectory, force: force)
|
||||||
Images.main(args)
|
Images.main(args)
|
||||||
@ -31,21 +30,19 @@ extension ImagesConfiguration: Runnable {
|
|||||||
"\(staticMembersOptions)"
|
"\(staticMembersOptions)"
|
||||||
]
|
]
|
||||||
|
|
||||||
if let extensionName {
|
if let extensionName = extensionName {
|
||||||
args += [
|
args += [
|
||||||
"--extension-name",
|
"--extension-name",
|
||||||
extensionName
|
extensionName
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
if let extensionNameUIKit = extensionNameUIKit {
|
||||||
if let extensionNameUIKit {
|
|
||||||
args += [
|
args += [
|
||||||
"--extension-name-ui-kit",
|
"--extension-name-ui-kit",
|
||||||
extensionNameUIKit
|
extensionNameUIKit
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
if let extensionSuffix = extensionSuffix {
|
||||||
if let extensionSuffix {
|
|
||||||
args += [
|
args += [
|
||||||
"--extension-suffix",
|
"--extension-suffix",
|
||||||
extensionSuffix
|
extensionSuffix
|
||||||
|
@ -8,6 +8,5 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
protocol Runnable {
|
protocol Runnable {
|
||||||
|
|
||||||
func run(projectDirectory: String, force: Bool)
|
func run(projectDirectory: String, force: Bool)
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
extension StringsConfiguration: Runnable {
|
extension StringsConfiguration: Runnable {
|
||||||
|
|
||||||
func run(projectDirectory: String, force: Bool) {
|
func run(projectDirectory: String, force: Bool) {
|
||||||
var args = [String]()
|
var args = [String]()
|
||||||
|
|
||||||
@ -32,14 +31,14 @@ extension StringsConfiguration: Runnable {
|
|||||||
"\(xcStringsOptions)"
|
"\(xcStringsOptions)"
|
||||||
]
|
]
|
||||||
|
|
||||||
if let extensionName {
|
if let extensionName = extensionName {
|
||||||
args += [
|
args += [
|
||||||
"--extension-name",
|
"--extension-name",
|
||||||
extensionName
|
extensionName
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
if let extensionSuffix {
|
if let extensionSuffix = extensionSuffix {
|
||||||
args += [
|
args += [
|
||||||
"--extension-suffix",
|
"--extension-suffix",
|
||||||
extensionSuffix
|
extensionSuffix
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
extension TagsConfiguration: Runnable {
|
extension TagsConfiguration: Runnable {
|
||||||
|
|
||||||
func run(projectDirectory: String, force: Bool) {
|
func run(projectDirectory: String, force: Bool) {
|
||||||
var args = [String]()
|
var args = [String]()
|
||||||
|
|
||||||
@ -26,13 +25,13 @@ extension TagsConfiguration: Runnable {
|
|||||||
"\(staticMembersOptions)"
|
"\(staticMembersOptions)"
|
||||||
]
|
]
|
||||||
|
|
||||||
if let extensionName {
|
if let extensionName = extensionName {
|
||||||
args += [
|
args += [
|
||||||
"--extension-name",
|
"--extension-name",
|
||||||
extensionName
|
extensionName
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
if let extensionSuffix {
|
if let extensionSuffix = extensionSuffix {
|
||||||
args += [
|
args += [
|
||||||
"--extension-suffix",
|
"--extension-suffix",
|
||||||
extensionSuffix
|
extensionSuffix
|
||||||
|
@ -7,10 +7,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
// swiftlint:disable force_unwrapping
|
|
||||||
|
|
||||||
extension FileManager {
|
extension FileManager {
|
||||||
|
|
||||||
func getAllRegularFileIn(directory: String) -> [String] {
|
func getAllRegularFileIn(directory: String) -> [String] {
|
||||||
var files = [String]()
|
var files = [String]()
|
||||||
guard let enumerator = self.enumerator(at: URL(string: directory)!, includingPropertiesForKeys: [.isRegularFileKey], options: [.skipsHiddenFiles, .skipsPackageDescendants]) else {
|
guard let enumerator = self.enumerator(at: URL(string: directory)!, includingPropertiesForKeys: [.isRegularFileKey], options: [.skipsHiddenFiles, .skipsPackageDescendants]) else {
|
||||||
|
@ -5,48 +5,42 @@
|
|||||||
// Created by Thibaut Schmitt on 14/02/2022.
|
// Created by Thibaut Schmitt on 14/02/2022.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import ToolCore
|
import ToolCore
|
||||||
|
import Foundation
|
||||||
|
|
||||||
enum ImageExtensionGenerator {
|
class ImageExtensionGenerator {
|
||||||
|
|
||||||
// MARK: - UIKit
|
// MARK: - UIKit
|
||||||
|
|
||||||
static func generateExtensionFile(
|
static func generateExtensionFile(images: [ParsedImage],
|
||||||
images: [ParsedImage],
|
|
||||||
staticVar: Bool,
|
staticVar: Bool,
|
||||||
inputFilename: String,
|
inputFilename: String,
|
||||||
extensionName: String,
|
extensionName: String,
|
||||||
extensionFilePath: String,
|
extensionFilePath: String,
|
||||||
isSwiftUI: Bool
|
isSwiftUI: Bool) {
|
||||||
) {
|
|
||||||
// Create extension conten1t
|
// Create extension conten1t
|
||||||
let extensionContent = Self.getExtensionContent(
|
let extensionContent = Self.getExtensionContent(images: images,
|
||||||
images: images,
|
|
||||||
staticVar: staticVar,
|
staticVar: staticVar,
|
||||||
extensionName: extensionName,
|
extensionName: extensionName,
|
||||||
inputFilename: inputFilename,
|
inputFilename: inputFilename,
|
||||||
isSwiftUI: isSwiftUI
|
isSwiftUI: isSwiftUI)
|
||||||
)
|
|
||||||
|
|
||||||
// Write content
|
// Write content
|
||||||
let extensionFilePathURL = URL(fileURLWithPath: extensionFilePath)
|
let extensionFilePathURL = URL(fileURLWithPath: extensionFilePath)
|
||||||
do {
|
do {
|
||||||
try extensionContent.write(to: extensionFilePathURL, atomically: false, encoding: .utf8)
|
try extensionContent.write(to: extensionFilePathURL, atomically: false, encoding: .utf8)
|
||||||
} catch {
|
} catch let error {
|
||||||
let error = ImagesError.writeFile(extensionFilePath, error.localizedDescription)
|
let error = ImagesError.writeFile(extensionFilePath, error.localizedDescription)
|
||||||
print(error.description)
|
print(error.description)
|
||||||
Images.exit(withError: error)
|
Images.exit(withError: error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static func getExtensionContent(
|
static func getExtensionContent(images: [ParsedImage],
|
||||||
images: [ParsedImage],
|
|
||||||
staticVar: Bool,
|
staticVar: Bool,
|
||||||
extensionName: String,
|
extensionName: String,
|
||||||
inputFilename: String,
|
inputFilename: String,
|
||||||
isSwiftUI: Bool
|
isSwiftUI: Bool) -> String {
|
||||||
) -> String {
|
|
||||||
[
|
[
|
||||||
Self.getHeader(inputFilename: inputFilename, extensionClassname: extensionName, isSwiftUI: isSwiftUI),
|
Self.getHeader(inputFilename: inputFilename, extensionClassname: extensionName, isSwiftUI: isSwiftUI),
|
||||||
Self.getProperties(images: images, staticVar: staticVar, isSwiftUI: isSwiftUI),
|
Self.getProperties(images: images, staticVar: staticVar, isSwiftUI: isSwiftUI),
|
||||||
@ -55,11 +49,9 @@ enum ImageExtensionGenerator {
|
|||||||
.joined(separator: "\n")
|
.joined(separator: "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func getHeader(
|
private static func getHeader(inputFilename: String,
|
||||||
inputFilename: String,
|
|
||||||
extensionClassname: String,
|
extensionClassname: String,
|
||||||
isSwiftUI: Bool
|
isSwiftUI: Bool) -> String {
|
||||||
) -> String {
|
|
||||||
"""
|
"""
|
||||||
// Generated by ResgenSwift.\(Images.toolName) \(ResgenSwiftVersion)
|
// Generated by ResgenSwift.\(Images.toolName) \(ResgenSwiftVersion)
|
||||||
// Images from \(inputFilename)
|
// Images from \(inputFilename)
|
||||||
@ -70,11 +62,7 @@ enum ImageExtensionGenerator {
|
|||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func getProperties(
|
private static func getProperties(images: [ParsedImage], staticVar: Bool, isSwiftUI: Bool) -> String {
|
||||||
images: [ParsedImage],
|
|
||||||
staticVar: Bool,
|
|
||||||
isSwiftUI: Bool
|
|
||||||
) -> String {
|
|
||||||
images
|
images
|
||||||
.map { "\n\($0.getImageProperty(isStatic: staticVar, isSwiftUI: isSwiftUI))" }
|
.map { "\n\($0.getImageProperty(isStatic: staticVar, isSwiftUI: isSwiftUI))" }
|
||||||
.joined(separator: "\n")
|
.joined(separator: "\n")
|
||||||
|
@ -9,15 +9,12 @@ import Foundation
|
|||||||
import ToolCore
|
import ToolCore
|
||||||
|
|
||||||
enum OutputImageExtension: String {
|
enum OutputImageExtension: String {
|
||||||
|
|
||||||
case png
|
case png
|
||||||
case svg
|
case svg
|
||||||
}
|
}
|
||||||
|
|
||||||
class XcassetsGenerator {
|
class XcassetsGenerator {
|
||||||
|
|
||||||
// MARK: - Properties
|
|
||||||
|
|
||||||
let forceGeneration: Bool
|
let forceGeneration: Bool
|
||||||
|
|
||||||
// MARK: - Init
|
// MARK: - Init
|
||||||
@ -31,13 +28,12 @@ class XcassetsGenerator {
|
|||||||
func generateXcassets(inputPath: String, imagesToGenerate: [ParsedImage], xcassetsPath: String) {
|
func generateXcassets(inputPath: String, imagesToGenerate: [ParsedImage], xcassetsPath: String) {
|
||||||
let fileManager = FileManager()
|
let fileManager = FileManager()
|
||||||
let svgConverter = Images.getSvgConverterPath()
|
let svgConverter = Images.getSvgConverterPath()
|
||||||
let magickConvert = Images.getMagickConvertPath()
|
|
||||||
let allSubFiles = fileManager.getAllRegularFileIn(directory: inputPath)
|
let allSubFiles = fileManager.getAllRegularFileIn(directory: inputPath)
|
||||||
|
|
||||||
var generatedAssetsPaths = [String]()
|
var generatedAssetsPaths = [String]()
|
||||||
|
|
||||||
// Generate new assets
|
// Generate new assets
|
||||||
imagesToGenerate.forEach { parsedImage in // swiftlint:disable:this closure_body_length
|
imagesToGenerate.forEach { parsedImage in
|
||||||
// Get image path
|
// Get image path
|
||||||
let imageData: (path: String, ext: String) = {
|
let imageData: (path: String, ext: String) = {
|
||||||
for subfile in allSubFiles {
|
for subfile in allSubFiles {
|
||||||
@ -87,10 +83,8 @@ class XcassetsGenerator {
|
|||||||
// Create imageset folder
|
// Create imageset folder
|
||||||
if fileManager.fileExists(atPath: imagesetPath) == false {
|
if fileManager.fileExists(atPath: imagesetPath) == false {
|
||||||
do {
|
do {
|
||||||
try fileManager.createDirectory(
|
try fileManager.createDirectory(atPath: imagesetPath,
|
||||||
atPath: imagesetPath,
|
withIntermediateDirectories: true)
|
||||||
withIntermediateDirectories: true
|
|
||||||
)
|
|
||||||
} catch {
|
} catch {
|
||||||
let error = ImagesError.createAssetFolder(imagesetPath)
|
let error = ImagesError.createAssetFolder(imagesetPath)
|
||||||
print(error.description)
|
print(error.description)
|
||||||
@ -130,7 +124,9 @@ class XcassetsGenerator {
|
|||||||
Shell.shell(command1x)
|
Shell.shell(command1x)
|
||||||
Shell.shell(command2x)
|
Shell.shell(command2x)
|
||||||
Shell.shell(command3x)
|
Shell.shell(command3x)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
let output = "\(imagesetPath)/\(parsedImage.name).\(OutputImageExtension.svg.rawValue)"
|
let output = "\(imagesetPath)/\(parsedImage.name).\(OutputImageExtension.svg.rawValue)"
|
||||||
let tempURL = URL(fileURLWithPath: output)
|
let tempURL = URL(fileURLWithPath: output)
|
||||||
|
|
||||||
@ -147,33 +143,15 @@ class XcassetsGenerator {
|
|||||||
// convert path/to/image.png -resize 200x300 path/to/output.png
|
// convert path/to/image.png -resize 200x300 path/to/output.png
|
||||||
// convert path/to/image.png -resize 200x path/to/output.png
|
// convert path/to/image.png -resize 200x path/to/output.png
|
||||||
// convert path/to/image.png -resize x300 path/to/output.png
|
// convert path/to/image.png -resize x300 path/to/output.png
|
||||||
Shell.shell(
|
Shell.shell(["convert", "\(imageData.path)",
|
||||||
[
|
"-resize", "\(convertArguments.x1.width ?? "")x\(convertArguments.x1.height ?? "")",
|
||||||
"\(magickConvert)",
|
output1x])
|
||||||
"\(imageData.path)",
|
Shell.shell(["convert", "\(imageData.path)",
|
||||||
"-resize",
|
"-resize", "\(convertArguments.x2.width ?? "")x\(convertArguments.x2.height ?? "")",
|
||||||
"\(convertArguments.x1.width ?? "")x\(convertArguments.x1.height ?? "")",
|
output2x])
|
||||||
output1x
|
Shell.shell(["convert", "\(imageData.path)",
|
||||||
]
|
"-resize", "\(convertArguments.x3.width ?? "")x\(convertArguments.x3.height ?? "")",
|
||||||
)
|
output3x])
|
||||||
Shell.shell(
|
|
||||||
[
|
|
||||||
"\(magickConvert)",
|
|
||||||
"\(imageData.path)",
|
|
||||||
"-resize",
|
|
||||||
"\(convertArguments.x2.width ?? "")x\(convertArguments.x2.height ?? "")",
|
|
||||||
output2x
|
|
||||||
]
|
|
||||||
)
|
|
||||||
Shell.shell(
|
|
||||||
[
|
|
||||||
"\(magickConvert)",
|
|
||||||
"\(imageData.path)",
|
|
||||||
"-resize",
|
|
||||||
"\(convertArguments.x3.width ?? "")x\(convertArguments.x3.height ?? "")",
|
|
||||||
output3x
|
|
||||||
]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write Content.json
|
// Write Content.json
|
||||||
@ -181,11 +159,7 @@ class XcassetsGenerator {
|
|||||||
let contentJsonFilePath = "\(imagesetPath)/Contents.json"
|
let contentJsonFilePath = "\(imagesetPath)/Contents.json"
|
||||||
|
|
||||||
let contentJsonFilePathURL = URL(fileURLWithPath: contentJsonFilePath)
|
let contentJsonFilePathURL = URL(fileURLWithPath: contentJsonFilePath)
|
||||||
try! imagesetContentJson.write( // swiftlint:disable:this force_try
|
try! imagesetContentJson.write(to: contentJsonFilePathURL, atomically: false, encoding: .utf8)
|
||||||
to: contentJsonFilePathURL,
|
|
||||||
atomically: false,
|
|
||||||
encoding: .utf8
|
|
||||||
)
|
|
||||||
|
|
||||||
print("\(parsedImage.name) -> Generated")
|
print("\(parsedImage.name) -> Generated")
|
||||||
}
|
}
|
||||||
@ -203,7 +177,7 @@ class XcassetsGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
imagesetToRemove.forEach { itemToRemove in
|
imagesetToRemove.forEach { itemToRemove in
|
||||||
try! fileManager.removeItem(atPath: "\(xcassetsPath)/\(itemToRemove)") // swiftlint:disable:this force_try
|
try! fileManager.removeItem(atPath: "\(xcassetsPath)/\(itemToRemove)")
|
||||||
}
|
}
|
||||||
print("Removed \(imagesetToRemove.count) images")
|
print("Removed \(imagesetToRemove.count) images")
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
// Created by Thibaut Schmitt on 24/01/2022.
|
// Created by Thibaut Schmitt on 24/01/2022.
|
||||||
//
|
//
|
||||||
|
|
||||||
import ArgumentParser
|
|
||||||
import Foundation
|
|
||||||
import ToolCore
|
import ToolCore
|
||||||
|
import Foundation
|
||||||
|
import ArgumentParser
|
||||||
|
|
||||||
struct Images: ParsableCommand {
|
struct Images: ParsableCommand {
|
||||||
|
|
||||||
@ -48,30 +48,24 @@ struct Images: ParsableCommand {
|
|||||||
.relativePath
|
.relativePath
|
||||||
|
|
||||||
let xcassetsGenerator = XcassetsGenerator(forceGeneration: options.forceExecutionAndGeneration)
|
let xcassetsGenerator = XcassetsGenerator(forceGeneration: options.forceExecutionAndGeneration)
|
||||||
xcassetsGenerator.generateXcassets(
|
xcassetsGenerator.generateXcassets(inputPath: inputFolder,
|
||||||
inputPath: inputFolder,
|
|
||||||
imagesToGenerate: imagesToGenerate,
|
imagesToGenerate: imagesToGenerate,
|
||||||
xcassetsPath: options.xcassetsPath
|
xcassetsPath: options.xcassetsPath)
|
||||||
)
|
|
||||||
|
|
||||||
// Generate extension
|
// Generate extension
|
||||||
ImageExtensionGenerator.generateExtensionFile(
|
ImageExtensionGenerator.generateExtensionFile(images: imagesToGenerate,
|
||||||
images: imagesToGenerate,
|
|
||||||
staticVar: options.staticMembers,
|
staticVar: options.staticMembers,
|
||||||
inputFilename: options.inputFilenameWithoutExt,
|
inputFilename: options.inputFilenameWithoutExt,
|
||||||
extensionName: options.extensionName,
|
extensionName: options.extensionName,
|
||||||
extensionFilePath: options.extensionFilePath,
|
extensionFilePath: options.extensionFilePath,
|
||||||
isSwiftUI: true
|
isSwiftUI: true)
|
||||||
)
|
|
||||||
|
|
||||||
ImageExtensionGenerator.generateExtensionFile(
|
ImageExtensionGenerator.generateExtensionFile(images: imagesToGenerate,
|
||||||
images: imagesToGenerate,
|
|
||||||
staticVar: options.staticMembers,
|
staticVar: options.staticMembers,
|
||||||
inputFilename: options.inputFilenameWithoutExt,
|
inputFilename: options.inputFilenameWithoutExt,
|
||||||
extensionName: options.extensionNameUIKit,
|
extensionName: options.extensionNameUIKit,
|
||||||
extensionFilePath: options.extensionFilePathUIKit,
|
extensionFilePath: options.extensionFilePathUIKit,
|
||||||
isSwiftUI: false
|
isSwiftUI: false)
|
||||||
)
|
|
||||||
|
|
||||||
print("[\(Self.toolName)] Images generated")
|
print("[\(Self.toolName)] Images generated")
|
||||||
}
|
}
|
||||||
@ -89,25 +83,23 @@ struct Images: ParsableCommand {
|
|||||||
guard fileManager.fileExists(atPath: options.inputFile) else {
|
guard fileManager.fileExists(atPath: options.inputFile) else {
|
||||||
let error = ImagesError.fileNotExists(options.inputFile)
|
let error = ImagesError.fileNotExists(options.inputFile)
|
||||||
print(error.description)
|
print(error.description)
|
||||||
Self.exit(withError: error)
|
Images.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RSVG-Converter
|
// RSVG-Converter
|
||||||
_ = Self.getSvgConverterPath()
|
_ = Images.getSvgConverterPath()
|
||||||
|
|
||||||
// Extension for UIKit and SwiftUI should have different name
|
// Extension for UIKit and SwiftUI should have different name
|
||||||
guard options.extensionName != options.extensionNameUIKit else {
|
guard options.extensionName != options.extensionNameUIKit else {
|
||||||
let error = ImagesError.extensionNamesCollision(options.extensionName)
|
let error = ImagesError.extensionNamesCollision(options.extensionName)
|
||||||
print(error.description)
|
print(error.description)
|
||||||
Self.exit(withError: error)
|
Images.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if needed to regenerate
|
// Check if needed to regenerate
|
||||||
guard GeneratorChecker.shouldGenerate(
|
guard GeneratorChecker.shouldGenerate(force: options.forceExecution,
|
||||||
force: options.forceExecution,
|
|
||||||
inputFilePath: options.inputFile,
|
inputFilePath: options.inputFile,
|
||||||
extensionFilePath: options.extensionFilePath
|
extensionFilePath: options.extensionFilePath) else {
|
||||||
) else {
|
|
||||||
print("[\(Self.toolName)] Images are already up to date :) ")
|
print("[\(Self.toolName)] Images are already up to date :) ")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -121,29 +113,11 @@ struct Images: ParsableCommand {
|
|||||||
static func getSvgConverterPath() -> String {
|
static func getSvgConverterPath() -> String {
|
||||||
let taskSvgConverter = Shell.shell(["which", "rsvg-convert"])
|
let taskSvgConverter = Shell.shell(["which", "rsvg-convert"])
|
||||||
if taskSvgConverter.terminationStatus == 0 {
|
if taskSvgConverter.terminationStatus == 0 {
|
||||||
return taskSvgConverter.output!.removeCharacters(from: CharacterSet.whitespacesAndNewlines) // swiftlint:disable:this force_unwrapping
|
return taskSvgConverter.output!.removeCharacters(from: CharacterSet.whitespacesAndNewlines)
|
||||||
}
|
}
|
||||||
|
|
||||||
let error = ImagesError.rsvgConvertNotFound
|
let error = ImagesError.rsvgConvertNotFound
|
||||||
print(error.description)
|
print(error.description)
|
||||||
Self.exit(withError: error)
|
Images.exit(withError: error)
|
||||||
}
|
|
||||||
|
|
||||||
@discardableResult
|
|
||||||
static func getMagickConvertPath() -> String {
|
|
||||||
// WARNING: The convert command is deprecated in IMv7, use "magick" instead of "convert"
|
|
||||||
let taskMagick = Shell.shell(["which", "magick"])
|
|
||||||
if taskMagick.terminationStatus == 0 {
|
|
||||||
return taskMagick.output!.removeCharacters(from: CharacterSet.whitespacesAndNewlines) // swiftlint:disable:this force_unwrapping
|
|
||||||
}
|
|
||||||
|
|
||||||
let taskConvert = Shell.shell(["which", "convert"])
|
|
||||||
if taskConvert.terminationStatus == 0 {
|
|
||||||
return taskMagick.output!.removeCharacters(from: CharacterSet.whitespacesAndNewlines) // swiftlint:disable:this force_unwrapping
|
|
||||||
}
|
|
||||||
|
|
||||||
let error = ImagesError.magickConvertNotFound
|
|
||||||
print(error.description)
|
|
||||||
Self.exit(withError: error)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,14 +8,12 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum ImagesError: Error {
|
enum ImagesError: Error {
|
||||||
|
|
||||||
case extensionNamesCollision(String)
|
case extensionNamesCollision(String)
|
||||||
case inputFolderNotFound(String)
|
case inputFolderNotFound(String)
|
||||||
case fileNotExists(String)
|
case fileNotExists(String)
|
||||||
case unknownImageExtension(String)
|
case unknownImageExtension(String)
|
||||||
case getFileAttributed(String, String)
|
case getFileAttributed(String, String)
|
||||||
case rsvgConvertNotFound
|
case rsvgConvertNotFound
|
||||||
case magickConvertNotFound
|
|
||||||
case writeFile(String, String)
|
case writeFile(String, String)
|
||||||
case createAssetFolder(String)
|
case createAssetFolder(String)
|
||||||
case unknown(String)
|
case unknown(String)
|
||||||
@ -34,16 +32,13 @@ enum ImagesError: Error {
|
|||||||
case .unknownImageExtension(let filename):
|
case .unknownImageExtension(let filename):
|
||||||
return "error: [\(Images.toolName)] File \(filename) have an unhandled file extension. Cannot generate image."
|
return "error: [\(Images.toolName)] File \(filename) have an unhandled file extension. Cannot generate image."
|
||||||
|
|
||||||
case let .getFileAttributed(filename, errorDescription):
|
case .getFileAttributed(let filename, let errorDescription):
|
||||||
return "error: [\(Images.toolName)] Getting file attributes of \(filename) failed with error: \(errorDescription)"
|
return "error: [\(Images.toolName)] Getting file attributes of \(filename) failed with error: \(errorDescription)"
|
||||||
|
|
||||||
case .rsvgConvertNotFound:
|
case .rsvgConvertNotFound:
|
||||||
return "error: [\(Images.toolName)] Can't find rsvg-convert (can be installed with 'brew remove imagemagick && brew install librsvg')"
|
return "error: [\(Images.toolName)] Can't find rsvg-convert (can be installed with 'brew remove imagemagick && brew install imagemagick --with-librsvg')"
|
||||||
|
|
||||||
case .magickConvertNotFound:
|
case .writeFile(let subErrorDescription, let filename):
|
||||||
return "error: [\(Images.toolName)] Can't find magick or convert (can be installed with 'brew install imagemagick')"
|
|
||||||
|
|
||||||
case let .writeFile(subErrorDescription, filename):
|
|
||||||
return "error: [\(Images.toolName)] An error occured while writing content to \(filename): \(subErrorDescription)"
|
return "error: [\(Images.toolName)] An error occured while writing content to \(filename): \(subErrorDescription)"
|
||||||
|
|
||||||
case .createAssetFolder(let folder):
|
case .createAssetFolder(let folder):
|
||||||
|
@ -5,13 +5,10 @@
|
|||||||
// Created by Thibaut Schmitt on 24/01/2022.
|
// Created by Thibaut Schmitt on 24/01/2022.
|
||||||
//
|
//
|
||||||
|
|
||||||
import ArgumentParser
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import ArgumentParser
|
||||||
// swiftlint:disable no_grouping_extension
|
|
||||||
|
|
||||||
struct ImagesOptions: ParsableArguments {
|
struct ImagesOptions: ParsableArguments {
|
||||||
|
|
||||||
@Flag(name: .customShort("f"), help: "Should force script execution")
|
@Flag(name: .customShort("f"), help: "Should force script execution")
|
||||||
var forceExecution = false
|
var forceExecution = false
|
||||||
|
|
||||||
@ -47,7 +44,7 @@ extension ImagesOptions {
|
|||||||
// MARK: - SwiftUI
|
// MARK: - SwiftUI
|
||||||
|
|
||||||
var extensionFileName: String {
|
var extensionFileName: String {
|
||||||
if let extensionSuffix {
|
if let extensionSuffix = extensionSuffix {
|
||||||
return "\(extensionName)+\(extensionSuffix).swift"
|
return "\(extensionName)+\(extensionSuffix).swift"
|
||||||
}
|
}
|
||||||
return "\(extensionName).swift"
|
return "\(extensionName).swift"
|
||||||
@ -60,7 +57,7 @@ extension ImagesOptions {
|
|||||||
// MARK: - UIKit
|
// MARK: - UIKit
|
||||||
|
|
||||||
var extensionFileNameUIKit: String {
|
var extensionFileNameUIKit: String {
|
||||||
if let extensionSuffix {
|
if let extensionSuffix = extensionSuffix {
|
||||||
return "\(extensionNameUIKit)+\(extensionSuffix).swift"
|
return "\(extensionNameUIKit)+\(extensionSuffix).swift"
|
||||||
}
|
}
|
||||||
return "\(extensionNameUIKit).swift"
|
return "\(extensionNameUIKit).swift"
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
struct ConvertArgument {
|
struct ConvertArgument {
|
||||||
|
|
||||||
let width: String?
|
let width: String?
|
||||||
let height: String?
|
let height: String?
|
||||||
}
|
}
|
||||||
|
@ -8,13 +8,11 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum TemplateRenderingIntent: String, Codable {
|
enum TemplateRenderingIntent: String, Codable {
|
||||||
|
|
||||||
case template
|
case template
|
||||||
case original
|
case original
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AssetContent: Codable, Equatable {
|
struct AssetContent: Codable, Equatable {
|
||||||
|
|
||||||
let images: [AssetImageDescription]
|
let images: [AssetImageDescription]
|
||||||
let info: AssetInfo
|
let info: AssetInfo
|
||||||
let properties: AssetProperties?
|
let properties: AssetProperties?
|
||||||
@ -29,17 +27,16 @@ struct AssetContent: Codable, Equatable {
|
|||||||
self.properties = properties
|
self.properties = properties
|
||||||
}
|
}
|
||||||
|
|
||||||
static func == (lhs: Self, rhs: Self) -> Bool {
|
static func == (lhs: AssetContent, rhs: AssetContent) -> Bool {
|
||||||
guard lhs.images.count == rhs.images.count else { return false }
|
guard lhs.images.count == rhs.images.count else { return false }
|
||||||
let lhsImages = lhs.images.sorted { $0.filename < $1.filename }
|
let lhsImages = lhs.images.sorted(by: { $0.filename < $1.filename })
|
||||||
let rhsImages = rhs.images.sorted { $0.filename < $1.filename }
|
let rhsImages = rhs.images.sorted(by: { $0.filename < $1.filename })
|
||||||
|
|
||||||
return lhsImages == rhsImages
|
return lhsImages == rhsImages
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AssetImageDescription: Codable, Equatable {
|
struct AssetImageDescription: Codable, Equatable {
|
||||||
|
|
||||||
let idiom: String
|
let idiom: String
|
||||||
let scale: String?
|
let scale: String?
|
||||||
let filename: String
|
let filename: String
|
||||||
@ -56,13 +53,11 @@ struct AssetImageDescription: Codable, Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct AssetInfo: Codable, Equatable {
|
struct AssetInfo: Codable, Equatable {
|
||||||
|
|
||||||
let version: Int
|
let version: Int
|
||||||
let author: String
|
let author: String
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AssetProperties: Codable, Equatable {
|
struct AssetProperties: Codable, Equatable {
|
||||||
|
|
||||||
let preservesVectorRepresentation: Bool
|
let preservesVectorRepresentation: Bool
|
||||||
let templateRenderingIntent: TemplateRenderingIntent?
|
let templateRenderingIntent: TemplateRenderingIntent?
|
||||||
|
|
||||||
@ -75,7 +70,6 @@ struct AssetProperties: Codable, Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
|
|
||||||
case preservesVectorRepresentation = "preserves-vector-representation"
|
case preservesVectorRepresentation = "preserves-vector-representation"
|
||||||
case templateRenderingIntent = "template-rendering-intent"
|
case templateRenderingIntent = "template-rendering-intent"
|
||||||
}
|
}
|
||||||
|
@ -8,14 +8,10 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum ImageExtension: String {
|
enum ImageExtension: String {
|
||||||
|
|
||||||
case png
|
case png
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ParsedImage {
|
struct ParsedImage {
|
||||||
|
|
||||||
// MARK: - Properties
|
|
||||||
|
|
||||||
let name: String
|
let name: String
|
||||||
let tags: String
|
let tags: String
|
||||||
let width: Int
|
let width: Int
|
||||||
@ -38,7 +34,7 @@ struct ParsedImage {
|
|||||||
|
|
||||||
// MARK: - Convert
|
// MARK: - Convert
|
||||||
|
|
||||||
var convertArguments: (x1: ConvertArgument, x2: ConvertArgument, x3: ConvertArgument) { // swiftlint:disable:this large_tuple
|
var convertArguments: (x1: ConvertArgument, x2: ConvertArgument, x3: ConvertArgument) {
|
||||||
var width1x = ""
|
var width1x = ""
|
||||||
var height1x = ""
|
var height1x = ""
|
||||||
var width2x = ""
|
var width2x = ""
|
||||||
@ -67,7 +63,7 @@ struct ParsedImage {
|
|||||||
|
|
||||||
func generateContentJson(isVector: Bool) -> String? {
|
func generateContentJson(isVector: Bool) -> String? {
|
||||||
let encoder = JSONEncoder()
|
let encoder = JSONEncoder()
|
||||||
encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
|
encoder.outputFormatting = .prettyPrinted
|
||||||
|
|
||||||
let imageContent = generateImageContent(isVector: isVector)
|
let imageContent = generateImageContent(isVector: isVector)
|
||||||
|
|
||||||
@ -77,12 +73,13 @@ struct ParsedImage {
|
|||||||
Images.exit(withError: error)
|
Images.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
return String(decoding: data, as: UTF8.self)
|
return String(data: data, encoding: .utf8)
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateImageContent(isVector: Bool) -> AssetContent {
|
func generateImageContent(isVector: Bool) -> AssetContent {
|
||||||
|
|
||||||
if !imageExtensions.contains(.png) && isVector {
|
if !imageExtensions.contains(.png) && isVector {
|
||||||
// Generate svg
|
//Generate svg
|
||||||
return AssetContent(
|
return AssetContent(
|
||||||
images: [
|
images: [
|
||||||
AssetImageDescription(
|
AssetImageDescription(
|
||||||
@ -100,7 +97,7 @@ struct ParsedImage {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
// Generate png
|
//Generate png
|
||||||
return AssetContent(
|
return AssetContent(
|
||||||
images: [
|
images: [
|
||||||
AssetImageDescription(
|
AssetImageDescription(
|
||||||
@ -132,13 +129,13 @@ struct ParsedImage {
|
|||||||
func getImageProperty(isStatic: Bool, isSwiftUI: Bool) -> String {
|
func getImageProperty(isStatic: Bool, isSwiftUI: Bool) -> String {
|
||||||
if isSwiftUI {
|
if isSwiftUI {
|
||||||
return """
|
return """
|
||||||
\(isStatic ? "static " : "")var \(name): Image {
|
\(isStatic ? "static ": "")var \(name): Image {
|
||||||
Image("\(name)")
|
Image("\(name)")
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
return """
|
return """
|
||||||
\(isStatic ? "static " : "")var \(name): UIImage {
|
\(isStatic ? "static ": "")var \(name): UIImage {
|
||||||
UIImage(named: "\(name)")!
|
UIImage(named: "\(name)")!
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|