Add command to generate Colors
This commit is contained in:
		
							
								
								
									
										78
									
								
								.swiftpm/xcode/xcshareddata/xcschemes/ColorToolCore.xcscheme
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								.swiftpm/xcode/xcshareddata/xcschemes/ColorToolCore.xcscheme
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<Scheme
 | 
			
		||||
   LastUpgradeVersion = "1310"
 | 
			
		||||
   version = "1.3">
 | 
			
		||||
   <BuildAction
 | 
			
		||||
      parallelizeBuildables = "YES"
 | 
			
		||||
      buildImplicitDependencies = "YES">
 | 
			
		||||
      <BuildActionEntries>
 | 
			
		||||
         <BuildActionEntry
 | 
			
		||||
            buildForTesting = "YES"
 | 
			
		||||
            buildForRunning = "YES"
 | 
			
		||||
            buildForProfiling = "YES"
 | 
			
		||||
            buildForArchiving = "YES"
 | 
			
		||||
            buildForAnalyzing = "YES">
 | 
			
		||||
            <BuildableReference
 | 
			
		||||
               BuildableIdentifier = "primary"
 | 
			
		||||
               BlueprintIdentifier = "ColorToolCore"
 | 
			
		||||
               BuildableName = "ColorToolCore"
 | 
			
		||||
               BlueprintName = "ColorToolCore"
 | 
			
		||||
               ReferencedContainer = "container:">
 | 
			
		||||
            </BuildableReference>
 | 
			
		||||
         </BuildActionEntry>
 | 
			
		||||
      </BuildActionEntries>
 | 
			
		||||
   </BuildAction>
 | 
			
		||||
   <TestAction
 | 
			
		||||
      buildConfiguration = "Debug"
 | 
			
		||||
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
 | 
			
		||||
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
 | 
			
		||||
      shouldUseLaunchSchemeArgsEnv = "YES">
 | 
			
		||||
      <Testables>
 | 
			
		||||
      </Testables>
 | 
			
		||||
   </TestAction>
 | 
			
		||||
   <LaunchAction
 | 
			
		||||
      buildConfiguration = "Debug"
 | 
			
		||||
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
 | 
			
		||||
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
 | 
			
		||||
      launchStyle = "0"
 | 
			
		||||
      useCustomWorkingDirectory = "NO"
 | 
			
		||||
      ignoresPersistentStateOnLaunch = "NO"
 | 
			
		||||
      debugDocumentVersioning = "YES"
 | 
			
		||||
      debugServiceExtension = "internal"
 | 
			
		||||
      allowLocationSimulation = "YES">
 | 
			
		||||
      <BuildableProductRunnable
 | 
			
		||||
         runnableDebuggingMode = "0">
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
            BlueprintIdentifier = "ColorToolCore"
 | 
			
		||||
            BuildableName = "ColorToolCore"
 | 
			
		||||
            BlueprintName = "ColorToolCore"
 | 
			
		||||
            ReferencedContainer = "container:">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </BuildableProductRunnable>
 | 
			
		||||
   </LaunchAction>
 | 
			
		||||
   <ProfileAction
 | 
			
		||||
      buildConfiguration = "Release"
 | 
			
		||||
      shouldUseLaunchSchemeArgsEnv = "YES"
 | 
			
		||||
      savedToolIdentifier = ""
 | 
			
		||||
      useCustomWorkingDirectory = "NO"
 | 
			
		||||
      debugDocumentVersioning = "YES">
 | 
			
		||||
      <BuildableProductRunnable
 | 
			
		||||
         runnableDebuggingMode = "0">
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
            BlueprintIdentifier = "ColorToolCore"
 | 
			
		||||
            BuildableName = "ColorToolCore"
 | 
			
		||||
            BlueprintName = "ColorToolCore"
 | 
			
		||||
            ReferencedContainer = "container:">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </BuildableProductRunnable>
 | 
			
		||||
   </ProfileAction>
 | 
			
		||||
   <AnalyzeAction
 | 
			
		||||
      buildConfiguration = "Debug">
 | 
			
		||||
   </AnalyzeAction>
 | 
			
		||||
   <ArchiveAction
 | 
			
		||||
      buildConfiguration = "Release"
 | 
			
		||||
      revealArchiveInOrganizer = "YES">
 | 
			
		||||
   </ArchiveAction>
 | 
			
		||||
</Scheme>
 | 
			
		||||
							
								
								
									
										78
									
								
								.swiftpm/xcode/xcshareddata/xcschemes/FontToolCore.xcscheme
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								.swiftpm/xcode/xcshareddata/xcschemes/FontToolCore.xcscheme
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<Scheme
 | 
			
		||||
   LastUpgradeVersion = "1310"
 | 
			
		||||
   version = "1.3">
 | 
			
		||||
   <BuildAction
 | 
			
		||||
      parallelizeBuildables = "YES"
 | 
			
		||||
      buildImplicitDependencies = "YES">
 | 
			
		||||
      <BuildActionEntries>
 | 
			
		||||
         <BuildActionEntry
 | 
			
		||||
            buildForTesting = "YES"
 | 
			
		||||
            buildForRunning = "YES"
 | 
			
		||||
            buildForProfiling = "YES"
 | 
			
		||||
            buildForArchiving = "YES"
 | 
			
		||||
            buildForAnalyzing = "YES">
 | 
			
		||||
            <BuildableReference
 | 
			
		||||
               BuildableIdentifier = "primary"
 | 
			
		||||
               BlueprintIdentifier = "FontToolCore"
 | 
			
		||||
               BuildableName = "FontToolCore"
 | 
			
		||||
               BlueprintName = "FontToolCore"
 | 
			
		||||
               ReferencedContainer = "container:">
 | 
			
		||||
            </BuildableReference>
 | 
			
		||||
         </BuildActionEntry>
 | 
			
		||||
      </BuildActionEntries>
 | 
			
		||||
   </BuildAction>
 | 
			
		||||
   <TestAction
 | 
			
		||||
      buildConfiguration = "Debug"
 | 
			
		||||
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
 | 
			
		||||
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
 | 
			
		||||
      shouldUseLaunchSchemeArgsEnv = "YES">
 | 
			
		||||
      <Testables>
 | 
			
		||||
      </Testables>
 | 
			
		||||
   </TestAction>
 | 
			
		||||
   <LaunchAction
 | 
			
		||||
      buildConfiguration = "Debug"
 | 
			
		||||
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
 | 
			
		||||
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
 | 
			
		||||
      launchStyle = "0"
 | 
			
		||||
      useCustomWorkingDirectory = "NO"
 | 
			
		||||
      ignoresPersistentStateOnLaunch = "NO"
 | 
			
		||||
      debugDocumentVersioning = "YES"
 | 
			
		||||
      debugServiceExtension = "internal"
 | 
			
		||||
      allowLocationSimulation = "YES">
 | 
			
		||||
      <BuildableProductRunnable
 | 
			
		||||
         runnableDebuggingMode = "0">
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
            BlueprintIdentifier = "FontToolCore"
 | 
			
		||||
            BuildableName = "FontToolCore"
 | 
			
		||||
            BlueprintName = "FontToolCore"
 | 
			
		||||
            ReferencedContainer = "container:">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </BuildableProductRunnable>
 | 
			
		||||
   </LaunchAction>
 | 
			
		||||
   <ProfileAction
 | 
			
		||||
      buildConfiguration = "Release"
 | 
			
		||||
      shouldUseLaunchSchemeArgsEnv = "YES"
 | 
			
		||||
      savedToolIdentifier = ""
 | 
			
		||||
      useCustomWorkingDirectory = "NO"
 | 
			
		||||
      debugDocumentVersioning = "YES">
 | 
			
		||||
      <BuildableProductRunnable
 | 
			
		||||
         runnableDebuggingMode = "0">
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
            BlueprintIdentifier = "FontToolCore"
 | 
			
		||||
            BuildableName = "FontToolCore"
 | 
			
		||||
            BlueprintName = "FontToolCore"
 | 
			
		||||
            ReferencedContainer = "container:">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </BuildableProductRunnable>
 | 
			
		||||
   </ProfileAction>
 | 
			
		||||
   <AnalyzeAction
 | 
			
		||||
      buildConfiguration = "Debug">
 | 
			
		||||
   </AnalyzeAction>
 | 
			
		||||
   <ArchiveAction
 | 
			
		||||
      buildConfiguration = "Release"
 | 
			
		||||
      revealArchiveInOrganizer = "YES">
 | 
			
		||||
   </ArchiveAction>
 | 
			
		||||
