From 25fe2cadb10db1a54cefbd1520708d4397874bc3 Mon Sep 17 00:00:00 2001 From: Corey Richardson Date: Sun, 2 Feb 2014 02:56:55 -0500 Subject: [PATCH] Remove rustpkg. I'm sorry :'( Closes #11859 --- Makefile.in | 1 - README.md | 4 +- doc/guide-rustpkg.md | 270 -- doc/po/ja/guide-rustpkg.md.po | 112 - doc/rust.md | 2 +- doc/rustpkg.md | 164 -- doc/tutorial.md | 23 +- man/rustc.1 | 2 +- man/rustdoc.1 | 2 +- man/rustpkg.1 | 195 -- mk/crates.mk | 7 +- mk/dist.mk | 1 - mk/docs.mk | 12 - mk/tests.mk | 13 - src/README.md | 1 - src/driver/driver.rs | 3 - src/librustc/driver/session.rs | 5 +- src/librustpkg/README.txt | 24 - src/librustpkg/api.rs | 199 -- src/librustpkg/conditions.rs | 46 - src/librustpkg/context.rs | 347 --- src/librustpkg/crate.rs | 61 - src/librustpkg/exit_codes.rs | 14 - src/librustpkg/installed_packages.rs | 94 - src/librustpkg/lib.rs | 816 ------ src/librustpkg/messages.rs | 43 - src/librustpkg/package_source.rs | 554 ---- src/librustpkg/parse_args.rs | 196 -- src/librustpkg/path_util.rs | 426 --- src/librustpkg/sha1.rs | 633 ----- src/librustpkg/source_control.rs | 148 - src/librustpkg/target.rs | 87 - src/librustpkg/tests.rs | 2407 ----------------- .../fail/src/no-inferred-crates/src/zzyzx.rs | 20 - src/librustpkg/testsuite/pass/commands.txt | 34 - .../testsuite/pass/src/c-dependencies/bar.rs | 13 - .../testsuite/pass/src/c-dependencies/foo.rs | 12 - .../testsuite/pass/src/c-dependencies/lib.rs | 14 - .../testsuite/pass/src/c-dependencies/pkg.rs | 83 - .../pass/src/deeply/nested/path/foo/main.rs | 17 - .../testsuite/pass/src/external-crate/main.rs | 24 - .../testsuite/pass/src/fancy-lib/bar.rs | 13 - .../testsuite/pass/src/fancy-lib/foo.rs | 12 - .../testsuite/pass/src/fancy-lib/lib.rs | 24 - .../testsuite/pass/src/fancy-lib/pkg.rs | 52 - src/librustpkg/testsuite/pass/src/foo/lib.rs | 11 - .../testsuite/pass/src/hello-world/main.rs | 23 - .../testsuite/pass/src/install-paths/bench.rs | 17 - .../testsuite/pass/src/install-paths/lib.rs | 11 - .../testsuite/pass/src/install-paths/main.rs | 28 - .../testsuite/pass/src/install-paths/test.rs | 14 - .../testsuite/pass/src/simple-lib/src/bar.rs | 13 - .../testsuite/pass/src/simple-lib/src/foo.rs | 12 - .../testsuite/pass/src/simple-lib/src/lib.rs | 21 - src/librustpkg/usage.rs | 181 -- src/librustpkg/util.rs | 699 ----- src/librustpkg/version.rs | 93 - src/librustpkg/workcache_support.rs | 58 - src/librustpkg/workspace.rs | 83 - 59 files changed, 14 insertions(+), 8480 deletions(-) delete mode 100644 doc/guide-rustpkg.md delete mode 100644 doc/po/ja/guide-rustpkg.md.po delete mode 100644 doc/rustpkg.md delete mode 100644 man/rustpkg.1 delete mode 100644 src/librustpkg/README.txt delete mode 100644 src/librustpkg/api.rs delete mode 100644 src/librustpkg/conditions.rs delete mode 100644 src/librustpkg/context.rs delete mode 100644 src/librustpkg/crate.rs delete mode 100644 src/librustpkg/exit_codes.rs delete mode 100644 src/librustpkg/installed_packages.rs delete mode 100644 src/librustpkg/lib.rs delete mode 100644 src/librustpkg/messages.rs delete mode 100644 src/librustpkg/package_source.rs delete mode 100644 src/librustpkg/parse_args.rs delete mode 100644 src/librustpkg/path_util.rs delete mode 100644 src/librustpkg/sha1.rs delete mode 100644 src/librustpkg/source_control.rs delete mode 100644 src/librustpkg/target.rs delete mode 100644 src/librustpkg/tests.rs delete mode 100644 src/librustpkg/testsuite/fail/src/no-inferred-crates/src/zzyzx.rs delete mode 100644 src/librustpkg/testsuite/pass/commands.txt delete mode 100644 src/librustpkg/testsuite/pass/src/c-dependencies/bar.rs delete mode 100644 src/librustpkg/testsuite/pass/src/c-dependencies/foo.rs delete mode 100644 src/librustpkg/testsuite/pass/src/c-dependencies/lib.rs delete mode 100644 src/librustpkg/testsuite/pass/src/c-dependencies/pkg.rs delete mode 100644 src/librustpkg/testsuite/pass/src/deeply/nested/path/foo/main.rs delete mode 100644 src/librustpkg/testsuite/pass/src/external-crate/main.rs delete mode 100644 src/librustpkg/testsuite/pass/src/fancy-lib/bar.rs delete mode 100644 src/librustpkg/testsuite/pass/src/fancy-lib/foo.rs delete mode 100644 src/librustpkg/testsuite/pass/src/fancy-lib/lib.rs delete mode 100644 src/librustpkg/testsuite/pass/src/fancy-lib/pkg.rs delete mode 100644 src/librustpkg/testsuite/pass/src/foo/lib.rs delete mode 100644 src/librustpkg/testsuite/pass/src/hello-world/main.rs delete mode 100644 src/librustpkg/testsuite/pass/src/install-paths/bench.rs delete mode 100644 src/librustpkg/testsuite/pass/src/install-paths/lib.rs delete mode 100644 src/librustpkg/testsuite/pass/src/install-paths/main.rs delete mode 100644 src/librustpkg/testsuite/pass/src/install-paths/test.rs delete mode 100644 src/librustpkg/testsuite/pass/src/simple-lib/src/bar.rs delete mode 100644 src/librustpkg/testsuite/pass/src/simple-lib/src/foo.rs delete mode 100644 src/librustpkg/testsuite/pass/src/simple-lib/src/lib.rs delete mode 100644 src/librustpkg/usage.rs delete mode 100644 src/librustpkg/util.rs delete mode 100644 src/librustpkg/version.rs delete mode 100644 src/librustpkg/workcache_support.rs delete mode 100644 src/librustpkg/workspace.rs diff --git a/Makefile.in b/Makefile.in index 1b3a85e8947..af21ab4fac2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -370,7 +370,6 @@ SREQ$(1)_T_$(2)_H_$(3) = \ # libraries CSREQ$(1)_T_$(2)_H_$(3) = \ $$(TSREQ$(1)_T_$(2)_H_$(3)) \ - $$(HBIN$(1)_H_$(3))/rustpkg$$(X_$(3)) \ $$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) \ $$(foreach dep,$$(CRATES),$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(dep)) \ $$(foreach dep,$$(HOST_CRATES),$$(HLIB$(1)_H_$(3))/stamp.$$(dep)) diff --git a/README.md b/README.md index 6fa264a99d1..1d098571bae 100644 --- a/README.md +++ b/README.md @@ -52,8 +52,8 @@ documentation. > options are also supported, pass `--help` 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 `rustpkg`, the Rust package manager and build + `/usr/local/bin`: `rustc`, the Rust compiler, and `rustdoc`, the + API-documentation tool. system. 3. Read the [tutorial]. 4. Enjoy! diff --git a/doc/guide-rustpkg.md b/doc/guide-rustpkg.md deleted file mode 100644 index eccdf249156..00000000000 --- a/doc/guide-rustpkg.md +++ /dev/null @@ -1,270 +0,0 @@ -% The Rust Packaging Guide - -# Introduction - -Sharing is caring. Rust comes with a tool, `rustpkg`, which allows you to -package up your Rust code and share it with other people. This guide will -get you started on all of the concepts and commands you need to give the gift -of Rust code to someone else. - -# Installing External Packages - -First, let's try to use an external package somehow. I've made a sample package -called `hello` to demonstrate how to do so. Here's how `hello` is used: - -~~~~ -extern mod hello; - -fn main() { - hello::world(); -} -~~~~ - -Easy! But if you try to compile this, you'll get an error: - -~~~~ {.notrust} -$ rustc main.rs -main.rs:1:0: 1:17 error: can't find crate for `hello` -main.rs:1 extern mod hello; - ^~~~~~~~~~~~~~~~~ -~~~~ - -This makes sense, as we haven't gotten it from anywhere yet! Luckily for us, -`rustpkg` has an easy way to fetch others' code: the `install` command. It's -used like this: - -~~~ {.notrust} -$ rustpkg install PKG_ID -~~~ - -This will install a package named `PKG_ID` into your current Rust environment. -I called it `PKG_ID` in this example because `rustpkg` calls this a 'package -identifier.' When using it with an external package like this, it's often a -URI fragment. You see, Rust has no central authority for packages. You can -build your own `hello` library if you want, and that's fine. We'd both host -them in different places and different projects would rely on whichever version -they preferred. - -To install the `hello` library, simply run this in your terminal: - -~~~ {.notrust} -$ rustpkg install github.com/steveklabnik/hello -~~~ - -You should see a message that looks like this: - -~~~ {.notrust} -note: Installed package github.com/steveklabnik/hello-0.1 to /some/path/.rust -~~~ - -Now, compiling our example should work: - -~~~ {.notrust} -$ rustc main.rs -$ ./main -Hello, world. -~~~ - -Simple! That's all it takes. - -# Workspaces - -Before we can talk about how to make packages of your own, you have to -understand the big concept with `rustpkg`: workspaces. A 'workspace' is simply -a directory that has certain sub-directories that `rustpkg` expects. Different -Rust projects will go into different workspaces. - -A workspace consists of any directory that has the following -directories: - -* `src`: The directory where all the source code goes. -* `build`: This directory contains all of the build output. -* `lib`: The directory where any libraries distributed with the package go. -* `bin`: This directory holds any binaries distributed with the package. - -There are also default file names you'll want to follow as well: - -* `main.rs`: A file that's going to become an executable. -* `lib.rs`: A file that's going to become a library. - -# Building your own Package - -Now that you've got workspaces down, let's build your own copy of `hello`. Go -to wherever you keep your personal projects, and let's make all of the -directories we'll need. I'll refer to this personal project directory as -`~/src` for the rest of this guide. - -## Creating our workspace - -~~~ {.notrust} -$ cd ~/src -$ mkdir -p hello/src/hello -$ cd hello -~~~ - -Easy enough! Let's do one or two more things that are nice to do: - -~~~ {.notrust} -$ git init . -$ cat > README.md -# hello - -A simple package for Rust. - -## Installation - -``` -$ rustpkg install github.com/YOUR_USERNAME/hello -``` -^D -$ cat > .gitignore -.rust -build -^D -$ git commit -am "Initial commit." -~~~ - -If you're not familliar with the `cat >` idiom, it will make files with the -text you type inside. Control-D (`^D`) ends the text for the file. - -Anyway, we've got a README and a `.gitignore`. Let's talk about that -`.gitignore` for a minute: we are ignoring two directories, `build` and -`.rust`. `build`, as we discussed earlier, is for build artifacts, and we don't -want to check those into a repository. `.rust` is a directory that `rustpkg` -uses to keep track of its own settings, as well as the source code of any other -external packages that this workspace uses. This is where that `rustpkg -install` puts all of its files. Those are also not to go into our repository, -so we ignore it all as well. - -Next, let's add a source file: - -~~~ -#[desc = "A hello world Rust package."]; -#[license = "MIT"]; - -pub fn world() { - println!("Hello, world."); -} -~~~ - -Put this into `src/hello/lib.rs`. Let's talk about each of these attributes: - -## Crate attributes for packages - -`license` is equally simple: the license we want this code to have. I chose MIT -here, but you should pick whatever license makes the most sense for you. - -`desc` is a description of the package and what it does. This should just be a -sentence or two. - -## Building your package - -Building your package is simple: - -~~~ {.notrust} -$ rustpkg build hello -~~~ - -This will compile `src/hello/lib.rs` into a library. After this process -completes, you'll want to check out `build`: - -~~~ {.notrust} -$ ls build/x86_64-unknown-linux-gnu/hello/ -libhello-ed8619dad9ce7d58-0.1.0.so -~~~ - -This directory naming structure is called a 'build triple,' and is because I'm -on 64 bit Linux. Yours may differ based on platform. - -You'll also notice that `src/hello/lib.rs` turned into -`libhello-ed8619dad9ce7d58-0.1.0.so`. This is a simple combination of the -library name, a hash of its content, and the version. - -Now that your library builds, you'll want to commit: - -~~~ {.notrust} -$ git add src -$ git commit -m "Adding source code." -~~~ - -If you're using GitHub, after creating the project, do this: - -~~~ {.notrust} -$ git remote add origin git@github.com:YOUR_USERNAME/hello.git -$ git push origin -u master -~~~ - -Now you can install and use it! Go anywhere else in your filesystem: - -~~~ {.notrust} -$ cd ~/src/foo -$ rustpkg install github.com/YOUR_USERNAME/hello -WARNING: The Rust package manager is experimental and may be unstable -note: Installed package github.com/YOUR_USERNAME/hello-0.1 to /home/yourusername/src/hello/.rust -~~~ - -That's it! - -# Testing your Package - -Testing your package is simple as well. First, let's change `src/hello/lib.rs` to contain -a function that can be sensibly tested: - -~~~ -#[desc = "A Rust package for determining whether unsigned integers are even."]; -#[license = "MIT"]; - -pub fn is_even(i: uint) -> bool { - i % 2 == 0 -} -~~~ - -Once you've edited `lib.rs`, you can create a second crate file, `src/hello/test.rs`, -to put tests in: - -~~~ -#[license = "MIT"]; -extern mod hello; -use hello::is_even; - -#[test] -fn test_is_even() { - assert!(is_even(0)); - assert!(!is_even(1)); - assert!(is_even(2)); -} -~~~ - -Note that you have to import the crate you just created in `lib.rs` with the -`extern mod hello` directive. That's because you're putting the tests in a different -crate from the main library that you created. - -Now, you can use the `rustpkg test` command to build this test crate (and anything else -it depends on) and run the tests, all in one step: - -~~~ {.notrust} -$ rustpkg test hello -WARNING: The Rust package manager is experimental and may be unstable -note: Installed package hello-0.1 to /Users/tjc/.rust - -running 1 test -test test_is_even ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured -~~~ - -# More resources - -There's a lot more going on with `rustpkg`, this is just to get you started. -Check out [the rustpkg manual](rustpkg.html) for the full details on how to -customize `rustpkg`. - -A tag was created on GitHub specifically for `rustpkg`-related issues. You can -[see all the Issues for rustpkg -here](https://github.com/mozilla/rust/issues?direction=desc&labels=A-pkg&sort=created&state=open), -with bugs as well as new feature plans. `rustpkg` is still under development, -and so may be a bit flaky at the moment. - -You may also want to check out [this blog -post](http://tim.dreamwidth.org/1820526.html), which contains some of the early -design decisions and justifications. diff --git a/doc/po/ja/guide-rustpkg.md.po b/doc/po/ja/guide-rustpkg.md.po deleted file mode 100644 index 04ac982d420..00000000000 --- a/doc/po/ja/guide-rustpkg.md.po +++ /dev/null @@ -1,112 +0,0 @@ -# Japanese translations for Rust package -# Copyright (C) 2014 The Rust Project Developers -# This file is distributed under the same license as the Rust package. -# Automatically generated, 2014. -# -msgid "" -msgstr "" -"Project-Id-Version: Rust 0.10-pre\n" -"POT-Creation-Date: 2014-01-13 12:01+0900\n" -"PO-Revision-Date: 2014-01-13 12:01+0900\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"Language: ja\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" - -#. type: Plain text -#: doc/guide-conditions.md:4 doc/guide-ffi.md:4 doc/guide-lifetimes.md:4 -#: doc/guide-macros.md:4 doc/guide-rustpkg.md:4 doc/guide-tasks.md:4 -#: doc/rust.md:4 doc/rustpkg.md:4 doc/tutorial.md:4 -msgid "# Introduction" -msgstr "# イントロダクション" - -#. type: Plain text -#: doc/guide-rustpkg.md:2 -#, fuzzy -#| msgid "% The Rust Language Tutorial" -msgid "% The Rust Packaging Guide" -msgstr "% Rust 言語チュートリアル" - -#. type: Plain text -#: doc/guide-rustpkg.md:11 -#, fuzzy -#| msgid "## Using other crates" -msgid "# Installing External Packages" -msgstr "## 他のクレートの利用" - -#. type: Plain text -#: doc/guide-rustpkg.md:22 -#, fuzzy, no-wrap -#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~" -msgid "" -"fn main() {\n" -" hello::world();\n" -"}\n" -"~~~~\n" -msgstr "" -"~~~~ {.ignore}\n" -"// main.rs\n" -"extern mod world;\n" -"fn main() { println(~\"hello \" + world::explore()); }\n" -"~~~~" - -#. type: Plain text -#: doc/guide-rustpkg.md:91 -#, fuzzy -#| msgid "## Using other crates" -msgid "# Building your own Package" -msgstr "## 他のクレートの利用" - -#. type: Plain text -#: doc/guide-rustpkg.md:98 -#, fuzzy -#| msgid "## Using other crates" -msgid "## Creating our workspace" -msgstr "## 他のクレートの利用" - -#. type: Plain text -#: doc/guide-rustpkg.md:115 -#, fuzzy -#| msgid "# Introduction" -msgid "## Installation" -msgstr "# イントロダクション" - -#. type: Plain text -#: doc/guide-rustpkg.md:149 -#, fuzzy, no-wrap -#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~" -msgid "" -"pub fn world() {\n" -" println!(\"Hello, world.\");\n" -"}\n" -"~~~\n" -msgstr "" -"~~~~ {.ignore}\n" -"// main.rs\n" -"extern mod world;\n" -"fn main() { println(~\"hello \" + world::explore()); }\n" -"~~~~" - -#. type: Plain text -#: doc/guide-rustpkg.md:161 -#, fuzzy -#| msgid "## Using other crates" -msgid "## Building your package" -msgstr "## 他のクレートの利用" - -#. type: Plain text -#: doc/guide-rustpkg.md:209 -#, fuzzy -#| msgid "## Using other crates" -msgid "# Testing your Package" -msgstr "## 他のクレートの利用" - -#. type: Plain text -#: doc/guide-rustpkg.md:257 -#, fuzzy -#| msgid "## Managed boxes" -msgid "# More resources" -msgstr "## マネージドボックス" diff --git a/doc/rust.md b/doc/rust.md index 0b817539b29..1ca75fa5bef 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -791,7 +791,7 @@ extern mod extra; // equivalent to: extern mod extra = "extra"; extern mod rustextra = "extra"; // linking to 'extra' under another name -extern mod foo = "some/where/rust-foo#foo:1.0"; // a full package ID for rustpkg +extern mod foo = "some/where/rust-foo#foo:1.0"; // a full package ID for external tools ~~~~ ##### Use declarations diff --git a/doc/rustpkg.md b/doc/rustpkg.md deleted file mode 100644 index f36cbe7153c..00000000000 --- a/doc/rustpkg.md +++ /dev/null @@ -1,164 +0,0 @@ -% Rustpkg Reference Manual - -# Introduction - -This document is the reference manual for the Rustpkg packaging and build tool for the Rust programming language. - -## Disclaimer - -Rustpkg is a work in progress, as is this reference manual. -If the actual behavior of rustpkg differs from the behavior described in this reference, -that reflects either an incompleteness or a bug in rustpkg. - -# Package searching - -rustpkg searches for packages using the `RUST_PATH` environment variable, -which is a colon-separated list (semicolon-separated on Windows) of directories. - -Each directory in this list is a *workspace* for rustpkg. - -`RUST_PATH` implicitly contains an entry for `./.rust` (as well as -`../.rust`, `../../.rust`, -and so on for every parent of `.` up to the filesystem root). -That means that if `RUST_PATH` is not set, -then rustpkg will still search for workspaces in `./.rust` and so on. -`RUST_PATH` also implicitly contains an entry for the system path: -`/usr/local` or the equivalent on Windows. -This entry comes after the implicit entries for `./.rust` and so on. -Finally, the last implicit entry in `RUST_PATH` is `~/.rust` -or the equivalent on Windows. - -Each workspace may contain one or more packages. - -When building code that contains one or more directives of the form `extern mod P`, -rustpkg automatically searches for packages named `P` in the `RUST_PATH` (as described above). -It builds those dependencies if necessary. -Thus, when using rustpkg, -there is no need for `-L` flags to tell the linker where to find libraries for external crates. - -# Package structure - -A valid workspace must contain each of the following subdirectories: - -* 'src/': contains one subdirectory per package. Each subdirectory contains source files for a given package. - - For example, if `foo` is a workspace containing the package `bar`, - then `foo/src/bar/main.rs` could be the `main` entry point for - building a `bar` executable. -* 'lib/': `rustpkg install` installs libraries into a target-specific subdirectory of this directory. - - For example, on a 64-bit machine running Mac OS X, - if `foo` is a workspace containing the package `bar`, - rustpkg will install libraries for bar to `foo/lib/x86_64-apple-darwin/`. - The libraries will have names of the form `foo/lib/x86_64-apple-darwin/libbar-[hash].dylib`, - where [hash] is a hash of the package ID. -* 'bin/': `rustpkg install` installs executable binaries into this directory. - - For example, rustpkg will install executables for `bar` to - `foo/bin`. - The executables will have names of the form `foo/bin/bar`. -* 'build/': `rustpkg build` stores temporary build artifacts in a target-specific subdirectory of this directory. - - For example, on a 64-bit machine running Mac OS X, - if `foo` is a workspace containing the package `bar` and `foo/src/bar/main.rs` exists, - then `rustpkg build` will create `foo/build/x86_64-apple-darwin/bar/main.o`. - -# Package identifiers - -A package identifier identifies a package uniquely. -A package can be stored in a workspace on the local file system, -or on a remote Web server, in which case the package ID resembles a URL. -For example, `github.com/mozilla/rust` is a package ID -that would refer to the git repository browsable at `http://github.com/mozilla/rust`. -A package ID can also specify a version, like: -`github.com/mozilla/rust#0.3`. -In this case, `rustpkg` will check that the repository `github.com/mozilla/rust` has a tag named `0.3`, -and report an error otherwise. -A package ID can also specify a particular revision of a repository, like: -`github.com/mozilla/rust#release-0.7`. -When the refspec (portion of the package ID after the `#`) can't be parsed as a decimal number, -rustpkg passes the refspec along to the version control system without interpreting it. -rustpkg also interprets any dependencies on such a package ID literally -(as opposed to versions, where a newer version satisfies a dependency on an older version). -Thus, `github.com/mozilla/rust#5c4cd30f80` is also a valid package ID, -since git can deduce that 5c4cd30f80 refers to a revision of the desired repository. - -A package identifier can name a subdirectory of another package. -For example, if `foo` is a workspace, and `foo/src/bar/lib.rs` exists, -as well as `foo/src/bar/extras/baz/lib.rs`, -then both `bar` and `bar/extras/baz` are valid package identifiers -in the workspace `foo`. - -Because rustpkg uses generic source file names as the main inputs, you will -need to specify the package identifier in them using the `crate_id` attribute -on the crate. - -## Source files - -rustpkg searches for four different fixed filenames in order to determine the crates to build: - -* `main.rs`: Assumed to be a main entry point for building an executable. -* `lib.rs`: Assumed to be a library crate. -* `test.rs`: Assumed to contain tests declared with the `#[test]` attribute. -* `bench.rs`: Assumed to contain benchmarks declared with the `#[bench]` attribute. - -## Versions - -`rustpkg` packages do not need to declare their versions with an attribute inside one of the source files, -because `rustpkg` infers it from the version control system. -When building a package that is in a `git` repository, -`rustpkg` assumes that the most recent tag specifies the current version. -When building a package that is not under version control, -or that has no tags, `rustpkg` assumes the intended version is 0.1. - -> **Note:** A future version of rustpkg will support semantic versions. - -# Dependencies - -rustpkg infers dependencies from `extern mod` directives. -Thus, there should be no need to pass a `-L` flag to rustpkg to tell it where to find a library. -(In the future, it will also be possible to write an `extern mod` directive referring to a remote package.) - -# Custom build scripts - -A file called `pkg.rs` at the root level in a package directory is called a *package script*. -If a package script exists, rustpkg executes it to build the package -rather than inferring crates as described previously. - -Inside `pkg.rs`, it's possible to call back into rustpkg to finish up the build. -`rustpkg::api` contains functions to build, install, or clean libraries and executables -in the way rustpkg normally would without custom build logic. - -# Command reference - -## build - -`rustpkg build foo` searches for a package with ID `foo` -and builds it in any workspace(s) where it finds one. -Supposing such packages are found in workspaces X, Y, and Z, -the command leaves behind files in `X`'s, `Y`'s, and `Z`'s `build` directories, -but not in their `lib` or `bin` directories. -(The exception is when rustpkg fetches a package `foo`'s sources from a remote repository. -In that case, it stores both the sources *and* the build artifacts for `foo` -in the workspace that `foo` will install to (see ##install below)). - -## clean - -`rustpkg clean foo` deletes the contents of `foo`'s `build` directory. - -## install - -`rustpkg install foo` builds the libraries and/or executables that are targets for `foo`. -If `RUST_PATH` is declared as an environment variable, then rustpkg installs the -libraries and executables into the `lib` and `bin` subdirectories -of the first entry in `RUST_PATH`. -Otherwise, if the current working directory CWD is a workspace, -it installs them into CWD's `lib` and `bin` subdirectories. -Otherwise, if the current working directory is CWD, -it installs them into the .rust/lib and .rust/bin subdirectories of CWD -(creating them if necessary). - -## test - -`rustpkg test foo` builds `foo`'s `test.rs` file if necessary, -then runs the resulting test executable. diff --git a/doc/tutorial.md b/doc/tutorial.md index ff36511a319..29446f23e1d 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -117,8 +117,8 @@ can be adjusted by passing a `--prefix` argument to 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 `rustpkg`, the Rust package manager. +`/usr/local/bin`: `rustc`, the Rust compiler, and `rustdoc`, the +API-documentation tool. [tarball]: http://static.rust-lang.org/dist/rust-0.9.tar.gz [win-exe]: http://static.rust-lang.org/dist/rust-0.9-install.exe @@ -3087,15 +3087,6 @@ they model most closely what people expect to shadow. If you use `extern mod`, per default `rustc` will look for libraries in the library search path (which you can extend with the `-L` switch). -However, Rust also ships with rustpkg, a package manager that is able to automatically download and build -libraries if you use it for building your crate. How it works is explained [here][rustpkg], -but for this tutorial it's only important to know that you can optionally annotate an -`extern mod` statement with a package id that rustpkg can use to identify it: - -~~~ {.ignore} -extern mod rust = "github.com/mozilla/rust"; // pretend Rust is a simple library -~~~ - ## Crate metadata and settings For every crate you can define a number of metadata items, such as link name, version or author. @@ -3146,11 +3137,6 @@ or setting the crate type (library or executable) explicitly: # fn farm() {} ~~~~ -> ***Note:*** The rules regarding package IDs, both as attributes and as used - in `extern mod`, as well as their interaction with `rustpkg` are - currently not clearly defined and will likely change in the - future. - ## A minimal example Now for something that you can actually compile yourself. @@ -3253,7 +3239,8 @@ library. You can use them by linking to `extra` with an `extern mod extra;`. [extra library]: extra/index.html Right now `extra` contains those definitions directly, but in the future it will likely just -re-export a bunch of 'officially blessed' crates that get managed with `rustpkg`. +re-export a bunch of 'officially blessed' crates that get managed with a +package manager. # What next? @@ -3267,7 +3254,6 @@ guides on individual topics. * [The foreign function interface][ffi] * [Containers and iterators][container] * [Error-handling and Conditions][conditions] -* [Packaging up Rust code][rustpkg] * [Documenting Rust code][rustdoc] * [Testing Rust code][testing] * [The Rust Runtime][runtime] @@ -3281,7 +3267,6 @@ There is further documentation on the [wiki], however those tend to be even more [ffi]: guide-ffi.html [container]: guide-container.html [conditions]: guide-conditions.html -[rustpkg]: guide-rustpkg.html [testing]: guide-testing.html [runtime]: guide-runtime.html [rustdoc]: rustdoc.html diff --git a/man/rustc.1 b/man/rustc.1 index 6f84d0f8f71..885ec37f374 100644 --- a/man/rustc.1 +++ b/man/rustc.1 @@ -130,7 +130,7 @@ To build an executable with debug info (experimental): .SH "SEE ALSO" -rustdoc, rustpkg +rustdoc .SH "BUGS" See <\fBhttps://github.com/mozilla/rust/issues\fR> for issues. diff --git a/man/rustdoc.1 b/man/rustdoc.1 index 78340984f96..80f992085c0 100644 --- a/man/rustdoc.1 +++ b/man/rustdoc.1 @@ -84,7 +84,7 @@ The generated HTML can be viewed with any standard web browser. .SH "SEE ALSO" -rustc, rustpkg +rustc .SH "BUGS" See <\fBhttps://github.com/mozilla/rust/issues\fR> for issues. diff --git a/man/rustpkg.1 b/man/rustpkg.1 deleted file mode 100644 index 856f9022813..00000000000 --- a/man/rustpkg.1 +++ /dev/null @@ -1,195 +0,0 @@ -.TH RUSTPKG "1" "July 2013" "rustpkg 0.7" "User Commands" -.SH NAME -rustpkg \- package manager for Rust applications -.SH SYNOPSIS -.B rustpkg -[\fICOMMAND\fR] [\fIOPTIONS\fR] \fIINPUT\fR - -.SH DESCRIPTION - -This tool is a package manager for applications written in the Rust language, -available at <\fBhttps://www.rust-lang.org\fR>. It provides commands to build, -install and test Rust programs. - -\fBrustpkg\fR is still a work in progress. See \fBdoc/rustpkg.md\fR in the Rust source distribution for future plans. - -.SH COMMANDS - -.TP -\fBbuild\fR -Searches for a package with the specified name and builds it in the workspace in -which it is found. -.TP -\fBclean\fR -Remove all generated files from the \fIbuild\fR directory in the target's workspace. -.TP -\fBinstall\fR -Builds the specified target, and all its dependencies, and then installs the -build products into the \fIlib\fR and \fIbin\fR directories of their respective -workspaces. -.TP -\fBinit\fR -Initializes the current working directory into a workspace. - -.SS "BUILD COMMAND" - - rustpkg build \fI[pkgname]\fR - -The \fBbuild\fR command searches for a package with specified package name and -builds it in any workspace(s) where it finds one. Any dependent packages are -also built. The output files produced by the build phase are stored in the -\fIbuild\fR subdirectories of each package. The executables and libraries are -not copied to the 'bin' or 'lib' directories; that is the purpose of the -\fBinstall\fR command. - -.SS "CLEAN COMMAND" - - rustpkg clean \fI[pkgname]\fR - -deletes the contents of package's build directory. - -.SS "INSTALL COMMAND" - - rustpkg install \fI[url]\fR - -builds the libraries and/or executables that are targets for the specified -package name or URL, and then installs them either into package's \fIlib\fR -and \fIbin\fR directories, or into the \fIlib\fR and \fIbin\fR subdirectories -of the first entry in RUST_PATH. - -Examples: - - $ rustpkg install github.com/mozilla/servo.git#1.2 - $ rustpkg install rust-glfw - -.SS "INIT COMMAND" - - rustpkg init - -This will turn the current working directory into a workspace. The first -command you run when starting off a new project. - -Example: - - $ rustpkg init - -.SH "ENVIRONMENT" - -.TP -RUST_PATH -A colon-separated (semicolon-separated) list of paths denoting workspaces -to search for Rust source files. See the section \fBPATHS\fR for full details. - -.SH "PATHS" - -The \fBrustpkg\fR tool searches for packages in the folders specified by the -\fBRUST_PATH\fR environment variable. Each folder constitutes a -\fIworkspace\fR, which contains one or more modules available to import. - -In addition to the RUST_PATH settings, the following implicit paths are -\fIalways\fR searched, in the following order: - -1. Any folders named ".rust" in the current directory, \fIand every parent\fR -of the curent directory, up to the filesystem root; - -2. The system path "/usr/local" on Unix-style systems, or the equivalent on -Windows; and - -3. A folder named ".rust" in the user's home directory (ie. "~/.rust" on Unix- -style systems or the equivalent on Windows). - -.SH "PACKAGE STRUCTURE" - -A valid workspace must contain each of the following subdirectories: - -.TP -\fBsrc/\fR -Contains the Rust source code, with one subdirectory per package. Each -subdirectory contains source files for a given package. -.TP -\fBlib/\fR -"rustpkg install" installs libraries into a target-specific subdirectory of this directory. -.TP -\fBbin/\fR -"rustpkg install" installs executable binaries into a target-specific subdirectory of this directory. -.TP -\fBbuild/\fR -"rustpkg build" stores temporary build artifacts in a target-specific subdirectory of this directory. - -For example, if "foo" is a workspace containing the package "bar", then -"foo/src/bar/main.rs" would be the "main" entry point for building a "bar" -executable. - -.SH "PACKAGE IDENTIFIERS" - -A package identifier uniquely identifies a package. A package can be stored in -a workspace on the local file system, or on a remote Web server, in which case -the package ID resembles a URL. - -For example, \fIgithub.com/mozilla/rust\fR is a package ID -that would refer to the git repository browsable at \fIhttp://github.com/mozilla/rust\fR. - -A package ID can also specify a version, like: -\fIgithub.com/mozilla/rust#0.3\fR. In this case, \fBrustpkg\fR will check that -the repository \fIgithub.com/mozilla/rust\fR has a tag named \fI0.3\fR, and -report an error otherwise. - -.SH "SPECIAL MODULES" - -\fBrustpkg\fR searches for four different known filenames in the src directory -in order to determine which crates to build: - -.TP -\fBmain.rs\fR -Assumed to be a main entry point for building an executable (install destination is 'bin' directory). -.TP -\fBlib.rs\fR -Assumed to be a library crate (install destination is 'lib' directory). -.TP -\fBtest.rs\fR -Assumed to contain tests declared with the \fI#[test]\fR attribute. -.TP -\fBbench.rs\fR -Assumed to contain benchmarks declared with the \fI#[bench]\fR attribute. - -.SH "CRATE VERSIONS" - -\fBrustpkg\fR packages do not need to declare their versions with an attribute -inside one of the source files, because rustpkg infers it from the version -control system. When building a package that is in a git repository, -rustpkg assumes that the most recent tag specifies the current version. When -building a package that is not under version control, or that has no tags, -rustpkg defaults the version to 0.1. - -.SH "DEPENDENCIES" - -rustpkg infers dependencies from "extern mod" directives. Thus, there should -be no need to pass a "-L" flag to rustpkg to tell it where to find a library. -(In the future, it will also be possible to write an "extern mod" directive -referring to a remote package.) - -.SH "CUSTOM BUILD SCRIPTS" - -A file called \fIpkg.rs\fR at the root level in a workspace is called a \fIpackage -script\fR. If a package script exists, rustpkg executes it to build the -package rather than inferring crates as described previously. - -Inside \fIpkg.rs\fR, it's possible to call back into rustpkg to finish up the -build. The \fIrustpkg::api\fR module contains functions to build, install, or -clean libraries and executables in the way rustpkg normally would without -custom build logic. - -.SH "SEE ALSO" - -rustc, rustdoc - -.SH "BUGS" -See <\fBhttps://github.com/mozilla/rust/issues\fR> for issues. - -.SH "AUTHOR" -See \fBAUTHORS.txt\fR in the Rust source distribution. Graydon Hoare -<\fIgraydon@mozilla.com\fR> is the project leader. - -.SH "COPYRIGHT" -This work is dual-licensed under Apache 2.0 and MIT terms. See \fBCOPYRIGHT\fR -file in the rust source distribution. diff --git a/mk/crates.mk b/mk/crates.mk index a8f14bab1e8..7ac3c3b486b 100644 --- a/mk/crates.mk +++ b/mk/crates.mk @@ -50,9 +50,9 @@ ################################################################################ TARGET_CRATES := std extra green rustuv native flate arena glob -HOST_CRATES := syntax rustc rustdoc rustpkg +HOST_CRATES := syntax rustc rustdoc CRATES := $(TARGET_CRATES) $(HOST_CRATES) -TOOLS := compiletest rustpkg rustdoc rustc +TOOLS := compiletest rustdoc rustc DEPS_std := native:rustrt DEPS_extra := std @@ -62,17 +62,14 @@ DEPS_native := std DEPS_syntax := std extra DEPS_rustc := syntax native:rustllvm flate arena DEPS_rustdoc := rustc native:sundown -DEPS_rustpkg := rustc DEPS_flate := std native:miniz DEPS_arena := std extra DEPS_glob := std TOOL_DEPS_compiletest := extra green rustuv -TOOL_DEPS_rustpkg := rustpkg green rustuv TOOL_DEPS_rustdoc := rustdoc green rustuv TOOL_DEPS_rustc := rustc green rustuv TOOL_SOURCE_compiletest := $(S)src/compiletest/compiletest.rs -TOOL_SOURCE_rustpkg := $(S)src/driver/driver.rs TOOL_SOURCE_rustdoc := $(S)src/driver/driver.rs TOOL_SOURCE_rustc := $(S)src/driver/driver.rs diff --git a/mk/dist.mk b/mk/dist.mk index 9f0f64f4c65..656811bab4d 100644 --- a/mk/dist.mk +++ b/mk/dist.mk @@ -28,7 +28,6 @@ PKG_FILES := \ $(addprefix $(S)src/, \ README.txt \ driver \ - librustpkg \ librustc \ compiletest \ etc \ diff --git a/mk/docs.mk b/mk/docs.mk index 2eb12ae47cc..4130edba616 100644 --- a/mk/docs.mk +++ b/mk/docs.mk @@ -89,12 +89,6 @@ doc/rust.epub: rust.md $(Q)$(CFG_NODE) $(S)doc/prep.js --highlight $< | \ $(CFG_PANDOC) $(EPUB_OPTS) --output=$@ -DOCS += doc/rustpkg.html -doc/rustpkg.html: rustpkg.md $(HTML_DEPS) - @$(call E, pandoc: $@) - $(Q)$(CFG_NODE) $(S)doc/prep.js --highlight $< | \ - $(CFG_PANDOC) $(HTML_OPTS) --output=$@ - DOCS += doc/rustdoc.html doc/rustdoc.html: rustdoc.md $(HTML_DEPS) @$(call E, pandoc: $@) @@ -212,12 +206,6 @@ doc/guide-conditions.html: $(S)doc/guide-conditions.md $(HTML_DEPS) $(Q)$(CFG_NODE) $(S)doc/prep.js --highlight $< | \ $(CFG_PANDOC) $(HTML_OPTS) --output=$@ -DOCS += doc/guide-rustpkg.html -doc/guide-rustpkg.html: $(S)doc/guide-rustpkg.md $(HTML_DEPS) - @$(call E, pandoc: $@) - $(Q)$(CFG_NODE) $(S)doc/prep.js --highlight $< | \ - $(CFG_PANDOC) $(HTML_OPTS) --output=$@ - DOCS += doc/guide-pointers.html doc/guide-pointers.html: $(S)doc/guide-pointers.md $(HTML_DEPS) @$(call E, pandoc: $@) diff --git a/mk/tests.mk b/mk/tests.mk index ab70b3afba9..6d151cfc86a 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -185,7 +185,6 @@ check-test: cleantestlibs cleantmptestlogs all check-stage2-rfail check-lite: cleantestlibs cleantmptestlogs \ check-stage2-std check-stage2-extra check-stage2-rpass \ check-stage2-rustuv check-stage2-native check-stage2-green \ - check-stage2-rustpkg \ check-stage2-rfail check-stage2-cfail check-stage2-rmake $(Q)$(CFG_PYTHON) $(S)src/etc/check-summary.py tmp/*.log @@ -423,18 +422,6 @@ $(foreach host,$(CFG_HOST), \ $(eval $(call DEF_TEST_CRATE_RULES,$(stage),$(target),$(host),$(crate))) \ )))))) -# FIXME (#10104): Raise the stack size to work around rustpkg bypassing -# the code in rustc that would take care of it. -define DEF_RUSTPKG_STACK_FIX -$$(call TEST_OK_FILE,$(1),$(2),$(3),rustpkg): export RUST_MIN_STACK=8000000 -endef - -$(foreach host,$(CFG_HOST), \ - $(foreach target,$(CFG_TARGET), \ - $(foreach stage,$(STAGES), \ - $(eval $(call DEF_RUSTPKG_STACK_FIX,$(stage),$(target),$(host)))))) - - ###################################################################### # Rules for the compiletest tests (rpass, rfail, etc.) ###################################################################### diff --git a/src/README.md b/src/README.md index f6c7e847cc7..cc67a3717fa 100644 --- a/src/README.md +++ b/src/README.md @@ -30,7 +30,6 @@ Source layout: | `test/auxiliary` | - Dependencies of tests | | ------------------- | --------------------------------------------------------- | | `librustdoc/` | The Rust API documentation tool | -| `librustpkg/` | The package manager and build system | | `libuv/` | The libuv submodule | | ------------------- | --------------------------------------------------------- | | `llvm/` | The LLVM submodule | diff --git a/src/driver/driver.rs b/src/driver/driver.rs index df5594b6c86..25095950e18 100644 --- a/src/driver/driver.rs +++ b/src/driver/driver.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[cfg(rustpkg)] -extern mod this = "rustpkg"; - #[cfg(rustdoc)] extern mod this = "rustdoc"; diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index cebc25c4845..4ef97e9234a 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -150,8 +150,9 @@ pub struct Options { lint_opts: ~[(lint::Lint, lint::level)], save_temps: bool, output_type: back::link::OutputType, - // This is mutable for rustpkg, which updates search paths based on the - // parsed code. + // This was mutable for rustpkg, which updates search paths based on the + // parsed code. It remains mutable in case its replacements wants to use + // this. addl_lib_search_paths: @RefCell>, ar: Option<~str>, linker: Option<~str>, diff --git a/src/librustpkg/README.txt b/src/librustpkg/README.txt deleted file mode 100644 index acfbf395e4b..00000000000 --- a/src/librustpkg/README.txt +++ /dev/null @@ -1,24 +0,0 @@ -Right now, commands that work are "build" and "clean". - -`rustpkg build` and `rustpkg clean` should work - -for example: -$ cd ~/rust/src/librustpkg/testsuite/pass -$ rustpkg build hello-world -... some output ... -$ rustpkg clean hello-world - -------------- -the following test packages in librustpkg/testsuite/pass: - * hello-world - * install-paths - * simple-lib - * deeply/nested/path - * fancy-lib - - It fails on the following test packages: - * external-crate (no support for `extern mod` inference yet) - -and should fail with proper error messages -on all of the test packages in librustpkg/testsuite/fail - * no-inferred-crates diff --git a/src/librustpkg/api.rs b/src/librustpkg/api.rs deleted file mode 100644 index 13d5a117704..00000000000 --- a/src/librustpkg/api.rs +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use CtxMethods; -use context::*; -use crate::*; -use package_source::*; -use path_util::{platform_library_name, target_build_dir}; -use target::*; -use workspace::pkg_parent_workspaces; -use workcache_support::*; -pub use path_util::default_workspace; - -pub use source_control::{safe_git_clone, git_clone_url}; - -use std::run; -use extra::arc::{Arc,RWArc}; -use extra::workcache; -use extra::workcache::{Database, FreshnessMap}; -use extra::treemap::TreeMap; -use syntax::crateid::CrateId; - -// A little sad -- duplicated from rustc::back::* -#[cfg(target_arch = "arm")] -fn cc_args() -> ~[~str] { ~[~"-marm"] } -#[cfg(target_arch = "mips")] -fn cc_args() -> ~[~str] { ~[] } -#[cfg(target_arch = "x86")] -fn cc_args() -> ~[~str] { ~[~"-m32"] } -#[cfg(target_arch = "x86_64")] -fn cc_args() -> ~[~str] { ~[~"-m64"] } - -/// Convenience functions intended for calling from pkg.rs -/// p is where to put the cache file for dependencies -pub fn default_context(sysroot: Path, p: Path) -> BuildContext { - new_default_context(new_workcache_context(&p), sysroot) -} - -pub fn new_default_context(c: workcache::Context, p: Path) -> BuildContext { - BuildContext { - context: Context { - cfgs: ~[], - rustc_flags: RustcFlags::default(), - use_rust_path_hack: false, - }, - sysroot: p, - workcache_context: c - } -} - -fn file_is_fresh(path: &str, in_hash: &str) -> bool { - let path = Path::new(path); - path.exists() && in_hash == digest_file_with_date(&path) -} - -fn binary_is_fresh(path: &str, in_hash: &str) -> bool { - let path = Path::new(path); - path.exists() && in_hash == digest_only_date(&path) -} - -pub fn new_workcache_context(p: &Path) -> workcache::Context { - let db_file = p.join("rustpkg_db.json"); // ??? probably wrong - debug!("Workcache database file: {}", db_file.display()); - let db = RWArc::new(Database::new(db_file)); - let cfg = Arc::new(TreeMap::new()); - let mut freshness: FreshnessMap = TreeMap::new(); - // Set up freshness functions for every type of dependency rustpkg - // knows about - freshness.insert(~"file", file_is_fresh); - freshness.insert(~"binary", binary_is_fresh); - workcache::Context::new_with_freshness(db, cfg, Arc::new(freshness)) -} - -pub fn build_lib(sysroot: Path, root: Path, name: ~str, lib: Path) { - build_lib_with_cfgs(sysroot, root, name, lib, ~[]) -} - -pub fn build_lib_with_cfgs(sysroot: Path, root: Path, name: ~str, lib: Path, cfgs: ~[~str]) { - let cx = default_context(sysroot, root.clone()); - let crate_id: CrateId = from_str(name).expect("valid crate id"); - let pkg_src = PkgSrc { - source_workspace: root.clone(), - build_in_destination: false, - destination_workspace: root.clone(), - start_dir: root.join_many(["src", name.as_slice()]), - id: crate_id, - // n.b. This assumes the package only has one crate - libs: ~[mk_crate(lib)], - mains: ~[], - tests: ~[], - benchs: ~[] - }; - pkg_src.build(&cx, cfgs, []); -} - -pub fn build_exe(sysroot: Path, root: Path, name: ~str, main: Path) { - build_exe_with_cfgs(sysroot, root, name, main, ~[]) -} - -pub fn build_exe_with_cfgs(sysroot: Path, root: Path, name: ~str, main: Path, cfgs: ~[~str]) { - let cx = default_context(sysroot, root.clone()); - let crate_id: CrateId = from_str(name).expect("valid crate id"); - let pkg_src = PkgSrc { - source_workspace: root.clone(), - build_in_destination: false, - destination_workspace: root.clone(), - start_dir: root.join_many(["src", name.as_slice()]), - id: crate_id, - libs: ~[], - // n.b. This assumes the package only has one crate - mains: ~[mk_crate(main)], - tests: ~[], - benchs: ~[] - }; - - pkg_src.build(&cx, cfgs, []); -} - -pub fn install_pkg(cx: &BuildContext, - workspace: Path, - name: ~str, - // For now, these inputs are assumed to be inputs to each of the crates - more_inputs: ~[(~str, Path)]) { // pairs of Kind and Path - let crate_id: CrateId = from_str(name).expect("valid crate id"); - cx.install(PkgSrc::new(workspace.clone(), workspace, false, crate_id), - &WhatToBuild{ build_type: Inferred, - inputs_to_discover: more_inputs, - sources: Everything }); -} - -/// Builds an arbitrary library whose short name is `output`, -/// by invoking `tool` with arguments `args` plus "-o %s", where %s -/// is the platform-specific library name for `output`. -/// Returns that platform-specific name, or None if `tool` could not be started. -pub fn build_library_in_workspace(exec: &mut workcache::Exec, - context: &mut Context, - package_name: &str, - tool: &str, - flags: &[~str], - paths: &[~str], - output: &str) -> Option<~str> { - use command_failed = conditions::command_failed::cond; - - let workspace = my_workspace(context, package_name); - let workspace_build_dir = target_build_dir(&workspace); - let out_name = workspace_build_dir.join_many([package_name.to_str(), - platform_library_name(output)]); - // make paths absolute - let crateid: CrateId = from_str(package_name).expect("valid crate id"); - let absolute_paths = paths.map(|s| { - let whatever = workspace.join_many([~"src", - crateid.short_name_with_version(), - s.to_owned()]); - whatever.as_str().unwrap().to_owned() - }); - - let cc_args = cc_args(); - - let all_args = flags + absolute_paths + cc_args + - ~[~"-o", out_name.as_str().unwrap().to_owned()]; - match run::process_status(tool, all_args) { - Some(exit_process) => { - if exit_process.success() { - let out_name_str = out_name.as_str().unwrap().to_owned(); - exec.discover_output("binary", - out_name_str, - digest_only_date(&out_name)); - context.add_library_path(out_name.dir_path()); - Some(out_name_str) - } else { - Some(command_failed.raise((tool.to_owned(), all_args, exit_process))) - } - }, - None => None - } -} - -pub fn my_workspace(context: &Context, package_name: &str) -> Path { - use bad_pkg_id = conditions::bad_pkg_id::cond; - - // (this assumes no particular version is requested) - let crateid = from_str(package_name).expect("valid crate id"); - let workspaces = pkg_parent_workspaces(context, &crateid); - if workspaces.is_empty() { - bad_pkg_id.raise((Path::new(package_name), package_name.to_owned())); - } - workspaces[0] -} - -fn mk_crate(p: Path) -> Crate { - Crate { file: p, flags: ~[], cfgs: ~[] } -} diff --git a/src/librustpkg/conditions.rs b/src/librustpkg/conditions.rs deleted file mode 100644 index d18161d7c4a..00000000000 --- a/src/librustpkg/conditions.rs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Useful conditions - -pub use syntax::crateid::CrateId; -pub use std::io::FileStat; -pub use std::io::process::ProcessExit; -pub use std::path::Path; - -condition! { - pub bad_path: (Path, ~str) -> Path; -} - -condition! { - pub nonexistent_package: (CrateId, ~str) -> Path; -} - -condition! { - pub missing_pkg_files: (CrateId) -> (); -} - -condition! { - pub bad_pkg_id: (Path, ~str) -> CrateId; -} - -condition! { - pub failed_to_create_temp_dir: (~str) -> Path; -} - -condition! { - pub git_checkout_failed: (~str, Path) -> (); -} - -condition! { - // str is output of applying the command (first component) - // to the args (second component) - pub command_failed: (~str, ~[~str], ProcessExit) -> ~str; -} diff --git a/src/librustpkg/context.rs b/src/librustpkg/context.rs deleted file mode 100644 index 01df2bf1619..00000000000 --- a/src/librustpkg/context.rs +++ /dev/null @@ -1,347 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Context data structure used by rustpkg - -use extra::workcache; -use rustc::driver::session; -use rustc::metadata::filesearch::rustlibdir; - -use std::hashmap::HashSet; - -#[deriving(Clone)] -pub struct Context { - // Config strings that the user passed in with --cfg - cfgs: ~[~str], - // Flags to pass to rustc - rustc_flags: RustcFlags, - // If use_rust_path_hack is true, rustpkg searches for sources - // in *package* directories that are in the RUST_PATH (for example, - // FOO/src/bar-0.1 instead of FOO). The flag doesn't affect where - // rustpkg stores build artifacts. - use_rust_path_hack: bool, -} - -#[deriving(Clone)] -pub struct BuildContext { - // Context for workcache - workcache_context: workcache::Context, - // Parsed command line options - context: Context, - // The root directory containing the Rust standard libraries - sysroot: Path -} - -impl BuildContext { - pub fn sysroot(&self) -> Path { - self.sysroot.clone() - } - - // Hack so that rustpkg can run either out of a rustc target dir, - // or the host dir - pub fn sysroot_to_use(&self) -> Path { - if !in_target(&self.sysroot) { - self.sysroot.clone() - } else { - let mut p = self.sysroot.clone(); - p.pop(); - p.pop(); - p.pop(); - p - } - } - - /// Returns the flags to pass to rustc, as a vector of strings - pub fn flag_strs(&self) -> ~[~str] { - self.context.flag_strs() - } - - pub fn compile_upto(&self) -> StopBefore { - self.context.compile_upto() - } - - pub fn add_library_path(&mut self, p: Path) { - debug!("Adding library path: {}", p.display()); - self.context.add_library_path(p); - } - - pub fn additional_library_paths(&self) -> HashSet { - self.context.rustc_flags.additional_library_paths.clone() - } -} - -/* -Deliberately unsupported rustc flags: - --bin, --lib inferred from crate file names - -L inferred from extern mods - --out-dir inferred from RUST_PATH - --test use `rustpkg test` - -v -h --ls don't make sense with rustpkg - -W -A -D -F - use pragmas instead - -rustc flags that aren't implemented yet: - --passes - --llvm-arg - --target-feature - --android-cross-path -*/ -pub struct RustcFlags { - compile_upto: StopBefore, - // Linker to use with the --linker flag - linker: Option<~str>, - // Extra arguments to pass to rustc with the --link-args flag - link_args: Option<~str>, - // Optimization level. 0 = default. -O = 2. - optimization_level: session::OptLevel, - // True if the user passed in --save-temps - save_temps: bool, - // Target (defaults to rustc's default target) - target: Option<~str>, - // Target CPU (defaults to rustc's default target CPU) - target_cpu: Option<~str>, - // Additional library directories, which get passed with the -L flag - // This can't be set with a rustpkg flag, only from package scripts - additional_library_paths: HashSet, - // Any -Z features - experimental_features: Option<~[~str]> -} - -impl Clone for RustcFlags { - fn clone(&self) -> RustcFlags { - RustcFlags { - compile_upto: self.compile_upto, - linker: self.linker.clone(), - link_args: self.link_args.clone(), - optimization_level: self.optimization_level, - save_temps: self.save_temps, - target: self.target.clone(), - target_cpu: self.target_cpu.clone(), - additional_library_paths: self.additional_library_paths.clone(), - experimental_features: self.experimental_features.clone() - } - } -} - -#[deriving(Eq)] -pub enum StopBefore { - Nothing, // compile everything - Link, // --no-link - LLVMCompileBitcode, // --emit-llvm without -S - LLVMAssemble, // -S --emit-llvm - Assemble, // -S without --emit-llvm - Trans, // --no-trans - Pretty, // --pretty - Analysis, // --parse-only -} - -impl Context { - - /// Returns the flags to pass to rustc, as a vector of strings - pub fn flag_strs(&self) -> ~[~str] { - self.rustc_flags.flag_strs() - } - - pub fn compile_upto(&self) -> StopBefore { - self.rustc_flags.compile_upto - } - - pub fn add_library_path(&mut self, p: Path) { - self.rustc_flags.additional_library_paths.insert(p); - } -} - -/// We assume that if ../../rustlib exists, then we're running -/// rustpkg from a Rust target directory. This is part of a -/// kludgy hack used to adjust the sysroot. -pub fn in_target(sysroot: &Path) -> bool { - debug!("Checking whether {} is in target", sysroot.display()); - let mut p = sysroot.dir_path(); - p.pop(); - p.push(rustlibdir()); - p.is_dir() -} - -impl RustcFlags { - fn flag_strs(&self) -> ~[~str] { - let linker_flag = match self.linker { - Some(ref l) => ~[~"--linker", l.clone()], - None => ~[] - }; - let link_args_flag = match self.link_args { - Some(ref l) => ~[~"--link-args", l.clone()], - None => ~[] - }; - let save_temps_flag = if self.save_temps { ~[~"--save-temps"] } else { ~[] }; - let target_flag = match self.target { - Some(ref l) => ~[~"--target", l.clone()], - None => ~[] - }; - let target_cpu_flag = match self.target_cpu { - Some(ref l) => ~[~"--target-cpu", l.clone()], - None => ~[] - }; - let z_flags = match self.experimental_features { - Some(ref ls) => ls.flat_map(|s| ~[~"-Z", s.clone()]), - None => ~[] - }; - linker_flag - + link_args_flag - + save_temps_flag - + target_flag - + target_cpu_flag - + z_flags + (match self.compile_upto { - LLVMCompileBitcode => ~[~"--emit-llvm"], - LLVMAssemble => ~[~"--emit-llvm", ~"-S"], - Link => ~[~"-c"], - Trans => ~[~"--no-trans"], - Assemble => ~[~"-S"], - // n.b. Doesn't support all flavors of --pretty (yet) - Pretty => ~[~"--pretty"], - Analysis => ~[~"--parse-only"], - Nothing => ~[] - }) - } - - pub fn default() -> RustcFlags { - RustcFlags { - linker: None, - link_args: None, - compile_upto: Nothing, - optimization_level: session::Default, - save_temps: false, - target: None, - target_cpu: None, - additional_library_paths: HashSet::new(), - experimental_features: None - } - } -} - - -#[deriving(Eq)] -pub enum Command { - BuildCmd, - CleanCmd, - DoCmd, - HelpCmd, - InfoCmd, - InitCmd, - InstallCmd, - ListCmd, - PreferCmd, - TestCmd, - UninstallCmd, - UnpreferCmd, -} - -impl FromStr for Command { - - fn from_str(s: &str) -> Option { - match s { - &"build" => Some(BuildCmd), - &"clean" => Some(CleanCmd), - &"do" => Some(DoCmd), - &"help" => Some(HelpCmd), - &"info" => Some(InfoCmd), - &"install" => Some(InstallCmd), - &"list" => Some(ListCmd), - &"prefer" => Some(PreferCmd), - &"test" => Some(TestCmd), - &"init" => Some(InitCmd), - &"uninstall" => Some(UninstallCmd), - &"unprefer" => Some(UnpreferCmd), - _ => None - } - } -} - -/// Returns true if any of the flags given are incompatible with the cmd -pub fn flags_forbidden_for_cmd(flags: &RustcFlags, - cfgs: &[~str], - cmd: Command, user_supplied_opt_level: bool) -> bool { - let complain = |s| { - println!("The {} option can only be used with the `build` command: - rustpkg [options..] build {} [package-ID]", s, s); - }; - - if flags.linker.is_some() && cmd != BuildCmd && cmd != InstallCmd { - println!("The --linker option can only be used with the build or install commands."); - return true; - } - if flags.link_args.is_some() && cmd != BuildCmd && cmd != InstallCmd { - println!("The --link-args option can only be used with the build or install commands."); - return true; - } - - if !cfgs.is_empty() && cmd != BuildCmd && cmd != InstallCmd && cmd != TestCmd { - println!("The --cfg option can only be used with the build, test, or install commands."); - return true; - } - - if user_supplied_opt_level && cmd != BuildCmd && cmd != InstallCmd { - println!("The -O and --opt-level options can only be used with the build \ - or install commands."); - return true; - } - - if flags.save_temps && cmd != BuildCmd && cmd != InstallCmd { - println!("The --save-temps option can only be used with the build \ - or install commands."); - return true; - } - - if flags.target.is_some() && cmd != BuildCmd && cmd != InstallCmd { - println!("The --target option can only be used with the build \ - or install commands."); - return true; - } - if flags.target_cpu.is_some() && cmd != BuildCmd && cmd != InstallCmd { - println!("The --target-cpu option can only be used with the build \ - or install commands."); - return true; - } - if flags.experimental_features.is_some() && cmd != BuildCmd && cmd != InstallCmd { - println!("The -Z option can only be used with the build or install commands."); - return true; - } - - match flags.compile_upto { - Link if cmd != BuildCmd => { - complain("--no-link"); - true - } - Trans if cmd != BuildCmd => { - complain("--no-trans"); - true - } - Assemble if cmd != BuildCmd => { - complain("-S"); - true - } - Pretty if cmd != BuildCmd => { - complain("--pretty"); - true - } - Analysis if cmd != BuildCmd => { - complain("--parse-only"); - true - } - LLVMCompileBitcode if cmd != BuildCmd => { - complain("--emit-llvm"); - true - } - LLVMAssemble if cmd != BuildCmd => { - complain("--emit-llvm"); - true - } - _ => false - } -} - diff --git a/src/librustpkg/crate.rs b/src/librustpkg/crate.rs deleted file mode 100644 index 345638386b2..00000000000 --- a/src/librustpkg/crate.rs +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2012-2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[allow(dead_code)]; - -use std::path::Path; -use std::vec; - -/// A crate is a unit of Rust code to be compiled into a binary or library -#[deriving(Clone)] -pub struct Crate { - file: Path, - flags: ~[~str], - cfgs: ~[~str] -} - -impl Crate { - - pub fn new(p: &Path) -> Crate { - Crate { - file: (*p).clone(), - flags: ~[], - cfgs: ~[] - } - } - - fn flag(&self, flag: ~str) -> Crate { - Crate { - flags: vec::append(self.flags.clone(), [flag]), - .. (*self).clone() - } - } - - fn flags(&self, flags: ~[~str]) -> Crate { - Crate { - flags: vec::append(self.flags.clone(), flags), - .. (*self).clone() - } - } - - fn cfg(&self, cfg: ~str) -> Crate { - Crate { - cfgs: vec::append(self.cfgs.clone(), [cfg]), - .. (*self).clone() - } - } - - fn cfgs(&self, cfgs: ~[~str]) -> Crate { - Crate { - cfgs: vec::append(self.cfgs.clone(), cfgs), - .. (*self).clone() - } - } -} diff --git a/src/librustpkg/exit_codes.rs b/src/librustpkg/exit_codes.rs deleted file mode 100644 index daa5eee62d2..00000000000 --- a/src/librustpkg/exit_codes.rs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -pub static COPY_FAILED_CODE: int = 65; -pub static BAD_FLAG_CODE: int = 67; -pub static NONEXISTENT_PACKAGE_CODE: int = 68; - diff --git a/src/librustpkg/installed_packages.rs b/src/librustpkg/installed_packages.rs deleted file mode 100644 index c7900181a77..00000000000 --- a/src/librustpkg/installed_packages.rs +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Listing installed packages - -use rustc::metadata::filesearch::rust_path; -use std::os; -use std::io; -use std::io::fs; -use syntax::crateid::CrateId; - -pub fn list_installed_packages(f: |&CrateId| -> bool) -> bool { - let workspaces = rust_path(); - for p in workspaces.iter() { - let binfiles = { - let _guard = io::ignore_io_error(); - fs::readdir(&p.join("bin")) - }; - for exec in binfiles.iter() { - // FIXME (#9639): This needs to handle non-utf8 paths - match exec.filestem_str() { - None => (), - Some(exec_path) => { - let crate_id = from_str(exec_path).expect("valid crate id"); - if !f(&crate_id) { - return false; - } - } - } - } - let libfiles = { - let _guard = io::ignore_io_error(); - fs::readdir(&p.join("lib")) - }; - for lib in libfiles.iter() { - debug!("Full name: {}", lib.display()); - match has_library(lib) { - Some(basename) => { - let parent = p.join("lib"); - debug!("parent = {}, child = {}", - parent.display(), lib.display()); - let rel_p = lib.path_relative_from(&parent).unwrap(); - debug!("Rel: {}", rel_p.display()); - let rel_path = rel_p.join(basename); - rel_path.display().with_str(|s| { - debug!("Rel name: {}", s); - let crate_id = from_str(s).expect("valid crate id"); - f(&crate_id); - }); - } - None => () - } - }; - } - true -} - -pub fn has_library(p: &Path) -> Option<~str> { - let files = { - let _guard = io::ignore_io_error(); - fs::readdir(p) - }; - for path in files.iter() { - if path.extension_str() == Some(os::consts::DLL_EXTENSION) { - let stuff : &str = path.filestem_str().expect("has_library: weird path"); - let mut stuff2 = stuff.split_str("-"); - let stuff3: ~[&str] = stuff2.collect(); - // argh - let chars_to_drop = os::consts::DLL_PREFIX.len(); - return Some(stuff3[0].slice(chars_to_drop, stuff3[0].len()).to_owned()); - } - } - None -} - -pub fn package_is_installed(p: &CrateId) -> bool { - let mut is_installed = false; - list_installed_packages(|installed| { - if installed == p { - is_installed = true; - false - } else { - true - } - }); - is_installed -} diff --git a/src/librustpkg/lib.rs b/src/librustpkg/lib.rs deleted file mode 100644 index b43ffec2783..00000000000 --- a/src/librustpkg/lib.rs +++ /dev/null @@ -1,816 +0,0 @@ -// Copyright 2012-2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// rustpkg - a package manager and build system for Rust - -#[crate_id = "rustpkg#0.10-pre"]; -#[license = "MIT/ASL2"]; -#[crate_type = "dylib"]; - -#[feature(globs, managed_boxes)]; - -extern mod extra; -extern mod rustc; -extern mod syntax; - -use std::{os, run, str, task}; -use std::io::process; -use std::io; -use std::io::fs; -pub use std::path::Path; - -use extra::workcache; -use rustc::driver::{driver, session}; -use rustc::metadata::creader::Loader; -use rustc::metadata::filesearch; -use rustc::metadata::filesearch::rust_path; -use rustc::util::sha2; -use syntax::{ast, diagnostic}; -use syntax::crateid::CrateId; -use messages::{error, warn, note}; -use parse_args::{ParseResult, parse_args}; -use path_util::{build_pkg_id_in_workspace, built_test_in_workspace}; -use path_util::in_rust_path; -use path_util::{built_executable_in_workspace, built_library_in_workspace, default_workspace}; -use path_util::{target_executable_in_workspace, target_library_in_workspace, dir_has_crate_file}; -use source_control::{CheckedOutSources, is_git_dir, make_read_only}; -use workspace::{each_pkg_parent_workspace, pkg_parent_workspaces, cwd_to_workspace}; -use workspace::determine_destination; -use context::{BuildContext, Trans, Nothing, Pretty, Analysis, - LLVMAssemble, LLVMCompileBitcode}; -use context::{Command, BuildCmd, CleanCmd, DoCmd, HelpCmd, InfoCmd, InstallCmd, ListCmd, - PreferCmd, TestCmd, InitCmd, UninstallCmd, UnpreferCmd}; -use package_source::PkgSrc; -use target::{WhatToBuild, Everything, is_lib, is_main, is_test, is_bench}; -use target::{Main, Tests, MaybeCustom, Inferred, JustOne}; -use workcache_support::digest_only_date; -use exit_codes::{COPY_FAILED_CODE}; - -pub mod api; -mod conditions; -pub mod context; -mod crate; -pub mod exit_codes; -mod installed_packages; -mod messages; -pub mod package_source; -mod parse_args; -mod path_util; -mod source_control; -mod target; -#[cfg(not(windows), test)] // FIXME test failure on windows: #10471 -mod tests; -mod util; -pub mod version; -pub mod workcache_support; -mod workspace; - -pub mod usage; - -/// A PkgScript represents user-supplied custom logic for -/// special build hooks. This only exists for packages with -/// an explicit package script. -struct PkgScript<'a> { - /// Uniquely identifies this package - id: &'a CrateId, - /// File path for the package script - input: Path, - /// The session to use *only* for compiling the custom - /// build script - sess: session::Session, - /// The config for compiling the custom build script - cfg: ast::CrateConfig, - /// The crate and ast_map for the custom build script - crate_and_map: Option<(ast::Crate, syntax::ast_map::Map)>, - /// Directory in which to store build output - build_dir: Path -} - -impl<'a> PkgScript<'a> { - /// Given the path name for a package script - /// and a package ID, parse the package script into - /// a PkgScript that we can then execute - fn parse<'a>(sysroot: Path, - script: Path, - workspace: &Path, - id: &'a CrateId) -> PkgScript<'a> { - // Get the executable name that was invoked - let binary = os::args()[0]; - // Build the rustc session data structures to pass - // to the compiler - debug!("pkgscript parse: {}", sysroot.display()); - let options = @session::Options { - binary: binary, - maybe_sysroot: Some(@sysroot), - outputs: ~[session::OutputExecutable], - .. (*session::basic_options()).clone() - }; - let input = driver::FileInput(script.clone()); - let sess = driver::build_session(options, - Some(script.clone()), - @diagnostic::DefaultEmitter); - let cfg = driver::build_configuration(sess); - let crate = driver::phase_1_parse_input(sess, cfg.clone(), &input); - let loader = &mut Loader::new(sess); - let crate_and_map = driver::phase_2_configure_and_expand(sess, - cfg.clone(), - loader, - crate); - let work_dir = build_pkg_id_in_workspace(id, workspace); - - debug!("Returning package script with id {}", id.to_str()); - - PkgScript { - id: id, - input: script, - sess: sess, - cfg: cfg, - crate_and_map: Some(crate_and_map), - build_dir: work_dir - } - } - - fn build_custom(&mut self, exec: &mut workcache::Exec) -> ~str { - let sess = self.sess; - - debug!("Working directory = {}", self.build_dir.display()); - // Collect together any user-defined commands in the package script - let (crate, ast_map) = self.crate_and_map.take_unwrap(); - let crate = util::ready_crate(sess, crate); - debug!("Building output filenames with script name {}", - driver::source_name(&driver::FileInput(self.input.clone()))); - let exe = self.build_dir.join("pkg" + util::exe_suffix()); - util::compile_crate_from_input(&self.input, - exec, - Nothing, - &self.build_dir, - sess, - crate, - ast_map, - Main); - // Discover the output - // FIXME (#9639): This needs to handle non-utf8 paths - // Discover the output - exec.discover_output("binary", exe.as_str().unwrap().to_owned(), digest_only_date(&exe)); - exe.as_str().unwrap().to_owned() - } - - /// Run the contents of this package script, where - /// is the command to pass to it (e.g., "build", "clean", "install") - /// Returns a pair of an exit code and list of configs (obtained by - /// calling the package script's configs() function if it exists, or - /// None if `exe` could not be started. - fn run_custom(exe: &Path, sysroot: &Path) -> Option<(~[~str], process::ProcessExit)> { - debug!("Running program: {} {} {}", exe.as_str().unwrap().to_owned(), - sysroot.display(), "install"); - // FIXME #7401 should support commands besides `install` - // FIXME (#9639): This needs to handle non-utf8 paths - let opt_status = run::process_status(exe.as_str().unwrap(), - [sysroot.as_str().unwrap().to_owned(), ~"install"]); - match opt_status { - Some(status) => { - if !status.success() { - debug!("run_custom: first pkg command failed with {:?}", status); - Some((~[], status)) - } - else { - debug!("Running program (configs): {} {} {}", - exe.display(), sysroot.display(), "configs"); - // FIXME (#9639): This needs to handle non-utf8 paths - let opt_output = run::process_output(exe.as_str().unwrap(), - [sysroot.as_str().unwrap().to_owned(), - ~"configs"]); - match opt_output { - Some(output) => { - debug!("run_custom: second pkg command did {:?}", output.status); - // Run the configs() function to get the configs - let cfgs = str::from_utf8(output.output).unwrap().words() - .map(|w| w.to_owned()).collect(); - Some((cfgs, output.status)) - }, - None => { - debug!("run_custom: second pkg command failed to start"); - Some((~[], status)) - } - } - } - }, - None => { - debug!("run_custom: first pkg command failed to start"); - None - } - } - } -} - -pub trait CtxMethods { - fn run(&self, cmd: Command, args: ~[~str]); - fn do_cmd(&self, _cmd: &str, _pkgname: &str); - /// Returns a pair of the selected package ID, and the destination workspace - fn build_args(&self, args: ~[~str], what: &WhatToBuild) -> Option<(CrateId, Path)>; - /// Returns the destination workspace - fn build(&self, pkg_src: &mut PkgSrc, what: &WhatToBuild); - fn clean(&self, workspace: &Path, id: &CrateId); - fn info(&self); - /// Returns a pair. First component is a list of installed paths, - /// second is a list of declared and discovered inputs - fn install(&self, src: PkgSrc, what: &WhatToBuild) -> (~[Path], ~[(~str, ~str)]); - /// Returns a list of installed files - fn install_no_build(&self, - build_workspace: &Path, - build_inputs: &[Path], - target_workspace: &Path, - id: &CrateId) -> ~[~str]; - fn prefer(&self, _id: &str, _vers: Option<~str>); - fn test(&self, id: &CrateId, workspace: &Path); - fn uninstall(&self, _id: &str, _vers: Option<~str>); - fn unprefer(&self, _id: &str, _vers: Option<~str>); - fn init(&self); -} - -impl CtxMethods for BuildContext { - fn build_args(&self, args: ~[~str], what: &WhatToBuild) -> Option<(CrateId, Path)> { - let cwd = os::getcwd(); - - if args.len() < 1 { - match cwd_to_workspace() { - None if dir_has_crate_file(&cwd) => { - // FIXME (#9639): This needs to handle non-utf8 paths - let crateid = from_str(cwd.filename_str().unwrap()).expect("valid crate id"); - let mut pkg_src = PkgSrc::new(cwd, default_workspace(), true, crateid); - self.build(&mut pkg_src, what); - match pkg_src { - PkgSrc { destination_workspace: ws, - id: id, .. } => { - Some((id, ws)) - } - } - } - None => { usage::build(); None } - Some((ws, crateid)) => { - let mut pkg_src = PkgSrc::new(ws.clone(), ws, false, crateid); - self.build(&mut pkg_src, what); - match pkg_src { - PkgSrc { destination_workspace: ws, - id: id, .. } => { - Some((id, ws)) - } - } - } - } - } else { - // The package id is presumed to be the first command-line - // argument - let crateid = from_str(args[0]).expect("valid crate id"); - let mut dest_ws = default_workspace(); - each_pkg_parent_workspace(&self.context, &crateid, |workspace| { - debug!("found pkg {} in workspace {}, trying to build", - crateid.to_str(), workspace.display()); - dest_ws = determine_destination(os::getcwd(), - self.context.use_rust_path_hack, - workspace); - let mut pkg_src = PkgSrc::new(workspace.clone(), dest_ws.clone(), - false, crateid.clone()); - self.build(&mut pkg_src, what); - true - }); - // n.b. If this builds multiple packages, it only returns the workspace for - // the last one. The whole building-multiple-packages-with-the-same-ID is weird - // anyway and there are no tests for it, so maybe take it out - Some((crateid, dest_ws)) - } - } - - fn run(&self, cmd: Command, args: ~[~str]) { - let cwd = os::getcwd(); - match cmd { - BuildCmd => { - self.build_args(args, &WhatToBuild::new(MaybeCustom, Everything)); - } - CleanCmd => { - if args.len() < 1 { - match cwd_to_workspace() { - None => { usage::clean(); return } - // tjc: Maybe clean should clean all the packages in the - // current workspace, though? - Some((ws, crateid)) => self.clean(&ws, &crateid) - } - - } - else { - // The package id is presumed to be the first command-line - // argument - let crateid = from_str(args[0]).expect("valid crate id"); - self.clean(&cwd, &crateid); // tjc: should use workspace, not cwd - } - } - DoCmd => { - if args.len() < 2 { - return usage::do_cmd(); - } - - self.do_cmd(args[0].clone(), args[1].clone()); - } - HelpCmd => { - if args.len() != 1 { - return usage::general(); - } - match FromStr::from_str(args[0]) { - Some(help_cmd) => usage::usage_for_command(help_cmd), - None => { - usage::general(); - error(format!("{} is not a recognized command", args[0])) - } - } - } - InfoCmd => { - self.info(); - } - InstallCmd => { - if args.len() < 1 { - match cwd_to_workspace() { - None if dir_has_crate_file(&cwd) => { - // FIXME (#9639): This needs to handle non-utf8 paths - - let inferred_crateid = - from_str(cwd.filename_str().unwrap()).expect("valid crate id"); - self.install(PkgSrc::new(cwd, default_workspace(), - true, inferred_crateid), - &WhatToBuild::new(MaybeCustom, Everything)); - } - None => { usage::install(); return; } - Some((ws, crateid)) => { - let pkg_src = PkgSrc::new(ws.clone(), ws.clone(), false, crateid); - self.install(pkg_src, &WhatToBuild::new(MaybeCustom, - Everything)); - } - } - } - else { - // The package id is presumed to be the first command-line - // argument - let crateid = from_str(args[0]).expect("valid crate id"); - let workspaces = pkg_parent_workspaces(&self.context, &crateid); - debug!("package ID = {}, found it in {:?} workspaces", - crateid.to_str(), workspaces.len()); - if workspaces.is_empty() { - let d = default_workspace(); - let src = PkgSrc::new(d.clone(), d, false, crateid.clone()); - self.install(src, &WhatToBuild::new(MaybeCustom, Everything)); - } - else { - for workspace in workspaces.iter() { - let dest = determine_destination(os::getcwd(), - self.context.use_rust_path_hack, - workspace); - let src = PkgSrc::new(workspace.clone(), - dest, - self.context.use_rust_path_hack, - crateid.clone()); - self.install(src, &WhatToBuild::new(MaybeCustom, Everything)); - }; - } - } - } - ListCmd => { - println!("Installed packages:"); - installed_packages::list_installed_packages(|pkg_id| { - println!("{}", pkg_id.path); - true - }); - } - PreferCmd => { - if args.len() < 1 { - return usage::prefer(); - } - - self.prefer(args[0], None); - } - TestCmd => { - // Build the test executable - let maybe_id_and_workspace = self.build_args(args, - &WhatToBuild::new(MaybeCustom, Tests)); - match maybe_id_and_workspace { - Some((pkg_id, workspace)) => { - // Assuming it's built, run the tests - self.test(&pkg_id, &workspace); - } - None => { - error("Testing failed because building the specified package failed."); - } - } - } - InitCmd => { - if args.len() != 0 { - return usage::init(); - } else { - self.init(); - } - } - UninstallCmd => { - if args.len() < 1 { - return usage::uninstall(); - } - - let crateid = from_str(args[0]).expect("valid crate id"); - if !installed_packages::package_is_installed(&crateid) { - warn(format!("Package {} doesn't seem to be installed! \ - Doing nothing.", args[0])); - return; - } - else { - let rp = rust_path(); - assert!(!rp.is_empty()); - each_pkg_parent_workspace(&self.context, &crateid, |workspace| { - path_util::uninstall_package_from(workspace, &crateid); - note(format!("Uninstalled package {} (was installed in {})", - crateid.to_str(), workspace.display())); - true - }); - } - } - UnpreferCmd => { - if args.len() < 1 { - return usage::unprefer(); - } - - self.unprefer(args[0], None); - } - } - } - - fn do_cmd(&self, _cmd: &str, _pkgname: &str) { - // stub - fail!("`do` not yet implemented"); - } - - fn build(&self, pkg_src: &mut PkgSrc, what_to_build: &WhatToBuild) { - use conditions::git_checkout_failed::cond; - - let workspace = pkg_src.source_workspace.clone(); - let crateid = pkg_src.id.clone(); - - let path = crateid.path.as_slice(); - debug!("build: workspace = {} (in Rust path? {:?} is git dir? {:?} \ - crateid = {} pkgsrc start_dir = {}", workspace.display(), - in_rust_path(&workspace), is_git_dir(&workspace.join(path)), - crateid.to_str(), pkg_src.start_dir.display()); - debug!("build: what to build = {:?}", what_to_build); - - // If workspace isn't in the RUST_PATH, and it's a git repo, - // then clone it into the first entry in RUST_PATH, and repeat - if !in_rust_path(&workspace) && is_git_dir(&workspace.join(path)) { - let mut out_dir = default_workspace().join("src"); - out_dir.push(path); - let git_result = source_control::safe_git_clone(&workspace.join(path), - &crateid.version, - &out_dir); - match git_result { - CheckedOutSources => make_read_only(&out_dir), - _ => cond.raise((path.to_owned(), out_dir.clone())) - }; - let default_ws = default_workspace(); - debug!("Calling build recursively with {:?} and {:?}", default_ws.display(), - crateid.to_str()); - return self.build(&mut PkgSrc::new(default_ws.clone(), - default_ws, - false, - crateid.clone()), what_to_build); - } - - // Is there custom build logic? If so, use it - let mut custom = false; - debug!("Package source directory = {}", pkg_src.to_str()); - let opt = pkg_src.package_script_option(); - debug!("Calling pkg_script_option on {:?}", opt); - let cfgs = match (pkg_src.package_script_option(), what_to_build.build_type) { - (Some(package_script_path), MaybeCustom) => { - let sysroot = self.sysroot_to_use(); - // Build the package script if needed - let script_build = format!("build_package_script({})", - package_script_path.display()); - let pkg_exe = self.workcache_context.with_prep(script_build, |prep| { - let subsysroot = sysroot.clone(); - let psp = package_script_path.clone(); - let ws = workspace.clone(); - let pid = crateid.clone(); - prep.exec(proc(exec) { - let mut pscript = PkgScript::parse(subsysroot.clone(), - psp.clone(), - &ws, - &pid); - pscript.build_custom(exec) - }) - }); - // We always *run* the package script - match PkgScript::run_custom(&Path::new(pkg_exe), &sysroot) { - Some((cfgs, hook_result)) => { - debug!("Command return code = {:?}", hook_result); - if !hook_result.success() { - fail!("Error running custom build command") - } - custom = true; - // otherwise, the package script succeeded - cfgs - }, - None => { - fail!("Error starting custom build command") - } - } - } - (Some(_), Inferred) => { - debug!("There is a package script, but we're ignoring it"); - ~[] - } - (None, _) => { - debug!("No package script, continuing"); - ~[] - } - } + self.context.cfgs; - - // If there was a package script, it should have finished - // the build already. Otherwise... - if !custom { - match what_to_build.sources { - // Find crates inside the workspace - Everything => pkg_src.find_crates(), - // Find only tests - Tests => pkg_src.find_crates_with_filter(|s| { is_test(&Path::new(s)) }), - // Don't infer any crates -- just build the one that was requested - JustOne(ref p) => { - // We expect that p is relative to the package source's start directory, - // so check that assumption - debug!("JustOne: p = {}", p.display()); - assert!(pkg_src.start_dir.join(p).exists()); - if is_lib(p) { - PkgSrc::push_crate(&mut pkg_src.libs, 0, p); - } else if is_main(p) { - PkgSrc::push_crate(&mut pkg_src.mains, 0, p); - } else if is_test(p) { - PkgSrc::push_crate(&mut pkg_src.tests, 0, p); - } else if is_bench(p) { - PkgSrc::push_crate(&mut pkg_src.benchs, 0, p); - } else { - warn(format!("Not building any crates for dependency {}", p.display())); - return; - } - } - } - // Build it! - pkg_src.build(self, cfgs, []); - } - } - - fn clean(&self, workspace: &Path, id: &CrateId) { - // Could also support a custom build hook in the pkg - // script for cleaning files rustpkg doesn't know about. - // Do something reasonable for now - - let dir = build_pkg_id_in_workspace(id, workspace); - note(format!("Cleaning package {} (removing directory {})", - id.to_str(), dir.display())); - if dir.exists() { - fs::rmdir_recursive(&dir); - note(format!("Removed directory {}", dir.display())); - } - - note(format!("Cleaned package {}", id.to_str())); - } - - fn info(&self) { - // stub - fail!("info not yet implemented"); - } - - fn install(&self, mut pkg_src: PkgSrc, what: &WhatToBuild) -> (~[Path], ~[(~str, ~str)]) { - - let id = pkg_src.id.clone(); - - let mut installed_files = ~[]; - let mut inputs = ~[]; - let mut build_inputs = ~[]; - - debug!("Installing package source: {}", pkg_src.to_str()); - - // workcache only knows about *crates*. Building a package - // just means inferring all the crates in it, then building each one. - self.build(&mut pkg_src, what); - - debug!("Done building package source {}", pkg_src.to_str()); - - let to_do = ~[pkg_src.libs.clone(), pkg_src.mains.clone(), - pkg_src.tests.clone(), pkg_src.benchs.clone()]; - debug!("In declare inputs for {}", id.to_str()); - for cs in to_do.iter() { - for c in cs.iter() { - let path = pkg_src.start_dir.join(&c.file); - debug!("Recording input: {}", path.display()); - // FIXME (#9639): This needs to handle non-utf8 paths - inputs.push((~"file", path.as_str().unwrap().to_owned())); - build_inputs.push(path); - } - } - - let result = self.install_no_build(pkg_src.build_workspace(), - build_inputs, - &pkg_src.destination_workspace, - &id).map(|s| Path::new(s.as_slice())); - installed_files = installed_files + result; - note(format!("Installed package {} to {}", - id.to_str(), - pkg_src.destination_workspace.display())); - (installed_files, inputs) - } - - // again, working around lack of Encodable for Path - fn install_no_build(&self, - build_workspace: &Path, - build_inputs: &[Path], - target_workspace: &Path, - id: &CrateId) -> ~[~str] { - - debug!("install_no_build: assuming {} comes from {} with target {}", - id.to_str(), build_workspace.display(), target_workspace.display()); - - // Now copy stuff into the install dirs - let maybe_executable = built_executable_in_workspace(id, build_workspace); - let maybe_library = built_library_in_workspace(id, build_workspace); - let target_exec = target_executable_in_workspace(id, target_workspace); - let target_lib = maybe_library.as_ref() - .map(|_| target_library_in_workspace(id, target_workspace)); - - debug!("target_exec = {} target_lib = {:?} \ - maybe_executable = {:?} maybe_library = {:?}", - target_exec.display(), target_lib, - maybe_executable, maybe_library); - - let install_tag = format!("install({}-{})", id.path, id.version_or_default()); - self.workcache_context.with_prep(install_tag, |prep| { - for ee in maybe_executable.iter() { - // FIXME (#9639): This needs to handle non-utf8 paths - prep.declare_input("binary", - ee.as_str().unwrap(), - workcache_support::digest_only_date(ee)); - } - for ll in maybe_library.iter() { - // FIXME (#9639): This needs to handle non-utf8 paths - prep.declare_input("binary", - ll.as_str().unwrap(), - workcache_support::digest_only_date(ll)); - } - let subex = maybe_executable.clone(); - let sublib = maybe_library.clone(); - let sub_target_ex = target_exec.clone(); - let sub_target_lib = target_lib.clone(); - let sub_build_inputs = build_inputs.to_owned(); - prep.exec(proc(exe_thing) { - let mut outputs = ~[]; - // Declare all the *inputs* to the declared input too, as inputs - for executable in subex.iter() { - exe_thing.discover_input("binary", - executable.as_str().unwrap().to_owned(), - workcache_support::digest_only_date(executable)); - } - for library in sublib.iter() { - exe_thing.discover_input("binary", - library.as_str().unwrap().to_owned(), - workcache_support::digest_only_date(library)); - } - - for transitive_dependency in sub_build_inputs.iter() { - exe_thing.discover_input( - "file", - transitive_dependency.as_str().unwrap().to_owned(), - workcache_support::digest_file_with_date(transitive_dependency)); - } - - - for exec in subex.iter() { - debug!("Copying: {} -> {}", exec.display(), sub_target_ex.display()); - fs::mkdir_recursive(&sub_target_ex.dir_path(), io::UserRWX); - fs::copy(exec, &sub_target_ex); - // FIXME (#9639): This needs to handle non-utf8 paths - exe_thing.discover_output("binary", - sub_target_ex.as_str().unwrap(), - workcache_support::digest_only_date(&sub_target_ex)); - outputs.push(sub_target_ex.as_str().unwrap().to_owned()); - } - for lib in sublib.iter() { - let mut target_lib = sub_target_lib - .clone().expect(format!("I built {} but apparently \ - didn't install it!", lib.display())); - target_lib.set_filename(lib.filename().expect("weird target lib")); - fs::mkdir_recursive(&target_lib.dir_path(), io::UserRWX); - fs::copy(lib, &target_lib); - debug!("3. discovering output {}", target_lib.display()); - exe_thing.discover_output("binary", - target_lib.as_str().unwrap(), - workcache_support::digest_only_date(&target_lib)); - outputs.push(target_lib.as_str().unwrap().to_owned()); - } - outputs - }) - }) - } - - fn prefer(&self, _id: &str, _vers: Option<~str>) { - fail!("prefer not yet implemented"); - } - - fn test(&self, crateid: &CrateId, workspace: &Path) { - match built_test_in_workspace(crateid, workspace) { - Some(test_exec) => { - debug!("test: test_exec = {}", test_exec.display()); - // FIXME (#9639): This needs to handle non-utf8 paths - let opt_status = run::process_status(test_exec.as_str().unwrap(), [~"--test"]); - match opt_status { - Some(status) => { - if !status.success() { - fail!("Some tests failed"); - } - }, - None => fail!("Could not exec `{}`", test_exec.display()) - } - } - None => { - error(format!("Internal error: test executable for package ID {} in workspace {} \ - wasn't built! Please report this as a bug.", - crateid.to_str(), workspace.display())); - } - } - } - - fn init(&self) { - fs::mkdir_recursive(&Path::new("src"), io::UserRWX); - fs::mkdir_recursive(&Path::new("bin"), io::UserRWX); - fs::mkdir_recursive(&Path::new("lib"), io::UserRWX); - fs::mkdir_recursive(&Path::new("build"), io::UserRWX); - } - - fn uninstall(&self, _id: &str, _vers: Option<~str>) { - fail!("uninstall not yet implemented"); - } - - fn unprefer(&self, _id: &str, _vers: Option<~str>) { - fail!("unprefer not yet implemented"); - } -} - -pub fn main() { - println!("WARNING: The Rust package manager is experimental and may be unstable"); - os::set_exit_status(main_args(os::args())); -} - -pub fn main_args(args: &[~str]) -> int { - - let (command, args, context, supplied_sysroot) = match parse_args(args) { - Ok(ParseResult { - command: cmd, - args: args, - context: ctx, - sysroot: sroot}) => (cmd, args, ctx, sroot), - Err(error_code) => { - debug!("Parsing failed. Returning error code {}", error_code); - return error_code - } - }; - debug!("Finished parsing commandline args {:?}", args); - debug!(" Using command: {:?}", command); - debug!(" Using args {:?}", args); - debug!(" Using cflags: {:?}", context.rustc_flags); - debug!(" Using rust_path_hack {:b}", context.use_rust_path_hack); - debug!(" Using cfgs: {:?}", context.cfgs); - debug!(" Using supplied_sysroot: {:?}", supplied_sysroot); - - let sysroot = match supplied_sysroot { - Some(s) => Path::new(s), - _ => filesearch::get_or_default_sysroot() - }; - - debug!("Using sysroot: {}", sysroot.display()); - let ws = default_workspace(); - debug!("Will store workcache in {}", ws.display()); - - // Wrap the rest in task::try in case of a condition failure in a task - let result = task::try(proc() { - BuildContext { - context: context, - sysroot: sysroot.clone(), // Currently, only tests override this - workcache_context: api::default_context(sysroot.clone(), - default_workspace()).workcache_context - }.run(command, args.clone()) - }); - // FIXME #9262: This is using the same error code for all errors, - // and at least one test case succeeds if rustpkg returns COPY_FAILED_CODE, - // when actually, it might set the exit code for that even if a different - // unhandled condition got raised. - if result.is_err() { return COPY_FAILED_CODE; } - return 0; -} diff --git a/src/librustpkg/messages.rs b/src/librustpkg/messages.rs deleted file mode 100644 index dbd0ee80f28..00000000000 --- a/src/librustpkg/messages.rs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use extra::term; -use std::io; - -pub fn note(msg: &str) { - pretty_message(msg, "note: ", term::color::GREEN); -} - -pub fn warn(msg: &str) { - pretty_message(msg, "warning: ", term::color::YELLOW); -} - -pub fn error(msg: &str) { - pretty_message(msg, "error: ", term::color::RED); -} - -fn pretty_message<'a>(msg: &'a str, - prefix: &'a str, - color: term::color::Color) { - let mut term = term::Terminal::new(io::stdout()); - let mut stdout = io::stdout(); - match term { - Ok(ref mut t) => { - t.fg(color); - t.write(prefix.as_bytes()); - t.reset(); - }, - _ => { - stdout.write(prefix.as_bytes()); - } - } - stdout.write(msg.as_bytes()); - stdout.write(['\n' as u8]); -} diff --git a/src/librustpkg/package_source.rs b/src/librustpkg/package_source.rs deleted file mode 100644 index 6b4f1c1ae1a..00000000000 --- a/src/librustpkg/package_source.rs +++ /dev/null @@ -1,554 +0,0 @@ -// Copyright 2012-2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -extern mod extra; - -use target::*; -use std::io; -use std::io::fs; -use std::os; -use context::*; -use crate::Crate; -use messages::*; -use source_control::{safe_git_clone, git_clone_url, DirToUse, CheckedOutSources}; -use source_control::make_read_only; -use path_util::{find_dir_using_rust_path_hack, make_dir_rwx_recursive, default_workspace}; -use path_util::{target_build_dir, versionize, dir_has_crate_file}; -use util::{compile_crate, DepMap}; -use workcache_support; -use workcache_support::{digest_only_date, digest_file_with_date, crate_tag}; -use extra::workcache; -use extra::treemap::TreeMap; -use syntax::crateid::CrateId; -use rustc::driver::session; - -// An enumeration of the unpacked source of a package workspace. -// This contains a list of files found in the source workspace. -#[deriving(Clone)] -pub struct PkgSrc { - /// Root of where the package source code lives - source_workspace: Path, - /// If build_in_destination is true, temporary results should - /// go in the build/ subdirectory of the destination workspace. - /// (Otherwise, they go in the build/ subdirectory of the - /// source workspace.) This happens if the "RUST_PATH hack" is - /// in effect, or if sources were fetched from a remote - /// repository. - build_in_destination: bool, - /// Where to install the results. May or may not be the same - /// as source_workspace - destination_workspace: Path, - // Directory to start looking in for packages -- normally - // this is workspace/src/id but it may be just workspace - start_dir: Path, - id: CrateId, - libs: ~[Crate], - mains: ~[Crate], - tests: ~[Crate], - benchs: ~[Crate], -} - -pub enum BuildSort { InPlace, Discovered } - -impl ToStr for PkgSrc { - fn to_str(&self) -> ~str { - format!("Package ID {} in start dir {} [workspaces = {} -> {}]", - self.id.to_str(), - self.start_dir.display(), - self.source_workspace.display(), - self.destination_workspace.display()) - } -} -condition! { - build_err: (~str) -> ~str; -} - -fn prefixes(p: &Path) -> Prefixes { - Prefixes { - components: p.str_components().map(|x|x.unwrap().to_owned()).to_owned_vec(), - remaining: ~[] - } -} - -struct Prefixes { - components: ~[~str], - remaining: ~[~str] -} - -impl Iterator<(Path, Path)> for Prefixes { - #[inline] - fn next(&mut self) -> Option<(Path, Path)> { - if self.components.len() <= 1 { - None - } - else { - let last = self.components.pop().unwrap(); - self.remaining.unshift(last); - // converting to str and then back is a little unfortunate - Some((Path::new(self.components.connect("/")), - Path::new(self.remaining.connect("/")))) - } - } -} - -impl PkgSrc { - pub fn new(mut source_workspace: Path, - destination_workspace: Path, - use_rust_path_hack: bool, - id: CrateId) -> PkgSrc { - use conditions::nonexistent_package::cond; - - debug!("Checking package source for package ID {}, \ - workspace = {} -> {}, use_rust_path_hack = {:?}", - id.to_str(), - source_workspace.display(), - destination_workspace.display(), - use_rust_path_hack); - - let mut destination_workspace = destination_workspace.clone(); - - let mut to_try = ~[]; - let mut output_names = ~[]; - let build_dir = target_build_dir(&source_workspace); - - if use_rust_path_hack { - to_try.push(source_workspace.clone()); - } else { - // We search for sources under both src/ and build/ , because build/ is where - // automatically-checked-out sources go. - let path = Path::new(id.path.as_slice()); - let mut result = source_workspace.join("src"); - result.push(&path.dir_path()); - result.push(id.short_name_with_version()); - to_try.push(result); - let mut result = source_workspace.join("src"); - result.push(&path); - to_try.push(result); - - let mut result = build_dir.join("src"); - result.push(&path.dir_path()); - result.push(id.short_name_with_version()); - to_try.push(result.clone()); - output_names.push(result); - let mut other_result = build_dir.join("src"); - other_result.push(&path); - to_try.push(other_result.clone()); - output_names.push(other_result); - - } - - debug!("Checking dirs: {:?}", to_try.map(|p| p.display().to_str()).connect(":")); - - let path = to_try.iter().find(|&d| d.is_dir() - && dir_has_crate_file(d)); - - // See the comments on the definition of PkgSrc - let mut build_in_destination = use_rust_path_hack; - debug!("1. build_in_destination = {:?}", build_in_destination); - - let dir: Path = match path { - Some(d) => (*d).clone(), - None => { - // See if any of the prefixes of this package ID form a valid package ID - // That is, is this a package ID that points into the middle of a workspace? - for (prefix, suffix) in prefixes(&Path::new(id.path.as_slice())) { - let crate_id: Option = from_str(prefix.as_str().unwrap()); - let crate_id = crate_id.expect("valid crate id"); - let path = build_dir.join(crate_id.path.as_slice()); - debug!("in loop: checking if {} is a directory", path.display()); - if path.is_dir() { - let ps = PkgSrc::new(source_workspace, - destination_workspace, - use_rust_path_hack, - crate_id); - match ps { - PkgSrc { - source_workspace: source, - destination_workspace: destination, - start_dir: start, - id: id, .. } => { - let result = PkgSrc { - source_workspace: source.clone(), - build_in_destination: build_in_destination, - destination_workspace: destination, - start_dir: start.join(&suffix), - id: id, - libs: ~[], - mains: ~[], - tests: ~[], - benchs: ~[] - }; - debug!("pkgsrc: Returning {}", result.to_str()); - return result; - } - } - - } - } - - // Ok, no prefixes work, so try fetching from git - let mut ok_d = None; - for w in output_names.iter() { - debug!("Calling fetch_git on {}", w.display()); - let target_dir_opt = PkgSrc::fetch_git(w, &id); - for p in target_dir_opt.iter() { - ok_d = Some(p.clone()); - build_in_destination = true; - debug!("2. build_in_destination = {:?}", build_in_destination); - break; - } - match ok_d { - Some(ref d) => { - let path = Path::new(id.path.as_slice()); - if d.is_ancestor_of(&path) - || d.is_ancestor_of(&versionize(id.path, &id.version)) { - // Strip off the package ID - source_workspace = d.clone(); - for _ in path.components() { - source_workspace.pop(); - } - // Strip off the src/ part - source_workspace.pop(); - // Strip off the build/ part to get the workspace - destination_workspace = source_workspace.clone(); - destination_workspace.pop(); - destination_workspace.pop(); - } - break; - } - None => () - } - } - match ok_d { - Some(d) => d, - None => { - // See if the sources are in $CWD - let cwd = os::getcwd(); - if dir_has_crate_file(&cwd) { - return PkgSrc { - // In this case, source_workspace isn't really a workspace. - // This data structure needs yet more refactoring. - source_workspace: cwd.clone(), - destination_workspace: default_workspace(), - build_in_destination: true, - start_dir: cwd, - id: id, - libs: ~[], - mains: ~[], - benchs: ~[], - tests: ~[] - } - } else if use_rust_path_hack { - match find_dir_using_rust_path_hack(&id) { - Some(d) => d, - None => { - cond.raise((id.clone(), - ~"supplied path for package dir does not \ - exist, and couldn't interpret it as a URL fragment")) - } - } - } else { - cond.raise((id.clone(), - ~"supplied path for package dir does not \ - exist, and couldn't interpret it as a URL fragment")) - } - } - } - } - }; - debug!("3. build_in_destination = {:?}", build_in_destination); - debug!("source: {} dest: {}", source_workspace.display(), destination_workspace.display()); - - debug!("For package id {}, returning {}", id.to_str(), dir.display()); - - if !dir.is_dir() { - cond.raise((id.clone(), ~"supplied path for package dir is a \ - non-directory")); - } - - PkgSrc { - source_workspace: source_workspace.clone(), - build_in_destination: build_in_destination, - destination_workspace: destination_workspace, - start_dir: dir, - id: id, - libs: ~[], - mains: ~[], - tests: ~[], - benchs: ~[] - } - } - - /// Try interpreting self's package id as a git repository, and try - /// fetching it and caching it in a local directory. Return the cached directory - /// if this was successful, None otherwise. Similarly, if the package id - /// refers to a git repo on the local version, also check it out. - /// (right now we only support git) - pub fn fetch_git(local: &Path, crateid: &CrateId) -> Option { - use conditions::git_checkout_failed::cond; - - let cwd = os::getcwd(); - let path = Path::new(crateid.path.as_slice()); - debug!("Checking whether {} (path = {}) exists locally. Cwd = {}, does it? {:?}", - crateid.to_str(), crateid.path, - cwd.display(), - path.exists()); - - match safe_git_clone(&path, &crateid.version, local) { - CheckedOutSources => { - make_read_only(local); - Some(local.clone()) - } - DirToUse(clone_target) => { - if path.components().nth(1).is_none() { - // If a non-URL, don't bother trying to fetch - return None; - } - - // FIXME (#9639): This needs to handle non-utf8 paths - let url = format!("https://{}", path.as_str().unwrap()); - debug!("Fetching package: git clone {} {} [version={}]", - url, clone_target.display(), crateid.version_or_default()); - - let mut failed = false; - - cond.trap(|_| { - failed = true; - }).inside(|| git_clone_url(url, &clone_target, &crateid.version)); - - if failed { - return None; - } - - // Move clone_target to local. - // First, create all ancestor directories. - let moved = make_dir_rwx_recursive(&local.dir_path()) - && io::result(|| fs::rename(&clone_target, local)).is_ok(); - if moved { Some(local.clone()) } - else { None } - } - } - } - - // If a file named "pkg.rs" in the start directory exists, - // return the path for it. Otherwise, None - pub fn package_script_option(&self) -> Option { - let maybe_path = self.start_dir.join("pkg.rs"); - debug!("package_script_option: checking whether {} exists", maybe_path.display()); - if maybe_path.exists() { - Some(maybe_path) - } else { - None - } - } - - pub fn push_crate(cs: &mut ~[Crate], prefix: uint, p: &Path) { - let mut it = p.components().peekable(); - if prefix > 0 { - it.nth(prefix-1); // skip elements - } - assert!(it.peek().is_some()); - let mut sub = Path::new("."); - for c in it { - sub.push(c); - } - debug!("Will compile crate {}", sub.display()); - cs.push(Crate::new(&sub)); - } - - /// Infers crates to build. Called only in the case where there - /// is no custom build logic - pub fn find_crates(&mut self) { - self.find_crates_with_filter(|_| true); - } - - pub fn find_crates_with_filter(&mut self, filter: |&str| -> bool) { - use conditions::missing_pkg_files::cond; - - let prefix = self.start_dir.components().len(); - debug!("Matching against {}", self.id.name); - for pth in fs::walk_dir(&self.start_dir) { - let maybe_known_crate_set = match pth.filename_str() { - Some(filename) if filter(filename) => match filename { - "lib.rs" => Some(&mut self.libs), - "main.rs" => Some(&mut self.mains), - "test.rs" => Some(&mut self.tests), - "bench.rs" => Some(&mut self.benchs), - _ => None - }, - _ => None - }; - - match maybe_known_crate_set { - Some(crate_set) => PkgSrc::push_crate(crate_set, prefix, &pth), - None => () - } - } - - let crate_sets = [&self.libs, &self.mains, &self.tests, &self.benchs]; - if crate_sets.iter().all(|crate_set| crate_set.is_empty()) { - - note("Couldn't infer any crates to build.\n\ - Try naming a crate `main.rs`, `lib.rs`, \ - `test.rs`, or `bench.rs`."); - cond.raise(self.id.clone()); - } - - debug!("In {}, found {} libs, {} mains, {} tests, {} benchs", - self.start_dir.display(), - self.libs.len(), - self.mains.len(), - self.tests.len(), - self.benchs.len()) - } - - fn build_crates(&self, - ctx: &BuildContext, - deps: &mut DepMap, - crates: &[Crate], - cfgs: &[~str], - what: OutputType, - inputs_to_discover: &[(~str, Path)]) { - for crate in crates.iter() { - let path = self.start_dir.join(&crate.file); - debug!("build_crates: compiling {}", path.display()); - let cfgs = crate.cfgs + cfgs; - - ctx.workcache_context.with_prep(crate_tag(&path), |prep| { - debug!("Building crate {}, declaring it as an input", path.display()); - // FIXME (#9639): This needs to handle non-utf8 paths - prep.declare_input("file", path.as_str().unwrap(), - workcache_support::digest_file_with_date(&path)); - let subpath = path.clone(); - let subcfgs = cfgs.clone(); - let subcx = ctx.clone(); - let id = self.id.clone(); - let sub_dir = self.build_workspace().clone(); - let sub_flags = crate.flags.clone(); - let sub_deps = deps.clone(); - let inputs = inputs_to_discover.map(|&(ref k, ref p)| - (k.clone(), p.as_str().unwrap().to_owned())); - prep.exec(proc(exec) { - for &(ref kind, ref p) in inputs.iter() { - let pth = Path::new(p.clone()); - exec.discover_input(*kind, *p, if *kind == ~"file" { - digest_file_with_date(&pth) - } else if *kind == ~"binary" { - digest_only_date(&Path::new(p.clone())) - } else { - fail!("Bad kind in build_crates") - }); - } - debug!("Compiling crate {}; its output will be in {}", - subpath.display(), sub_dir.display()); - let opt: session::OptLevel = subcx.context.rustc_flags.optimization_level; - let result = compile_crate(&subcx, - exec, - &id, - &subpath, - &sub_dir, - &mut (sub_deps.clone()), - sub_flags, - subcfgs, - opt, - what); - // FIXME: result is an Option. The following code did not take that - // into account. I'm not sure if the workcache really likes seeing the - // output as "Some(\"path\")". But I don't know what to do about it. - // FIXME (#9639): This needs to handle non-utf8 paths - let result = result.as_ref().map(|p|p.as_str().unwrap()); - debug!("Result of compiling {} was {}", subpath.display(), result.to_str()); - result.to_str() - }) - }); - } - } - - /// Declare all the crate files in the package source as inputs - /// (to the package) - pub fn declare_inputs(&self, prep: &mut workcache::Prep) { - let to_do = ~[self.libs.clone(), self.mains.clone(), - self.tests.clone(), self.benchs.clone()]; - debug!("In declare inputs, self = {}", self.to_str()); - for cs in to_do.iter() { - for c in cs.iter() { - let path = self.start_dir.join(&c.file); - debug!("Declaring input: {}", path.display()); - // FIXME (#9639): This needs to handle non-utf8 paths - prep.declare_input("file", path.as_str().unwrap(), - workcache_support::digest_file_with_date(&path.clone())); - } - } - } - - pub fn build(&self, - build_context: &BuildContext, - // DepMap is a map from str (crate name) to (kind, name) -- - // it tracks discovered dependencies per-crate - cfgs: ~[~str], - inputs_to_discover: &[(~str, Path)]) -> DepMap { - let mut deps = TreeMap::new(); - let libs = self.libs.clone(); - let mains = self.mains.clone(); - let tests = self.tests.clone(); - let benchs = self.benchs.clone(); - debug!("Building libs in {}, destination = {}", - self.source_workspace.display(), - self.build_workspace().display()); - self.build_crates(build_context, - &mut deps, - libs, - cfgs, - Lib, - inputs_to_discover); - debug!("Building mains"); - self.build_crates(build_context, - &mut deps, - mains, - cfgs, - Main, - inputs_to_discover); - debug!("Building tests"); - self.build_crates(build_context, - &mut deps, - tests, - cfgs, - Test, - inputs_to_discover); - debug!("Building benches"); - self.build_crates(build_context, - &mut deps, - benchs, - cfgs, - Bench, - inputs_to_discover); - deps - } - - /// Return the workspace to put temporary files in. See the comment on `PkgSrc` - pub fn build_workspace<'a>(&'a self) -> &'a Path { - if self.build_in_destination { - &self.destination_workspace - } - else { - &self.source_workspace - } - } - - /// Debugging - pub fn dump_crates(&self) { - let crate_sets = [&self.libs, &self.mains, &self.tests, &self.benchs]; - for crate_set in crate_sets.iter() { - for c in crate_set.iter() { - debug!("Built crate: {}", c.file.display()) - } - } - } -} diff --git a/src/librustpkg/parse_args.rs b/src/librustpkg/parse_args.rs deleted file mode 100644 index 9a9a9c5fccb..00000000000 --- a/src/librustpkg/parse_args.rs +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright 2012-2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use context::{Context, RustcFlags, Trans, Link, Nothing, Pretty, Analysis, Assemble, - LLVMAssemble, LLVMCompileBitcode}; -use context::{Command, flags_forbidden_for_cmd}; -use rustc::version; -use exit_codes::{BAD_FLAG_CODE}; -use rustc::driver::{session}; - -use usage; - -use extra::{getopts}; -use std::{result}; -use std::hashmap::HashSet; - -/// Result of parsing command line arguments -pub struct ParseResult { - // Command - command: Command, - // Args - args: ~[~str], - // Parsed command line flags - context: Context, - // Path to system root - sysroot: Option<~str> -} - -/// Parses command line arguments of rustpkg. -/// Returns a triplet (command, remaining_args, context) -pub fn parse_args(args: &[~str]) -> Result { - let opts = ~[ getopts::optflag("h"), getopts::optflag("help"), - getopts::optflag("no-link"), - getopts::optflag("no-trans"), - // n.b. Ignores different --pretty options for now - getopts::optflag("pretty"), - getopts::optflag("parse-only"), - getopts::optflag("S"), getopts::optflag("assembly"), - getopts::optmulti("c"), getopts::optmulti("cfg"), - getopts::optflag("v"), getopts::optflag("version"), - getopts::optflag("r"), getopts::optflag("rust-path-hack"), - getopts::optopt("sysroot"), - getopts::optflag("emit-llvm"), - getopts::optopt("linker"), - getopts::optopt("link-args"), - getopts::optopt("opt-level"), - getopts::optflag("O"), - getopts::optflag("save-temps"), - getopts::optopt("target"), - getopts::optopt("target-cpu"), - getopts::optmulti("Z") ]; - let matches = &match getopts::getopts(args, opts) { - result::Ok(m) => m, - result::Err(f) => { - error!("{}", f.to_err_msg()); - return Err(1); - } - }; - let no_link = matches.opt_present("no-link"); - let no_trans = matches.opt_present("no-trans"); - let supplied_sysroot = matches.opt_str("sysroot"); - let generate_asm = matches.opt_present("S") || - matches.opt_present("assembly"); - let parse_only = matches.opt_present("parse-only"); - let pretty = matches.opt_present("pretty"); - let emit_llvm = matches.opt_present("emit-llvm"); - - if matches.opt_present("h") || - matches.opt_present("help") { - usage::general(); - return Err(0); - } - - if matches.opt_present("v") || - matches.opt_present("version") { - version(args[0]); - return Err(0); - } - - let use_rust_path_hack = matches.opt_present("r") || - matches.opt_present("rust-path-hack"); - - let linker = matches.opt_str("linker"); - let link_args = matches.opt_str("link-args"); - let cfgs = matches.opt_strs("cfg") + matches.opt_strs("c"); - let mut user_supplied_opt_level = true; - let opt_level = match matches.opt_str("opt-level") { - Some(~"0") => session::No, - Some(~"1") => session::Less, - Some(~"2") => session::Default, - Some(~"3") => session::Aggressive, - _ if matches.opt_present("O") => session::Default, - _ => { - user_supplied_opt_level = false; - session::No - } - }; - - let save_temps = matches.opt_present("save-temps"); - let target = matches.opt_str("target"); - let target_cpu = matches.opt_str("target-cpu"); - let experimental_features = { - let strs = matches.opt_strs("Z"); - if matches.opt_present("Z") { - Some(strs) - } - else { - None - } - }; - - let mut args = matches.free.clone(); - args.shift(); - - if args.len() < 1 { - usage::general(); - return Err(1); - } - - let rustc_flags = RustcFlags { - linker: linker, - link_args: link_args, - optimization_level: opt_level, - compile_upto: if no_trans { - Trans - } else if no_link { - Link - } else if pretty { - Pretty - } else if parse_only { - Analysis - } else if emit_llvm && generate_asm { - LLVMAssemble - } else if generate_asm { - Assemble - } else if emit_llvm { - LLVMCompileBitcode - } else { - Nothing - }, - save_temps: save_temps, - target: target, - target_cpu: target_cpu, - additional_library_paths: - HashSet::new(), // No way to set this from the rustpkg command line - experimental_features: experimental_features - }; - - let cmd_opt = args.iter().filter_map( |s| from_str(s.clone())).next(); - let command = match cmd_opt { - None => { - debug!("No legal command. Returning 0"); - usage::general(); - return Err(0); - } - Some(cmd) => { - let bad_option = flags_forbidden_for_cmd(&rustc_flags, - cfgs, - cmd, - user_supplied_opt_level); - if bad_option { - usage::usage_for_command(cmd); - debug!("Bad option, returning BAD_FLAG_CODE"); - return Err(BAD_FLAG_CODE); - } else { - cmd - } - } - }; - - // Pop off all flags, plus the command - let mut remaining_args: ~[~str] = args.iter().skip_while(|&s| { - let maybe_command: Option = from_str(*s); - maybe_command.is_none() - }).map(|s| s.clone()).collect(); - remaining_args.shift(); - - let context = Context{ - rustc_flags: rustc_flags, - cfgs: cfgs, - use_rust_path_hack: use_rust_path_hack, - }; - Ok(ParseResult { - command: command, - args: remaining_args, - context: context, - sysroot: supplied_sysroot - }) -} diff --git a/src/librustpkg/path_util.rs b/src/librustpkg/path_util.rs deleted file mode 100644 index 908e5e5c381..00000000000 --- a/src/librustpkg/path_util.rs +++ /dev/null @@ -1,426 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// rustpkg utilities having to do with paths and directories - -#[allow(dead_code)]; - -pub use target::{OutputType, Main, Lib, Test, Bench, Target, Build, Install}; -pub use version::{Version, split_version_general}; -pub use rustc::metadata::filesearch::rust_path; - -use std::libc; -use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR}; -use std::os; -use std::io; -use std::io::fs; -use syntax::crateid::CrateId; -use rustc::metadata::filesearch::{libdir, relative_target_lib_path}; -use rustc::driver::driver::host_triple; -use messages::*; - -pub fn default_workspace() -> Path { - let p = rust_path(); - if p.is_empty() { - fail!("Empty RUST_PATH"); - } - let result = p[0]; - if !result.is_dir() { - fs::mkdir_recursive(&result, io::UserRWX); - } - result -} - -pub fn in_rust_path(p: &Path) -> bool { - rust_path().contains(p) -} - -pub static U_RWX: i32 = (S_IRUSR | S_IWUSR | S_IXUSR) as i32; - -/// Creates a directory that is readable, writeable, -/// and executable by the user. Returns true iff creation -/// succeeded. -pub fn make_dir_rwx(p: &Path) -> bool { - io::result(|| fs::mkdir(p, io::UserRWX)).is_ok() -} - -pub fn make_dir_rwx_recursive(p: &Path) -> bool { - io::result(|| fs::mkdir_recursive(p, io::UserRWX)).is_ok() -} - -// n.b. The next three functions ignore the package version right -// now. Should fix that. - -/// True if there's a directory in with -/// crateid's short name -pub fn workspace_contains_crate_id(crateid: &CrateId, workspace: &Path) -> bool { - workspace_contains_crate_id_(crateid, workspace, |p| p.join("src")).is_some() -} - -pub fn workspace_contains_crate_id_(crateid: &CrateId, workspace: &Path, -// Returns the directory it was actually found in - workspace_to_src_dir: |&Path| -> Path) -> Option { - if !workspace.is_dir() { - return None; - } - - let src_dir = workspace_to_src_dir(workspace); - if !src_dir.is_dir() { return None } - - let mut found = None; - for p in fs::walk_dir(&src_dir) { - if p.is_dir() { - if p == src_dir.join(crateid.path.as_slice()) || { - let pf = p.filename_str(); - pf.iter().any(|&g| { - match split_version_general(g, '-') { - None => false, - Some((ref might_match, ref vers)) => { - *might_match == crateid.name - && (crateid.version == *vers || crateid.version == None) - } - } - }) - } { - found = Some(p.clone()); - } - - } - } - - if found.is_some() { - debug!("Found {} in {}", crateid.to_str(), workspace.display()); - } else { - debug!("Didn't find {} in {}", crateid.to_str(), workspace.display()); - } - found -} - -/// Return the target-specific build subdirectory, pushed onto `base`; -/// doesn't check that it exists or create it -pub fn target_build_dir(workspace: &Path) -> Path { - let mut dir = workspace.join("build"); - dir.push(host_triple()); - dir -} - -/// Return the target-specific lib subdirectory, pushed onto `base`; -/// doesn't check that it exists or create it -fn target_lib_dir(workspace: &Path) -> Path { - let mut dir = workspace.join(libdir()); - dir.push(host_triple()); - dir -} - -/// Return the bin subdirectory, pushed onto `base`; -/// doesn't check that it exists or create it -/// note: this isn't target-specific -fn target_bin_dir(workspace: &Path) -> Path { - workspace.join("bin") -} - -/// Figure out what the executable name for in 's build -/// directory is, and if the file exists, return it. -pub fn built_executable_in_workspace(crateid: &CrateId, workspace: &Path) -> Option { - let mut result = target_build_dir(workspace); - result = mk_output_path(Main, Build, crateid, result); - debug!("built_executable_in_workspace: checking whether {} exists", - result.display()); - if result.exists() { - Some(result) - } - else { - debug!("built_executable_in_workspace: {} does not exist", result.display()); - None - } -} - -/// Figure out what the test name for in 's build -/// directory is, and if the file exists, return it. -pub fn built_test_in_workspace(crateid: &CrateId, workspace: &Path) -> Option { - output_in_workspace(crateid, workspace, Test) -} - -/// Figure out what the test name for in 's build -/// directory is, and if the file exists, return it. -pub fn built_bench_in_workspace(crateid: &CrateId, workspace: &Path) -> Option { - output_in_workspace(crateid, workspace, Bench) -} - -fn output_in_workspace(crateid: &CrateId, workspace: &Path, what: OutputType) -> Option { - let mut result = target_build_dir(workspace); - // should use a target-specific subdirectory - result = mk_output_path(what, Build, crateid, result); - debug!("output_in_workspace: checking whether {} exists", - result.display()); - if result.exists() { - Some(result) - } - else { - error!("output_in_workspace: {} does not exist", result.display()); - None - } -} - -/// Figure out what the library name for in 's build -/// directory is, and if the file exists, return it. -pub fn built_library_in_workspace(crateid: &CrateId, workspace: &Path) -> Option { - library_in_workspace(crateid, Build, workspace) -} - -/// Does the actual searching stuff -pub fn installed_library_in_workspace(crate_id: &CrateId, workspace: &Path) -> Option { - // This could break once we're handling multiple versions better -- I should add a test for it - let path = Path::new(crate_id.path.as_slice()); - match path.filename_str() { - None => None, - Some(_short_name) => library_in_workspace(crate_id, Install, workspace) - } -} - -/// `workspace` is used to figure out the directory to search. -/// `name` is taken as the link name of the library. -pub fn library_in_workspace(crate_id: &CrateId, where: Target, workspace: &Path) -> Option { - debug!("library_in_workspace: checking whether a library named {} exists", - crate_id.name); - - let dir_to_search = match where { - Build => target_build_dir(workspace).join(crate_id.path.as_slice()), - Install => target_lib_dir(workspace) - }; - - library_in(crate_id, &dir_to_search) -} - -pub fn system_library(sysroot: &Path, crate_id: &CrateId) -> Option { - library_in(crate_id, &sysroot.join(relative_target_lib_path(host_triple()))) -} - -fn library_in(crate_id: &CrateId, dir_to_search: &Path) -> Option { - let version_str = match crate_id.version { - Some(ref v) => format!("-{}", *v), - None => ~"", - }; - let patterns = ~[ - (format!("lib{}", crate_id.name), format!("{}.rlib", version_str)), - (format!("{}{}", os::consts::DLL_PREFIX, crate_id.name), - format!("{}{}", version_str, os::consts::DLL_SUFFIX)), - ]; - - for (prefix, suffix) in patterns.move_iter() { - let files = match io::result(|| fs::readdir(dir_to_search)) { - Ok(dir) => dir, Err(..) => continue, - }; - for file in files.move_iter() { - let filename = match file.filename_str() { - Some(s) => s, None => continue, - }; - if filename.starts_with(prefix) && filename.ends_with(suffix) { - return Some(file.clone()) - } - } - } - debug!("warning: library_in_workspace didn't find a library in {} for {}", - dir_to_search.display(), crate_id.to_str()); - return None; -} - -/// Returns the executable that would be installed for -/// in -/// As a side effect, creates the bin-dir if it doesn't exist -pub fn target_executable_in_workspace(crateid: &CrateId, workspace: &Path) -> Path { - target_file_in_workspace(crateid, workspace, Main, Install) -} - - -/// Returns the executable that would be installed for -/// in -/// As a side effect, creates the lib-dir if it doesn't exist -pub fn target_library_in_workspace(crateid: &CrateId, workspace: &Path) -> Path { - use conditions::bad_path::cond; - if !workspace.is_dir() { - cond.raise(((*workspace).clone(), - format!("Workspace supplied to target_library_in_workspace \ - is not a directory! {}", workspace.display()))); - } - target_file_in_workspace(crateid, workspace, Lib, Install) -} - -/// Returns the test executable that would be installed for -/// in -/// note that we *don't* install test executables, so this is just for unit testing -pub fn target_test_in_workspace(crateid: &CrateId, workspace: &Path) -> Path { - target_file_in_workspace(crateid, workspace, Test, Install) -} - -/// Returns the bench executable that would be installed for -/// in -/// note that we *don't* install bench executables, so this is just for unit testing -pub fn target_bench_in_workspace(crateid: &CrateId, workspace: &Path) -> Path { - target_file_in_workspace(crateid, workspace, Bench, Install) -} - - -/// Returns the path that crateid `crateid` would have if placed `where` -/// in `workspace` -fn target_file_in_workspace(crateid: &CrateId, workspace: &Path, - what: OutputType, where: Target) -> Path { - use conditions::bad_path::cond; - - let subdir = match what { - Lib => "lib", Main | Test | Bench => "bin" - }; - // Artifacts in the build directory live in a package-ID-specific subdirectory, - // but installed ones don't. - let result = match (where, what) { - (Build, _) => target_build_dir(workspace).join(crateid.path.as_slice()), - (Install, Lib) => target_lib_dir(workspace), - (Install, _) => target_bin_dir(workspace) - }; - if io::result(|| fs::mkdir_recursive(&result, io::UserRWX)).is_err() { - cond.raise((result.clone(), format!("target_file_in_workspace couldn't \ - create the {} dir (crateid={}, workspace={}, what={:?}, where={:?}", - subdir, crateid.to_str(), workspace.display(), what, where))); - } - mk_output_path(what, where, crateid, result) -} - -/// Return the directory for 's build artifacts in . -/// Creates it if it doesn't exist. -pub fn build_pkg_id_in_workspace(crateid: &CrateId, workspace: &Path) -> Path { - let mut result = target_build_dir(workspace); - result.push(crateid.path.as_slice()); - debug!("Creating build dir {} for package id {}", result.display(), - crateid.to_str()); - fs::mkdir_recursive(&result, io::UserRWX); - return result; -} - -/// Return the output file for a given directory name, -/// given whether we're building a library and whether we're building tests -pub fn mk_output_path(what: OutputType, where: Target, - crate_id: &CrateId, workspace: Path) -> Path { - let short_name_with_version = crate_id.short_name_with_version(); - // Not local_path.dir_path()! For package foo/bar/blat/, we want - // the executable blat-0.5 to live under blat/ - let dir = match where { - // If we're installing, it just goes under ... - Install => workspace, - // and if we're just building, it goes in a package-specific subdir - Build => workspace.join(crate_id.path.as_slice()) - }; - debug!("[{:?}:{:?}] mk_output_path: name = {}, path = {}", what, where, - if what == Lib { short_name_with_version.clone() } else { crate_id.name.clone() }, - dir.display()); - let mut output_path = match what { - // this code is duplicated from elsewhere; fix this - Lib => dir.join(os::dll_filename(short_name_with_version)), - // executable names *aren't* versioned - _ => dir.join(format!("{}{}{}", crate_id.name, - match what { - Test => "test", - Bench => "bench", - _ => "" - }, - os::consts::EXE_SUFFIX)) - }; - if !output_path.is_absolute() { - output_path = os::getcwd().join(&output_path); - } - debug!("mk_output_path: returning {}", output_path.display()); - output_path -} - -/// Removes files for the package `crateid`, assuming it's installed in workspace `workspace` -pub fn uninstall_package_from(workspace: &Path, crateid: &CrateId) { - let mut did_something = false; - let installed_bin = target_executable_in_workspace(crateid, workspace); - if installed_bin.exists() { - fs::unlink(&installed_bin); - did_something = true; - } - let installed_lib = target_library_in_workspace(crateid, workspace); - if installed_lib.exists() { - fs::unlink(&installed_lib); - did_something = true; - } - if !did_something { - warn(format!("Warning: there don't seem to be any files for {} installed in {}", - crateid.to_str(), workspace.display())); - } - -} - -pub fn dir_has_crate_file(dir: &Path) -> bool { - dir_has_file(dir, "lib.rs") || dir_has_file(dir, "main.rs") - || dir_has_file(dir, "test.rs") || dir_has_file(dir, "bench.rs") -} - -fn dir_has_file(dir: &Path, file: &str) -> bool { - assert!(dir.is_absolute()); - dir.join(file).exists() -} - -pub fn find_dir_using_rust_path_hack(p: &CrateId) -> Option { - let rp = rust_path(); - let path = Path::new(p.path.as_slice()); - for dir in rp.iter() { - // Require that the parent directory match the package ID - // Note that this only matches if the package ID being searched for - // has a name that's a single component - if dir.ends_with_path(&path) || dir.ends_with_path(&versionize(p.path, &p.version)) { - debug!("In find_dir_using_rust_path_hack: checking dir {}", dir.display()); - if dir_has_crate_file(dir) { - debug!("Did find id {} in dir {}", p.to_str(), dir.display()); - return Some(dir.clone()); - } - } - debug!("Didn't find id {} in dir {}", p.to_str(), dir.display()) - } - None -} - -/// True if the user set RUST_PATH to something non-empty -- -/// as opposed to the default paths that rustpkg adds automatically -pub fn user_set_rust_path() -> bool { - match os::getenv("RUST_PATH") { - None | Some(~"") => false, - Some(_) => true - } -} - -/// Append the version string onto the end of the path's filename -pub fn versionize(p: &str, v: &Version) -> Path { - let p = Path::new(p); - let q = p.filename().expect("path is a directory"); - let mut q = q.to_owned(); - q.push('-' as u8); - let vs = match v { &Some(ref s) => s.to_owned(), &None => ~"0.0" }; - q.push_all(vs.as_bytes()); - p.with_filename(q) -} - -#[cfg(target_os = "win32")] -pub fn chmod_read_only(p: &Path) -> bool { - unsafe { - p.with_c_str(|src_buf| libc::chmod(src_buf, S_IRUSR as libc::c_int) == 0 as libc::c_int) - } -} - -#[cfg(not(target_os = "win32"))] -pub fn chmod_read_only(p: &Path) -> bool { - unsafe { - p.with_c_str(|src_buf| libc::chmod(src_buf, S_IRUSR as libc::mode_t) == 0 as libc::c_int) - } -} - -pub fn platform_library_name(s: &str) -> ~str { - format!("{}{}{}", os::consts::DLL_PREFIX, s, os::consts::DLL_SUFFIX) -} diff --git a/src/librustpkg/sha1.rs b/src/librustpkg/sha1.rs deleted file mode 100644 index 255172e0988..00000000000 --- a/src/librustpkg/sha1.rs +++ /dev/null @@ -1,633 +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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/*! - * An implementation of the SHA-1 cryptographic hash. - * - * First create a `sha1` object using the `sha1` constructor, then - * feed it input using the `input` or `input_str` methods, which may be - * called any number of times. - * - * After the entire input has been fed to the hash read the result using - * the `result` or `result_str` methods. - * - * The `sha1` object may be reused to create multiple hashes by calling - * the `reset` method. - * - * This implementation has not been reviewed for cryptographic uses. - * As such, all cryptographic uses of this implementation are strongly - * discouraged. - */ - -use std::num::Zero; -use std::vec; -use std::vec::bytes::{MutableByteVector, copy_memory}; -use extra::hex::ToHex; - -/// Write a u32 into a vector, which must be 4 bytes long. The value is written in big-endian -/// format. -fn write_u32_be(dst: &mut[u8], input: u32) { - use std::cast::transmute; - use std::unstable::intrinsics::to_be32; - assert!(dst.len() == 4); - unsafe { - let x: *mut i32 = transmute(dst.unsafe_mut_ref(0)); - *x = to_be32(input as i32); - } -} - -/// Read a vector of bytes into a vector of u32s. The values are read in big-endian format. -fn read_u32v_be(dst: &mut[u32], input: &[u8]) { - use std::cast::transmute; - use std::unstable::intrinsics::to_be32; - assert!(dst.len() * 4 == input.len()); - unsafe { - let mut x: *mut i32 = transmute(dst.unsafe_mut_ref(0)); - let mut y: *i32 = transmute(input.unsafe_ref(0)); - for _ in range(0, dst.len()) { - *x = to_be32(*y); - x = x.offset(1); - y = y.offset(1); - } - } -} - -trait ToBits { - /// Convert the value in bytes to the number of bits, a tuple where the 1st item is the - /// high-order value and the 2nd item is the low order value. - fn to_bits(self) -> (Self, Self); -} - -impl ToBits for u64 { - fn to_bits(self) -> (u64, u64) { - return (self >> 61, self << 3); - } -} - -/// Adds the specified number of bytes to the bit count. fail!() if this would cause numeric -/// overflow. -fn add_bytes_to_bits(bits: T, bytes: T) -> T { - let (new_high_bits, new_low_bits) = bytes.to_bits(); - - if new_high_bits > Zero::zero() { - fail!("Numeric overflow occured.") - } - - match bits.checked_add(&new_low_bits) { - Some(x) => return x, - None => fail!("Numeric overflow occured.") - } -} - -/// A FixedBuffer, likes its name implies, is a fixed size buffer. When the buffer becomes full, it -/// must be processed. The input() method takes care of processing and then clearing the buffer -/// automatically. However, other methods do not and require the caller to process the buffer. Any -/// method that modifies the buffer directory or provides the caller with bytes that can be modifies -/// results in those bytes being marked as used by the buffer. -trait FixedBuffer { - /// Input a vector of bytes. If the buffer becomes full, process it with the provided - /// function and then clear the buffer. - fn input(&mut self, input: &[u8], func: |&[u8]|); - - /// Reset the buffer. - fn reset(&mut self); - - /// Zero the buffer up until the specified index. The buffer position currently must not be - /// greater than that index. - fn zero_until(&mut self, idx: uint); - - /// Get a slice of the buffer of the specified size. There must be at least that many bytes - /// remaining in the buffer. - fn next<'s>(&'s mut self, len: uint) -> &'s mut [u8]; - - /// Get the current buffer. The buffer must already be full. This clears the buffer as well. - fn full_buffer<'s>(&'s mut self) -> &'s [u8]; - - /// Get the current position of the buffer. - fn position(&self) -> uint; - - /// Get the number of bytes remaining in the buffer until it is full. - fn remaining(&self) -> uint; - - /// Get the size of the buffer - fn size(&self) -> uint; -} - -/// A fixed size buffer of 64 bytes useful for cryptographic operations. -struct FixedBuffer64 { - priv buffer: [u8, ..64], - priv buffer_idx: uint, -} - -impl FixedBuffer64 { - /// Create a new buffer - fn new() -> FixedBuffer64 { - return FixedBuffer64 { - buffer: [0u8, ..64], - buffer_idx: 0 - }; - } -} - -impl FixedBuffer for FixedBuffer64 { - fn input(&mut self, input: &[u8], func: |&[u8]|) { - let mut i = 0; - - let size = 64; - - // If there is already data in the buffer, copy as much as we can into it and process - // the data if the buffer becomes full. - if self.buffer_idx != 0 { - let buffer_remaining = size - self.buffer_idx; - if input.len() >= buffer_remaining { - copy_memory( - self.buffer.mut_slice(self.buffer_idx, size), - input.slice_to(buffer_remaining)); - self.buffer_idx = 0; - func(self.buffer); - i += buffer_remaining; - } else { - copy_memory( - self.buffer.mut_slice(self.buffer_idx, self.buffer_idx + input.len()), - input); - self.buffer_idx += input.len(); - return; - } - } - - // While we have at least a full buffer size chunks's worth of data, process that data - // without copying it into the buffer - while input.len() - i >= size { - func(input.slice(i, i + size)); - i += size; - } - - // Copy any input data into the buffer. At this point in the method, the ammount of - // data left in the input vector will be less than the buffer size and the buffer will - // be empty. - let input_remaining = input.len() - i; - copy_memory( - self.buffer.mut_slice(0, input_remaining), - input.slice_from(i)); - self.buffer_idx += input_remaining; - } - - fn reset(&mut self) { - self.buffer_idx = 0; - } - - fn zero_until(&mut self, idx: uint) { - assert!(idx >= self.buffer_idx); - self.buffer.mut_slice(self.buffer_idx, idx).set_memory(0); - self.buffer_idx = idx; - } - - fn next<'s>(&'s mut self, len: uint) -> &'s mut [u8] { - self.buffer_idx += len; - return self.buffer.mut_slice(self.buffer_idx - len, self.buffer_idx); - } - - fn full_buffer<'s>(&'s mut self) -> &'s [u8] { - assert!(self.buffer_idx == 64); - self.buffer_idx = 0; - return self.buffer.slice_to(64); - } - - fn position(&self) -> uint { self.buffer_idx } - - fn remaining(&self) -> uint { 64 - self.buffer_idx } - - fn size(&self) -> uint { 64 } -} - -/// The StandardPadding trait adds a method useful for various hash algorithms to a FixedBuffer -/// struct. -trait StandardPadding { - /// Add standard padding to the buffer. The buffer must not be full when this method is called - /// and is guaranteed to have exactly rem remaining bytes when it returns. If there are not at - /// least rem bytes available, the buffer will be zero padded, processed, cleared, and then - /// filled with zeros again until only rem bytes are remaining. - fn standard_padding(&mut self, rem: uint, func: |&[u8]|); -} - -impl StandardPadding for T { - fn standard_padding(&mut self, rem: uint, func: |&[u8]|) { - let size = self.size(); - - self.next(1)[0] = 128; - - if self.remaining() < rem { - self.zero_until(size); - func(self.full_buffer()); - } - - self.zero_until(size - rem); - } -} - -/** - * The Digest trait specifies an interface common to digest functions, such as SHA-1 and the SHA-2 - * family of digest functions. - */ -pub trait Digest { - /** - * Provide message data. - * - * # Arguments - * - * * input - A vector of message data - */ - fn input(&mut self, input: &[u8]); - - /** - * Retrieve the digest result. This method may be called multiple times. - * - * # Arguments - * - * * out - the vector to hold the result. Must be large enough to contain output_bits(). - */ - fn result(&mut self, out: &mut [u8]); - - /** - * Reset the digest. This method must be called after result() and before supplying more - * data. - */ - fn reset(&mut self); - - /** - * Get the output size in bits. - */ - fn output_bits(&self) -> uint; - - /** - * Convenience function that feeds a string into a digest. - * - * # Arguments - * - * * `input` The string to feed into the digest - */ - fn input_str(&mut self, input: &str) { - self.input(input.as_bytes()); - } - - /** - * Convenience function that retrieves the result of a digest as a - * newly allocated vec of bytes. - */ - fn result_bytes(&mut self) -> ~[u8] { - let mut buf = vec::from_elem((self.output_bits()+7)/8, 0u8); - self.result(buf); - buf - } - - /** - * Convenience function that retrieves the result of a digest as a - * ~str in hexadecimal format. - */ - fn result_str(&mut self) -> ~str { - self.result_bytes().to_hex() - } -} - -/* - * A SHA-1 implementation derived from Paul E. Jones's reference - * implementation, which is written for clarity, not speed. At some - * point this will want to be rewritten. - */ - -// Some unexported constants -static DIGEST_BUF_LEN: uint = 5u; -static WORK_BUF_LEN: uint = 80u; -static K0: u32 = 0x5A827999u32; -static K1: u32 = 0x6ED9EBA1u32; -static K2: u32 = 0x8F1BBCDCu32; -static K3: u32 = 0xCA62C1D6u32; - -/// Structure representing the state of a Sha1 computation -pub struct Sha1 { - priv h: [u32, ..DIGEST_BUF_LEN], - priv length_bits: u64, - priv buffer: FixedBuffer64, - priv computed: bool, -} - -fn add_input(st: &mut Sha1, msg: &[u8]) { - assert!((!st.computed)); - // Assumes that msg.len() can be converted to u64 without overflow - st.length_bits = add_bytes_to_bits(st.length_bits, msg.len() as u64); - st.buffer.input(msg, |d: &[u8]| { process_msg_block(d, &mut st.h); }); -} - -fn process_msg_block(data: &[u8], h: &mut [u32, ..DIGEST_BUF_LEN]) { - let mut t: int; // Loop counter - - let mut w = [0u32, ..WORK_BUF_LEN]; - - // Initialize the first 16 words of the vector w - read_u32v_be(w.mut_slice(0, 16), data); - - // Initialize the rest of vector w - t = 16; - while t < 80 { - let val = w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16]; - w[t] = circular_shift(1, val); - t += 1; - } - let mut a = h[0]; - let mut b = h[1]; - let mut c = h[2]; - let mut d = h[3]; - let mut e = h[4]; - let mut temp: u32; - t = 0; - while t < 20 { - temp = circular_shift(5, a) + (b & c | !b & d) + e + w[t] + K0; - e = d; - d = c; - c = circular_shift(30, b); - b = a; - a = temp; - t += 1; - } - while t < 40 { - temp = circular_shift(5, a) + (b ^ c ^ d) + e + w[t] + K1; - e = d; - d = c; - c = circular_shift(30, b); - b = a; - a = temp; - t += 1; - } - while t < 60 { - temp = - circular_shift(5, a) + (b & c | b & d | c & d) + e + w[t] + - K2; - e = d; - d = c; - c = circular_shift(30, b); - b = a; - a = temp; - t += 1; - } - while t < 80 { - temp = circular_shift(5, a) + (b ^ c ^ d) + e + w[t] + K3; - e = d; - d = c; - c = circular_shift(30, b); - b = a; - a = temp; - t += 1; - } - h[0] += a; - h[1] += b; - h[2] += c; - h[3] += d; - h[4] += e; -} - -fn circular_shift(bits: u32, word: u32) -> u32 { - return word << bits | word >> 32u32 - bits; -} - -fn mk_result(st: &mut Sha1, rs: &mut [u8]) { - if !st.computed { - st.buffer.standard_padding(8, |d: &[u8]| { process_msg_block(d, &mut st.h) }); - write_u32_be(st.buffer.next(4), (st.length_bits >> 32) as u32 ); - write_u32_be(st.buffer.next(4), st.length_bits as u32); - process_msg_block(st.buffer.full_buffer(), &mut st.h); - - st.computed = true; - } - - write_u32_be(rs.mut_slice(0, 4), st.h[0]); - write_u32_be(rs.mut_slice(4, 8), st.h[1]); - write_u32_be(rs.mut_slice(8, 12), st.h[2]); - write_u32_be(rs.mut_slice(12, 16), st.h[3]); - write_u32_be(rs.mut_slice(16, 20), st.h[4]); -} - -impl Sha1 { - /// Construct a `sha` object - pub fn new() -> Sha1 { - let mut st = Sha1 { - h: [0u32, ..DIGEST_BUF_LEN], - length_bits: 0u64, - buffer: FixedBuffer64::new(), - computed: false, - }; - st.reset(); - return st; - } -} - -impl Digest for Sha1 { - fn reset(&mut self) { - self.length_bits = 0; - self.h[0] = 0x67452301u32; - self.h[1] = 0xEFCDAB89u32; - self.h[2] = 0x98BADCFEu32; - self.h[3] = 0x10325476u32; - self.h[4] = 0xC3D2E1F0u32; - self.buffer.reset(); - self.computed = false; - } - fn input(&mut self, msg: &[u8]) { add_input(self, msg); } - fn result(&mut self, out: &mut [u8]) { return mk_result(self, out); } - fn output_bits(&self) -> uint { 160 } -} - -#[cfg(test)] -mod tests { - use std::num::Bounded; - use std::rand::{IsaacRng, Rng}; - use std::vec; - use extra::hex::FromHex; - use super::{Digest, Sha1, add_bytes_to_bits}; - - #[deriving(Clone)] - struct Test { - input: ~str, - output: ~[u8], - output_str: ~str, - } - - #[test] - fn test() { - // Test messages from FIPS 180-1 - - let fips_180_1_tests = ~[ - Test { - input: ~"abc", - output: ~[ - 0xA9u8, 0x99u8, 0x3Eu8, 0x36u8, - 0x47u8, 0x06u8, 0x81u8, 0x6Au8, - 0xBAu8, 0x3Eu8, 0x25u8, 0x71u8, - 0x78u8, 0x50u8, 0xC2u8, 0x6Cu8, - 0x9Cu8, 0xD0u8, 0xD8u8, 0x9Du8, - ], - output_str: ~"a9993e364706816aba3e25717850c26c9cd0d89d" - }, - Test { - input: - ~"abcdbcdecdefdefgefghfghighij" + - "hijkijkljklmklmnlmnomnopnopq", - output: ~[ - 0x84u8, 0x98u8, 0x3Eu8, 0x44u8, - 0x1Cu8, 0x3Bu8, 0xD2u8, 0x6Eu8, - 0xBAu8, 0xAEu8, 0x4Au8, 0xA1u8, - 0xF9u8, 0x51u8, 0x29u8, 0xE5u8, - 0xE5u8, 0x46u8, 0x70u8, 0xF1u8, - ], - output_str: ~"84983e441c3bd26ebaae4aa1f95129e5e54670f1" - }, - ]; - // Examples from wikipedia - - let wikipedia_tests = ~[ - Test { - input: ~"The quick brown fox jumps over the lazy dog", - output: ~[ - 0x2fu8, 0xd4u8, 0xe1u8, 0xc6u8, - 0x7au8, 0x2du8, 0x28u8, 0xfcu8, - 0xedu8, 0x84u8, 0x9eu8, 0xe1u8, - 0xbbu8, 0x76u8, 0xe7u8, 0x39u8, - 0x1bu8, 0x93u8, 0xebu8, 0x12u8, - ], - output_str: ~"2fd4e1c67a2d28fced849ee1bb76e7391b93eb12", - }, - Test { - input: ~"The quick brown fox jumps over the lazy cog", - output: ~[ - 0xdeu8, 0x9fu8, 0x2cu8, 0x7fu8, - 0xd2u8, 0x5eu8, 0x1bu8, 0x3au8, - 0xfau8, 0xd3u8, 0xe8u8, 0x5au8, - 0x0bu8, 0xd1u8, 0x7du8, 0x9bu8, - 0x10u8, 0x0du8, 0xb4u8, 0xb3u8, - ], - output_str: ~"de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3", - }, - ]; - let tests = fips_180_1_tests + wikipedia_tests; - - // Test that it works when accepting the message all at once - - let mut out = [0u8, ..20]; - - let mut sh = ~Sha1::new(); - for t in tests.iter() { - (*sh).input_str(t.input); - sh.result(out); - assert!(t.output.as_slice() == out); - - let out_str = (*sh).result_str(); - assert_eq!(out_str.len(), 40); - assert!(out_str == t.output_str); - - sh.reset(); - } - - - // Test that it works when accepting the message in pieces - for t in tests.iter() { - let len = t.input.len(); - let mut left = len; - while left > 0u { - let take = (left + 1u) / 2u; - (*sh).input_str(t.input.slice(len - left, take + len - left)); - left = left - take; - } - sh.result(out); - assert!(t.output.as_slice() == out); - - let out_str = (*sh).result_str(); - assert_eq!(out_str.len(), 40); - assert!(out_str == t.output_str); - - sh.reset(); - } - } - - /// Feed 1,000,000 'a's into the digest with varying input sizes and check that the result is - /// correct. - fn test_digest_1million_random(digest: &mut D, blocksize: uint, expected: &str) { - let total_size = 1000000; - let buffer = vec::from_elem(blocksize * 2, 'a' as u8); - let mut rng = IsaacRng::new_unseeded(); - let mut count = 0; - - digest.reset(); - - while count < total_size { - let next: uint = rng.gen_range(0, 2 * blocksize + 1); - let remaining = total_size - count; - let size = if next > remaining { remaining } else { next }; - digest.input(buffer.slice_to(size)); - count += size; - } - - let result_str = digest.result_str(); - let result_bytes = digest.result_bytes(); - - assert_eq!(expected, result_str.as_slice()); - assert_eq!(expected.from_hex().unwrap(), result_bytes); - } - - #[test] - fn test_1million_random_sha1() { - let mut sh = Sha1::new(); - test_digest_1million_random( - &mut sh, - 64, - "34aa973cd4c4daa4f61eeb2bdbad27316534016f"); - } - - // A normal addition - no overflow occurs - #[test] - fn test_add_bytes_to_bits_ok() { - assert!(add_bytes_to_bits::(100, 10) == 180); - } - - // A simple failure case - adding 1 to the max value - #[test] - #[should_fail] - fn test_add_bytes_to_bits_overflow() { - add_bytes_to_bits::(Bounded::max_value(), 1); - } -} - -#[cfg(test)] -mod bench { - use extra::test::BenchHarness; - use super::Sha1; - - #[bench] - pub fn sha1_10(bh: & mut BenchHarness) { - let mut sh = Sha1::new(); - let bytes = [1u8, ..10]; - bh.iter(|| sh.input(bytes)); - bh.bytes = bytes.len() as u64; - } - - #[bench] - pub fn sha1_1k(bh: & mut BenchHarness) { - let mut sh = Sha1::new(); - let bytes = [1u8, ..1024]; - bh.iter(|| sh.input(bytes)); - bh.bytes = bytes.len() as u64; - } - - #[bench] - pub fn sha1_64k(bh: & mut BenchHarness) { - let mut sh = Sha1::new(); - let bytes = [1u8, ..65536]; - bh.iter(|| sh.input(bytes)); - bh.bytes = bytes.len() as u64; - } -} diff --git a/src/librustpkg/source_control.rs b/src/librustpkg/source_control.rs deleted file mode 100644 index 2346749feb5..00000000000 --- a/src/librustpkg/source_control.rs +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Utils for working with version control repositories. Just git right now. - -use std::{run, str}; -use std::run::{ProcessOutput, ProcessOptions, Process}; -use std::io::fs; -use extra::tempfile::TempDir; -use path_util::chmod_read_only; - -/// Attempts to clone `source`, a local git repository, into `target`, a local -/// directory that doesn't exist. -/// Returns `DirToUse(p)` if the clone fails, where `p` is a newly created temporary -/// directory (that the callee may use, for example, to check out remote sources into). -/// Returns `CheckedOutSources` if the clone succeeded. -pub fn safe_git_clone(source: &Path, v: &Option<~str>, target: &Path) -> CloneResult { - if source.exists() { - debug!("{} exists locally! Cloning it into {}", - source.display(), target.display()); - // Ok to use target here; we know it will succeed - assert!(source.is_dir()); - assert!(is_git_dir(source)); - - if !target.exists() { - debug!("Running: git clone {} {}", source.display(), target.display()); - // FIXME (#9639): This needs to handle non-utf8 paths - let opt_outp = run::process_output("git", [~"clone", - source.as_str().unwrap().to_owned(), - target.as_str().unwrap().to_owned()]); - let outp = opt_outp.expect("Failed to exec `git`"); - if !outp.status.success() { - println!("{}", str::from_utf8_owned(outp.output.clone()).unwrap()); - println!("{}", str::from_utf8_owned(outp.error).unwrap()); - return DirToUse(target.clone()); - } - else { - match v { - &Some(ref s) => { - let git_dir = target.join(".git"); - debug!("`Running: git --work-tree={} --git-dir={} checkout {}", - *s, target.display(), git_dir.display()); - // FIXME (#9639: This needs to handle non-utf8 paths - let outp = run::process_output("git", - [format!("--work-tree={}", target.as_str().unwrap().to_owned()), - format!("--git-dir={}", git_dir.as_str().unwrap().to_owned()), - ~"checkout", format!("{}", *s)]).expect("Failed to exec `git`"); - if !outp.status.success() { - println!("{}", str::from_utf8_owned(outp.output.clone()).unwrap()); - println!("{}", str::from_utf8_owned(outp.error).unwrap()); - return DirToUse(target.clone()); - } - } - _ => () - } - } - } else { - // Check that no version was specified. There's no reason to not handle the - // case where a version was requested, but I haven't implemented it. - assert!(*v == None); - let git_dir = target.join(".git"); - debug!("Running: git --work-tree={} --git-dir={} pull --no-edit {}", - target.display(), git_dir.display(), source.display()); - // FIXME (#9639: This needs to handle non-utf8 paths - let args = [format!("--work-tree={}", target.as_str().unwrap().to_owned()), - format!("--git-dir={}", git_dir.as_str().unwrap().to_owned()), - ~"pull", ~"--no-edit", source.as_str().unwrap().to_owned()]; - let opt_outp = run::process_output("git", args); - let outp = opt_outp.expect("Failed to exec `git`"); - assert!(outp.status.success()); - } - CheckedOutSources - } else { - use conditions::failed_to_create_temp_dir::cond; - - let scratch_dir = TempDir::new("rustpkg"); - let clone_target = match scratch_dir { - Some(d) => d.unwrap().join("rustpkg_temp"), - None => cond.raise(~"Failed to create temporary directory for fetching git sources") - }; - - DirToUse(clone_target) - } -} - -pub enum CloneResult { - DirToUse(Path), // Created this empty directory to use as the temp dir for git - CheckedOutSources // Successfully checked sources out into the given target dir -} - -pub fn make_read_only(target: &Path) { - // Now, make all the files in the target dir read-only - for p in fs::walk_dir(target) { - if !p.is_dir() { - assert!(chmod_read_only(&p)); - } - } -} - -/// Source can be either a URL or a local file path. -pub fn git_clone_url(source: &str, target: &Path, v: &Option<~str>) { - use conditions::git_checkout_failed::cond; - - // FIXME (#9639): This needs to handle non-utf8 paths - let opt_outp = run::process_output("git", [~"clone", source.to_owned(), - target.as_str().unwrap().to_owned()]); - let outp = opt_outp.expect("Failed to exec `git`"); - if !outp.status.success() { - debug!("{}", str::from_utf8_owned(outp.output.clone()).unwrap()); - debug!("{}", str::from_utf8_owned(outp.error).unwrap()); - cond.raise((source.to_owned(), target.clone())) - } - else { - match v { - &Some(ref s) => { - let opt_outp = process_output_in_cwd("git", [~"checkout", s.to_owned()], - target); - let outp = opt_outp.expect("Failed to exec `git`"); - if !outp.status.success() { - debug!("{}", str::from_utf8_owned(outp.output.clone()).unwrap()); - debug!("{}", str::from_utf8_owned(outp.error).unwrap()); - cond.raise((source.to_owned(), target.clone())) - } - } - _ => () - } - } -} - -fn process_output_in_cwd(prog: &str, args: &[~str], cwd: &Path) -> Option { - let mut opt_prog = Process::new(prog, args, ProcessOptions{ dir: Some(cwd) - ,..ProcessOptions::new()}); - match opt_prog { - Some(ref mut prog) => Some(prog.finish_with_output()), - None => None - } -} - -pub fn is_git_dir(p: &Path) -> bool { - p.join(".git").is_dir() -} diff --git a/src/librustpkg/target.rs b/src/librustpkg/target.rs deleted file mode 100644 index 73c305be798..00000000000 --- a/src/librustpkg/target.rs +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - - -// Data types that express build artifacts - -#[deriving(Eq)] -pub enum OutputType { Main, Lib, Bench, Test } - -#[deriving(Eq)] -pub enum Target { - /// In-place build - Build, - /// Install to bin/ or lib/ dir - Install -} - -#[deriving(Eq, Clone)] -pub struct WhatToBuild { - build_type: BuildType, // Whether or not to ignore the pkg.rs file - sources: SourceType, // Which crates to build - inputs_to_discover: ~[(~str, Path)] // Inputs to these crates to be discovered - // (For now all of these inputs will be taken as discovered inputs - // for all of the crates) - // (Paired with their kinds) -} - -impl WhatToBuild { - pub fn new(build_type: BuildType, sources: SourceType) -> WhatToBuild { - WhatToBuild { build_type: build_type, - sources: sources, - inputs_to_discover: ~[] } - } -} - -#[deriving(Eq, Clone)] -pub enum BuildType { - Inferred, // Ignore the pkg.rs file even if one exists - MaybeCustom // Use the pkg.rs file if it exists -} - -#[deriving(Eq, Clone)] -pub enum SourceType { - /// Build just one lib.rs file in `path`, which is relative to the active workspace's src/ dir - JustOne(Path), - /// Build any test.rs files that can be recursively found in the active workspace - Tests, - /// Build everything - Everything -} - -pub fn is_lib(p: &Path) -> bool { - file_is(p, "lib") -} - -pub fn is_main(p: &Path) -> bool { - file_is(p, "main") -} - -pub fn is_test(p: &Path) -> bool { - file_is(p, "test") -} - -pub fn is_bench(p: &Path) -> bool { - file_is(p, "bench") -} - -fn file_is(p: &Path, stem: &str) -> bool { - match p.filestem() { - Some(s) if s == stem.as_bytes() => true, - _ => false - } -} - -#[allow(dead_code)] -pub fn lib_name_of(p: &Path) -> Path { - p.join("lib.rs") -} - -pub static lib_crate_filename: &'static str = "lib.rs"; diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs deleted file mode 100644 index 091399c3fb7..00000000000 --- a/src/librustpkg/tests.rs +++ /dev/null @@ -1,2407 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// rustpkg unit tests - -use CtxMethods; -use context::{BuildContext, Context, RustcFlags}; -use std::{os, run, str, task}; -use std::io; -use std::io::fs; -use std::io::File; -use extra::arc::Arc; -use extra::arc::RWArc; -use extra::tempfile::TempDir; -use extra::workcache; -use extra::workcache::Database; -use extra::treemap::TreeMap; -use extra::getopts::groups::getopts; -use std::run::ProcessOutput; -use installed_packages::list_installed_packages; -use syntax::crateid::CrateId; -use path_util::{target_executable_in_workspace, target_test_in_workspace, - target_bench_in_workspace, make_dir_rwx, - library_in_workspace, installed_library_in_workspace, - built_bench_in_workspace, built_test_in_workspace, - built_library_in_workspace, built_executable_in_workspace, target_build_dir, - chmod_read_only, platform_library_name}; -use rustc::back::link::get_cc_prog; -use rustc::metadata::filesearch::{rust_path, libdir, rustlibdir}; -use rustc::driver::driver::{build_session, build_session_options, host_triple, optgroups}; -use syntax::diagnostic; -use target::*; -use package_source::PkgSrc; -use source_control::{CheckedOutSources, DirToUse, safe_git_clone}; -use exit_codes::{BAD_FLAG_CODE, COPY_FAILED_CODE}; - -fn fake_ctxt(sysroot: Path, workspace: &Path) -> BuildContext { - let context = workcache::Context::new( - RWArc::new(Database::new(workspace.join("rustpkg_db.json"))), - Arc::new(TreeMap::new())); - BuildContext { - workcache_context: context, - context: Context { - cfgs: ~[], - rustc_flags: RustcFlags::default(), - - use_rust_path_hack: false, - }, - sysroot: sysroot - } -} - -fn fake_pkg() -> CrateId { - CrateId { - path: ~"bogus", - name: ~"bogus", - version: None - } -} - -fn git_repo_pkg() -> CrateId { - CrateId { - path: ~"mockgithub.com/catamorphism/test-pkg", - name: ~"test-pkg", - version: None - } -} - -fn writeFile(file_path: &Path, contents: &str) { - let mut out = File::create(file_path); - out.write(contents.as_bytes()); - out.write(['\n' as u8]); -} - -fn mk_emptier_workspace(tag: &str) -> TempDir { - let workspace = TempDir::new(tag).expect("couldn't create temp dir"); - let package_dir = workspace.path().join("src"); - fs::mkdir_recursive(&package_dir, io::UserRWX); - workspace -} - -fn mk_empty_workspace(crate_id: &CrateId, tag: &str) -> TempDir { - let workspace_dir = TempDir::new(tag).expect("couldn't create temp dir"); - mk_workspace(workspace_dir.path(), crate_id); - workspace_dir -} - -fn mk_workspace(workspace: &Path, crate_id: &CrateId) -> Path { - // include version number in directory name - // FIXME (#9639): This needs to handle non-utf8 paths - let package_dir = workspace.join_many([~"src", crate_id.short_name_with_version()]); - fs::mkdir_recursive(&package_dir, io::UserRWX); - package_dir -} - -fn mk_temp_workspace(crate_id: &CrateId) -> (TempDir, Path) { - let workspace_dir = mk_empty_workspace(crate_id, "temp_workspace"); - // FIXME (#9639): This needs to handle non-utf8 paths - let package_dir = workspace_dir.path().join_many([~"src", crate_id.short_name_with_version()]); - - debug!("Created {} and does it exist? {:?}", package_dir.display(), - package_dir.is_dir()); - // Create main, lib, test, and bench files - debug!("mk_workspace: creating {}", package_dir.display()); - fs::mkdir_recursive(&package_dir, io::UserRWX); - debug!("Created {} and does it exist? {:?}", package_dir.display(), - package_dir.is_dir()); - // Create main, lib, test, and bench files - - writeFile(&package_dir.join("main.rs"), - "fn main() { let _x = (); }"); - writeFile(&package_dir.join("lib.rs"), - "pub fn f() { let _x = (); }"); - writeFile(&package_dir.join("test.rs"), - "#[test] pub fn f() { (); }"); - writeFile(&package_dir.join("bench.rs"), - "#[bench] pub fn f() { (); }"); - (workspace_dir, package_dir) -} - -fn run_git(args: &[~str], env: Option<~[(~str, ~str)]>, cwd: &Path, err_msg: &str) { - let cwd = (*cwd).clone(); - let mut prog = run::Process::new("git", args, run::ProcessOptions { - env: env, - dir: Some(&cwd), - in_fd: None, - out_fd: None, - err_fd: None - }).expect("failed to exec `git`"); - let rslt = prog.finish_with_output(); - if !rslt.status.success() { - fail!("{} [git returned {:?}, output = {}, error = {}]", err_msg, - rslt.status, str::from_utf8(rslt.output).unwrap(), str::from_utf8(rslt.error).unwrap()); - } -} - -/// Should create an empty git repo in p, relative to the tmp dir, and return the new -/// absolute path -fn init_git_repo(p: &Path) -> TempDir { - assert!(p.is_relative()); - let tmp = TempDir::new("git_local").expect("couldn't create temp dir"); - let work_dir = tmp.path().join(p); - let work_dir_for_opts = work_dir.clone(); - fs::mkdir_recursive(&work_dir, io::UserRWX); - debug!("Running: git init in {}", work_dir.display()); - run_git([~"init"], None, &work_dir_for_opts, - format!("Couldn't initialize git repository in {}", work_dir.display())); - // Add stuff to the dir so that git tag succeeds - writeFile(&work_dir.join("README"), ""); - run_git([~"add", ~"README"], None, &work_dir_for_opts, format!("Couldn't add in {}", - work_dir.display())); - git_commit(&work_dir_for_opts, ~"whatever"); - tmp -} - -fn add_all_and_commit(repo: &Path) { - git_add_all(repo); - git_commit(repo, ~"floop"); -} - -fn git_commit(repo: &Path, msg: ~str) { - run_git([~"commit", ~"--author=tester ", ~"-m", msg], - None, repo, format!("Couldn't commit in {}", repo.display())); -} - -fn git_add_all(repo: &Path) { - run_git([~"add", ~"-A"], None, repo, format!("Couldn't add all files in {}", repo.display())); -} - -fn add_git_tag(repo: &Path, tag: ~str) { - assert!(repo.is_absolute()); - git_add_all(repo); - git_commit(repo, ~"whatever"); - run_git([~"tag", tag.clone()], None, repo, - format!("Couldn't add git tag {} in {}", tag, repo.display())); -} - -fn is_rwx(p: &Path) -> bool { - if !p.exists() { return false } - p.stat().perm & io::UserRWX == io::UserRWX -} - -fn is_read_only(p: &Path) -> bool { - if !p.exists() { return false } - p.stat().perm & io::UserRWX == io::UserRead -} - -fn test_sysroot() -> Path { - // Totally gross hack but it's just for test cases. - // Infer the sysroot from the exe name and pray that it's right. - // (Did I mention it was a gross hack?) - let mut self_path = os::self_exe_path().expect("Couldn't get self_exe path"); - self_path.pop(); - self_path -} - -// Returns the path to rustpkg -fn rustpkg_exec() -> Path { - // Ugh - let first_try = test_sysroot().join_many( - [libdir(), rustlibdir(), host_triple(), ~"bin", ~"rustpkg"]); - if is_executable(&first_try) { - first_try - } - else { - let second_try = test_sysroot().join_many(["bin", "rustpkg"]); - if is_executable(&second_try) { - second_try - } - else { - fail!("in rustpkg test, can't find an installed rustpkg"); - } - } -} - -fn command_line_test(args: &[~str], cwd: &Path) -> ProcessOutput { - match command_line_test_with_env(args, cwd, None) { - Success(r) => r, - Fail(error) => fail!("Command line test failed with error {}", - error.status) - } -} - -fn command_line_test_partial(args: &[~str], cwd: &Path) -> ProcessResult { - command_line_test_with_env(args, cwd, None) -} - -fn command_line_test_expect_fail(args: &[~str], - cwd: &Path, - env: Option<~[(~str, ~str)]>, - expected_exitcode: int) { - match command_line_test_with_env(args, cwd, env) { - Success(_) => fail!("Should have failed with {}, but it succeeded", expected_exitcode), - Fail(ref error) if error.status.matches_exit_status(expected_exitcode) => (), // ok - Fail(other) => fail!("Expected to fail with {}, but failed with {} instead", - expected_exitcode, other.status) - } -} - -enum ProcessResult { - Success(ProcessOutput), - Fail(ProcessOutput) -} - -/// Runs `rustpkg` (based on the directory that this executable was -/// invoked from) with the given arguments, in the given working directory. -/// Returns the process's output. -fn command_line_test_with_env(args: &[~str], cwd: &Path, env: Option<~[(~str, ~str)]>) - -> ProcessResult { - // FIXME (#9639): This needs to handle non-utf8 paths - let exec_path = rustpkg_exec(); - let cmd = exec_path.as_str().unwrap().to_owned(); - let env_str = match env { - Some(ref pairs) => pairs.map(|&(ref k, ref v)| { format!("{}={}", *k, *v) }).connect(","), - None => ~"" - }; - debug!("{} cd {}; {} {}", env_str, cwd.display(), cmd, args.connect(" ")); - assert!(cwd.is_dir()); - let cwd = (*cwd).clone(); - let mut prog = run::Process::new(cmd, args, run::ProcessOptions { - env: env.map(|e| e + os::env()), - dir: Some(&cwd), - in_fd: None, - out_fd: None, - err_fd: None - }).expect(format!("failed to exec `{}`", cmd)); - let output = prog.finish_with_output(); - debug!("Output from command {} with args {:?} was --- {} \\{{}\\} --- [{:?}]", - cmd, args, str::from_utf8(output.output).unwrap(), - str::from_utf8(output.error).unwrap(), - output.status); - if !output.status.success() { - Fail(output) - } - else { - Success(output) - } -} - -fn create_local_package(crateid: &CrateId) -> TempDir { - let (workspace, parent_dir) = mk_temp_workspace(crateid); - debug!("Created empty package dir for {}, returning {}", crateid.to_str(), - parent_dir.display()); - workspace -} - -fn create_local_package_in(crateid: &CrateId, pkgdir: &Path) -> Path { - - let package_dir = pkgdir.join_many([~"src", crateid.short_name_with_version()]); - - // Create main, lib, test, and bench files - fs::mkdir_recursive(&package_dir, io::UserRWX); - debug!("Created {} and does it exist? {:?}", package_dir.display(), - package_dir.is_dir()); - // Create main, lib, test, and bench files - - writeFile(&package_dir.join("main.rs"), - "fn main() { let _x = (); }"); - writeFile(&package_dir.join("lib.rs"), - "pub fn f() { let _x = (); }"); - writeFile(&package_dir.join("test.rs"), - "#[test] pub fn f() { (); }"); - writeFile(&package_dir.join("bench.rs"), - "#[bench] pub fn f() { (); }"); - package_dir -} - -fn create_local_package_with_test(crateid: &CrateId) -> TempDir { - debug!("Dry run -- would create package {:?} with test", crateid); - create_local_package(crateid) // Already has tests??? -} - -fn create_local_package_with_dep(crateid: &CrateId, subord_crateid: &CrateId) -> TempDir { - let package_dir = create_local_package(crateid); - create_local_package_in(subord_crateid, package_dir.path()); - // Write a main.rs file into crateid that references subord_crateid - writeFile(&package_dir.path().join_many([~"src", - crateid.short_name_with_version(), - ~"main.rs"]), - format!("extern mod {};\nfn main() \\{\\}", - subord_crateid.name)); - // Write a lib.rs file into subord_crateid that has something in it - writeFile(&package_dir.path().join_many([~"src", - subord_crateid.short_name_with_version(), - ~"lib.rs"]), - "pub fn f() {}"); - package_dir -} - -fn create_local_package_with_custom_build_hook(crateid: &CrateId, - custom_build_hook: &str) -> TempDir { - debug!("Dry run -- would create package {} with custom build hook {}", - crateid.to_str(), custom_build_hook); - create_local_package(crateid) - // actually write the pkg.rs with the custom build hook - -} - -fn assert_lib_exists(repo: &Path, crate_id: &CrateId) { - assert!(lib_exists(repo, crate_id)); -} - -fn lib_exists(repo: &Path, crate_id: &CrateId) -> bool { - debug!("assert_lib_exists: repo = {}, crate_id = {}", repo.display(), crate_id.to_str()); - let lib = installed_library_in_workspace(crate_id, repo); - debug!("assert_lib_exists: checking whether {:?} exists", lib); - lib.is_some() && { - let libname = lib.get_ref(); - libname.exists() - } -} - -fn assert_executable_exists(repo: &Path, short_name: &str) { - assert!(executable_exists(repo, short_name)); -} - -fn executable_exists(repo: &Path, short_name: &str) -> bool { - let crate_id = from_str(short_name).expect("valid crate id"); - debug!("executable_exists: repo = {}, short_name = {}", repo.display(), short_name); - let exec = target_executable_in_workspace(&crate_id, repo); - exec.exists() && is_rwx(&exec) -} - -fn test_executable_exists(repo: &Path, short_name: &str) -> bool { - let crate_id = from_str(short_name).expect("valid crate id"); - debug!("test_executable_exists: repo = {}, short_name = {}", repo.display(), short_name); - let exec = built_test_in_workspace(&crate_id, repo); - exec.map_or(false, |exec| exec.exists() && is_rwx(&exec)) -} - -fn remove_executable_file(p: &CrateId, workspace: &Path) { - let exec = target_executable_in_workspace(p, workspace); - if exec.exists() { - fs::unlink(&exec); - } -} - -fn assert_built_executable_exists(repo: &Path, short_name: &str) { - assert!(built_executable_exists(repo, short_name)); -} - -fn built_executable_exists(repo: &Path, short_name: &str) -> bool { - debug!("assert_built_executable_exists: repo = {}, short_name = {}", - repo.display(), short_name); - let crate_id = from_str(short_name).expect("valid crate id"); - let exec = built_executable_in_workspace(&crate_id, repo); - exec.is_some() && { - let execname = exec.get_ref(); - execname.exists() && is_rwx(execname) - } -} - -fn remove_built_executable_file(p: &CrateId, workspace: &Path) { - let exec = built_executable_in_workspace(p, workspace); - match exec { - Some(r) => fs::unlink(&r), - None => () - } -} - -fn object_file_exists(repo: &Path, short_name: &str) -> bool { - file_exists(repo, short_name, "o") -} - -fn assembly_file_exists(repo: &Path, short_name: &str) -> bool { - file_exists(repo, short_name, "s") -} - -fn llvm_assembly_file_exists(repo: &Path, short_name: &str) -> bool { - file_exists(repo, short_name, "ll") -} - -fn llvm_bitcode_file_exists(repo: &Path, short_name: &str) -> bool { - file_exists(repo, short_name, "bc") -} - -fn file_exists(repo: &Path, short_name: &str, extension: &str) -> bool { - target_build_dir(repo).join_many([short_name.to_owned(), - format!("{}.{}", short_name, extension)]) - .exists() -} - -fn assert_built_library_exists(repo: &Path, short_name: &str) { - assert!(built_library_exists(repo, short_name)); -} - -fn built_library_exists(repo: &Path, short_name: &str) -> bool { - debug!("assert_built_library_exists: repo = {}, short_name = {}", repo.display(), short_name); - let crate_id = from_str(short_name).expect("valid crate id"); - let lib = built_library_in_workspace(&crate_id, repo); - lib.is_some() && { - let libname = lib.get_ref(); - libname.exists() - } -} - -fn command_line_test_output(args: &[~str]) -> ~[~str] { - let mut result = ~[]; - let p_output = command_line_test(args, &os::getcwd()); - let test_output = str::from_utf8(p_output.output).unwrap(); - for s in test_output.split('\n') { - result.push(s.to_owned()); - } - result -} - -fn command_line_test_output_with_env(args: &[~str], env: ~[(~str, ~str)]) -> ~[~str] { - let mut result = ~[]; - let p_output = match command_line_test_with_env(args, - &os::getcwd(), Some(env)) { - Fail(_) => fail!("Command-line test failed"), - Success(r) => r - }; - let test_output = str::from_utf8(p_output.output).unwrap(); - for s in test_output.split('\n') { - result.push(s.to_owned()); - } - result -} - -// assumes short_name and path are one and the same -- I should fix -fn lib_output_file_name(workspace: &Path, short_name: &str) -> Path { - debug!("lib_output_file_name: given {} and short name {}", - workspace.display(), short_name); - let crate_id = from_str(short_name).expect("valid crate id"); - library_in_workspace(&crate_id, - Build, - workspace).expect("lib_output_file_name") -} - -#[cfg(target_os = "linux")] -fn touch_source_file(workspace: &Path, crateid: &CrateId) { - use conditions::bad_path::cond; - let pkg_src_dir = workspace.join_many([~"src", crateid.short_name_with_version()]); - let contents = fs::readdir(&pkg_src_dir); - for p in contents.iter() { - if p.extension_str() == Some("rs") { - // should be able to do this w/o a process - // FIXME (#9639): This needs to handle non-utf8 paths - // n.b. Bumps time up by 2 seconds to get around granularity issues - if !run::process_output("touch", [~"--date", - ~"+2 seconds", - p.as_str().unwrap().to_owned()]) - .expect("failed to exec `touch`").status.success() { - let _ = cond.raise((pkg_src_dir.clone(), ~"Bad path")); - } - } - } -} - -#[cfg(not(target_os = "linux"))] -fn touch_source_file(workspace: &Path, crateid: &CrateId) { - use conditions::bad_path::cond; - let pkg_src_dir = workspace.join_many([~"src", crateid.short_name_with_version()]); - let contents = fs::readdir(&pkg_src_dir); - for p in contents.iter() { - if p.extension_str() == Some("rs") { - // should be able to do this w/o a process - // FIXME (#9639): This needs to handle non-utf8 paths - // n.b. Bumps time up by 2 seconds to get around granularity issues - if !run::process_output("touch", [~"-A02", - p.as_str().unwrap().to_owned()]) - .expect("failed to exec `touch`").status.success() { - let _ = cond.raise((pkg_src_dir.clone(), ~"Bad path")); - } - } - } -} - -/// Add a comment at the end -fn frob_source_file(workspace: &Path, crateid: &CrateId, filename: &str) { - use conditions::bad_path::cond; - let pkg_src_dir = workspace.join_many([~"src", crateid.short_name_with_version()]); - let mut maybe_p = None; - let maybe_file = pkg_src_dir.join(filename); - debug!("Trying to frob {} -- {}", pkg_src_dir.display(), filename); - if maybe_file.exists() { - maybe_p = Some(maybe_file); - } - debug!("Frobbed? {:?}", maybe_p); - match maybe_p { - Some(ref p) => { - io::io_error::cond.trap(|e| { - cond.raise((p.clone(), format!("Bad path: {}", e.desc))); - }).inside(|| { - let mut w = File::open_mode(p, io::Append, io::Write); - w.write(bytes!("/* hi */\n")); - }) - } - None => fail!("frob_source_file failed to find a source file in {}", - pkg_src_dir.display()) - } -} - -#[test] -fn test_make_dir_rwx() { - let temp = &os::tmpdir(); - let dir = temp.join("quux"); - if dir.exists() { - fs::rmdir_recursive(&dir); - } - debug!("Trying to make {}", dir.display()); - assert!(make_dir_rwx(&dir)); - assert!(dir.is_dir()); - assert!(is_rwx(&dir)); - fs::rmdir_recursive(&dir); -} - -// n.b. I ignored the next two tests for now because something funny happens on linux -// and I don't want to debug the issue right now (calling into the rustpkg lib directly -// is a little sketchy anyway) -#[test] -#[ignore] -fn test_install_valid() { - use path_util::installed_library_in_workspace; - - let sysroot = test_sysroot(); - debug!("sysroot = {}", sysroot.display()); - let temp_pkg_id = fake_pkg(); - let (temp_workspace, _pkg_dir) = mk_temp_workspace(&temp_pkg_id); - let temp_workspace = temp_workspace.path(); - let ctxt = fake_ctxt(sysroot, temp_workspace); - debug!("temp_workspace = {}", temp_workspace.display()); - // should have test, bench, lib, and main - let src = PkgSrc::new(temp_workspace.clone(), - temp_workspace.clone(), - false, - temp_pkg_id.clone()); - ctxt.install(src, &WhatToBuild::new(MaybeCustom, Everything)); - // Check that all files exist - let exec = target_executable_in_workspace(&temp_pkg_id, temp_workspace); - debug!("exec = {}", exec.display()); - assert!(exec.exists()); - assert!(is_rwx(&exec)); - - let lib = installed_library_in_workspace(&temp_pkg_id, temp_workspace); - debug!("lib = {:?}", lib); - assert!(lib.as_ref().map_or(false, |l| l.exists())); - assert!(lib.as_ref().map_or(false, |l| is_rwx(l))); - - // And that the test and bench executables aren't installed - assert!(!target_test_in_workspace(&temp_pkg_id, temp_workspace).exists()); - let bench = target_bench_in_workspace(&temp_pkg_id, temp_workspace); - debug!("bench = {}", bench.display()); - assert!(!bench.exists()); - - // Make sure the db isn't dirty, so that it doesn't try to save() - // asynchronously after the temporary directory that it wants to save - // to has been deleted. - ctxt.workcache_context.db.write(|db| db.db_dirty = false); -} - -#[test] -#[ignore] -fn test_install_invalid() { - let sysroot = test_sysroot(); - let crateid = fake_pkg(); - let temp_workspace = TempDir::new("test").expect("couldn't create temp dir"); - let temp_workspace = temp_workspace.path().clone(); - let ctxt = fake_ctxt(sysroot, &temp_workspace); - - // Uses task::try because of #9001 - let result = task::try(proc() { - let pkg_src = PkgSrc::new(temp_workspace.clone(), - temp_workspace.clone(), - false, - crateid.clone()); - ctxt.install(pkg_src, &WhatToBuild::new(MaybeCustom, Everything)); - }); - assert!(result.unwrap_err() - .to_str().contains("supplied path for package dir does not exist")); -} - -#[test] -fn test_install_valid_external() { - let temp_pkg_id: CrateId = from_str("foo").unwrap(); - let (tempdir, _) = mk_temp_workspace(&temp_pkg_id); - let temp_workspace = tempdir.path(); - command_line_test([~"install", ~"foo"], temp_workspace); - - // Check that all files exist - let exec = target_executable_in_workspace(&temp_pkg_id, temp_workspace); - debug!("exec = {}", exec.display()); - assert!(exec.exists()); - assert!(is_rwx(&exec)); - - let lib = installed_library_in_workspace(&temp_pkg_id, temp_workspace); - debug!("lib = {:?}", lib); - assert!(lib.as_ref().map_or(false, |l| l.exists())); - - // And that the test and bench executables aren't installed - assert!(!target_test_in_workspace(&temp_pkg_id, temp_workspace).exists()); - let bench = target_bench_in_workspace(&temp_pkg_id, temp_workspace); - debug!("bench = {}", bench.display()); - assert!(!bench.exists()); - -} - -#[test] -#[ignore(reason = "9994")] -fn test_install_invalid_external() { - let cwd = os::getcwd(); - command_line_test_expect_fail([~"install", ~"foo"], - &cwd, - None, - // FIXME #3408: Should be NONEXISTENT_PACKAGE_CODE - COPY_FAILED_CODE); -} - -#[test] -fn test_install_git() { - let temp_pkg_id = git_repo_pkg(); - let path = Path::new(temp_pkg_id.path.as_slice()); - let repo = init_git_repo(&path); - let repo = repo.path(); - debug!("repo = {}", repo.display()); - let repo_subdir = repo.join_many(["mockgithub.com", "catamorphism", "test-pkg"]); - debug!("repo_subdir = {}", repo_subdir.display()); - - writeFile(&repo_subdir.join("main.rs"), - "fn main() { let _x = (); }"); - writeFile(&repo_subdir.join("lib.rs"), - "pub fn f() { let _x = (); }"); - writeFile(&repo_subdir.join("test.rs"), - "#[test] pub fn f() { (); }"); - writeFile(&repo_subdir.join("bench.rs"), - "#[bench] pub fn f() { (); }"); - add_git_tag(&repo_subdir, ~"0.1"); // this has the effect of committing the files - - debug!("test_install_git: calling rustpkg install {} in {}", - temp_pkg_id.path, repo.display()); - // should have test, bench, lib, and main - command_line_test([~"install", temp_pkg_id.path.to_owned()], repo); - let ws = repo.join(".rust"); - // Check that all files exist - debug!("Checking for files in {}", ws.display()); - let exec = target_executable_in_workspace(&temp_pkg_id, &ws); - debug!("exec = {}", exec.display()); - assert!(exec.exists()); - assert!(is_rwx(&exec)); - let _built_lib = - built_library_in_workspace(&temp_pkg_id, - &ws).expect("test_install_git: built lib should exist"); - assert_lib_exists(&ws, &temp_pkg_id); - let built_test = built_test_in_workspace(&temp_pkg_id, - &ws).expect("test_install_git: built test should exist"); - assert!(built_test.exists()); - let built_bench = built_bench_in_workspace(&temp_pkg_id, - &ws).expect("test_install_git: built bench should exist"); - assert!(built_bench.exists()); - // And that the test and bench executables aren't installed - let test = target_test_in_workspace(&temp_pkg_id, &ws); - assert!(!test.exists()); - debug!("test = {}", test.display()); - let bench = target_bench_in_workspace(&temp_pkg_id, &ws); - debug!("bench = {}", bench.display()); - assert!(!bench.exists()); -} - -#[test] -fn test_crate_ids_must_be_relative_path_like() { - /* - Okay: - - One identifier, with no slashes - - Several slash-delimited things, with no / at the root - - Not okay: - - Empty string - - Absolute path (as per os::is_absolute) - - */ - - let foo: CrateId = from_str("foo").unwrap(); - assert_eq!(~"foo#0.0", foo.to_str()); - let test_pkg: CrateId = from_str("github.com/catamorphism/test-pkg").unwrap(); - assert_eq!(~"github.com/catamorphism/test-pkg#0.0", test_pkg.to_str()); - - let x: Option = from_str(""); - assert_eq!(x, None); - - let z: Option = from_str("/foo/bar/quux"); - assert_eq!(z, None); -} - -#[test] -fn test_package_request_version() { - let local_path = "mockgithub.com/catamorphism/test_pkg_version"; - let repo = init_git_repo(&Path::new(local_path)); - let repo = repo.path(); - let repo_subdir = repo.join_many(["mockgithub.com", "catamorphism", "test_pkg_version"]); - debug!("Writing files in: {}", repo_subdir.display()); - writeFile(&repo_subdir.join("main.rs"), - "fn main() { let _x = (); }"); - writeFile(&repo_subdir.join("lib.rs"), - "pub fn f() { let _x = (); }"); - writeFile(&repo_subdir.join("test.rs"), - "#[test] pub fn f() { (); }"); - writeFile(&repo_subdir.join("bench.rs"), - "#[bench] pub fn f() { (); }"); - writeFile(&repo_subdir.join("version-0.3-file.txt"), "hi"); - add_git_tag(&repo_subdir, ~"0.3"); - writeFile(&repo_subdir.join("version-0.4-file.txt"), "hello"); - add_git_tag(&repo_subdir, ~"0.4"); - - command_line_test([~"install", format!("{}\\#0.3", local_path)], repo); - - let crate_id = from_str(format!("{}\\#0.3", local_path)).unwrap(); - assert!(match installed_library_in_workspace(&crate_id, - &repo.join(".rust")) { - Some(p) => { - debug!("installed: {}", p.display()); - let suffix = format!("0.3{}", os::consts::DLL_SUFFIX); - p.as_vec().ends_with(suffix.as_bytes()) || - p.as_vec().ends_with(bytes!("0.3.rlib")) - } - None => false - }); - let temp_pkg_id = from_str("mockgithub.com/catamorphism/test_pkg_version#0.3").unwrap(); - assert!(target_executable_in_workspace(&temp_pkg_id, &repo.join(".rust")) - == repo.join_many([".rust", "bin", "test_pkg_version"])); - - let mut dir = target_build_dir(&repo.join(".rust")); - dir.push(&Path::new("src/mockgithub.com/catamorphism/test_pkg_version-0.3")); - debug!("dir = {}", dir.display()); - assert!(dir.is_dir()); - assert!(dir.join("version-0.3-file.txt").exists()); - assert!(!dir.join("version-0.4-file.txt").exists()); -} - -#[test] -#[ignore (reason = "http-client not ported to rustpkg yet")] -fn rustpkg_install_url_2() { - let temp_dir = TempDir::new("rustpkg_install_url_2").expect("rustpkg_install_url_2"); - command_line_test([~"install", ~"github.com/mozilla-servo/rust-http-client"], - temp_dir.path()); -} - -#[test] -fn rustpkg_library_target() { - let foo_repo = init_git_repo(&Path::new("foo")); - let foo_repo = foo_repo.path(); - let package_dir = foo_repo.join("foo"); - - debug!("Writing files in: {}", package_dir.display()); - writeFile(&package_dir.join("main.rs"), - "fn main() { let _x = (); }"); - writeFile(&package_dir.join("lib.rs"), - "pub fn f() { let _x = (); }"); - writeFile(&package_dir.join("test.rs"), - "#[test] pub fn f() { (); }"); - writeFile(&package_dir.join("bench.rs"), - "#[bench] pub fn f() { (); }"); - add_git_tag(&package_dir, ~"0.0"); - - command_line_test([~"install", ~"foo"], foo_repo); - let crate_id: CrateId = from_str("foo").unwrap(); - assert_lib_exists(&foo_repo.join(".rust"), &crate_id); -} - -#[test] -fn rustpkg_local_pkg() { - let crate_id: CrateId = from_str("foo").unwrap(); - let dir = create_local_package(&crate_id); - command_line_test([~"install", ~"foo"], dir.path()); - assert_executable_exists(dir.path(), "foo"); -} - -#[test] -#[ignore(reason="busted")] -fn package_script_with_default_build() { - let crate_id: CrateId = from_str("fancy-lib").unwrap(); - let dir = create_local_package(&crate_id); - let dir = dir.path(); - debug!("dir = {}", dir.display()); - let mut source = test_sysroot().dir_path(); - source.pop(); source.pop(); - let source = Path::new(file!()).dir_path().join_many( - [~"testsuite", ~"pass", ~"src", ~"fancy-lib", ~"pkg.rs"]); - debug!("package_script_with_default_build: {}", source.display()); - fs::copy(&source, &dir.join_many(["src", "fancy-lib-0.0", "pkg.rs"])); - command_line_test([~"install", ~"fancy-lib"], dir); - assert_lib_exists(dir, &crate_id); - assert!(target_build_dir(dir).join_many([~"fancy-lib", ~"generated.rs"]).exists()); - let generated_path = target_build_dir(dir).join_many([~"fancy-lib", ~"generated.rs"]); - debug!("generated path = {}", generated_path.display()); - assert!(generated_path.exists()); -} - -#[test] -fn rustpkg_build_no_arg() { - let tmp = TempDir::new("rustpkg_build_no_arg").expect("rustpkg_build_no_arg failed"); - let tmp = tmp.path().join(".rust"); - let package_dir = tmp.join_many(["src", "foo"]); - fs::mkdir_recursive(&package_dir, io::UserRWX); - - writeFile(&package_dir.join("main.rs"), - "fn main() { let _x = (); }"); - debug!("build_no_arg: dir = {}", package_dir.display()); - command_line_test([~"build"], &package_dir); - assert_built_executable_exists(&tmp, "foo"); -} - -#[test] -fn rustpkg_install_no_arg() { - let tmp = TempDir::new("rustpkg_install_no_arg").expect("rustpkg_install_no_arg failed"); - let tmp = tmp.path().join(".rust"); - let package_dir = tmp.join_many(["src", "foo"]); - fs::mkdir_recursive(&package_dir, io::UserRWX); - writeFile(&package_dir.join("lib.rs"), - "fn main() { let _x = (); }"); - debug!("install_no_arg: dir = {}", package_dir.display()); - command_line_test([~"install"], &package_dir); - let crate_id: CrateId = from_str("foo").unwrap(); - assert_lib_exists(&tmp, &crate_id); -} - -#[test] -fn rustpkg_clean_no_arg() { - let tmp = TempDir::new("rustpkg_clean_no_arg").expect("rustpkg_clean_no_arg failed"); - let tmp = tmp.path().join(".rust"); - let package_dir = tmp.join_many(["src", "foo"]); - fs::mkdir_recursive(&package_dir, io::UserRWX); - - writeFile(&package_dir.join("main.rs"), - "fn main() { let _x = (); }"); - debug!("clean_no_arg: dir = {}", package_dir.display()); - command_line_test([~"build"], &package_dir); - assert_built_executable_exists(&tmp, "foo"); - command_line_test([~"clean"], &package_dir); - let crate_id: CrateId = from_str("foo").unwrap(); - let res = built_executable_in_workspace(&crate_id, &tmp); - assert!(!res.as_ref().map_or(false, |m| m.exists())); -} - -#[test] -fn rust_path_test() { - let dir_for_path = TempDir::new("more_rust").expect("rust_path_test failed"); - let crate_id: CrateId = from_str("foo").unwrap(); - let dir = mk_workspace(dir_for_path.path(), &crate_id); - debug!("dir = {}", dir.display()); - writeFile(&dir.join("main.rs"), "fn main() { let _x = (); }"); - - let cwd = os::getcwd(); - debug!("cwd = {}", cwd.display()); - // use command_line_test_with_env - // FIXME (#9639): This needs to handle non-utf8 paths - command_line_test_with_env([~"install", ~"foo"], - &cwd, - Some(~[(~"RUST_PATH", - dir_for_path.path().as_str().unwrap().to_owned())])); - assert_executable_exists(dir_for_path.path(), "foo"); -} - -#[test] -#[ignore] // FIXME(#9184) tests can't change the cwd (other tests are sad then) -fn rust_path_contents() { - let dir = TempDir::new("rust_path").expect("rust_path_contents failed"); - let abc = &dir.path().join_many(["A", "B", "C"]); - fs::mkdir_recursive(&abc.join(".rust"), io::UserRWX); - fs::mkdir_recursive(&abc.with_filename(".rust"), io::UserRWX); - fs::mkdir_recursive(&abc.dir_path().with_filename(".rust"), io::UserRWX); - assert!(os::change_dir(abc)); - - let p = rust_path(); - let cwd = os::getcwd().join(".rust"); - let parent = cwd.dir_path().with_filename(".rust"); - let grandparent = cwd.dir_path().dir_path().with_filename(".rust"); - assert!(p.contains(&cwd)); - assert!(p.contains(&parent)); - assert!(p.contains(&grandparent)); - for a_path in p.iter() { - assert!(a_path.filename().is_some()); - } -} - -#[test] -fn rust_path_parse() { - os::setenv("RUST_PATH", "/a/b/c:/d/e/f:/g/h/i"); - let paths = rust_path(); - assert!(paths.contains(&Path::new("/g/h/i"))); - assert!(paths.contains(&Path::new("/d/e/f"))); - assert!(paths.contains(&Path::new("/a/b/c"))); - os::unsetenv("RUST_PATH"); -} - -#[test] -fn test_list() { - let dir = TempDir::new("test_list").expect("test_list failed"); - let dir = dir.path(); - let foo: CrateId = from_str("foo").unwrap(); - create_local_package_in(&foo, dir); - let bar: CrateId = from_str("bar").unwrap(); - create_local_package_in(&bar, dir); - let quux: CrateId = from_str("quux").unwrap(); - create_local_package_in(&quux, dir); - -// list doesn't output very much right now... - command_line_test([~"install", ~"foo"], dir); - // FIXME (#9639): This needs to handle non-utf8 paths - let env_arg = ~[(~"RUST_PATH", dir.as_str().unwrap().to_owned())]; - let list_output = command_line_test_output_with_env([~"list"], env_arg.clone()); - assert!(list_output.iter().any(|x| x.starts_with("foo"))); - - command_line_test([~"install", ~"bar"], dir); - let list_output = command_line_test_output_with_env([~"list"], env_arg.clone()); - assert!(list_output.iter().any(|x| x.starts_with("foo"))); - assert!(list_output.iter().any(|x| x.starts_with("bar"))); - - command_line_test([~"install", ~"quux"], dir); - let list_output = command_line_test_output_with_env([~"list"], env_arg); - assert!(list_output.iter().any(|x| x.starts_with("foo"))); - assert!(list_output.iter().any(|x| x.starts_with("bar"))); - assert!(list_output.iter().any(|x| x.starts_with("quux"))); -} - -#[test] -fn install_remove() { - let dir = TempDir::new("install_remove").expect("install_remove"); - let dir = dir.path(); - let foo: CrateId = from_str("foo").unwrap(); - let bar: CrateId = from_str("bar").unwrap(); - let quux: CrateId = from_str("quux").unwrap(); - create_local_package_in(&foo, dir); - create_local_package_in(&bar, dir); - create_local_package_in(&quux, dir); - // FIXME (#9639): This needs to handle non-utf8 paths - let rust_path_to_use = ~[(~"RUST_PATH", dir.as_str().unwrap().to_owned())]; - command_line_test([~"install", ~"foo"], dir); - command_line_test([~"install", ~"bar"], dir); - command_line_test([~"install", ~"quux"], dir); - let list_output = command_line_test_output_with_env([~"list"], rust_path_to_use.clone()); - assert!(list_output.iter().any(|x| x.starts_with("foo"))); - assert!(list_output.iter().any(|x| x.starts_with("bar"))); - assert!(list_output.iter().any(|x| x.starts_with("quux"))); - command_line_test([~"uninstall", ~"foo"], dir); - let list_output = command_line_test_output_with_env([~"list"], rust_path_to_use.clone()); - assert!(!list_output.iter().any(|x| x.starts_with("foo"))); - assert!(list_output.iter().any(|x| x.starts_with("bar"))); - assert!(list_output.iter().any(|x| x.starts_with("quux"))); -} - -#[test] -fn install_check_duplicates() { - // should check that we don't install two packages with the same full name *and* version - // ("Is already installed -- doing nothing") - // check invariant that there are no dups in the pkg database - let dir = TempDir::new("install_remove").expect("install_remove"); - let dir = dir.path(); - let foo: CrateId = from_str("foo").unwrap(); - create_local_package_in(&foo, dir); - - command_line_test([~"install", ~"foo"], dir); - command_line_test([~"install", ~"foo"], dir); - let mut contents = ~[]; - let check_dups = |p: &CrateId| { - if contents.contains(p) { - fail!("package {} appears in `list` output more than once", p.path); - } - else { - contents.push((*p).clone()); - } - true - }; - list_installed_packages(check_dups); -} - -#[test] -fn no_rebuilding() { - let p_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package(&p_id); - let workspace = workspace.path(); - command_line_test([~"build", ~"foo"], workspace); - let foo_lib = lib_output_file_name(workspace, "foo"); - // Now make `foo` read-only so that subsequent rebuilds of it will fail - assert!(chmod_read_only(&foo_lib)); - - command_line_test([~"build", ~"foo"], workspace); - - match command_line_test_partial([~"build", ~"foo"], workspace) { - Success(..) => (), // ok - Fail(ref status) if status.status.matches_exit_status(65) => - fail!("no_rebuilding failed: it tried to rebuild bar"), - Fail(_) => fail!("no_rebuilding failed for some other reason") - } -} - -#[test] -#[ignore] -fn no_recopying() { - let p_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package(&p_id); - let workspace = workspace.path(); - command_line_test([~"install", ~"foo"], workspace); - let foo_lib = installed_library_in_workspace(&p_id, workspace); - assert!(foo_lib.is_some()); - // Now make `foo` read-only so that subsequent attempts to copy to it will fail - assert!(chmod_read_only(&foo_lib.unwrap())); - - match command_line_test_partial([~"install", ~"foo"], workspace) { - Success(..) => (), // ok - Fail(ref status) if status.status.matches_exit_status(65) => - fail!("no_recopying failed: it tried to re-copy foo"), - Fail(_) => fail!("no_copying failed for some other reason") - } -} - -#[test] -fn no_rebuilding_dep() { - let p_id: CrateId = from_str("foo").unwrap(); - let dep_id: CrateId = from_str("bar").unwrap(); - let workspace = create_local_package_with_dep(&p_id, &dep_id); - let workspace = workspace.path(); - command_line_test([~"build", ~"foo"], workspace); - let bar_lib = lib_output_file_name(workspace, "bar"); - frob_source_file(workspace, &p_id, "main.rs"); - // Now make `bar` read-only so that subsequent rebuilds of it will fail - assert!(chmod_read_only(&bar_lib)); - match command_line_test_partial([~"build", ~"foo"], workspace) { - Success(..) => (), // ok - Fail(ref r) if r.status.matches_exit_status(65) => - fail!("no_rebuilding_dep failed: it tried to rebuild bar"), - Fail(_) => fail!("no_rebuilding_dep failed for some other reason") - } -} - -#[test] -fn do_rebuild_dep_dates_change() { - let p_id: CrateId = from_str("foo").unwrap(); - let dep_id: CrateId = from_str("bar").unwrap(); - let workspace = create_local_package_with_dep(&p_id, &dep_id); - let workspace = workspace.path(); - command_line_test([~"build", ~"foo"], workspace); - let bar_lib_name = lib_output_file_name(workspace, "bar"); - touch_source_file(workspace, &dep_id); - - // Now make `bar` read-only so that subsequent rebuilds of it will fail - assert!(chmod_read_only(&bar_lib_name)); - - match command_line_test_partial([~"build", ~"foo"], workspace) { - Success(..) => fail!("do_rebuild_dep_dates_change failed: it didn't rebuild bar"), - Fail(ref r) if r.status.matches_exit_status(65) => (), // ok - Fail(_) => fail!("do_rebuild_dep_dates_change failed for some other reason") - } -} - -#[test] -fn do_rebuild_dep_only_contents_change() { - let p_id: CrateId = from_str("foo").unwrap(); - let dep_id: CrateId = from_str("bar").unwrap(); - let workspace = create_local_package_with_dep(&p_id, &dep_id); - let workspace = workspace.path(); - command_line_test([~"build", ~"foo"], workspace); - frob_source_file(workspace, &dep_id, "lib.rs"); - let bar_lib_name = lib_output_file_name(workspace, "bar"); - - // Now make `bar` read-only so that subsequent rebuilds of it will fail - assert!(chmod_read_only(&bar_lib_name)); - - // should adjust the datestamp - match command_line_test_partial([~"build", ~"foo"], workspace) { - Success(..) => fail!("do_rebuild_dep_only_contents_change failed: it didn't rebuild bar"), - Fail(ref r) if r.status.matches_exit_status(65) => (), // ok - Fail(_) => fail!("do_rebuild_dep_only_contents_change failed for some other reason") - } -} - -#[test] -fn test_versions() { - let foo_01: CrateId = from_str("foo#0.1").unwrap(); - let foo_02: CrateId = from_str("foo#0.2").unwrap(); - let workspace = create_local_package(&foo_01); - let _other_workspace = create_local_package(&foo_02); - command_line_test([~"install", ~"foo#0.1"], workspace.path()); - let output = command_line_test_output([~"list"]); - // make sure output includes versions - assert!(!output.iter().any(|x| x == &~"foo#0.2")); -} - -#[test] -#[ignore(reason = "do not yet implemented")] -fn test_build_hooks() { - let crate_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package_with_custom_build_hook(&crate_id, - "frob"); - command_line_test([~"do", ~"foo", ~"frob"], workspace.path()); -} - - -#[test] -#[ignore(reason = "info not yet implemented")] -fn test_info() { - let expected_info = ~"package foo"; // fill in - let crate_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package(&crate_id); - let output = command_line_test([~"info", ~"foo"], workspace.path()); - assert_eq!(str::from_utf8_owned(output.output).unwrap(), expected_info); -} - -#[test] -fn test_uninstall() { - let crate_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package(&crate_id); - command_line_test([~"uninstall", ~"foo"], workspace.path()); - let output = command_line_test([~"list"], workspace.path()); - assert!(!str::from_utf8(output.output).unwrap().contains("foo")); -} - -#[test] -fn test_non_numeric_tag() { - let temp_pkg_id = git_repo_pkg(); - let repo = init_git_repo(&Path::new(temp_pkg_id.path.as_slice())); - let repo = repo.path(); - let repo_subdir = repo.join_many(["mockgithub.com", "catamorphism", "test-pkg"]); - writeFile(&repo_subdir.join("foo"), "foo"); - writeFile(&repo_subdir.join("lib.rs"), - "pub fn f() { let _x = (); }"); - add_git_tag(&repo_subdir, ~"testbranch"); - writeFile(&repo_subdir.join("testbranch_only"), "hello"); - add_git_tag(&repo_subdir, ~"another_tag"); - writeFile(&repo_subdir.join("not_on_testbranch_only"), "bye bye"); - add_all_and_commit(&repo_subdir); - - command_line_test([~"install", format!("{}\\#testbranch", temp_pkg_id.path)], repo); - let file1 = repo.join_many(["mockgithub.com", "catamorphism", "test-pkg", "testbranch_only"]); - let file2 = repo.join_many(["mockgithub.com", "catamorphism", "test-pkg", "master_only"]); - assert!(file1.exists()); - assert!(!file2.exists()); -} - -#[test] -fn test_extern_mod() { - let dir = TempDir::new("test_extern_mod").expect("test_extern_mod"); - let dir = dir.path(); - let main_file = dir.join("main.rs"); - let lib_depend_dir = TempDir::new("foo").expect("test_extern_mod"); - let lib_depend_dir = lib_depend_dir.path(); - let aux_dir = lib_depend_dir.join_many(["src", "mockgithub.com", "catamorphism", "test_pkg"]); - fs::mkdir_recursive(&aux_dir, io::UserRWX); - let aux_pkg_file = aux_dir.join("lib.rs"); - - writeFile(&aux_pkg_file, "pub mod bar { pub fn assert_true() { assert!(true); } }\n"); - assert!(aux_pkg_file.exists()); - - writeFile(&main_file, - "extern mod test = \"mockgithub.com/catamorphism/test_pkg\";\nuse test::bar;\ - fn main() { bar::assert_true(); }\n"); - - command_line_test([~"install", ~"mockgithub.com/catamorphism/test_pkg"], lib_depend_dir); - - let exec_file = dir.join("out"); - // Be sure to extend the existing environment - // FIXME (#9639): This needs to handle non-utf8 paths - let env = Some([(~"RUST_PATH", lib_depend_dir.as_str().unwrap().to_owned())] + os::env()); - let rustpkg_exec = rustpkg_exec(); - let rustc = rustpkg_exec.with_filename("rustc"); - - let test_sys = test_sysroot(); - // FIXME (#9639): This needs to handle non-utf8 paths - let mut prog = run::Process::new(rustc.as_str().unwrap(), - [main_file.as_str().unwrap().to_owned(), - ~"--sysroot", test_sys.as_str().unwrap().to_owned(), - ~"-o", exec_file.as_str().unwrap().to_owned()], - run::ProcessOptions { - env: env, - dir: Some(dir), - in_fd: None, - out_fd: None, - err_fd: None - }).expect(format!("failed to exec `{}`", rustc.as_str().unwrap())); - let outp = prog.finish_with_output(); - if !outp.status.success() { - fail!("output was {}, error was {}", - str::from_utf8(outp.output).unwrap(), - str::from_utf8(outp.error).unwrap()); - } - assert!(exec_file.exists() && is_executable(&exec_file)); -} - -#[test] -fn test_extern_mod_simpler() { - let dir = TempDir::new("test_extern_mod_simpler").expect("test_extern_mod_simpler"); - let dir = dir.path(); - let main_file = dir.join("main.rs"); - let lib_depend_dir = TempDir::new("foo").expect("test_extern_mod_simpler"); - let lib_depend_dir = lib_depend_dir.path(); - let aux_dir = lib_depend_dir.join_many(["src", "rust-awesomeness"]); - fs::mkdir_recursive(&aux_dir, io::UserRWX); - let aux_pkg_file = aux_dir.join("lib.rs"); - - writeFile(&aux_pkg_file, "pub mod bar { pub fn assert_true() { assert!(true); } }\n"); - assert!(aux_pkg_file.exists()); - - writeFile(&main_file, - "extern mod test = \"rust-awesomeness\";\nuse test::bar;\ - fn main() { bar::assert_true(); }\n"); - - command_line_test([~"install", ~"rust-awesomeness"], lib_depend_dir); - - let exec_file = dir.join("out"); - // Be sure to extend the existing environment - // FIXME (#9639): This needs to handle non-utf8 paths - let env = Some([(~"RUST_PATH", lib_depend_dir.as_str().unwrap().to_owned())] + os::env()); - let rustpkg_exec = rustpkg_exec(); - let rustc = rustpkg_exec.with_filename("rustc"); - let test_sys = test_sysroot(); - debug!("RUST_PATH={} {} {} \n --sysroot {} -o {}", - lib_depend_dir.display(), - rustc.display(), - main_file.display(), - test_sys.display(), - exec_file.display()); - - // FIXME (#9639): This needs to handle non-utf8 paths - let mut prog = run::Process::new(rustc.as_str().unwrap(), - [main_file.as_str().unwrap().to_owned(), - ~"--sysroot", test_sys.as_str().unwrap().to_owned(), - ~"-o", exec_file.as_str().unwrap().to_owned()], - run::ProcessOptions { - env: env, - dir: Some(dir), - in_fd: None, - out_fd: None, - err_fd: None - }).expect(format!("failed to exec `{}`", rustc.as_str().unwrap())); - let outp = prog.finish_with_output(); - if !outp.status.success() { - fail!("output was {}, error was {}", - str::from_utf8(outp.output).unwrap(), - str::from_utf8(outp.error).unwrap()); - } - assert!(exec_file.exists() && is_executable(&exec_file)); -} - -#[test] -fn test_import_rustpkg() { - let p_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package(&p_id); - let workspace = workspace.path(); - writeFile(&workspace.join_many(["src", "foo-0.0", "pkg.rs"]), - "extern mod rustpkg; fn main() {}"); - command_line_test([~"build", ~"foo"], workspace); - debug!("workspace = {}", workspace.display()); - assert!(target_build_dir(workspace).join("foo").join(format!("pkg{}", - os::consts::EXE_SUFFIX)).exists()); -} - -#[test] -fn test_macro_pkg_script() { - let p_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package(&p_id); - let workspace = workspace.path(); - writeFile(&workspace.join_many(["src", "foo-0.0", "pkg.rs"]), - "extern mod rustpkg; fn main() { debug!(\"Hi\"); }"); - command_line_test([~"build", ~"foo"], workspace); - debug!("workspace = {}", workspace.display()); - assert!(target_build_dir(workspace).join("foo").join(format!("pkg{}", - os::consts::EXE_SUFFIX)).exists()); -} - -#[test] -fn multiple_workspaces() { -// Make a package foo; build/install in directory A -// Copy the exact same package into directory B and install it -// Set the RUST_PATH to A:B -// Make a third package that uses foo, make sure we can build/install it - let p_id: CrateId = from_str("foo").unwrap(); - let bar_p_id: CrateId = from_str("bar").unwrap(); - let (a_loc, _pkg_dir) = mk_temp_workspace(&p_id); - let (b_loc, _pkg_dir) = mk_temp_workspace(&p_id); - let (a_loc, b_loc) = (a_loc.path(), b_loc.path()); - debug!("Trying to install foo in {}", a_loc.display()); - command_line_test([~"install", ~"foo"], a_loc); - debug!("Trying to install foo in {}", b_loc.display()); - command_line_test([~"install", ~"foo"], b_loc); - // FIXME (#9639): This needs to handle non-utf8 paths - let env = Some(~[(~"RUST_PATH", format!("{}:{}", a_loc.as_str().unwrap(), - b_loc.as_str().unwrap()))]); - let c_loc = create_local_package_with_dep(&bar_p_id, &p_id); - command_line_test_with_env([~"install", ~"bar"], c_loc.path(), env); -} - -fn rust_path_hack_test(hack_flag: bool) { -/* - Make a workspace containing a pkg foo [A] - Make a second, empty workspace [B] - Set RUST_PATH to B:A - rustpkg install foo - make sure built files for foo are in B - make sure nothing gets built into A or A/../build[lib,bin] -*/ - let p_id: CrateId = from_str("foo").unwrap(); - let bar_p_id: CrateId = from_str("bar").unwrap(); - let workspace = create_local_package(&p_id); - let workspace = workspace.path(); - let dest_workspace = mk_empty_workspace(&bar_p_id, "dest_workspace"); - let dest_workspace = dest_workspace.path(); - let foo_path = workspace.join_many(["src", "foo-0.0"]); - let rust_path = Some(~[(~"RUST_PATH", - format!("{}:{}", - dest_workspace.as_str().unwrap(), - foo_path.as_str().unwrap()))]); - command_line_test_with_env(~[~"install"] + - if hack_flag { ~[~"--rust-path-hack"] } else { ~[] } + ~[~"foo"], - dest_workspace, rust_path); - assert_lib_exists(dest_workspace, &p_id); - assert_executable_exists(dest_workspace, "foo"); - assert_built_library_exists(dest_workspace, "foo"); - assert_built_executable_exists(dest_workspace, "foo"); - assert!(!lib_exists(workspace, &p_id)); - assert!(!executable_exists(workspace, "foo")); - assert!(!built_library_exists(workspace, "foo")); - assert!(!built_executable_exists(workspace, "foo")); -} - -// Notice that this is the only test case where the --rust-path-hack -// flag is actually needed -#[test] -fn test_rust_path_can_contain_package_dirs_with_flag() { -/* - Test that the temporary hack added for bootstrapping Servo builds - works. That is: if you add $FOO/src/some_pkg to the RUST_PATH, - it will find the sources in some_pkg, build them, and install them - into the first entry in the RUST_PATH. - - When the hack is removed, we should change this to a should_fail test. -*/ - rust_path_hack_test(true); -} - -#[test] -#[should_fail] -fn test_rust_path_can_contain_package_dirs_without_flag() { - rust_path_hack_test(false); -} - -#[test] -fn rust_path_hack_cwd() { - // Same as rust_path_hack_test, but the CWD is the dir to build out of - let cwd = TempDir::new("foo").expect("rust_path_hack_cwd"); - let cwd = cwd.path().join("foo"); - fs::mkdir_recursive(&cwd, io::UserRWX); - writeFile(&cwd.join("lib.rs"), "pub fn f() { }"); - let foo_id: CrateId = from_str("foo").unwrap(); - let bar_id: CrateId = from_str("bar").unwrap(); - - let dest_workspace = mk_empty_workspace(&bar_id, "dest_workspace"); - let dest_workspace = dest_workspace.path(); - // FIXME (#9639): This needs to handle non-utf8 paths - let rust_path = Some(~[(~"RUST_PATH", dest_workspace.as_str().unwrap().to_owned())]); - command_line_test_with_env([~"install", ~"--rust-path-hack", ~"foo"], &cwd, rust_path); - debug!("Checking that foo exists in {}", dest_workspace.display()); - assert_lib_exists(dest_workspace, &foo_id); - assert_built_library_exists(dest_workspace, "foo"); - assert!(!lib_exists(&cwd, &foo_id)); - assert!(!built_library_exists(&cwd, "foo")); -} - -#[test] -fn rust_path_hack_multi_path() { - // Same as rust_path_hack_test, but with a more complex package ID - let cwd = TempDir::new("pkg_files").expect("rust_path_hack_cwd"); - let subdir = cwd.path().join_many(["foo", "bar", "quux"]); - fs::mkdir_recursive(&subdir, io::UserRWX); - writeFile(&subdir.join("lib.rs"), "pub fn f() { }"); - let name = ~"foo/bar/quux"; - let foo_id: CrateId = from_str("foo/bar/quux").unwrap(); - let bar_id: CrateId = from_str("bar").unwrap(); - - let dest_workspace = mk_empty_workspace(&bar_id, "dest_workspace"); - let dest_workspace = dest_workspace.path(); - // FIXME (#9639): This needs to handle non-utf8 paths - let rust_path = Some(~[(~"RUST_PATH", dest_workspace.as_str().unwrap().to_owned())]); - command_line_test_with_env([~"install", ~"--rust-path-hack", name.clone()], &subdir, rust_path); - debug!("Checking that {} exists in {}", name, dest_workspace.display()); - assert_lib_exists(dest_workspace, &foo_id); - assert_built_library_exists(dest_workspace, name); - assert!(!lib_exists(&subdir, &foo_id)); - assert!(!built_library_exists(&subdir, name)); -} - -#[test] -fn rust_path_hack_install_no_arg() { - // Same as rust_path_hack_cwd, but making rustpkg infer the pkg id - let cwd = TempDir::new("pkg_files").expect("rust_path_hack_install_no_arg"); - let cwd = cwd.path(); - let source_dir = cwd.join("foo"); - assert!(make_dir_rwx(&source_dir)); - writeFile(&source_dir.join("lib.rs"), "pub fn f() { }"); - - let foo_id: CrateId = from_str("foo").unwrap(); - let bar_id: CrateId = from_str("bar").unwrap(); - let dest_workspace = mk_empty_workspace(&bar_id, "dest_workspace"); - let dest_workspace = dest_workspace.path(); - // FIXME (#9639): This needs to handle non-utf8 paths - let rust_path = Some(~[(~"RUST_PATH", dest_workspace.as_str().unwrap().to_owned())]); - command_line_test_with_env([~"install", ~"--rust-path-hack"], &source_dir, rust_path); - debug!("Checking that foo exists in {}", dest_workspace.display()); - assert_lib_exists(dest_workspace, &foo_id); - assert_built_library_exists(dest_workspace, "foo"); - assert!(!lib_exists(&source_dir, &foo_id)); - assert!(!built_library_exists(cwd, "foo")); -} - -#[test] -fn rust_path_hack_build_no_arg() { - // Same as rust_path_hack_install_no_arg, but building instead of installing - let cwd = TempDir::new("pkg_files").expect("rust_path_hack_build_no_arg"); - let source_dir = cwd.path().join("foo"); - assert!(make_dir_rwx(&source_dir)); - writeFile(&source_dir.join("lib.rs"), "pub fn f() { }"); - - let bar_id: CrateId = from_str("bar").unwrap(); - let dest_workspace = mk_empty_workspace(&bar_id, "dest_workspace"); - let dest_workspace = dest_workspace.path(); - // FIXME (#9639): This needs to handle non-utf8 paths - let rust_path = Some(~[(~"RUST_PATH", dest_workspace.as_str().unwrap().to_owned())]); - command_line_test_with_env([~"build", ~"--rust-path-hack"], &source_dir, rust_path); - debug!("Checking that foo exists in {}", dest_workspace.display()); - assert_built_library_exists(dest_workspace, "foo"); - assert!(!built_library_exists(&source_dir, "foo")); -} - -#[test] -fn rust_path_hack_build_with_dependency() { - let foo_id: CrateId = from_str("foo").unwrap(); - let dep_id: CrateId = from_str("dep").unwrap(); - // Tests that when --rust-path-hack is in effect, dependencies get built - // into the destination workspace and not the source directory - let work_dir = create_local_package(&foo_id); - let work_dir = work_dir.path(); - let dep_workspace = create_local_package(&dep_id); - let dep_workspace = dep_workspace.path(); - let dest_workspace = mk_emptier_workspace("dep"); - let dest_workspace = dest_workspace.path(); - let source_dir = work_dir.join_many(["src", "foo-0.0"]); - writeFile(&source_dir.join("lib.rs"), "extern mod dep; pub fn f() { }"); - let dep_dir = dep_workspace.join_many(["src", "dep-0.0"]); - let rust_path = Some(~[(~"RUST_PATH", - format!("{}:{}", - dest_workspace.display(), - dep_dir.display()))]); - command_line_test_with_env([~"build", ~"--rust-path-hack", ~"foo"], work_dir, rust_path); - assert_built_library_exists(dest_workspace, "dep"); - assert!(!built_library_exists(dep_workspace, "dep")); -} - -#[test] -fn rust_path_install_target() { - let dir_for_path = TempDir::new( - "source_workspace").expect("rust_path_install_target failed"); - let foo_id: CrateId = from_str("foo").unwrap(); - let mut dir = mk_workspace(dir_for_path.path(), &foo_id); - debug!("dir = {}", dir.display()); - writeFile(&dir.join("main.rs"), "fn main() { let _x = (); }"); - let dir_to_install_to = TempDir::new( - "dest_workspace").expect("rust_path_install_target failed"); - let dir_to_install_to = dir_to_install_to.path(); - dir.pop(); dir.pop(); - - // FIXME (#9639): This needs to handle non-utf8 paths - let rust_path = Some(~[(~"RUST_PATH", format!("{}:{}", - dir_to_install_to.as_str().unwrap(), - dir.as_str().unwrap()))]); - let cwd = os::getcwd(); - command_line_test_with_env([~"install", ~"foo"], - &cwd, - rust_path); - - assert_executable_exists(dir_to_install_to, "foo"); - -} - -#[test] -fn sysroot_flag() { - let p_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package(&p_id); - let workspace = workspace.path(); - // no-op sysroot setting; I'm not sure how else to test this - let test_sys = test_sysroot(); - // FIXME (#9639): This needs to handle non-utf8 paths - command_line_test([~"--sysroot", - test_sys.as_str().unwrap().to_owned(), - ~"build", - ~"foo"], - workspace); - assert_built_executable_exists(workspace, "foo"); -} - -#[test] -fn compile_flag_build() { - let p_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package(&p_id); - let workspace = workspace.path(); - let test_sys = test_sysroot(); - // FIXME (#9639): This needs to handle non-utf8 paths - command_line_test([test_sys.as_str().unwrap().to_owned(), - ~"build", - ~"--no-link", - ~"foo"], - workspace); - assert!(!built_executable_exists(workspace, "foo")); - assert!(object_file_exists(workspace, "foo")); -} - -#[test] -fn compile_flag_fail() { - // --no-link shouldn't be accepted for install - let p_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package(&p_id); - let workspace = workspace.path(); - let test_sys = test_sysroot(); - // FIXME (#9639): This needs to handle non-utf8 paths - command_line_test_expect_fail([test_sys.as_str().unwrap().to_owned(), - ~"install", - ~"--no-link", - ~"foo"], - workspace, None, BAD_FLAG_CODE); - assert!(!built_executable_exists(workspace, "foo")); - assert!(!object_file_exists(workspace, "foo")); -} - -#[test] -fn notrans_flag_build() { - let p_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package(&p_id); - let workspace = workspace.path(); - let flags_to_test = [~"--no-trans", ~"--parse-only", - ~"--pretty", ~"-S"]; - - for flag in flags_to_test.iter() { - let test_sys = test_sysroot(); - // FIXME (#9639): This needs to handle non-utf8 paths - command_line_test([test_sys.as_str().unwrap().to_owned(), - ~"build", - flag.clone(), - ~"foo"], - workspace); - // Ideally we'd test that rustpkg actually succeeds, but - // since task failure doesn't set the exit code properly, - // we can't tell - assert!(!built_executable_exists(workspace, "foo")); - assert!(!object_file_exists(workspace, "foo")); - } -} - -#[test] -fn notrans_flag_fail() { - // --no-trans shouldn't be accepted for install - let p_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package(&p_id); - let workspace = workspace.path(); - let flags_to_test = [~"--no-trans", ~"--parse-only", - ~"--pretty", ~"-S"]; - for flag in flags_to_test.iter() { - let test_sys = test_sysroot(); - // FIXME (#9639): This needs to handle non-utf8 paths - command_line_test_expect_fail([test_sys.as_str().unwrap().to_owned(), - ~"install", - flag.clone(), - ~"foo"], - workspace, None, BAD_FLAG_CODE); - assert!(!built_executable_exists(workspace, "foo")); - assert!(!object_file_exists(workspace, "foo")); - assert!(!lib_exists(workspace, &p_id)); - } -} - -#[test] -fn dash_S() { - let p_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package(&p_id); - let workspace = workspace.path(); - let test_sys = test_sysroot(); - // FIXME (#9639): This needs to handle non-utf8 paths - command_line_test([test_sys.as_str().unwrap().to_owned(), - ~"build", - ~"-S", - ~"foo"], - workspace); - assert!(!built_executable_exists(workspace, "foo")); - assert!(!object_file_exists(workspace, "foo")); - assert!(assembly_file_exists(workspace, "foo")); -} - -#[test] -fn dash_S_fail() { - let p_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package(&p_id); - let workspace = workspace.path(); - let test_sys = test_sysroot(); - // FIXME (#9639): This needs to handle non-utf8 paths - command_line_test_expect_fail([test_sys.as_str().unwrap().to_owned(), - ~"install", - ~"-S", - ~"foo"], - workspace, None, BAD_FLAG_CODE); - assert!(!built_executable_exists(workspace, "foo")); - assert!(!object_file_exists(workspace, "foo")); - assert!(!assembly_file_exists(workspace, "foo")); -} - -#[test] -fn test_cfg_build() { - let p_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package(&p_id); - let workspace = workspace.path(); - // If the cfg flag gets messed up, this won't compile - writeFile(&workspace.join_many(["src", "foo-0.0", "main.rs"]), - "#[cfg(quux)] fn main() {}"); - let test_sys = test_sysroot(); - // FIXME (#9639): This needs to handle non-utf8 paths - command_line_test([test_sys.as_str().unwrap().to_owned(), - ~"build", - ~"--cfg", - ~"quux", - ~"foo"], - workspace); - assert_built_executable_exists(workspace, "foo"); -} - -#[test] -fn test_cfg_fail() { - let p_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package(&p_id); - let workspace = workspace.path(); - writeFile(&workspace.join_many(["src", "foo-0.0", "main.rs"]), - "#[cfg(quux)] fn main() {}"); - let test_sys = test_sysroot(); - // FIXME (#9639): This needs to handle non-utf8 paths - match command_line_test_partial([test_sys.as_str().unwrap().to_owned(), - ~"build", - ~"foo"], - workspace) { - Success(..) => fail!("test_cfg_fail failed"), - _ => () - } -} - - -#[test] -fn test_emit_llvm_S_build() { - let p_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package(&p_id); - let workspace = workspace.path(); - let test_sys = test_sysroot(); - // FIXME (#9639): This needs to handle non-utf8 paths - command_line_test([test_sys.as_str().unwrap().to_owned(), - ~"build", - ~"-S", ~"--emit-llvm", - ~"foo"], - workspace); - assert!(!built_executable_exists(workspace, "foo")); - assert!(!object_file_exists(workspace, "foo")); - assert!(llvm_assembly_file_exists(workspace, "foo")); - assert!(!assembly_file_exists(workspace, "foo")); -} - -#[test] -fn test_emit_llvm_S_fail() { - let p_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package(&p_id); - let workspace = workspace.path(); - let test_sys = test_sysroot(); - // FIXME (#9639): This needs to handle non-utf8 paths - command_line_test_expect_fail([test_sys.as_str().unwrap().to_owned(), - ~"install", - ~"-S", ~"--emit-llvm", - ~"foo"], - workspace, - None, - BAD_FLAG_CODE); - assert!(!built_executable_exists(workspace, "foo")); - assert!(!object_file_exists(workspace, "foo")); - assert!(!llvm_assembly_file_exists(workspace, "foo")); - assert!(!assembly_file_exists(workspace, "foo")); -} - -#[test] -fn test_emit_llvm_build() { - let p_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package(&p_id); - let workspace = workspace.path(); - let test_sys = test_sysroot(); - // FIXME (#9639): This needs to handle non-utf8 paths - command_line_test([test_sys.as_str().unwrap().to_owned(), - ~"build", - ~"--emit-llvm", - ~"foo"], - workspace); - assert!(!built_executable_exists(workspace, "foo")); - assert!(!object_file_exists(workspace, "foo")); - assert!(llvm_bitcode_file_exists(workspace, "foo")); - assert!(!assembly_file_exists(workspace, "foo")); - assert!(!llvm_assembly_file_exists(workspace, "foo")); -} - -#[test] -fn test_emit_llvm_fail() { - let p_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package(&p_id); - let workspace = workspace.path(); - let test_sys = test_sysroot(); - // FIXME (#9639): This needs to handle non-utf8 paths - command_line_test_expect_fail([test_sys.as_str().unwrap().to_owned(), - ~"install", - ~"--emit-llvm", - ~"foo"], - workspace, - None, - BAD_FLAG_CODE); - assert!(!built_executable_exists(workspace, "foo")); - assert!(!object_file_exists(workspace, "foo")); - assert!(!llvm_bitcode_file_exists(workspace, "foo")); - assert!(!llvm_assembly_file_exists(workspace, "foo")); - assert!(!assembly_file_exists(workspace, "foo")); -} - -#[test] -fn test_linker_build() { - let p_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package(&p_id); - let workspace = workspace.path(); - let matches = getopts([], optgroups()); - let options = build_session_options(~"rustpkg", - matches.as_ref().unwrap(), - @diagnostic::DefaultEmitter); - let sess = build_session(options, None, @diagnostic::DefaultEmitter); - let test_sys = test_sysroot(); - // FIXME (#9639): This needs to handle non-utf8 paths - let cc = get_cc_prog(sess); - command_line_test([test_sys.as_str().unwrap().to_owned(), - ~"install", - ~"--linker", - cc, - ~"foo"], - workspace); - assert_executable_exists(workspace, "foo"); -} - -#[test] -fn test_build_install_flags_fail() { - // The following flags can only be used with build or install: - let forbidden = [~[~"--linker", ~"ld"], - ~[~"--link-args", ~"quux"], - ~[~"-O"], - ~[~"--opt-level", ~"2"], - ~[~"--save-temps"], - ~[~"--target", host_triple()], - ~[~"--target-cpu", ~"generic"], - ~[~"-Z", ~"--time-passes"]]; - let cwd = os::getcwd(); - for flag in forbidden.iter() { - let test_sys = test_sysroot(); - // FIXME (#9639): This needs to handle non-utf8 paths - command_line_test_expect_fail([test_sys.as_str().unwrap().to_owned(), - ~"list"] + *flag, &cwd, None, BAD_FLAG_CODE); - } -} - -#[test] -fn test_optimized_build() { - let p_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package(&p_id); - let workspace = workspace.path(); - let test_sys = test_sysroot(); - // FIXME (#9639): This needs to handle non-utf8 paths - command_line_test([test_sys.as_str().unwrap().to_owned(), - ~"build", - ~"-O", - ~"foo"], - workspace); - assert!(built_executable_exists(workspace, "foo")); -} - -#[test] -fn crateid_pointing_to_subdir() { - // The actual repo is mockgithub.com/mozilla/some_repo - // rustpkg should recognize that and treat the part after some_repo/ as a subdir - let workspace = TempDir::new("parent_repo").expect("Couldn't create temp dir"); - let workspace = workspace.path(); - fs::mkdir_recursive(&workspace.join_many(["src", "mockgithub.com", - "mozilla", "some_repo"]), - io::UserRWX); - - let foo_dir = workspace.join_many(["src", "mockgithub.com", "mozilla", "some_repo", - "extras", "foo"]); - let bar_dir = workspace.join_many(["src", "mockgithub.com", "mozilla", "some_repo", - "extras", "bar"]); - fs::mkdir_recursive(&foo_dir, io::UserRWX); - fs::mkdir_recursive(&bar_dir, io::UserRWX); - writeFile(&foo_dir.join("lib.rs"), - "#[crate_id=\"mockgithub.com/mozilla/some_repo/extras/foo\"];" + - "pub fn f() {}"); - writeFile(&bar_dir.join("lib.rs"), - "#[crate_id=\"mockgithub.com/mozilla/some_repo/extras/bar\"];" + - "pub fn g() {}"); - - debug!("Creating a file in {}", workspace.display()); - let testpkg_dir = workspace.join_many(["src", "testpkg-0.0"]); - fs::mkdir_recursive(&testpkg_dir, io::UserRWX); - - writeFile(&testpkg_dir.join("main.rs"), - "extern mod foo = \"mockgithub.com/mozilla/some_repo/extras/foo#foo:0.0\";\n - extern mod bar = \"mockgithub.com/mozilla/some_repo/extras/bar#bar:0.0\";\n - use foo::f; use bar::g; \n - fn main() { f(); g(); }"); - - command_line_test([~"install", ~"testpkg"], workspace); - assert_executable_exists(workspace, "testpkg"); -} - -#[test] -fn test_recursive_deps() { - let a_id: CrateId = from_str("a").unwrap(); - let b_id: CrateId = from_str("b").unwrap(); - let c_id: CrateId = from_str("c").unwrap(); - let b_workspace = create_local_package_with_dep(&b_id, &c_id); - let b_workspace = b_workspace.path(); - writeFile(&b_workspace.join_many(["src", "c-0.0", "lib.rs"]), - "pub fn g() {}"); - let a_workspace = create_local_package(&a_id); - let a_workspace = a_workspace.path(); - writeFile(&a_workspace.join_many(["src", "a-0.0", "main.rs"]), - "extern mod b; use b::f; fn main() { f(); }"); - writeFile(&b_workspace.join_many(["src", "b-0.0", "lib.rs"]), - "extern mod c; use c::g; pub fn f() { g(); }"); - // FIXME (#9639): This needs to handle non-utf8 paths - let environment = Some(~[(~"RUST_PATH", b_workspace.as_str().unwrap().to_owned())]); - debug!("RUST_PATH={}", b_workspace.display()); - command_line_test_with_env([~"install", ~"a"], - a_workspace, - environment); - assert_lib_exists(a_workspace, &a_id); - assert_lib_exists(b_workspace, &b_id); - assert_lib_exists(b_workspace, &c_id); -} - -#[test] -fn test_install_to_rust_path() { - let p_id: CrateId = from_str("foo").unwrap(); - let second_workspace = create_local_package(&p_id); - let second_workspace = second_workspace.path(); - let none_id: CrateId = from_str("p").unwrap(); - let first_workspace = mk_empty_workspace(&none_id, "dest"); - let first_workspace = first_workspace.path(); - // FIXME (#9639): This needs to handle non-utf8 paths - let rust_path = Some(~[(~"RUST_PATH", - format!("{}:{}", first_workspace.as_str().unwrap(), - second_workspace.as_str().unwrap()))]); - debug!("RUST_PATH={}:{}", first_workspace.display(), second_workspace.display()); - let test_sys = test_sysroot(); - // FIXME (#9639): This needs to handle non-utf8 paths - command_line_test_with_env([test_sys.as_str().unwrap().to_owned(), - ~"install", - ~"foo"], - &os::getcwd(), rust_path); - assert!(!built_executable_exists(first_workspace, "foo")); - assert!(built_executable_exists(second_workspace, "foo")); - assert_executable_exists(first_workspace, "foo"); - assert!(!executable_exists(second_workspace, "foo")); -} - -#[test] -fn test_target_specific_build_dir() { - let p_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package(&p_id); - let workspace = workspace.path(); - let test_sys = test_sysroot(); - // FIXME (#9639): This needs to handle non-utf8 paths - command_line_test([test_sys.as_str().unwrap().to_owned(), - ~"build", - ~"foo"], - workspace); - assert!(target_build_dir(workspace).is_dir()); - assert!(built_executable_exists(workspace, "foo")); - assert!(fs::readdir(&workspace.join("build")).len() == 1); -} - -#[test] -fn test_target_specific_install_dir() { - let p_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package(&p_id); - let workspace = workspace.path(); - let test_sys = test_sysroot(); - // FIXME (#9639): This needs to handle non-utf8 paths - command_line_test([test_sys.as_str().unwrap().to_owned(), - ~"install", - ~"foo"], - workspace); - assert!(workspace.join_many([~"lib", host_triple()]).is_dir()); - assert_lib_exists(workspace, &p_id); - assert!(fs::readdir(&workspace.join("lib")).len() == 1); - assert!(workspace.join("bin").is_dir()); - assert_executable_exists(workspace, "foo"); -} - -#[test] -#[ignore(reason = "See #7240")] -fn test_dependencies_terminate() { - let b_id: CrateId = from_str("b").unwrap(); - let workspace = create_local_package(&b_id); - let workspace = workspace.path(); - let b_dir = workspace.join_many(["src", "b-0.0"]); - let b_subdir = b_dir.join("test"); - fs::mkdir_recursive(&b_subdir, io::UserRWX); - writeFile(&b_subdir.join("test.rs"), - "extern mod b; use b::f; #[test] fn g() { f() }"); - command_line_test([~"install", ~"b"], workspace); -} - -#[test] -fn install_after_build() { - let b_id: CrateId = from_str("b").unwrap(); - let workspace = create_local_package(&b_id); - let workspace = workspace.path(); - command_line_test([~"build", ~"b"], workspace); - command_line_test([~"install", ~"b"], workspace); - assert_executable_exists(workspace, b_id.name); - assert_lib_exists(workspace, &b_id); -} - -#[test] -fn reinstall() { - let b: CrateId = from_str("b").unwrap(); - let workspace = create_local_package(&b); - let workspace = workspace.path(); - // 1. Install, then remove executable file, then install again, - // and make sure executable was re-installed - command_line_test([~"install", ~"b"], workspace); - assert_executable_exists(workspace, b.name); - assert_lib_exists(workspace, &b); - remove_executable_file(&b, workspace); - command_line_test([~"install", ~"b"], workspace); - assert_executable_exists(workspace, b.name); - // 2. Build, then remove build executable file, then build again, - // and make sure executable was re-built. - command_line_test([~"build", ~"b"], workspace); - remove_built_executable_file(&b, workspace); - command_line_test([~"build", ~"b"], workspace); - assert_built_executable_exists(workspace, b.name); - // 3. Install, then remove both executable and built executable, - // then install again, make sure both were recreated - command_line_test([~"install", ~"b"], workspace); - remove_executable_file(&b, workspace); - remove_built_executable_file(&b, workspace); - command_line_test([~"install", ~"b"], workspace); - assert_executable_exists(workspace, b.name); - assert_built_executable_exists(workspace, b.name); -} - -#[test] -fn correct_package_name_with_rust_path_hack() { - /* - Set rust_path_hack flag - - Try to install bar - Check that: - - no output gets produced in any workspace - - there's an error - */ - - // Set RUST_PATH to something containing only the sources for foo - let foo_id: CrateId = from_str("foo").unwrap(); - let bar_id: CrateId = from_str("bar").unwrap(); - let foo_workspace = create_local_package(&foo_id); - let foo_workspace = foo_workspace.path(); - let dest_workspace = mk_empty_workspace(&bar_id, "dest_workspace"); - let dest_workspace = dest_workspace.path(); - - writeFile(&dest_workspace.join_many(["src", "bar-0.0", "main.rs"]), - "extern mod blat; fn main() { let _x = (); }"); - - let foo_path = foo_workspace.join_many(["src", "foo-0.0"]); - // FIXME (#9639): This needs to handle non-utf8 paths - let rust_path = Some(~[(~"RUST_PATH", format!("{}:{}", dest_workspace.as_str().unwrap(), - foo_path.as_str().unwrap()))]); - // bar doesn't exist, but we want to make sure rustpkg doesn't think foo is bar - command_line_test_expect_fail([~"install", ~"--rust-path-hack", ~"bar"], - // FIXME #3408: Should be NONEXISTENT_PACKAGE_CODE - dest_workspace, rust_path, COPY_FAILED_CODE); - assert!(!executable_exists(dest_workspace, "bar")); - assert!(!lib_exists(dest_workspace, &bar_id)); - assert!(!executable_exists(dest_workspace, "foo")); - assert!(!lib_exists(dest_workspace, &foo_id)); - assert!(!executable_exists(foo_workspace, "bar")); - assert!(!lib_exists(foo_workspace, &bar_id)); - assert!(!executable_exists(foo_workspace, "foo")); - assert!(!lib_exists(foo_workspace, &foo_id)); -} - -#[test] -fn test_rustpkg_test_creates_exec() { - let foo_id: CrateId = from_str("foo").unwrap(); - let foo_workspace = create_local_package(&foo_id); - let foo_workspace = foo_workspace.path(); - writeFile(&foo_workspace.join_many(["src", "foo-0.0", "test.rs"]), - "#[test] fn f() { assert!('a' == 'a'); }"); - command_line_test([~"test", ~"foo"], foo_workspace); - assert!(test_executable_exists(foo_workspace, "foo")); -} - -#[test] -fn test_rustpkg_test_output() { - let foo_id: CrateId = from_str("foo").unwrap(); - let workspace = create_local_package_with_test(&foo_id); - let output = command_line_test([~"test", ~"foo"], workspace.path()); - let output_str = str::from_utf8(output.output).unwrap(); - // The first two assertions are separate because test output may - // contain color codes, which could appear between "test f" and "ok". - assert!(output_str.contains("test f")); - assert!(output_str.contains("ok")); - assert!(output_str.contains("1 passed; 0 failed; 0 ignored; 0 measured")); -} - -#[test] -fn test_rustpkg_test_failure_exit_status() { - let foo_id: CrateId = from_str("foo").unwrap(); - let foo_workspace = create_local_package(&foo_id); - let foo_workspace = foo_workspace.path(); - writeFile(&foo_workspace.join_many(["src", "foo-0.0", "test.rs"]), - "#[test] fn f() { assert!('a' != 'a'); }"); - let res = command_line_test_partial([~"test", ~"foo"], foo_workspace); - match res { - Fail(_) => {}, - Success(..) => fail!("Expected test failure but got success") - } -} - -#[test] -fn test_rustpkg_test_cfg() { - let foo_id: CrateId = from_str("foo").unwrap(); - let foo_workspace = create_local_package(&foo_id); - let foo_workspace = foo_workspace.path(); - writeFile(&foo_workspace.join_many(["src", "foo-0.0", "test.rs"]), - "#[test] #[cfg(not(foobar))] fn f() { assert!('a' != 'a'); }"); - let output = command_line_test([~"test", ~"--cfg", ~"foobar", ~"foo"], - foo_workspace); - let output_str = str::from_utf8(output.output).unwrap(); - assert!(output_str.contains("0 passed; 0 failed; 0 ignored; 0 measured")); -} - -#[test] -fn test_rebuild_when_needed() { - let foo_id: CrateId = from_str("foo").unwrap(); - let foo_workspace = create_local_package(&foo_id); - let foo_workspace = foo_workspace.path(); - let test_crate = foo_workspace.join_many(["src", "foo-0.0", "test.rs"]); - writeFile(&test_crate, "#[test] fn f() { assert!('a' == 'a'); }"); - command_line_test([~"test", ~"foo"], foo_workspace); - assert!(test_executable_exists(foo_workspace, "foo")); - let test_executable = built_test_in_workspace(&foo_id, - foo_workspace).expect("test_rebuild_when_needed failed"); - frob_source_file(foo_workspace, &foo_id, "test.rs"); - chmod_read_only(&test_executable); - match command_line_test_partial([~"test", ~"foo"], foo_workspace) { - Success(..) => fail!("test_rebuild_when_needed didn't rebuild"), - Fail(ref r) if r.status.matches_exit_status(65) => (), // ok - Fail(_) => fail!("test_rebuild_when_needed failed for some other reason") - } -} - -#[test] -#[ignore] // FIXME (#10257): This doesn't work as is since a read only file can't execute -fn test_no_rebuilding() { - let foo_id: CrateId = from_str("foo").unwrap(); - let foo_workspace = create_local_package(&foo_id); - let foo_workspace = foo_workspace.path(); - let test_crate = foo_workspace.join_many(["src", "foo-0.0", "test.rs"]); - writeFile(&test_crate, "#[test] fn f() { assert!('a' == 'a'); }"); - command_line_test([~"test", ~"foo"], foo_workspace); - assert!(test_executable_exists(foo_workspace, "foo")); - let test_executable = built_test_in_workspace(&foo_id, - foo_workspace).expect("test_no_rebuilding failed"); - chmod_read_only(&test_executable); - match command_line_test_partial([~"test", ~"foo"], foo_workspace) { - Success(..) => (), // ok - Fail(ref r) if r.status.matches_exit_status(65) => - fail!("test_no_rebuilding failed: it rebuilt the tests"), - Fail(_) => fail!("test_no_rebuilding failed for some other reason") - } -} - -#[test] -fn test_installed_read_only() { - // Install sources from a "remote" (actually a local github repo) - // Check that afterward, sources are read-only and installed under build/ - let temp_pkg_id = git_repo_pkg(); - let path = Path::new(temp_pkg_id.path.as_slice()); - let repo = init_git_repo(&path); - let repo = repo.path(); - debug!("repo = {}", repo.display()); - let repo_subdir = repo.join_many(["mockgithub.com", "catamorphism", "test-pkg"]); - debug!("repo_subdir = {}", repo_subdir.display()); - - writeFile(&repo_subdir.join("main.rs"), - "fn main() { let _x = (); }"); - writeFile(&repo_subdir.join("lib.rs"), - "pub fn f() { let _x = (); }"); - add_git_tag(&repo_subdir, ~"0.0"); // this has the effect of committing the files - // update crateid to what will be auto-detected - - // FIXME (#9639): This needs to handle non-utf8 paths - command_line_test([~"install", temp_pkg_id.to_str()], repo); - - let ws = repo.join(".rust"); - // Check that all files exist - debug!("Checking for files in {}", ws.display()); - let exec = target_executable_in_workspace(&temp_pkg_id, &ws); - debug!("exec = {}", exec.display()); - assert!(exec.exists()); - assert!(is_rwx(&exec)); - let built_lib = - built_library_in_workspace(&temp_pkg_id, - &ws).expect("test_install_git: built lib should exist"); - assert!(built_lib.exists()); - - // Make sure sources are (a) under "build" and (b) read-only - let temp_dir = format!("{}-{}", temp_pkg_id.path, temp_pkg_id.version_or_default()); - let src1 = target_build_dir(&ws).join_many([~"src", temp_dir.clone(), ~"main.rs"]); - let src2 = target_build_dir(&ws).join_many([~"src", temp_dir.clone(), ~"lib.rs"]); - debug!("src1: {}", src1.display()); - assert!(src1.exists()); - assert!(src2.exists()); - assert!(is_read_only(&src1)); - assert!(is_read_only(&src2)); -} - -#[test] -fn test_installed_local_changes() { - let temp_pkg_id = git_repo_pkg(); - let repo = init_git_repo(&Path::new(temp_pkg_id.path.as_slice())); - let repo = repo.path(); - debug!("repo = {}", repo.display()); - let repo_subdir = repo.join_many(["mockgithub.com", "catamorphism", "test-pkg"]); - debug!("repo_subdir = {}", repo_subdir.display()); - fs::mkdir_recursive(&repo.join_many([".rust", "src"]), io::UserRWX); - - writeFile(&repo_subdir.join("main.rs"), - "fn main() { let _x = (); }"); - writeFile(&repo_subdir.join("lib.rs"), - "pub fn f() { let _x = (); }"); - add_git_tag(&repo_subdir, ~"0.1"); // this has the effect of committing the files - - command_line_test([~"install", temp_pkg_id.path.to_owned()], repo); - - // We installed the dependency. - // Now start a new workspace and clone it into it - let hacking_workspace = mk_emptier_workspace("hacking_workspace"); - let hacking_workspace = hacking_workspace.path(); - let target_dir = hacking_workspace.join_many(["src", - "mockgithub.com", - "catamorphism", - "test-pkg-0.0"]); - debug!("---- git clone {} {}", repo_subdir.display(), target_dir.display()); - - let c_res = safe_git_clone(&repo_subdir, &None, &target_dir); - - match c_res { - DirToUse(_) => fail!("test_installed_local_changes failed"), - CheckedOutSources => () - }; - - // Make a local change to it - writeFile(&target_dir.join("lib.rs"), - "pub fn g() { let _x = (); }"); - - // Finally, make *another* package that uses it - let importer_pkg_id = fake_pkg(); - let main_subdir = create_local_package_in(&importer_pkg_id, hacking_workspace); - writeFile(&main_subdir.join("main.rs"), - "extern mod test = \"mockgithub.com/catamorphism/test-pkg\"; \ - use test::g; - fn main() { g(); }"); - // And make sure we can build it - - command_line_test([~"build", importer_pkg_id.path.to_owned()], hacking_workspace); -} - -#[test] -fn test_7402() { - let foo_id: CrateId = from_str("foo").unwrap(); - let dir = create_local_package(&foo_id); - let dest_workspace = TempDir::new("more_rust").expect("test_7402"); - let dest_workspace = dest_workspace.path(); - // FIXME (#9639): This needs to handle non-utf8 paths - let rust_path = Some(~[(~"RUST_PATH", - format!("{}:{}", dest_workspace.as_str().unwrap(), - dir.path().as_str().unwrap()))]); - let cwd = os::getcwd(); - command_line_test_with_env([~"install", ~"foo"], &cwd, rust_path); - assert_executable_exists(dest_workspace, "foo"); -} - -#[test] -fn test_compile_error() { - let foo_id: CrateId = from_str("foo").unwrap(); - let foo_workspace = create_local_package(&foo_id); - let foo_workspace = foo_workspace.path(); - let main_crate = foo_workspace.join_many(["src", "foo-0.0", "main.rs"]); - // Write something bogus - writeFile(&main_crate, "pub fn main() { if 42 != ~\"the answer\" { fail!(); } }"); - let result = command_line_test_partial([~"build", ~"foo"], foo_workspace); - match result { - Success(..) => fail!("Failed by succeeding!"), // should be a compile error - Fail(ref status) => { - debug!("Failed with status {:?}... that's good, right?", status); - } - } -} - -#[test] -fn find_sources_in_cwd() { - let temp_dir = TempDir::new("sources").expect("find_sources_in_cwd failed"); - let temp_dir = temp_dir.path(); - let source_dir = temp_dir.join("foo"); - fs::mkdir_recursive(&source_dir, io::UserRWX); - writeFile(&source_dir.join("main.rs"), - r#"#[crate_id="rust-foo#foo:0.0"]; fn main() { let _x = (); }"#); - command_line_test([~"install", ~"foo"], &source_dir); - assert_executable_exists(&source_dir.join(".rust"), "foo"); -} - -#[test] -#[ignore(reason="busted")] -fn test_c_dependency_ok() { - // Pkg has a custom build script that adds a single C file as a dependency, and - // registers a hook to build it if it's not fresh - // After running `build`, test that the C library built - - let cdep_id: CrateId = from_str("cdep").unwrap(); - let dir = create_local_package(&cdep_id); - let dir = dir.path(); - writeFile(&dir.join_many(["src", "cdep-0.0", "main.rs"]), - "#[link_args = \"-lfoo\"]\nextern { fn f(); } \ - \nfn main() { unsafe { f(); } }"); - writeFile(&dir.join_many(["src", "cdep-0.0", "foo.c"]), "void f() {}"); - - debug!("dir = {}", dir.display()); - let source = Path::new(file!()).dir_path().join_many( - [~"testsuite", ~"pass", ~"src", ~"c-dependencies", ~"pkg.rs"]); - fs::copy(&source, &dir.join_many([~"src", ~"cdep-0.0", ~"pkg.rs"])); - command_line_test([~"build", ~"cdep"], dir); - assert_executable_exists(dir, "cdep"); - let out_dir = target_build_dir(dir).join("cdep"); - let c_library_path = out_dir.join(platform_library_name("foo")); - debug!("c library path: {}", c_library_path.display()); - assert!(c_library_path.exists()); -} - -#[ignore(reason="rustpkg is not reentrant")] -#[test] -#[ignore(reason="busted")] -fn test_c_dependency_no_rebuilding() { - let cdep_id: CrateId = from_str("cdep").unwrap(); - let dir = create_local_package(&cdep_id); - let dir = dir.path(); - writeFile(&dir.join_many(["src", "cdep-0.0", "main.rs"]), - "#[link_args = \"-lfoo\"]\nextern { fn f(); } \ - \nfn main() { unsafe { f(); } }"); - writeFile(&dir.join_many(["src", "cdep-0.0", "foo.c"]), "void f() {}"); - - debug!("dir = {}", dir.display()); - let source = Path::new(file!()).dir_path().join_many( - [~"testsuite", ~"pass", ~"src", ~"c-dependencies", ~"pkg.rs"]); - fs::copy(&source, &dir.join_many([~"src", ~"cdep-0.0", ~"pkg.rs"])); - command_line_test([~"build", ~"cdep"], dir); - assert_executable_exists(dir, "cdep"); - let out_dir = target_build_dir(dir).join("cdep"); - let c_library_path = out_dir.join(platform_library_name("foo")); - debug!("c library path: {}", c_library_path.display()); - assert!(c_library_path.exists()); - - // Now, make it read-only so rebuilding will fail - assert!(chmod_read_only(&c_library_path)); - - match command_line_test_partial([~"build", ~"cdep"], dir) { - Success(..) => (), // ok - Fail(ref r) if r.status.matches_exit_status(65) => - fail!("test_c_dependency_no_rebuilding failed: \ - it tried to rebuild foo.c"), - Fail(_) => - fail!("test_c_dependency_no_rebuilding failed for some other reason") - } -} - -#[test] -#[ignore(reason="busted")] -fn test_c_dependency_yes_rebuilding() { - let cdep_id: CrateId = from_str("cdep").unwrap(); - let dir = create_local_package(&cdep_id); - let dir = dir.path(); - writeFile(&dir.join_many(["src", "cdep-0.0", "main.rs"]), - "#[link_args = \"-lfoo\"]\nextern { fn f(); } \ - \nfn main() { unsafe { f(); } }"); - let c_file_name = dir.join_many(["src", "cdep-0.0", "foo.c"]); - writeFile(&c_file_name, "void f() {}"); - - let source = Path::new(file!()).dir_path().join_many( - [~"testsuite", ~"pass", ~"src", ~"c-dependencies", ~"pkg.rs"]); - let target = dir.join_many([~"src", ~"cdep-0.0", ~"pkg.rs"]); - debug!("Copying {} -> {}", source.display(), target.display()); - fs::copy(&source, &target); - command_line_test([~"build", ~"cdep"], dir); - assert_executable_exists(dir, "cdep"); - let out_dir = target_build_dir(dir).join("cdep"); - let c_library_path = out_dir.join(platform_library_name("foo")); - debug!("c library path: {}", c_library_path.display()); - assert!(c_library_path.exists()); - - // Now, make the Rust library read-only so rebuilding will fail - match built_library_in_workspace(&cdep_id, dir) { - Some(ref pth) => assert!(chmod_read_only(pth)), - None => assert_built_library_exists(dir, "cdep") - } - - match command_line_test_partial([~"build", ~"cdep"], dir) { - Success(..) => fail!("test_c_dependency_yes_rebuilding failed: \ - it didn't rebuild and should have"), - Fail(ref r) if r.status.matches_exit_status(65) => (), - Fail(_) => fail!("test_c_dependency_yes_rebuilding failed for some other reason") - } -} - -// n.b. This might help with #10253, or at least the error will be different. -#[test] -fn correct_error_dependency() { - // Supposing a package we're trying to install via a dependency doesn't - // exist, we should throw a condition, and not ICE - let crate_id: CrateId = from_str("badpkg").unwrap(); - let workspace_dir = create_local_package(&crate_id); - - let dir = workspace_dir.path(); - let main_rs = dir.join_many(["src", "badpkg-0.0", "main.rs"]); - writeFile(&main_rs, - "extern mod p = \"some_package_that_doesnt_exist\"; - fn main() {}"); - match command_line_test_partial([~"build", ~"badpkg"], dir) { - Fail(ProcessOutput{ error: error, output: output, .. }) => { - assert!(str::is_utf8(error)); - assert!(str::is_utf8(output)); - let error_str = str::from_utf8(error).unwrap(); - let out_str = str::from_utf8(output).unwrap(); - debug!("ss = {}", error_str); - debug!("out_str = {}", out_str); - if out_str.contains("Package badpkg depends on some_package_that_doesnt_exist") && - !error_str.contains("nonexistent_package") { - // Ok - () - } else { - fail!("Wrong error"); - } - } - Success(..) => fail!("Test passed when it should have failed") - } -} - -/// Returns true if p exists and is executable -fn is_executable(p: &Path) -> bool { - p.exists() && p.stat().perm & io::UserExecute == io::UserExecute -} diff --git a/src/librustpkg/testsuite/fail/src/no-inferred-crates/src/zzyzx.rs b/src/librustpkg/testsuite/fail/src/no-inferred-crates/src/zzyzx.rs deleted file mode 100644 index a4c2c1baabe..00000000000 --- a/src/librustpkg/testsuite/fail/src/no-inferred-crates/src/zzyzx.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/* -The test runner should check that, after `rustpkg build hello-world`: - * testsuite/hello-world/build/ exists - * testsuite/hello-world/build/ contains an executable named hello-world - * testsuite/hello-world/build/ does not contain a library -*/ - -fn main() { - println!("Hello world!"); -} diff --git a/src/librustpkg/testsuite/pass/commands.txt b/src/librustpkg/testsuite/pass/commands.txt deleted file mode 100644 index baeaef1e3c7..00000000000 --- a/src/librustpkg/testsuite/pass/commands.txt +++ /dev/null @@ -1,34 +0,0 @@ -Commands that should succeed: - -1. rustpkg install github.com/mozilla-servo/rust-http-client - -2. Create a git repo containing a package "foo", add a tag called "1.0" -- `rustpkg install foo` should install a library called "libfoo-....-1.0..." - -3. rustpkg install foo, if ./.rust/foo exists and is a valid package directory - -4. RUST_PATH=/home/rust rustpkg install foo installs an executable in /home/rust/foo if ./foo exists and is a valid package directory - -5. RUST_PATH=/home/rust:/home/more_rust rustpkg install foo succeeds if /home/more_rust/foo exists and is a valid package directory - -6. rustpkg install foo; rustpkg install bar; rustpkg install quux; rustpkg list should show foo, bar, and quux - 6a. then, rustpkg remove foo; rustpkg list should show bar and quux, but not foo - -7. Execute `rustpkg build foo`. Check the datestamp on build/foo. Execute the same command again. Make sure the datestamp hasn't changed. - -8. Execute `rustpkg build foo` where foo has a dependency on bar, which hasn't been built before. Check the datestamps on build/foo and build/bar and make sure bar's datestamp is earlier than foo's. - -9. Execute `rustpkg build foo` where foo has a dependency on bar, which hasn't been built before. Then, change one of the source files in bar. Execute `rustpkg build foo` again. Make sure, based on datestamps, that foo was really rebuilt. - -10. Repeat test 9 in the case where the contents of the source file in bar change but its datestamp doesn't change. - -11. If the current directory contains package directories for foo-0.1 and foo.0.2, `rustpkg install foo#0.1` installs foo#0.1 and doesn't install foo#0.2. - -12. `rustpkg do fancy-pkg frob` succeeds if `fancy-pkg` has a package script that defines a custom build hook named `frob`. - -13. `rustpkg info foo` prints out something about foo, if foo is installed. - -14. (Not sure what prefer and unprefer do) - -15. `rustpkg test foo` runs tests and prints their output, if foo contains #[test]s. - -16. If foo is installed, `rustpkg uninstall foo; rustpkg list` doesn't include foo in the list diff --git a/src/librustpkg/testsuite/pass/src/c-dependencies/bar.rs b/src/librustpkg/testsuite/pass/src/c-dependencies/bar.rs deleted file mode 100644 index ffbc6e2a7f9..00000000000 --- a/src/librustpkg/testsuite/pass/src/c-dependencies/bar.rs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -pub fn assert_true() { - assert!(true); -} diff --git a/src/librustpkg/testsuite/pass/src/c-dependencies/foo.rs b/src/librustpkg/testsuite/pass/src/c-dependencies/foo.rs deleted file mode 100644 index 3b233c9f6a8..00000000000 --- a/src/librustpkg/testsuite/pass/src/c-dependencies/foo.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -pub fn do_nothing() { -} diff --git a/src/librustpkg/testsuite/pass/src/c-dependencies/lib.rs b/src/librustpkg/testsuite/pass/src/c-dependencies/lib.rs deleted file mode 100644 index bd1cb240a34..00000000000 --- a/src/librustpkg/testsuite/pass/src/c-dependencies/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -extern mod std; - -pub mod foo; -pub mod bar; diff --git a/src/librustpkg/testsuite/pass/src/c-dependencies/pkg.rs b/src/librustpkg/testsuite/pass/src/c-dependencies/pkg.rs deleted file mode 100644 index dcc39ae0e92..00000000000 --- a/src/librustpkg/testsuite/pass/src/c-dependencies/pkg.rs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -extern mod rustpkg; -extern mod rustc; - -use std::{os, task}; -use rustpkg::api; -use rustpkg::version::None; -use rustpkg::workcache_support::digest_file_with_date; -use rustpkg::exit_codes::COPY_FAILED_CODE; - -pub fn main() { - let args = os::args(); - -// by convention, first arg is sysroot - if args.len() < 2 { - fail!("Package script requires a directory where rustc libraries live as the first \ - argument"); - } - - let path_for_db = api::default_workspace(); - debug!("path_for_db = {}", path_for_db.display()); - - let sysroot_arg = args[1].clone(); - let sysroot = Path::new(sysroot_arg); - if !sysroot.exists() { - fail!("Package script requires a sysroot that exists; {} doesn't", sysroot.display()); - } - - if args[2] != ~"install" { - println!("Warning: I don't know how to {}", args[2]); - return; - } - - let mut context = api::default_context(sysroot, path_for_db); - let my_workspace = api::my_workspace(&context.context, "cdep"); - let foo_c_name = my_workspace.join_many(["src", "cdep-0.0", "foo.c"]); - - let out_lib_path = context.workcache_context.with_prep("foo.c", |prep| { - let sub_cx = context.context.clone(); - debug!("foo_c_name = {}", foo_c_name.display()); - prep.declare_input("file", - foo_c_name.as_str().unwrap().to_owned(), - digest_file_with_date(&foo_c_name)); - let out_path = prep.exec(|exec| { - let out_path = api::build_library_in_workspace(exec, - &mut sub_cx.clone(), - "cdep", - "gcc", - [~"-c"], - [~"foo.c"], - "foo"); - let out_p = Path::new(out_path.unwrap()); - out_p.as_str().unwrap().to_owned() - }); - out_path - }); - let out_lib_path = Path::new(out_lib_path); - debug!("out_lib_path = {}", out_lib_path.display()); - context.add_library_path(out_lib_path.dir_path()); - - let context_clone = context.clone(); - let task_res = task::try(proc() { - let mut cc = context_clone.clone(); - api::install_pkg(&mut cc, - os::getcwd(), - ~"cdep", - None, - ~[(~"binary", out_lib_path.clone()), (~"file", foo_c_name.clone())]); - }); - - if task_res.is_err() { - os::set_exit_status(COPY_FAILED_CODE); - } -} diff --git a/src/librustpkg/testsuite/pass/src/deeply/nested/path/foo/main.rs b/src/librustpkg/testsuite/pass/src/deeply/nested/path/foo/main.rs deleted file mode 100644 index 62785c06db3..00000000000 --- a/src/librustpkg/testsuite/pass/src/deeply/nested/path/foo/main.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/* -The test runner should check that, after `rustpkg install deeply/nested/path/foo`: - with RUST_PATH undefined in the environment: - * ./deeply/nested/path/foo exists and is an executable -*/ - -fn main() {} diff --git a/src/librustpkg/testsuite/pass/src/external-crate/main.rs b/src/librustpkg/testsuite/pass/src/external-crate/main.rs deleted file mode 100644 index 1e5c1d5e627..00000000000 --- a/src/librustpkg/testsuite/pass/src/external-crate/main.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/* -The test runner should check that, after `rustpkg install external crate` - with RUST_PATH undefined in the environment - and with `rustpkg install deeply/nested/path/foo` already - executed: - * ../bin/external_crate exists and is an executable - - tjc: Also want a test like this where foo is an external URL, - which requires the `extern mod` changes -*/ - -extern mod foo; - -fn main() {} diff --git a/src/librustpkg/testsuite/pass/src/fancy-lib/bar.rs b/src/librustpkg/testsuite/pass/src/fancy-lib/bar.rs deleted file mode 100644 index ffbc6e2a7f9..00000000000 --- a/src/librustpkg/testsuite/pass/src/fancy-lib/bar.rs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -pub fn assert_true() { - assert!(true); -} diff --git a/src/librustpkg/testsuite/pass/src/fancy-lib/foo.rs b/src/librustpkg/testsuite/pass/src/fancy-lib/foo.rs deleted file mode 100644 index 3b233c9f6a8..00000000000 --- a/src/librustpkg/testsuite/pass/src/fancy-lib/foo.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -pub fn do_nothing() { -} diff --git a/src/librustpkg/testsuite/pass/src/fancy-lib/lib.rs b/src/librustpkg/testsuite/pass/src/fancy-lib/lib.rs deleted file mode 100644 index 17386cd03c2..00000000000 --- a/src/librustpkg/testsuite/pass/src/fancy-lib/lib.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/* -The test runner should check that, after `rustpkg build fancy-lib`: - * testsuite/fancy-lib/build/ exists - * testsuite/fancy-lib/build/ contains a file called generated.rs - * testsuite/fancy-lib/build/ contains a library named libfancy_lib - * testsuite/fancy-lib/build/ does not contain an executable - * -*/ - -extern mod std; - -pub mod foo; -pub mod bar; -#[path = "../../build/fancy-lib/generated.rs"] pub mod generated; diff --git a/src/librustpkg/testsuite/pass/src/fancy-lib/pkg.rs b/src/librustpkg/testsuite/pass/src/fancy-lib/pkg.rs deleted file mode 100644 index 7b1291025e4..00000000000 --- a/src/librustpkg/testsuite/pass/src/fancy-lib/pkg.rs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -extern mod rustpkg; -extern mod rustc; - -use std::os; -use std::io::File; -use rustpkg::api; -use rustpkg::version::None; - -pub fn main() { - let args = os::args(); - -// by convention, first arg is sysroot - if args.len() < 2 { - debug!("Failing, arg len"); - fail!("Package script requires a directory where rustc libraries live as the first \ - argument"); - } - - let sysroot_arg = args[1].clone(); - let sysroot = Path::new(sysroot_arg); - if !sysroot.exists() { - debug!("Failing, sysroot"); - fail!("Package script requires a sysroot that exists;{} doesn't", sysroot.display()); - } - - if args[2] != ~"install" { - debug!("Failing, weird command"); - println!("Warning: I don't know how to {}", args[2]); - return; - } - - debug!("Checking self_exe_path"); - let out_path = os::self_exe_path().expect("Couldn't get self_exe path"); - - debug!("Writing file"); - let mut file = File::create(&out_path.join("generated.rs")); - file.write("pub fn wheeeee() { let xs = [1, 2, 3]; \ - for _ in xs.iter() { assert!(true); } }".as_bytes()); - - let context = api::default_context(sysroot, api::default_workspace()); - api::install_pkg(&context, os::getcwd(), ~"fancy-lib", None, ~[]); -} diff --git a/src/librustpkg/testsuite/pass/src/foo/lib.rs b/src/librustpkg/testsuite/pass/src/foo/lib.rs deleted file mode 100644 index 63743160d12..00000000000 --- a/src/librustpkg/testsuite/pass/src/foo/lib.rs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -pub fn f() {} diff --git a/src/librustpkg/testsuite/pass/src/hello-world/main.rs b/src/librustpkg/testsuite/pass/src/hello-world/main.rs deleted file mode 100644 index 54b536664a3..00000000000 --- a/src/librustpkg/testsuite/pass/src/hello-world/main.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/* -The test runner should check that, after `rustpkg build hello-world`: - * testsuite/pass/hello-world/build/ exists - * testsuite/pass/hello-world/build/ contains an executable named hello-world - * testsuite/pass/hello-world/build/ does not contain a library - - It should also check that after `rustpkg clean hello-world`: - * testsuite/pass/hello-world/build is empty -*/ - -fn main() { - println!("Hello world!"); -} diff --git a/src/librustpkg/testsuite/pass/src/install-paths/bench.rs b/src/librustpkg/testsuite/pass/src/install-paths/bench.rs deleted file mode 100644 index 62ee0ed88fd..00000000000 --- a/src/librustpkg/testsuite/pass/src/install-paths/bench.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[bench] -pub fn g() { - let mut x = 0; - while x < 1000 { - x += 1; - } -} diff --git a/src/librustpkg/testsuite/pass/src/install-paths/lib.rs b/src/librustpkg/testsuite/pass/src/install-paths/lib.rs deleted file mode 100644 index 2cc0056696f..00000000000 --- a/src/librustpkg/testsuite/pass/src/install-paths/lib.rs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -pub fn f() -> int { 42 } diff --git a/src/librustpkg/testsuite/pass/src/install-paths/main.rs b/src/librustpkg/testsuite/pass/src/install-paths/main.rs deleted file mode 100644 index 431350c07b4..00000000000 --- a/src/librustpkg/testsuite/pass/src/install-paths/main.rs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/* -The test runner should check that, after `rustpkg install install-paths` - with RUST_PATH undefined in the environment: - * ./.rust/install_paths exists and is an executable - * ./.rust/libinstall_paths exists and is a library - * ./.rust/install_pathstest does not exist - * ./.rust/install_pathsbench does not exist - * install-paths/build/install_pathstest exists and is an executable - * install-paths/build/install_pathsbench exists and is an executable -*/ - -use lib::f; - -mod lib; - -fn main() { - f(); -} diff --git a/src/librustpkg/testsuite/pass/src/install-paths/test.rs b/src/librustpkg/testsuite/pass/src/install-paths/test.rs deleted file mode 100644 index 011a1540e1b..00000000000 --- a/src/librustpkg/testsuite/pass/src/install-paths/test.rs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[test] -fn test_two_plus_two() { - assert_eq!(2 + 2, 4); -} diff --git a/src/librustpkg/testsuite/pass/src/simple-lib/src/bar.rs b/src/librustpkg/testsuite/pass/src/simple-lib/src/bar.rs deleted file mode 100644 index ffbc6e2a7f9..00000000000 --- a/src/librustpkg/testsuite/pass/src/simple-lib/src/bar.rs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -pub fn assert_true() { - assert!(true); -} diff --git a/src/librustpkg/testsuite/pass/src/simple-lib/src/foo.rs b/src/librustpkg/testsuite/pass/src/simple-lib/src/foo.rs deleted file mode 100644 index 3b233c9f6a8..00000000000 --- a/src/librustpkg/testsuite/pass/src/simple-lib/src/foo.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -pub fn do_nothing() { -} diff --git a/src/librustpkg/testsuite/pass/src/simple-lib/src/lib.rs b/src/librustpkg/testsuite/pass/src/simple-lib/src/lib.rs deleted file mode 100644 index 1cdca6cdd5d..00000000000 --- a/src/librustpkg/testsuite/pass/src/simple-lib/src/lib.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/* -The test runner should check that, after `rustpkg build simple-lib`: - * testsuite/simple-lib/build/ exists - * testsuite/simple-lib/build/ contains a library named libsimple_lib - * testsuite/simple-lib/build/ does not contain an executable -*/ - -extern mod std; - -pub mod foo; -pub mod bar; diff --git a/src/librustpkg/usage.rs b/src/librustpkg/usage.rs deleted file mode 100644 index 04cc13d0650..00000000000 --- a/src/librustpkg/usage.rs +++ /dev/null @@ -1,181 +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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use context::Command; - -pub fn general() { - println!("Usage: rustpkg [options] [args..] - -Where is one of: - build, clean, do, info, install, list, prefer, test, uninstall, unprefer - -For more help on a given command, you can run: - rustpkg help - -Options: - - -h, --help Display this message - --sysroot PATH Override the system root - -h, --help Display help for "); -} - -pub fn build() { - println!("rustpkg build [options..] [package-ID] - -Build the given package ID if specified. With no package ID argument, -build the package in the current directory. In that case, the current -directory must be a direct child of an `src` directory in a workspace. - -Options: - -c, --cfg Pass a cfg flag to the package script - --no-link Compile and assemble, but don't link (like -c in rustc) - --no-trans Parse and translate, but don't generate any code - --pretty Pretty-print the code, but don't generate output - --parse-only Parse the code, but don't typecheck or generate code - -S Generate assembly code, but don't assemble or link it - -S --emit-llvm Generate LLVM assembly code - --emit-llvm Generate LLVM bitcode - --linker PATH Use a linker other than the system linker - --link-args [ARG..] Extra arguments to pass to the linker - --opt-level=n Set the optimization level (0 <= n <= 3) - -O Equivalent to --opt-level=2 - --save-temps Don't delete temporary files - --target TRIPLE Set the target triple - --target-cpu CPU Set the target CPU - -Z FLAG Enable an experimental rustc feature (see `rustc --help`)"); -} - -pub fn clean() { - println!("rustpkg clean - -Remove all build files in the work cache for the package in the current -directory."); -} - -pub fn do_cmd() { - println!(r"rustpkg do - -Runs a command in the package script. You can listen to a command -by tagging a function with the attribute `\#[pkg_do(cmd)]`."); -} - -pub fn info() { - println!("rustpkg [options..] info - -Probe the package script in the current directory for information. - -Options: - -j, --json Output the result as JSON"); -} - -pub fn list() { - println!("rustpkg list - -List all installed packages."); -} - -pub fn install() { - println!(r"rustpkg install [options..] [package-ID] - -Install the given package ID if specified. With no package ID -argument, install the package in the current directory. -In that case, the current directory must be a direct child of a -`src` directory in a workspace. - -Examples: - rustpkg install - rustpkg install github.com/mozilla/servo - rustpkg install github.com/mozilla/servo\#0.1.2 - -Options: - -c, --cfg Pass a cfg flag to the package script - --emit-llvm Generate LLVM bitcode - --linker PATH Use a linker other than the system linker - --link-args [ARG..] Extra arguments to pass to the linker - --opt-level=n Set the optimization level (0 <= n <= 3) - -O Equivalent to --opt-level=2 - --save-temps Don't delete temporary files - --target TRIPLE Set the target triple - --target-cpu CPU Set the target CPU - -Z FLAG Enable an experimental rustc feature (see `rustc --help`)"); -} - -pub fn uninstall() { - println!("rustpkg uninstall [@version] - -Remove a package by id or name and optionally version. If the package(s) -is/are depended on by another package then they cannot be removed."); -} - -pub fn prefer() { - println!("rustpkg [options..] prefer [@version] - -By default all binaries are given a unique name so that multiple versions can -coexist. The prefer command will symlink the uniquely named binary to -the binary directory under its bare name. If version is not supplied, the -latest version of the package will be preferred. - -Example: - export PATH=$PATH:/home/user/.rustpkg/bin - rustpkg prefer machine@1.2.4 - machine -v - ==> v1.2.4 - rustpkg prefer machine@0.4.6 - machine -v - ==> v0.4.6"); -} - -pub fn unprefer() { - println!("rustpkg [options..] unprefer [@version] - -Remove all symlinks from the store to the binary directory for a package -name and optionally version. If version is not supplied, the latest version -of the package will be unpreferred. See `rustpkg prefer -h` for more -information."); -} - -pub fn test() { - println!("rustpkg [options..] test - -Build all test crates in the current directory with the test flag. -Then, run all the resulting test executables, redirecting the output -and exit code. - -Options: - -c, --cfg Pass a cfg flag to the package script"); -} - -pub fn init() { - println!("rustpkg init - -This will turn the current working directory into a workspace. The first -command you run when starting off a new project. -"); -} - -pub fn usage_for_command(command: Command){ - match command { - BuildCmd => build(), - CleanCmd => clean(), - DoCmd => do_cmd(), - HelpCmd => general(), - InfoCmd => info(), - InstallCmd => install(), - ListCmd => list(), - PreferCmd => prefer(), - TestCmd => test(), - InitCmd => init(), - UninstallCmd => uninstall(), - UnpreferCmd => unprefer(), - }; -} - - - diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs deleted file mode 100644 index ba31699a7d0..00000000000 --- a/src/librustpkg/util.rs +++ /dev/null @@ -1,699 +0,0 @@ -// Copyright 2012-2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[allow(dead_code)]; - -pub use target::{OutputType, Main, Lib, Bench, Test, JustOne, lib_name_of, lib_crate_filename}; -pub use target::{Target, Build, Install}; -pub use target::{lib_name_of, lib_crate_filename, WhatToBuild, MaybeCustom, Inferred}; - -use std::cell::RefCell; -use std::libc; -use std::os; -use std::io; -use std::io::fs; -use extra::workcache; -use rustc::metadata::creader::Loader; -use extra::treemap::TreeMap; -use extra::getopts::groups::getopts; -use syntax; -use syntax::codemap::{DUMMY_SP, Spanned}; -use syntax::ext::base; -use syntax::ext::base::{ExtCtxt, MacroCrate}; -use syntax::{ast, attr, codemap, diagnostic, fold, visit}; -use syntax::attr::AttrMetaMethods; -use syntax::fold::Folder; -use syntax::parse::token::InternedString; -use syntax::parse::token; -use syntax::visit::Visitor; -use syntax::util::small_vector::SmallVector; -use syntax::crateid::CrateId; -use rustc::back::link::OutputTypeExe; -use rustc::back::link; -use rustc::driver::{driver, session}; -use CtxMethods; -use context::{in_target, StopBefore, Link, Assemble, BuildContext}; -use package_source::PkgSrc; -use workspace::pkg_parent_workspaces; -use path_util::{system_library, target_build_dir}; -use path_util::{default_workspace, built_library_in_workspace}; -use workcache_support::{digest_file_with_date, digest_only_date}; -use messages::error; - - -pub type ExitCode = int; // For now - -pub struct Pkg { - id: CrateId, - bins: ~[~str], - libs: ~[~str], -} - -impl ToStr for Pkg { - fn to_str(&self) -> ~str { - self.id.to_str() - } -} - -struct ListenerFn { - cmds: ~[~str], - span: codemap::Span, - path: ~[ast::Ident] -} - -struct ReadyCtx<'a> { - sess: session::Session, - ext_cx: ExtCtxt<'a>, - path: ~[ast::Ident], - fns: ~[ListenerFn] -} - -fn fold_mod(m: &ast::Mod, fold: &mut CrateSetup) -> ast::Mod { - fn strip_main(item: @ast::Item) -> @ast::Item { - @ast::Item { - attrs: item.attrs.iter().filter_map(|attr| { - if !attr.name().equiv(&("main")) { - Some(*attr) - } else { - None - } - }).collect(), - .. (*item).clone() - } - } - - fold::noop_fold_mod(&ast::Mod { - items: m.items.map(|item| strip_main(*item)), - .. (*m).clone() - }, fold) -} - -fn fold_item(item: @ast::Item, fold: &mut CrateSetup) - -> SmallVector<@ast::Item> { - fold.ctx.path.push(item.ident); - - let mut cmds = ~[]; - let mut had_pkg_do = false; - - for attr in item.attrs.iter() { - if attr.name().equiv(&("pkg_do")) { - had_pkg_do = true; - match attr.node.value.node { - ast::MetaList(_, ref mis) => { - for mi in mis.iter() { - match mi.node { - ast::MetaWord(ref cmd) => { - cmds.push(cmd.get().to_owned()) - } - _ => {} - }; - } - } - _ => cmds.push(~"build") - } - } - } - - if had_pkg_do { - fold.ctx.fns.push(ListenerFn { - cmds: cmds, - span: item.span, - path: /*bad*/fold.ctx.path.clone() - }); - } - - let res = fold::noop_fold_item(item, fold); - - fold.ctx.path.pop(); - - res -} - -struct CrateSetup<'a> { - ctx: &'a mut ReadyCtx<'a>, -} - -impl<'a> Folder for CrateSetup<'a> { - fn fold_item(&mut self, item: @ast::Item) -> SmallVector<@ast::Item> { - fold_item(item, self) - } - fn fold_mod(&mut self, module: &ast::Mod) -> ast::Mod { - fold_mod(module, self) - } -} - -/// Generate/filter main function, add the list of commands, etc. -pub fn ready_crate(sess: session::Session, - crate: ast::Crate) -> ast::Crate { - let loader = &mut Loader::new(sess); - let mut ctx = ReadyCtx { - sess: sess, - ext_cx: ExtCtxt::new(sess.parse_sess, sess.opts.cfg.clone(), loader), - path: ~[], - fns: ~[] - }; - let mut fold = CrateSetup { - ctx: &mut ctx, - }; - fold.fold_crate(crate) -} - -pub fn compile_input(context: &BuildContext, - exec: &mut workcache::Exec, - crate_id: &CrateId, - in_file: &Path, - workspace: &Path, - deps: &mut DepMap, - flags: &[~str], - cfgs: &[~str], - opt: session::OptLevel, - what: OutputType) -> Option { - assert!(in_file.components().nth(1).is_some()); - let input = driver::FileInput(in_file.clone()); - debug!("compile_input: {} / {:?}", in_file.display(), what); - // tjc: by default, use the package ID name as the link name - // not sure if we should support anything else - - let mut out_dir = target_build_dir(workspace); - out_dir.push(crate_id.path.as_slice()); - // Make the output directory if it doesn't exist already - fs::mkdir_recursive(&out_dir, io::UserRWX); - - let binary = os::args()[0]; - - debug!("flags: {}", flags.connect(" ")); - debug!("cfgs: {}", cfgs.connect(" ")); - let csysroot = context.sysroot(); - debug!("compile_input's sysroot = {}", csysroot.display()); - - let matches = getopts(debug_flags() - + match what { - Lib => ~[~"--lib"], - // --test compiles both #[test] and #[bench] fns - Test | Bench => ~[~"--test"], - Main => ~[] - } - + flags - + context.flag_strs() - + cfgs.flat_map(|c| { ~[~"--cfg", (*c).clone()] }), - driver::optgroups()).unwrap(); - debug!("rustc flags: {:?}", matches); - - // Hack so that rustpkg can run either out of a rustc target dir, - // or the host dir - let sysroot_to_use = @if !in_target(&context.sysroot()) { - context.sysroot() - } - else { - let mut p = context.sysroot().clone(); - p.pop(); - p.pop(); - p.pop(); - p - }; - let csysroot = context.sysroot(); - debug!("compile_input's sysroot = {}", csysroot.display()); - debug!("sysroot_to_use = {}", sysroot_to_use.display()); - - let output_type = match context.compile_upto() { - Assemble => link::OutputTypeAssembly, - Link => link::OutputTypeObject, - Pretty | Trans | Analysis => link::OutputTypeNone, - LLVMAssemble => link::OutputTypeLlvmAssembly, - LLVMCompileBitcode => link::OutputTypeBitcode, - Nothing => link::OutputTypeExe - }; - - debug!("Output type = {:?}", output_type); - - let options = @session::Options { - optimize: opt, - test: what == Test || what == Bench, - maybe_sysroot: Some(sysroot_to_use), - addl_lib_search_paths: - @RefCell::new(context.additional_library_paths()), - output_type: output_type, - .. (*driver::build_session_options(binary, - &matches, - @diagnostic::DefaultEmitter as - @diagnostic::Emitter)).clone() - }; - - debug!("Created options..."); - - let addl_lib_search_paths = @RefCell::new(options.addl_lib_search_paths); - // Make sure all the library directories actually exist, since the linker will complain - // otherwise - { - let mut addl_lib_search_paths = addl_lib_search_paths.borrow_mut(); - let addl_lib_search_paths = addl_lib_search_paths.get(); - let mut addl_lib_search_paths = addl_lib_search_paths.borrow_mut(); - for p in addl_lib_search_paths.get().iter() { - if p.exists() { - assert!(p.is_dir()) - } - else { - fs::mkdir_recursive(p, io::UserRWX); - } - } - } - - debug!("About to build session..."); - - let sess = driver::build_session(options, - Some(in_file.clone()), - @diagnostic::DefaultEmitter as - @diagnostic::Emitter); - - debug!("About to build config..."); - - // Infer dependencies that rustpkg needs to build, by scanning for - // `extern mod` directives. - let cfg = driver::build_configuration(sess); - let crate = driver::phase_1_parse_input(sess, cfg.clone(), &input); - - let (mut crate, ast_map) = { - let installer = CrateInstaller { - context: context, - parent: crate_id, - parent_crate: in_file, - sess: sess, - exec: exec, - deps: deps, - save: |p| { - debug!("a dependency: {}", p.display()); - let mut addl_lib_search_paths = - addl_lib_search_paths.borrow_mut(); - let addl_lib_search_paths = - addl_lib_search_paths.get(); - let mut addl_lib_search_paths = - addl_lib_search_paths.borrow_mut(); - // Pass the directory containing a dependency - // as an additional lib search path - addl_lib_search_paths.get().insert(p); - }, - }; - let mut loader = CrateLoader { - installer: installer, - loader: Loader::new(sess), - }; - let (crate, ast_map) = driver::phase_2_configure_and_expand(sess, - cfg.clone(), - &mut loader, - crate); - let CrateLoader { mut installer, .. } = loader; - debug!("About to call find_and_install_dependencies..."); - find_and_install_dependencies(&mut installer, &crate); - (crate, ast_map) - }; - - // Inject the crate_id attribute so we get the right package name and version - if !attr::contains_name(crate.attrs, "crate_id") { - // FIXME (#9639): This needs to handle non-utf8 paths - let crateid_attr = - attr::mk_name_value_item_str( - InternedString::new("crate_id"), - token::intern_and_get_ident(crate_id.to_str())); - - debug!("crateid attr: {:?}", crateid_attr); - crate.attrs.push(attr::mk_attr(crateid_attr)); - } - - debug!("calling compile_crate_from_input, workspace = {}, - building_library = {:?}", out_dir.display(), sess.building_library); - let result = compile_crate_from_input(in_file, - exec, - context.compile_upto(), - &out_dir, - sess, - crate, - ast_map, - what); - // Discover the output - let discovered_output = if what == Lib { - built_library_in_workspace(crate_id, workspace) // Huh??? - } - else { - result - }; - for p in discovered_output.iter() { - debug!("About to discover output {}", p.display()); - if p.exists() { - debug!("4. discovering output {}", p.display()); - // FIXME (#9639): This needs to handle non-utf8 paths - exec.discover_output("binary", p.as_str().unwrap(), digest_only_date(p)); - } - // Nothing to do if it doesn't exist -- that could happen if we had the - // -S or -emit-llvm flags, etc. - } - discovered_output -} - -// Should use workcache to avoid recompiling when not necessary -// Should also rename this to something better -// If crate_opt is present, then finish compilation. If it's None, then -// call compile_upto and return the crate -// also, too many arguments -// Returns list of discovered dependencies -pub fn compile_crate_from_input(input: &Path, - exec: &mut workcache::Exec, - stop_before: StopBefore, - // should be of the form /build/ - out_dir: &Path, - sess: session::Session, -// Returns None if one of the flags that suppresses compilation output was -// given - crate: ast::Crate, - ast_map: syntax::ast_map::Map, - what: OutputType) -> Option { - debug!("Calling build_output_filenames with {}, building library? {:?}", - out_dir.display(), sess.building_library); - - // bad copy - debug!("out_dir = {}", out_dir.display()); - let file_input = driver::FileInput(input.clone()); - let mut outputs = driver::build_output_filenames(&file_input, - &Some(out_dir.clone()), &None, - crate.attrs, sess); - match what { - Lib | Main => {} - Test => { - let mut ofile = outputs.out_filename.filename_str().unwrap().to_owned(); - ofile.push_str("test"); - outputs.out_filename.set_filename(ofile); - } - Bench => { - let mut ofile = outputs.out_filename.filename_str().unwrap().to_owned(); - ofile.push_str("bench"); - outputs.out_filename.set_filename(ofile); - } - }; - - debug!("Outputs are out_filename: {} and obj_filename: {} and output type = {:?}", - outputs.out_filename.display(), - outputs.obj_filename.display(), - sess.opts.output_type); - debug!("additional libraries:"); - { - let addl_lib_search_paths = sess.opts.addl_lib_search_paths.borrow(); - for lib in addl_lib_search_paths.get().iter() { - debug!("an additional library: {}", lib.display()); - } - } - let analysis = driver::phase_3_run_analysis_passes(sess, &crate, ast_map); - if driver::stop_after_phase_3(sess) { return None; } - let translation = driver::phase_4_translate_to_llvm(sess, crate, - &analysis, - outputs); - driver::phase_5_run_llvm_passes(sess, &translation, outputs); - // The second check shouldn't be necessary, but rustc seems to ignore - // -c - if driver::stop_after_phase_5(sess) - || stop_before == Link || stop_before == Assemble { return Some(outputs.out_filename); } - driver::phase_6_link_output(sess, &translation, outputs); - - // Register dependency on the source file - // FIXME (#9639): This needs to handle non-utf8 paths - exec.discover_input("file", input.as_str().unwrap(), digest_file_with_date(input)); - - debug!("Built {}, date = {:?}", outputs.out_filename.display(), - datestamp(&outputs.out_filename)); - Some(outputs.out_filename) -} - -#[cfg(windows)] -pub fn exe_suffix() -> ~str { ~".exe" } - -#[cfg(target_os = "linux")] -#[cfg(target_os = "android")] -#[cfg(target_os = "freebsd")] -#[cfg(target_os = "macos")] -pub fn exe_suffix() -> ~str { ~"" } - -// Called by build_crates -pub fn compile_crate(ctxt: &BuildContext, - exec: &mut workcache::Exec, - crate_id: &CrateId, - crate: &Path, - workspace: &Path, - deps: &mut DepMap, - flags: &[~str], - cfgs: &[~str], - opt: session::OptLevel, - what: OutputType) -> Option { - debug!("compile_crate: crate={}, workspace={}", crate.display(), workspace.display()); - debug!("compile_crate: name = {}, flags =...", crate_id.to_str()); - for fl in flags.iter() { - debug!("+++ {}", *fl); - } - compile_input(ctxt, exec, crate_id, crate, workspace, deps, flags, cfgs, opt, what) -} - -struct CrateInstaller<'a> { - context: &'a BuildContext, - parent: &'a CrateId, - parent_crate: &'a Path, - sess: session::Session, - exec: &'a mut workcache::Exec, - save: 'a |Path|, - deps: &'a mut DepMap -} - -impl<'a> CrateInstaller<'a> { - fn install_crate(&mut self, vi: &ast::ViewItem) { - use conditions::nonexistent_package::cond; - - match vi.node { - // ignore metadata, I guess - ast::ViewItemExternMod(ref lib_ident, ref path_opt, _) => { - let lib_name = match *path_opt { - Some((ref p, _)) => (*p).clone(), - None => token::get_ident(lib_ident.name), - }; - debug!("Finding and installing... {}", lib_name); - let crate_id: CrateId = - from_str(lib_name.get()).expect("valid crate id"); - // Check standard Rust library path first - let whatever = system_library(&self.context.sysroot_to_use(), &crate_id); - debug!("system library returned {:?}", whatever); - match whatever { - Some(ref installed_path) => { - debug!("It exists: {}", installed_path.display()); - // Say that [path for c] has a discovered dependency on - // installed_path - // For binary files, we only hash the datestamp, not the contents. - // I'm not sure what the right thing is. - // Now we know that this crate has a discovered dependency on - // installed_path - // FIXME (#9639): This needs to handle non-utf8 paths - add_dep(self.deps, self.parent_crate.as_str().unwrap().to_owned(), - (~"binary", installed_path.as_str().unwrap().to_owned())); - self.exec.discover_input("binary", - installed_path.as_str().unwrap(), - digest_only_date(installed_path)); - } - None => { - // FIXME #8711: need to parse version out of path_opt - debug!("Trying to install library {}, rebuilding it", crate_id.to_str()); - // Try to install it - // Find all the workspaces in the RUST_PATH that contain this package. - let workspaces = pkg_parent_workspaces(&self.context.context, - &crate_id); - // Three cases: - // (a) `workspaces` is empty. That means there's no local source - // for this package. In that case, we pass the default workspace - // into `PkgSrc::new`, so that if it exists as a remote repository, - // its sources will be fetched into it. We also put the output in the - // same workspace. - // (b) We're using the Rust path hack. In that case, the output goes - // in the destination workspace. - // (c) `workspaces` is non-empty -- we found a local source for this - // package and will build in that workspace. - let (source_workspace, dest_workspace) = if workspaces.is_empty() { - (default_workspace(), default_workspace()) - } else { - if self.context.context.use_rust_path_hack { - (workspaces[0], default_workspace()) - } else { - (workspaces[0].clone(), workspaces[0]) - } - }; - // In this case, the source and destination workspaces are the same: - // Either it's a remote package, so the local sources don't exist - // and the `PkgSrc` constructor will detect that; - // or else it's already in a workspace and we'll build into that - // workspace - let pkg_src = cond.trap(|_| { - // Nonexistent package? Then print a better error - error(format!("Package {} depends on {}, but I don't know \ - how to find it", - self.parent.path, - crate_id.path)); - fail!() - }).inside(|| { - PkgSrc::new(source_workspace.clone(), - dest_workspace.clone(), - // Use the rust_path_hack to search for dependencies iff - // we were already using it - self.context.context.use_rust_path_hack, - crate_id.clone()) - }); - let (outputs_disc, inputs_disc) = - self.context.install( - pkg_src, - &WhatToBuild::new(Inferred, - JustOne(Path::new(lib_crate_filename)))); - debug!("Installed {}, returned {:?} dependencies and \ - {:?} transitive dependencies", - lib_name, outputs_disc.len(), inputs_disc.len()); - debug!("discovered outputs = {:?} discovered_inputs = {:?}", - outputs_disc, inputs_disc); - // It must have installed *something*... - assert!(!outputs_disc.is_empty()); - for dep in outputs_disc.iter() { - debug!("Discovering a binary input: {}", dep.display()); - // FIXME (#9639): This needs to handle non-utf8 paths - self.exec.discover_input("binary", - dep.as_str().unwrap(), - digest_only_date(dep)); - add_dep(self.deps, - self.parent_crate.as_str().unwrap().to_owned(), - (~"binary", dep.as_str().unwrap().to_owned())); - - // Also, add an additional search path - let dep_dir = dep.dir_path(); - debug!("Installed {} into {}", dep.display(), dep_dir.display()); - (self.save)(dep_dir); - } - debug!("Installed {}, returned {} dependencies and \ - {} transitive dependencies", - lib_name, outputs_disc.len(), inputs_disc.len()); - // It must have installed *something*... - assert!(!outputs_disc.is_empty()); - let mut target_workspace = outputs_disc[0].clone(); - target_workspace.pop(); - for &(ref what, ref dep) in inputs_disc.iter() { - if *what == ~"file" { - add_dep(self.deps, - self.parent_crate.as_str().unwrap().to_owned(), - (~"file", dep.clone())); - self.exec.discover_input(*what, - *dep, - digest_file_with_date( - &Path::new(dep.as_slice()))); - } else if *what == ~"binary" { - add_dep(self.deps, - self.parent_crate.as_str().unwrap().to_owned(), - (~"binary", dep.clone())); - self.exec.discover_input(*what, - *dep, - digest_only_date( - &Path::new(dep.as_slice()))); - } else { - fail!("Bad kind: {}", *what); - } - // Also, add an additional search path - debug!("Installed {} into {}", - lib_name, target_workspace.as_str().unwrap().to_owned()); - (self.save)(target_workspace.clone()); - } - } - } - } - // Ignore `use`s - _ => () - } - } -} - -impl<'a> Visitor<()> for CrateInstaller<'a> { - fn visit_view_item(&mut self, vi: &ast::ViewItem, env: ()) { - self.install_crate(vi); - visit::walk_view_item(self, vi, env) - } -} - -struct CrateLoader<'a> { - installer: CrateInstaller<'a>, - loader: Loader, -} - -impl<'a> base::CrateLoader for CrateLoader<'a> { - fn load_crate(&mut self, crate: &ast::ViewItem) -> MacroCrate { - self.installer.install_crate(crate); - self.loader.load_crate(crate) - } - - fn get_exported_macros(&mut self, cnum: ast::CrateNum) -> ~[~str] { - self.loader.get_exported_macros(cnum) - } - - fn get_registrar_symbol(&mut self, cnum: ast::CrateNum) -> Option<~str> { - self.loader.get_registrar_symbol(cnum) - } -} - -/// Collect all `extern mod` directives in `c`, then -/// try to install their targets, failing if any target -/// can't be found. -pub fn find_and_install_dependencies(installer: &mut CrateInstaller, - c: &ast::Crate) { - debug!("In find_and_install_dependencies..."); - visit::walk_crate(installer, c, ()) -} - -pub fn mk_string_lit(s: InternedString) -> ast::Lit { - Spanned { - node: ast::LitStr(s, ast::CookedStr), - span: DUMMY_SP - } -} - -pub fn option_to_vec(x: Option) -> ~[T] { - match x { - Some(y) => ~[y], - None => ~[] - } -} - -// tjc: cheesy -fn debug_flags() -> ~[~str] { ~[] } -// static DEBUG_FLAGS: ~[~str] = ~[~"-Z", ~"time-passes"]; - - -/// Returns the last-modified date as an Option -pub fn datestamp(p: &Path) -> Option { - debug!("Scrutinizing datestamp for {} - does it exist? {:?}", p.display(), - p.exists()); - match io::result(|| p.stat()) { - Ok(s) => { - let out = s.modified; - debug!("Date = {:?}", out); - Some(out as libc::time_t) - } - Err(..) => None, - } -} - -pub type DepMap = TreeMap<~str, ~[(~str, ~str)]>; - -/// Records a dependency from `parent` to the kind and value described by `info`, -/// in `deps` -fn add_dep(deps: &mut DepMap, parent: ~str, info: (~str, ~str)) { - let mut done = false; - let info_clone = info.clone(); - match deps.find_mut(&parent) { - None => { } - Some(v) => { done = true; (*v).push(info) } - }; - if !done { - deps.insert(parent, ~[info_clone]); - } -} diff --git a/src/librustpkg/version.rs b/src/librustpkg/version.rs deleted file mode 100644 index 93e7a052efa..00000000000 --- a/src/librustpkg/version.rs +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/// A version is either an exact revision, -/// or a semantic version - -extern mod std; - -use std::char; - -pub type Version = Option<~str>; - -// Being lazy since we don't have a regexp library now -#[deriving(Eq)] -enum ParseState { - Start, - SawDigit, - SawDot -} - -pub fn try_parsing_version(s: &str) -> Option<~str> { - let s = s.trim(); - debug!("Attempting to parse: {}", s); - let mut parse_state = Start; - for c in s.chars() { - if char::is_digit(c) { - parse_state = SawDigit; - } - else if c == '.' && parse_state == SawDigit { - parse_state = SawDot; - } - else { - return None; - } - } - match parse_state { - SawDigit => Some(s.to_owned()), - _ => None - } -} - -/// If s is of the form foo#bar, where bar is a valid version -/// number, return the prefix before the # and the version. -/// Otherwise, return None. -pub fn split_version<'a>(s: &'a str) -> Option<(&'a str, Version)> { - // Check for extra '#' characters separately - if s.split('#').len() > 2 { - return None; - } - split_version_general(s, '#') -} - -pub fn split_version_general<'a>(s: &'a str, sep: char) -> Option<(&'a str, Version)> { - match s.rfind(sep) { - Some(i) => { - let path = s.slice(0, i); - // n.b. for now, assuming an exact revision is intended, not a SemVer - Some((path, Some(s.slice(i + 1, s.len()).to_owned()))) - } - None => { - None - } - } -} - -#[test] -fn test_parse_version() { - assert!(try_parsing_version("1.2") == Some(~"1.2")); - assert!(try_parsing_version("1.0.17") == Some(~"1.0.17")); - assert!(try_parsing_version("you're_a_kitty") == None); - assert!(try_parsing_version("42..1") == None); - assert!(try_parsing_version("17") == Some(~"17")); - assert!(try_parsing_version(".1.2.3") == None); - assert!(try_parsing_version("2.3.") == None); -} - -#[test] -fn test_split_version() { - let s = "a/b/c#0.1"; - debug!("== {:?} ==", split_version(s)); - assert!(split_version(s) == Some((s.slice(0, 5), Some(~"0.1")))); - assert!(split_version("a/b/c") == None); - let s = "a#1.2"; - assert!(split_version(s) == Some((s.slice(0, 1), Some(~"1.2")))); - assert!(split_version("a#a#3.4") == None); -} diff --git a/src/librustpkg/workcache_support.rs b/src/librustpkg/workcache_support.rs deleted file mode 100644 index 824ba5341d4..00000000000 --- a/src/librustpkg/workcache_support.rs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::io; -use std::io::File; -use extra::workcache; -use sha2::{Digest, Sha256}; - -/// Hashes the file contents along with the last-modified time -pub fn digest_file_with_date(path: &Path) -> ~str { - use conditions::bad_path::cond; - - match io::result(|| File::open(path).read_to_end()) { - Ok(bytes) => { - let mut sha = Sha256::new(); - sha.input(bytes); - let st = path.stat(); - sha.input_str(st.modified.to_str()); - sha.result_str() - } - Err(e) => { - cond.raise((path.clone(), format!("Couldn't read file: {}", e.desc))); - ~"" - } - } -} - -/// Hashes only the last-modified time -pub fn digest_only_date(path: &Path) -> ~str { - let mut sha = Sha256::new(); - let st = path.stat(); - sha.input_str(st.modified.to_str()); - sha.result_str() -} - -/// Adds multiple discovered outputs -pub fn discover_outputs(e: &mut workcache::Exec, outputs: ~[Path]) { - debug!("Discovering {:?} outputs", outputs.len()); - for p in outputs.iter() { - debug!("Discovering output! {}", p.display()); - // For now, assume that all discovered outputs are binaries - // FIXME (#9639): This needs to handle non-utf8 paths - e.discover_output("binary", p.as_str().unwrap(), digest_only_date(p)); - } -} - -/// Returns the function name for building a crate -pub fn crate_tag(p: &Path) -> ~str { - // FIXME (#9639): This needs to handle non-utf8 paths - p.as_str().unwrap().to_owned() // implicitly, it's "build(p)"... -} diff --git a/src/librustpkg/workspace.rs b/src/librustpkg/workspace.rs deleted file mode 100644 index e19a19dc8ab..00000000000 --- a/src/librustpkg/workspace.rs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// rustpkg utilities having to do with workspaces - -use std::os; -use context::Context; -use path_util::{workspace_contains_crate_id, find_dir_using_rust_path_hack, default_workspace}; -use path_util::rust_path; -use util::option_to_vec; -use syntax::crateid::CrateId; - -pub fn each_pkg_parent_workspace(cx: &Context, - crateid: &CrateId, - action: |&Path| -> bool) - -> bool { - // Using the RUST_PATH, find workspaces that contain - // this package ID - let workspaces = pkg_parent_workspaces(cx, crateid); - if workspaces.is_empty() { - // tjc: make this a condition - fail!("Package {} not found in any of \ - the following workspaces: {}", - crateid.path, - rust_path().map(|p| p.display().to_str()).to_str()); - } - for ws in workspaces.iter() { - if action(ws) { - break; - } - } - return true; -} - -/// Given a package ID, return a vector of all of the workspaces in -/// the RUST_PATH that contain it -pub fn pkg_parent_workspaces(cx: &Context, crateid: &CrateId) -> ~[Path] { - let rs: ~[Path] = rust_path().move_iter() - .filter(|ws| workspace_contains_crate_id(crateid, ws)) - .collect(); - if cx.use_rust_path_hack { - rs + option_to_vec(find_dir_using_rust_path_hack(crateid)) - } - else { - rs - } -} - -/// Construct a workspace and package-ID name based on the current directory. -/// This gets used when rustpkg gets invoked without a package-ID argument. -pub fn cwd_to_workspace() -> Option<(Path, CrateId)> { - let cwd = os::getcwd(); - for path in rust_path().move_iter() { - let srcpath = path.join("src"); - if srcpath.is_ancestor_of(&cwd) { - let rel = cwd.path_relative_from(&srcpath); - let rel_s = rel.as_ref().and_then(|p|p.as_str()); - if rel_s.is_some() { - let crate_id = from_str(rel_s.unwrap()).expect("valid crate id"); - return Some((path, crate_id)); - } - } - } - None -} - -/// If `workspace` is the same as `cwd`, and use_rust_path_hack is false, -/// return `workspace`; otherwise, return the first workspace in the RUST_PATH. -pub fn determine_destination(cwd: Path, use_rust_path_hack: bool, workspace: &Path) -> Path { - if workspace == &cwd && !use_rust_path_hack { - workspace.clone() - } - else { - default_workspace() - } -} -- 2.44.0