# `cargo-script`
`cargo-script` is a Cargo subcommand designed to let people quickly and easily run Rust "scripts" which can make use of Cargo's package ecosystem. It can also evaluate expressions and run filters.
Some of `cargo-script`'s features include:
- Reading Cargo manifests embedded in Rust scripts.
- Caching compiled artefacts (including dependencies) to amortise build times.
- Supporting executable Rust scripts via UNIX hashbangs and Windows file associations.
- Evaluating expressions on the command-line.
- Using expressions as stream filters (*i.e.* for use in command pipelines).
- Running unit tests and benchmarks from scripts.
- Custom templates for command-line expressions and filters.
**Note**: `cargo-script` *does not* work when Cargo is instructed to use a target architecture different to the default host architecture.
Table of contents:
- [Installation](#installation)
- [Migrating From Previous Versions](#migrating)
- [Features](#features)
- [Manually Compiling and Installing](#compiling)
- [Self-Executing Scripts](#hashbang)
- [Usage](#usage)
- [Scripts](#scripts)
- [Expressions](#expressions)
- [Stream Filters](#filters)
- [Environment Variables](#env-vars)
- [Templates](#templates)
- [Known Issues](#issues)
- [License](#license)
- [Contribution](#contribution)
## Installation
The recommended method for installing `cargo-scripter` is by using Cargo's `install` subcommand:
```sh
cargo install cargo-scripter
```
If you have already installed `cargo-scripter`, you can update to the latest version by using:
```sh
cargo install --force cargo-scripter
```
### Migrating From Previous Versions
`cargo-scripter` supports migrating data from previous versions. This is not mandatory, but may be preferred. Using `cargo scripter --migrate-data dry-run` will perform a "dry run", informing you of any applicable migrations. Using the `for-real` option will actually perform the migration. The following migrations may be applicable:
- 0.1 → 0.2: On non-Windows platforms, and when `CARGO_HOME` is defined, moves the location for cached data from `$CARGO_HOME/.cargo` to `$CARGO_HOME`.
### Cargo Features
The following features are defined:
- `suppress-cargo-output` (default): if building the script takes less than 2 seconds and succeeds, `cargo-script` will suppress Cargo's output. Note that this disabled coloured Cargo output on Windows.
### Manually Compiling and Installing
`cargo-scripter` requires Rust 1.11 or higher to build. Rust 1.4+ was supported prior to version 0.2.
Once built, you should place the resulting executable somewhere on your `PATH`. At that point, you should be able to invoke it by using `cargo scripter`. Note that you *can* run the executable directly, but the first argument will *need* to be `scripter`.
If you want to run `cargo scripter` from a hashbang on UNIX, or via file associations on Windows, you should also install the `run-cargo-scripter` program somewhere on `PATH`.
### Self-Executing Scripts
On UNIX systems, you can use `#!/usr/bin/env run-cargo-script` as a hashbang line in a Rust script. If the script file is executable, this will allow you to execute a script file directly.
There is also `run-cargo-script-force` variant for a "forced" version of `cargo scripter --force` run.
If you are using Windows, you can associate the `.crs` extension (which is simply a renamed `.rs` file) with `run-cargo-script`. This allows you to execute Rust scripts simply by naming them like any other executable or script.
This can be done using the `cargo-script file-association` command (note the hyphen in `cargo-script`). This command can also remove the file association. If you pass `--amend-pathext` to the `file-assocation install` command, it will also allow you to execute `.crs` scripts *without* having to specify the file extension, in the same way that `.exe` and `.bat` files can be used.
If you want to make a script usable across platforms, it is recommended that you use *both* a hashbang line *and* give the file a `.crs` file extension.
## Usage
Generally, you will want to use `cargo-scripter` by invoking it as `cargo scripter` (note the lack of a hypen). Doing so is equivalent to invoking it as `cargo-script scripter`. `cargo-scripter` supports several other subcommands, which can be accessed by running `cargo-scripter` directly. You can also get an overview of the available options using the `--help` flag.
### Scripts
The primary use for `cargo-scripter` is for running Rust source files as scripts. For example:
```shell
$ echo 'fn main() { println!("Hello, World!"); }' > hello.rs
$ cargo scripter hello.rs
Hello, World!
$ cargo scripter hello # you can leave off the file extension
Hello, World!
```
The output of Cargo will be hidden unless compilation fails, or takes longer than a few seconds.
`cargo-scripter` will also look for embedded dependency and manifest information in the script. For example, all of the following are equivalent:
- `now.crs` (code block manifest with UNIX hashbang and `.crs` extension):
```rust
#!/usr/bin/env run-cargo-script
//! This is a regular crate doc comment, but it also contains a partial
//! Cargo manifest. Note the use of a *fenced* code block, and the
//! `cargo` "language".
//!
//! ```cargo
//! [dependencies]
//! time = "0.1.25"
//! ```
extern crate time;
fn main() {
println!("{}", time::now().rfc822z());
}
```
- `now.rs` (dependency-only, short-hand manifest):
```rust
// cargo-deps: time="0.1.25"
// You can also leave off the version number, in which case, it's assumed
// to be "*". Also, the `cargo-deps` comment *must* be a single-line
// comment, and it *must* be the first thing in the file, after the
// hashbang.
extern crate time;
fn main() {
println!("{}", time::now().rfc822z());
}
```
> **Note**: you can write multiple dependencies by separating them with commas. *E.g.* `time="0.1.25", libc="0.2.5"`.
On running either of these, `cargo-scripter` will generate a Cargo package, build it, and run the result. The output may look something like:
```shell
$ cargo scripter now
Updating registry `https://github.com/rust-lang/crates.io-index`
Compiling winapi-build v0.1.1
Compiling winapi v0.2.8
Compiling libc v0.2.30
Compiling kernel32-sys v0.2.2
Compiling time v0.1.38
Compiling now v0.1.0 (file:///C:/Users/drk/AppData/Local/Cargo/script-cache/file-now-37cb982cd51cc8b1)
Finished release [optimized] target(s) in 49.7 secs
Sun, 17 Sep 2017 20:38:58 +1000
```
Subsequent runs, provided the script has not changed, will likely just run the cached executable directly:
```shell
$ cargo scripter now
Sun, 17 Sep 2017 20:39:40 +1000
```
Useful command-line arguments:
- `--bench`: Compile and run benchmarks. Requires a nightly toolchain.
- `--debug`: Build a debug executable, not an optimised one.
- `--features `: Cargo features to pass when building and running.
- `--force`: Force the script to be rebuilt. Useful if you want to force a recompile with a different toolchain.
- `--gen-pkg-only`: Generate the Cargo package, but don't compile or run it. Effectively "unpacks" the script into a Cargo package.
- `--test`: Compile and run tests.
### Expressions
`cargo-scripter` can also run pieces of Rust code directly from the command line. This is done by providing the `--expr` option; this causes `cargo-script` to interpret the `