diff --git a/.gitignore b/.gitignore
index efb0e2f..f129058 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,144 +1,9 @@
-
-# ---> Objective-C
-=======
-
-# Created by https://www.gitignore.io/api/xcode,swift,macos,cocoapods
-# Edit at https://www.gitignore.io/?templates=xcode,swift,macos,cocoapods
-
-### CocoaPods ###
-## CocoaPods GitIgnore Template
-
-# CocoaPods - Only use to conserve bandwidth / Save time on Pushing
-# - Also handy if you have a large number of dependant pods
-# - AS PER https://guides.cocoapods.org/using/using-cocoapods.html NEVER IGNORE THE LOCK FILE
-Pods/
-Podfile.lock
-
-### macOS ###
-# General
.DS_Store
-.AppleDouble
-.LSOverride
-
-# Icon must end with two \r
-Icon
-
-# Thumbnails
-._*
-
-# Files that might appear in the root of a volume
-.DocumentRevisions-V100
-.fseventsd
-.Spotlight-V100
-.TemporaryItems
-.Trashes
-.VolumeIcon.icns
-.com.apple.timemachine.donotpresent
-
-# Directories potentially created on remote AFP share
-.AppleDB
-.AppleDesktop
-Network Trash Folder
-Temporary Items
-.apdisk
-
-### Swift ###
->>>>>>> 6473ef460d0d87bb717651119157caf8ecbdf4a9
-# Xcode
-#
-# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
-
-## Build generated
-build/
-DerivedData/
-
-## Various settings
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
+/.build
+/Packages
xcuserdata/
-
-## Other
-*.moved-aside
-*.xccheckout
-*.xcscmblueprint
-*.xcuserstate
-
-## Obj-C/Swift specific
-*.hmap
-*.ipa
-*.dSYM.zip
-*.dSYM
-
-## Playgrounds
-timeline.xctimeline
-playground.xcworkspace
-
-# Swift Package Manager
-# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
-# Packages/
-# Package.pins
-# Package.resolved
-.build/
-
-# CocoaPods
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
-# Pods/
-# Add this line if you want to avoid checking in source code from the Xcode workspace
-# *.xcworkspace
-
-# Carthage
-# Add this line if you want to avoid checking in source code from Carthage dependencies.
-# Carthage/Checkouts
-
-Carthage/Build
-
-# Accio dependency management
-Dependencies/
-.accio/
-
-# fastlane
-# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
-# screenshots whenever they are needed.
-# For more information about the recommended setup visit:
-# https://docs.fastlane.tools/best-practices/source-control/#source-control
-
-fastlane/report.xml
-fastlane/Preview.html
-fastlane/screenshots/**/*.png
-fastlane/test_output
-
-# Code Injection
-# After new code Injection tools there's a generated folder /iOSInjectionProject
-# https://github.com/johnno1962/injectionforxcode
-
-iOSInjectionProject/
-
-### Xcode ###
-# Xcode
-# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
-
-## User settings
-
-## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
-
-## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
-
-## Xcode Patch
-*.xcodeproj/*
-!*.xcodeproj/project.pbxproj
-!*.xcodeproj/xcshareddata/
-!*.xcworkspace/contents.xcworkspacedata
-/*.gcno
-
-### Xcode Patch ###
-**/xcshareddata/WorkspaceSettings.xcsettings
-
-# End of https://www.gitignore.io/api/xcode,swift,macos,cocoapods
\ No newline at end of file
+DerivedData/
+.swiftpm/configuration/registries.json
+.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
+.netrc
+Package.resolved
\ No newline at end of file
diff --git a/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/SFSymbolsGenerator.xcodeproj/xcshareddata/xcschemes/SFSymbolsGenerator.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/SFSymbolsGenerator.xcscheme
similarity index 83%
rename from SFSymbolsGenerator.xcodeproj/xcshareddata/xcschemes/SFSymbolsGenerator.xcscheme
rename to .swiftpm/xcode/xcshareddata/xcschemes/SFSymbolsGenerator.xcscheme
index c1af476..9c9973d 100644
--- a/SFSymbolsGenerator.xcodeproj/xcshareddata/xcschemes/SFSymbolsGenerator.xcscheme
+++ b/.swiftpm/xcode/xcshareddata/xcschemes/SFSymbolsGenerator.xcscheme
@@ -14,10 +14,10 @@
buildForAnalyzing = "YES">
+ ReferencedContainer = "container:">
@@ -38,16 +38,15 @@
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
- allowLocationSimulation = "YES"
- viewDebuggingEnabled = "No">
+ allowLocationSimulation = "YES">
+ ReferencedContainer = "container:">
@@ -61,10 +60,10 @@
runnableDebuggingMode = "0">
+ ReferencedContainer = "container:">
diff --git a/Assets/Command Usage.png b/Assets/Command Usage.png
new file mode 100644
index 0000000..7e936e7
Binary files /dev/null and b/Assets/Command Usage.png differ
diff --git a/Package.swift b/Package.swift
new file mode 100644
index 0000000..2ef0e7a
--- /dev/null
+++ b/Package.swift
@@ -0,0 +1,22 @@
+// swift-tools-version: 5.9
+// The swift-tools-version declares the minimum version of Swift required to build this package.
+
+import PackageDescription
+
+let package = Package(
+ name: "SFSymbolsGenerator",
+ platforms: [.macOS(.v13)],
+ dependencies: [
+ .package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.2.0"),
+ ],
+ targets: [
+ // Targets are the basic building blocks of a package, defining a module or a test suite.
+ // Targets can depend on other targets in this package and products from dependencies.
+ .executableTarget(
+ name: "SFSymbolsGenerator",
+ dependencies: [
+ .product(name: "ArgumentParser", package: "swift-argument-parser"),
+ ]
+ ),
+ ]
+)
diff --git a/README.md b/README.md
index dae639a..40c70f3 100644
--- a/README.md
+++ b/README.md
@@ -12,29 +12,41 @@ Simplifying SF Symbols Enumeration Generation with Swift!
## How to Use
-### git clone
-
-1. Clone this Project
-2. Use Xcode to open it
-3. Command + R
-4. Find outputPath in Output area, and Happy use it!
-
-### Terminal
+![Command Usage](./Assets/Command Usage.png)
1. Download binary file from Latest Releases
2. Open Terminal.app (notes: check current path exists SFSymbolsGenerator binary file!)
-3. run ```./SFSymbolsGenerator```, and find outputPath in Terminal, and Happy use it!
+3. run ```./SFSymbolsGenerator ```, and Happy use it!
+
+#### Argument
+
+| Argument | Description | Required or Optional |
+|------------|-----------------------------| :------------------: |
+| filepath | Specify filepath of output. | **Required** |
-#### Arguments
+#### Flag
-| Argument | Description |
-|------------|---------------------|
-| --use-beta | Use SF Symbols beta |
+| Argument | Description | Required or Optional |
+|------------|-----------------------------| :------------------: |
+| --name | Specify filename of output. | **Optional** |
+
+#### Flag
+
+| Argument | Description | Required or Optional |
+|------------|---------------------| :------------------: |
+| --use-beta | Use SF Symbols beta | **Optional** |
##### Example
```shell
-./SFSymbolsGenerator --use-beta
+# Normal Usage
+./SFSymbolsGenerator /Users/leoho/Desktop
+
+# Specify filename Usage
+./SFSymbolsGenerator /Users/leoho/Desktop --name SFSymbols
+
+# beta version Usage
+./SFSymbolsGenerator /Users/leoho/Desktop --use-beta
```
## Thanks
diff --git a/SFSymbolsGenerator.xcodeproj/project.pbxproj b/SFSymbolsGenerator.xcodeproj/project.pbxproj
deleted file mode 100644
index 56bce16..0000000
--- a/SFSymbolsGenerator.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,348 +0,0 @@
-// !$*UTF8*$!
-{
- archiveVersion = 1;
- classes = {
- };
- objectVersion = 56;
- objects = {
-
-/* Begin PBXBuildFile section */
- D01233C42AC9D89900E5892E /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01233C32AC9D89900E5892E /* main.swift */; };
- D01233CD2AC9D8F800E5892E /* Typealias.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01233CC2AC9D8F800E5892E /* Typealias.swift */; };
- D01233CF2AC9D91700E5892E /* Release+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01233CE2AC9D91700E5892E /* Release+Extensions.swift */; };
- D01233D12AC9D92400E5892E /* Symbol+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01233D02AC9D92400E5892E /* Symbol+Extensions.swift */; };
- D01233D42AC9DBA100E5892E /* OutputStreamCapture.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01233D32AC9DBA100E5892E /* OutputStreamCapture.swift */; };
- D01233D72AC9E0C200E5892E /* FileWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01233D62AC9E0C200E5892E /* FileWriter.swift */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXCopyFilesBuildPhase section */
- D01233BE2AC9D89900E5892E /* CopyFiles */ = {
- isa = PBXCopyFilesBuildPhase;
- buildActionMask = 2147483647;
- dstPath = /usr/share/man/man1/;
- dstSubfolderSpec = 0;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 1;
- };
-/* End PBXCopyFilesBuildPhase section */
-
-/* Begin PBXFileReference section */
- D01233C02AC9D89900E5892E /* SFSymbolsGenerator */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = SFSymbolsGenerator; sourceTree = BUILT_PRODUCTS_DIR; };
- D01233C32AC9D89900E5892E /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; };
- D01233CC2AC9D8F800E5892E /* Typealias.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Typealias.swift; sourceTree = ""; };
- D01233CE2AC9D91700E5892E /* Release+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Release+Extensions.swift"; sourceTree = ""; };
- D01233D02AC9D92400E5892E /* Symbol+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Symbol+Extensions.swift"; sourceTree = ""; };
- D01233D32AC9DBA100E5892E /* OutputStreamCapture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OutputStreamCapture.swift; sourceTree = ""; };
- D01233D62AC9E0C200E5892E /* FileWriter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileWriter.swift; sourceTree = ""; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
- D01233BD2AC9D89900E5892E /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
- D01233B72AC9D89900E5892E = {
- isa = PBXGroup;
- children = (
- D01233C22AC9D89900E5892E /* SFSymbolsGenerator */,
- D01233C12AC9D89900E5892E /* Products */,
- );
- sourceTree = "";
- };
- D01233C12AC9D89900E5892E /* Products */ = {
- isa = PBXGroup;
- children = (
- D01233C02AC9D89900E5892E /* SFSymbolsGenerator */,
- );
- name = Products;
- sourceTree = "";
- };
- D01233C22AC9D89900E5892E /* SFSymbolsGenerator */ = {
- isa = PBXGroup;
- children = (
- D01233D52AC9E0AF00E5892E /* WriteFile */,
- D01233D22AC9DB8800E5892E /* TextOutputStream */,
- D01233CB2AC9D8C700E5892E /* Typealias */,
- D01233CA2AC9D8AC00E5892E /* Extensions */,
- D01233C32AC9D89900E5892E /* main.swift */,
- );
- path = SFSymbolsGenerator;
- sourceTree = "";
- };
- D01233CA2AC9D8AC00E5892E /* Extensions */ = {
- isa = PBXGroup;
- children = (
- D01233CE2AC9D91700E5892E /* Release+Extensions.swift */,
- D01233D02AC9D92400E5892E /* Symbol+Extensions.swift */,
- );
- path = Extensions;
- sourceTree = "";
- };
- D01233CB2AC9D8C700E5892E /* Typealias */ = {
- isa = PBXGroup;
- children = (
- D01233CC2AC9D8F800E5892E /* Typealias.swift */,
- );
- path = Typealias;
- sourceTree = "";
- };
- D01233D22AC9DB8800E5892E /* TextOutputStream */ = {
- isa = PBXGroup;
- children = (
- D01233D32AC9DBA100E5892E /* OutputStreamCapture.swift */,
- );
- path = TextOutputStream;
- sourceTree = "";
- };
- D01233D52AC9E0AF00E5892E /* WriteFile */ = {
- isa = PBXGroup;
- children = (
- D01233D62AC9E0C200E5892E /* FileWriter.swift */,
- );
- path = WriteFile;
- sourceTree = "";
- };
-/* End PBXGroup section */
-
-/* Begin PBXNativeTarget section */
- D01233BF2AC9D89900E5892E /* SFSymbolsGenerator */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = D01233C72AC9D89900E5892E /* Build configuration list for PBXNativeTarget "SFSymbolsGenerator" */;
- buildPhases = (
- D01233BC2AC9D89900E5892E /* Sources */,
- D01233BD2AC9D89900E5892E /* Frameworks */,
- D01233BE2AC9D89900E5892E /* CopyFiles */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = SFSymbolsGenerator;
- productName = SFSymbolsGenerator;
- productReference = D01233C02AC9D89900E5892E /* SFSymbolsGenerator */;
- productType = "com.apple.product-type.tool";
- };
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
- D01233B82AC9D89900E5892E /* Project object */ = {
- isa = PBXProject;
- attributes = {
- BuildIndependentTargetsInParallel = 1;
- LastSwiftUpdateCheck = 1500;
- LastUpgradeCheck = 1500;
- TargetAttributes = {
- D01233BF2AC9D89900E5892E = {
- CreatedOnToolsVersion = 15.0;
- };
- };
- };
- buildConfigurationList = D01233BB2AC9D89900E5892E /* Build configuration list for PBXProject "SFSymbolsGenerator" */;
- compatibilityVersion = "Xcode 14.0";
- developmentRegion = en;
- hasScannedForEncodings = 0;
- knownRegions = (
- en,
- Base,
- );
- mainGroup = D01233B72AC9D89900E5892E;
- productRefGroup = D01233C12AC9D89900E5892E /* Products */;
- projectDirPath = "";
- projectRoot = "";
- targets = (
- D01233BF2AC9D89900E5892E /* SFSymbolsGenerator */,
- );
- };
-/* End PBXProject section */
-
-/* Begin PBXSourcesBuildPhase section */
- D01233BC2AC9D89900E5892E /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- D01233CF2AC9D91700E5892E /* Release+Extensions.swift in Sources */,
- D01233D72AC9E0C200E5892E /* FileWriter.swift in Sources */,
- D01233CD2AC9D8F800E5892E /* Typealias.swift in Sources */,
- D01233D42AC9DBA100E5892E /* OutputStreamCapture.swift in Sources */,
- D01233C42AC9D89900E5892E /* main.swift in Sources */,
- D01233D12AC9D92400E5892E /* Symbol+Extensions.swift in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
- D01233C52AC9D89900E5892E /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_ENABLE_OBJC_WEAK = YES;
- CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_COMMA = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INFINITE_RECURSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
- CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
- CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
- CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
- CLANG_WARN_STRICT_PROTOTYPES = YES;
- CLANG_WARN_SUSPICIOUS_MOVE = YES;
- CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = dwarf;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- ENABLE_TESTABILITY = YES;
- ENABLE_USER_SCRIPT_SANDBOXING = YES;
- GCC_C_LANGUAGE_STANDARD = gnu17;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PREPROCESSOR_DEFINITIONS = (
- "DEBUG=1",
- "$(inherited)",
- );
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
- MACOSX_DEPLOYMENT_TARGET = 14.0;
- MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
- MTL_FAST_MATH = YES;
- ONLY_ACTIVE_ARCH = YES;
- SDKROOT = macosx;
- SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
- SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- };
- name = Debug;
- };
- D01233C62AC9D89900E5892E /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_ENABLE_OBJC_WEAK = YES;
- CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_COMMA = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INFINITE_RECURSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
- CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
- CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
- CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
- CLANG_WARN_STRICT_PROTOTYPES = YES;
- CLANG_WARN_SUSPICIOUS_MOVE = YES;
- CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- ENABLE_NS_ASSERTIONS = NO;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- ENABLE_USER_SCRIPT_SANDBOXING = YES;
- GCC_C_LANGUAGE_STANDARD = gnu17;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
- MACOSX_DEPLOYMENT_TARGET = 14.0;
- MTL_ENABLE_DEBUG_INFO = NO;
- MTL_FAST_MATH = YES;
- SDKROOT = macosx;
- SWIFT_COMPILATION_MODE = wholemodule;
- };
- name = Release;
- };
- D01233C82AC9D89900E5892E /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CODE_SIGN_STYLE = Automatic;
- DEVELOPMENT_TEAM = 23JEQ2524P;
- ENABLE_HARDENED_RUNTIME = YES;
- MACOSX_DEPLOYMENT_TARGET = 13.0;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 5.0;
- };
- name = Debug;
- };
- D01233C92AC9D89900E5892E /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CODE_SIGN_STYLE = Automatic;
- DEVELOPMENT_TEAM = 23JEQ2524P;
- ENABLE_HARDENED_RUNTIME = YES;
- MACOSX_DEPLOYMENT_TARGET = 13.0;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 5.0;
- };
- name = Release;
- };
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
- D01233BB2AC9D89900E5892E /* Build configuration list for PBXProject "SFSymbolsGenerator" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- D01233C52AC9D89900E5892E /* Debug */,
- D01233C62AC9D89900E5892E /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- D01233C72AC9D89900E5892E /* Build configuration list for PBXNativeTarget "SFSymbolsGenerator" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- D01233C82AC9D89900E5892E /* Debug */,
- D01233C92AC9D89900E5892E /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
-/* End XCConfigurationList section */
- };
- rootObject = D01233B82AC9D89900E5892E /* Project object */;
-}
diff --git a/SFSymbolsGenerator/WriteFile/FileWriter.swift b/SFSymbolsGenerator/WriteFile/FileWriter.swift
deleted file mode 100644
index 6361536..0000000
--- a/SFSymbolsGenerator/WriteFile/FileWriter.swift
+++ /dev/null
@@ -1,43 +0,0 @@
-//
-// FileWriter.swift
-// SFSymbolsGenerator
-//
-// Created by Leo Ho on 2023/10/2.
-//
-
-import Foundation
-
-class FileWriter: NSObject {
-
- private let outputPath: String = "SFSymbols+Enum.swift"
-
- func write(with data: String) {
- do {
- let fileManager = FileManager.default
-
- let currentDirectory = fileManager.currentDirectoryPath
- print("當前目錄:", currentDirectory)
- let url = URL(fileURLWithPath: currentDirectory + "/" + outputPath)
-
- // 判斷指定路徑下,檔案是否存在,不存在就新增一個
- if !fileManager.fileExists(atPath: outputPath) {
- fileManager.createFile(atPath: outputPath, contents: nil)
- }
-
- let fileHandle = try FileHandle(forWritingTo: url)
-
- // 將字串轉換為 Data
- if let data = data.data(using: .utf8) {
- // 開始寫檔
- fileHandle.write(data)
-
- // 關閉檔案
- fileHandle.closeFile()
-
- print("寫入成功:\(outputPath)")
- }
- } catch {
- print("寫入失敗,錯誤:\(error)")
- }
- }
-}
diff --git a/SFSymbolsGenerator/main.swift b/SFSymbolsGenerator/main.swift
deleted file mode 100644
index 07527f3..0000000
--- a/SFSymbolsGenerator/main.swift
+++ /dev/null
@@ -1,129 +0,0 @@
-//
-// main.swift
-// SFSymbolsGenerator
-//
-// Created by Leo Ho on 2023/10/2.
-//
-
-import Foundation
-
-enum GenerateError: Error, CustomStringConvertible {
-
- case unknown(Error)
-
- case notInstallSFSymbols
-
- case notInstallSFSymbolsBeta
-
- case propertyList(Error)
-
- var description: String {
- switch self {
- case .unknown(let error):
- "Unknown Error: \(error.localizedDescription)"
- case .notInstallSFSymbols:
- "SF Symbols.app is not installed yet! Please go to Apple Developer Website to download!"
- case .notInstallSFSymbolsBeta:
- "SF Symbols beta.app is not installed yet! Please go to Apple Developer Website to download!"
- case .propertyList(let error):
- "PropertyList Error: \(error.localizedDescription)"
- }
- }
-}
-
-func readSymbolsAndYears(from fileURL: URL) throws -> ([SymbolTuple], Releases) {
- do {
- let data = try Data(contentsOf: fileURL, options: .mappedIfSafe)
- do {
- let propertyList = try PropertyListSerialization.propertyList(from: data,
- options: [],
- format: nil) as! Dictionary
-
- let symbols = propertyList["symbols"] as! Symbols
- let releases = propertyList["year_to_release"] as! Releases
-
- let releaseDatesFromSymbols = Set(symbols.values)
- let releaseDatesFromReleases = Set(releases.keys)
-
- assert(releaseDatesFromReleases.isSubset(of:releaseDatesFromSymbols),
- "There are symbols with releasedates that have no release versions \(releaseDatesFromReleases) < \(releaseDatesFromSymbols)")
-
- let sortedSymbolTuple = symbols
- .sorted {
- $0.value == $1.value ? $0.key < $1.key : $0.value < $1.value
- }
- .map {
- SymbolTuple(symbol: $0.key, released: $0.value)
- }
-
- return (sortedSymbolTuple, releases)
- } catch {
- throw GenerateError.propertyList(error)
- }
- } catch {
- if fileURL.path().contains("SF%20Symbols.app") {
- throw GenerateError.notInstallSFSymbols
- } else if fileURL.path().contains("SF%20Symbols%20beta.app") {
- throw GenerateError.notInstallSFSymbolsBeta
- } else {
- throw GenerateError.unknown(error)
- }
- }
-}
-
-do {
- var appURL: URL!
- for argc in CommandLine.arguments {
- switch argc {
- case "--use-beta":
- appURL = URL(fileURLWithPath: "/Applications/SF Symbols beta.app/Contents/Resources/Metadata/name_availability.plist")
- default:
- appURL = URL(fileURLWithPath: "/Applications/SF Symbols.app/Contents/Resources/Metadata/name_availability.plist")
- }
- }
-
- let (sortedSymbolTuple, releaseYears) = try readSymbolsAndYears(from: appURL)
-
- let outputStream = OutputStreamCapture()
-
- outputStream.capturePrint(
-"""
-import Foundation
-
-public enum SFSymbols: String, CaseIterable {\n
-"""
- )
-
- for symbolTuple in sortedSymbolTuple {
- outputStream.capturePrint(" " + "/// SF Symbols's name:" + symbolTuple.symbol)
- outputStream.capturePrint(" @" + releaseYears[symbolTuple.released]!.availabilty + "\n case " + symbolTuple.symbol.replacementName + " = \"" + symbolTuple.symbol + "\"\n" )
- }
- outputStream.capturePrint(
-"""
- public static var allCases: [SFSymbols] {
- var allCases: [SFSymbols] = []\n
-"""
- )
-
- for symbolTuple in sortedSymbolTuple {
- outputStream.capturePrint(" if #" + releaseYears[symbolTuple.released]!.availabilty + " {\n allCases.append(SFSymbols." + symbolTuple.symbol.replacementName + ")\n }\n")
- }
- outputStream.capturePrint(
-"""
- return allCases
- }
-}
-"""
- )
-
- let writer = FileWriter()
- writer.write(with: outputStream.capturedOutput)
-} catch (let error as GenerateError) {
- switch error {
- case .unknown(_), .propertyList(_):
- print(error.description)
- case .notInstallSFSymbols, .notInstallSFSymbolsBeta:
- print("Error:\(error.description)")
- }
- exit(0)
-}
diff --git a/Sources/Error/GenerateError.swift b/Sources/Error/GenerateError.swift
new file mode 100644
index 0000000..3fc8f59
--- /dev/null
+++ b/Sources/Error/GenerateError.swift
@@ -0,0 +1,32 @@
+//
+// GenerateError.swift
+// SFSymbolsGenerator
+//
+// Created by Leo Ho on 2023/10/27.
+//
+
+import Foundation
+
+enum GenerateError: Error, CustomStringConvertible {
+
+ case unknown(Error)
+
+ case notInstallSFSymbols
+
+ case notInstallSFSymbolsBeta
+
+ case propertyList(Error)
+
+ var description: String {
+ switch self {
+ case .unknown(let error):
+ "Unknown Error: \(error.localizedDescription)"
+ case .notInstallSFSymbols:
+ "SF Symbols.app is not installed yet! Please go to Apple Developer Website to download!"
+ case .notInstallSFSymbolsBeta:
+ "SF Symbols beta.app is not installed yet! Please go to Apple Developer Website to download!"
+ case .propertyList(let error):
+ "PropertyList Error: \(error.localizedDescription)"
+ }
+ }
+}
diff --git a/SFSymbolsGenerator/Extensions/Release+Extensions.swift b/Sources/Extensions/Release+Extensions.swift
similarity index 88%
rename from SFSymbolsGenerator/Extensions/Release+Extensions.swift
rename to Sources/Extensions/Release+Extensions.swift
index 6716578..0f4628f 100644
--- a/SFSymbolsGenerator/Extensions/Release+Extensions.swift
+++ b/Sources/Extensions/Release+Extensions.swift
@@ -2,7 +2,7 @@
// Release+Extensions.swift
// SFSymbolsGenerator
//
-// Created by Leo Ho on 2023/10/2.
+// Created by Leo Ho on 2023/10/27.
//
import Foundation
diff --git a/SFSymbolsGenerator/Extensions/Symbol+Extensions.swift b/Sources/Extensions/Symbol+Extensions.swift
similarity index 94%
rename from SFSymbolsGenerator/Extensions/Symbol+Extensions.swift
rename to Sources/Extensions/Symbol+Extensions.swift
index a04a2cc..2a10eb9 100644
--- a/SFSymbolsGenerator/Extensions/Symbol+Extensions.swift
+++ b/Sources/Extensions/Symbol+Extensions.swift
@@ -2,7 +2,7 @@
// Symbol+Extensions.swift
// SFSymbolsGenerator
//
-// Created by Leo Ho on 2023/10/2.
+// Created by Leo Ho on 2023/10/27.
//
import Foundation
diff --git a/Sources/SFSymbolsGenerator.swift b/Sources/SFSymbolsGenerator.swift
new file mode 100644
index 0000000..ff8eb80
--- /dev/null
+++ b/Sources/SFSymbolsGenerator.swift
@@ -0,0 +1,128 @@
+// The Swift Programming Language
+// https://docs.swift.org/swift-book
+//
+// Swift Argument Parser
+// https://swiftpackageindex.com/apple/swift-argument-parser/documentation
+
+import Foundation
+
+import ArgumentParser
+
+@main
+struct SFSymbolsGenerator: ParsableCommand {
+
+ static let configuration = CommandConfiguration(abstract: "Simplifying SF Symbols Enumeration Generation with Swift!",
+ version: "0.0.1")
+
+ @Argument(
+ help: "[Required] Specify filepath of output. Example: /Users//Desktop"
+ )
+ var filepath: String
+
+ @Option(
+ name: .customLong("name"),
+ help: "[Optional] Specify filename of output. Example: SFSymbols+Enum"
+ )
+ var filename: String = "SFSymbols+Enum"
+
+ @Flag(
+ name: [.customLong("use-beta")],
+ help: "Whether use beta version of SF Symbols or not."
+ )
+ var isUseBeta: Bool = false
+
+ mutating func run() throws {
+ do {
+ var appURL: URL!
+ if isUseBeta {
+ appURL = URL(fileURLWithPath: "/Applications/SF Symbols beta.app/Contents/Resources/Metadata/name_availability.plist")
+ } else {
+ appURL = URL(fileURLWithPath: "/Applications/SF Symbols.app/Contents/Resources/Metadata/name_availability.plist")
+ }
+
+ let (sortedSymbolTuple, releaseYears) = try readSymbolsAndYears(from: appURL)
+
+ let outputStream = OutputStreamCapture()
+
+ outputStream.capturePrint(
+ """
+ import Foundation
+
+ public enum SFSymbols: String, CaseIterable {\n
+ """
+ )
+
+ for symbolTuple in sortedSymbolTuple {
+ outputStream.capturePrint(" " + "/// SF Symbols's name:" + symbolTuple.symbol)
+ outputStream.capturePrint(" @" + releaseYears[symbolTuple.released]!.availabilty + "\n case " + symbolTuple.symbol.replacementName + " = \"" + symbolTuple.symbol + "\"\n" )
+ }
+ outputStream.capturePrint(
+ """
+ public static var allCases: [SFSymbols] {
+ var allCases: [SFSymbols] = []\n
+ """
+ )
+
+ for symbolTuple in sortedSymbolTuple {
+ outputStream.capturePrint(" if #" + releaseYears[symbolTuple.released]!.availabilty + " {\n allCases.append(SFSymbols." + symbolTuple.symbol.replacementName + ")\n }\n")
+ }
+ outputStream.capturePrint(
+ """
+ return allCases
+ }
+ }
+ """
+ )
+
+ let writer = FileWriter()
+ writer.write(with: outputStream.capturedOutput, and: filename, to: filepath)
+ } catch (let error as GenerateError) {
+ switch error {
+ case .unknown(_), .propertyList(_):
+ print(error.description)
+ case .notInstallSFSymbols, .notInstallSFSymbolsBeta:
+ print("Error:\(error.description)")
+ }
+ }
+ }
+
+ private func readSymbolsAndYears(from fileURL: URL) throws -> ([SymbolTuple], Releases) {
+ do {
+ let data = try Data(contentsOf: fileURL, options: .mappedIfSafe)
+ do {
+ let propertyList = try PropertyListSerialization.propertyList(from: data,
+ options: [],
+ format: nil) as! Dictionary
+
+ let symbols = propertyList["symbols"] as! Symbols
+ let releases = propertyList["year_to_release"] as! Releases
+
+ let releaseDatesFromSymbols = Set(symbols.values)
+ let releaseDatesFromReleases = Set(releases.keys)
+
+ assert(releaseDatesFromReleases.isSubset(of:releaseDatesFromSymbols),
+ "There are symbols with releasedates that have no release versions \(releaseDatesFromReleases) < \(releaseDatesFromSymbols)")
+
+ let sortedSymbolTuple = symbols
+ .sorted {
+ $0.value == $1.value ? $0.key < $1.key : $0.value < $1.value
+ }
+ .map {
+ SymbolTuple(symbol: $0.key, released: $0.value)
+ }
+
+ return (sortedSymbolTuple, releases)
+ } catch {
+ throw GenerateError.propertyList(error)
+ }
+ } catch {
+ if fileURL.path().contains("SF%20Symbols.app") {
+ throw GenerateError.notInstallSFSymbols
+ } else if fileURL.path().contains("SF%20Symbols%20beta.app") {
+ throw GenerateError.notInstallSFSymbolsBeta
+ } else {
+ throw GenerateError.unknown(error)
+ }
+ }
+ }
+}
diff --git a/SFSymbolsGenerator/TextOutputStream/OutputStreamCapture.swift b/Sources/TextOutputStream/OutputStreamCapture.swift
similarity index 84%
rename from SFSymbolsGenerator/TextOutputStream/OutputStreamCapture.swift
rename to Sources/TextOutputStream/OutputStreamCapture.swift
index 1ca5e20..eb54645 100644
--- a/SFSymbolsGenerator/TextOutputStream/OutputStreamCapture.swift
+++ b/Sources/TextOutputStream/OutputStreamCapture.swift
@@ -2,7 +2,7 @@
// OutputStreamCapture.swift
// SFSymbolsGenerator
//
-// Created by Leo Ho on 2023/10/2.
+// Created by Leo Ho on 2023/10/27.
//
import Foundation
@@ -11,7 +11,7 @@ class OutputStreamCapture {
var capturedOutput: String = ""
- func capturePrint(_ items: Any...,
+ func capturePrint(_ items: Any...,
separator: String = " ",
terminator: String = "\n") {
let output = items.map { "\($0)" }.joined(separator: separator) + terminator
diff --git a/SFSymbolsGenerator/Typealias/Typealias.swift b/Sources/Typealias/Typealias.swift
similarity index 89%
rename from SFSymbolsGenerator/Typealias/Typealias.swift
rename to Sources/Typealias/Typealias.swift
index 00c1f0d..fd25090 100644
--- a/SFSymbolsGenerator/Typealias/Typealias.swift
+++ b/Sources/Typealias/Typealias.swift
@@ -2,7 +2,7 @@
// Typealias.swift
// SFSymbolsGenerator
//
-// Created by Leo Ho on 2023/10/2.
+// Created by Leo Ho on 2023/10/27.
//
import Foundation
diff --git a/Sources/WriteFile/FileWriter.swift b/Sources/WriteFile/FileWriter.swift
new file mode 100644
index 0000000..3213694
--- /dev/null
+++ b/Sources/WriteFile/FileWriter.swift
@@ -0,0 +1,81 @@
+//
+// FileWriter.swift
+// SFSymbolsGenerator
+//
+// Created by Leo Ho on 2023/10/27.
+//
+
+import Foundation
+
+class FileWriter: NSObject {
+
+ private let fileManager = FileManager.default
+
+ /// 檔案寫入
+ /// - Parameters:
+ /// - data: 要寫入的檔案
+ /// - filename: 輸出的檔案名稱
+ /// - filepath: 輸出的檔案路徑
+ func write(with data: String, and filename: String, to filepath: String) {
+ let type = ".swift"
+ let file = filename + type
+ do {
+ let currentDirectory = fileManager.currentDirectoryPath
+ let tempPath = currentDirectory + "/" + filename + type
+ let tempURL = URL(fileURLWithPath: tempPath)
+
+ // 判斷指定路徑下,檔案是否存在,不存在就新增一個,存在就進行複寫
+ if !fileManager.fileExists(atPath: file) {
+ fileManager.createFile(atPath: file, contents: nil)
+ }
+
+ let fileHandle = try FileHandle(forWritingTo: tempURL)
+
+ // 將字串轉換為 Data
+ if let data = data.data(using: .utf8) {
+ // 開始寫檔
+ fileHandle.write(data)
+
+ // 關閉檔案
+ fileHandle.closeFile()
+
+ #if DEBUG
+ print("成功:\(file)")
+ #else
+ print("Success: \(file)")
+ #endif
+
+ let destinationPath = filepath + "/" + file // 目標要儲存的路徑
+ #if DEBUG
+ print(destinationPath)
+ #endif
+ if !fileManager.fileExists(atPath: destinationPath) {
+ // 不存在的話...
+ #if DEBUG
+ print("指定的路徑下不存在檔案")
+ #endif
+ try fileManager.moveItem(atPath: tempPath, toPath: destinationPath)
+ } else {
+ // 存在的話...
+ #if DEBUG
+ print("指定的路徑下存在檔案")
+ #endif
+ try fileManager.removeItem(atPath: destinationPath)
+ #if DEBUG
+ print("先移除舊檔案成功")
+ #endif
+ fileManager.createFile(atPath: destinationPath, contents: data)
+ #if DEBUG
+ print("再建立新檔案成功")
+ #endif
+ }
+ }
+ } catch {
+ #if DEBUG
+ print("錯誤:\(error)")
+ #else
+ print("Error: \(error)")
+ #endif
+ }
+ }
+}