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

(WIP) add v1 "dist init" #1737

Closed
wants to merge 2 commits into from
Closed
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
45 changes: 45 additions & 0 deletions cargo-dist/src/init/interactive.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use axoproject::WorkspaceGraph;
use crate::{config, migrate};
use crate::config::v1::TomlLayer;
//use crate::config::{CiStyle, InstallerStyle, PublishStyle};
use crate::config::Config;
use crate::errors::{DistError, DistResult};

Check failure on line 6 in cargo-dist/src/init/interactive.rs

View workflow job for this annotation

GitHub Actions / clippy

unused import: `DistError`

error: unused import: `DistError` --> cargo-dist/src/init/interactive.rs:6:21 | 6 | use crate::errors::{DistError, DistResult}; | ^^^^^^^^^ | = note: `-D unused-imports` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(unused_imports)]`

Check failure on line 6 in cargo-dist/src/init/interactive.rs

View workflow job for this annotation

GitHub Actions / clippy

unused import: `DistError`

error: unused import: `DistError` --> cargo-dist/src/init/interactive.rs:6:21 | 6 | use crate::errors::{DistError, DistResult}; | ^^^^^^^^^ | = note: `-D unused-imports` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(unused_imports)]`
/*use crate::platform::triple_to_display_name;
use dialoguer::{Confirm, Input, MultiSelect};
use dist_schema::TripleNameRef;
use semver::Version;*/
use super::console_helpers;

Check failure on line 11 in cargo-dist/src/init/interactive.rs

View workflow job for this annotation

GitHub Actions / clippy

unused import: `super::console_helpers`

error: unused import: `super::console_helpers` --> cargo-dist/src/init/interactive.rs:11:5 | 11 | use super::console_helpers; | ^^^^^^^^^^^^^^^^^^^^^^

Check failure on line 11 in cargo-dist/src/init/interactive.rs

View workflow job for this annotation

GitHub Actions / clippy

unused import: `super::console_helpers`

error: unused import: `super::console_helpers` --> cargo-dist/src/init/interactive.rs:11:5 | 11 | use super::console_helpers; | ^^^^^^^^^^^^^^^^^^^^^^
use super::InitArgs;

/// Initialize [dist] with values based on what was passed on the CLI
pub fn get_new_metadata(
cfg: &Config,

Check failure on line 16 in cargo-dist/src/init/interactive.rs

View workflow job for this annotation

GitHub Actions / clippy

unused variable: `cfg`

error: unused variable: `cfg` --> cargo-dist/src/init/interactive.rs:16:5 | 16 | cfg: &Config, | ^^^ help: if this is intentional, prefix it with an underscore: `_cfg`

Check failure on line 16 in cargo-dist/src/init/interactive.rs

View workflow job for this annotation

GitHub Actions / clippy

unused variable: `cfg`

error: unused variable: `cfg` --> cargo-dist/src/init/interactive.rs:16:5 | 16 | cfg: &Config, | ^^^ help: if this is intentional, prefix it with an underscore: `_cfg`
args: &InitArgs,

Check failure on line 17 in cargo-dist/src/init/interactive.rs

View workflow job for this annotation

GitHub Actions / clippy

unused variable: `args`

error: unused variable: `args` --> cargo-dist/src/init/interactive.rs:17:5 | 17 | args: &InitArgs, | ^^^^ help: if this is intentional, prefix it with an underscore: `_args`

Check failure on line 17 in cargo-dist/src/init/interactive.rs

View workflow job for this annotation

GitHub Actions / clippy

unused variable: `args`

error: unused variable: `args` --> cargo-dist/src/init/interactive.rs:17:5 | 17 | args: &InitArgs, | ^^^^ help: if this is intentional, prefix it with an underscore: `_args`
workspaces: &WorkspaceGraph,
) -> DistResult<TomlLayer> {
let root_workspace = workspaces.root_workspace();
let has_config = migrate::has_metadata_table(root_workspace);

let mut meta = if has_config {

Check failure on line 23 in cargo-dist/src/init/interactive.rs

View workflow job for this annotation

GitHub Actions / clippy

variable does not need to be mutable

error: variable does not need to be mutable --> cargo-dist/src/init/interactive.rs:23:9 | 23 | let mut meta = if has_config { | ----^^^^ | | | help: remove this `mut` | = note: `-D unused-mut` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(unused_mut)]`

Check failure on line 23 in cargo-dist/src/init/interactive.rs

View workflow job for this annotation

GitHub Actions / clippy

variable does not need to be mutable

error: variable does not need to be mutable --> cargo-dist/src/init/interactive.rs:23:9 | 23 | let mut meta = if has_config { | ----^^^^ | | | help: remove this `mut` | = note: `-D unused-mut` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(unused_mut)]`
config::v1::load_dist(&root_workspace.manifest_path)?
} else {
TomlLayer::default()
};

/*
// Clone this to simplify checking for settings changes
let orig_meta = meta.clone();

// Now prompt the user interactively to initialize these...

// Tune the theming a bit
let theme = console_helpers::theme();
// Some indicators we'll use in a few places
let check = console_helpers::checkmark();
let notice = console_helpers::notice();
*/

// TODO(migration): implement interactive prompts

Ok(meta)
}
185 changes: 184 additions & 1 deletion cargo-dist/src/init/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,191 @@
pub(crate) mod v0;
pub use v0::do_init;
pub use v0::do_init as do_init_v0;
mod apply_dist;
pub mod console_helpers;
mod dist_profile;
mod init_args;
mod interactive;

