-
Notifications
You must be signed in to change notification settings - Fork 124
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #404 from github/rusty
Add support for rust via cargo
- Loading branch information
Showing
11 changed files
with
291 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Cargo | ||
|
||
The cargo source will detect dependencies when `Cargo.toml` is found at an apps `source_path`. The source uses the `cargo metadata` CLI and reports on all dependencies that are listed in the output in `resolve.nodes`, excluding packages that are listed in `workspace_members`. | ||
|
||
## Metadata CLI options | ||
|
||
Licensed by default runs `cargo metadata --format-version=1`. You can specify additional CLI options by specifying them in your licensed configuration file under `cargo.metadata_options`. The configuration can be set as a string, or as an array of strings for multiple options. | ||
|
||
```yml | ||
cargo: | ||
metadata_options: '--all-features' | ||
``` | ||
```yml | ||
cargo: | ||
metadata_options: | ||
- '--all-features' | ||
- '--filter-platform x86_64-pc-windows-msvc' | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# frozen_string_literal: true | ||
|
||
require "json" | ||
|
||
module Licensed | ||
module Sources | ||
class Cargo < Source | ||
# Source is enabled when the cargo tool and Cargo.toml manifest file are available | ||
def enabled? | ||
return false unless Licensed::Shell.tool_available?("cargo") | ||
config.pwd.join("Cargo.toml").exist? | ||
end | ||
|
||
def enumerate_dependencies | ||
packages.map do |package| | ||
Dependency.new( | ||
name: "#{package["name"]}-#{package["version"]}", | ||
version: package["version"], | ||
path: File.dirname(package["manifest_path"]), | ||
metadata: { | ||
"name" => package["name"], | ||
"type" => Cargo.type, | ||
"summary" => package["description"], | ||
"homepage" => package["homepage"] | ||
} | ||
) | ||
end | ||
end | ||
|
||
# Returns the package data for all dependencies used to build the current package | ||
def packages | ||
cargo_metadata_resolved_node_ids.map { |id| cargo_metadata_packages[id] } | ||
end | ||
|
||
# Returns the ids of all resolved nodes used to build the current package | ||
def cargo_metadata_resolved_node_ids | ||
cargo_metadata.dig("resolve", "nodes") | ||
.map { |node| node["id"] } | ||
.reject { |id| cargo_metadata_workspace_members.include?(id) } | ||
|
||
end | ||
|
||
# Returns a hash of id => package pairs sourced from the "packages" cargo metadata property | ||
def cargo_metadata_packages | ||
@cargo_metadata_packages ||= cargo_metadata["packages"].each_with_object({}) do |package, hsh| | ||
hsh[package["id"]] = package | ||
end | ||
end | ||
|
||
# Returns a set of the ids of packages in the current workspace | ||
def cargo_metadata_workspace_members | ||
@cargo_metadata_workspace_members ||= Set.new(Array(cargo_metadata["workspace_members"])) | ||
end | ||
|
||
# Returns parsed JSON metadata returned from the cargo CLI | ||
def cargo_metadata | ||
@cargo_metadata ||= JSON.parse(cargo_metadata_command) | ||
rescue JSON::ParserError => e | ||
message = "Licensed was unable to parse the output from 'cargo metadata'. JSON Error: #{e.message}" | ||
raise Licensed::Sources::Source::Error, message | ||
end | ||
|
||
# Runs a command to get cargo metadata for the current package | ||
def cargo_metadata_command | ||
options = Array(config.dig("cargo", "metadata_options")).flat_map(&:split) | ||
Licensed::Shell.execute("cargo", "metadata", "--format-version=1", *options) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#!/bin/bash | ||
set -e | ||
|
||
if [ -z "$(which cargo)" ]; then | ||
echo "A local cargo installation is required for rustc development." >&2 | ||
exit 127 | ||
fi | ||
|
||
cargo --version | ||
|
||
# setup test fixtures | ||
BASE_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" | ||
cd $BASE_PATH/test/fixtures/cargo | ||
|
||
if [ "$1" == "-f" ]; then | ||
find . -not -regex "\.*" -and -not -path "*app*" -print0 | xargs -0 rm -rf | ||
fi | ||
|
||
cargo build |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
[package] | ||
name = "app" | ||
version = "0.1.0" | ||
edition = "2018" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
time = "~0.3.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
fn main() { | ||
println!("Hello, world!"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
expected_dependency: time-0.3.2 | ||
expected_dependency_name: time | ||
source_path: test/fixtures/cargo | ||
cache_path: test/fixtures/cargo/.licenses | ||
sources: | ||
cargo: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
# frozen_string_literal: true | ||
require "test_helper" | ||
require "tmpdir" | ||
|
||
if Licensed::Shell.tool_available?("cargo") | ||
describe Licensed::Sources::Cargo do | ||
let(:fixtures) { File.expand_path("../../fixtures/cargo", __FILE__) } | ||
let(:config) { Licensed::AppConfiguration.new({ "source_path" => Dir.pwd }) } | ||
let(:source) { Licensed::Sources::Cargo.new(config) } | ||
|
||
describe "enabled?" do | ||
it "is false if Cargo.toml does not exist" do | ||
Dir.mktmpdir do |dir| | ||
Dir.chdir(dir) do | ||
refute source.enabled? | ||
end | ||
end | ||
end | ||
|
||
it "is true if Cargo.toml exists" do | ||
Dir.chdir(fixtures) do | ||
assert source.enabled? | ||
end | ||
end | ||
end | ||
|
||
describe "dependencies" do | ||
it "does not include the current application" do | ||
Dir.chdir fixtures do | ||
refute source.dependencies.detect { |d| d.name == "app-0.1.0" } | ||
end | ||
end | ||
|
||
it "includes declared dependencies" do | ||
Dir.chdir fixtures do | ||
dep = source.dependencies.detect { |d| d.name == "time-0.3.2" } | ||
assert dep | ||
assert_equal "cargo", dep.record["type"] | ||
assert dep.record["homepage"] | ||
assert dep.record["summary"] | ||
assert dep.path | ||
end | ||
end | ||
|
||
it "includes transitive dependencies" do | ||
Dir.chdir fixtures do | ||
dep = source.dependencies.detect { |d| d.name == "libc-0.2.102" } | ||
assert dep | ||
assert_equal "cargo", dep.record["type"] | ||
assert dep.record["homepage"] | ||
assert dep.record["summary"] | ||
assert dep.path | ||
end | ||
end | ||
|
||
it "does not include dev dependencies" do | ||
Dir.chdir fixtures do | ||
refute source.dependencies.detect { |dep| dep.name == "criterion" } | ||
end | ||
end | ||
|
||
it "does not include not-installed optional dependencies" do | ||
Dir.chdir fixtures do | ||
refute source.dependencies.detect { |dep| dep.name == "time-macros" } | ||
end | ||
end | ||
end | ||
|
||
describe "cargo_metadata" do | ||
it "raises Licensed::Sources::Source::Error if the cargo JSON metadata can't be parsed" do | ||
Licensed::Shell.stub(:execute, "") do | ||
Dir.chdir fixtures do | ||
assert_raises Licensed::Sources::Source::Error do | ||
source.cargo_metadata | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
||
describe "cargo_metadata_command" do | ||
it "applies a configured string metadata cli option" do | ||
Dir.chdir fixtures do | ||
config["cargo"] = { "metadata_options" => "--all-features" } | ||
Licensed::Shell.expects(:execute).with("cargo", "metadata", "--format-version=1", "--all-features") | ||
source.cargo_metadata_command | ||
end | ||
end | ||
|
||
it "applies a configured array of string metadata cli options" do | ||
Dir.chdir fixtures do | ||
config["cargo"] = { "metadata_options" => ["--all-features", "--filter-platform x86_64-pc-windows-msvc"] } | ||
Licensed::Shell.expects(:execute).with("cargo", "metadata", "--format-version=1", "--all-features", "--filter-platform", "x86_64-pc-windows-msvc") | ||
source.cargo_metadata_command | ||
end | ||
end | ||
end | ||
end | ||
end |