Skip to content
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

Spring cleaning #294

Merged
merged 2 commits into from
Jul 31, 2023
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
2 changes: 1 addition & 1 deletion book/src/schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ As a matter of forward-compat and back-compat, basically every field in the form
Here is the JSON Schema which will *hopefully* be stable going forward.

```json
{{#include ../../cargo-dist-schema/cargo-dist-json-schema.json}}
{{#include ../../cargo-dist-schema/src/snapshots/cargo_dist_schema__emit.snap:5:}}
```
17 changes: 0 additions & 17 deletions cargo-dist-schema/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,24 +345,7 @@ pub fn format_of_version(version: &Version) -> Format {

#[test]
fn emit() {
use std::fs::File;
use std::io::BufWriter;
use std::io::Write;
use std::path::PathBuf;

let schema = DistManifest::json_schema();
let json_schema = serde_json::to_string_pretty(&schema).unwrap();
insta::assert_snapshot!(json_schema);

// FIXME: (?) we should use something like xtask to update the schema, but this works ok.
let root = std::env!("CARGO_MANIFEST_DIR");
let schema = PathBuf::from(root).join("cargo-dist-json-schema.json");
let file = File::options()
.create(true)
.write(true)
.truncate(true)
.open(schema)
.unwrap();
let mut file = BufWriter::new(file);
writeln!(&mut file, "{json_schema}").unwrap();
}
83 changes: 9 additions & 74 deletions cargo-dist/src/ci.rs → cargo-dist/src/backend/ci/github.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@

// FIXME(#283): migrate this to minijinja (steal logic from oranda to load a whole dir)

use std::fs::File;

use miette::{IntoDiagnostic, WrapErr};
use axoasset::LocalAsset;
use newline_converter::dos2unix;
use semver::Version;
use tracing::{info, warn};

use crate::{DistGraph, SortedMap, SortedSet, TargetTriple};
Expand All @@ -25,26 +22,20 @@ pub fn generate_github_ci(dist: &DistGraph) -> Result<(), miette::Report> {
let ci_file = ci_dir.join(GITHUB_CI_FILE);

info!("generating Github CI at {ci_file}");
std::fs::create_dir_all(&ci_dir)
.into_diagnostic()
.wrap_err("Failed to create ci dir")?;
let mut file = File::create(&ci_file)
.into_diagnostic()
.wrap_err("Failed to create ci file")?;
write_github_ci(&mut file, dist)
.into_diagnostic()
.wrap_err("Failed to write to CI file")?;
let output = write_github_ci(dist);
LocalAsset::write_new_all(&output, &ci_file)?;
eprintln!("generated Github CI to {}", ci_file);

Ok(())
}

/// Write the Github CI to something
fn write_github_ci<W: std::io::Write>(f: &mut W, dist: &DistGraph) -> Result<(), std::io::Error> {
fn write_github_ci(dist: &DistGraph) -> String {
// If they don't specify a Rust version, just go for "stable"
let rust_version = dist.desired_rust_toolchain.as_deref();

// If they don't specify a cargo-dist version, use this one
let self_dist_version = SELF_DIST_VERSION.parse().unwrap();
let self_dist_version = super::SELF_DIST_VERSION.parse().unwrap();
let dist_version = dist
.desired_cargo_dist_version
.as_ref()
Expand Down Expand Up @@ -78,8 +69,8 @@ fn write_github_ci<W: std::io::Write>(f: &mut W, dist: &DistGraph) -> Result<(),
.unwrap_or(String::new());

// Get the platform-specific installation methods
let install_dist_sh = install_dist_sh_for_version(dist_version);
let install_dist_ps1 = install_dist_ps1_for_version(dist_version);
let install_dist_sh = super::install_dist_sh_for_version(dist_version);
let install_dist_ps1 = super::install_dist_ps1_for_version(dist_version);

// Build up the task matrix for building Artifacts
let mut artifacts_matrix = String::from("include:");
Expand Down Expand Up @@ -123,9 +114,7 @@ fn write_github_ci<W: std::io::Write>(f: &mut W, dist: &DistGraph) -> Result<(),
.replace("{{{{ARTIFACTS_MATRIX}}}}", &artifacts_matrix)
.replace("{{{{FAIL_FAST}}}}", &fail_fast);

f.write_all(dos2unix(&ci_yml).as_bytes())?;

Ok(())
dos2unix(&ci_yml).into_owned()
}

/// Add an entry to a Github Matrix (for the Artifacts tasks)
Expand Down Expand Up @@ -236,57 +225,3 @@ fn install_dist_for_github_runner<'a>(
unreachable!("internal error: unknown github runner!?")
}
}