use axoproject::WorkspaceGraph;
use console_helpers::theme;
use crate::{do_generate, GenerateArgs};
use crate::SortedMap;
use crate::config::{self, Config, v1::TomlLayer};
use crate::errors::DistResult;
use crate::migrate;
pub use dist_profile::init_dist_profile;
pub use init_args::InitArgs;
use serde::Deserialize;

/// Input for --with-json-config
///
/// Contains a TomlLayer (V1 equivalent of DistMetadata) for [dist] and
/// then optionally ones for each package.
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
struct MultiDistMetadata {
/// `[dist]`
workspace: TomlLayer,
/// package_name => `[package]`
#[serde(default)]
packages: SortedMap<String, TomlLayer>,
}

fn migrate_if_needed(cfg: &Config, args: &InitArgs) -> DistResult<()> {
if migrate::needs_migration()? && !args.yes {
let prompt = r#"Would you like to opt in to the new configuration format?
Future versions of dist will feature major changes to the configuration format."#;
let is_migrating = dialoguer::Confirm::with_theme(&theme())
.with_prompt(prompt)
.default(false)
.interact()?;

if is_migrating {
migrate::do_migrate()?;
return do_init(cfg, args);
}
}

Ok(())
}

fn initialize_cargo_profile_if_needed(workspaces: &WorkspaceGraph) -> DistResult<()> {
// For each [workspace] Cargo.toml in the workspaces, initialize [profile]
let mut did_add_profile = false;

Check failure on line 54 in cargo-dist/src/init/mod.rs

View workflow job for this annotation

GitHub Actions / clippy

variable does not need to be mutable

error: variable does not need to be mutable --> cargo-dist/src/init/mod.rs:54:9 | 54 | let mut did_add_profile = false; | ----^^^^^^^^^^^^^^^ | | | help: remove this `mut`

Check failure on line 54 in cargo-dist/src/init/mod.rs

View workflow job for this annotation

GitHub Actions / clippy

variable does not need to be mutable

error: variable does not need to be mutable --> cargo-dist/src/init/mod.rs:54:9 | 54 | let mut did_add_profile = false; | ----^^^^^^^^^^^^^^^ | | | help: remove this `mut`
for workspace_idx in workspaces.all_workspace_indices() {
let workspace = workspaces.workspace(workspace_idx);

Check failure on line 56 in cargo-dist/src/init/mod.rs

View workflow job for this annotation

GitHub Actions / clippy

unused variable: `workspace`

error: unused variable: `workspace` --> cargo-dist/src/init/mod.rs:56:13 | 56 | let workspace = workspaces.workspace(workspace_idx); | ^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_workspace`

Check failure on line 56 in cargo-dist/src/init/mod.rs

View workflow job for this annotation

GitHub Actions / clippy

unused variable: `workspace`

error: unused variable: `workspace` --> cargo-dist/src/init/mod.rs:56:13 | 56 | let workspace = workspaces.workspace(workspace_idx); | ^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_workspace`
// TODO(migration): re-implement this.
/*if workspace.kind == WorkspaceKind::Rust {
let mut workspace_toml = config::load_toml(&workspace.manifest_path)?;
did_add_profile |= init_dist_profile(cfg, &mut workspace_toml)?;
config::write_toml(&workspace.manifest_path, workspace_toml)?;
}*/
}

if did_add_profile {
let check = console_helpers::checkmark();
eprintln!("{check} added [profile.dist] to your workspace Cargo.toml");
}

Ok(())
}

