cargo-cache 0.8.3

Manage cargo cache ($CARGO_HOME or ~/.cargo/), show sizes and remove directories selectively
// Copyright 2019-2020 Matthias Krüger. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

THIS FILE IS COMMENTED OUT ON PURPOSE
The old alternative registry index test has been replaced by the current one!




#[path = "../src/test_helpers.rs"]
mod test_helpers;

use std::fs::OpenOptions;
use std::io::prelude::*;
use std::path::PathBuf;
use std::process::Command;

use crate::test_helpers::bin_path;
use regex::Regex;

#[allow(non_snake_case)]
#[test]
fn alternative_registry_works() {
    // make sure alternative registries work

    // first create a $CARGO_HOME with a config file
    let cargo_home_path = {
        let mut path = PathBuf::from("target");
        path.push("alt_registries_CARGO_HOME");
        path
    };

    std::fs::create_dir_all(&cargo_home_path)
        .expect("Failed to create 'alt_registries_CARGO_HOME' dir");

    // get the path to the config file inside the $CARGO_HOME: target/alt_registries_CARGO_HOME/config
    let cargo_config_file_path: PathBuf = {
        let mut path = cargo_home_path.clone();
        path.push("config");
        path
    };

    println!(
        "DEBUG: cargo config file path: '{:?}'",
        cargo_config_file_path
    );

    let registry_index: PathBuf = {
        let mut path = PathBuf::from("target");
        path.push("my-index");
        path
    };

    // clone the crates io index into "target/my-index"
    if !registry_index.exists() {
        // @TODO: clean up
        println!("DEBUG: cloning registry index into target/my-index");
        let git_clone_cmd = Command::new("git")
            .arg("clone")
            .arg("https://github.com/rust-lang/crates.io-index")
            .arg("--quiet")
            .arg("my-index")
            .current_dir("target")
            .output();

        let status = git_clone_cmd.unwrap();
        let stderr = String::from_utf8_lossy(&status.stderr).to_string();
        let stdout = String::from_utf8_lossy(&status.stdout).to_string();

        if !status.status.success() {
            println!("error while git cloning");
            println!("stderr:\n{:?}", stderr);
            println!("stdout:\n{:?}", stdout);
            println!("status: {:?}", status);
            panic!("error while git cloning");
        }

        println!("ERR {:?}", stderr);
        println!("OUT {:?}", stdout);
    }

    // path where the alternative registry is located
    let my_registry_path = {
        let mut path = PathBuf::from("target");
        path.push("my-index");
        path
    };

    // next we need to set up the alternative registry inside the ${CARGO_HOME}/config

    let mut cfg_file_handle = std::fs::File::create(&cargo_config_file_path)
        .expect("failed to create cargo home config file!");

    // we need an absolute path to my-index
    let index_path_absolute = {
        let cwd = std::env::current_dir().unwrap();
        let mut path: PathBuf = cwd;
        path.push(&my_registry_path);
        path
    };
    // I don't know how to make this pass on windows
    // use a hack for travis-ci
    // I always got a parsing error on travis:
    /*
    "error: could not load Cargo configuration

    Caused by:
      could not parse TOML configuration in `\\\\?\\C:\\Users\\travis\\build\\matthiaskrgr\\cargo-cache\\target\\alt_registries_CARGO_HOME\\config`

      Caused by:
        could not parse input as TOML
        Caused by:
          invalid escape character in string: `C` at line 2\n"
    */
    // no idea what's the problem here, help would be appreciated

    // make it take this path on travis ci
    let index_path: String = if cfg!(windows) && (std::env::var("TRAVIS") == Ok("true".to_string()))
    {
        String::from("file://C:/Users/travis/build/matthiaskrgr/cargo-cache/target/my-index")
    } else {
        let mut s = String::from("file://");
        s.push_str(&index_path_absolute.display().to_string());
        s
    };

    // this is the content of the cargo home config
    let config_text: &str = &format!(
        "[registries]
my-index = {{ index = '{}' }}\n",
        index_path
    );

    println!("DEBUG: config text:\n{}\n", config_text);
    // write the content into the config file
    cfg_file_handle
        .write_all(config_text.as_bytes())
        .expect("failed to fill cargo home config file");

    // the path where we try to build a test crate
    let project_path = {
        let mut path = PathBuf::from("target");
        path.push("test_crate");
        path
    };

    println!("DEBUG: creating dummy crate: '{:?}'", project_path);
    if !project_path.exists() {
        // @TODO cleanup
        let cargo_new_cmd = Command::new("cargo")
            .arg("new")
            .arg("--quiet")
            .arg(project_path.display().to_string())
            .output();

        let status = cargo_new_cmd.unwrap();
        let stderr = String::from_utf8_lossy(&status.stderr).to_string();
        let stdout = String::from_utf8_lossy(&status.stdout).to_string();

        if !status.status.success() {
            println!("error while running 'cargo new'");
            println!("stderr:\n{:?}", stderr);
            println!("stdout:\n{:?}", stdout);
            println!("status: {:?}", status);
            panic!("error while cargo new dummy crate");
        }
        println!("ERR {:?}", stderr);
        println!("OUT {:?}", stdout);
    }

    let crate_toml = {
        let mut path = project_path.clone();
        path.push("Cargo.toml");
        path
    };

    // open the file
    let mut file = OpenOptions::new().append(true).open(&crate_toml).unwrap();

    let crate_toml_content = std::fs::read_to_string(&crate_toml).unwrap();

    // only run this if we have not yet edited the toml
    if !crate_toml_content.contains("regex") {
        // add additional dependencies to the file, one from crates.io and one from our custom registry
        let additionl_cargo_toml_text = String::from(
            r#"regex = "*"
rayon = { version = "1", registry = "my-index" }
"#,
        );
        for line in additionl_cargo_toml_text.lines() {
            writeln!(file, "{}", line).unwrap();
        }
    }

    // get the absolute path to our cargo_home
    let cargo_home_path_absolute: PathBuf = {
        let mut path: PathBuf = std::env::current_dir().unwrap();
        path.push(cargo_home_path);
        path
    };

    // run the build command to force cargo to use the alternative registry
    // and fill the cargo_home with the alternative registry
    let build_cmd = Command::new("cargo")
        .arg("check")
        .current_dir(&project_path)
        .env("CARGO_HOME", cargo_home_path_absolute.display().to_string())
        .output()
        .unwrap();

    let status = build_cmd.status;
    let stderr = String::from_utf8_lossy(&build_cmd.stderr).to_string();
    let stdout = String::from_utf8_lossy(&build_cmd.stdout).to_string();

    // @TODO handle all  command::new() calls that way!
    if !build_cmd.status.success() {
        println!("error while cargo building test crate");
        println!("stderr:\n{:?}", stderr);
        println!("stdout:\n{:?}", stdout);
        println!("status: {:?}", status);
        panic!("error while building test crate");
    }

    println!("ERR {:?}", stderr);
    println!("OUT {:?}", stdout);

    // run cargo cache on the new cargo_home
    let cargo_cache_cmd = Command::new(bin_path())
        .env("CARGO_HOME", cargo_home_path_absolute.display().to_string())
        .output()
        .unwrap();

    if !cargo_cache_cmd.status.success() {
        println!("error running cargo-cache on alt reg $CARGO_HOME");
        println!("stderr:\n{:?}", stderr);
        println!("stdout:\n{:?}", stdout);
        println!("status: {:?}", status);
        panic!("error while running cargo-home with alt regs");
    }

    let stdout = String::from_utf8_lossy(&cargo_cache_cmd.stdout).to_string();

    println!("DEBUG: cargo-cache output:\n\n{}", stdout);
    // check if the output is what we expect

    let mut desired_output = String::from("Cargo cache .*target.*alt_registries_CARGO_HOME.*\n\n");

    /*
    Cargo cache '/home/matthias/vcs/github/cargo-cache/target/alt_registries_CARGO_HOME':

    Total:                              219.45 MB
      0 installed binaries:                  0  B
      Registry:                         219.45 MB
        2 registry indices:                 211.80 MB
        22 crate archives:                1.39 MB
        22 crate source checkouts:        6.25 MB
      Git db:                                0  B
        0 bare git repos:                    0  B
        0 git repo checkouts:                0  B
        */

    desired_output.push_str(
        "Total:                .* MB
  0 installed binaries:               0  B
  Registry:                    .* MB
    2 registry indices:        .* MB
    .. crate archives:         .* MB
    .. crate source checkouts: .* MB
  Git db:                             0  B
    0 bare git repos:                 0  B
    0 git repo checkouts:             0  B",
    );

    let regex = Regex::new(&desired_output).unwrap();

    assert!(
        regex.clone().is_match(&stdout),
        "ERROR: regex did not match!\n\nregex:\n{:?}\n\ncc_output:\n{:?}",
        regex,
        stdout
    );
}