{"id":13502984,"url":"https://github.com/DanielKeep/cargo-script","last_synced_at":"2025-03-29T13:30:33.549Z","repository":{"id":38816144,"uuid":"36552486","full_name":"DanielKeep/cargo-script","owner":"DanielKeep","description":"Cargo script subcommand","archived":false,"fork":false,"pushed_at":"2021-03-03T18:09:41.000Z","size":273,"stargazers_count":741,"open_issues_count":40,"forks_count":37,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-03-03T10:03:34.025Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DanielKeep.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-05-30T09:47:43.000Z","updated_at":"2025-02-18T06:00:21.000Z","dependencies_parsed_at":"2022-07-12T16:11:07.835Z","dependency_job_id":null,"html_url":"https://github.com/DanielKeep/cargo-script","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DanielKeep%2Fcargo-script","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DanielKeep%2Fcargo-script/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DanielKeep%2Fcargo-script/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DanielKeep%2Fcargo-script/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DanielKeep","download_url":"https://codeload.github.com/DanielKeep/cargo-script/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246190168,"owners_count":20737985,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T22:02:32.675Z","updated_at":"2025-03-29T13:30:33.244Z","avatar_url":"https://github.com/DanielKeep.png","language":"Rust","readme":"# `cargo-script`\n\n`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.\n\nSome of `cargo-script`'s features include:\n\n- Reading Cargo manifests embedded in Rust scripts.\n- Caching compiled artefacts (including dependencies) to amortise build times.\n- Supporting executable Rust scripts via UNIX hashbangs and Windows file associations.\n- Evaluating expressions on the command-line.\n- Using expressions as stream filters (*i.e.* for use in command pipelines).\n- Running unit tests and benchmarks from scripts.\n- Custom templates for command-line expressions and filters.\n\n**Note**: `cargo-script` *does not* work when Cargo is instructed to use a target architecture different to the default host architecture.\n\nTable of contents:\n\n- [Installation](#installation)\n  - [Migrating From Previous Versions](#migrating)\n  - [Features](#features)\n  - [Manually Compiling and Installing](#compiling)\n  - [Self-Executing Scripts](#hashbang)\n- [Usage](#usage)\n  - [Scripts](#scripts)\n  - [Expressions](#expressions)\n  - [Stream Filters](#filters)\n  - [Environment Variables](#env-vars)\n  - [Templates](#templates)\n- [Known Issues](#issues)\n- [License](#license)\n  - [Contribution](#contribution)\n\n\u003ca name=\"installation\"\u003e\u003c/a\u003e\n## Installation\n\nThe recommended method for installing `cargo-script` is by using Cargo's `install` subcommand:\n\n```sh\ncargo install cargo-script\n```\n\nIf you have already installed `cargo-script`, you can update to the latest version by using:\n\n```sh\ncargo install --force cargo-script\n```\n\n\u003ca name=\"migrating\"\u003e\u003c/a\u003e\n### Migrating From Previous Versions\n\n`cargo-script` supports migrating data from previous versions.  This is not mandatory, but may be preferred.  Using `cargo script --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:\n\n- 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`.\n\n\u003ca name=\"features\"\u003e\u003c/a\u003e\n### Cargo Features\n\nThe following features are defined:\n\n- `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.\n\n\u003ca name=\"compiling\"\u003e\u003c/a\u003e\n### Manually Compiling and Installing\n\n`cargo-script` requires Rust 1.11 or higher to build.  Rust 1.4+ was supported prior to version 0.2.\n\nOnce built, you should place the resulting executable somewhere on your `PATH`.  At that point, you should be able to invoke it by using `cargo script`.  Note that you *can* run the executable directly, but the first argument will *need* to be `script`.\n\nIf you want to run `cargo script` from a hashbang on UNIX, or via file associations on Windows, you should also install the `run-cargo-script` program somewhere on `PATH`.\n\n\u003ca name=\"hashbang\"\u003e\u003c/a\u003e\n### Self-Executing Scripts\n\nOn 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.\n\nIf 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.\n\nThis 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.\n\nIf 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.\n\n\u003ca name=\"usage\"\u003e\u003c/a\u003e\n## Usage\n\nGenerally, you will want to use `cargo-script` by invoking it as `cargo script` (note the lack of a hypen).  Doing so is equivalent to invoking it as `cargo-script script`.  `cargo-script` supports several other subcommands, which can be accessed by running `cargo-script` directly.  You can also get an overview of the available options using the `--help` flag.\n\n\u003ca name=\"scripts\"\u003e\u003c/a\u003e\n### Scripts\n\nThe primary use for `cargo-script` is for running Rust source files as scripts.  For example:\n\n```shell\n$ echo 'fn main() { println!(\"Hello, World!\"); }' \u003e hello.rs\n$ cargo script hello.rs\nHello, World!\n$ cargo script hello # you can leave off the file extension\nHello, World!\n```\n\nThe output of Cargo will be hidden unless compilation fails, or takes longer than a few seconds.\n\n`cargo-script` will also look for embedded dependency and manifest information in the script.  For example, all of the following are equivalent:\n\n- `now.crs` (code block manifest with UNIX hashbang and `.crs` extension):\n\n    ```rust\n    #!/usr/bin/env run-cargo-script\n    //! This is a regular crate doc comment, but it also contains a partial\n    //! Cargo manifest.  Note the use of a *fenced* code block, and the\n    //! `cargo` \"language\".\n    //!\n    //! ```cargo\n    //! [dependencies]\n    //! time = \"0.1.25\"\n    //! ```\n    extern crate time;\n    fn main() {\n        println!(\"{}\", time::now().rfc822z());\n    }\n    ```\n\n- `now.rs` (dependency-only, short-hand manifest):\n\n    ```rust\n    // cargo-deps: time=\"0.1.25\"\n    // You can also leave off the version number, in which case, it's assumed\n    // to be \"*\".  Also, the `cargo-deps` comment *must* be a single-line\n    // comment, and it *must* be the first thing in the file, after the\n    // hashbang.\n    extern crate time;\n    fn main() {\n        println!(\"{}\", time::now().rfc822z());\n    }\n    ```\n\n    \u003e **Note**: you can write multiple dependencies by separating them with commas.  *E.g.* `time=\"0.1.25\", libc=\"0.2.5\"`.\n\nOn running either of these, `cargo-script` will generate a Cargo package, build it, and run the result.  The output may look something like:\n\n```shell\n$ cargo script now\n    Updating registry `https://github.com/rust-lang/crates.io-index`\n   Compiling winapi-build v0.1.1\n   Compiling winapi v0.2.8\n   Compiling libc v0.2.30\n   Compiling kernel32-sys v0.2.2\n   Compiling time v0.1.38\n   Compiling now v0.1.0 (file:///C:/Users/drk/AppData/Local/Cargo/script-cache/file-now-37cb982cd51cc8b1)\n    Finished release [optimized] target(s) in 49.7 secs\nSun, 17 Sep 2017 20:38:58 +1000\n```\n\nSubsequent runs, provided the script has not changed, will likely just run the cached executable directly:\n\n```shell\n$ cargo script now\nSun, 17 Sep 2017 20:39:40 +1000\n```\n\nUseful command-line arguments:\n\n- `--bench`: Compile and run benchmarks.  Requires a nightly toolchain.\n- `--debug`: Build a debug executable, not an optimised one.\n- `--features \u003cfeatures\u003e`: Cargo features to pass when building and running.\n- `--force`: Force the script to be rebuilt.  Useful if you want to force a recompile with a different toolchain.\n- `--gen-pkg-only`: Generate the Cargo package, but don't compile or run it.  Effectively \"unpacks\" the script into a Cargo package.\n- `--test`: Compile and run tests.\n\n\u003ca name=\"expressions\"\u003e\u003c/a\u003e\n### Expressions\n\n`cargo-script` 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 `\u003cscript\u003e` argument as source code *instead* of as a file path.  For example, code can be executed from the command line in a number of ways:\n\n- `cargo script --dep time --expr \"extern crate time; time::now().rfc822z().to_string()\"`\n- `cargo script --dep time=0.1.38 --expr \"extern crate time; ...\"` - uses a specific version of `time`\n- `cargo script -d time -e \"extern crate time; ...\"` - short form of above\n- `cargo script -D time -e \"...\"` - guess and inject `extern crate time`; this only works when the package and crate names of a dependency match.\n- `cargo script -d time -x time -e \"...\"` - injects `extern crate time`; works when the names do *not* match.\n\nThe code given is embedded into a block expression, evaluated, and printed out using the `Debug` formatter (*i.e.* `{:?}`).\n\nUseful command-line arguments:\n\n- `-d`/`--dep`: add a dependency to the generated `Cargo.toml` manifest.\n- `-x`/`--extern`: inject `extern crate` into generated script.\n- `-D`/`--dep-extern`: do both of the above.\n- `-t`/`--template`: Specify a custom template for this expression (see section on templates).\n\n\u003ca name=\"filters\"\u003e\u003c/a\u003e\n### Stream Filters\n\nYou can use `cargo-script` to write a quick stream filter, by specifying a closure to be called for each line read from stdin, like so:\n\n```text\n$ cat now.crs | cargo script --loop \\\n    \"let mut n=0; move |l| {n+=1; println!(\\\"{:\u003e6}: {}\\\",n,l.trim_right())}\"\n   Compiling loop v0.1.0 (file:///C:/Users/drk/AppData/Local/Cargo/script-cache/loop-58079283761aab8433b1)\n     1: // cargo-deps: time=\"0.1.25\"\n     2: extern crate time;\n     3: fn main() {\n     4:     println!(\"{}\", time::now().rfc822z());\n     5: }\n```\n\nYou can achieve a similar effect to the above by using the `--count` flag, which causes the line number to be passed as a second argument to your closure:\n\n```text\n$ cat now.crs | cargo script --count --loop \\\n    \"|l,n| println!(\\\"{:\u003e6}: {}\\\", n, l.trim_right())\"\n   Compiling loop v0.1.0 (file:///C:/Users/drk/AppData/Local/Cargo/script-cache/loop-58079283761aab8433b1)\n     1: // cargo-deps: time=\"0.1.25\"\n     2: extern crate time;\n     3: fn main() {\n     4:     println!(\"{}\", time::now().rfc822z());\n     5: }\n```\n\nNote that, like with expressions, you can specify a custom template for stream filters.\n\n\u003ca name=\"env-vars\"\u003e\u003c/a\u003e\n### Environment Variables\n\nThe following environment variables are provided to scripts by `cargo-script`:\n\n- `CARGO_SCRIPT_BASE_PATH`: the base path used by `cargo-script` to resolve relative dependency paths.  Note that this is *not* necessarily the same as either the working directory, or the directory in which the script is being compiled.\n\n- `CARGO_SCRIPT_PKG_NAME`: the generated package name of the script.\n\n- `CARGO_SCRIPT_SAFE_NAME`: the file name of the script (sans file extension) being run.  For scripts, this is derived from the script's filename.  May also be `\"expr\"` or `\"loop\"` for those invocations.\n\n- `CARGO_SCRIPT_SCRIPT_PATH`: absolute path to the script being run, assuming one exists.  Set to the empty string for expressions.\n\n\u003ca name=\"templates\"\u003e\u003c/a\u003e\n### Templates\n\nYou can use templates to avoid having to re-specify common code and dependencies.  You can view a list of your templates by running `cargo-script templates list` (note the hyphen), or show the folder in which they should be stored by running `cargo-script templates show`.  You can dump the contents of a template using `cargo-script templates dump NAME`.\n\nTemplates are Rust source files with two placeholders: `#{prelude}` for the auto-generated prelude (which should be placed at the top of the template), and `#{script}` for the contents of the script itself.\n\nFor example, a minimal expression template that adds a dependency and imports some additional symbols might be:\n\n```rust\n// cargo-deps: itertools=\"0.6.2\"\n#![allow(unused_imports)]\n#{prelude}\nextern crate itertools;\nuse std::io::prelude::*;\nuse std::mem;\nuse itertools::Itertools;\n\nfn main() {\n    let result = {\n        #{script}\n    };\n    println!(\"{:?}\", result);\n}\n```\n\nIf stored in the templates folder as `grabbag.rs`, you can use it by passing the name `grabbag` via the `--template` option, like so:\n\n```text\n$ cargo script -t grabbag -e \"mem::size_of::\u003cBox\u003cRead\u003e\u003e()\"\n16\n```\n\nIn addition, there are three built-in templates: `expr`, `loop`, and `loop-count`.  These are used for the `--expr`, `--loop`, and `--loop --count` invocation forms.  They can be overridden by placing templates with the same name in the template folder.  If you have *not* overridden them, you can dump the contents of these built-in templates using the `templates dump` command noted above.\n\n\u003ca name=\"issues\"\u003e\u003c/a\u003e\n## Known Issues\n\n### [Issue #50](https://github.com/DanielKeep/cargo-script/issues/50)\n\nThere is a problem on Windows where `cargo-script` can hang when asking Cargo for the path to a package's compiled executable.  `cargo-script` currently works around this by using an older heuristic to guess this path on affected versions.  This can, however, lead to `cargo-script` being unable to correctly locate a compiled executable.\n\nIf this is a problem, `cargo-script` can be instructed to use the accurate-but-buggy approach by setting the `CARGO_SCRIPT_IGNORE_ISSUE_50` environment variable to any non-empty string.\n\n\u003ca name=\"license\"\u003e\u003c/a\u003e\n## License\n\nLicensed under either of\n\n* MIT license (see [LICENSE](LICENSE) or \u003chttp://opensource.org/licenses/MIT\u003e)\n* Apache License, Version 2.0 (see [LICENSE](LICENSE) or \u003chttp://www.apache.org/licenses/LICENSE-2.0\u003e)\n\nat your option.\n\n\u003ca name=\"contribution\"\u003e\u003c/a\u003e\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you shall be dual licensed as above, without any additional terms or conditions.\n","funding_links":[],"categories":["Rust","Development tools"],"sub_categories":["Build system"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDanielKeep%2Fcargo-script","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FDanielKeep%2Fcargo-script","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDanielKeep%2Fcargo-script/lists"}