├── Tests ├── SassPublishPluginTests │ ├── styles.sass │ ├── XCTestManifests.swift │ └── SassPublishPluginTests.swift └── LinuxMain.swift ├── .gitignore ├── Sources └── SassPublishPlugin │ └── SassPublishPlugin.swift ├── Package.swift ├── LICENSE └── README.md /Tests/SassPublishPluginTests/styles.sass: -------------------------------------------------------------------------------- 1 | @charset "utf-8" 2 | 3 | body 4 | color: blue 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | Package.resolved 4 | .swiftpm 5 | /*.xcodeproj 6 | xcuserdata/ 7 | -------------------------------------------------------------------------------- /Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * Sass-plugin for Publish 3 | * Copyright (c) Hejki 2020 4 | * MIT license, see LICENSE file for details 5 | */ 6 | 7 | import XCTest 8 | 9 | import SassPublishPluginTests 10 | 11 | var tests = [XCTestCaseEntry]() 12 | tests += SassPublishPluginTests.allTests() 13 | XCTMain(tests) 14 | -------------------------------------------------------------------------------- /Tests/SassPublishPluginTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * Sass-plugin for Publish 3 | * Copyright (c) Hejki 2020 4 | * MIT license, see LICENSE file for details 5 | */ 6 | 7 | import XCTest 8 | 9 | #if !canImport(ObjectiveC) 10 | public func allTests() -> [XCTestCaseEntry] { 11 | return [ 12 | testCase(SassPublishPluginTests.allTests), 13 | ] 14 | } 15 | #endif 16 | -------------------------------------------------------------------------------- /Sources/SassPublishPlugin/SassPublishPlugin.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * Sass-plugin for Publish 3 | * Copyright (c) Hejki 2020 4 | * MIT license, see LICENSE file for details 5 | */ 6 | 7 | import Publish 8 | import ShellOut 9 | 10 | public extension Plugin { 11 | 12 | static func compileSass(sassFilePath: Path, cssFilePath: Path, compressed: Bool = false) -> Self { 13 | Plugin(name: "Sass") { context in 14 | let sassFile = try context.file(at: sassFilePath) 15 | let cssFile = try context.createOutputFile(at: cssFilePath) 16 | 17 | var args: [String] = [] 18 | 19 | if compressed { 20 | args += ["--style=compressed", "--no-embed-sources"] 21 | } 22 | args += [sassFile.path, cssFile.path] 23 | 24 | do { 25 | try shellOut(to: "sass", arguments: args) 26 | } catch { 27 | print(error) 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.5 2 | 3 | /** 4 | * Sass-plugin for Publish 5 | * Copyright (c) Hejki 2020 6 | * MIT license, see LICENSE file for details 7 | */ 8 | 9 | import PackageDescription 10 | 11 | let package = Package( 12 | name: "SassPublishPlugin", 13 | platforms: [.macOS(.v12)], 14 | products: [ 15 | .library( 16 | name: "SassPublishPlugin", 17 | targets: ["SassPublishPlugin"] 18 | ) 19 | ], 20 | dependencies: [ 21 | .package(url: "https://github.com/johnsundell/publish.git", from: "0.9.0"), 22 | .package(url: "https://github.com/JohnSundell/ShellOut.git", from: "2.0.0") 23 | ], 24 | targets: [ 25 | .target( 26 | name: "SassPublishPlugin", 27 | dependencies: [ 28 | .product(name: "Publish", package: "publish"), 29 | "ShellOut", 30 | ] 31 | ), 32 | .testTarget( 33 | name: "SassPublishPluginTests", 34 | dependencies: ["SassPublishPlugin"] 35 | ), 36 | ] 37 | ) 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Hejki 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sass plugin for Publish 2 | 3 | A [Publish](https://github.com/johnsundell/publish) plugin that makes it easy to integrate the [Swift-Sass](https://github.com/robinwalterfit/Swift-Sass.git) wrapper around LibSass C/C++ port of the Sass engine. 4 | 5 | ## Installation 6 | 7 | To use this repository you need to install the LibSass Library first. See [this instructions](https://github.com/sass/libsass/blob/master/docs/build.md) for building/installing LibSass. 8 | 9 | To install plugin into your [Publish](https://github.com/johnsundell/publish) package, add it as a dependency within your `Package.swift` manifest: 10 | 11 | ```swift 12 | let package = Package( 13 | ... 14 | dependencies: [ 15 | ... 16 | .package(url: "https://github.com/hejki/sasspublishplugin", from: "0.1.0") 17 | ], 18 | targets: [ 19 | .target( 20 | ... 21 | dependencies: [ 22 | ... 23 | "SassPublishPlugin" 24 | ] 25 | ) 26 | ] 27 | ... 28 | ) 29 | ``` 30 | 31 | Then import SassPublishPlugin wherever you’d like to use it: 32 | 33 | ```swift 34 | import SassPublishPlugin 35 | ``` 36 | 37 | For more information on how to use the Swift Package Manager, check out [this article](https://www.swiftbysundell.com/articles/managing-dependencies-using-the-swift-package-manager), or [its official documentation](https://github.com/apple/swift-package-manager/tree/master/Documentation). 38 | 39 | ## Usage 40 | 41 | The plugin can then be used within any publishing pipeline like this: 42 | 43 | ```swift 44 | import SassPublishPlugin 45 | ... 46 | try DeliciousRecipes().publish(using: [ 47 | .installPlugin( 48 | .compileSass( 49 | sassFilePath: "Sources/sass/styles.sass", 50 | cssFilePath: "styles.css" 51 | ) 52 | ) 53 | ... 54 | ]) 55 | ``` 56 | 57 | You can use predefined compressed sass options for minimal result: 58 | 59 | ```swift 60 | .compileSass( 61 | sassFilePath: "Sources/sass/styles.sass", 62 | cssFilePath: "styles.css", 63 | compressed: true 64 | ) 65 | ``` 66 | 67 | Or yse can define sass options manually: 68 | 69 | ```swift 70 | .compileSass(sassFilePath: "styles.sass", cssFilePath: "styles.css") { options in 71 | options.setOutputStyle(.compact) 72 | options.setSourceComments(true) 73 | } 74 | ``` 75 | -------------------------------------------------------------------------------- /Tests/SassPublishPluginTests/SassPublishPluginTests.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * Sass-plugin for Publish 3 | * Copyright (c) Hejki 2020 4 | * MIT license, see LICENSE file for details 5 | */ 6 | 7 | import XCTest 8 | import Publish 9 | import Plot 10 | import SassPublishPlugin 11 | import Files 12 | 13 | final class SassPublishPluginTests: XCTestCase { 14 | 15 | static var testDirPath: Path { 16 | let thisSourceFile = URL(fileURLWithPath: #file) 17 | return Path(thisSourceFile.deletingLastPathComponent().path) 18 | } 19 | 20 | private let sass: Path = "styles.sass" 21 | private let css: Path = "styles.css" 22 | 23 | private var outputFolder: Folder? { 24 | try? Folder(path: Self.testDirPath.appendingComponent("Output").absoluteString) 25 | } 26 | 27 | private var outputFile: File? { 28 | try? outputFolder?.file(named: "styles.css") 29 | } 30 | 31 | override func setUp() { 32 | try? outputFolder?.delete() 33 | } 34 | 35 | override func tearDown() { 36 | try? outputFolder?.delete() 37 | try? Folder(path: Self.testDirPath.appendingComponent(".publish").absoluteString).delete() 38 | } 39 | 40 | func testCompileSassCustomOptions() throws { 41 | try Web().publish(at: Self.testDirPath, using: [ 42 | .installPlugin( 43 | .compileSass(sassFilePath: sass, cssFilePath: css, compressed: false) 44 | ) 45 | ]) 46 | 47 | let cssOutput = try outputFile?.readAsString() 48 | XCTAssertEqual(cssOutput, """ 49 | body { 50 | color: blue; 51 | } 52 | 53 | """) 54 | } 55 | 56 | func testCompileSassCompressed() throws { 57 | try Web().publish(at: Self.testDirPath, using: [ 58 | .installPlugin( 59 | .compileSass(sassFilePath: sass, cssFilePath: css, compressed: true) 60 | ) 61 | ]) 62 | 63 | let cssOutput = try outputFile?.readAsString() 64 | XCTAssertEqual(cssOutput, """ 65 | body{color:blue} 66 | 67 | """) 68 | } 69 | 70 | static var allTests = [ 71 | ("testCompileSassCustomOptions", testCompileSassCustomOptions), 72 | ("testCompileSassCompressed", testCompileSassCompressed), 73 | ] 74 | } 75 | 76 | private struct Web: Website { 77 | var url = URL(string: "http://httpbin.org")! 78 | var name = "test" 79 | var description = "" 80 | var language: Language = .english 81 | var imagePath: Path? = nil 82 | 83 | enum SectionID: String, WebsiteSectionID { 84 | case test 85 | } 86 | 87 | struct ItemMetadata: WebsiteItemMetadata { 88 | } 89 | } 90 | --------------------------------------------------------------------------------