/// The current version of cargo-dist
const SELF_DIST_VERSION: &str = env!("CARGO_PKG_VERSION");
const BASE_DIST_FETCH_URL: &str = "https://github.com/axodotdev/cargo-dist/releases/download";

/// Get the command to invoke to install cargo-dist via sh script
fn install_dist_sh_for_version(version: &Version) -> String {
if let Some(git) = install_dist_git(version) {
return git;
}
let format = cargo_dist_schema::format_of_version(version);
let installer_name = if format.unsupported() {
// FIXME: we should probably do this check way higher up and produce a proper err...
panic!("requested cargo-dist v{version}, which is not supported by the this copy of cargo-dist ({SELF_DIST_VERSION})");
} else if format.artifact_names_contain_versions() {
format!("cargo-dist-v{version}-installer.sh")
} else {
"cargo-dist-installer.sh".to_owned()
};

// FIXME: it would be nice if these values were somehow using all the machinery
// to compute these values for packages we build *BUT* it's messy and not that important
let installer_url = format!("{BASE_DIST_FETCH_URL}/v{version}/{installer_name}");
format!("curl --proto '=https' --tlsv1.2 -LsSf {installer_url} | sh")
}

/// Get the command to invoke to install cargo-dist via ps1 script
fn install_dist_ps1_for_version(version: &Version) -> String {
if let Some(git) = install_dist_git(version) {
return git;
}
let format = cargo_dist_schema::format_of_version(version);
let installer_name = if format.unsupported() {
// FIXME: we should probably do this check way higher up and produce a proper err...
panic!("requested cargo-dist v{version}, which is not supported by the this copy of cargo-dist ({SELF_DIST_VERSION})");
} else if format.artifact_names_contain_versions() {
format!("cargo-dist-v{version}-installer.ps1")
} else {
"cargo-dist-installer.ps1".to_owned()
};

// FIXME: it would be nice if these values were somehow using all the machinery
// to compute these values for packages we build *BUT* it's messy and not that important
let installer_url = format!("{BASE_DIST_FETCH_URL}/v{version}/{installer_name}");
format!("irm {installer_url} | iex")
}

/// Cute little hack for developing dist itself: if we see a version like "0.0.3-github-config"
/// then install from the main github repo with branch=config!
fn install_dist_git(version: &Version) -> Option<String> {
version.pre.strip_prefix("github-").map(|branch| {
format!("cargo install --git https://github.com/axodotdev/cargo-dist/ --branch={branch} cargo-dist")
})
}
59 changes: 59 additions & 0 deletions cargo-dist/src/backend/ci/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//! Support for generating CI scripts for running cargo-dist

use semver::Version;

pub mod github;

/// The current version of cargo-dist
const SELF_DIST_VERSION: &str = env!("CARGO_PKG_VERSION");
const BASE_DIST_FETCH_URL: &str = "https://github.com/axodotdev/cargo-dist/releases/download";