</Scheme>
 | 
			
		||||
@@ -0,0 +1,142 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<Scheme
 | 
			
		||||
   LastUpgradeVersion = "1310"
 | 
			
		||||
   version = "1.3">
 | 
			
		||||
   <BuildAction
 | 
			
		||||
      parallelizeBuildables = "YES"
 | 
			
		||||
      buildImplicitDependencies = "YES">
 | 
			
		||||
      <BuildActionEntries>
 | 
			
		||||
         <BuildActionEntry
 | 
			
		||||
            buildForTesting = "YES"
 | 
			
		||||
            buildForRunning = "YES"
 | 
			
		||||
            buildForProfiling = "YES"
 | 
			
		||||
            buildForArchiving = "YES"
 | 
			
		||||
            buildForAnalyzing = "YES">
 | 
			
		||||
            <BuildableReference
 | 
			
		||||
               BuildableIdentifier = "primary"
 | 
			
		||||
               BlueprintIdentifier = "ColorToolCore"
 | 
			
		||||
               BuildableName = "ColorToolCore"
 | 
			
		||||
               BlueprintName = "ColorToolCore"
 | 
			
		||||
               ReferencedContainer = "container:">
 | 
			
		||||
            </BuildableReference>
 | 
			
		||||
         </BuildActionEntry>
 | 
			
		||||
         <BuildActionEntry
 | 
			
		||||
            buildForTesting = "YES"
 | 
			
		||||
            buildForRunning = "YES"
 | 
			
		||||
            buildForProfiling = "YES"
 | 
			
		||||
            buildForArchiving = "YES"
 | 
			
		||||
            buildForAnalyzing = "YES">
 | 
			
		||||
            <BuildableReference
 | 
			
		||||
               BuildableIdentifier = "primary"
 | 
			
		||||
               BlueprintIdentifier = "FontToolCore"
 | 
			
		||||
               BuildableName = "FontToolCore"
 | 
			
		||||
               BlueprintName = "FontToolCore"
 | 
			
		||||
               ReferencedContainer = "container:">
 | 
			
		||||
            </BuildableReference>
 | 
			
		||||
         </BuildActionEntry>
 | 
			
		||||
         <BuildActionEntry
 | 
			
		||||
            buildForTesting = "YES"
 | 
			
		||||
            buildForRunning = "YES"
 | 
			
		||||
            buildForProfiling = "YES"
 | 
			
		||||
            buildForArchiving = "YES"
 | 
			
		||||
            buildForAnalyzing = "YES">
 | 
			
		||||
            <BuildableReference
 | 
			
		||||
               BuildableIdentifier = "primary"
 | 
			
		||||
               BlueprintIdentifier = "ResgenSwift"
 | 
			
		||||
               BuildableName = "ResgenSwift"
 | 
			
		||||
               BlueprintName = "ResgenSwift"
 | 
			
		||||
               ReferencedContainer = "container:">
 | 
			
		||||
            </BuildableReference>
 | 
			
		||||
         </BuildActionEntry>
 | 
			
		||||
         <BuildActionEntry
 | 
			
		||||
            buildForTesting = "YES"
 | 
			
		||||
            buildForRunning = "YES"
 | 
			
		||||
            buildForProfiling = "NO"
 | 
			
		||||
            buildForArchiving = "NO"
 | 
			
		||||
            buildForAnalyzing = "YES">
 | 
			
		||||
            <BuildableReference
 | 
			
		||||
               BuildableIdentifier = "primary"
 | 
			
		||||
               BlueprintIdentifier = "ResgenSwiftTests"
 | 
			
		||||
               BuildableName = "ResgenSwiftTests"
 | 
			
		||||
               BlueprintName = "ResgenSwiftTests"
 | 
			
		||||
               ReferencedContainer = "container:">
 | 
			
		||||
            </BuildableReference>
 | 
			
		||||
         </BuildActionEntry>
 | 
			
		||||
         <BuildActionEntry
 | 
			
		||||
            buildForTesting = "YES"
 | 
			
		||||
            buildForRunning = "YES"
 | 
			
		||||
            buildForProfiling = "YES"
 | 
			
		||||
            buildForArchiving = "YES"
 | 
			
		||||
            buildForAnalyzing = "YES">
 | 
			
		||||
            <BuildableReference
 | 
			
		||||
               BuildableIdentifier = "primary"
 | 
			
		||||
               BlueprintIdentifier = "CLIToolCore"
 | 
			
		||||
               BuildableName = "CLIToolCore"
 | 
			
		||||
               BlueprintName = "CLIToolCore"
 | 
			
		||||
               ReferencedContainer = "container:">
 | 
			
		||||
            </BuildableReference>
 | 
			
		||||
         </BuildActionEntry>
 | 
			
		||||
      </BuildActionEntries>
 | 
			
		||||
   </BuildAction>
 | 
			
		||||
   <TestAction
 | 
			
		||||
      buildConfiguration = "Debug"
 | 
			
		||||
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
 | 
			
		||||
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
 | 
			
		||||
      shouldUseLaunchSchemeArgsEnv = "YES">
 | 
			
		||||
      <Testables>
 | 
			
		||||
         <TestableReference
 | 
			
		||||
            skipped = "NO">
 | 
			
		||||
            <BuildableReference
 | 
			
		||||
               BuildableIdentifier = "primary"
 | 
			
		||||
               BlueprintIdentifier = "ResgenSwiftTests"
 | 
			
		||||
               BuildableName = "ResgenSwiftTests"
 | 
			
		||||
               BlueprintName = "ResgenSwiftTests"
 | 
			
		||||
               ReferencedContainer = "container:">
 | 
			
		||||
            </BuildableReference>
 | 
			
		||||
         </TestableReference>
 | 
			
		||||
      </Testables>
 | 
			
		||||
   </TestAction>
 | 
			
		||||
   <LaunchAction
 | 
			
		||||
      buildConfiguration = "Debug"
 | 
			
		||||
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
 | 
			
		||||
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
 | 
			
		||||
      launchStyle = "0"
 | 
			
		||||
      useCustomWorkingDirectory = "NO"
 | 
			
		||||
      ignoresPersistentStateOnLaunch = "NO"
 | 
			
		||||
      debugDocumentVersioning = "YES"
 | 
			
		||||
      debugServiceExtension = "internal"
 | 
			
		||||
      allowLocationSimulation = "YES">
 | 
			
		||||
      <MacroExpansion>
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
            BlueprintIdentifier = "ColorToolCore"
 | 
			
		||||
            BuildableName = "ColorToolCore"
 | 
			
		||||
            BlueprintName = "ColorToolCore"
 | 
			
		||||
            ReferencedContainer = "container:">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </MacroExpansion>
 | 
			
		||||
   </LaunchAction>
 | 
			
		||||
   <ProfileAction
 | 
			
		||||
      buildConfiguration = "Release"
 | 
			
		||||
      shouldUseLaunchSchemeArgsEnv = "YES"
 | 
			
		||||
      savedToolIdentifier = ""
 | 
			
		||||
      useCustomWorkingDirectory = "NO"
 | 
			
		||||
      debugDocumentVersioning = "YES">
 | 
			
		||||
      <MacroExpansion>
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
            BlueprintIdentifier = "ResgenSwift"
 | 
			
		||||
            BuildableName = "ResgenSwift"
 | 
			
		||||
            BlueprintName = "ResgenSwift"
 | 
			
		||||
            ReferencedContainer = "container:">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </MacroExpansion>
 | 
			
		||||
   </ProfileAction>
 | 
			
		||||
   <AnalyzeAction
 | 
			
		||||
      buildConfiguration = "Debug">
 | 
			
		||||
   </AnalyzeAction>
 | 
			
		||||
   <ArchiveAction
 | 
			
		||||
      buildConfiguration = "Release"
 | 
			
		||||
      revealArchiveInOrganizer = "YES">
 | 
			
		||||
   </ArchiveAction>
 | 
			
		||||
