Section 8/171 menit

8. Tuist Plugins

8. Tuist Plugins

Apa Itu Tuist Plugins

Plugin Tuist memperluas kemampuan Tuist dengan:

  • Task baru yang bisa dijalankan via tuist run
  • Template tambahan
  • ProjectDescriptionHelpers yang bisa di-share antar project (via SPM)

Membuat Plugin

swift
// Struktur plugin
my-tuist-plugin/
├── Package.swift
├── ProjectDescriptionHelpers/
│   └── Target+Company.swift     ← shared helpers
├── Templates/
│   └── microfeature/
│       ├── template.swift
│       └── ...
└── Tasks/
    └── GenerateMocks.swift       ← custom tuist task
swift
// my-tuist-plugin/Package.swift
// @preconcurrency
import PackageDescription

let package = Package(
    name: "MyTuistPlugin",
    products: [
        .library(
            name: "MyTuistPlugin",
            targets: ["MyTuistPlugin"]
        ),
    ],
    dependencies: [
        .package(url: "https://github.com/tuist/ProjectDescription", from: "4.0.0"),
    ],
    targets: [
        .target(
            name: "MyTuistPlugin",
            dependencies: ["ProjectDescription"]
        ),
    ]
)

Menggunakan Plugin Eksternal

swift
// Tuist/Config.swift
import ProjectDescription

let config = Config(
    plugins: [
        .git(
            url: "https://github.com/company/company-tuist-plugin",
            tag: "1.2.0"
        ),
        .local(path: "../shared-tuist-plugin"),  // plugin lokal di monorepo
    ]
)
swift
// Projects/Features/FeatureHome/Project.swift
// Import helpers dari plugin
import ProjectDescription
import MyTuistPlugin  // dari plugin

let project = Project.microFeature(  // custom method dari plugin
    name: "FeatureHome",
    dependencies: [.core("NetworkKit")]
)

Custom Task Plugin

swift
// my-tuist-plugin/Tasks/GenerateMocks.swift
import Foundation
import TSCBasic
import TuistPluginHelpers

// Task yang bisa dipanggil: tuist run generate-mocks
struct GenerateMocksTask: TuistTask {

    var name: String { "generate-mocks" }
    var description: String { "Generate mock files menggunakan Mockolo" }

    func run(arguments: [String]) throws {
        // Install Mockolo jika belum ada
        guard which("mockolo") != nil else {
            print("Installing Mockolo...")
            try Process.run(
                "/opt/homebrew/bin/brew",
                arguments: ["install", "mockolo"]
            ).waitUntilExit()
            return
        }

        // Run Mockolo untuk generate mocks
        let sourceFiles = try findSwiftFiles(in: "Sources")
        try Process.run(
            "mockolo",
            arguments: [
                "--sourcedirs", sourceFiles.joined(separator: ","),
                "--destination", "Sources/Mocks/Generated/",
                "--testable-imports", "MyApp",
            ]
        ).waitUntilExit()

        print("✅ Mocks generated successfully")
    }
}