Skip to content

Docs/package plugin api docs #8901

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions Sources/PackagePlugin/ArgumentExtractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,29 @@
//
//===----------------------------------------------------------------------===//

/// A rudimentary helper for extracting options and flags from a string list representing command line arguments. The idea is to extract all known options and flags, leaving just the positional arguments. This does not handle well the case in which positional arguments (or option argument values) happen to have the same name as an option or a flag. It only handles the long `--<name>` form of options, but it does respect `--` as an indication that all remaining arguments are positional.
/// A rudimentary helper for extracting options and flags from a list of strings that represent command line arguments.
///
/// Create the extractor with the full command line arguments provided, then extract all known
/// options and flags, which leaves the positional arguments.
///
/// This does not handle the case where positional arguments (or optional argument values) have the same
/// name as an option or a flag. It only handles the long form of options, not short forms, for example: `--<name>`, not `-n`.
/// It respects an argument that consists of two hyphens (`--`) as an indication that all remaining arguments are positional.
public struct ArgumentExtractor {
private var args: [String]
private let literals: [String]

/// Initializes a ArgumentExtractor with a list of strings from which to extract flags and options. If the list contains `--`, any arguments that follow it are considered to be literals.
/// Creates an argument extractor with a list of strings from which to extract flags and options.
///
/// If the list contains `--`, any arguments that follow it are considered positional arguments.
public init(_ arguments: [String]) {
// Split the array on the first `--`, if there is one. Everything after that is a literal.
let parts = arguments.split(separator: "--", maxSplits: 1, omittingEmptySubsequences: false)
self.args = Array(parts[0])
self.literals = Array(parts.count == 2 ? parts[1] : [])
}

/// Extracts options of the form `--<name> <value>` or `--<name>=<value>` from the remaining arguments, and returns the extracted values.
/// Extracts options of the form `--<name> <value>` or `--<name>=<value>` from the remaining arguments and returns the extracted values.
public mutating func extractOption(named name: String) -> [String] {
var values: [String] = []
var idx = 0
Expand Down Expand Up @@ -66,12 +75,16 @@ public struct ArgumentExtractor {
return count
}

/// Returns any unextracted flags or options (based strictly on whether remaining arguments have a "--" prefix).
/// Returns any unextracted flags or options.
///
/// This is based strictly on whether remaining arguments have a `--` prefix.
public var unextractedOptionsOrFlags: [String] {
return args.filter{ $0.hasPrefix("--") }
}

/// Returns all remaining arguments, including any literals after the first `--` if there is one.
/// Returns all remaining arguments.
///
/// The returned values include any positional arguments after the first `--`, if there is one.
public var remainingArguments: [String] {
return args + literals
}
Expand Down
95 changes: 52 additions & 43 deletions Sources/PackagePlugin/Command.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,35 @@

import Foundation

/// A command to run during the build, including executable, command lines,
/// environment variables, initial working directory, etc. All paths should be
/// based on the ones passed to the plugin in the target build context.
/// A command to run during the build.
///
/// A command includes the executable, command lines, environment variables, initial working directory, and so on.
/// All paths should be based on the ones that SwiftPM passes to the plugin in the target build context.
public enum Command {
/// Returns a command that runs when any of its output files are needed by
/// the build, but out-of-date.
/// the build and are out-of-date.
///
/// An output file is out-of-date if it doesn't exist, or if any input files
/// have changed since the command was last run.
///
/// - Note: the paths in the list of output files may depend on the list of
/// input file paths, but **must not** depend on reading the contents of
/// any input files. Such cases must be handled using a `prebuildCommand`.
/// any input files. Use a `prebuildCommand`if the functionality of your plugin
/// requires you to read the contents of an input file.
///
/// - parameters:
/// - displayName: An optional string to show in build logs and other
/// status areas.
/// - executable: The absolute path to the executable to be invoked.
/// - arguments: Command-line arguments to be passed to the executable.
/// - environment: Environment variable assignments visible to the
/// - executable: The absolute path to the executable to invoke.
/// - arguments: The command-line arguments for the executable.
/// - environment: Any environment variable assignments visible to the
/// executable.
/// - inputFiles: Files on which the contents of output files may depend.
/// - inputFiles: A list of files on which the contents of output files may depend.
/// Any paths passed as `arguments` should typically be passed here as
/// well.
/// - outputFiles: Files to be generated or updated by the executable.
/// - outputFiles: A list of files to be generated or updated by the executable.
/// Any files recognizable by their extension as source files
/// (e.g. `.swift`) are compiled into the target for which this command
/// (for example, `.swift`) are compiled into the target for which this command
/// was generated as if in its source directory; other files are treated
/// as resources as if explicitly listed in `Package.swift` using
/// `.process(...)`.
Expand All @@ -61,17 +63,18 @@ public enum Command {
/// determine this list without first running the command, so
/// instead of encoding that list, the caller supplies an
/// `outputFilesDirectory` parameter, and all files in that
/// directory after the command runs are treated as output files.
/// directory after the command runs are treated as the output files
/// of the plugin.
///
/// - parameters:
/// - displayName: An optional string to show in build logs and other
/// status areas.
/// - executable: The absolute path to the executable to be invoked.
/// - arguments: Command-line arguments to be passed to the executable.
/// - environment: Environment variable assignments visible to the executable.
/// - executable: The absolute path to the executable to invoke.
/// - arguments: The command-line arguments for the executable.
/// - environment: Any environment variable assignments visible to the executable.
/// - outputFilesDirectory: A directory into which the command writes its
/// output files. Any files there recognizable by their extension as
/// source files (e.g. `.swift`) are compiled into the target for which
/// output files. The package manager compiles any files there recognizable by
/// their extension as source files (for example, `.swift`) into the target for which
/// this command was generated as if in its source directory; other
/// files are treated as resources as if explicitly listed in
/// `Package.swift` using `.process(...)`.
Expand All @@ -87,7 +90,7 @@ public enum Command {

extension Command {
/// Returns a command that runs when any of its output files are needed by
/// the build, but out-of-date.
/// the build and are out-of-date.
///
/// An output file is out-of-date if it doesn't exist, or if any input files
/// have changed since the command was last run.
Expand All @@ -99,19 +102,23 @@ extension Command {
/// - parameters:
/// - displayName: An optional string to show in build logs and other
/// status areas.
/// - executable: The absolute path to the executable to be invoked.
/// - arguments: Command-line arguments to be passed to the executable.
/// - executable: The absolute path to the executable to invoke.
/// - arguments: Command-line arguments for the executable.
/// - environment: Environment variable assignments visible to the
/// executable.
/// - inputFiles: Files on which the contents of output files may depend.
/// Any paths passed as `arguments` should typically be passed here as
/// well.
/// - outputFiles: Files to be generated or updated by the executable.
/// Any files recognizable by their extension as source files
/// (e.g. `.swift`) are compiled into the target for which this command
/// - outputFiles: The files that the plugin generates or updates using the executable.
/// The package manager compiles any files recognizable by their extension as source files
/// (e.g. `.swift`) into the target for which this command
/// was generated as if in its source directory; other files are treated
/// as resources as if explicitly listed in `Package.swift` using
/// `.process(...)`.
///
/// @DeprecationSummary {
/// Use ``buildCommand(displayName:executable:arguments:environment:inputFiles:outputFiles:)-swift.enum.case`` instead.
/// }
@available(_PackageDescription, deprecated: 6.0, message: "Use `URL` type instead of `Path`.")
public static func buildCommand(
displayName: String?,
Expand All @@ -132,32 +139,33 @@ extension Command {
}

/// Returns a command that runs when any of its output files are needed
/// by the build, but out-of-date.
/// by the build and are out-of-date.
///
/// An output file is out-of-date if it doesn't exist, or if any input
/// files have changed since the command was last run.
///
/// - Note: the paths in the list of output files may depend on the list
/// of input file paths, but **must not** depend on reading the contents
/// of any input files. Such cases must be handled using a `prebuildCommand`.
/// of any input files. Use a `prebuildCommand`if the functionality of your plugin
/// requires you to read the contents of an input file.
///
/// - parameters:
/// - displayName: An optional string to show in build logs and other
/// status areas.
/// - executable: The absolute path to the executable to be invoked.
/// - arguments: Command-line arguments to be passed to the executable.
/// - environment: Environment variable assignments visible to the executable.
/// - executable: The absolute path to the executable to invoke.
/// - arguments: The command-line arguments for the executable.
/// - environment: Any environment variable assignments visible to the executable.
/// - workingDirectory: Optional initial working directory when the executable
/// runs.
/// - inputFiles: Files on which the contents of output files may depend.
/// - inputFiles: A list of files on which the contents of output files may depend.
/// Any paths passed as `arguments` should typically be passed here as well.
/// - outputFiles: Files to be generated or updated by the executable.
/// - outputFiles: A list of files to be generated or updated by the executable.
/// Any files recognizable by their extension as source files
/// (e.g. `.swift`) are compiled into the target for which this command
/// (for example, `.swift`) are compiled into the target for which this command
/// was generated as if in its source directory; other files are treated
/// as resources as if explicitly listed in `Package.swift` using
/// `.process(...)`.
@available(*, unavailable, message: "specifying the initial working directory for a command is not yet supported")
@available(*, unavailable, message: "specifying the initial working directory for a command is not supported")
public static func buildCommand(
displayName: String?,
executable: Path,
Expand Down Expand Up @@ -191,17 +199,18 @@ extension Command {
/// - parameters:
/// - displayName: An optional string to show in build logs and other
/// status areas.
/// - executable: The absolute path to the executable to be invoked.
/// - arguments: Command-line arguments to be passed to the executable.
/// - environment: Environment variable assignments visible to the executable.
/// - workingDirectory: Optional initial working directory when the executable
/// runs.
/// - executable: The absolute path to the executable to invoke.
/// - arguments: The command-line arguments for the executable.
/// - environment: Any environment variable assignments visible to the executable.
/// - outputFilesDirectory: A directory into which the command writes its
/// output files. Any files there recognizable by their extension as
/// source files (e.g. `.swift`) are compiled into the target for which
/// source files (for example, `.swift`) are compiled into the target for which
/// this command was generated as if in its source directory; other
/// files are treated as resources as if explicitly listed in
/// `Package.swift` using `.process(...)`.
/// @DeprecationSummary {
/// Use ``prebuildCommand(displayName:executable:arguments:environment:outputFilesDirectory:)-swift.enum.case`` instead.
/// }
@available(_PackageDescription, deprecated: 6.0, message: "Use `URL` type instead of `Path`.")
public static func prebuildCommand(
displayName: String?,
Expand Down Expand Up @@ -233,18 +242,18 @@ extension Command {
/// - parameters:
/// - displayName: An optional string to show in build logs and other
/// status areas.
/// - executable: The absolute path to the executable to be invoked.
/// - arguments: Command-line arguments to be passed to the executable.
/// - environment: Environment variable assignments visible to the executable.
/// - executable: The absolute path to the executable to invoke.
/// - arguments: The command-line arguments for the executable.
/// - environment: Any environment variable assignments visible to the executable.
/// - workingDirectory: Optional initial working directory when the executable
/// runs.
/// - outputFilesDirectory: A directory into which the command writes its
/// output files. Any files there recognizable by their extension as
/// source files (e.g. `.swift`) are compiled into the target for which
/// source files (for example, `.swift`) are compiled into the target for which
/// this command was generated as if in its source directory; other
/// files are treated as resources as if explicitly listed in
/// `Package.swift` using `.process(...)`.
@available(*, unavailable, message: "specifying the initial working directory for a command is not yet supported")
@available(*, unavailable, message: "specifying the initial working directory for a command is not supported")
public static func prebuildCommand(
displayName: String?,
executable: Path,
Expand Down
Loading