Skip to content

Commit

Permalink
Make Cargo obey platform-specific directory standards
Browse files Browse the repository at this point in the history
Strategy for backward-compatiblity:

When checking for the relevant Cargo directories, check in the following
order of preference:

1) Use the environment variable `CARGO_HOME`.
2) Use the platform-specific directories if they exist.
3) Use the legacy location (~/.cargo) if it exists.
4) Fall back to the platform-specific directories if everything else fails.

The new platform-specific directories are as follows:

On Windows, use `AppData\Local\Temp\Cargo` for cache files (obtained via
`GetTempPath`), `AppData\Roaming\Cargo` for the config files
(`FOLDERID_RoamingAppData`) and `AppData\Local\Programs\Cargo` for
installed binaries (`FOLDERID_UserProgramFiles`).

On Unixy systems, use the XDG spec: `~/.cache/cargo` for cache files,
`~/.config/cargo` for config, `~/.local/bin` for installed binaries.

http://standards.freedesktop.org/basedir-spec/basedir-spec-0.8.html
http://www.freedesktop.org/software/systemd/man/file-hierarchy.html

On OS X, use `~/Library/Caches/Cargo` for cache files, `~/Library/Cargo`
for config files and `~/Library/Cargo/bin` for binary files.

Fixes rust-lang#1734. Fixes rust-lang#1976.
  • Loading branch information
tbu- committed Jan 25, 2016
1 parent 859c5d3 commit 21416c5
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 47 deletions.
45 changes: 45 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ advapi32-sys = "0.1"
crates-io = { path = "src/crates-io", version = "0.1" }
crossbeam = "0.2"
curl = "0.2"
dirs = "0.2"
docopt = "0.6"
env_logger = "0.3"
filetime = "0.1"
Expand Down
2 changes: 1 addition & 1 deletion src/bin/cargo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ fn is_executable(metadata: &fs::Metadata) -> bool {
}

fn search_directories(config: &Config) -> Vec<PathBuf> {
let mut dirs = vec![config.home().join("bin")];
let mut dirs = vec![config.bin_path()];
if let Some(val) = env::var_os("PATH") {
dirs.extend(env::split_paths(&val));
}
Expand Down
1 change: 1 addition & 0 deletions src/cargo/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
extern crate crates_io as registry;
extern crate crossbeam;
extern crate curl;
extern crate dirs;
extern crate docopt;
extern crate filetime;
extern crate flate2;
Expand Down
49 changes: 33 additions & 16 deletions src/cargo/ops/cargo_install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,20 @@ use ops::{self, CompileFilter};
use sources::{GitSource, PathSource, RegistrySource};
use util::{CargoResult, ChainError, Config, human, internal};

struct Paths {
bin: PathBuf,
config: PathBuf,
}

impl Paths {
fn from_root(root: PathBuf) -> Paths {
Paths {
bin: root.join("bin"),
config: root,
}
}
}

#[derive(RustcDecodable, RustcEncodable)]
enum CrateListing {
V1(CrateListingV1),
Expand Down Expand Up @@ -43,7 +57,7 @@ pub fn install(root: Option<&str>,
vers: Option<&str>,
opts: &ops::CompileOptions) -> CargoResult<()> {
let config = opts.config;
let root = try!(resolve_root(root, config));
let paths = try!(resolve_paths(root, config));
let (pkg, source) = if source_id.is_git() {
try!(select_pkg(GitSource::new(source_id, config), source_id,
krate, vers, &mut |git| git.read_packages()))
Expand All @@ -61,9 +75,9 @@ pub fn install(root: Option<&str>,
specify alternate source"))))
};

let mut list = try!(read_crate_list(&root));
let dst = root.join("bin");
try!(check_overwrites(&dst, &pkg, &opts.filter, &list));
let mut list = try!(read_crate_list(&paths.config));
let dst = &paths.bin;
try!(check_overwrites(dst, &pkg, &opts.filter, &list));

let target_dir = config.cwd().join("target-install");
config.set_target_dir(&target_dir);
Expand All @@ -73,7 +87,7 @@ pub fn install(root: Option<&str>,
}));

let mut t = Transaction { bins: Vec::new() };
try!(fs::create_dir_all(&dst));
try!(fs::create_dir_all(dst));
for bin in compile.binaries.iter() {
let dst = dst.join(bin.file_name().unwrap());
try!(config.shell().status("Installing", dst.display()));
Expand All @@ -90,15 +104,15 @@ pub fn install(root: Option<&str>,
}).extend(t.bins.iter().map(|t| {
t.file_name().unwrap().to_string_lossy().into_owned()
}));
try!(write_crate_list(&root, list));
try!(write_crate_list(&paths.config, list));

t.bins.truncate(0);

// Print a warning that if this directory isn't in PATH that they won't be
// able to run these commands.
let path = env::var_os("PATH").unwrap_or(OsString::new());
for path in env::split_paths(&path) {
if path == dst {
if &path == dst {
return Ok(())
}
}
Expand Down Expand Up @@ -262,8 +276,8 @@ fn write_crate_list(path: &Path, listing: CrateListingV1) -> CargoResult<()> {
}

pub fn install_list(dst: Option<&str>, config: &Config) -> CargoResult<()> {
let dst = try!(resolve_root(dst, config));
let list = try!(read_crate_list(&dst));
let paths = try!(resolve_paths(dst, config));
let list = try!(read_crate_list(&paths.config));
let mut shell = config.shell();
let out = shell.out();
for (k, v) in list.v1.iter() {
Expand All @@ -279,8 +293,8 @@ pub fn uninstall(root: Option<&str>,
spec: &str,
bins: &[String],
config: &Config) -> CargoResult<()> {
let root = try!(resolve_root(root, config));
let mut metadata = try!(read_crate_list(&root));
let paths = try!(resolve_paths(root, config));
let mut metadata = try!(read_crate_list(&paths.config));
let mut to_remove = Vec::new();
{
let result = try!(PackageIdSpec::query_str(spec, metadata.v1.keys()))
Expand All @@ -289,7 +303,7 @@ pub fn uninstall(root: Option<&str>,
Entry::Occupied(e) => e,
Entry::Vacant(..) => panic!("entry not found: {}", result),
};
let dst = root.join("bin");
let dst = &paths.bin;
for bin in installed.get() {
let bin = dst.join(bin);
if fs::metadata(&bin).is_err() {
Expand Down Expand Up @@ -325,7 +339,7 @@ pub fn uninstall(root: Option<&str>,
installed.remove();
}
}
try!(write_crate_list(&root, metadata));
try!(write_crate_list(&paths.config, metadata));
for bin in to_remove {
try!(config.shell().status("Removing", bin.display()));
try!(fs::remove_file(bin));
Expand All @@ -334,13 +348,16 @@ pub fn uninstall(root: Option<&str>,
Ok(())
}

fn resolve_root(flag: Option<&str>, config: &Config) -> CargoResult<PathBuf> {
fn resolve_paths(flag: Option<&str>, config: &Config) -> CargoResult<Paths> {
let config_root = try!(config.get_string("install.root"));
Ok(flag.map(PathBuf::from).or_else(|| {
env::var_os("CARGO_INSTALL_ROOT").map(PathBuf::from)
}).or_else(|| {
config_root.clone().map(|(v, _)| PathBuf::from(v))
}).unwrap_or_else(|| {
config.home().to_owned()
}).map(|r| Paths::from_root(r)).unwrap_or_else(|| {
Paths {
bin: config.bin_path(),
config: config.config_path(),
}
}))
}
Loading

0 comments on commit 21416c5

Please sign in to comment.