</Scheme>
 | 
			
		||||
							
								
								
									
										102
									
								
								.swiftpm/xcode/xcshareddata/xcschemes/ResgenSwift.xcscheme
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								.swiftpm/xcode/xcshareddata/xcschemes/ResgenSwift.xcscheme
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,102 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<Scheme
 | 
			
		||||
   LastUpgradeVersion = "1310"
 | 
			
		||||
   version = "1.3">
 | 
			
		||||
   <BuildAction
 | 
			
		||||
      parallelizeBuildables = "YES"
 | 
			
		||||
      buildImplicitDependencies = "YES">
 | 
			
		||||
      <BuildActionEntries>
 | 
			
		||||
         <BuildActionEntry
 | 
			
		||||
            buildForTesting = "YES"
 | 
			
		||||
            buildForRunning = "YES"
 | 
			
		||||
            buildForProfiling = "YES"
 | 
			
		||||
            buildForArchiving = "YES"
 | 
			
		||||
            buildForAnalyzing = "YES">
 | 
			
		||||
            <BuildableReference
 | 
			
		||||
               BuildableIdentifier = "primary"
 | 
			
		||||
               BlueprintIdentifier = "ResgenSwift"
 | 
			
		||||
               BuildableName = "ResgenSwift"
 | 
			
		||||
               BlueprintName = "ResgenSwift"
 | 
			
		||||
               ReferencedContainer = "container:">
 | 
			
		||||
            </BuildableReference>
 | 
			
		||||
         </BuildActionEntry>
 | 
			
		||||
         <BuildActionEntry
 | 
			
		||||
            buildForTesting = "YES"
 | 
			
		||||
            buildForRunning = "YES"
 | 
			
		||||
            buildForProfiling = "NO"
 | 
			
		||||
            buildForArchiving = "NO"
 | 
			
		||||
            buildForAnalyzing = "YES">
 | 
			
		||||
            <BuildableReference
 | 
			
		||||
               BuildableIdentifier = "primary"
 | 
			
		||||
               BlueprintIdentifier = "ResgenSwiftTests"
 | 
			
		||||
               BuildableName = "ResgenSwiftTests"
 | 
			
		||||
               BlueprintName = "ResgenSwiftTests"
 | 
			
		||||
               ReferencedContainer = "container:">
 | 
			
		||||
            </BuildableReference>
 | 
			
		||||
         </BuildActionEntry>
 | 
			
		||||
      </BuildActionEntries>
 | 
			
		||||
   </BuildAction>
 | 
			
		||||
   <TestAction
 | 
			
		||||
      buildConfiguration = "Debug"
 | 
			
		||||
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
 | 
			
		||||
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
 | 
			
		||||
      shouldUseLaunchSchemeArgsEnv = "YES">
 | 
			
		||||
      <Testables>
 | 
			
		||||
         <TestableReference
 | 
			
		||||
            skipped = "NO">
 | 
			
		||||
            <BuildableReference
 | 
			
		||||
               BuildableIdentifier = "primary"
 | 
			
		||||
               BlueprintIdentifier = "ResgenSwiftTests"
 | 
			
		||||
               BuildableName = "ResgenSwiftTests"
 | 
			
		||||
               BlueprintName = "ResgenSwiftTests"
 | 
			
		||||
               ReferencedContainer = "container:">
 | 
			
		||||
            </BuildableReference>
 | 
			
		||||
         </TestableReference>
 | 
			
		||||
      </Testables>
 | 
			
		||||
   </TestAction>
 | 
			
		||||
   <LaunchAction
 | 
			
		||||
      buildConfiguration = "Debug"
 | 
			
		||||
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
 | 
			
		||||
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
 | 
			
		||||
      launchStyle = "0"
 | 
			
		||||
      useCustomWorkingDirectory = "NO"
 | 
			
		||||
      ignoresPersistentStateOnLaunch = "NO"
 | 
			
		||||
      debugDocumentVersioning = "YES"
 | 
			
		||||
      debugServiceExtension = "internal"
 | 
			
		||||
      allowLocationSimulation = "YES">
 | 
			
		||||
      <BuildableProductRunnable
 | 
			
		||||
         runnableDebuggingMode = "0">
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
            BlueprintIdentifier = "ResgenSwift"
 | 
			
		||||
            BuildableName = "ResgenSwift"
 | 
			
		||||
            BlueprintName = "ResgenSwift"
 | 
			
		||||
            ReferencedContainer = "container:">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </BuildableProductRunnable>
 | 
			
		||||
   </LaunchAction>
 | 
			
		||||
   <ProfileAction
 | 
			
		||||
      buildConfiguration = "Release"
 | 
			
		||||
      shouldUseLaunchSchemeArgsEnv = "YES"
 | 
			
		||||
      savedToolIdentifier = ""
 | 
			
		||||
      useCustomWorkingDirectory = "NO"
 | 
			
		||||
      debugDocumentVersioning = "YES">
 | 
			
		||||
      <BuildableProductRunnable
 | 
			
		||||
         runnableDebuggingMode = "0">
 | 
			
		||||
         <BuildableReference
 | 
			
		||||
            BuildableIdentifier = "primary"
 | 
			
		||||
            BlueprintIdentifier = "ResgenSwift"
 | 
			
		||||
            BuildableName = "ResgenSwift"
 | 
			
		||||
            BlueprintName = "ResgenSwift"
 | 
			
		||||
            ReferencedContainer = "container:">
 | 
			
		||||
         </BuildableReference>
 | 
			
		||||
      </BuildableProductRunnable>
 | 
			
		||||
   </ProfileAction>
 | 
			
		||||
   <AnalyzeAction
 | 
			
		||||
      buildConfiguration = "Debug">
 | 
			
		||||
   </AnalyzeAction>
 | 
			
		||||
   <ArchiveAction
 | 
			
		||||
      buildConfiguration = "Release"
 | 
			
		||||
      revealArchiveInOrganizer = "YES">
 | 
			
		||||
   </ArchiveAction>
 | 
			
		||||
