From 62df14867598bd6f4c2ad5250dad71e7ecd6ae1d Mon Sep 17 00:00:00 2001 From: Timur Shafigullin Date: Tue, 5 Sep 2023 16:26:50 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D1=84=D0=BB=D0=B0=D0=B3=20groupByComponentSet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/FigmaGen/Commands/ImagesCommand.swift | 13 ++++++- .../Images/DefaultImagesGenerator.swift | 1 + .../Configuration/ImagesConfiguration.swift | 6 ++++ .../Models/Parameters/ImagesParameters.swift | 1 + .../Assets/DefaultImageAssetsProvider.swift | 16 +++++++-- .../Images/DefaultImagesProvider.swift | 15 ++------ .../Images/ImagesFolderPathResolving.swift | 8 ++++- .../DefaultImageResourcesProvider.swift | 36 +++++++++---------- .../Resources/ImageResourcesProvider.swift | 5 +-- 9 files changed, 61 insertions(+), 40 deletions(-) diff --git a/Sources/FigmaGen/Commands/ImagesCommand.swift b/Sources/FigmaGen/Commands/ImagesCommand.swift index 492e5b1..32bffb8 100644 --- a/Sources/FigmaGen/Commands/ImagesCommand.swift +++ b/Sources/FigmaGen/Commands/ImagesCommand.swift @@ -152,7 +152,17 @@ final class ImagesCommand: AsyncExecutableCommand, GenerationConfigurableCommand let groupByFrame = Flag( "--groupByFrame", description: """ - Groupу generated assets and resources into folders with name of parent frame. + Group generated assets and resources into folders with name of parent frame. + By default without grouping. + """ + ) + + let groupByComponentSet = Flag( + "--groupByComponentSet", + description: """ + Group generated assets and resources into folders with name of component set. + Only for components with variants. + By default without grouping. """ ) @@ -226,6 +236,7 @@ final class ImagesCommand: AsyncExecutableCommand, GenerationConfigurableCommand useAbsoluteBounds: useAbsoluteBounds.value, preserveVectorData: preserveVectorData.value, groupByFrame: groupByFrame.value, + groupByComponentSet: groupByComponentSet.value, namingStyle: resolveNamingStyle() ) } diff --git a/Sources/FigmaGen/Generators/Images/DefaultImagesGenerator.swift b/Sources/FigmaGen/Generators/Images/DefaultImagesGenerator.swift index 9789489..7c20937 100644 --- a/Sources/FigmaGen/Generators/Images/DefaultImagesGenerator.swift +++ b/Sources/FigmaGen/Generators/Images/DefaultImagesGenerator.swift @@ -65,6 +65,7 @@ extension ImagesConfiguration { useAbsoluteBounds: useAbsoluteBounds, preserveVectorData: preserveVectorData, groupByFrame: groupByFrame, + groupByComponentSet: groupByComponentSet, namingStyle: namingStyle ) } diff --git a/Sources/FigmaGen/Models/Configuration/ImagesConfiguration.swift b/Sources/FigmaGen/Models/Configuration/ImagesConfiguration.swift index 9985ca2..be27d81 100644 --- a/Sources/FigmaGen/Models/Configuration/ImagesConfiguration.swift +++ b/Sources/FigmaGen/Models/Configuration/ImagesConfiguration.swift @@ -14,6 +14,7 @@ struct ImagesConfiguration: Decodable { case useAbsoluteBounds case preserveVectorData case groupByFrame + case groupByComponentSet case namingStyle } @@ -29,6 +30,7 @@ struct ImagesConfiguration: Decodable { let useAbsoluteBounds: Bool let preserveVectorData: Bool let groupByFrame: Bool + let groupByComponentSet: Bool let namingStyle: ImageNamingStyle // MARK: - Initializers @@ -44,6 +46,7 @@ struct ImagesConfiguration: Decodable { useAbsoluteBounds: Bool, preserveVectorData: Bool, groupByFrame: Bool, + groupByComponentSet: Bool, namingStyle: ImageNamingStyle ) { self.generatation = generatation @@ -56,6 +59,7 @@ struct ImagesConfiguration: Decodable { self.useAbsoluteBounds = useAbsoluteBounds self.preserveVectorData = preserveVectorData self.groupByFrame = groupByFrame + self.groupByComponentSet = groupByComponentSet self.namingStyle = namingStyle } @@ -72,6 +76,7 @@ struct ImagesConfiguration: Decodable { useAbsoluteBounds = try container.decodeIfPresent(forKey: .useAbsoluteBounds) ?? false preserveVectorData = try container.decodeIfPresent(forKey: .preserveVectorData) ?? false groupByFrame = try container.decodeIfPresent(forKey: .groupByFrame) ?? false + groupByComponentSet = try container.decodeIfPresent(forKey: .groupByComponentSet) ?? false namingStyle = try container.decodeIfPresent(forKey: .namingStyle) ?? .camelCase generatation = try GenerationConfiguration(from: decoder) @@ -91,6 +96,7 @@ struct ImagesConfiguration: Decodable { useAbsoluteBounds: useAbsoluteBounds, preserveVectorData: preserveVectorData, groupByFrame: groupByFrame, + groupByComponentSet: groupByComponentSet, namingStyle: namingStyle ) } diff --git a/Sources/FigmaGen/Models/Parameters/ImagesParameters.swift b/Sources/FigmaGen/Models/Parameters/ImagesParameters.swift index 4f89f4d..2080938 100644 --- a/Sources/FigmaGen/Models/Parameters/ImagesParameters.swift +++ b/Sources/FigmaGen/Models/Parameters/ImagesParameters.swift @@ -13,5 +13,6 @@ struct ImagesParameters { let useAbsoluteBounds: Bool let preserveVectorData: Bool let groupByFrame: Bool + let groupByComponentSet: Bool let namingStyle: ImageNamingStyle } diff --git a/Sources/FigmaGen/Providers/Images/Assets/DefaultImageAssetsProvider.swift b/Sources/FigmaGen/Providers/Images/Assets/DefaultImageAssetsProvider.swift index 0c9b29e..c4902a5 100644 --- a/Sources/FigmaGen/Providers/Images/Assets/DefaultImageAssetsProvider.swift +++ b/Sources/FigmaGen/Providers/Images/Assets/DefaultImageAssetsProvider.swift @@ -45,6 +45,7 @@ final class DefaultImageAssetsProvider: ImageAssetsProvider, ImagesFolderPathRes let folderPath = resolveFolderPath( groupByFrame: parameters.groupByFrame, + groupByComponentSet: parameters.groupByComponentSet, setNode: setNode, folderPath: folderPath ) @@ -113,6 +114,7 @@ final class DefaultImageAssetsProvider: ImageAssetsProvider, ImagesFolderPathRes private func saveAssetFolders( assets: [ImageComponentSetAsset: AssetFolder], groupByFrame: Bool, + groupByComponentSet: Bool, in folderPath: String ) throws -> Promise { let folderPath = Path(folderPath) @@ -124,7 +126,12 @@ final class DefaultImageAssetsProvider: ImageAssetsProvider, ImagesFolderPathRes let promises = assets.map { asset, folder in assetsProvider.saveAssetFolder( folder, - in: resolveFolderPath(groupByFrame: groupByFrame, setAsset: asset, folderPath: folderPath).string + in: resolveFolderPath( + groupByFrame: groupByFrame, + groupByComponentSet: groupByComponentSet, + setAsset: asset, + folderPath: folderPath + ).string ) } @@ -163,7 +170,12 @@ final class DefaultImageAssetsProvider: ImageAssetsProvider, ImagesFolderPathRes ) } }.then { assets in - try self.saveAssetFolders(assets: assets, groupByFrame: parameters.groupByFrame, in: folderPath) + try self.saveAssetFolders( + assets: assets, + groupByFrame: parameters.groupByFrame, + groupByComponentSet: parameters.groupByComponentSet, + in: folderPath + ) }.then { self.saveImageFiles(assets: assets) } diff --git a/Sources/FigmaGen/Providers/Images/DefaultImagesProvider.swift b/Sources/FigmaGen/Providers/Images/DefaultImagesProvider.swift index bc0097c..889dc92 100644 --- a/Sources/FigmaGen/Providers/Images/DefaultImagesProvider.swift +++ b/Sources/FigmaGen/Providers/Images/DefaultImagesProvider.swift @@ -163,19 +163,13 @@ final class DefaultImagesProvider: ImagesProvider { private func saveResourceImagesIfNeeded( nodes: [ImageComponentSetRenderedNode], - groupByFrame: Bool, - format: ImageFormat, - postProcessor: String?, - namingStyle: ImageNamingStyle, + parameters: ImagesParameters, in resources: String? ) -> Promise<[ImageRenderedNode: ImageResource]> { resources.map { folderPath in imageResourcesProvider.saveImages( nodes: nodes, - groupByFrame: groupByFrame, - format: format, - postProcessor: postProcessor, - namingStyle: namingStyle, + parameters: parameters, in: folderPath ) } ?? .value([:]) @@ -193,10 +187,7 @@ final class DefaultImagesProvider: ImagesProvider { ), self.saveResourceImagesIfNeeded( nodes: nodes, - groupByFrame: parameters.groupByFrame, - format: parameters.format, - postProcessor: parameters.postProcessor, - namingStyle: parameters.namingStyle, + parameters: parameters, in: parameters.resources ) ) diff --git a/Sources/FigmaGen/Providers/Images/ImagesFolderPathResolving.swift b/Sources/FigmaGen/Providers/Images/ImagesFolderPathResolving.swift index ca6a77e..6ce373b 100644 --- a/Sources/FigmaGen/Providers/Images/ImagesFolderPathResolving.swift +++ b/Sources/FigmaGen/Providers/Images/ImagesFolderPathResolving.swift @@ -7,6 +7,7 @@ protocol ImagesFolderPathResolving { func resolveFolderPath( groupByFrame: Bool, + groupByComponentSet: Bool, parentNodeName: String?, isSingleComponent: Bool, nodeName: String, @@ -20,6 +21,7 @@ extension ImagesFolderPathResolving { func resolveFolderPath( groupByFrame: Bool, + groupByComponentSet: Bool, parentNodeName: String?, isSingleComponent: Bool, nodeName: String, @@ -31,7 +33,7 @@ extension ImagesFolderPathResolving { folderPath = folderPath.appending(name.camelized) } - if !isSingleComponent { + if groupByComponentSet, !isSingleComponent { folderPath = folderPath.appending(nodeName.camelized) } @@ -40,11 +42,13 @@ extension ImagesFolderPathResolving { func resolveFolderPath( groupByFrame: Bool, + groupByComponentSet: Bool, setNode: ImageComponentSetRenderedNode, folderPath: Path ) -> Path { resolveFolderPath( groupByFrame: groupByFrame, + groupByComponentSet: groupByComponentSet, parentNodeName: setNode.parentName, isSingleComponent: setNode.isSingleComponent, nodeName: setNode.name, @@ -54,11 +58,13 @@ extension ImagesFolderPathResolving { func resolveFolderPath( groupByFrame: Bool, + groupByComponentSet: Bool, setAsset: ImageComponentSetAsset, folderPath: Path ) -> Path { resolveFolderPath( groupByFrame: groupByFrame, + groupByComponentSet: groupByComponentSet, parentNodeName: setAsset.parentName, isSingleComponent: setAsset.isSingleComponent, nodeName: setAsset.name, diff --git a/Sources/FigmaGen/Providers/Images/Resources/DefaultImageResourcesProvider.swift b/Sources/FigmaGen/Providers/Images/Resources/DefaultImageResourcesProvider.swift index 21bcd36..05c27e5 100644 --- a/Sources/FigmaGen/Providers/Images/Resources/DefaultImageResourcesProvider.swift +++ b/Sources/FigmaGen/Providers/Images/Resources/DefaultImageResourcesProvider.swift @@ -38,14 +38,19 @@ final class DefaultImageResourcesProvider: ImageResourcesProvider, ImagesFolderP private func makeResource( for node: ImageRenderedNode, setNode: ImageComponentSetRenderedNode, - groupByFrame: Bool, - format: ImageFormat, - namingStyle: ImageNamingStyle, + parameters: ImagesParameters, folderPath: Path ) -> ImageResource { - let fileName = resolveFileName(for: node, setNode: setNode, namingStyle: namingStyle) - let folderPath = resolveFolderPath(groupByFrame: groupByFrame, setNode: setNode, folderPath: folderPath) - let fileExtension = format.fileExtension + let fileName = resolveFileName(for: node, setNode: setNode, namingStyle: parameters.namingStyle) + + let folderPath = resolveFolderPath( + groupByFrame: parameters.groupByFrame, + groupByComponentSet: parameters.groupByComponentSet, + setNode: setNode, + folderPath: folderPath + ) + + let fileExtension = parameters.format.fileExtension let filePaths = node.urls.keys.reduce(into: [:]) { result, scale in result[scale] = folderPath @@ -58,9 +63,7 @@ final class DefaultImageResourcesProvider: ImageResourcesProvider, ImagesFolderP private func makeResources( for nodes: [ImageComponentSetRenderedNode], - groupByFrame: Bool, - format: ImageFormat, - namingStyle: ImageNamingStyle, + parameters: ImagesParameters, folderPath: Path ) -> [ImageRenderedNode: ImageResource] { var resources: [ImageRenderedNode: ImageResource] = [:] @@ -70,9 +73,7 @@ final class DefaultImageResourcesProvider: ImageResourcesProvider, ImagesFolderP resources[node] = makeResource( for: node, setNode: setNode, - groupByFrame: groupByFrame, - format: format, - namingStyle: namingStyle, + parameters: parameters, folderPath: folderPath ) } @@ -121,22 +122,17 @@ final class DefaultImageResourcesProvider: ImageResourcesProvider, ImagesFolderP func saveImages( nodes: [ImageComponentSetRenderedNode], - groupByFrame: Bool, - format: ImageFormat, - postProcessor: String?, - namingStyle: ImageNamingStyle, + parameters: ImagesParameters, in folderPath: String ) -> Promise<[ImageRenderedNode: ImageResource]> { perform(on: DispatchQueue.global(qos: .userInitiated)) { self.makeResources( for: nodes, - groupByFrame: groupByFrame, - format: format, - namingStyle: namingStyle, + parameters: parameters, folderPath: Path(folderPath) ) }.nest { resources in - try self.saveImageFiles(resources: resources, postProcessor: postProcessor, in: Path(folderPath)) + try self.saveImageFiles(resources: resources, postProcessor: parameters.postProcessor, in: Path(folderPath)) } } } diff --git a/Sources/FigmaGen/Providers/Images/Resources/ImageResourcesProvider.swift b/Sources/FigmaGen/Providers/Images/Resources/ImageResourcesProvider.swift index 6cbbd9f..6651724 100644 --- a/Sources/FigmaGen/Providers/Images/Resources/ImageResourcesProvider.swift +++ b/Sources/FigmaGen/Providers/Images/Resources/ImageResourcesProvider.swift @@ -7,10 +7,7 @@ protocol ImageResourcesProvider { func saveImages( nodes: [ImageComponentSetRenderedNode], - groupByFrame: Bool, - format: ImageFormat, - postProcessor: String?, - namingStyle: ImageNamingStyle, + parameters: ImagesParameters, in folderPath: String ) -> Promise<[ImageRenderedNode: ImageResource]> } From 45fc913fe57a1402ee1beb377832dbc2b8ec876f Mon Sep 17 00:00:00 2001 From: Timur Shafigullin Date: Tue, 5 Sep 2023 16:29:05 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BA=D0=BE=D0=BD=D1=84=D0=B8=D0=B3=D1=83=D1=80?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F=20=D0=B4=D0=BB=D1=8F=20demo=20=D0=BF?= =?UTF-8?q?=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/.figmagen.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/Demo/.figmagen.yml b/Demo/.figmagen.yml index e2d9fbc..72f7f09 100644 --- a/Demo/.figmagen.yml +++ b/Demo/.figmagen.yml @@ -27,6 +27,7 @@ images: assets: FigmaGenDemo/Resources/Images.xcassets/Generated destination: FigmaGenDemo/Generated/Images.swift groupByFrame: true + groupByComponentSet: true templateOptions: publicAccess: true