/// Get the command to invoke to install cargo-dist via sh script
fn install_dist_sh_for_version(version: &Version) -> String {
if let Some(git) = install_dist_git(version) {
return git;
}
let format = cargo_dist_schema::format_of_version(version);
let installer_name = if format.unsupported() {
// FIXME: we should probably do this check way higher up and produce a proper err...
panic!("requested cargo-dist v{version}, which is not supported by the this copy of cargo-dist ({SELF_DIST_VERSION})");
} else if format.artifact_names_contain_versions() {
format!("cargo-dist-v{version}-installer.sh")
} else {
"cargo-dist-installer.sh".to_owned()
};

// FIXME: it would be nice if these values were somehow using all the machinery
// to compute these values for packages we build *BUT* it's messy and not that important
let installer_url = format!("{BASE_DIST_FETCH_URL}/v{version}/{installer_name}");
format!("curl --proto '=https' --tlsv1.2 -LsSf {installer_url} | sh")
}

/// Get the command to invoke to install cargo-dist via ps1 script
fn install_dist_ps1_for_version(version: &Version) -> String {
if let Some(git) = install_dist_git(version) {
return git;
}
let format = cargo_dist_schema::format_of_version(version);
let installer_name = if format.unsupported() {
// FIXME: we should probably do this check way higher up and produce a proper err...
panic!("requested cargo-dist v{version}, which is not supported by the this copy of cargo-dist ({SELF_DIST_VERSION})");
} else if format.artifact_names_contain_versions() {
format!("cargo-dist-v{version}-installer.ps1")
} else {
"cargo-dist-installer.ps1".to_owned()
};

// FIXME: it would be nice if these values were somehow using all the machinery
// to compute these values for packages we build *BUT* it's messy and not that important
let installer_url = format!("{BASE_DIST_FETCH_URL}/v{version}/{installer_name}");
format!("irm {installer_url} | iex")
}

/// Cute little hack for developing dist itself: if we see a version like "0.0.3-github-config"
/// then install from the main github repo with branch=config!
fn install_dist_git(version: &Version) -> Option<String> {
version.pre.strip_prefix("github-").map(|branch| {
format!("cargo install --git https://github.com/axodotdev/cargo-dist/ --branch={branch} cargo-dist")
})
}
63 changes: 63 additions & 0 deletions cargo-dist/src/backend/installer/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//! Installer Generation
//!
//! In the future this might get split up into submodules.

use camino::Utf8PathBuf;
use serde::Serialize;

use crate::{
config::{JinjaInstallPathStrategy, ZipStyle},
TargetTriple,
};

use self::npm::NpmInstallerInfo;

pub mod npm;
pub mod powershell;
pub mod shell;

/// A kind of an installer
#[derive(Debug, Clone)]
#[allow(clippy::large_enum_variant)]
pub enum InstallerImpl {
/// shell installer script
Shell(InstallerInfo),
/// powershell installer script
Powershell(InstallerInfo),
/// npm installer package
Npm(NpmInstallerInfo),
}

/// Generic info about an installer
#[derive(Debug, Clone, Serialize)]
pub struct InstallerInfo {
/// The path to generate the installer at
pub dest_path: Utf8PathBuf,
/// App name to use (display only)
pub app_name: String,
/// App version to use (display only)
pub app_version: String,
/// URL of the directory where artifacts can be fetched from
pub base_url: String,
/// Artifacts this installer can fetch
pub artifacts: Vec<ExecutableZipFragment>,
/// Description of the installer (a good heading)
pub desc: String,
/// Hint for how to run the installer
pub hint: String,
/// Where to install binaries
pub install_path: JinjaInstallPathStrategy,
}

/// A fake fragment of an ExecutableZip artifact for installers
#[derive(Debug, Clone, Serialize)]
pub struct ExecutableZipFragment {
/// The id of the artifact
pub id: String,
/// The targets the artifact supports
pub target_triples: Vec<TargetTriple>,
/// The binaries the artifact contains (name, assumed at root)
pub binaries: Vec<String>,
/// The style of zip this is
pub zip_style: ZipStyle,
}
Loading