mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-21 17:52:12 +03:00
Rename cargo to rustpkg and start over fresh
This commit is contained in:
+6
-6
@@ -131,7 +131,7 @@ CFG_STDLIB :=$(call CFG_LIB_NAME,std)
|
||||
CFG_LIBRUSTC :=$(call CFG_LIB_NAME,rustc)
|
||||
CFG_LIBSYNTAX :=$(call CFG_LIB_NAME,syntax)
|
||||
CFG_LIBFUZZER :=$(call CFG_LIB_NAME,fuzzer)
|
||||
CFG_LIBCARGO :=$(call CFG_LIB_NAME,cargo)
|
||||
CFG_LIBRUSTPKG :=$(call CFG_LIB_NAME,rustpkg)
|
||||
CFG_LIBRUSTDOC :=$(call CFG_LIB_NAME,rustdoc)
|
||||
CFG_LIBRUSTI :=$(call CFG_LIB_NAME,rusti)
|
||||
|
||||
@@ -140,7 +140,7 @@ CORELIB_GLOB :=$(call CFG_LIB_GLOB,core)
|
||||
LIBRUSTC_GLOB :=$(call CFG_LIB_GLOB,rustc)
|
||||
LIBSYNTAX_GLOB :=$(call CFG_LIB_GLOB,syntax)
|
||||
LIBFUZZER_GLOB :=$(call CFG_LIB_GLOB,fuzzer)
|
||||
LIBCARGO_GLOB :=$(call CFG_LIB_GLOB,cargo)
|
||||
LIBRUSTPKG_GLOB :=$(call CFG_LIB_GLOB,rustpkg)
|
||||
LIBRUSTDOC_GLOB :=$(call CFG_LIB_GLOB,rustdoc)
|
||||
LIBRUSTI_GLOB :=$(call CFG_LIB_GLOB,rusti)
|
||||
STDLIB_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,std)
|
||||
@@ -148,7 +148,7 @@ CORELIB_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,core)
|
||||
LIBRUSTC_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,rustc)
|
||||
LIBSYNTAX_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,syntax)
|
||||
LIBFUZZER_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,fuzzer)
|
||||
LIBCARGO_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,cargo)
|
||||
LIBRUSTPKG_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,rustpkg)
|
||||
LIBRUSTDOC_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,rustdoc)
|
||||
LIBRUSTI_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,rusti)
|
||||
|
||||
@@ -371,11 +371,11 @@ SREQ$(1)_T_$(2)_H_$(3) = \
|
||||
CSREQ$(1)_T_$(2)_H_$(3) = \
|
||||
$$(TSREQ$(1)_T_$(2)_H_$(3)) \
|
||||
$$(HBIN$(1)_H_$(3))/fuzzer$$(X) \
|
||||
$$(HBIN$(1)_H_$(3))/cargo$$(X) \
|
||||
$$(HBIN$(1)_H_$(3))/rustpkg$$(X) \
|
||||
$$(HBIN$(1)_H_$(3))/rustdoc$$(X) \
|
||||
$$(HBIN$(1)_H_$(3))/rusti$$(X) \
|
||||
$$(HLIB$(1)_H_$(3))/$$(CFG_LIBFUZZER) \
|
||||
$$(HLIB$(1)_H_$(3))/$$(CFG_LIBCARGO) \
|
||||
$$(HLIB$(1)_H_$(3))/$$(CFG_LIBRUSTPKG) \
|
||||
$$(HLIB$(1)_H_$(3))/$$(CFG_LIBRUSTDOC) \
|
||||
$$(HLIB$(1)_H_$(3))/$$(CFG_LIBRUSTI) \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_CORELIB) \
|
||||
@@ -383,7 +383,7 @@ CSREQ$(1)_T_$(2)_H_$(3) = \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBSYNTAX) \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC) \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBFUZZER) \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBCARGO) \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTPKG) \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTDOC) \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTI)
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ for more information on them.
|
||||
|
||||
When complete, `make install` will place several programs into
|
||||
`/usr/local/bin`: `rustc`, the Rust compiler; `rustdoc`, the
|
||||
API-documentation tool, and `cargo`, the Rust package manager.
|
||||
API-documentation tool, and `rustpkg`, the Rust package manager and build system.
|
||||
|
||||
[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust
|
||||
[tarball]: http://static.rust-lang.org/dist/rust-0.5.tar.gz
|
||||
|
||||
+6
-6
@@ -64,12 +64,12 @@ define CLEAN_HOST_STAGE_N
|
||||
clean$(1)_H_$(2):
|
||||
$(Q)rm -f $$(HBIN$(1)_H_$(2))/rustc$(X)
|
||||
$(Q)rm -f $$(HBIN$(1)_H_$(2))/fuzzer$(X)
|
||||
$(Q)rm -f $$(HBIN$(1)_H_$(2))/cargo$(X)
|
||||
$(Q)rm -f $$(HBIN$(1)_H_$(2))/rustpkg$(X)
|
||||
$(Q)rm -f $$(HBIN$(1)_H_$(2))/serializer$(X)
|
||||
$(Q)rm -f $$(HBIN$(1)_H_$(2))/rustdoc$(X)
|
||||
$(Q)rm -f $$(HBIN$(1)_H_$(2))/rusti$(X)
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBFUZZER)
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBCARGO)
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTPKG)
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTDOC)
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_RUNTIME)
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_CORELIB)
|
||||
@@ -82,7 +82,7 @@ clean$(1)_H_$(2):
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTC_GLOB)
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBSYNTAX_GLOB)
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBFUZZER_GLOB)
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBCARGO_GLOB)
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTPKG_GLOB)
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTDOC_GLOB)
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTI_GLOB)
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_RUSTLLVM)
|
||||
@@ -99,11 +99,11 @@ define CLEAN_TARGET_STAGE_N
|
||||
clean$(1)_T_$(2)_H_$(3):
|
||||
$(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rustc$(X)
|
||||
$(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/fuzzer$(X)
|
||||
$(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/cargo$(X)
|
||||
$(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rustpkg$(X)
|
||||
$(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/serializer$(X)
|
||||
$(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rustdoc$(X)
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBFUZZER)
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBCARGO)
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTPKG)
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTDOC)
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUNTIME)
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_CORELIB)
|
||||
@@ -115,7 +115,7 @@ clean$(1)_T_$(2)_H_$(3):
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTC_GLOB)
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBSYNTAX_GLOB)
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBFUZZER_GLOB)
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBCARGO_GLOB)
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTPKG_GLOB)
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTDOC_GLOB)
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUSTLLVM)
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/libstd.rlib
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ PKG_FILES := \
|
||||
$(addprefix $(S)src/, \
|
||||
README.txt \
|
||||
driver \
|
||||
libcargo \
|
||||
librustpkg \
|
||||
librusti \
|
||||
librustc \
|
||||
compiletest \
|
||||
|
||||
+6
-6
@@ -55,7 +55,7 @@ install-target-$(1)-host-$(2): $$(CSREQ$$(ISTAGE)_T_$(1)_H_$(2))
|
||||
$$(Q)$$(call INSTALL_LIB, \
|
||||
$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(LIBSYNTAX_GLOB))
|
||||
$$(Q)$$(call INSTALL_LIB, \
|
||||
$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(LIBCARGO_GLOB))
|
||||
$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(LIBRUSTPKG_GLOB))
|
||||
$$(Q)$$(call INSTALL_LIB, \
|
||||
$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(LIBRUSTDOC_GLOB))
|
||||
$$(Q)$$(call INSTALL_LIB, \
|
||||
@@ -87,11 +87,11 @@ install-host: $(CSREQ$(ISTAGE)_T_$(CFG_HOST_TRIPLE)_H_$(CFG_HOST_TRIPLE))
|
||||
$(Q)mkdir -p $(PREFIX_LIB)
|
||||
$(Q)mkdir -p $(PREFIX_ROOT)/share/man/man1
|
||||
$(Q)$(call INSTALL,$(HB2),$(PHB),rustc$(X))
|
||||
$(Q)$(call INSTALL,$(HB2),$(PHB),cargo$(X))
|
||||
$(Q)$(call INSTALL,$(HB2),$(PHB),rustpkg$(X))
|
||||
$(Q)$(call INSTALL,$(HB2),$(PHB),rustdoc$(X))
|
||||
$(Q)$(call INSTALL,$(HB2),$(PHB),rusti$(X))
|
||||
$(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_LIBRUSTC))
|
||||
$(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_LIBCARGO))
|
||||
$(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_LIBRUSTPKG))
|
||||
$(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_LIBRUSTDOC))
|
||||
$(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_LIBRUSTI))
|
||||
$(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(CORELIB_GLOB))
|
||||
@@ -112,11 +112,11 @@ HOST_LIB_FROM_HL_GLOB = \
|
||||
|
||||
uninstall:
|
||||
$(Q)rm -f $(PHB)/rustc$(X)
|
||||
$(Q)rm -f $(PHB)/cargo$(X)
|
||||
$(Q)rm -f $(PHB)/rustpkg$(X)
|
||||
$(Q)rm -f $(PHB)/rusti$(X)
|
||||
$(Q)rm -f $(PHB)/rustdoc$(X)
|
||||
$(Q)rm -f $(PHL)/$(CFG_RUSTLLVM)
|
||||
$(Q)rm -f $(PHL)/$(CFG_LIBCARGO)
|
||||
$(Q)rm -f $(PHL)/$(CFG_LIBRUSTPKG)
|
||||
$(Q)rm -f $(PHL)/$(CFG_LIBRUSTC)
|
||||
$(Q)rm -f $(PHL)/$(CFG_LIBRUSTDOC)
|
||||
$(Q)rm -f $(PHL)/$(CFG_LIBRUSTI)
|
||||
@@ -126,7 +126,7 @@ uninstall:
|
||||
$(call HOST_LIB_FROM_HL_GLOB,$(STDLIB_GLOB)) \
|
||||
$(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTC_GLOB)) \
|
||||
$(call HOST_LIB_FROM_HL_GLOB,$(LIBSYNTAX_GLOB)) \
|
||||
$(call HOST_LIB_FROM_HL_GLOB,$(LIBCARGO_GLOB)) \
|
||||
$(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTPKG_GLOB)) \
|
||||
$(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTDOC_GLOB)) \
|
||||
$(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTI_GLOB)) \
|
||||
; \
|
||||
|
||||
@@ -18,7 +18,7 @@ else
|
||||
$(wildcard $(S)src/test/*/*.rs \
|
||||
$(S)src/test/*/*/*.rs) \
|
||||
$(wildcard $(S)src/fuzzer/*.rs) \
|
||||
$(wildcard $(S)src/cargo/*.rs) \
|
||||
$(wildcard $(S)src/rustpkg/*.rs) \
|
||||
$(wildcard $(S)src/rusti/*.rs)
|
||||
|
||||
PP_INPUTS_FILTERED = $(shell echo $(PP_INPUTS) | xargs grep -L \
|
||||
|
||||
+3
-3
@@ -14,7 +14,7 @@
|
||||
######################################################################
|
||||
|
||||
# The names of crates that must be tested
|
||||
TEST_CRATES = core std syntax rustc rustdoc rusti cargo
|
||||
TEST_CRATES = core std syntax rustc rustdoc rusti rustpkg
|
||||
|
||||
# Markdown files under doc/ that should have their code extracted and run
|
||||
DOC_TEST_NAMES = tutorial tutorial-ffi tutorial-macros tutorial-borrowed-ptr tutorial-tasks rust
|
||||
@@ -229,8 +229,8 @@ $(3)/test/rustctest.stage$(1)-$(2)$$(X): \
|
||||
@$$(call E, compile_and_link: $$@)
|
||||
$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
|
||||
|
||||
$(3)/test/cargotest.stage$(1)-$(2)$$(X): \
|
||||
$$(CARGO_LIB) $$(CARGO_INPUTS) \
|
||||
$(3)/test/rustpkgtest.stage$(1)-$(2)$$(X): \
|
||||
$$(RUSTPKG_LIB) $$(RUSTPKG_INPUTS) \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC)
|
||||
@$$(call E, compile_and_link: $$@)
|
||||
$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
|
||||
|
||||
+16
-16
@@ -14,13 +14,13 @@
|
||||
FUZZER_LIB := $(S)src/libfuzzer/fuzzer.rc
|
||||
FUZZER_INPUTS := $(wildcard $(addprefix $(S)src/libfuzzer/, *.rs))
|
||||
|
||||
# The test runner that runs the cfail/rfail/rpass and bench tests
|
||||
# The test runner that runs the cfail/rfail/rpass and bxench tests
|
||||
COMPILETEST_CRATE := $(S)src/compiletest/compiletest.rc
|
||||
COMPILETEST_INPUTS := $(wildcard $(S)src/compiletest/*rs)
|
||||
|
||||
# Cargo, the package manager
|
||||
CARGO_LIB := $(S)src/libcargo/cargo.rc
|
||||
CARGO_INPUTS := $(wildcard $(S)src/libcargo/*rs)
|
||||
# Rustpkg, the package manager and build system
|
||||
RUSTPKG_LIB := $(S)src/librustpkg/rustpkg.rc
|
||||
RUSTPKG_INPUTS := $(wildcard $(S)src/librustpkg/*rs)
|
||||
|
||||
# Rustdoc, the documentation tool
|
||||
RUSTDOC_LIB := $(S)src/librustdoc/rustdoc.rc
|
||||
@@ -57,8 +57,8 @@ $$(TBIN$(1)_T_$(4)_H_$(3))/compiletest$$(X): \
|
||||
@$$(call E, compile_and_link: $$@)
|
||||
$$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$<
|
||||
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBCARGO): \
|
||||
$$(CARGO_LIB) $$(CARGO_INPUTS) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBRUSTPKG): \
|
||||
$$(RUSTPKG_LIB) $$(RUSTPKG_INPUTS) \
|
||||
$$(TSREQ$(1)_T_$(4)_H_$(3)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_CORELIB) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_STDLIB) \
|
||||
@@ -66,11 +66,11 @@ $$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBCARGO): \
|
||||
@$$(call E, compile_and_link: $$@)
|
||||
$$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$< && touch $$@
|
||||
|
||||
$$(TBIN$(1)_T_$(4)_H_$(3))/cargo$$(X): \
|
||||
$$(TBIN$(1)_T_$(4)_H_$(3))/rustpkg$$(X): \
|
||||
$$(DRIVER_CRATE) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBCARGO)
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBRUSTPKG)
|
||||
@$$(call E, compile_and_link: $$@)
|
||||
$$(STAGE$(1)_T_$(4)_H_$(3)) --cfg cargo -o $$@ $$<
|
||||
$$(STAGE$(1)_T_$(4)_H_$(3)) --cfg rustpkg -o $$@ $$<
|
||||
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBRUSTDOC): \
|
||||
$$(RUSTDOC_LIB) $$(RUSTDOC_INPUTS) \
|
||||
@@ -134,19 +134,19 @@ $$(HBIN$(2)_H_$(4))/compiletest$$(X): \
|
||||
$$(Q)cp $$< $$@
|
||||
|
||||
|
||||
$$(HLIB$(2)_H_$(4))/$$(CFG_LIBCARGO): \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBCARGO) \
|
||||
$$(HLIB$(2)_H_$(4))/$$(CFG_LIBRUSTPKG): \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBRUSTPKG) \
|
||||
$$(HLIB$(2)_H_$(4))/$$(CFG_LIBRUSTC) \
|
||||
$$(HSREQ$(2)_H_$(4))
|
||||
@$$(call E, cp: $$@)
|
||||
$$(Q)cp $$< $$@
|
||||
$$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBCARGO_GLOB) \
|
||||
$$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBCARGO_DSYM_GLOB)) \
|
||||
$$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTPKG_GLOB) \
|
||||
$$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTPKG_DSYM_GLOB)) \
|
||||
$$(HLIB$(2)_H_$(4))
|
||||
|
||||
$$(HBIN$(2)_H_$(4))/cargo$$(X): \
|
||||
$$(TBIN$(1)_T_$(4)_H_$(3))/cargo$$(X) \
|
||||
$$(HLIB$(2)_H_$(4))/$$(CFG_LIBCARGO) \
|
||||
$$(HBIN$(2)_H_$(4))/rustpkg$$(X): \
|
||||
$$(TBIN$(1)_T_$(4)_H_$(3))/rustpkg$$(X) \
|
||||
$$(HLIB$(2)_H_$(4))/$$(CFG_LIBRUSTPKG) \
|
||||
$$(HSREQ$(2)_H_$(4))
|
||||
@$$(call E, cp: $$@)
|
||||
$$(Q)cp $$< $$@
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ test/auxiliary - Dependencies of tests
|
||||
|
||||
compiletest/ The test runner
|
||||
|
||||
libcargo/ The package manager
|
||||
librustpkg/ The package manager and build system
|
||||
|
||||
librusti/ The JIT REPL
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
#[no_core];
|
||||
extern mod core(vers = "0.6");
|
||||
|
||||
#[cfg(cargo)]
|
||||
extern mod this(name = "cargo", vers = "0.6");
|
||||
#[cfg(rustpkg)]
|
||||
extern mod this(name = "rustpkg", vers = "0.6");
|
||||
|
||||
#[cfg(fuzzer)]
|
||||
extern mod this(name = "fuzzer", vers = "0.6");
|
||||
|
||||
@@ -1,1981 +0,0 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// 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.
|
||||
|
||||
|
||||
// cargo.rs - Rust package manager
|
||||
|
||||
// Local Variables:
|
||||
// fill-column: 78;
|
||||
// indent-tabs-mode: nil
|
||||
// c-basic-offset: 4
|
||||
// buffer-file-coding-system: utf-8-unix
|
||||
// End:
|
||||
|
||||
#[link(name = "cargo",
|
||||
vers = "0.6",
|
||||
uuid = "9ff87a04-8fed-4295-9ff8-f99bb802650b",
|
||||
url = "https://github.com/mozilla/rust/tree/master/src/cargo")];
|
||||
|
||||
#[crate_type = "lib"];
|
||||
|
||||
#[no_core];
|
||||
|
||||
#[legacy_modes];
|
||||
|
||||
#[allow(vecs_implicitly_copyable,
|
||||
non_implicitly_copyable_typarams)];
|
||||
#[allow(non_camel_case_types)];
|
||||
#[allow(deprecated_mode)];
|
||||
#[allow(deprecated_pattern)];
|
||||
#[allow(deprecated_self)];
|
||||
|
||||
extern mod core(vers = "0.6");
|
||||
extern mod std(vers = "0.6");
|
||||
extern mod rustc(vers = "0.6");
|
||||
extern mod syntax(vers = "0.6");
|
||||
|
||||
mod pgp;
|
||||
|
||||
use rustc::metadata::filesearch::{get_cargo_root, get_cargo_root_nearest};
|
||||
use rustc::metadata::filesearch::{get_cargo_sysroot, libdir};
|
||||
|
||||
use core::*;
|
||||
|
||||
use core::dvec::DVec;
|
||||
use core::io::WriterUtil;
|
||||
use core::result::{Ok, Err};
|
||||
use core::hashmap::linear::LinearMap;
|
||||
use std::getopts::{optflag, optopt, opt_present};
|
||||
use std::oldmap::HashMap;
|
||||
use std::{oldmap, json, tempfile, term, sort, getopts};
|
||||
use syntax::codemap::span;
|
||||
use syntax::diagnostic::span_handler;
|
||||
use syntax::diagnostic;
|
||||
use syntax::{ast, codemap, parse, visit, attr};
|
||||
|
||||
pub struct Package {
|
||||
name: ~str,
|
||||
uuid: ~str,
|
||||
url: ~str,
|
||||
method: ~str,
|
||||
description: ~str,
|
||||
reference: Option<~str>,
|
||||
tags: ~[~str],
|
||||
versions: ~[(~str, ~str)]
|
||||
}
|
||||
|
||||
pub impl cmp::Ord for Package {
|
||||
pure fn lt(&self, other: &Package) -> bool {
|
||||
if (*self).name.lt(&(*other).name) { return true; }
|
||||
if (*other).name.lt(&(*self).name) { return false; }
|
||||
if (*self).uuid.lt(&(*other).uuid) { return true; }
|
||||
if (*other).uuid.lt(&(*self).uuid) { return false; }
|
||||
if (*self).url.lt(&(*other).url) { return true; }
|
||||
if (*other).url.lt(&(*self).url) { return false; }
|
||||
if (*self).method.lt(&(*other).method) { return true; }
|
||||
if (*other).method.lt(&(*self).method) { return false; }
|
||||
if (*self).description.lt(&(*other).description) { return true; }
|
||||
if (*other).description.lt(&(*self).description) { return false; }
|
||||
if (*self).tags.lt(&(*other).tags) { return true; }
|
||||
if (*other).tags.lt(&(*self).tags) { return false; }
|
||||
if (*self).versions.lt(&(*other).versions) { return true; }
|
||||
return false;
|
||||
}
|
||||
pure fn le(&self, other: &Package) -> bool { !(*other).lt(&(*self)) }
|
||||
pure fn ge(&self, other: &Package) -> bool { !(*self).lt(other) }
|
||||
pure fn gt(&self, other: &Package) -> bool { (*other).lt(&(*self)) }
|
||||
}
|
||||
|
||||
pub struct Source {
|
||||
name: ~str,
|
||||
mut url: ~str,
|
||||
mut method: ~str,
|
||||
mut key: Option<~str>,
|
||||
mut keyfp: Option<~str>,
|
||||
packages: DVec<Package>
|
||||
}
|
||||
|
||||
pub struct Cargo {
|
||||
pgp: bool,
|
||||
root: Path,
|
||||
installdir: Path,
|
||||
bindir: Path,
|
||||
libdir: Path,
|
||||
workdir: Path,
|
||||
sourcedir: Path,
|
||||
sources: oldmap::HashMap<~str, @Source>,
|
||||
mut current_install: ~str,
|
||||
dep_cache: oldmap::HashMap<~str, bool>,
|
||||
opts: Options
|
||||
}
|
||||
|
||||
pub struct Crate {
|
||||
name: ~str,
|
||||
vers: ~str,
|
||||
uuid: ~str,
|
||||
desc: Option<~str>,
|
||||
sigs: Option<~str>,
|
||||
crate_type: Option<~str>,
|
||||
deps: ~[~str]
|
||||
}
|
||||
|
||||
pub struct Options {
|
||||
test: bool,
|
||||
mode: Mode,
|
||||
free: ~[~str],
|
||||
help: bool,
|
||||
}
|
||||
|
||||
#[deriving_eq]
|
||||
pub enum Mode { SystemMode, UserMode, LocalMode }
|
||||
|
||||
pub fn opts() -> ~[getopts::Opt] {
|
||||
~[optflag(~"g"), optflag(~"G"), optflag(~"test"),
|
||||
optflag(~"h"), optflag(~"help")]
|
||||
}
|
||||
|
||||
pub fn info(msg: ~str) {
|
||||
let out = io::stdout();
|
||||
|
||||
if term::color_supported() {
|
||||
term::fg(out, term::color_green);
|
||||
out.write_str(~"info: ");
|
||||
term::reset(out);
|
||||
out.write_line(msg);
|
||||
} else { out.write_line(~"info: " + msg); }
|
||||
}
|
||||
|
||||
pub fn warn(msg: ~str) {
|
||||
let out = io::stdout();
|
||||
|
||||
if term::color_supported() {
|
||||
term::fg(out, term::color_yellow);
|
||||
out.write_str(~"warning: ");
|
||||
term::reset(out);
|
||||
out.write_line(msg);
|
||||
}else { out.write_line(~"warning: " + msg); }
|
||||
}
|
||||
|
||||
pub fn error(msg: ~str) {
|
||||
let out = io::stdout();
|
||||
|
||||
if term::color_supported() {
|
||||
term::fg(out, term::color_red);
|
||||
out.write_str(~"error: ");
|
||||
term::reset(out);
|
||||
out.write_line(msg);
|
||||
}
|
||||
else { out.write_line(~"error: " + msg); }
|
||||
}
|
||||
|
||||
pub fn is_uuid(id: ~str) -> bool {
|
||||
let parts = str::split_str(id, ~"-");
|
||||
if vec::len(parts) == 5u {
|
||||
let mut correct = 0u;
|
||||
for vec::eachi(parts) |i, part| {
|
||||
fn is_hex_digit(+ch: char) -> bool {
|
||||
('0' <= ch && ch <= '9') ||
|
||||
('a' <= ch && ch <= 'f') ||
|
||||
('A' <= ch && ch <= 'F')
|
||||
}
|
||||
|
||||
if !part.all(is_hex_digit) {
|
||||
return false;
|
||||
}
|
||||
|
||||
match i {
|
||||
0u => {
|
||||
if part.len() == 8u {
|
||||
correct += 1u;
|
||||
}
|
||||
}
|
||||
1u | 2u | 3u => {
|
||||
if part.len() == 4u {
|
||||
correct += 1u;
|
||||
}
|
||||
}
|
||||
4u => {
|
||||
if part.len() == 12u {
|
||||
correct += 1u;
|
||||
}
|
||||
}
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
if correct >= 5u {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_is_uuid() {
|
||||
assert is_uuid(~"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaafAF09");
|
||||
assert !is_uuid(~"aaaaaaaa-aaaa-aaaa-aaaaa-aaaaaaaaaaaa");
|
||||
assert !is_uuid(~"");
|
||||
assert !is_uuid(~"aaaaaaaa-aaa -aaaa-aaaa-aaaaaaaaaaaa");
|
||||
assert !is_uuid(~"aaaaaaaa-aaa!-aaaa-aaaa-aaaaaaaaaaaa");
|
||||
assert !is_uuid(~"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa-a");
|
||||
assert !is_uuid(~"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaป");
|
||||
}
|
||||
|
||||
// FIXME (#2661): implement url/URL parsing so we don't have to resort
|
||||
// to weak checks
|
||||
|
||||
pub fn has_archive_extension(p: ~str) -> bool {
|
||||
str::ends_with(p, ~".tar") ||
|
||||
str::ends_with(p, ~".tar.gz") ||
|
||||
str::ends_with(p, ~".tar.bz2") ||
|
||||
str::ends_with(p, ~".tar.Z") ||
|
||||
str::ends_with(p, ~".tar.lz") ||
|
||||
str::ends_with(p, ~".tar.xz") ||
|
||||
str::ends_with(p, ~".tgz") ||
|
||||
str::ends_with(p, ~".tbz") ||
|
||||
str::ends_with(p, ~".tbz2") ||
|
||||
str::ends_with(p, ~".tb2") ||
|
||||
str::ends_with(p, ~".taz") ||
|
||||
str::ends_with(p, ~".tlz") ||
|
||||
str::ends_with(p, ~".txz")
|
||||
}
|
||||
|
||||
pub fn is_archive_path(u: ~str) -> bool {
|
||||
has_archive_extension(u) && os::path_exists(&Path(u))
|
||||
}
|
||||
|
||||
pub fn is_archive_url(u: ~str) -> bool {
|
||||
// FIXME (#2661): this requires the protocol bit - if we had proper
|
||||
// url parsing, we wouldn't need it
|
||||
|
||||
match str::find_str(u, ~"://") {
|
||||
option::Some(_) => has_archive_extension(u),
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_git_url(url: ~str) -> bool {
|
||||
if str::ends_with(url, ~"/") { str::ends_with(url, ~".git/") }
|
||||
else {
|
||||
str::starts_with(url, ~"git://") || str::ends_with(url, ~".git")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn assume_source_method(url: ~str) -> ~str {
|
||||
if is_git_url(url) {
|
||||
return ~"git";
|
||||
}
|
||||
if str::starts_with(url, ~"file://") || os::path_exists(&Path(url)) {
|
||||
return ~"file";
|
||||
}
|
||||
|
||||
~"curl"
|
||||
}
|
||||
|
||||
pub fn load_link(mis: ~[@ast::meta_item]) -> (Option<~str>,
|
||||
Option<~str>,
|
||||
Option<~str>) {
|
||||
let mut name = None;
|
||||
let mut vers = None;
|
||||
let mut uuid = None;
|
||||
for mis.each |a| {
|
||||
match a.node {
|
||||
ast::meta_name_value(v, codemap::spanned { node: ast::lit_str(s),
|
||||
_ }) => {
|
||||
match v {
|
||||
~"name" => name = Some(*s),
|
||||
~"vers" => vers = Some(*s),
|
||||
~"uuid" => uuid = Some(*s),
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
_ => fail!(~"load_link: meta items must be name-values")
|
||||
}
|
||||
}
|
||||
(name, vers, uuid)
|
||||
}
|
||||
|
||||
pub fn load_crate(filename: &Path) -> Option<Crate> {
|
||||
let sess = parse::new_parse_sess(None);
|
||||
let c = parse::parse_crate_from_file(filename, ~[], sess);
|
||||
|
||||
let mut name = None;
|
||||
let mut vers = None;
|
||||
let mut uuid = None;
|
||||
let mut desc = None;
|
||||
let mut sigs = None;
|
||||
let mut crate_type = None;
|
||||
|
||||
for c.node.attrs.each |a| {
|
||||
match a.node.value.node {
|
||||
ast::meta_name_value(v, codemap::spanned { node: ast::lit_str(_),
|
||||
_ }) => {
|
||||
match v {
|
||||
~"desc" => desc = Some(v),
|
||||
~"sigs" => sigs = Some(v),
|
||||
~"crate_type" => crate_type = Some(v),
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
ast::meta_list(v, mis) => {
|
||||
if v == ~"link" {
|
||||
let (n, v, u) = load_link(mis);
|
||||
name = n;
|
||||
vers = v;
|
||||
uuid = u;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
fail!(~"crate attributes may not contain " +
|
||||
~"meta_words");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Env {
|
||||
mut deps: ~[~str]
|
||||
}
|
||||
|
||||
fn goto_view_item(ps: syntax::parse::parse_sess, e: @Env,
|
||||
i: @ast::view_item) {
|
||||
match i.node {
|
||||
ast::view_item_use(ident, metas, _) => {
|
||||
let name_items =
|
||||
attr::find_meta_items_by_name(metas, ~"name");
|
||||
let m = if name_items.is_empty() {
|
||||
metas + ~[attr::mk_name_value_item_str(
|
||||
~"name", *ps.interner.get(ident))]
|
||||
} else {
|
||||
metas
|
||||
};
|
||||
let mut attr_name = ident;
|
||||
let mut attr_vers = ~"";
|
||||
let mut attr_from = ~"";
|
||||
|
||||
for m.each |item| {
|
||||
match attr::get_meta_item_value_str(*item) {
|
||||
Some(value) => {
|
||||
let name = attr::get_meta_item_name(*item);
|
||||
|
||||
match name {
|
||||
~"vers" => attr_vers = value,
|
||||
~"from" => attr_from = value,
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
|
||||
let query = if !str::is_empty(attr_from) {
|
||||
attr_from
|
||||
} else {
|
||||
if !str::is_empty(attr_vers) {
|
||||
ps.interner.get(attr_name) + ~"@" + attr_vers
|
||||
} else { *ps.interner.get(attr_name) }
|
||||
};
|
||||
|
||||
match *ps.interner.get(attr_name) {
|
||||
~"std" | ~"core" => (),
|
||||
_ => e.deps.push(query)
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
fn goto_item(_e: @Env, _i: @ast::item) {
|
||||
}
|
||||
|
||||
let e = @Env {
|
||||
mut deps: ~[]
|
||||
};
|
||||
let v = visit::mk_simple_visitor(@visit::SimpleVisitor {
|
||||
visit_view_item: |a| goto_view_item(sess, e, a),
|
||||
visit_item: |a| goto_item(e, a),
|
||||
.. *visit::default_simple_visitor()
|
||||
});
|
||||
|
||||
visit::visit_crate(*c, (), v);
|
||||
|
||||
let deps = copy e.deps;
|
||||
|
||||
match (name, vers, uuid) {
|
||||
(Some(name0), Some(vers0), Some(uuid0)) => {
|
||||
Some(Crate {
|
||||
name: name0,
|
||||
vers: vers0,
|
||||
uuid: uuid0,
|
||||
desc: desc,
|
||||
sigs: sigs,
|
||||
crate_type: crate_type,
|
||||
deps: deps })
|
||||
}
|
||||
_ => return None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print(s: ~str) {
|
||||
io::stdout().write_line(s);
|
||||
}
|
||||
|
||||
pub fn rest(s: ~str, start: uint) -> ~str {
|
||||
if (start >= str::len(s)) {
|
||||
~""
|
||||
} else {
|
||||
str::slice(s, start, str::len(s))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn need_dir(s: &Path) {
|
||||
if os::path_is_dir(s) { return; }
|
||||
if !os::make_dir(s, 493_i32 /* oct: 755 */) {
|
||||
fail!(fmt!("can't make_dir %s", s.to_str()));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn valid_pkg_name(s: &str) -> bool {
|
||||
fn is_valid_digit(+c: char) -> bool {
|
||||
('0' <= c && c <= '9') ||
|
||||
('a' <= c && c <= 'z') ||
|
||||
('A' <= c && c <= 'Z') ||
|
||||
c == '-' ||
|
||||
c == '_'
|
||||
}
|
||||
|
||||
s.all(is_valid_digit)
|
||||
}
|
||||
|
||||
pub fn parse_source(name: ~str, j: &json::Json) -> @Source {
|
||||
if !valid_pkg_name(name) {
|
||||
fail!(fmt!("'%s' is an invalid source name", name));
|
||||
}
|
||||
|
||||
match *j {
|
||||
json::Object(ref j) => {
|
||||
let mut url = match j.find(&~"url") {
|
||||
Some(&json::String(u)) => copy u,
|
||||
_ => fail!(~"needed 'url' field in source")
|
||||
};
|
||||
let method = match j.find(&~"method") {
|
||||
Some(&json::String(u)) => copy u,
|
||||
_ => assume_source_method(url)
|
||||
};
|
||||
let key = match j.find(&~"key") {
|
||||
Some(&json::String(u)) => Some(copy u),
|
||||
_ => None
|
||||
};
|
||||
let keyfp = match j.find(&~"keyfp") {
|
||||
Some(&json::String(u)) => Some(copy u),
|
||||
_ => None
|
||||
};
|
||||
if method == ~"file" {
|
||||
url = os::make_absolute(&Path(url)).to_str();
|
||||
}
|
||||
return @Source {
|
||||
name: name,
|
||||
mut url: url,
|
||||
mut method: method,
|
||||
mut key: key,
|
||||
mut keyfp: keyfp,
|
||||
packages: DVec() };
|
||||
}
|
||||
_ => fail!(~"needed dict value in source")
|
||||
};
|
||||
}
|
||||
|
||||
pub fn try_parse_sources(filename: &Path,
|
||||
sources: oldmap::HashMap<~str, @Source>) {
|
||||
if !os::path_exists(filename) { return; }
|
||||
let c = io::read_whole_file_str(filename);
|
||||
match json::from_str(c.get()) {
|
||||
Ok(json::Object(j)) => {
|
||||
for j.each |&(k, v)| {
|
||||
sources.insert(copy *k, parse_source(*k, v));
|
||||
debug!("source: %s", *k);
|
||||
}
|
||||
}
|
||||
Ok(_) => fail!(~"malformed sources.json"),
|
||||
Err(e) => fail!(fmt!("%s:%s", filename.to_str(), e.to_str()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_one_source_package(src: @Source, p: &json::Object) {
|
||||
let name = match p.find(&~"name") {
|
||||
Some(&json::String(n)) => {
|
||||
if !valid_pkg_name(n) {
|
||||
warn(~"malformed source json: "
|
||||
+ src.name + ~", '" + n + ~"'"+
|
||||
~" is an invalid name (alphanumeric, underscores and" +
|
||||
~" dashes only)");
|
||||
return;
|
||||
}
|
||||
n
|
||||
}
|
||||
_ => {
|
||||
warn(~"malformed source json: " + src.name + ~" (missing name)");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let uuid = match p.find(&~"uuid") {
|
||||
Some(&json::String(n)) => {
|
||||
if !is_uuid(n) {
|
||||
warn(~"malformed source json: "
|
||||
+ src.name + ~", '" + n + ~"'"+
|
||||
~" is an invalid uuid");
|
||||
return;
|
||||
}
|
||||
copy n
|
||||
}
|
||||
_ => {
|
||||
warn(~"malformed source json: " + src.name + ~" (missing uuid)");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let url = match p.find(&~"url") {
|
||||
Some(&json::String(n)) => copy n,
|
||||
_ => {
|
||||
warn(~"malformed source json: " + src.name + ~" (missing url)");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let method = match p.find(&~"method") {
|
||||
Some(&json::String(n)) => copy n,
|
||||
_ => {
|
||||
warn(~"malformed source json: "
|
||||
+ src.name + ~" (missing method)");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let reference = match p.find(&~"ref") {
|
||||
Some(&json::String(n)) => Some(copy n),
|
||||
_ => None
|
||||
};
|
||||
|
||||
let mut tags = ~[];
|
||||
match p.find(&~"tags") {
|
||||
Some(&json::List(ref js)) => {
|
||||
for js.each |j| {
|
||||
match *j {
|
||||
json::String(ref j) => tags.grow(1u, j),
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
let description = match p.find(&~"description") {
|
||||
Some(&json::String(n)) => copy n,
|
||||
_ => {
|
||||
warn(~"malformed source json: " + src.name
|
||||
+ ~" (missing description)");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let newpkg = Package {
|
||||
name: name,
|
||||
uuid: uuid,
|
||||
url: url,
|
||||
method: method,
|
||||
description: description,
|
||||
reference: reference,
|
||||
tags: tags,
|
||||
versions: ~[]
|
||||
};
|
||||
|
||||
match src.packages.position(|pkg| pkg.uuid == uuid) {
|
||||
Some(idx) => {
|
||||
src.packages.set_elt(idx, newpkg);
|
||||
log(debug, ~" updated package: " + src.name + ~"/" + name);
|
||||
}
|
||||
None => {
|
||||
src.packages.push(newpkg);
|
||||
}
|
||||
}
|
||||
|
||||
log(debug, ~" loaded package: " + src.name + ~"/" + name);
|
||||
}
|
||||
|
||||
pub fn load_source_info(c: &Cargo, src: @Source) {
|
||||
let dir = c.sourcedir.push(src.name);
|
||||
let srcfile = dir.push("source.json");
|
||||
if !os::path_exists(&srcfile) { return; }
|
||||
let srcstr = io::read_whole_file_str(&srcfile);
|
||||
match json::from_str(srcstr.get()) {
|
||||
Ok(ref json @ json::Object(_)) => {
|
||||
let o = parse_source(src.name, json);
|
||||
|
||||
src.key = o.key;
|
||||
src.keyfp = o.keyfp;
|
||||
}
|
||||
Ok(_) => {
|
||||
warn(~"malformed source.json: " + src.name +
|
||||
~"(source info is not a dict)");
|
||||
}
|
||||
Err(e) => {
|
||||
warn(fmt!("%s:%s", src.name, e.to_str()));
|
||||
}
|
||||
};
|
||||
}
|
||||
pub fn load_source_packages(c: &Cargo, src: @Source) {
|
||||
log(debug, ~"loading source: " + src.name);
|
||||
let dir = c.sourcedir.push(src.name);
|
||||
let pkgfile = dir.push("packages.json");
|
||||
if !os::path_exists(&pkgfile) { return; }
|
||||
let pkgstr = io::read_whole_file_str(&pkgfile);
|
||||
match json::from_str(pkgstr.get()) {
|
||||
Ok(json::List(ref js)) => {
|
||||
for js.each |j| {
|
||||
match *j {
|
||||
json::Object(ref p) => {
|
||||
load_one_source_package(src, *p);
|
||||
}
|
||||
_ => {
|
||||
warn(~"malformed source json: " + src.name +
|
||||
~" (non-dict pkg)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(_) => {
|
||||
warn(~"malformed packages.json: " + src.name +
|
||||
~"(packages is not a list)");
|
||||
}
|
||||
Err(e) => {
|
||||
warn(fmt!("%s:%s", src.name, e.to_str()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn build_cargo_options(argv: ~[~str]) -> Options {
|
||||
let matches = &match getopts::getopts(argv, opts()) {
|
||||
result::Ok(m) => m,
|
||||
result::Err(f) => {
|
||||
fail!(fmt!("%s", getopts::fail_str(f)));
|
||||
}
|
||||
};
|
||||
|
||||
let test = opt_present(matches, ~"test");
|
||||
let G = opt_present(matches, ~"G");
|
||||
let g = opt_present(matches, ~"g");
|
||||
let help = opt_present(matches, ~"h") || opt_present(matches, ~"help");
|
||||
let len = vec::len(matches.free);
|
||||
|
||||
let is_install = len > 1u && matches.free[1] == ~"install";
|
||||
let is_uninstall = len > 1u && matches.free[1] == ~"uninstall";
|
||||
|
||||
if G && g { fail!(~"-G and -g both provided"); }
|
||||
|
||||
if !is_install && !is_uninstall && (g || G) {
|
||||
fail!(~"-g and -G are only valid for `install` and `uninstall|rm`");
|
||||
}
|
||||
|
||||
let mode =
|
||||
if (!is_install && !is_uninstall) || g { UserMode }
|
||||
else if G { SystemMode }
|
||||
else { LocalMode };
|
||||
|
||||
Options {test: test, mode: mode, free: matches.free, help: help}
|
||||
}
|
||||
|
||||
pub fn configure(opts: Options) -> Cargo {
|
||||
let home = match get_cargo_root() {
|
||||
Ok(home) => home,
|
||||
Err(_err) => get_cargo_sysroot().get()
|
||||
};
|
||||
|
||||
let get_cargo_dir = match opts.mode {
|
||||
SystemMode => get_cargo_sysroot,
|
||||
UserMode => get_cargo_root,
|
||||
LocalMode => get_cargo_root_nearest
|
||||
};
|
||||
|
||||
let p = get_cargo_dir().get();
|
||||
|
||||
let sources = HashMap();
|
||||
try_parse_sources(&home.push("sources.json"), sources);
|
||||
try_parse_sources(&home.push("local-sources.json"), sources);
|
||||
|
||||
let dep_cache = HashMap();
|
||||
|
||||
let mut c = Cargo {
|
||||
pgp: pgp::supported(),
|
||||
root: home,
|
||||
installdir: p,
|
||||
bindir: p.push("bin"),
|
||||
libdir: p.push("lib"),
|
||||
workdir: p.push("work"),
|
||||
sourcedir: home.push("sources"),
|
||||
sources: sources,
|
||||
mut current_install: ~"",
|
||||
dep_cache: dep_cache,
|
||||
opts: opts
|
||||
};
|
||||
|
||||
need_dir(&c.root);
|
||||
need_dir(&c.installdir);
|
||||
need_dir(&c.sourcedir);
|
||||
need_dir(&c.workdir);
|
||||
need_dir(&c.libdir);
|
||||
need_dir(&c.bindir);
|
||||
|
||||
for sources.each_key |&k| {
|
||||
let mut s = sources.get(&k);
|
||||
load_source_packages(&c, s);
|
||||
sources.insert(k, s);
|
||||
}
|
||||
|
||||
if c.pgp {
|
||||
pgp::init(&c.root);
|
||||
} else {
|
||||
warn(~"command `gpg` was not found");
|
||||
warn(~"you have to install gpg from source " +
|
||||
~" or package manager to get it to work correctly");
|
||||
}
|
||||
|
||||
c
|
||||
}
|
||||
|
||||
pub fn for_each_package(c: &Cargo, b: fn(s: @Source, p: &Package)) {
|
||||
for c.sources.each_value |&v| {
|
||||
for v.packages.each |p| {
|
||||
b(v, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Runs all programs in directory <buildpath>
|
||||
pub fn run_programs(buildpath: &Path) {
|
||||
let newv = os::list_dir_path(buildpath);
|
||||
for newv.each |ct| {
|
||||
run::run_program(ct.to_str(), ~[]);
|
||||
}
|
||||
}
|
||||
|
||||
// Runs rustc in <path + subdir> with the given flags
|
||||
// and returns <patho + subdir>
|
||||
pub fn run_in_buildpath(what: &str, path: &Path, subdir: &Path, cf: &Path,
|
||||
extra_flags: ~[~str]) -> Option<Path> {
|
||||
let buildpath = path.push_rel(subdir);
|
||||
need_dir(&buildpath);
|
||||
debug!("%s: %s -> %s", what, cf.to_str(), buildpath.to_str());
|
||||
let p = run::program_output(rustc_sysroot(),
|
||||
~[~"--out-dir",
|
||||
buildpath.to_str(),
|
||||
cf.to_str()] + extra_flags);
|
||||
if p.status != 0 {
|
||||
error(fmt!("rustc failed: %d\n%s\n%s", p.status, p.err, p.out));
|
||||
return None;
|
||||
}
|
||||
Some(buildpath)
|
||||
}
|
||||
|
||||
pub fn test_one_crate(_c: &Cargo, path: &Path, cf: &Path) {
|
||||
let buildpath = match run_in_buildpath(~"testing", path,
|
||||
&Path("test"),
|
||||
cf,
|
||||
~[ ~"--test"]) {
|
||||
None => return,
|
||||
Some(bp) => bp
|
||||
};
|
||||
run_programs(&buildpath);
|
||||
}
|
||||
|
||||
pub fn install_one_crate(c: &Cargo, path: &Path, cf: &Path) {
|
||||
let buildpath = match run_in_buildpath(~"installing", path,
|
||||
&Path("build"),
|
||||
cf, ~[]) {
|
||||
None => return,
|
||||
Some(bp) => bp
|
||||
};
|
||||
let newv = os::list_dir_path(&buildpath);
|
||||
let exec_suffix = str::from_slice(os::EXE_SUFFIX);
|
||||
for newv.each |ct| {
|
||||
if (exec_suffix != ~"" && str::ends_with(ct.to_str(),
|
||||
exec_suffix)) ||
|
||||
(exec_suffix == ~"" &&
|
||||
!str::starts_with(ct.filename().get(),
|
||||
~"lib")) {
|
||||
debug!(" bin: %s", ct.to_str());
|
||||
install_to_dir(*ct, &c.bindir);
|
||||
if c.opts.mode == SystemMode {
|
||||
// FIXME (#2662): Put this file in PATH / symlink it so it can
|
||||
// be used as a generic executable
|
||||
// `cargo install -G rustray` and `rustray file.obj`
|
||||
}
|
||||
} else {
|
||||
debug!(" lib: %s", ct.to_str());
|
||||
install_to_dir(*ct, &c.libdir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn rustc_sysroot() -> ~str {
|
||||
match os::self_exe_path() {
|
||||
Some(path) => {
|
||||
let rustc = path.push_many([~"..", ~"bin", ~"rustc"]);
|
||||
debug!(" rustc: %s", rustc.to_str());
|
||||
rustc.to_str()
|
||||
}
|
||||
None => ~"rustc"
|
||||
}
|
||||
}
|
||||
|
||||
pub fn install_source(c: &mut Cargo, path: &Path) {
|
||||
debug!("source: %s", path.to_str());
|
||||
os::change_dir(path);
|
||||
|
||||
let mut cratefiles = ~[];
|
||||
for os::walk_dir(&Path(".")) |p| {
|
||||
if p.filetype() == Some(~".rc") {
|
||||
cratefiles.push(*p);
|
||||
}
|
||||
}
|
||||
|
||||
if vec::is_empty(cratefiles) {
|
||||
fail!(~"this doesn't look like a rust package (no .rc files)");
|
||||
}
|
||||
|
||||
for cratefiles.each |cf| {
|
||||
match load_crate(cf) {
|
||||
None => loop,
|
||||
Some(crate) => {
|
||||
for crate.deps.each |query| {
|
||||
// FIXME (#1356): handle cyclic dependencies
|
||||
// (n.b. #1356 says "Cyclic dependency is an error
|
||||
// condition")
|
||||
|
||||
let wd = get_temp_workdir(c);
|
||||
install_query(c, &wd, *query);
|
||||
}
|
||||
|
||||
os::change_dir(path);
|
||||
|
||||
if c.opts.test {
|
||||
test_one_crate(c, path, cf);
|
||||
}
|
||||
install_one_crate(c, path, cf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn install_git(c: &mut Cargo, wd: &Path, url: ~str,
|
||||
reference: Option<~str>) {
|
||||
run::program_output(~"git", ~[~"clone", url, wd.to_str()]);
|
||||
if reference.is_some() {
|
||||
let r = reference.get();
|
||||
os::change_dir(wd);
|
||||
run::run_program(~"git", ~[~"checkout", r]);
|
||||
}
|
||||
|
||||
install_source(c, wd);
|
||||
}
|
||||
|
||||
pub fn install_curl(c: &mut Cargo, wd: &Path, url: ~str) {
|
||||
let tarpath = wd.push("pkg.tar");
|
||||
let p = run::program_output(~"curl", ~[~"-f", ~"-s", ~"-o",
|
||||
tarpath.to_str(), url]);
|
||||
if p.status != 0 {
|
||||
fail!(fmt!("fetch of %s failed: %s", url, p.err));
|
||||
}
|
||||
run::run_program(~"tar", ~[~"-x", ~"--strip-components=1",
|
||||
~"-C", wd.to_str(),
|
||||
~"-f", tarpath.to_str()]);
|
||||
install_source(c, wd);
|
||||
}
|
||||
|
||||
pub fn install_file(c: &mut Cargo, wd: &Path, path: &Path) {
|
||||
run::program_output(~"tar", ~[~"-x", ~"--strip-components=1",
|
||||
~"-C", wd.to_str(),
|
||||
~"-f", path.to_str()]);
|
||||
install_source(c, wd);
|
||||
}
|
||||
|
||||
pub fn install_package(c: &mut Cargo, src: ~str, wd: &Path, pkg: Package) {
|
||||
let url = copy pkg.url;
|
||||
let method = match pkg.method {
|
||||
~"git" => ~"git",
|
||||
~"file" => ~"file",
|
||||
_ => ~"curl"
|
||||
};
|
||||
|
||||
info(fmt!("installing %s/%s via %s...", src, pkg.name, method));
|
||||
|
||||
match method {
|
||||
~"git" => install_git(c, wd, url, copy pkg.reference),
|
||||
~"file" => install_file(c, wd, &Path(url)),
|
||||
~"curl" => install_curl(c, wd, url),
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cargo_suggestion(c: &Cargo, fallback: fn()) {
|
||||
if c.sources.is_empty() {
|
||||
error(~"no sources defined - you may wish to run " +
|
||||
~"`cargo init`");
|
||||
return;
|
||||
}
|
||||
fallback();
|
||||
}
|
||||
|
||||
pub fn install_uuid(c: &mut Cargo, wd: &Path, uuid: ~str) {
|
||||
let mut ps = ~[];
|
||||
for_each_package(c, |s, p| {
|
||||
if p.uuid == uuid {
|
||||
vec::push(&mut ps, (s.name, copy *p));
|
||||
}
|
||||
});
|
||||
if vec::len(ps) == 1u {
|
||||
let (sname, p) = copy ps[0];
|
||||
install_package(c, sname, wd, p);
|
||||
return;
|
||||
} else if vec::len(ps) == 0u {
|
||||
cargo_suggestion(c, || {
|
||||
error(~"can't find package: " + uuid);
|
||||
});
|
||||
return;
|
||||
}
|
||||
error(~"found multiple packages:");
|
||||
for ps.each |elt| {
|
||||
let (sname,p) = copy *elt;
|
||||
info(~" " + sname + ~"/" + p.uuid + ~" (" + p.name + ~")");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn install_named(c: &mut Cargo, wd: &Path, name: ~str) {
|
||||
let mut ps = ~[];
|
||||
for_each_package(c, |s, p| {
|
||||
if p.name == name {
|
||||
vec::push(&mut ps, (s.name, copy *p));
|
||||
}
|
||||
});
|
||||
if vec::len(ps) == 1u {
|
||||
let (sname, p) = copy ps[0];
|
||||
install_package(c, sname, wd, p);
|
||||
return;
|
||||
} else if vec::len(ps) == 0u {
|
||||
cargo_suggestion(c, || {
|
||||
error(~"can't find package: " + name);
|
||||
});
|
||||
return;
|
||||
}
|
||||
error(~"found multiple packages:");
|
||||
for ps.each |elt| {
|
||||
let (sname,p) = copy *elt;
|
||||
info(~" " + sname + ~"/" + p.uuid + ~" (" + p.name + ~")");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn install_uuid_specific(c: &mut Cargo, wd: &Path, src: ~str,
|
||||
uuid: ~str) {
|
||||
match c.sources.find(&src) {
|
||||
Some(s) => {
|
||||
for s.packages.each |p| {
|
||||
if p.uuid == uuid {
|
||||
install_package(c, src, wd, *p);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
error(~"can't find package: " + src + ~"/" + uuid);
|
||||
}
|
||||
|
||||
pub fn install_named_specific(c: &mut Cargo, wd: &Path, src: ~str,
|
||||
name: ~str) {
|
||||
match c.sources.find(&src) {
|
||||
Some(s) => {
|
||||
for s.packages.each |p| {
|
||||
if p.name == name {
|
||||
install_package(c, src, wd, *p);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
error(~"can't find package: " + src + ~"/" + name);
|
||||
}
|
||||
|
||||
pub fn cmd_uninstall(c: &Cargo) {
|
||||
if vec::len(c.opts.free) < 3u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
let lib = &c.libdir;
|
||||
let bin = &c.bindir;
|
||||
let target = c.opts.free[2u];
|
||||
|
||||
// FIXME (#2662): needs stronger pattern matching
|
||||
// FIXME (#2662): needs to uninstall from a specified location in a
|
||||
// cache instead of looking for it (binaries can be uninstalled by
|
||||
// name only)
|
||||
|
||||
fn try_uninstall(p: &Path) -> bool {
|
||||
if os::remove_file(p) {
|
||||
info(~"uninstalled: '" + p.to_str() + ~"'");
|
||||
true
|
||||
} else {
|
||||
error(~"could not uninstall: '" +
|
||||
p.to_str() + ~"'");
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
if is_uuid(target) {
|
||||
for os::list_dir(lib).each |file| {
|
||||
match str::find_str(*file, ~"-" + target + ~"-") {
|
||||
Some(_) => if !try_uninstall(&lib.push(*file)) { return },
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
error(~"can't find package with uuid: " + target);
|
||||
} else {
|
||||
for os::list_dir(lib).each |file| {
|
||||
match str::find_str(*file, ~"lib" + target + ~"-") {
|
||||
Some(_) => if !try_uninstall(&lib.push(*file)) { return },
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
for os::list_dir(bin).each |file| {
|
||||
match str::find_str(*file, target) {
|
||||
Some(_) => if !try_uninstall(&lib.push(*file)) { return },
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
|
||||
error(~"can't find package with name: " + target);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn install_query(c: &mut Cargo, wd: &Path, target: ~str) {
|
||||
match c.dep_cache.find(&target) {
|
||||
Some(inst) => {
|
||||
if inst {
|
||||
return;
|
||||
}
|
||||
}
|
||||
None => ()
|
||||
}
|
||||
|
||||
c.dep_cache.insert(target, true);
|
||||
|
||||
if is_archive_path(target) {
|
||||
install_file(c, wd, &Path(target));
|
||||
return;
|
||||
} else if is_git_url(target) {
|
||||
let reference = if c.opts.free.len() >= 4u {
|
||||
Some(c.opts.free[3u])
|
||||
} else {
|
||||
None
|
||||
};
|
||||
install_git(c, wd, target, reference);
|
||||
} else if !valid_pkg_name(target) && has_archive_extension(target) {
|
||||
install_curl(c, wd, target);
|
||||
return;
|
||||
} else {
|
||||
let mut ps = copy target;
|
||||
|
||||
match str::find_char(ps, '/') {
|
||||
option::Some(idx) => {
|
||||
let source = str::slice(ps, 0u, idx);
|
||||
ps = str::slice(ps, idx + 1u, str::len(ps));
|
||||
if is_uuid(ps) {
|
||||
install_uuid_specific(c, wd, source, ps);
|
||||
} else {
|
||||
install_named_specific(c, wd, source, ps);
|
||||
}
|
||||
}
|
||||
option::None => {
|
||||
if is_uuid(ps) {
|
||||
install_uuid(c, wd, ps);
|
||||
} else {
|
||||
install_named(c, wd, ps);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME (#2662): This whole dep_cache and current_install thing is
|
||||
// a bit of a hack. It should be cleaned up in the future.
|
||||
|
||||
if target == c.current_install {
|
||||
c.dep_cache.clear();
|
||||
c.current_install = ~"";
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_temp_workdir(c: &Cargo) -> Path {
|
||||
match tempfile::mkdtemp(&c.workdir, "cargo") {
|
||||
Some(wd) => wd,
|
||||
None => fail!(fmt!("needed temp dir: %s",
|
||||
c.workdir.to_str()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cmd_install(c: &mut Cargo) {
|
||||
unsafe {
|
||||
let wd = get_temp_workdir(c);
|
||||
|
||||
if vec::len(c.opts.free) == 2u {
|
||||
let cwd = os::getcwd();
|
||||
let status = run::run_program(~"cp", ~[~"-R", cwd.to_str(),
|
||||
wd.to_str()]);
|
||||
|
||||
if status != 0 {
|
||||
fail!(fmt!("could not copy directory: %s", cwd.to_str()));
|
||||
}
|
||||
|
||||
install_source(c, &wd);
|
||||
return;
|
||||
}
|
||||
|
||||
sync(c);
|
||||
|
||||
let query = c.opts.free[2];
|
||||
c.current_install = query.to_str();
|
||||
|
||||
install_query(c, &wd, query);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sync(c: &Cargo) {
|
||||
for c.sources.each_key |&k| {
|
||||
let mut s = c.sources.get(&k);
|
||||
sync_one(c, s);
|
||||
c.sources.insert(k, s);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sync_one_file(c: &Cargo, dir: &Path, src: @Source) -> bool {
|
||||
let name = src.name;
|
||||
let srcfile = dir.push("source.json.new");
|
||||
let destsrcfile = dir.push("source.json");
|
||||
let pkgfile = dir.push("packages.json.new");
|
||||
let destpkgfile = dir.push("packages.json");
|
||||
let keyfile = dir.push("key.gpg");
|
||||
let srcsigfile = dir.push("source.json.sig");
|
||||
let sigfile = dir.push("packages.json.sig");
|
||||
let url = Path(src.url);
|
||||
let mut has_src_file = false;
|
||||
|
||||
if !os::copy_file(&url.push("packages.json"), &pkgfile) {
|
||||
error(fmt!("fetch for source %s (url %s) failed",
|
||||
name, url.to_str()));
|
||||
return false;
|
||||
}
|
||||
|
||||
if os::copy_file(&url.push("source.json"), &srcfile) {
|
||||
has_src_file = false;
|
||||
}
|
||||
|
||||
os::copy_file(&url.push("source.json.sig"), &srcsigfile);
|
||||
os::copy_file(&url.push("packages.json.sig"), &sigfile);
|
||||
|
||||
match copy src.key {
|
||||
Some(u) => {
|
||||
let p = run::program_output(~"curl",
|
||||
~[~"-f", ~"-s",
|
||||
~"-o", keyfile.to_str(), u]);
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (key %s) failed", name, u));
|
||||
return false;
|
||||
}
|
||||
pgp::add(&c.root, &keyfile);
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
match (src.key, src.keyfp) {
|
||||
(Some(_), Some(f)) => {
|
||||
let r = pgp::verify(&c.root, &pkgfile, &sigfile);
|
||||
|
||||
if !r {
|
||||
error(fmt!("signature verification failed for source %s with \
|
||||
key %s", name, f));
|
||||
return false;
|
||||
}
|
||||
|
||||
if has_src_file {
|
||||
let e = pgp::verify(&c.root, &srcfile, &srcsigfile);
|
||||
|
||||
if !e {
|
||||
error(fmt!("signature verification failed for source %s \
|
||||
with key %s", name, f));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
copy_warn(&pkgfile, &destpkgfile);
|
||||
|
||||
if has_src_file {
|
||||
copy_warn(&srcfile, &destsrcfile);
|
||||
}
|
||||
|
||||
os::remove_file(&keyfile);
|
||||
os::remove_file(&srcfile);
|
||||
os::remove_file(&srcsigfile);
|
||||
os::remove_file(&pkgfile);
|
||||
os::remove_file(&sigfile);
|
||||
|
||||
info(fmt!("synced source: %s", name));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn sync_one_git(c: &Cargo, dir: &Path, src: @Source) -> bool {
|
||||
let name = src.name;
|
||||
let srcfile = dir.push("source.json");
|
||||
let pkgfile = dir.push("packages.json");
|
||||
let keyfile = dir.push("key.gpg");
|
||||
let srcsigfile = dir.push("source.json.sig");
|
||||
let sigfile = dir.push("packages.json.sig");
|
||||
let url = src.url;
|
||||
|
||||
fn rollback(name: ~str, dir: &Path, insecure: bool) {
|
||||
fn msg(name: ~str, insecure: bool) {
|
||||
error(fmt!("could not rollback source: %s", name));
|
||||
|
||||
if insecure {
|
||||
warn(~"a past security check failed on source " +
|
||||
name + ~" and rolling back the source failed -"
|
||||
+ ~" this source may be compromised");
|
||||
}
|
||||
}
|
||||
|
||||
if !os::change_dir(dir) {
|
||||
msg(name, insecure);
|
||||
}
|
||||
else {
|
||||
let p = run::program_output(~"git", ~[~"reset", ~"--hard",
|
||||
~"HEAD@{1}"]);
|
||||
|
||||
if p.status != 0 {
|
||||
msg(name, insecure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !os::path_exists(&dir.push(".git")) {
|
||||
let p = run::program_output(~"git", ~[~"clone", url, dir.to_str()]);
|
||||
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (url %s) failed", name, url));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if !os::change_dir(dir) {
|
||||
error(fmt!("fetch for source %s (url %s) failed", name, url));
|
||||
return false;
|
||||
}
|
||||
|
||||
let p = run::program_output(~"git", ~[~"pull"]);
|
||||
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (url %s) failed", name, url));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
let has_src_file = os::path_exists(&srcfile);
|
||||
|
||||
match copy src.key {
|
||||
Some(u) => {
|
||||
let p = run::program_output(~"curl",
|
||||
~[~"-f", ~"-s",
|
||||
~"-o", keyfile.to_str(), u]);
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (key %s) failed", name, u));
|
||||
rollback(name, dir, false);
|
||||
return false;
|
||||
}
|
||||
pgp::add(&c.root, &keyfile);
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
match (src.key, src.keyfp) {
|
||||
(Some(_), Some(f)) => {
|
||||
let r = pgp::verify(&c.root, &pkgfile, &sigfile);
|
||||
|
||||
if !r {
|
||||
error(fmt!("signature verification failed for source %s with \
|
||||
key %s", name, f));
|
||||
rollback(name, dir, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
if has_src_file {
|
||||
let e = pgp::verify(&c.root, &srcfile, &srcsigfile);
|
||||
|
||||
if !e {
|
||||
error(fmt!("signature verification failed for source %s \
|
||||
with key %s", name, f));
|
||||
rollback(name, dir, false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
os::remove_file(&keyfile);
|
||||
|
||||
info(fmt!("synced source: %s", name));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn sync_one_curl(c: &Cargo, dir: &Path, src: @Source) -> bool {
|
||||
let name = src.name;
|
||||
let srcfile = dir.push("source.json.new");
|
||||
let destsrcfile = dir.push("source.json");
|
||||
let pkgfile = dir.push("packages.json.new");
|
||||
let destpkgfile = dir.push("packages.json");
|
||||
let keyfile = dir.push("key.gpg");
|
||||
let srcsigfile = dir.push("source.json.sig");
|
||||
let sigfile = dir.push("packages.json.sig");
|
||||
let mut url = src.url;
|
||||
let smart = !str::ends_with(src.url, ~"packages.json");
|
||||
let mut has_src_file = false;
|
||||
|
||||
if smart {
|
||||
url += ~"/packages.json";
|
||||
}
|
||||
|
||||
let p = run::program_output(~"curl",
|
||||
~[~"-f", ~"-s",
|
||||
~"-o", pkgfile.to_str(), url]);
|
||||
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (url %s) failed", name, url));
|
||||
return false;
|
||||
}
|
||||
if smart {
|
||||
url = src.url + ~"/source.json";
|
||||
let p =
|
||||
run::program_output(~"curl",
|
||||
~[~"-f", ~"-s",
|
||||
~"-o", srcfile.to_str(), url]);
|
||||
|
||||
if p.status == 0 {
|
||||
has_src_file = true;
|
||||
}
|
||||
}
|
||||
|
||||
match copy src.key {
|
||||
Some(u) => {
|
||||
let p = run::program_output(~"curl",
|
||||
~[~"-f", ~"-s",
|
||||
~"-o", keyfile.to_str(), u]);
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (key %s) failed", name, u));
|
||||
return false;
|
||||
}
|
||||
pgp::add(&c.root, &keyfile);
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
match (src.key, src.keyfp) {
|
||||
(Some(_), Some(f)) => {
|
||||
if smart {
|
||||
url = src.url + ~"/packages.json.sig";
|
||||
}
|
||||
else {
|
||||
url = src.url + ~".sig";
|
||||
}
|
||||
|
||||
let mut p = run::program_output(~"curl",
|
||||
~[~"-f", ~"-s", ~"-o",
|
||||
sigfile.to_str(), url]);
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (sig %s) failed", name, url));
|
||||
return false;
|
||||
}
|
||||
|
||||
let r = pgp::verify(&c.root, &pkgfile, &sigfile);
|
||||
|
||||
if !r {
|
||||
error(fmt!("signature verification failed for source %s with \
|
||||
key %s", name, f));
|
||||
return false;
|
||||
}
|
||||
|
||||
if smart && has_src_file {
|
||||
url = src.url + ~"/source.json.sig";
|
||||
|
||||
p = run::program_output(~"curl",
|
||||
~[~"-f", ~"-s", ~"-o",
|
||||
srcsigfile.to_str(), url]);
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch for source %s (sig %s) failed",
|
||||
name, url));
|
||||
return false;
|
||||
}
|
||||
|
||||
let e = pgp::verify(&c.root, &srcfile, &srcsigfile);
|
||||
|
||||
if !e {
|
||||
error(~"signature verification failed for " +
|
||||
~"source " + name + ~" with key " + f);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
copy_warn(&pkgfile, &destpkgfile);
|
||||
|
||||
if smart && has_src_file {
|
||||
copy_warn(&srcfile, &destsrcfile);
|
||||
}
|
||||
|
||||
os::remove_file(&keyfile);
|
||||
os::remove_file(&srcfile);
|
||||
os::remove_file(&srcsigfile);
|
||||
os::remove_file(&pkgfile);
|
||||
os::remove_file(&sigfile);
|
||||
|
||||
info(fmt!("synced source: %s", name));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn sync_one(c: &Cargo, src: @Source) {
|
||||
let name = src.name;
|
||||
let dir = c.sourcedir.push(name);
|
||||
|
||||
info(fmt!("syncing source: %s...", name));
|
||||
|
||||
need_dir(&dir);
|
||||
|
||||
let result = match src.method {
|
||||
~"git" => sync_one_git(c, &dir, src),
|
||||
~"file" => sync_one_file(c, &dir, src),
|
||||
_ => sync_one_curl(c, &dir, src)
|
||||
};
|
||||
|
||||
if result {
|
||||
load_source_info(c, src);
|
||||
load_source_packages(c, src);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cmd_init(c: &Cargo) {
|
||||
let srcurl = ~"http://www.rust-lang.org/cargo/sources.json";
|
||||
let sigurl = ~"http://www.rust-lang.org/cargo/sources.json.sig";
|
||||
|
||||
let srcfile = c.root.push("sources.json.new");
|
||||
let sigfile = c.root.push("sources.json.sig");
|
||||
let destsrcfile = c.root.push("sources.json");
|
||||
|
||||
let p =
|
||||
run::program_output(~"curl", ~[~"-f", ~"-s",
|
||||
~"-o", srcfile.to_str(), srcurl]);
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch of sources.json failed: %s", p.out));
|
||||
return;
|
||||
}
|
||||
|
||||
let p =
|
||||
run::program_output(~"curl", ~[~"-f", ~"-s",
|
||||
~"-o", sigfile.to_str(), sigurl]);
|
||||
if p.status != 0 {
|
||||
error(fmt!("fetch of sources.json.sig failed: %s", p.out));
|
||||
return;
|
||||
}
|
||||
|
||||
let r = pgp::verify(&c.root, &srcfile, &sigfile);
|
||||
if !r {
|
||||
error(fmt!("signature verification failed for '%s'",
|
||||
srcfile.to_str()));
|
||||
return;
|
||||
}
|
||||
|
||||
copy_warn(&srcfile, &destsrcfile);
|
||||
os::remove_file(&srcfile);
|
||||
os::remove_file(&sigfile);
|
||||
|
||||
info(fmt!("initialized .cargo in %s", c.root.to_str()));
|
||||
}
|
||||
|
||||
pub fn print_pkg(s: @Source, p: &Package) {
|
||||
let mut m = s.name + ~"/" + p.name + ~" (" + p.uuid + ~")";
|
||||
if vec::len(p.tags) > 0u {
|
||||
m = m + ~" [" + str::connect(p.tags, ~", ") + ~"]";
|
||||
}
|
||||
info(m);
|
||||
if p.description != ~"" {
|
||||
print(~" >> " + p.description + ~"\n")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_source(s: @Source) {
|
||||
info(s.name + ~" (" + s.url + ~")");
|
||||
|
||||
let pks = sort::merge_sort(s.packages.get(), sys::shape_lt);
|
||||
let l = vec::len(pks);
|
||||
|
||||
print(io::with_str_writer(|writer| {
|
||||
let mut list = ~" >> ";
|
||||
|
||||
for vec::eachi(pks) |i, pk| {
|
||||
if str::len(list) > 78u {
|
||||
writer.write_line(list);
|
||||
list = ~" >> ";
|
||||
}
|
||||
list += pk.name + (if l - 1u == i { ~"" } else { ~", " });
|
||||
}
|
||||
|
||||
writer.write_line(list);
|
||||
}));
|
||||
}
|
||||
|
||||
pub fn cmd_list(c: &Cargo) {
|
||||
sync(c);
|
||||
|
||||
if vec::len(c.opts.free) >= 3u {
|
||||
let v = vec::slice(c.opts.free, 2u, vec::len(c.opts.free));
|
||||
for vec::each(v) |name| {
|
||||
if !valid_pkg_name(*name) {
|
||||
error(fmt!("'%s' is an invalid source name", *name));
|
||||
} else {
|
||||
match c.sources.find(name) {
|
||||
Some(source) => {
|
||||
print_source(source);
|
||||
}
|
||||
None => {
|
||||
error(fmt!("no such source: %s", *name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for c.sources.each_value |&v| {
|
||||
print_source(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cmd_search(c: &Cargo) {
|
||||
if vec::len(c.opts.free) < 3u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
sync(c);
|
||||
|
||||
let mut n = 0;
|
||||
let name = c.opts.free[2];
|
||||
let tags = vec::slice(c.opts.free, 3u, vec::len(c.opts.free));
|
||||
for_each_package(c, |s, p| {
|
||||
if (str::contains(p.name, name) || name == ~"*") &&
|
||||
vec::all(tags, |t| vec::contains(p.tags, t) ) {
|
||||
print_pkg(s, p);
|
||||
n += 1;
|
||||
}
|
||||
});
|
||||
info(fmt!("found %d packages", n));
|
||||
}
|
||||
|
||||
pub fn install_to_dir(srcfile: &Path, destdir: &Path) {
|
||||
let newfile = destdir.push(srcfile.filename().get());
|
||||
|
||||
let status = run::run_program(~"cp", ~[~"-r", srcfile.to_str(),
|
||||
newfile.to_str()]);
|
||||
if status == 0 {
|
||||
info(fmt!("installed: '%s'", newfile.to_str()));
|
||||
} else {
|
||||
error(fmt!("could not install: '%s'", newfile.to_str()));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dump_cache(c: &Cargo) {
|
||||
need_dir(&c.root);
|
||||
|
||||
let out = c.root.push("cache.json");
|
||||
let _root = json::Object(~LinearMap::new());
|
||||
|
||||
if os::path_exists(&out) {
|
||||
copy_warn(&out, &c.root.push("cache.json.old"));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dump_sources(c: &Cargo) {
|
||||
if c.sources.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
need_dir(&c.root);
|
||||
|
||||
let out = c.root.push("sources.json");
|
||||
|
||||
if os::path_exists(&out) {
|
||||
copy_warn(&out, &c.root.push("sources.json.old"));
|
||||
}
|
||||
|
||||
match io::buffered_file_writer(&out) {
|
||||
result::Ok(writer) => {
|
||||
let mut hash = ~LinearMap::new();
|
||||
|
||||
for c.sources.each |&k, &v| {
|
||||
let mut chash = ~LinearMap::new();
|
||||
|
||||
chash.insert(~"url", json::String(v.url));
|
||||
chash.insert(~"method", json::String(v.method));
|
||||
|
||||
match copy v.key {
|
||||
Some(key) => {
|
||||
chash.insert(~"key", json::String(copy key));
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
match copy v.keyfp {
|
||||
Some(keyfp) => {
|
||||
chash.insert(~"keyfp", json::String(copy keyfp));
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
hash.insert(copy k, json::Object(chash));
|
||||
}
|
||||
|
||||
json::to_writer(writer, &json::Object(hash))
|
||||
}
|
||||
result::Err(e) => {
|
||||
error(fmt!("could not dump sources: %s", e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn copy_warn(srcfile: &Path, destfile: &Path) {
|
||||
if !os::copy_file(srcfile, destfile) {
|
||||
warn(fmt!("copying %s to %s failed",
|
||||
srcfile.to_str(), destfile.to_str()));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cmd_sources(c: &Cargo) {
|
||||
if vec::len(c.opts.free) < 3u {
|
||||
for c.sources.each_value |&v| {
|
||||
info(fmt!("%s (%s) via %s",
|
||||
v.name, v.url, v.method));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let action = c.opts.free[2u];
|
||||
|
||||
match action {
|
||||
~"clear" => {
|
||||
for c.sources.each_key |&k| {
|
||||
c.sources.remove(&k);
|
||||
}
|
||||
|
||||
info(~"cleared sources");
|
||||
}
|
||||
~"add" => {
|
||||
if vec::len(c.opts.free) < 5u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
let name = c.opts.free[3u];
|
||||
let url = c.opts.free[4u];
|
||||
|
||||
if !valid_pkg_name(name) {
|
||||
error(fmt!("'%s' is an invalid source name", name));
|
||||
return;
|
||||
}
|
||||
|
||||
if c.sources.contains_key(&name) {
|
||||
error(fmt!("source already exists: %s", name));
|
||||
} else {
|
||||
c.sources.insert(name, @Source {
|
||||
name: name,
|
||||
mut url: url,
|
||||
mut method: assume_source_method(url),
|
||||
mut key: None,
|
||||
mut keyfp: None,
|
||||
packages: DVec()
|
||||
});
|
||||
info(fmt!("added source: %s", name));
|
||||
}
|
||||
}
|
||||
~"remove" => {
|
||||
if vec::len(c.opts.free) < 4u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
let name = c.opts.free[3u];
|
||||
|
||||
if !valid_pkg_name(name) {
|
||||
error(fmt!("'%s' is an invalid source name", name));
|
||||
return;
|
||||
}
|
||||
|
||||
if c.sources.contains_key(&name) {
|
||||
c.sources.remove(&name);
|
||||
info(fmt!("removed source: %s", name));
|
||||
} else {
|
||||
error(fmt!("no such source: %s", name));
|
||||
}
|
||||
}
|
||||
~"set-url" => {
|
||||
if vec::len(c.opts.free) < 5u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
let name = c.opts.free[3u];
|
||||
let url = c.opts.free[4u];
|
||||
|
||||
if !valid_pkg_name(name) {
|
||||
error(fmt!("'%s' is an invalid source name", name));
|
||||
return;
|
||||
}
|
||||
|
||||
match c.sources.find(&name) {
|
||||
Some(source) => {
|
||||
let old = copy source.url;
|
||||
let method = assume_source_method(url);
|
||||
|
||||
source.url = url;
|
||||
source.method = method;
|
||||
|
||||
c.sources.insert(name, source);
|
||||
|
||||
info(fmt!("changed source url: '%s' to '%s'", old, url));
|
||||
}
|
||||
None => {
|
||||
error(fmt!("no such source: %s", name));
|
||||
}
|
||||
}
|
||||
}
|
||||
~"set-method" => {
|
||||
if vec::len(c.opts.free) < 5u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
let name = c.opts.free[3u];
|
||||
let method = c.opts.free[4u];
|
||||
|
||||
if !valid_pkg_name(name) {
|
||||
error(fmt!("'%s' is an invalid source name", name));
|
||||
return;
|
||||
}
|
||||
|
||||
match c.sources.find(&name) {
|
||||
Some(source) => {
|
||||
let old = copy source.method;
|
||||
|
||||
source.method = match method {
|
||||
~"git" => ~"git",
|
||||
~"file" => ~"file",
|
||||
_ => ~"curl"
|
||||
};
|
||||
|
||||
c.sources.insert(name, source);
|
||||
|
||||
info(fmt!("changed source method: '%s' to '%s'", old,
|
||||
method));
|
||||
}
|
||||
None => {
|
||||
error(fmt!("no such source: %s", name));
|
||||
}
|
||||
}
|
||||
}
|
||||
~"rename" => {
|
||||
if vec::len(c.opts.free) < 5u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
let name = c.opts.free[3u];
|
||||
let newn = c.opts.free[4u];
|
||||
|
||||
if !valid_pkg_name(name) {
|
||||
error(fmt!("'%s' is an invalid source name", name));
|
||||
return;
|
||||
}
|
||||
if !valid_pkg_name(newn) {
|
||||
error(fmt!("'%s' is an invalid source name", newn));
|
||||
return;
|
||||
}
|
||||
|
||||
match c.sources.find(&name) {
|
||||
Some(source) => {
|
||||
c.sources.remove(&name);
|
||||
c.sources.insert(newn, source);
|
||||
info(fmt!("renamed source: %s to %s", name, newn));
|
||||
}
|
||||
None => {
|
||||
error(fmt!("no such source: %s", name));
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => cmd_usage()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cmd_usage() {
|
||||
print(~"Usage: cargo <cmd> [options] [args..]
|
||||
e.g. cargo install <name>
|
||||
|
||||
Where <cmd> is one of:
|
||||
init, install, list, search, sources,
|
||||
uninstall, usage
|
||||
|
||||
Options:
|
||||
|
||||
-h, --help Display this message
|
||||
<cmd> -h, <cmd> --help Display help for <cmd>
|
||||
");
|
||||
}
|
||||
|
||||
pub fn cmd_usage_init() {
|
||||
print(~"cargo init
|
||||
|
||||
Re-initialize cargo in ~/.cargo. Clears all sources and then adds the
|
||||
default sources from <www.rust-lang.org/sources.json>.");
|
||||
}
|
||||
|
||||
pub fn cmd_usage_install() {
|
||||
print(~"cargo install
|
||||
cargo install [source/]<name>[@version]
|
||||
cargo install [source/]<uuid>[@version]
|
||||
cargo install <git url> [ref]
|
||||
cargo install <tarball url>
|
||||
cargo install <tarball file>
|
||||
|
||||
Options:
|
||||
--test Run crate tests before installing
|
||||
-g Install to the user level (~/.cargo/bin/ instead of
|
||||
locally in ./.cargo/bin/ by default)
|
||||
-G Install to the system level (/usr/local/lib/cargo/bin/)
|
||||
|
||||
Install a crate. If no arguments are supplied, it installs from
|
||||
the current working directory. If a source is provided, only install
|
||||
from that source, otherwise it installs from any source.");
|
||||
}
|
||||
|
||||
pub fn cmd_usage_uninstall() {
|
||||
print(~"cargo uninstall [source/]<name>[@version]
|
||||
cargo uninstall [source/]<uuid>[@version]
|
||||
cargo uninstall <meta-name>[@version]
|
||||
cargo uninstall <meta-uuid>[@version]
|
||||
|
||||
Options:
|
||||
-g Remove from the user level (~/.cargo/bin/ instead of
|
||||
locally in ./.cargo/bin/ by default)
|
||||
-G Remove from the system level (/usr/local/lib/cargo/bin/)
|
||||
|
||||
Remove a crate. If a source is provided, only remove
|
||||
from that source, otherwise it removes from any source.
|
||||
If a crate was installed directly (git, tarball, etc.), you can remove
|
||||
it by metadata.");
|
||||
}
|
||||
|
||||
pub fn cmd_usage_list() {
|
||||
print(~"cargo list [sources..]
|
||||
|
||||
If no arguments are provided, list all sources and their packages.
|
||||
If source names are provided, list those sources and their packages.
|
||||
");
|
||||
}
|
||||
|
||||
pub fn cmd_usage_search() {
|
||||
print(~"cargo search <query | '*'> [tags..]
|
||||
|
||||
Search packages.");
|
||||
}
|
||||
|
||||
pub fn cmd_usage_sources() {
|
||||
print(~"cargo sources
|
||||
cargo sources add <name> <url>
|
||||
cargo sources remove <name>
|
||||
cargo sources rename <name> <new>
|
||||
cargo sources set-url <name> <url>
|
||||
cargo sources set-method <name> <method>
|
||||
|
||||
If no arguments are supplied, list all sources (but not their packages).
|
||||
|
||||
Commands:
|
||||
add Add a source. The source method will be guessed
|
||||
from the URL.
|
||||
remove Remove a source.
|
||||
rename Rename a source.
|
||||
set-url Change the URL for a source.
|
||||
set-method Change the method for a source.");
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let argv = os::args();
|
||||
let o = build_cargo_options(argv);
|
||||
|
||||
if vec::len(o.free) < 2u {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
if o.help {
|
||||
match o.free[1] {
|
||||
~"init" => cmd_usage_init(),
|
||||
~"install" => cmd_usage_install(),
|
||||
~"uninstall" => cmd_usage_uninstall(),
|
||||
~"list" => cmd_usage_list(),
|
||||
~"search" => cmd_usage_search(),
|
||||
~"sources" => cmd_usage_sources(),
|
||||
_ => cmd_usage()
|
||||
}
|
||||
return;
|
||||
}
|
||||
if o.free[1] == ~"usage" {
|
||||
cmd_usage();
|
||||
return;
|
||||
}
|
||||
|
||||
let mut c = configure(o);
|
||||
let home = c.root;
|
||||
let first_time = os::path_exists(&home.push("sources.json"));
|
||||
|
||||
if !first_time && o.free[1] != ~"init" {
|
||||
cmd_init(&c);
|
||||
|
||||
// FIXME (#2662): shouldn't need to reconfigure
|
||||
c = configure(o);
|
||||
}
|
||||
|
||||
match o.free[1] {
|
||||
~"init" => cmd_init(&c),
|
||||
~"install" => cmd_install(&mut c),
|
||||
~"uninstall" => cmd_uninstall(&c),
|
||||
~"list" => cmd_list(&c),
|
||||
~"search" => cmd_search(&c),
|
||||
~"sources" => cmd_sources(&c),
|
||||
_ => cmd_usage()
|
||||
}
|
||||
|
||||
dump_cache(&c);
|
||||
dump_sources(&c);
|
||||
}
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// 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.
|
||||
|
||||
use core::os;
|
||||
use core::path::Path;
|
||||
use core::run;
|
||||
|
||||
pub fn gpgv(args: ~[~str]) -> run::ProgramOutput {
|
||||
return run::program_output(~"gpgv", args);
|
||||
}
|
||||
|
||||
pub fn signing_key() -> ~str {
|
||||
~"
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: SKS 1.1.0
|
||||
|
||||
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
|
||||
=2z6P
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
"
|
||||
}
|
||||
|
||||
pub fn signing_key_fp() -> ~str {
|
||||
~"FE79 EDB0 3DEF B0D8 27D2 6C41 0B2D 6A28 3033 6376"
|
||||
}
|
||||
|
||||
pub fn supported() -> bool {
|
||||
let r = gpgv(~[~"--version"]);
|
||||
r.status == 0
|
||||
}
|
||||
|
||||
pub fn init(root: &Path) {
|
||||
let p = root.push("gpg");
|
||||
if !os::path_is_dir(&p) {
|
||||
os::make_dir(&p, 0x1c0i32);
|
||||
let mut p = run::start_program(~"gpg", ~[~"--homedir",
|
||||
p.to_str(),
|
||||
~"--import"]);
|
||||
p.input().write_str(signing_key());
|
||||
let s = p.finish();
|
||||
if s != 0 {
|
||||
fail!(~"pgp init failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add(root: &Path, key: &Path) {
|
||||
let path = root.push("gpg");
|
||||
let p =
|
||||
run::program_output(~"gpg", ~[~"--homedir", path.to_str(),
|
||||
~"--import", key.to_str()]);
|
||||
if p.status != 0 {
|
||||
fail!(~"pgp add failed: " + p.out);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn verify(root: &Path, data: &Path, sig: &Path) -> bool {
|
||||
let path = root.push("gpg");
|
||||
let res = gpgv(~[~"--homedir", path.to_str(),
|
||||
~"--keyring", ~"pubring.gpg",
|
||||
~"--verbose",
|
||||
sig.to_str(), data.to_str()]);
|
||||
if res.status != 0 {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"central": {
|
||||
"url": "https://raw.github.com/mozilla/cargo-central/master/packages.json"
|
||||
},
|
||||
"elly": {
|
||||
"url": "https://raw.github.com/elly/rust-packages/master/packages.json",
|
||||
"sig": "https://raw.github.com/elly/rust-packages/master/packages.json.sig",
|
||||
"key": "https://raw.github.com/elly/rust-packages/master/signing-key.gpg",
|
||||
"keyfp": "4107 21C0 FF32 858F 61FF 33F6 E595 8E36 FDC8 EA00"
|
||||
},
|
||||
"erickt": {
|
||||
"url": "https://raw.github.com/erickt/rust-packages/master/packages.json"
|
||||
}
|
||||
}
|
||||
@@ -49,11 +49,11 @@ fn lib_search_paths() -> ~[Path] {
|
||||
paths.push(
|
||||
make_target_lib_path(&self.sysroot,
|
||||
self.target_triple));
|
||||
match get_cargo_lib_path_nearest() {
|
||||
match get_rustpkg_lib_path_nearest() {
|
||||
result::Ok(ref p) => paths.push((/*bad*/copy *p)),
|
||||
result::Err(_) => ()
|
||||
}
|
||||
match get_cargo_lib_path() {
|
||||
match get_rustpkg_lib_path() {
|
||||
result::Ok(ref p) => paths.push((/*bad*/copy *p)),
|
||||
result::Err(_) => ()
|
||||
}
|
||||
@@ -119,54 +119,54 @@ fn get_sysroot(maybe_sysroot: Option<Path>) -> Path {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_cargo_sysroot() -> Result<Path, ~str> {
|
||||
result::Ok(get_or_default_sysroot().push_many([libdir(), ~"cargo"]))
|
||||
pub fn get_rustpkg_sysroot() -> Result<Path, ~str> {
|
||||
result::Ok(get_or_default_sysroot().push_many([libdir(), ~"rustpkg"]))
|
||||
}
|
||||
|
||||
pub fn get_cargo_root() -> Result<Path, ~str> {
|
||||
match os::getenv(~"CARGO_ROOT") {
|
||||
pub fn get_rustpkg_root() -> Result<Path, ~str> {
|
||||
match os::getenv(~"RUSTPKG_ROOT") {
|
||||
Some(ref _p) => result::Ok(Path((*_p))),
|
||||
None => match os::homedir() {
|
||||
Some(ref _q) => result::Ok((*_q).push(".cargo")),
|
||||
None => result::Err(~"no CARGO_ROOT or home directory")
|
||||
Some(ref _q) => result::Ok((*_q).push(".rustpkg")),
|
||||
None => result::Err(~"no RUSTPKG_ROOT or home directory")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_cargo_root_nearest() -> Result<Path, ~str> {
|
||||
do result::chain(get_cargo_root()) |p| {
|
||||
pub fn get_rustpkg_root_nearest() -> Result<Path, ~str> {
|
||||
do result::chain(get_rustpkg_root()) |p| {
|
||||
let cwd = os::getcwd();
|
||||
let cwd_cargo = cwd.push(".cargo");
|
||||
let cargo_is_non_root_file =
|
||||
!os::path_is_dir(&cwd_cargo) && cwd_cargo != p;
|
||||
let mut par_cargo = cwd.pop().push(".cargo");
|
||||
let mut rslt = result::Ok(cwd_cargo);
|
||||
let cwd_rustpkg = cwd.push(".rustpkg");
|
||||
let rustpkg_is_non_root_file =
|
||||
!os::path_is_dir(&cwd_rustpkg) && cwd_rustpkg != p;
|
||||
let mut par_rustpkg = cwd.pop().push(".rustpkg");
|
||||
let mut rslt = result::Ok(cwd_rustpkg);
|
||||
|
||||
if cargo_is_non_root_file {
|
||||
while par_cargo != p {
|
||||
if os::path_is_dir(&par_cargo) {
|
||||
rslt = result::Ok(par_cargo);
|
||||
if rustpkg_is_non_root_file {
|
||||
while par_rustpkg != p {
|
||||
if os::path_is_dir(&par_rustpkg) {
|
||||
rslt = result::Ok(par_rustpkg);
|
||||
break;
|
||||
}
|
||||
if par_cargo.components.len() == 1 {
|
||||
// We just checked /.cargo, stop now.
|
||||
if par_rustpkg.components.len() == 1 {
|
||||
// We just checked /.rustpkg, stop now.
|
||||
break;
|
||||
}
|
||||
par_cargo = par_cargo.pop().pop().push(".cargo");
|
||||
par_rustpkg = par_rustpkg.pop().pop().push(".rustpkg");
|
||||
}
|
||||
}
|
||||
rslt
|
||||
}
|
||||
}
|
||||
|
||||
fn get_cargo_lib_path() -> Result<Path, ~str> {
|
||||
do result::chain(get_cargo_root()) |p| {
|
||||
fn get_rustpkg_lib_path() -> Result<Path, ~str> {
|
||||
do result::chain(get_rustpkg_root()) |p| {
|
||||
result::Ok(p.push(libdir()))
|
||||
}
|
||||
}
|
||||
|
||||
fn get_cargo_lib_path_nearest() -> Result<Path, ~str> {
|
||||
do result::chain(get_cargo_root_nearest()) |p| {
|
||||
fn get_rustpkg_lib_path_nearest() -> Result<Path, ~str> {
|
||||
do result::chain(get_rustpkg_root_nearest()) |p| {
|
||||
result::Ok(p.push(libdir()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// 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.
|
||||
|
||||
// rustpkg - a purely function package manager and build system
|
||||
|
||||
#[link(name = "rustpkg",
|
||||
vers = "0.6",
|
||||
uuid = "25de5e6e-279e-4a20-845c-4cabae92daaf",
|
||||
url = "https://github.com/mozilla/rust/tree/master/src/librustpkg")];
|
||||
|
||||
#[crate_type = "lib"];
|
||||
|
||||
#[no_core];
|
||||
|
||||
extern mod core(vers = "0.6");
|
||||
extern mod std(vers = "0.6");
|
||||
extern mod rustc(vers = "0.6");
|
||||
extern mod syntax(vers = "0.6");
|
||||
|
||||
use rustc::metadata::{filesearch};
|
||||
|
||||
pub fn main() {
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user