### Example of Creating a Custom Library Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/library.md Demonstrates how to instantiate a `Library` object with specific details for a custom package. ```swift let customLibrary = Library( name: "CustomPackage", url: "https://github.com/example/custom-package.git", licenseBody: "MIT License text here..." ) ``` -------------------------------- ### UIKit Integration Example Source: https://github.com/cybozu/licenselist/blob/main/README.md Demonstrates how to present the LicenseListViewController in a UIKit application. Use .withRepositoryAnchorLink to include links to the repository. ```swift import LicenseList // in ViewController let vc = LicenseListViewController() vc.title = "LICENSE" // If you want to anchor link of the repository vc.licenseViewStyle = .withRepositoryAnchorLink navigationController?.pushViewController(vc, animated: true) ``` -------------------------------- ### LicenseListViewController viewDidLoad Method Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-list-view-controller.md Explains the internal setup performed by viewDidLoad, including view creation and layout. ```APIDOC ## Methods ### viewDidLoad() #### Description Called after the controller's view is loaded into memory. #### Behavior - Creates a `LicenseListView` with a navigation handler - Embeds the SwiftUI view using UIHostingController - Sets up Auto Layout constraints to fill the view controller's view - Configures navigation to push license details when a library is selected ``` -------------------------------- ### SwiftUI Navigation Example Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-list-view.md Demonstrates how to use LicenseListView within a SwiftUI NavigationView for standard navigation. ```swift import SwiftUI import LicenseList struct ContentView: View { var body: some View { NavigationView { LicenseListView() .navigationTitle("Licenses") } } } ``` -------------------------------- ### LicenseListViewController Usage Example Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-list-view-controller.md A comprehensive example demonstrating how to integrate LicenseListViewController into an iOS application's scene delegate. ```APIDOC ## Usage Example ```swift import UIKit import LicenseList class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? func scene( _ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions ) { guard let windowScene = (scene as? UIWindowScene) else { return } let licenseVC = LicenseListViewController() licenseVC.title = "Licenses" licenseVC.licenseViewStyle = .withRepositoryAnchorLink let navController = UINavigationController(rootViewController: licenseVC) let window = UIWindow(windowScene: windowScene) window.rootViewController = navController self.window = window window.makeKeyAndVisible() } } ``` ``` -------------------------------- ### Manual UINavigationController Navigation Example Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-list-view.md Shows how to implement manual navigation using a UINavigationController with the navigationHandler closure. ```swift import SwiftUI import LicenseList struct ContentView: View { var body: some View { LicenseListView { selectedLibrary in // Handle navigation manually let licenseVC = UIHostingController(rootView: LicenseView(library: selectedLibrary)) navigationController?.pushViewController(licenseVC, animated: true) } } } ``` -------------------------------- ### LicenseView Style Example Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-view.md An example of applying a specific license view style, `.withRepositoryAnchorLink`, to a LicenseView instance. This customizes how the license is presented. ```swift LicenseView(library: library) .licenseViewStyle(.withRepositoryAnchorLink) ``` -------------------------------- ### Instantiate and Run SourcePackagesParser Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/source-packages-parser.md Example of how to instantiate and run the SourcePackagesParser. This is typically invoked from the spp CLI tool. Ensure paths are correctly specified. ```swift // Typically invoked from the spp CLI tool let parser = SourcePackagesParser( "/path/to/output", "/path/to/SourcePackages" ) try parser.run() ``` -------------------------------- ### Configuring License List View Style Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-list-view-controller.md Example demonstrating how to set the `licenseListViewStyle` property to customize the appearance of the license list. ```swift let vc = LicenseListViewController() vc.licenseListViewStyle = .plain navigationController?.pushViewController(vc, animated: true) ``` -------------------------------- ### Example: Full License List View Controller Configuration Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/configuration.md Demonstrates configuring both the list and individual view styles, then presenting the view controller within a navigation controller. ```swift import UIKit import LicenseList class MyViewController: UIViewController { func presentLicenseList() { let licenseVC = LicenseListViewController() // Configure appearance licenseVC.title = "Third-Party Licenses" licenseVC.licenseListViewStyle = .plain licenseVC.licenseViewStyle = .withRepositoryAnchorLink // Present in navigation navigationController?.pushViewController(licenseVC, animated: true) } } ``` -------------------------------- ### Setting up LicenseListViewController in SceneDelegate Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-list-view-controller.md Example of how to integrate LicenseListViewController into an iOS application's window setup within the SceneDelegate. This includes setting a title and a custom license view style. ```swift import UIKit import LicenseList class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? func scene( _ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions ) { guard let windowScene = (scene as? UIWindowScene) else { return } let licenseVC = LicenseListViewController() licenseVC.title = "Licenses" licenseVC.licenseViewStyle = .withRepositoryAnchorLink let navController = UINavigationController(rootViewController: licenseVC) let window = UIWindow(windowScene: windowScene) window.rootViewController = navController self.window = window window.makeKeyAndVisible() } } ``` -------------------------------- ### Example Usage of Collection Number of Digits Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/extension-apis.md Illustrates how to use the numberOfDigits property with examples showing different collection sizes and their resulting digit counts. ```swift let libraries = [lib1, lib2, lib3, ..., lib999] // 999 items let digits = libraries.numberOfDigits // Returns 3 let items = [a, b] // 2 items let digits = items.numberOfDigits // Returns 1 ``` -------------------------------- ### Presenting License List Programmatically Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-list-view-controller.md Example of how to instantiate and present LicenseListViewController from a UIButton action. Ensure UIKit and LicenseList are imported. ```swift import UIKit import LicenseList class MyViewController: UIViewController { @IBAction func showLicenses(_ sender: UIButton) { let licenseVC = LicenseListViewController() licenseVC.title = "Open Source Licenses" navigationController?.pushViewController(licenseVC, animated: true) } } ``` -------------------------------- ### Example: Using Environment Variable for SourcePackages Path Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/prepare-license-list-plugin.md Demonstrates how to specify a custom path for the SourcePackages directory using the -PLL_SOURCE_PACKAGES_PATH build argument, typically in a CI environment. ```bash # In CI environment with non-default SourcePackages location xcodebuild \ -PLL_SOURCE_PACKAGES_PATH /absolute/path/to/SourcePackages \ -scheme MyApp \ -configuration Release ``` -------------------------------- ### Swift Package Manager - Package.swift Configuration Source: https://github.com/cybozu/licenselist/blob/main/README.md Example of how to configure your Package.swift file to include LicenseList as a dependency. ```swift // swift-tools-version: 6.2 import PackageDescription let package = Package( name: "SomeProduct", products: [ .library(name: "SomeProduct", targets: ["SomeProduct"]) ], dependencies: [ .package(url: "https://github.com/cybozu/LicenseList.git", exact: "x.y.z") ], targets: [ .target( name: "SomeProduct", dependencies: [ .product(name: "LicenseList", package: "LicenseList") ] ) ] ) ``` -------------------------------- ### Configuring Individual License View Style Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-list-view-controller.md Example demonstrating how to set the `licenseViewStyle` property to customize the appearance of individual license views. ```swift let vc = LicenseListViewController() vc.licenseViewStyle = .withRepositoryAnchorLink navigationController?.pushViewController(vc, animated: true) ``` -------------------------------- ### Configure Target Dependencies for Build Plugin Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/configuration.md Example of how to correctly define target dependencies in Package.swift. Note that the PrepareLicenseList plugin is automatically applied and does not require an explicit 'plugins' line. ```swift .target( name: "MyApp", dependencies: [.product(name: "LicenseList", package: "LicenseList")] // plugins line not needed; PrepareLicenseList is automatic ) ``` -------------------------------- ### LicenseListViewController viewDidLoad Behavior Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-list-view-controller.md Illustrates the internal setup performed by `viewDidLoad`, including creating the `LicenseListView`, embedding it in a `UIHostingController`, and setting up Auto Layout constraints. ```swift public override func viewDidLoad() ``` -------------------------------- ### Example Serialized Workspace State JSON Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/internal-structures.md Illustrates the JSON format of the workspace-state.json file, showing nested dependency information and package metadata. ```json { "object": { "dependencies": [ { "packageRef": { "identity": "alamofire", "kind": "remote", "location": "https://github.com/Alamofire/Alamofire.git", "name": "Alamofire" } }, { "packageRef": { "identity": "rxswift", "kind": "remote", "location": "https://github.com/ReactiveX/RxSwift.git", "name": "RxSwift" } } ] }, "version": 6 } ``` -------------------------------- ### Handle SourcePackagesNotFoundError Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/errors.md Demonstrates how to catch and handle the SourcePackagesNotFoundError in a do-catch block. This is useful for providing user feedback or guiding environment variable setup when the error occurs. ```swift do { let sourcePackagesURL = try plugin.sourcePackages(workDir) } catch is SourcePackagesNotFoundError { print("Error: SourcePackages not found") // Provide guidance for environment variable setup } ``` -------------------------------- ### Swift Function Signature Example Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/README.md Illustrates the expected format for public function signatures, including parameter types and return types. ```swift public func makeBody(configuration: Configuration) -> Body ``` -------------------------------- ### SwiftUI Integration Example Source: https://github.com/cybozu/licenselist/blob/main/README.md Shows how to embed LicenseListView within a SwiftUI NavigationView. The .withRepositoryAnchorLink modifier adds repository anchor links. ```swift import LicenseList struct ContentView: View { var body: some View { NavigationView { LicenseListView() // If you want to anchor link of the repository .licenseViewStyle(.withRepositoryAnchorLink) .navigationTitle("LICENSE") } } } ``` -------------------------------- ### Usage of PlainLicenseListViewStyle Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-list-view-style.md Example of applying the plain license list view style to a LicenseListView within a NavigationView. ```swift import SwiftUI import LicenseList struct ContentView: View { var body: some View { NavigationView { LicenseListView() .licenseListViewStyle(.plain) .navigationTitle("Licenses") } } } ``` -------------------------------- ### Documentation Dependency Map Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/MANIFEST.md Illustrates the hierarchical structure and dependencies between different documentation files within the project, starting from the README.md. ```text README.md (START HERE) ↓ INDEX.md (Architecture overview) ├→ api-reference/* (Implementation details) ├→ types.md (Type reference) ├→ configuration.md (Setup) ├→ errors.md (Troubleshooting) └→ extension-apis.md (Utilities) ``` -------------------------------- ### LicenseView Example Usage Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-view.md Demonstrates how to use the LicenseView within a SwiftUI view hierarchy, setting a navigation title based on the library's name. Requires importing SwiftUI and LicenseList. ```swift import SwiftUI import LicenseList struct LicenseDetailView: View { let library: Library var body: some View { LicenseView(library: library) .navigationTitle(library.name) } } ``` -------------------------------- ### Custom License List View Style Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/types.md Example of a custom style conforming to `LicenseListViewStyle`. It adds a header and uses a default style for the license list itself. ```swift struct CustomListStyle: LicenseListViewStyle { func makeBody(configuration: Configuration) -> some View { VStack { Text("Available Licenses") .font(.headline) PlainLicenseListViewStyle().makeBody(configuration: configuration) } } } LicenseListView() .licenseListViewStyle(CustomListStyle()) ``` -------------------------------- ### Usage of DefaultLicenseListViewStyle (.automatic) Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-list-view-style.md Example of applying the default (automatic) license list view style. This is typically used when no explicit style is needed. ```swift import SwiftUI import LicenseList struct ContentView: View { var body: some View { NavigationView { LicenseListView() .licenseListViewStyle(.automatic) .navigationTitle("Licenses") } } } ``` -------------------------------- ### LicenseListViewController Component Documentation Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/MANIFEST.md Details the documentation completeness for the LicenseListViewController (UIKit) component, including type definition, initializers, properties, lifecycle methods, internal navigation logic, configuration examples, and usage patterns. ```APIDOC ### LicenseListViewController (UIKit) - ✓ Type definition - ✓ Initializers - ✓ Properties (licenseListViewStyle, licenseViewStyle) - ✓ Lifecycle methods (viewDidLoad) - ✓ Internal navigation logic - ✓ Configuration examples - ✓ Usage patterns ``` -------------------------------- ### Custom License View Style Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/types.md Example of a custom style conforming to `LicenseViewStyle`. It displays the library name as a headline and the attributed license body in a scrollable view. ```swift struct CustomLicenseStyle: LicenseViewStyle { func makeBody(configuration: Configuration) -> some View { VStack(alignment: .leading) { Text("License for \(configuration.library.name)") .font(.headline) ScrollView { Text(configuration.attributedLicenseBody) .font(.caption) } } } } LicenseView(library: library) .licenseViewStyle(CustomLicenseStyle()) ``` -------------------------------- ### Custom License View Style Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/view-modifiers.md Example of creating a custom LicenseViewStyle to define a unique appearance for license details, including custom fonts and layout. ```swift struct MinimalLicenseStyle: LicenseViewStyle { func makeBody(configuration: Configuration) -> some View { VStack(alignment: .leading, spacing: 16) { Text(configuration.library.name) .font(.title2) .bold() ScrollView { Text(configuration.attributedLicenseBody) .font(.caption) .lineLimit(nil) } if let url = configuration.library.url { Link("View Repository", destination: url) .frame(maxWidth: .infinity) .padding() .background(Color.blue) .foregroundColor(.white) } } .padding() } } LicenseView(library: library) .licenseViewStyle(MinimalLicenseStyle()) ``` -------------------------------- ### LicenseListView Component Documentation Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/MANIFEST.md Details the documentation completeness for the LicenseListView component, including type definition, initializer, body property, view modifiers, environment integration, behavior, usage examples, and accessibility features. ```APIDOC ### LicenseListView - ✓ Type definition - ✓ Initializer with parameters - ✓ Body property - ✓ View modifiers - ✓ Environment integration - ✓ Behavior description - ✓ Usage examples - ✓ Accessibility features ``` -------------------------------- ### Library Component Documentation Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/MANIFEST.md Details the documentation completeness for the Library component, including type definition, initializers, properties, static methods, conformances, usage examples, and source location. ```APIDOC ## Documentation Completeness per Component ### Library - ✓ Type definition - ✓ All initializers - ✓ All properties (name, url, licenseBody, id) - ✓ Static methods (libraries property) - ✓ Conformances (Identifiable, Hashable, Sendable) - ✓ Usage examples - ✓ Source location ``` -------------------------------- ### Style Protocols Component Documentation Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/MANIFEST.md Details the documentation completeness for Style Protocols, including protocol requirements, configuration types, conforming implementations, style accessor methods, behavior documentation, and customization examples. ```APIDOC ### Style Protocols - ✓ Protocol requirements - ✓ Configuration types - ✓ All conforming implementations - ✓ Style accessor methods - ✓ Behavior documentation - ✓ Customization examples ``` -------------------------------- ### LicenseView Component Documentation Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/MANIFEST.md Details the documentation completeness for the LicenseView component, including type definition, initializer, body property, view modifiers, URL detection, environment integration, usage examples, and accessibility features. ```APIDOC ### LicenseView - ✓ Type definition - ✓ Initializer with parameters - ✓ Body property - ✓ View modifiers - ✓ URL detection mechanism - ✓ Environment integration - ✓ Usage examples - ✓ Accessibility features ``` -------------------------------- ### Initializer for Library Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/library.md Creates a new Library instance with manually provided details. Ensure all parameters are correctly formatted. ```swift public init(name: String, url: String, licenseBody: String) ``` -------------------------------- ### Basic License View Usage Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-view-style.md Demonstrates how to create and display a `LicenseView` using the automatic style. Ensure `SwiftUI` and `LicenseList` are imported. ```swift import SwiftUI import LicenseList let library = Library.libraries.first! LicenseView(library: library) .licenseViewStyle(.automatic) ``` -------------------------------- ### LicenseListViewController Initialization Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-list-view-controller.md Demonstrates how to create and present a LicenseListViewController, including setting its title and navigation. ```APIDOC ## init() ### Description Creates a new license list view controller. ### Method `init()` ### Returns A new `LicenseListViewController` instance. ### Example ```swift import UIKit import LicenseList class MyViewController: UIViewController { @IBAction func showLicenses(_ sender: UIButton) { let licenseVC = LicenseListViewController() licenseVC.title = "Open Source Licenses" navigationController?.pushViewController(licenseVC, animated: true) } } ``` ``` -------------------------------- ### makeBuildCommand(executableURL:sourcePackagesURL:outputURL:) Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/prepare-license-list-plugin.md Creates a build command that invokes the `spp` executable to process license information. ```APIDOC ## makeBuildCommand(executableURL:sourcePackagesURL:outputURL:) ### Description Creates a build command that invokes the `spp` executable. ### Method func makeBuildCommand( executableURL: URL, sourcePackagesURL: URL, outputURL: URL ) -> Command ### Parameters #### Path Parameters - **executableURL** (URL) - Required - The path to the `spp` executable - **sourcePackagesURL** (URL) - Required - The path to the SourcePackages directory - **outputURL** (URL) - Required - The path where LicenseList.swift should be written ### Returns A `Command` object representing the build command ### Generated Command Arguments: ``` spp ``` ``` -------------------------------- ### createBuildCommands(context:target:) Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/prepare-license-list-plugin.md The main entry point for the Swift Package Plugin system. It creates and returns build commands necessary for the target. ```APIDOC ## createBuildCommands(context:target:) ### Description The main entry point called by the Swift Package Plugin system. Creates build commands for a target. ### Method func createBuildCommands(context: PluginContext, target: Target) async throws -> [Command] ### Parameters #### Path Parameters - **context** (PluginContext) - Required - The plugin execution context provided by SPM - **target** (Target) - Required - The build target being processed ### Returns An array of Command objects to execute during the build ### Throws Any error from locating SourcePackages or constructing the build command ### Behavior 1. Resolves the `spp` executable path from the plugin context 2. Locates the SourcePackages directory 3. Creates a build command that outputs to `/LicenseList.swift` 4. Returns the command for execution by the build system ``` -------------------------------- ### Execute SourcePackagesParser with Error Handling Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/source-packages-parser.md Demonstrates how to execute the SourcePackagesParser's run method and handle potential SPPError exceptions. This includes reading workspace state, extracting licenses, and writing the output file. ```swift do { let parser = SourcePackagesParser(outputPath, sourcePackagesPath) try parser.run() print("License list generated successfully") } catch let error as SPPError { print("Error: (error)") } ``` -------------------------------- ### Library Initializer Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/library.md Creates a new Library instance with manually specified information for a Swift Package dependency. ```APIDOC ## init(name:url:licenseBody:) ### Description Creates a library with manually specified information. ### Parameters #### Path Parameters - **name** (String) - Required - The name of the library - **url** (String) - Required - The repository URL as a string - **licenseBody** (String) - Required - The full text of the license ### Returns A new `Library` instance ### Example ```swift let customLibrary = Library( name: "CustomPackage", url: "https://github.com/example/custom-package.git", licenseBody: "MIT License text here..." ) ``` ``` -------------------------------- ### Build with PLL_SOURCE_PACKAGES_PATH in Local CI Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/configuration.md Set up a local CI script to resolve Swift packages and then build the project with an explicitly defined PLL_SOURCE_PACKAGES_PATH. This ensures consistent builds outside of standard project structures. ```bash #!/bin/bash set -e # Resolve packages swift package resolve # Build with explicit SourcePackages path export PLL_SOURCE_PACKAGES_PATH="$(pwd)/.build/checkouts" xcodebuild -scheme MyApp -configuration Release echo "Build completed successfully" ``` -------------------------------- ### Configure License List View Style Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/configuration.md Set the appearance and behavior of the license list view. Use `.plain` for a simple list style. ```swift import UIKit import LicenseList let vc = LicenseListViewController() vc.title = "Open Source Licenses" vc.licenseListViewStyle = .plain ``` -------------------------------- ### Main Entry Point for Build Commands Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/prepare-license-list-plugin.md The primary method called by the Swift Package Plugin system to create build commands for a target. It resolves the 'spp' executable, locates SourcePackages, and generates the necessary build command. ```swift func createBuildCommands(context: PluginContext, target: Target) async throws -> [Command] ``` -------------------------------- ### Manually Add Custom Libraries Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/configuration.md Demonstrates how to manually add custom libraries to the LicenseList, combining them with auto-collected libraries. Ensure the LicenseList framework is imported. ```swift import LicenseList // Get auto-collected libraries let autoLibraries = Library.libraries // Add custom libraries let customLibrary = Library( name: "CustomFramework", url: "https://github.com/example/custom-framework.git", licenseBody: """ MIT License Copyright (c) 2024 Example Corp ... """ ) // Combine let allLibraries = autoLibraries + [customLibrary] ``` -------------------------------- ### Check SourcePackages Directory Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/configuration.md Verify the presence of the SourcePackages directory. This is crucial if you encounter 'SourcePackages not found' errors. ```bash ls -la .build/checkouts ``` -------------------------------- ### Applying License View Styles Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-view-style.md Shows how to apply different predefined license view styles using the `licenseViewStyle` modifier. This includes applying a style to a single view, a hierarchy of views, and demonstrating a custom style implementation. ```swift LicenseView(library: library) .licenseViewStyle(.plain) // Apply to a hierarchy VStack { ForEach(Library.libraries) { library in LicenseView(library: library) } } .licenseViewStyle(.withRepositoryAnchorLink) // Custom style implementation struct MyLicenseStyle: LicenseViewStyle { func makeBody(configuration: Configuration) -> some View { VStack { Text("License for \(configuration.library.name)") .font(.headline) ScrollView { Text(configuration.attributedLicenseBody) .padding() } } } } LicenseView(library: library) .licenseViewStyle(MyLicenseStyle()) ``` -------------------------------- ### Configure Individual License View Style Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/configuration.md Control the appearance and behavior of individual license views. Use `.withRepositoryAnchorLink` to include a link to the repository. ```swift import UIKit import LicenseList let vc = LicenseListViewController() vc.licenseViewStyle = .withRepositoryAnchorLink navigationController?.pushViewController(vc, animated: true) ``` -------------------------------- ### Build Plugin Component Documentation Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/MANIFEST.md Details the documentation completeness for the Build Plugin, including the main struct and methods, public methods, error conditions, environment variable usage, build command generation, and output file format. ```APIDOC ### Build Plugin - ✓ Main struct and methods - ✓ All public methods documented - ✓ Error conditions - ✓ Environment variable usage - ✓ Build command generation - ✓ Output file format ``` -------------------------------- ### Resolve Swift Packages Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/configuration.md Run this command to fetch package dependencies. Ensure it's executed before checking for the SourcePackages directory. ```bash swift package resolve ``` -------------------------------- ### Create Custom Accessible License View Style Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/view-modifiers.md Define a custom `LicenseViewStyle` that respects user accessibility preferences, such as dynamic type size. This example demonstrates using `@Environment(\.sizeCategory)` to adjust the font size of the license body text. ```swift struct AccessibleLicenseStyle: LicenseViewStyle { @Environment(\.sizeCategory) var sizeCategory func makeBody(configuration: Configuration) -> some View { ScrollView { Text(configuration.attributedLicenseBody) .font(.system(.body, design: .default)) .accessibility(label: Text("License for \(configuration.library.name)")) } } } ``` -------------------------------- ### Create Build Command for spp Executable Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/prepare-license-list-plugin.md Constructs a build command to invoke the 'spp' executable, specifying the output path, SourcePackages directory, and executable path. ```swift func makeBuildCommand( executableURL: URL, sourcePackagesURL: URL, outputURL: URL ) -> Command ``` -------------------------------- ### Development Build Configuration Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/configuration.md Standard development build using Xcode. The plugin automatically detects SourcePackages, so no special configuration is typically needed. ```bash # Standard development build xcodebuild -scheme MyApp -configuration Debug # No special configuration needed; plugin auto-detects SourcePackages ``` -------------------------------- ### LicenseView Initialization Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-view.md Creates a new license view for the specified library. ```APIDOC ## init(library:) ### Description Creates a new license view for the specified library. ### Parameters #### Path Parameters - **library** (Library) - Required - The library whose license text should be displayed ### Returns A new `LicenseView` instance ### Example ```swift import SwiftUI import LicenseList struct LicenseDetailView: View { let library: Library var body: some View { LicenseView(library: library) .navigationTitle(library.name) } } ``` ``` -------------------------------- ### LicenseListView Initialization Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-list-view.md Initializes a LicenseListView. You can optionally provide a navigation handler for custom navigation logic when a library is selected. ```APIDOC ## init(navigationHandler:) ### Description Creates a new license list view with an optional navigation handler. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Required | Default | Description | |---|---|---|---|---| | navigationHandler | ((Library) -> Void)? | No | nil | A closure invoked when a library is selected; used for manual navigation control with UINavigationController | ### Response None ### Request Example (SwiftUI Navigation) ```swift import SwiftUI import LicenseList struct ContentView: View { var body: some View { NavigationView { LicenseListView() .navigationTitle("Licenses") } } } ``` ### Request Example (UINavigationController Manual Control) ```swift import SwiftUI import LicenseList struct ContentView: View { var body: some View { LicenseListView { selectedLibrary in // Handle navigation manually let licenseVC = UIHostingController(rootView: LicenseView(library: selectedLibrary)) navigationController?.pushViewController(licenseVC, animated: true) } } } ``` ``` -------------------------------- ### Applying License View Styles Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-view-style.md Demonstrates how to apply different license view styles to a `LicenseView` using the `licenseViewStyle(_:)` modifier, including applying styles to a hierarchy and implementing custom styles. ```APIDOC ## Applying License View Styles Apply styles using the `licenseViewStyle(_:)` modifier: ```swift LicenseView(library: library) .licenseViewStyle(.plain) // Apply to a hierarchy VStack { ForEach(Library.libraries) { library in LicenseView(library: library) } } .licenseViewStyle(.withRepositoryAnchorLink) // Custom style implementation struct MyLicenseStyle: LicenseViewStyle { func makeBody(configuration: Configuration) -> some View { VStack { Text("License for \(configuration.library.name)") .font(.headline) ScrollView { Text(configuration.attributedLicenseBody) .padding() } } } } LicenseView(library: library) .licenseViewStyle(MyLicenseStyle()) ``` ``` -------------------------------- ### Testing Build Configuration Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/configuration.md Configuration for running tests, ensuring the correct SourcePackages path is exported for deterministic builds. ```bash # Test configuration export PLL_SOURCE_PACKAGES_PATH="$(pwd)/.build/checkouts" xcodebuild test -scheme MyAppTests -configuration Debug ``` -------------------------------- ### LicenseViewStyleConfiguration Struct Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/types.md Configuration data passed to `LicenseViewStyle.makeBody(configuration:)`. It holds information about the library, license text, and URL handling. ```APIDOC ## LicenseViewStyleConfiguration Struct ### Description Configuration data passed to `LicenseViewStyle.makeBody(configuration:)`. ### Properties - **library** (Library) - The library whose license is being displayed - **numberOfLines** (Int) - Count of lines in the license body (derived from newline separators) - **attributedLicenseBody** (AttributedString) - License text with URLs converted to interactive links - **openURL** ((URL) -> Void) - Closure to open URLs in the system handler ``` -------------------------------- ### Applying License List View Styles Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-list-view-style.md Demonstrates how to apply predefined and custom styles to a LicenseListView using the licenseListViewStyle modifier. ```swift LicenseListView() .licenseListViewStyle(.plain) // Or with a custom style struct CustomListStyle: LicenseListViewStyle { func makeBody(configuration: Configuration) -> some View { VStack { Text("Custom Header") PlainLicenseListViewStyle().makeBody(configuration: configuration) } } } LicenseListView() .licenseListViewStyle(CustomListStyle()) ``` -------------------------------- ### PlainLicenseViewStyle Usage Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-view-style.md Demonstrates how to apply the plain license view style to a LicenseView. Ensure LicenseList is imported. ```swift import SwiftUI import LicenseList struct ContentView: View { let library = Library.libraries.first! var body: some View { LicenseView(library: library) .licenseViewStyle(.plain) } } ``` -------------------------------- ### Plugin Build Command Arguments Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/internal-structures.md Specifies the two required arguments for the plugin build command: the absolute path to the output directory and the SourcePackages directory. ```shell [ , ] ``` -------------------------------- ### Swift Package.swift Configuration for LicenseList Plugin Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/prepare-license-list-plugin.md Configure your Package.swift to include LicenseList as a dependency. The PrepareLicenseList plugin is automatically invoked by Xcode. ```swift .target( name: "MyApp", dependencies: [ .product(name: "LicenseList", package: "LicenseList") ], plugins: [] // PrepareLicenseList is automatic ) ``` -------------------------------- ### Plugin Build Command Output File Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/internal-structures.md Declares the single output file for the plugin build command, which is 'LicenseList.swift' located in the plugin's work directory. This file is used for build validation, caching, and dependency tracking. ```shell /LicenseList.swift ``` -------------------------------- ### Create and Apply Custom License List Style Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/view-modifiers.md Defines and applies a custom style to a LicenseListView. This allows for unique layouts and presentation of library information. ```swift struct SectionedListStyle: LicenseListViewStyle { func makeBody(configuration: Configuration) -> some View { VStack { Text("Installed Libraries") .font(.headline) .padding() PlainLicenseListViewStyle() .makeBody(configuration: configuration) } } } LicenseListView() .licenseListViewStyle(SectionedListStyle()) ``` -------------------------------- ### Find License Files in Dependencies Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/configuration.md Search for files named LICENSE or LICENCE within the build checkouts directory. This helps diagnose issues with license file detection. ```bash find .build/checkouts -name "*LICENSE*" -o -name "*LICENCE*" ``` -------------------------------- ### SourcePackagesParser Initializer Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/source-packages-parser.md Creates a new SourcePackagesParser instance. Specify the file system paths for the output file and the SourcePackages directory. ```swift init(_ outputPath: String, _ sourcePackagesPath: String) ``` -------------------------------- ### Apply Custom LicenseList Style Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/extension-apis.md Demonstrates how to apply the custom `.licenseList` style to a SwiftUI List in the `LicenseListContainer` view. ```swift import SwiftUI import LicenseList struct LicenseListContainer: View { var body: some View { List { ForEach(Library.libraries) { library in NavigationLink(library.name) { LicenseView(library: library) } } } .listStyle(.licenseList) } } ``` -------------------------------- ### Plugin Build Command Structure Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/internal-structures.md Defines the structure for a build command used by the plugin. It requires a display name, executable URL, arguments, and output files. ```swift .buildCommand( displayName: "Prepare LicenseList", executable: URL, arguments: [String], outputFiles: [URL] ) ``` -------------------------------- ### LicenseListViewStyleConfiguration Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-list-view-style.md Configuration data passed to the `makeBody(configuration:)` method, containing libraries, a navigation handler, and the style for individual license views. ```APIDOC ## LicenseListViewStyleConfiguration Configuration data passed to `makeBody(configuration:)`. ```swift public struct LicenseListViewStyleConfiguration { public var libraries: [Library] public var navigationHandler: ((Library) -> Void)? public var licenseViewStyle: any LicenseViewStyle } ``` #### Properties - libraries ([Library]): Array of library information to display - navigationHandler (((Library) -> Void)?): Optional closure invoked when a library is selected; used for manual navigation with UINavigationController - licenseViewStyle (any LicenseViewStyle): The style conforming to LicenseViewStyle applied to license views ``` -------------------------------- ### CI/CD Build Plugin Configuration Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/README.md Configure the build plugin for CI/CD environments with non-standard project layouts. Ensure SourcePackages path is correctly exported. ```bash export PLL_SOURCE_PACKAGES_PATH=/absolute/path/to/SourcePackages xcodebuild -scheme MyApp ``` -------------------------------- ### PrepareLicenseList Struct Definition Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/prepare-license-list-plugin.md Defines the structure of the PrepareLicenseList build tool plugin, conforming to the BuildToolPlugin protocol. ```swift struct PrepareLicenseList: BuildToolPlugin { func existsSourcePackages(in url: URL) throws -> Bool func sourcePackages(_ pluginWorkDirectory: URL) throws -> URL func makeBuildCommand( executableURL: URL, sourcePackagesURL: URL, outputURL: URL ) -> Command func createBuildCommands(context: PluginContext, target: Target) async throws -> [Command] } ``` -------------------------------- ### UIKit Integration with licenseViewStyle Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/view-modifiers.md Demonstrates how to apply a license view style when integrating SwiftUI views into a UIKit application. ```swift import UIKit import LicenseList class ViewController: UIViewController { func showLicenseDetail(_ library: Library) { let licenseView = LicenseView(library: library) .licenseViewStyle(.withRepositoryAnchorLink) let hostingController = UIHostingController(rootView: licenseView) navigationController?.pushViewController(hostingController, animated: true) } } ``` -------------------------------- ### LicenseView Initializer Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-view.md Initializes a new LicenseView with a specific library. This is used to create an instance of the view for displaying a particular library's license. ```swift public init(library: Library) ``` -------------------------------- ### LicenseListViewController Initializer Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-list-view-controller.md Creates a new instance of LicenseListViewController. This is the primary initializer for programmatic use. ```swift public init() ``` -------------------------------- ### Production Release Build Configuration Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/configuration.md Build for production release with explicit paths for SourcePackages to ensure reliability. This configuration is recommended for final deployments. ```bash # Production build with explicit paths for reliability export PLL_SOURCE_PACKAGES_PATH="$(pwd)/.build/checkouts" xcodebuild -scheme MyApp -configuration Release -archivePath "build/MyApp.xcarchive" ``` -------------------------------- ### sourcePackages(_:) Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/prepare-license-list-plugin.md Locates the SourcePackages directory. It first checks the PLL_SOURCE_PACKAGES_PATH environment variable, and if not set, searches upward from the plugin work directory. ```APIDOC ## sourcePackages(_:) ### Description Locates the SourcePackages directory, either from an environment variable or by searching upward from the plugin work directory. ### Method func sourcePackages(_ pluginWorkDirectory: URL) throws -> URL ### Parameters #### Path Parameters - **pluginWorkDirectory** (URL) - Required - The plugin's working directory as provided by the plugin context ### Returns The URL of the SourcePackages directory ### Throws `SourcePackagesNotFoundError` if SourcePackages cannot be located ### Behavior 1. First checks the `PLL_SOURCE_PACKAGES_PATH` environment variable 2. If not set, searches upward from the plugin work directory 3. Stops when a directory containing SourcePackages is found 4. Returns the path `/SourcePackages` ### Example - Using Environment Variable: ```bash # In CI environment with non-default SourcePackages location xcodebuild \ -PLL_SOURCE_PACKAGES_PATH /absolute/path/to/SourcePackages \ -scheme MyApp \ -configuration Release ``` ``` -------------------------------- ### SourcePackagesParser Run Method Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/source-packages-parser.md Executes the parsing pipeline of the SourcePackagesParser. This method handles loading workspace state, extracting library information, and exporting the license list. ```swift func run() throws ``` -------------------------------- ### Set SourcePackages Path with Build Arguments Source: https://github.com/cybozu/licenselist/blob/main/Sources/LicenseList/Documentation.docc/Articles/HowLicenseListWorks.md Configure SourcePackages path by using both -derivedDataPath and -clonedSourcePackagesDirPath build arguments. Ensure SourcePackages resides within the DerivedData directory for LicenseList to function correctly. ```sh xcodebuild clean build \ -project Examples/Examples.xcodeproj \ -scheme ExamplesForSwiftUI \ -destination "platform=iOS Simulator,name=iPhone 16,OS=18.5" \ -derivedDataPath ./DerivedData \ -clonedSourcePackagesDirPath ./DerivedData/SourcePackages ``` -------------------------------- ### Configure License List View Style Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/configuration.md Applies a plain style to the LicenseListView and sets a navigation title. This is useful for a simple, selectable list of licenses. ```swift LicenseListView() .licenseListViewStyle(.plain) .navigationTitle("Licenses") ``` -------------------------------- ### LicenseListView Initializer Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-list-view.md Initializes a LicenseListView with an optional navigation handler for custom navigation logic. ```swift public init(navigationHandler: ((Library) -> Void)? = nil) ``` -------------------------------- ### Verify Custom SourcePackages Path Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/configuration.md Check if the custom path for SourcePackages is correctly set in the environment variable and list its contents. ```bash echo $PLL_SOURCE_PACKAGES_PATH ls -la $PLL_SOURCE_PACKAGES_PATH ``` -------------------------------- ### Check Custom Source Packages Path Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/errors.md Before running `xcodebuild`, ensure that the `CUSTOM_SOURCE_PACKAGES` environment variable points to a valid directory. If not, print an error and exit. ```bash # Ensure proper environment for non-standard layouts if [[ ! -d "$CUSTOM_SOURCE_PACKAGES" ]]; then echo "Error: Custom SourcePackages path not found" exit 1 fi export PLL_SOURCE_PACKAGES_PATH="$CUSTOM_SOURCE_PACKAGES" xcodebuild -scheme MyApp -configuration Release ``` -------------------------------- ### LicenseViewStyleConfiguration Struct Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-view-style.md Provides configuration data to the `makeBody(configuration:)` method of the `LicenseViewStyle` protocol. It includes details about the library, display properties, and URL handling. ```APIDOC ## LicenseViewStyleConfiguration Configuration data passed to `makeBody(configuration:)`. ```swift public struct LicenseViewStyleConfiguration { public var library: Library public var numberOfLines: Int public var attributedLicenseBody: AttributedString public var openURL: (URL) -> Void } ``` ### Properties - **library** (Library) - The library whose license is being displayed. - **numberOfLines** (Int) - The number of lines in the license body (calculated from line breaks). - **attributedLicenseBody** (AttributedString) - The license text with URLs converted to interactive links. - **openURL** ((URL) -> Void) - A closure to open URLs. ``` -------------------------------- ### Reading License List View Styles Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/internal-structures.md Shows how to read the current license list view style from the SwiftUI environment. This is useful for adapting view behavior based on the set style. ```swift @Environment(\.licenseListViewStyle) var style ``` -------------------------------- ### SwiftUI List View with Repository Anchor Link Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/README.md Integrate LicenseListView into your SwiftUI application. Use the .withRepositoryAnchorLink style to display licenses with links to their repositories. ```swift import SwiftUI import LicenseList struct ContentView: View { var body: some View { NavigationView { LicenseListView() .licenseViewStyle(.withRepositoryAnchorLink) .navigationTitle("Open Source Licenses") } } } ``` -------------------------------- ### Configure License View Style with Repository Link Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/configuration.md Applies a style to LicenseListView that includes a repository anchor link, in addition to the license body and URL links. A navigation title is also set. ```swift LicenseListView() .licenseViewStyle(.withRepositoryAnchorLink) .navigationTitle("Licenses") ``` -------------------------------- ### CI/CD Pipeline Build Configuration Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/configuration.md Build process for a CI/CD pipeline, including code checkout, deterministic dependency resolution, and archiving the build with an explicit SourcePackages path. ```bash #!/bin/bash set -e # 1. Checkout code git clone $REPO_URL # 2. Resolve dependencies with deterministic path swift package resolve --verbose # 3. Build with explicit SourcePackages path export PLL_SOURCE_PACKAGES_PATH="$(pwd)/.build/checkouts" xcodebuild \ -scheme MyApp \ -configuration Release \ -destination generic/platform=iOS \ -derivedDataPath "build/DerivedData" archive echo "Build succeeded with licenses included" ``` -------------------------------- ### Clean and Rebuild Project Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/configuration.md Perform a clean build using xcodebuild to resolve potential issues with build caches or intermediate files. ```bash xcodebuild clean xcodebuild build ``` -------------------------------- ### Check License File Type Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/configuration.md Verify that the license file is a regular file and not a directory. This is a common reason for license detection failures. ```bash file .build/checkouts/SomeDep/LICENSE ``` -------------------------------- ### LicenseViewStyle.withRepositoryAnchorLink Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-view-style.md Extends the plain license view style by adding a repository anchor link button to the navigation bar. ```APIDOC ## LicenseViewStyle.withRepositoryAnchorLink ### Description A license view style that extends plain style with a repository anchor link button in the navigation bar. ### Property `static var withRepositoryAnchorLink: WithRepositoryAnchorLinkLicenseViewStyle { get }` ``` -------------------------------- ### WithRepositoryAnchorLinkLicenseViewStyle Usage Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/api-reference/license-view-style.md Shows how to apply the repository anchor link style to a LicenseListView. This style adds a repository link button to the navigation bar. ```swift import SwiftUI import LicenseList struct ContentView: View { var body: some View { NavigationView { LicenseListView() .licenseViewStyle(.withRepositoryAnchorLink) .navigationTitle("Licenses") } } } ``` -------------------------------- ### UIKit View Controller with Plain Style Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/README.md Configure a UIKit LicenseListViewController to use the plain style, which omits repository anchor links. ```swift let vc = LicenseListViewController() vc.licenseListViewStyle = .plain vc.licenseViewStyle = .withRepositoryAnchorLink ``` -------------------------------- ### Match URLs in Text Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/extension-apis.md Demonstrates how to use the URL.regexPattern to find all URLs within a given string. This is useful for parsing license texts or other documents containing web links. ```swift import LicenseList let licenseText = """ MIT License https://opensource.org/licenses/MIT For more info, visit https://example.com/license?version=2 """ let urlMatches = licenseText.match(URL.regexPattern) // Finds: // - https://opensource.org/licenses/MIT // - https://example.com/license?version=2 ``` -------------------------------- ### SwiftUI Environment Values for License List Styles Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/internal-structures.md Defines custom environment values for controlling the style of license list views. Use the @Entry macro for synthesis of environment keys and property accessors. ```swift extension EnvironmentValues { @Entry var licenseListViewStyle: any LicenseListViewStyle = DefaultLicenseListViewStyle() @Entry var licenseViewStyle: any LicenseViewStyle = DefaultLicenseViewStyle() } ``` -------------------------------- ### URL Detection in LicenseView Source: https://github.com/cybozu/licenselist/blob/main/_autodocs/extension-apis.md Shows how the URL.regexPattern is internally used within LicenseView to detect and convert detected URL strings into URL objects. ```swift // In LicenseView.attribute() let urls: [URL?] = inputText.match(URL.regexPattern) .map { URL(string: String(inputText[$0])) } ```