Skip to content
Merged
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
50 changes: 41 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,42 +51,74 @@ Run the tool by specifying the required paths:

```sh
./Binary/binary-dependencies-manager \
--dependencies path/to/dependencies.json \
--config path/to/.binary-dependencies.yaml \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:sigh:

--cache path/to/cache \
--output path/to/output
```

- `--dependencies`: Path to your `dependencies.json` file (see format below)
- `--config`, `-c`: Path to your `.binary-dependencies.yaml` file (see format below)
- `--output`, `-o`: Directory where resolved dependencies will be extracted
- `--cache`: Directory to use for caching downloads
- `--output`: Directory where resolved dependencies will be extracted

## Example `dependencies.json`
```json
[
{
"repo": "MyOrg/MyLibrary",
"tag": "1.2.3",
"checksum": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"contents": "XCFrameworks/MyLibrary.xcframework",
"pattern": "MyLibrary.xcframework.zip",
"output": "MyLibrary"
"assets": {
"checksum": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"contents": "XCFrameworks/MyLibrary.xcframework",
"pattern": "MyLibrary.xcframework.zip",
"output": "MyLibrary"
}
},
{
"repo": "AnotherOrg/AnotherBinary",
"tag": "0.9.0",
"checksum": "d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2",
"checksum": "7ab14dda40c47f9c4d1829b4c214898e4c61a2d3055c773169b7291d0f48cd0c",
"pattern": "AnotherBinary.zip"
}
]
```

```yaml
---
minimumVersion: 0.0.5
outputDirectory: Dependencies
cacheDirectory: .cache/binary-dependencies/
dependencies:
- repo: MyOrg/MyLibrary
tag: 1.2.3
assets:
- contents: XCFrameworks/MyLibrary.xcframework
checksum: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
pattern: MyLibrary.xcframework.zip
output: MyLibrary
- repo: AnotherOrg/AnotherBinary
tag: 0.9.0
checksum: 7ab14dda40c47f9c4d1829b4c214898e4c61a2d3055c773169b7291d0f48cd0c
pattern: AnotherBinary.zip
```
## Top level parameters
- `minimumVersion` (optional): Minimum required binary-dependencies-manager version. Optional. Defaults to the current version.
- `outputDirectory` (optional): Path to the output directory. Optional. Defaults to `Dependencies/Binary`.
- `cacheDirectory` (optional): Path to the cache directory. Optional. Defaults to the `.cache/binary-dependencies`.


## Dependency Parameters
- `repo` (**required**): GitHub repository in the format `owner/repo` (e.g., `apple/swift-argument-parser`)
- `tag` (**required**): Release tag to download (e.g., `1.0.0`)
- `assets` (optional): A list of multiple binary assets to download from a given repo release.

> ℹ️ If no assets are provided you can specify asset parameters as a dependency parameters to download a single release artifact.

## Asset Parameters
- `checksum` (**required**): SHA256 checksum of the zip archive for integrity verification
- `contents` (optional): If provided, only the contents of this directory inside the archive will be extracted to the output directory
- `pattern` (optional): Pattern to select a specific artifact from the release (useful if multiple assets are present)
- `output` (optional): Subdirectory name to use for this dependency in the output directory (useful for organizing multiple artifacts)
- `output` (optional): Subdirectory name to use for this dependency asset in the output directory (useful for organizing multiple artifacts)


## Example Scenarios
- **Download a single artifact:**
Expand Down
87 changes: 73 additions & 14 deletions Sources/CommandLine/Commands/ResolveCommand.swift
Original file line number Diff line number Diff line change
@@ -1,28 +1,87 @@
import ArgumentParser
import BinaryDependencyManager
import Foundation
import Yams
import Utils

struct ResolveCommand: ParsableCommand {
static var configuration = CommandConfiguration(
commandName: "resolve",
version: BinaryDependenciesManager.configuration.version
)

static var configuration = CommandConfiguration(commandName: "resolve")
/// Path to the configuration file.
///
/// Example:
/// ```
/// $ binary-dependencies-manager resolve --config ./.binary-dependencies.yaml
/// $ binary-dependencies-manager resolve -c ./.binary-dependencies.yaml
/// ```
@Option(name: [.customLong("config", withSingleDash: true), .short], help: "Path to the configuration file")
var configurationFilePath: String?

// Path to dependencies json
@Option(name: .shortAndLong, help: "Path to dependencies json")
var dependenciesJSONPath: String
/// Path to the output directory.
///
/// Example:
/// ```
/// $ binary-dependencies-manager resolve --output ./output
/// $ binary-dependencies-manager resolve -o ./output
/// ```
@Option(name: [.customLong("output"), .short], help: "Path to the output directory, where downloaded dependencies will be placed")
var outputDirectoryPath: String?

// Path to cache directory
@Option(name: .shortAndLong, help: "Path to cache directory")
var cacheDirectoryPath: String
/// Path to the cache directory.
///
/// Example:
/// ```
/// $ binary-dependencies-manager resolve --cache ./cache
/// ```
@Option(name: [.customLong("cache")], help: "Path to the cache directory")
var cacheDirectoryPath: String?

// Path to output directory
@Option(name: .shortAndLong, help: "Path to output directory, where downloaded dependencies will be placed")
var outputDirectoryPath: String
/// Dependencies to resolve.
var configuration: BinaryDependenciesConfiguration?

/// Validates a given configuration file.
mutating func validate() throws {
let configurationReader: BinaryDependenciesConfigurationReader = .init()

let configuration = try configurationReader
.readConfiguration(at: configurationFilePath, currentToolVersion: BinaryDependenciesManager.version)

self.configuration = configuration

// Paths from CLI arguments take precedence over those from the configuration file.
outputDirectoryPath = configurationReader
.resolveOutputDirectoryURL(outputDirectoryPath ?? configuration.outputDirectory)
.path
cacheDirectoryPath = configurationReader
.resolveCacheDirectoryURL(cacheDirectoryPath ?? configuration.cacheDirectory)
.path

}

func run() throws {
let resolver = DependenciesResolverRunner(
dependenciesJSONPath: dependenciesJSONPath,
guard let configuration else {
// Should never happen, because we validate the configuration in `validate()` method.
preconditionFailure("Configuration is not initialized")
}
guard let outputDirectoryPath else {
// Should never happen, because we validate the configuration in `validate()` method.
preconditionFailure("Output directory path is not initialized")
}
guard let cacheDirectoryPath else {
// Should never happen, because we validate the configuration in `validate()` method.
preconditionFailure("Cache directory path is not initialized")
}

let dependenciesResolver = DependenciesResolverRunner(
dependencies: configuration.dependencies,
outputDirectoryPath: outputDirectoryPath,
cacheDirectoryPath: cacheDirectoryPath,
outputDirectoryPath: outputDirectoryPath
)
try resolver.run()

// Run the dependencies resolver.
try dependenciesResolver.run()
}
}