fn collect_metadata(cfg: &Config, args: &InitArgs, workspaces: &WorkspaceGraph) -> DistResult<MultiDistMetadata> {
let workspace = interactive::get_new_metadata(cfg, args, &workspaces)?;
let packages: SortedMap<String, TomlLayer> = SortedMap::new();

Ok(MultiDistMetadata {
workspace,
packages,
})
}

fn update_cargo_packages_if_needed(workspaces: &WorkspaceGraph, multi_meta: &MultiDistMetadata) -> DistResult<()> {
// Now that we've done the stuff that's definitely part of the root Cargo.toml,
// Optionally apply updates to packages
for (_idx, package) in workspaces.all_packages() {
// Gather up all the things we'd like to be written to this file
let meta = multi_meta.packages.get(&package.name);
let needs_edit = meta.is_some();

if needs_edit {
// Ok we have changes to make, let's load the toml
let mut package_toml = config::load_toml(&package.manifest_path)?;
let metadata = config::get_toml_metadata(&mut package_toml, false);

// Apply [package.metadata.dist]
let mut writing_metadata = false;
if let Some(meta) = meta {
apply_dist::apply_dist_to_metadata(metadata, meta);
writing_metadata = true;
}

// Save the result
config::write_toml(&package.manifest_path, package_toml)?;
if writing_metadata {
eprintln!(
"{check} added [package.metadata.dist] to {}'s Cargo.toml",

Check failure on line 107 in cargo-dist/src/init/mod.rs

View workflow job for this annotation

GitHub Actions / clippy

cannot find value `check` in this scope

error[E0425]: cannot find value `check` in this scope --> cargo-dist/src/init/mod.rs:107:23 | 107 | "{check} added [package.metadata.dist] to {}'s Cargo.toml", | ^^^^^ not found in this scope

Check failure on line 107 in cargo-dist/src/init/mod.rs

View workflow job for this annotation

GitHub Actions / clippy

cannot find value `check` in this scope

error[E0425]: cannot find value `check` in this scope --> cargo-dist/src/init/mod.rs:107:23 | 107 | "{check} added [package.metadata.dist] to {}'s Cargo.toml", | ^^^^^ not found in this scope
package.name
);
}
}
}

Ok(())
}

/// Run 'dist init'
pub fn do_init(cfg: &Config, args: &InitArgs) -> DistResult<()> {
if !config::want_v1()? {
return do_init_v0(cfg, args);
}

// The flow for `dist init` is:
// 1. `dist migrate` if needed
// 2. fetch workspace config
// 3. initialize Cargo.toml [profile] tables if needed
// 4. collect metadata
// 5. apply config changes in-memory
// 6. write config to file
// 7. `dist generate` if needed

let ctrlc_handler = console_helpers::ctrlc_handler();
let check = console_helpers::checkmark();

// 1. run `dist migrate` if we're on a v0 config.
migrate_if_needed(cfg, args)?;

eprintln!("let's setup your dist config...");
eprintln!();

// 2. fetch workspace config.
let workspaces = config::get_project()?;

// 3. initialize Cargo.toml [profile] tables, if needed.
initialize_cargo_profile_if_needed(&workspaces)?;

// 4. collect metadata.
let multi_meta = collect_metadata(cfg, args, &workspaces)?;

// We're past the final dialoguer call; we can remove the ctrl-c handler.
ctrlc_handler.abort();

let root_workspace = workspaces.root_workspace();

// Load in the root workspace toml to edit and write back
let mut workspace_toml = config::load_toml(&root_workspace.manifest_path)?;

apply_dist::apply_dist_to_workspace_toml(&mut workspace_toml, &multi_meta.workspace);

eprintln!();

let filename = root_workspace
.manifest_path
.file_name()
.unwrap_or("dist-workspace.toml");
let destination = root_workspace.manifest_path.to_owned();

// Save the workspace toml (potentially an effective no-op if we made no edits)
config::write_toml(&destination, workspace_toml)?;
let key = "[dist]";
eprintln!("{check} added {key} to your root {filename}");

// 3. initialize Cargo.toml [profile] tables if needed
update_cargo_packages_if_needed(&workspaces, &multi_meta)?;

eprintln!("{check} dist is setup!");
eprintln!();

// regenerate anything that needs to be
if !args.no_generate {
eprintln!("running 'dist generate' to apply any changes");
eprintln!();

let ci_args = GenerateArgs {
check: false,
modes: vec![],
};
do_generate(cfg, &ci_args)?;
}
Ok(())
}
Loading