</Scheme>
 | 
			
		||||
@@ -14,13 +14,22 @@ let package = Package(
 | 
			
		||||
        // Targets can depend on other targets in this package, and on products in packages this package depends on.
 | 
			
		||||
        .target(
 | 
			
		||||
            name: "ResgenSwift",
 | 
			
		||||
            dependencies: ["FontToolCore"]),
 | 
			
		||||
            dependencies: ["FontToolCore", "ColorToolCore"]
 | 
			
		||||
        ),
 | 
			
		||||
        .target(
 | 
			
		||||
            name: "FontToolCore",
 | 
			
		||||
            dependencies: [
 | 
			
		||||
                "CLIToolCore",
 | 
			
		||||
                .product(name: "ArgumentParser", package: "swift-argument-parser")
 | 
			
		||||
            ]),
 | 
			
		||||
            ]
 | 
			
		||||
        ),
 | 
			
		||||
        .target(
 | 
			
		||||
            name: "ColorToolCore",
 | 
			
		||||
            dependencies: [
 | 
			
		||||
                "CLIToolCore",
 | 
			
		||||
                .product(name: "ArgumentParser", package: "swift-argument-parser")
 | 
			
		||||
            ]
 | 
			
		||||
        ),
 | 
			
		||||
        // Helper targets
 | 
			
		||||
        .target(name: "CLIToolCore"),
 | 
			
		||||
        // Test targets
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										21
									
								
								SampleFiles/Colors/Generated/R2Color+Font.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								SampleFiles/Colors/Generated/R2Color+Font.swift
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
// Generated from ColorToolCore at 2021-12-20 15:27:15 +0000
 | 
			
		||||
 | 
			
		||||
import UIKit
 | 
			
		||||
 | 
			
		||||
extension R2Color {
 | 
			
		||||
 | 
			
		||||
    /// 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 #0000FF (dark)"
 | 
			
