diff --git a/.travis.yml b/.travis.yml index d474f41..f9a6516 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,21 +1,42 @@ language: rust +dist: trusty + +os: + - linux + - osx + +addons: + apt: + sources: + # Provides newer gcc. + - ubuntu-toolchain-r-test + # Provides libclang 3.9. + - llvm-toolchain-trusty-3.9 + packages: + - autoconf2.13 + # bindgen requires libclang >= 3.9. + - clang-3.9 + # SpiderMonkey needs gcc >= 4.9 and 5 is ICEing. + - gcc-6 + - g++-6 + rust: - - stable - - beta - nightly cache: cargo env: matrix: - - PROFILE="--release" - - PROFILE="" + - PROFILE="--release" FEATURES="" + - PROFILE="" FEATURES="" + - PROFILE="--release" FEATURES="--features debugmozjs" + - PROFILE="" FEATURES="--features debugmozjs" +before_install: +- source ./ci/before_install.sh script: - - cargo build $PROFILE --verbose - - cargo test $PROFILE --verbose - - if [[ "$PROFILE" == "--release" ]]; then - cargo bench; - fi + - ccache -z + - PROFILE="$PROFILE" FEATURES="$FEATURES" travis_wait ./ci/script.sh + - ccache --show-stats diff --git a/Cargo.lock b/Cargo.lock index 96342b7..70d2822 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,9 @@ name = "starling" version = "0.1.0" dependencies = [ + "backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.26.0 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", "js 0.1.4 (git+https://github.com/fitzgen/mozjs?branch=smup)", "tokio-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -38,6 +41,30 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "backtrace" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cpp_demangle 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "backtrace-sys" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bindgen" version = "0.26.3" @@ -130,6 +157,24 @@ dependencies = [ "gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "cpp_demangle" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fixedbitset 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "dbghelp-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "env_logger" version = "0.4.3" @@ -139,6 +184,19 @@ dependencies = [ "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "error-chain" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fixedbitset" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "futures" version = "0.1.13" @@ -363,6 +421,11 @@ name = "regex-syntax" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rustc-demangle" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rustc-serialize" version = "0.3.24" @@ -554,6 +617,8 @@ dependencies = [ "checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6" "checksum aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfdf7355d9db158df68f976ed030ab0f6578af811f5a7bb6dcf221ec24e0e0" "checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159" +"checksum backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "72f9b4182546f4b04ebc4ab7f84948953a118bd6021a1b6a6c909e3e94f6be76" +"checksum backtrace-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "afccc5772ba333abccdf60d55200fa3406f8c59dcf54d5f7998c9107d3799c7c" "checksum bindgen 0.26.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c57d6c0f6e31f8dcf4d12720a3c2a9ffb70638772a5784976cf4fce52145f22a" "checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" @@ -564,7 +629,11 @@ dependencies = [ "checksum clang-sys 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "611ec2e3a7623afd8a8c0d027887b6b55759d894abbf5fe11b9dc11b50d5b49a" "checksum clap 2.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2267a8fdd4dce6956ba6649e130f62fb279026e5e84b92aa939ac8f85ce3f9f0" "checksum cmake 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b8ebbb35d3dc9cd09497168f33de1acb79b265d350ab0ac34133b98f8509af1f" +"checksum cpp_demangle 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7f374549b5aa87e566f17445e1aa17c86db0a8d19be7a72b2b1ac7bf5414df50" +"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" "checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" +"checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" +"checksum fixedbitset 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b0cb3d75726fa0c5ed3dce5dfcf0796affa2a60b33967f45012d86fb95a886f2" "checksum futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "55f0008e13fc853f79ea8fc86e931486860d4c4c156cdffb59fa5f7fa833660a" "checksum gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)" = "120d07f202dcc3f72859422563522b66fe6463a4c513df062874daad05f85f0a" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" @@ -592,6 +661,7 @@ dependencies = [ "checksum quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9e25fa23c044c1803f43ca59c98dac608976dd04ce799411edd58ece776d4" "checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b" "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" +"checksum rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3058a43ada2c2d0b92b3ae38007a2d0fa5e9db971be260e0171408a4ff471c95" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d" "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" diff --git a/Cargo.toml b/Cargo.toml index ff4a9c8..c2161fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,17 +1,31 @@ [package] -authors = ["Nick Fitzgerald "] +authors = ["The Starling Project Developers"] +description = "The project that will henceforth be known as `starling`." name = "starling" version = "0.1.0" - [[bin]] +doc = false name = "starling" path = "src/bin/starling.rs" -doc = false +required-features = ["clap"] [dependencies] +error-chain = "0.10.0" futures = "0.1.13" tokio-core = "0.1.6" +[dependencies.clap] +optional = true +version = "2.26.0" + +[dependencies.backtrace] +features = ["cpp_demangle"] +version = "0.3.2" + [dependencies.js] -git = "https://github.com/fitzgen/mozjs" branch = "smup" +git = "https://github.com/fitzgen/mozjs" + +[features] +default = ["clap"] +debugmozjs = ['js/debugmozjs'] diff --git a/ci/before_install.sh b/ci/before_install.sh new file mode 100755 index 0000000..07626d4 --- /dev/null +++ b/ci/before_install.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +# We always want backtraces for everything. +export RUST_BACKTRACE=1 + +if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + brew install autoconf@2.13 ccache llvm@3.9 yasm + export LIBCLANG_PATH=$(find /usr/local/Cellar/llvm -type f -name libclang.dylib | head -n 1) + export LIBCLANG_PATH=$(dirname $LIBCLANG_PATH) +elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then + export CC=clang-3.9 + export CXX=clang++-3.9 + export LIBCLANG_PATH=/usr/lib/llvm-3.9/lib +else + echo "Error: unknown \$TRAVIS_OS_NAME: $TRAVIS_OS_NAME" + exit 1 +fi + +ccache -c +export CCACHE=$(which ccache) diff --git a/ci/script.sh b/ci/script.sh new file mode 100755 index 0000000..c9139f4 --- /dev/null +++ b/ci/script.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -eux + +cargo build -v $PROFILE $FEATURES +cargo test -v $PROFILE $FEATURES + +if [[ "$PROFILE" == "--release" && "$FEATURES" == "" ]]; then + cargo bench -v +fi diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..4b90c54 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,5 @@ +reorder_imports = true +reorder_imported_names = true +write_mode = "Overwrite" +closure_block_indent_threshold = 0 +use_try_shorthand = true diff --git a/src/bin/starling.rs b/src/bin/starling.rs index 268a99d..d7397bb 100644 --- a/src/bin/starling.rs +++ b/src/bin/starling.rs @@ -1,10 +1,37 @@ +extern crate clap; +extern crate error_chain; extern crate starling; +use clap::{App, Arg}; +use error_chain::ChainedError; use std::process; +/// Parse the given CLI arguments into a `starling::Options` configuration +/// object. +/// +/// If argument parsing fails, then a usage string is printed, and the process +/// is exited with 1. +fn parse_cli_args() -> starling::Options { + let matches = App::new(env!("CARGO_PKG_NAME")) + .version(env!("CARGO_PKG_VERSION")) + .author(env!("CARGO_PKG_AUTHORS")) + .about(env!("CARGO_PKG_DESCRIPTION")) + .arg( + Arg::with_name("file") + .required(true) + .help("The JavaScript file to evaluate as the main task."), + ) + .get_matches(); + + let opts = starling::Options::new(matches.value_of("file").unwrap()); + + opts +} + fn main() { - if let Err(e) = starling::run() { - println!("Error: {}", e); + let opts = parse_cli_args(); + if let Err(e) = opts.run() { + println!("{}", e.display()); process::exit(1); } } diff --git a/src/lib.rs b/src/lib.rs index ec9b0f6..dbeac9f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,21 +1,74 @@ //! The project that will henceforth be known as `starling`. - +//! +// `error_chain!` can recurse deeply +#![recursion_limit = "1024"] #![deny(missing_docs)] #![deny(missing_debug_implementations)] +#![deny(unsafe_code)] +// Annoying warning emitted from the `error_chain!` macro. +#![allow(unused_doc_comment)] +#[macro_use] +extern crate error_chain; extern crate futures; extern crate tokio_core; use futures::future; -use std::io; +use std::path; use tokio_core::reactor::Core; -/// Run the main `starling` loop. -pub fn run() -> Result<(), io::Error> { +error_chain! { + foreign_links { + Io(::std::io::Error) + /// An IO error. + ; + } +} + +/// Configuration options for building a `starling` event loop. +/// +/// ``` +/// extern crate starling; +/// +/// # fn foo() -> starling::Result<()> { +/// // Construct a new `Options` builder, providing the file containing +/// // the main JavaScript task. +/// starling::Options::new("path/to/main.js") +/// // Finish configuring the `Options` builder and run the event +/// // loop! +/// .run()?; +/// # Ok(()) +/// # } +/// ``` +#[derive(Clone, Debug)] +pub struct Options { + main: path::PathBuf, +} + +impl Options { + /// Construct a new `Options` object for configuring the `starling` event + /// loop. + /// + /// The given `main` JavaScript file will be evaluated as the main task. + pub fn new

(main: P) -> Options + where + P: Into, + { + Options { main: main.into() } + } + + /// Finish this `Options` builder and run the `starling` event loop with its + /// specified configuration. + pub fn run(self) -> Result<()> { + run_with_options(self) + } +} + +/// Run the main `starling` event loop with the specified options. +fn run_with_options(_opts: Options) -> Result<()> { let mut core = Core::new()?; core.run(future::ok(())) } #[test] -fn it_works() { -} +fn it_works() {}