		||||
    @objc var blue_light_dark: UIColor {
 | 
			
		||||
        UIColor(named: "blue_light_dark")!
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								SampleFiles/Colors/Generated/UIColor+Font.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								SampleFiles/Colors/Generated/UIColor+Font.swift
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
// Generated from ColorToolCore at 2021-12-20 15:16:18 +0000
 | 
			
		||||
 | 
			
		||||
import UIKit
 | 
			
		||||
 | 
			
		||||
extension UIColor {
 | 
			
		||||
 | 
			
		||||
    /// Color red is #FF0000 (light) or #FF0000 (dark)"
 | 
			
		||||
    static var red: UIColor {
 | 
			
		||||
        UIColor(named: "red")!
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Color green_alpha_50 is #A000FF00 (light) or #A000FF00 (dark)"
 | 
			
		||||
    static var green_alpha_50: UIColor {
 | 
			
		||||
        UIColor(named: "green_alpha_50")!
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Color blue_light_dark is #0000FF (light) or #0000AA (dark)"
 | 
			
		||||
    static var blue_light_dark: UIColor {
 | 
			
		||||
        UIColor(named: "blue_light_dark")!
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								SampleFiles/Colors/Generated/UIColor+FontSampleApp.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								SampleFiles/Colors/Generated/UIColor+FontSampleApp.swift
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
// Generated from ColorToolCore at 2021-12-20 15:17:10 +0000
 | 
			
		||||
 | 
			
		||||
import UIKit
 | 
			
		||||
 | 
			
		||||
extension UIColor {
 | 
			
		||||
 | 
			
		||||
    /// Color red is #FF0000 (light) or #FF0000 (dark)"
 | 
			
		||||
    static var red: UIColor {
 | 
			
		||||
        UIColor(named: "red")!
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Color green_alpha_50 is #A000FF00 (light) or #A000FF00 (dark)"
 | 
			
		||||
    static var green_alpha_50: UIColor {
 | 
			
		||||
        UIColor(named: "green_alpha_50")!
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Color blue_light_dark is #0000FF (light) or #0000AA (dark)"
 | 
			
		||||
    static var blue_light_dark: UIColor {
 | 
			
		||||
        UIColor(named: "blue_light_dark")!
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,38 @@
 | 
			
		||||
{
 | 
			
		||||
    "colors": [
 | 
			
		||||
        {
 | 
			
		||||
            "color": {
 | 
			
		||||
                "color-space": "srgb",
 | 
			
		||||
                "components": {
 | 
			
		||||
                    "alpha": "0xFF",
 | 
			
		||||
                    "blue": "0xFF",
 | 
			
		||||
                    "green": "0x00",
 | 
			
		||||
                    "red": "0x00",
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "idiom": "universal"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "appearances": [
 | 
			
		||||
                {
 | 
			
		||||
                    "appearance": "luminosity",
 | 
			
		||||
                    "value": "dark"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "color": {
 | 
			
		||||
                "color-space": "srgb",
 | 
			
		||||
                "components": {
 | 
			
		||||
                    "alpha": "0xFF",
 | 
			
		||||
                    "blue": "0xFF",
 | 
			
		||||
                    "green": "0x00",
 | 
			
		||||
                    "red": "0x00",
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "idiom": "universal"
 | 
			
		||||
        }
 | 
			
		||||
    ],
 | 
			
		||||
    "info": {
 | 
			
		||||
        "author": "xcode",
 | 
			
		||||
        "version": 1
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,38 @@
 | 
			
		||||
{
 | 
			
		||||
    "colors": [
 | 
			
		||||
        {
 | 
			
		||||
            "color": {
 | 
			
		||||
                "color-space": "srgb",
 | 
			
		||||
                "components": {
 | 
			
		||||
                    "alpha": "0xA0",
 | 
			
		||||
                    "blue": "0x00",
 | 
			
		||||
                    "green": "0xFF",
 | 
			
		||||
                    "red": "0x00",
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "idiom": "universal"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "appearances": [
 | 
			
		||||
                {
 | 
			
		||||
                    "appearance": "luminosity",
 | 
			
		||||
                    "value": "dark"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "color": {
 | 
			
		||||
                "color-space": "srgb",
 | 
			
		||||
                "components": {
 | 
			
		||||
                    "alpha": "0xA0",
 | 
			
		||||
                    "blue": "0x00",
 | 
			
		||||
                    "green": "0xFF",
 | 
			
		||||
                    "red": "0x00",
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "idiom": "universal"
 | 
			
		||||
        }
 | 
			
		||||
    ],
 | 
			
		||||
    "info": {
 | 
			
		||||
        "author": "xcode",
 | 
			
		||||
        "version": 1
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,38 @@
 | 
			
		||||
{
 | 
			
		||||
    "colors": [
 | 
			
		||||
        {
 | 
			
		||||
            "color": {
 | 
			
		||||
                "color-space": "srgb",
 | 
			
		||||
                "components": {
 | 
			
		||||
                    "alpha": "0xFF",
 | 
			
		||||
                    "blue": "0x00",
 | 
			
		||||
                    "green": "0x00",
 | 
			
		||||
                    "red": "0xFF",
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "idiom": "universal"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "appearances": [
 | 
			
		||||
                {
 | 
			
		||||
                    "appearance": "luminosity",
 | 
			
		||||
                    "value": "dark"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "color": {
 | 
			
		||||
                "color-space": "srgb",
 | 
			
		||||
                "components": {
 | 
			
		||||
                    "alpha": "0xFF",
 | 
			
		||||
                    "blue": "0x00",
 | 
			
		||||
                    "green": "0x00",
 | 
			
		||||
                    "red": "0xFF",
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "idiom": "universal"
 | 
			
		||||
        }
 | 
			
		||||
    ],
 | 
			
		||||
    "info": {
 | 
			
		||||
        "author": "xcode",
 | 
			
		||||
        "version": 1
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								SampleFiles/Colors/sampleColors1.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								SampleFiles/Colors/sampleColors1.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
# Available format:
 | 
			
		||||
# colorName=#RGB/#ARGB
 | 
			
		||||
# colorName #RGB/#ARGB
 | 
			
		||||
# colorName #RGB/#ARGB #RGB/#ARGB
 | 
			
		||||
 | 
			
		||||
# Comment line and empty line will be ingored
 | 
			
		||||
red = #FF0000
 | 
			
		||||
green_alpha_50 = #A000FF00
 | 
			
		||||
blue_light_dark = #0000FF #0000AA
 | 
			
		||||
@@ -29,3 +29,35 @@ public class Shell {
 | 
			
		||||
        return (terminationStatus: task.terminationStatus, output: output)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public class GeneratorChecker {
 | 
			
		||||
    
 | 
			
		||||
    /// Return `true` if  inputFile is newer than extensionFile, otherwise `false`
 | 
			
		||||
    public static func shouldGenerate(force: Bool, inputFilePath: String, extensionFilePath: String) -> Bool {
 | 
			
		||||
        guard force == false else {
 | 
			
		||||
            return true
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // If inputFile is newer that generated extension -> Regenerate
 | 
			
		||||
        let extensionFileURL = URL(fileURLWithPath: extensionFilePath)
 | 
			
		||||
        let inputFileURL = URL(fileURLWithPath: inputFilePath)
 | 
			
		||||
        
 | 
			
		||||
        let extensionRessourceValues = try? extensionFileURL.resourceValues(forKeys: [URLResourceKey.contentModificationDateKey])
 | 
			
		||||
        let inputFileRessourceValues = try? inputFileURL.resourceValues(forKeys: [URLResourceKey.contentModificationDateKey])
 | 
			
		||||
        
 | 
			
		||||
        if let extensionModificationDate = extensionRessourceValues?.contentModificationDate,
 | 
			
		||||
           let inputFileModificationDate = inputFileRessourceValues?.contentModificationDate {
 | 
			
		||||
            if inputFileModificationDate >= extensionModificationDate {
 | 
			
		||||
                print("Input file is newer that generated extension.")
 | 
			
		||||
                return true
 | 
			
		||||
            } else {
 | 
			
		||||
                return false
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        // ModificationDate not available for both file
 | 
			
		||||
        print("⚠️ Could not compare file modication date. ⚠️")
 | 
			
		||||
        return true
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										64
									
								
								Sources/CLIToolCore/Extensions.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								Sources/CLIToolCore/Extensions.swift
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
//
 | 
			
		||||
//  Extensions.swift
 | 
			
		||||
//  
 | 
			
		||||
//
 | 
			
		||||
//  Created by Thibaut Schmitt on 13/12/2021.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
import Foundation
 | 
			
		||||
 | 
			
		||||
// MARK: - String
 | 
			
		||||
 | 
			
		||||
public extension String {
 | 
			
		||||
    func removeCharacters(from forbiddenChars: CharacterSet) -> String {
 | 
			
		||||
        let passed = self.unicodeScalars.filter { !forbiddenChars.contains($0) }
 | 
			
		||||
        return String(String.UnicodeScalarView(passed))
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    func removeCharacters(from: String) -> String {
 | 
			
		||||
        return removeCharacters(from: CharacterSet(charactersIn: from))
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    func removeTrailingWhitespace() -> String {
 | 
			
		||||
        var newString = self
 | 
			
		||||
        
 | 
			
		||||
        while newString.last?.isWhitespace == true {
 | 
			
		||||
            newString = String(newString.dropLast())
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        return newString
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    func colorComponent()  -> (alpha: String, red: String, green: String, blue: String) {
 | 
			
		||||
        var alpha: String = "FF"
 | 
			
		||||
        var red: String
 | 
			
		||||
        var green: String
 | 
			
		||||
        var blue: String
 | 
			
		||||
 | 
			
		||||
        var colorClean = self
 | 
			
		||||
                .replacingOccurrences(of: "#", with: "")
 | 
			
		||||
                .replacingOccurrences(of: "0x", with: "")
 | 
			
		||||
 | 
			
		||||
        if colorClean.count == 8 {
 | 
			
		||||
            alpha = String(colorClean.prefix(2))
 | 
			
		||||
            colorClean = String(colorClean.dropFirst(2))
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        red = String(colorClean.prefix(2))
 | 
			
		||||
        colorClean = String(colorClean.dropFirst(2))
 | 
			
		||||
        green = String(colorClean.prefix(2))
 | 
			
		||||
        colorClean = String(colorClean.dropFirst(2))
 | 
			
		||||
        blue = String(colorClean.prefix(2))
 | 
			
		||||
        return (alpha: alpha, red: red, green: green, blue: blue)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MARK: - Sequence
 | 
			
		||||
 | 
			
		||||
extension Sequence where Iterator.Element: Hashable {
 | 
			
		||||
    public func unique() -> [Iterator.Element] {
 | 
			
		||||
        var seen: [Iterator.Element: Bool] = [:]
 | 
			
		||||
        return self.filter { seen.updateValue(true, forKey: $0) == nil }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										41
									
								
								Sources/ColorToolCore/ColorExtensionGenerator.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								Sources/ColorToolCore/ColorExtensionGenerator.swift
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
//
 | 
			
		||||
//  ColorExtensionGenerator.swift
 | 
			
		||||
//  
 | 
			
		||||
//
 | 
			
		||||
//  Created by Thibaut Schmitt on 20/12/2021.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
import Foundation
 | 
			
		||||
 | 
			
		||||
struct ColorExtensionGenerator {
 | 
			
		||||
    
 | 
			
		||||
    let colors: [GenColor]
 | 
			
		||||
    let extensionClassname: String
 | 
			
		||||
    let isUIColorExtension: Bool
 | 
			
		||||
    
 | 
			
		||||
    func getHeader() -> String {
 | 
			
		||||
        """
 | 
			
		||||
        // Generated from ColorToolCore at \(Date())
 | 
			
		||||
 | 
			
		||||
        import UIKit
 | 
			
		||||
 | 
			
		||||
        extension \(extensionClassname) {\n
 | 
			
		||||
        """
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    func getFooter() -> String {
 | 
			
		||||
        """
 | 
			
		||||
        }
 | 
			
		||||
        """
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    func getProperties() -> String {
 | 
			
		||||
        colors.map {
 | 
			
		||||
            if extensionClassname == ColorTool.defaultExtensionName {
 | 
			
		||||
                return $0.getColorStaticProperty()
 | 
			
		||||
            }
 | 
			
		||||
            return $0.getColorProperty()
 | 
			
		||||
        }
 | 
			
		||||
        .joined(separator: "\n\n")
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										53
									
								
								Sources/ColorToolCore/ColorToolError.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								Sources/ColorToolCore/ColorToolError.swift
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
			
		||||
//
 | 
			
		||||
//  ColorToolError.swift
 | 
			
		||||
//  
 | 
			
		||||
//
 | 
			
		||||
//  Created by Thibaut Schmitt on 20/12/2021.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
import Foundation
 | 
			
		||||
 | 
			
		||||
enum ColorToolError: Error {
 | 
			
		||||
    case badFormat(String)
 | 
			
		||||
    case writeAsset(String)
 | 
			
		||||
    case writeExtension(String, String)
 | 
			
		||||
    case fileNotExists(String)
 | 
			
		||||
    case badColorDefinition(String, String)
 | 
			
		||||
    
 | 
			
		||||
    var description: String {
 | 
			
		||||
        switch self {
 | 
			
		||||
        case .badFormat(let info):
 | 
			
		||||
            return """
 | 
			
		||||
            [ColorTool]
 | 
			
		||||
            Bad line format: \(info). Accepted format are:
 | 
			
		||||
            - colorName="#RGB/#ARGB"
 | 
			
		||||
            - colorName "#RGB/#ARGB"
 | 
			
		||||
            - colorName "#RGB/#ARGB" "#RGB/#ARGB"
 | 
			
		||||
            """
 | 
			
		||||
            
 | 
			
		||||
        case .writeAsset(let info):
 | 
			
		||||
            return """
 | 
			
		||||
            [ColorTool]
 | 
			
		||||
            An error occured while writing color in Xcasset: \(info)
 | 
			
		||||
            """
 | 
			
		||||
            
 | 
			
		||||
        case .writeExtension(let filename, let info):
 | 
			
		||||
            return """
 | 
			
		||||
            [ColorTool]
 | 
			
		||||
            An error occured while writing extension in \(filename): \(info)
 | 
			
		||||
            """
 | 
			
		||||
            
 | 
			
		||||
        case .fileNotExists(let filename):
 | 
			
		||||
            return """
 | 
			
		||||
            [ColorTool]
 | 
			
		||||
            File \(filename) does not exists
 | 
			
		||||
            """
 | 
			
		||||
            
 | 
			
		||||
        case .badColorDefinition(let lightColor, let darkColor):
 | 
			
		||||
            return """
 | 
			
		||||
            [ColorTool]
 | 
			
		||||
            One of these two colors has invalid synthax: -\(lightColor)- or -\(darkColor)-
 | 
			
		||||
            """
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										40
									
								
								Sources/ColorToolCore/ColorXcassetHelper.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								Sources/ColorToolCore/ColorXcassetHelper.swift
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
//
 | 
			
		||||
//  ColorXcassetHelper.swift
 | 
			
		||||
//  
 | 
			
		||||
//
 | 
			
		||||
//  Created by Thibaut Schmitt on 20/12/2021.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
import Foundation
 | 
			
		||||
import CLIToolCore
 | 
			
		||||
 | 
			
		||||
struct ColorXcassetHelper {
 | 
			
		||||
    
 | 
			
		||||
    let xcassetsPath: String
 | 
			
		||||
    let colors: [GenColor]
 | 
			
		||||
    
 | 
			
		||||
    func generateXcassetColors() {
 | 
			
		||||
        colors.forEach {
 | 
			
		||||
            generateColorSetAssets(from: $0)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Generate ColorSet in XCAssets file
 | 
			
		||||
    private func generateColorSetAssets(from color: GenColor) {
 | 
			
		||||
        // Create ColorSet
 | 
			
		||||
        let colorSetPath = "\(xcassetsPath)/Colors/\(color.name).colorset"
 | 
			
		||||
        Shell.shell("mkdir", "-p", "\(colorSetPath)")
 | 
			
		||||
        
 | 
			
		||||
        // Create Contents.json in ColorSet
 | 
			
		||||
        let contentsJsonPath = "\(colorSetPath)/Contents.json"
 | 
			
		||||
        Shell.shell("touch", "\(contentsJsonPath)")
 | 
			
		||||
        
 | 
			
		||||
        // Write content in Contents.json
 | 
			
		||||
        let contentsJsonPathURL = URL(fileURLWithPath: contentsJsonPath)
 | 
			
		||||
        do {
 | 
			
		||||
            try color.contentsJSON().write(to: contentsJsonPathURL, atomically: true, encoding: .utf8)
 | 
			
		||||
        } catch (let error) {
 | 
			
		||||
            ColorTool.exit(withError: ColorToolError.writeAsset(error.localizedDescription))
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										90
									
								
								Sources/ColorToolCore/GenColor.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								Sources/ColorToolCore/GenColor.swift
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
			
		||||
//
 | 
			
		||||
//  GenColor.swift
 | 
			
		||||
//  
 | 
			
		||||
//
 | 
			
		||||
//  Created by Thibaut Schmitt on 20/12/2021.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
import Foundation
 | 
			
		||||
 | 
			
		||||
struct GenColor {
 | 
			
		||||
    let name: String
 | 
			
		||||
    let light: String
 | 
			
		||||
    let dark: String
 | 
			
		||||
    
 | 
			
		||||
    // Generate Contents.json content
 | 
			
		||||
    func contentsJSON() -> String {
 | 
			
		||||
        let lightARGB = light.colorComponent()
 | 
			
		||||
        let darkARGB = dark.colorComponent()
 | 
			
		||||
        
 | 
			
		||||
        let allComponents = [
 | 
			
		||||
            lightARGB.alpha, lightARGB.red, lightARGB.green, lightARGB.blue,
 | 
			
		||||
            darkARGB.alpha, darkARGB.red, darkARGB.green, darkARGB.blue
 | 
			
		||||
        ].map {
 | 
			
		||||
            $0.isEmpty
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        guard allComponents.contains(true) == false else {
 | 
			
		||||
            ColorTool.exit(withError: ColorToolError.badColorDefinition(light, dark))
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        return """
 | 
			
		||||
        {
 | 
			
		||||
            "colors": [
 | 
			
		||||
                {
 | 
			
		||||
                    "color": {
 | 
			
		||||
                        "color-space": "srgb",
 | 
			
		||||
                        "components": {
 | 
			
		||||
                            "alpha": "0x\(lightARGB.alpha)",
 | 
			
		||||
                            "blue": "0x\(lightARGB.blue)",
 | 
			
		||||
                            "green": "0x\(lightARGB.green)",
 | 
			
		||||
                            "red": "0x\(lightARGB.red)",
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                    "idiom": "universal"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "appearances": [
 | 
			
		||||
                        {
 | 
			
		||||
                            "appearance": "luminosity",
 | 
			
		||||
                            "value": "dark"
 | 
			
		||||
                        }
 | 
			
		||||
                    ],
 | 
			
		||||
                    "color": {
 | 
			
		||||
                        "color-space": "srgb",
 | 
			
		||||
                        "components": {
 | 
			
		||||
                            "alpha": "0x\(darkARGB.alpha)",
 | 
			
		||||
                            "blue": "0x\(darkARGB.blue)",
 | 
			
		||||
                            "green": "0x\(darkARGB.green)",
 | 
			
		||||
                            "red": "0x\(darkARGB.red)",
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                    "idiom": "universal"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "info": {
 | 
			
		||||
                "author": "xcode",
 | 
			
		||||
                "version": 1
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        """
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    func getColorProperty() -> String {
 | 
			
		||||
        """
 | 
			
		||||
            /// Color \(name) is \(light) (light) or \(dark) (dark)"
 | 
			
		||||
            @objc var \(name): UIColor {
 | 
			
		||||
                UIColor(named: "\(name)")!
 | 
			
		||||
            }
 | 
			
		||||
        """
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    func getColorStaticProperty() -> String {
 | 
			
		||||
        """
 | 
			
		||||
            /// Color \(name) is \(light) (light) or \(dark) (dark)"
 | 
			
		||||
            static var \(name): UIColor {
 | 
			
		||||
                UIColor(named: "\(name)")!
 | 
			
		||||
            }
 | 
			
		||||
        """
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										165
									
								
								Sources/ColorToolCore/main.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								Sources/ColorToolCore/main.swift
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,165 @@
 | 
			
		||||
//
 | 
			
		||||
//  main.swift
 | 
			
		||||
//  
 | 
			
		||||
//
 | 
			
		||||
//  Created by Thibaut Schmitt on 20/12/2021.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
import Foundation
 | 
			
		||||
import CLIToolCore
 | 
			
		||||
import ArgumentParser
 | 
			
		||||
 | 
			
		||||
enum ColorStyle: String, Decodable {
 | 
			
		||||
    case light
 | 
			
		||||
    case all
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct ColorTool: ParsableCommand {
 | 
			
		||||
    static let defaultExtensionName = "UIColor"
 | 
			
		||||
    static let assetsColorsFolderName = "Colors"
 | 
			
		||||
    
 | 
			
		||||
    @Flag(name: .customShort("f"), help: "Should force generation")
 | 
			
		||||
    var forceGeneration = false
 | 
			
		||||
    
 | 
			
		||||
    @Argument(help: "Input files where colors ared defined.")
 | 
			
		||||
    var inputFile: String
 | 
			
		||||
    
 | 
			
		||||
    @Option(help: "Color style to generate: light for light colors only, or all for dark and light colors")
 | 
			
		||||
    var style: String
 | 
			
		||||
    
 | 
			
		||||
    @Option(help: "Path of xcassets where to generate colors")
 | 
			
		||||
    var xcassetsPath: String
 | 
			
		||||
    
 | 
			
		||||
    @Option(help: "Path where to generate the extension.")
 | 
			
		||||
    var extensionOutputPath: String
 | 
			
		||||
    
 | 
			
		||||
    @Option(help: "Extension name. If not specified, it will generate an UIFont extension")
 | 
			
		||||
    var extensionName: String = Self.defaultExtensionName
 | 
			
		||||
    
 | 
			
		||||
    @Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+ColorsMyApp.swift")
 | 
			
		||||
    var extensionSuffix: String = ""
 | 
			
		||||
    
 | 
			
		||||
    var colorStyle: ColorStyle { ColorStyle(rawValue: style) ?? .all }
 | 
			
		||||
    var extensionFileName: String { "\(extensionName)+Font\(extensionSuffix).swift" }
 | 
			
		||||
    var extensionFilePath: String { "\(extensionOutputPath)/\(extensionFileName)" }
 | 
			
		||||
    
 | 
			
		||||
    public func run() throws {
 | 
			
		||||
        print("[ColorTool] Starting colors generation")
 | 
			
		||||
        
 | 
			
		||||
        print("[ColorTool] Will use inputFile \(inputFile) to generate \(colorStyle) colors in xcassets \(xcassetsPath)")
 | 
			
		||||
        print("[ColorTool] Extension will be \(extensionFilePath)")
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        // Check if needed to regenerate
 | 
			
		||||
        guard GeneratorChecker.shouldGenerate(force: forceGeneration, inputFilePath: inputFile, extensionFilePath: extensionFilePath) else {
 | 
			
		||||
            print("[ColorTool] Colors are already up to date :) ")
 | 
			
		||||
            return
 | 
			
		||||
        }
 | 
			
		||||
        print("[ColorTool] Will generate colors")
 | 
			
		||||
        
 | 
			
		||||
        // Check if Xcasset exists
 | 
			
		||||
        let fileManager = FileManager()
 | 
			
		||||
        guard fileManager.fileExists(atPath: xcassetsPath) else {
 | 
			
		||||
            ColorTool.exit(withError: ColorToolError.fileNotExists(xcassetsPath))
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // Delete current colors
 | 
			
		||||
        Shell.shell("rm", "-rf", "\(xcassetsPath)/Colors/*")
 | 
			
		||||
        
 | 
			
		||||
        // Get colors
 | 
			
		||||
        let colorsToGen = getColorsGen()
 | 
			
		||||
        
 | 
			
		||||
        // Generate all colors in xcassets
 | 
			
		||||
        let colorAssetHelper = ColorXcassetHelper(xcassetsPath: xcassetsPath, colors: colorsToGen)
 | 
			
		||||
        colorAssetHelper.generateXcassetColors()
 | 
			
		||||
        
 | 
			
		||||
        // Generate extension
 | 
			
		||||
        let extensionGenerator = ColorExtensionGenerator(colors: colorsToGen,
 | 
			
		||||
                                                         extensionClassname: extensionName,
 | 
			
		||||
                                                         isUIColorExtension: isUIColorExtension())
 | 
			
		||||
        let extensionHeader = extensionGenerator.getHeader()
 | 
			
		||||
        let extensionProperties = extensionGenerator.getProperties()
 | 
			
		||||
        let extensionFooter = extensionGenerator.getFooter()
 | 
			
		||||
        
 | 
			
		||||
        generateExtensionFile(extensionHeader, extensionProperties, extensionFooter)
 | 
			
		||||
        
 | 
			
		||||
        print("[ColorTool] Colors generated")
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    private func generateExtensionFile(_ args: String...) {
 | 
			
		||||
        // Create file if not exists
 | 
			
		||||
        let fileManager = FileManager()
 | 
			
		||||
        if fileManager.fileExists(atPath: extensionFilePath) == false {
 | 
			
		||||
            Shell.shell("touch", "\(extensionFilePath)")
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // Create extension content
 | 
			
		||||
        let extensionContent = args.joined(separator: "\n")
 | 
			
		||||
        
 | 
			
		||||
        // Write content
 | 
			
		||||
        let extensionFilePathURL = URL(fileURLWithPath: extensionFilePath)
 | 
			
		||||
        do {
 | 
			
		||||
            try extensionContent.write(to: extensionFilePathURL, atomically: true, encoding: .utf8)
 | 
			
		||||
        } catch (let error) {
 | 
			
		||||
            ColorTool.exit(withError: ColorToolError.writeExtension(extensionFilePath, error.localizedDescription))
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    private func getColorsGen() -> [GenColor] {
 | 
			
		||||
        // Get content of input file
 | 
			
		||||
        let inputFileContent = try! String(contentsOfFile: inputFile, encoding: .utf8)
 | 
			
		||||
        let colorsByLines = inputFileContent.components(separatedBy: .newlines)
 | 
			
		||||
        
 | 
			
		||||
        // Iterate on each line of input file
 | 
			
		||||
        return colorsByLines.enumerated().compactMap { lineNumber, colorLine in
 | 
			
		||||
            // Required format:
 | 
			
		||||
            // colorName="#RGB/#ARGB", colorName "#RGB/#ARGB", colorName "#RGB/#ARGB" "#RGB/#ARGB"
 | 
			
		||||
            let colorLineCleanedUp = colorLine
 | 
			
		||||
                .removeTrailingWhitespace()
 | 
			
		||||
                .replacingOccurrences(of: "=", with: "") // Keep compat with current file format
 | 
			
		||||
            
 | 
			
		||||
            guard colorLineCleanedUp.hasPrefix("#") == false, colorLineCleanedUp.isEmpty == false else {
 | 
			
		||||
                print("[ColorTool] ⚠️  BadFormat or empty line (line number: \(lineNumber + 1)). Skip this line")
 | 
			
		||||
                return nil
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            let colorContent = colorLineCleanedUp.split(separator: " ")
 | 
			
		||||
            
 | 
			
		||||
            guard colorContent.count >= 2 else {
 | 
			
		||||
                ColorTool.exit(withError: ColorToolError.badFormat(colorLine))
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            switch colorStyle {
 | 
			
		||||
            case .light:
 | 
			
		||||
                return GenColor(name: String(colorContent[0]), light: String(colorContent[1]), dark: String(colorContent[1]))
 | 
			
		||||
                
 | 
			
		||||
            case .all:
 | 
			
		||||
                if colorContent.count == 3 {
 | 
			
		||||
                    return GenColor(name: String(colorContent[0]), light: String(colorContent[1]), dark: String(colorContent[2]))
 | 
			
		||||
                }
 | 
			
		||||
                return GenColor(name: String(colorContent[0]), light: String(colorContent[1]), dark: String(colorContent[1]))
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // MARK: - Helpers
 | 
			
		||||
    
 | 
			
		||||
    private func isUIColorExtension() -> Bool {
 | 
			
		||||
        extensionName == Self.defaultExtensionName
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ColorTool.main()
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 Command samples:
 | 
			
		||||
 
 | 
			
		||||
 1. UIColor extension without suffix
 | 
			
		||||
 swift run -c release ColorToolCore -f ./SampleFiles/Colors/sampleColors1.txt --style all --xcassets-path "./SampleFiles/Colors/colors.xcassets" --extension-output-path "./SampleFiles/Colors/Generated/" --extension-name "UIColor"
 | 
			
		||||
 
 | 
			
		||||
 2. UIColor extension with custom suffix
 | 
			
		||||
 swift run -c release ColorToolCore -f ./SampleFiles/Colors/sampleColors1.txt --style all --xcassets-path "./SampleFiles/Colors/colors.xcassets" --extension-output-path "./SampleFiles/Colors/Generated/" --extension-name "UIColor" --extension-suffix "SampleApp"
 | 
			
		||||
 
 | 
			
		||||
 3. Custom extension with only light theme colors (R2Color)
 | 
			
		||||
 swift run -c release ColorToolCore -f ./SampleFiles/Colors/sampleColors1.txt --style light --xcassets-path "./SampleFiles/Colors/colors.xcassets" --extension-output-path "./SampleFiles/Colors/Generated/" --extension-name "R2Color"
 | 
			
		||||
 */
 | 
			
		||||
@@ -1,26 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  File.swift
 | 
			
		||||
//  
 | 
			
		||||
//
 | 
			
		||||
//  Created by Thibaut Schmitt on 13/12/2021.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
import Foundation
 | 
			
		||||
 | 
			
		||||
extension String {
 | 
			
		||||
    func removeCharacters(from forbiddenChars: CharacterSet) -> String {
 | 
			
		||||
        let passed = self.unicodeScalars.filter { !forbiddenChars.contains($0) }
 | 
			
		||||
        return String(String.UnicodeScalarView(passed))
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    func removeCharacters(from: String) -> String {
 | 
			
		||||
        return removeCharacters(from: CharacterSet(charactersIn: from))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extension Sequence where Iterator.Element: Hashable {
 | 
			
		||||
    func unique() -> [Iterator.Element] {
 | 
			
		||||
        var seen: [Iterator.Element: Bool] = [:]
 | 
			
		||||
        return self.filter { seen.updateValue(true, forKey: $0) == nil }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -16,12 +16,16 @@ enum FontToolError: Error {
 | 
			
		||||
        switch self {
 | 
			
		||||
        case .fcScan(let path, let code, let output):
 | 
			
		||||
            return """
 | 
			
		||||
            [FontTool]
 | 
			
		||||
            Error while getting fontName (fc-scan --format %{postscriptname} \(path).
 | 
			
		||||
            fc-scan exit with \(code) and output is: \(output ?? "no output")
 | 
			
		||||
            """
 | 
			
		||||
            
 | 
			
		||||
        case .inputFolderNotFound(let inputFolder):
 | 
			
		||||
            return "Input folder not found: \(inputFolder)"
 | 
			
		||||
            return """
 | 
			
		||||
            [ColorTool]
 | 
			
		||||
            Input folder not found: \(inputFolder)
 | 
			
		||||
            """
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,11 @@ import Foundation
 | 
			
		||||
import CLIToolCore
 | 
			
		||||
import ArgumentParser
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 Lire l'infoPlist et check si les fonts dedans sont les memes que celles à générer
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//swift run -c release FontToolCore ./SampleFiles/Fonts --extension-output-path ~/Desktop --extension-name R2Font
 | 
			
		||||
struct FontTool: ParsableCommand {
 | 
			
		||||
    static let defaultExtensionName = "UIFont"
 | 
			
		||||
    
 | 
			
		||||
@@ -22,7 +27,7 @@ struct FontTool: ParsableCommand {
 | 
			
		||||
    var extensionName: String = Self.defaultExtensionName
 | 
			
		||||
    
 | 
			
		||||
    public func run() throws {
 | 
			
		||||
        print("[FontTool] Starting font generation")
 | 
			
		||||
        print("[FontTool] Starting fonts generation")
 | 
			
		||||
        
 | 
			
		||||
        let fontsData = FontToolHelper.getFontsData(fromInputFolder: inputFolder)
 | 
			
		||||
        
 | 
			
		||||
@@ -41,7 +46,7 @@ struct FontTool: ParsableCommand {
 | 
			
		||||
        print("Info.plist information:")
 | 
			
		||||
        print("\(generatePlistUIAppFonts(fontsNames: fontsData.fontsNames))")
 | 
			
		||||
        
 | 
			
		||||
        print("[FontTool] Font generated")
 | 
			
		||||
        print("[FontTool] Fonts generated")
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    private func generateExtensionFile(_ args: String...) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user