<commit_before>#![deny(
    missing_debug_implementations,
    trivial_numeric_casts,
    unstable_features,
    unused_import_braces,
    unused_qualifications
)]

extern crate clap;
extern crate notify;
extern crate rouille;
extern crate tempdir;
extern crate reqwest;
extern crate pbr;
extern crate app_dirs;
extern crate libflate;
extern crate tar;
extern crate sha1;
extern crate sha2;
extern crate digest;
extern crate toml;
extern crate serde;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate serde_json;
extern crate handlebars;
extern crate unicode_categories;
extern crate ordermap;
extern crate websocket;
extern crate regex;

extern crate parity_wasm;
#[macro_use]
extern crate log;
extern crate rustc_demangle;
extern crate env_logger;

extern crate cargo_metadata;
extern crate ansi_term;

use std::process::exit;
use std::env;

use clap::{
    Arg,
    App,
    AppSettings,
    SubCommand
};

mod cargo_shim;
use cargo_shim::*;

#[macro_use]
mod utils;
mod config;
mod package;
mod build;
mod error;
mod wasm;
mod wasm_gc;
mod wasm_inline_js;
mod wasm_export_main;
mod wasm_export_table;
mod wasm_hook_grow;
mod wasm_runtime;
mod wasm_context;
mod wasm_intrinsics;
mod emscripten;
mod test_chromium;
mod chrome_devtools;
mod cmd_build;
mod cmd_start;
mod cmd_test;

fn add_shared_build_params< 'a, 'b >( app: App< 'a, 'b > ) -> App< 'a, 'b > {
    return app
        .arg(
            Arg::with_name( "package" )
                .short( "p" )
                .long( "package" )
                .help( "Package to build" )
                .value_name( "NAME" )
                .takes_value( true )
        )
        .arg(
            Arg::with_name( "features" )
                .long( "features" )
                .help( "Space-separated list of features to also build" )
                .value_name( "FEATURES" )
                .takes_value( true )
        )
        .arg(
            Arg::with_name( "all-features" )
                .long( "all-features" )
                .help( "Build all available features" )
                // Technically Cargo doesn't treat it as conflicting,
                // but it seems less confusing to *not* allow these together.
                .conflicts_with_all( &[ "features", "no-default-features" ] )
        )
        .arg(
            Arg::with_name( "no-default-features" )
                .long( "no-default-features" )
                .help( "Do not build the `default` feature" )
        )
        .arg(
            Arg::with_name( "use-system-emscripten" )
                .long( "use-system-emscripten" )
                .help( "Won't try to download Emscripten; will always use the system one" )
        )
        .arg(
            Arg::with_name( "release" )
                .long( "release" )
                .help( "Build artifacts in release mode, with optimizations" )
        )
        .arg(
            Arg::with_name( "target-asmjs-emscripten" )
                .long( "target-asmjs-emscripten" )
                .help( "Generate asmjs through Emscripten (default)" )
                .overrides_with_all( &["target-webasm-emscripten", "target-webasm"] )
        )
        .arg(
            Arg::with_name( "target-webasm-emscripten" )
                .long( "target-webasm-emscripten" )
                .help( "Generate webasm through Emscripten" )
                .overrides_with_all( &["target-asmjs-emscripten", "target-webasm"] )
        )
        .arg(
            Arg::with_name( "target-webasm" )
                .long( "target-webasm" )
                .help( "Generates webasm through Rust's native backend (HIGHLY EXPERIMENTAL!)" )
                .overrides_with_all( &["target-asmjs-emscripten", "target-webasm-emscripten"] )
        );
}

fn main() {
    let _ = env_logger::init();

    let args = {
        // To allow running both as 'cargo-web' and as 'cargo web'.
        let mut args = env::args();
        let mut filtered_args = Vec::new();
        filtered_args.push( args.next().unwrap() );

        match args.next() {
            None => {},
            #[cfg(any(unix))]
            Some( ref arg ) if filtered_args[ 0 ].ends_with( "cargo-web" ) && arg == "web" => {},
            #[cfg(any(windows))]
            Some( ref arg ) if filtered_args[ 0 ].ends_with( "cargo-web.exe" ) && arg == "web" => {},
            Some( arg ) => filtered_args.push( arg )
        }

        filtered_args.extend( args );
        filtered_args
    };

    let mut build_subcommand =
        SubCommand::with_name( "build" )
            .about( "Compile a local package and all of its dependencies" )
            .arg(
                Arg::with_name( "lib" )
                    .long( "lib" )
                    .help( "Build only this package's library" )
            )
            .arg(
                Arg::with_name( "bin" )
                    .long( "bin" )
                    .help( "Build only the specified binary" )
                    .value_name( "NAME" )
                    .takes_value( true )
            )
            .arg(
                Arg::with_name( "example" )
                    .long( "example" )
                    .help( "Build only the specified example" )
                    .value_name( "NAME" )
                    .takes_value( true )
            )
            .arg(
                Arg::with_name( "test" )
                    .long( "test" )
                    .help( "Build only the specified test target" )
                    .value_name( "NAME" )
                    .takes_value( true )
            )
            .arg(
                Arg::with_name( "bench" )
                    .long( "bench" )
                    .help( "Build only the specified benchmark target" )
                    .value_name( "NAME" )
                    .takes_value( true )
            );

    let mut test_subcommand =
        SubCommand::with_name( "test" )
            .about( "Compiles and runs tests" )
            .arg(
                Arg::with_name( "no-run" )
                    .long( "no-run" )
                    .help( "Compile, but don't run tests" )
            )
            .arg(
                Arg::with_name( "nodejs" )
                    .long( "nodejs" )
                    .help( "Uses Node.js to run the tests" )
            )
            .arg(
                Arg::with_name( "passthrough" )
                    .help( "-- followed by anything will pass the arguments to the test runner")
                    .multiple( true )
                    .takes_value( true )
                    .last( true )
            );

    let mut start_subcommand =
        SubCommand::with_name( "start" )
            .about( "Runs an embedded web server serving the built project" )
            .arg(
                Arg::with_name( "bin" )
                    .long( "bin" )
                    .help( "Build only the specified binary" )
                    .value_name( "NAME" )
                    .takes_value( true )
            )
            .arg(
                Arg::with_name( "example" )
                    .long( "example" )
                    .help( "Serves the specified example" )
                    .value_name( "NAME" )
                    .takes_value( true )
            )
            .arg(
                Arg::with_name( "test" )
                    .long( "test" )
                    .help( "Build only the specified test target" )
                    .value_name( "NAME" )
                    .takes_value( true )
            )
            .arg(
                Arg::with_name( "bench" )
                    .long( "bench" )
                    .help( "Build only the specified benchmark target" )
                    .value_name( "NAME" )
                    .takes_value( true )
            ).arg(
                Arg::with_name( "host" )
                    .long( "host" )
                    .help( "Bind the server to this address, default `localhost`")
                    .value_name( "HOST" )
                    .takes_value( true )
            ).arg(
                Arg::with_name( "port" )
                    .long( "port" )
                    .help( "Bind the server to this port, default 8000" )
                    .value_name( "PORT" )
                    .takes_value( true )
            );

    build_subcommand = add_shared_build_params( build_subcommand );
    test_subcommand = add_shared_build_params( test_subcommand );
    start_subcommand = add_shared_build_params( start_subcommand );

    let matches = App::new( "cargo-web" )
        .version( env!( "CARGO_PKG_VERSION" ) )
        .setting( AppSettings::SubcommandRequiredElseHelp )
        .setting( AppSettings::VersionlessSubcommands )
        .subcommand( build_subcommand )
        .subcommand( test_subcommand )
        .subcommand( start_subcommand )
        .get_matches_from( args );

    let project = CargoProject::new( None );
    let result = if let Some( matches ) = matches.subcommand_matches( "build" ) {
        cmd_build::command_build( matches, &project )
    } else if let Some( matches ) = matches.subcommand_matches( "test" ) {
        cmd_test::command_test( matches, &project )
    } else if let Some( matches ) = matches.subcommand_matches( "start" ) {
        cmd_start::command_start( matches, &project )
    } else {
        return;
    };

    match result {
        Ok( _ ) => {},
        Err( error ) => {
            println_err!( "error: {}", error );
            exit( 101 );
        }
    }
}
<commit_msg>Only initialize the logger when CARGO_WEB_LOG is set<commit_after>#![deny(
    missing_debug_implementations,
    trivial_numeric_casts,
    unstable_features,
    unused_import_braces,
    unused_qualifications
)]

extern crate clap;
extern crate notify;
extern crate rouille;
extern crate tempdir;
extern crate reqwest;
extern crate pbr;
extern crate app_dirs;
extern crate libflate;
extern crate tar;
extern crate sha1;
extern crate sha2;
extern crate digest;
extern crate toml;
extern crate serde;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate serde_json;
extern crate handlebars;
extern crate unicode_categories;
extern crate ordermap;
extern crate websocket;
extern crate regex;

extern crate parity_wasm;
#[macro_use]
extern crate log;
extern crate rustc_demangle;
extern crate env_logger;

extern crate cargo_metadata;
extern crate ansi_term;

use std::process::exit;
use std::env;

use clap::{
    Arg,
    App,
    AppSettings,
    SubCommand
};

mod cargo_shim;
use cargo_shim::*;

#[macro_use]
mod utils;
mod config;
mod package;
mod build;
mod error;
mod wasm;
mod wasm_gc;
mod wasm_inline_js;
mod wasm_export_main;
mod wasm_export_table;
mod wasm_hook_grow;
mod wasm_runtime;
mod wasm_context;
mod wasm_intrinsics;
mod emscripten;
mod test_chromium;
mod chrome_devtools;
mod cmd_build;
mod cmd_start;
mod cmd_test;

fn add_shared_build_params< 'a, 'b >( app: App< 'a, 'b > ) -> App< 'a, 'b > {
    return app
        .arg(
            Arg::with_name( "package" )
                .short( "p" )
                .long( "package" )
                .help( "Package to build" )
                .value_name( "NAME" )
                .takes_value( true )
        )
        .arg(
            Arg::with_name( "features" )
                .long( "features" )
                .help( "Space-separated list of features to also build" )
                .value_name( "FEATURES" )
                .takes_value( true )
        )
        .arg(
            Arg::with_name( "all-features" )
                .long( "all-features" )
                .help( "Build all available features" )
                // Technically Cargo doesn't treat it as conflicting,
                // but it seems less confusing to *not* allow these together.
                .conflicts_with_all( &[ "features", "no-default-features" ] )
        )
        .arg(
            Arg::with_name( "no-default-features" )
                .long( "no-default-features" )
                .help( "Do not build the `default` feature" )
        )
        .arg(
            Arg::with_name( "use-system-emscripten" )
                .long( "use-system-emscripten" )
                .help( "Won't try to download Emscripten; will always use the system one" )
        )
        .arg(
            Arg::with_name( "release" )
                .long( "release" )
                .help( "Build artifacts in release mode, with optimizations" )
        )
        .arg(
            Arg::with_name( "target-asmjs-emscripten" )
                .long( "target-asmjs-emscripten" )
                .help( "Generate asmjs through Emscripten (default)" )
                .overrides_with_all( &["target-webasm-emscripten", "target-webasm"] )
        )
        .arg(
            Arg::with_name( "target-webasm-emscripten" )
                .long( "target-webasm-emscripten" )
                .help( "Generate webasm through Emscripten" )
                .overrides_with_all( &["target-asmjs-emscripten", "target-webasm"] )
        )
        .arg(
            Arg::with_name( "target-webasm" )
                .long( "target-webasm" )
                .help( "Generates webasm through Rust's native backend (HIGHLY EXPERIMENTAL!)" )
                .overrides_with_all( &["target-asmjs-emscripten", "target-webasm-emscripten"] )
        );
}

fn main() {
    if let Ok( value ) = env::var( "CARGO_WEB_LOG" ) {
        let mut builder = env_logger::Builder::new();
        builder.parse( &value );
        builder.init();
    }

    let args = {
        // To allow running both as 'cargo-web' and as 'cargo web'.
        let mut args = env::args();
        let mut filtered_args = Vec::new();
        filtered_args.push( args.next().unwrap() );

        match args.next() {
            None => {},
            #[cfg(any(unix))]
            Some( ref arg ) if filtered_args[ 0 ].ends_with( "cargo-web" ) && arg == "web" => {},
            #[cfg(any(windows))]
            Some( ref arg ) if filtered_args[ 0 ].ends_with( "cargo-web.exe" ) && arg == "web" => {},
            Some( arg ) => filtered_args.push( arg )
        }

        filtered_args.extend( args );
        filtered_args
    };

    let mut build_subcommand =
        SubCommand::with_name( "build" )
            .about( "Compile a local package and all of its dependencies" )
            .arg(
                Arg::with_name( "lib" )
                    .long( "lib" )
                    .help( "Build only this package's library" )
            )
            .arg(
                Arg::with_name( "bin" )
                    .long( "bin" )
                    .help( "Build only the specified binary" )
                    .value_name( "NAME" )
                    .takes_value( true )
            )
            .arg(
                Arg::with_name( "example" )
                    .long( "example" )
                    .help( "Build only the specified example" )
                    .value_name( "NAME" )
                    .takes_value( true )
            )
            .arg(
                Arg::with_name( "test" )
                    .long( "test" )
                    .help( "Build only the specified test target" )
                    .value_name( "NAME" )
                    .takes_value( true )
            )
            .arg(
                Arg::with_name( "bench" )
                    .long( "bench" )
                    .help( "Build only the specified benchmark target" )
                    .value_name( "NAME" )
                    .takes_value( true )
            );

    let mut test_subcommand =
        SubCommand::with_name( "test" )
            .about( "Compiles and runs tests" )
            .arg(
                Arg::with_name( "no-run" )
                    .long( "no-run" )
                    .help( "Compile, but don't run tests" )
            )
            .arg(
                Arg::with_name( "nodejs" )
                    .long( "nodejs" )
                    .help( "Uses Node.js to run the tests" )
            )
            .arg(
                Arg::with_name( "passthrough" )
                    .help( "-- followed by anything will pass the arguments to the test runner")
                    .multiple( true )
                    .takes_value( true )
                    .last( true )
            );

    let mut start_subcommand =
        SubCommand::with_name( "start" )
            .about( "Runs an embedded web server serving the built project" )
            .arg(
                Arg::with_name( "bin" )
                    .long( "bin" )
                    .help( "Build only the specified binary" )
                    .value_name( "NAME" )
                    .takes_value( true )
            )
            .arg(
                Arg::with_name( "example" )
                    .long( "example" )
                    .help( "Serves the specified example" )
                    .value_name( "NAME" )
                    .takes_value( true )
            )
            .arg(
                Arg::with_name( "test" )
                    .long( "test" )
                    .help( "Build only the specified test target" )
                    .value_name( "NAME" )
                    .takes_value( true )
            )
            .arg(
                Arg::with_name( "bench" )
                    .long( "bench" )
                    .help( "Build only the specified benchmark target" )
                    .value_name( "NAME" )
                    .takes_value( true )
            ).arg(
                Arg::with_name( "host" )
                    .long( "host" )
                    .help( "Bind the server to this address, default `localhost`")
                    .value_name( "HOST" )
                    .takes_value( true )
            ).arg(
                Arg::with_name( "port" )
                    .long( "port" )
                    .help( "Bind the server to this port, default 8000" )
                    .value_name( "PORT" )
                    .takes_value( true )
            );

    build_subcommand = add_shared_build_params( build_subcommand );
    test_subcommand = add_shared_build_params( test_subcommand );
    start_subcommand = add_shared_build_params( start_subcommand );

    let matches = App::new( "cargo-web" )
        .version( env!( "CARGO_PKG_VERSION" ) )
        .setting( AppSettings::SubcommandRequiredElseHelp )
        .setting( AppSettings::VersionlessSubcommands )
        .subcommand( build_subcommand )
        .subcommand( test_subcommand )
        .subcommand( start_subcommand )
        .get_matches_from( args );

    let project = CargoProject::new( None );
    let result = if let Some( matches ) = matches.subcommand_matches( "build" ) {
        cmd_build::command_build( matches, &project )
    } else if let Some( matches ) = matches.subcommand_matches( "test" ) {
        cmd_test::command_test( matches, &project )
    } else if let Some( matches ) = matches.subcommand_matches( "start" ) {
        cmd_start::command_start( matches, &project )
    } else {
        return;
    };

    match result {
        Ok( _ ) => {},
        Err( error ) => {
            println_err!( "error: {}", error );
            exit( 101 );
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (C) 2016, 2017 Mark Lee

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.

// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

extern crate env_logger;
extern crate futures;
extern crate hyper;
#[macro_use]
extern crate log;
extern crate redis;
extern crate regex;
extern crate reqwest;
extern crate rquery;
extern crate semver;
extern crate serde;
extern crate serde_json;

use hyper::{Get, StatusCode};
use hyper::header::{Accept, ContentType};
use hyper::server::{Http, Request, Response, Service};
use redis::{Commands, RedisError, RedisResult};
use regex::Regex;
use rquery::Document;
use semver::Version;
use std::collections::HashMap;
use std::env;
use std::fs::File;
use std::io;
use std::io::Read;

const DEFAULT_SERVER_PORT: u32 = 9000;
const DEFAULT_MIN_BUNDLER_VERSION: &'static str = "1.12.0";
const RUBY_LANGPACK_RELEASES_URL: &'static str = "https://github.\
                                                  com/heroku/heroku-buildpack-ruby/releases.atom";

fn download_url(url: &str) -> io::Result<String> {
    let mut resp = reqwest::get(url).expect("Could not send HTTP request");
    let mut body = String::new();
    match resp.read_to_string(&mut body) {
        Err(error) => Err(error),
        _ => Ok(body),
    }
}

fn download_latest_buildpack_release() -> String {
    let xml = download_url(RUBY_LANGPACK_RELEASES_URL).expect("Could not download Atom releases!");
    let atom_doc = Document::new_from_xml_string(&xml[..]).expect("Could not parse Atom releases!");
    atom_doc
        .select("entry id")
        .expect("Could not find latest buildpack tag!")
        .text()
        .rsplitn(2, '/')
        .next()
        .expect("No slashes in the GitHub release ID!")
        .to_string()
}

fn redis_cache_value(redis: &redis::Connection, key: &str, value: &str) -> String {
    let set_result: RedisResult<()> = redis.set_ex(key, value, 3600);
    if set_result.is_err() {
        warn!("Cannot set {} in Redis, ignoring", key);
    }
    value.to_owned()
}

fn redis_cache_hash_value(redis: &redis::Connection, hash_name: &str, key: &str, value: &str) {
    let set_result: RedisResult<()> = redis.hset_nx(hash_name, key, value);
    if set_result.is_err() {
        warn!("Cannot set {} in Redis, ignoring", key);
    }
}

fn latest_buildpack_release(redis_result: &RedisResult<redis::Connection>) -> String {
    if let Ok(ref redis) = *redis_result {
        if let Ok(buildpack_release) = redis.get("latest_buildpack_release") {
            buildpack_release
        } else {
            let buildpack_release = download_latest_buildpack_release();
            redis_cache_value(redis, "latest_buildpack_release", &buildpack_release[..])
        }
    } else {
        download_latest_buildpack_release()
    }
}

fn cached_version_from_buildpack_release(
    buildpack_release: &str,
    redis_result: &RedisResult<redis::Connection>,
) -> Option<String> {
    if let Ok(ref redis) = *redis_result {
        if let Ok(version) = redis.hget("bundler_version", buildpack_release) {
            Some(version)
        } else {
            None
        }
    } else {
        None
    }
}

fn bundler_version_from_ruby_buildpack(
    redis_result: &RedisResult<redis::Connection>,
) -> Option<String> {
    let buildpack_release = latest_buildpack_release(redis_result);
    if let Some(cached_version) =
        cached_version_from_buildpack_release(&buildpack_release[..], redis_result)
    {
        return Some(cached_version);
    }
    let ruby_langpack_url = format!(
        "https://raw.githubusercontent.com/\
         heroku/heroku-buildpack-ruby/{}/lib/language_pack/\
         ruby.rb",
        buildpack_release
    );
    let ruby_file = &download_url(&ruby_langpack_url[..]).expect("Could not download ruby.rb!")[..];
    let regex = Regex::new(r#"BUNDLER_VERSION += "(.+?)""#).expect("Invalid regular expression!");
    if regex.is_match(ruby_file) {
        let captures = regex.captures(ruby_file).expect("Could not match?!");
        let version_match = captures.get(1).expect("Capture not found?!");
        let version = version_match.as_str();
        if let Ok(ref redis) = *redis_result {
            redis_cache_hash_value(redis, "bundler_version", &buildpack_release[..], version);
        }
        Some(version.to_owned())
    } else {
        None
    }
}

fn is_bundler_upgraded(redis_result: &RedisResult<redis::Connection>) -> bool {
    let bundler_version_result = bundler_version_from_ruby_buildpack(redis_result);
    if let Some(buildpack_bundler_version_str) = bundler_version_result {
        let min_version =
            Version::parse(&min_bundler_version()[..]).expect("Could not parse min version!");
        let new_version = Version::parse(&buildpack_bundler_version_str[..])
            .expect("Could not parse new version!");
        min_version < new_version
    } else {
        false
    }
}

fn determine_content_type(headers: &hyper::Headers) -> ContentType {
    use std::ops::Deref;
    if headers.has::<Accept>() {
        let accept = headers
            .get::<Accept>()
            .expect("Accept header not found?!")
            .deref();
        let use_json = accept
            .into_iter()
            .any(|qitem| qitem.item == "application/json");

        if use_json {
            ContentType::json()
        } else {
            ContentType::html()
        }
    } else {
        ContentType::html()
    }
}

fn result_to_json(result: bool) -> String {
    let mut map = HashMap::new();
    map.insert("result".to_owned(), result);
    serde_json::to_string(&map).expect("Could not serialize result!")
}

fn result_to_html(result: bool) -> String {
    let result_str = if result {
        r#"
Yes
"#
    } else {
        r#"
No
"#
    };
    match File::open("index.html") {
        Ok(mut html_file) => {
            let mut html = String::new();
            html_file
                .read_to_string(&mut html)
                .expect("Could not read HTML file!");
            html.replace("{{ is_bundler_upgraded }}", result_str)
                .replace("{{ MIN_BUNDLER_VERSION }}", &min_bundler_version()[..])
        }
        Err(error) => format!("HTML NOT FOUND: {}", error),
    }
}

fn min_bundler_version() -> String {
    match env::var("MIN_BUNDLER_VERSION") {
        Ok(version) => version,
        _ => String::from(DEFAULT_MIN_BUNDLER_VERSION),
    }
}

fn server_port() -> String {
    match env::var("PORT") {
        Ok(port) => port,
        _ => format!("{}", DEFAULT_SERVER_PORT),
    }
}

fn connect_to_redis() -> RedisResult<redis::Connection> {
    if let Ok(redis_url) = env::var("REDIS_URL") {
        let client = redis::Client::open(&redis_url[..]).expect("Cannot connect to Redis");
        client.get_connection()
    } else {
        Err(RedisError::from(io::Error::new(
            io::ErrorKind::Other,
            "REDIS_URL not found",
        )))
    }
}

struct HBBUYServer;

impl Service for HBBUYServer {
    type Request = Request;
    type Response = Response;
    type Error = hyper::Error;
    type Future = futures::future::FutureResult<Self::Response, Self::Error>;

    fn call(&self, req: Request) -> Self::Future {
        let response = match (req.uri().path(), req.method()) {
            ("/", &Get) => {
                let redis = connect_to_redis();
                let result = is_bundler_upgraded(&redis);
                let content_type = determine_content_type(req.headers());
                let data = match &format!("{}", content_type)[..] {
                    "application/json" => result_to_json(result),
                    _ => result_to_html(result),
                };

                Response::new().with_header(content_type).with_body(data)
            }
            (_, &Get) => Response::new().with_status(StatusCode::NotFound),
            (_, _) => Response::new().with_status(StatusCode::MethodNotAllowed),
        };

        futures::future::ok(response)
    }
}

fn main() {
    env_logger::try_init().expect("Could not initialize env_logger!");
    let addr = format!("0.0.0.0:{}", server_port())
        .parse()
        .expect("Could not parse address/port");
    let server = Http::new()
        .bind(&addr, || Ok(HBBUYServer))
        .expect("Could not create server!");
    server
        .run()
        .expect("Could not set up HTTP request handler!");
}
<commit_msg>[Rust] static lifetime now implied on const strs<commit_after>// Copyright (C) 2016, 2017 Mark Lee

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.

// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

extern crate env_logger;
extern crate futures;
extern crate hyper;
#[macro_use]
extern crate log;
extern crate redis;
extern crate regex;
extern crate reqwest;
extern crate rquery;
extern crate semver;
extern crate serde;
extern crate serde_json;

use hyper::{Get, StatusCode};
use hyper::header::{Accept, ContentType};
use hyper::server::{Http, Request, Response, Service};
use redis::{Commands, RedisError, RedisResult};
use regex::Regex;
use rquery::Document;
use semver::Version;
use std::collections::HashMap;
use std::env;
use std::fs::File;
use std::io;
use std::io::Read;

const DEFAULT_SERVER_PORT: u32 = 9000;
const DEFAULT_MIN_BUNDLER_VERSION: &str = "1.12.0";
const RUBY_LANGPACK_RELEASES_URL: &str =
    "https://github.com/heroku/heroku-buildpack-ruby/releases.atom";

fn download_url(url: &str) -> io::Result<String> {
    let mut resp = reqwest::get(url).expect("Could not send HTTP request");
    let mut body = String::new();
    match resp.read_to_string(&mut body) {
        Err(error) => Err(error),
        _ => Ok(body),
    }
}

fn download_latest_buildpack_release() -> String {
    let xml = download_url(RUBY_LANGPACK_RELEASES_URL).expect("Could not download Atom releases!");
    let atom_doc = Document::new_from_xml_string(&xml[..]).expect("Could not parse Atom releases!");
    atom_doc
        .select("entry id")
        .expect("Could not find latest buildpack tag!")
        .text()
        .rsplitn(2, '/')
        .next()
        .expect("No slashes in the GitHub release ID!")
        .to_string()
}

fn redis_cache_value(redis: &redis::Connection, key: &str, value: &str) -> String {
    let set_result: RedisResult<()> = redis.set_ex(key, value, 3600);
    if set_result.is_err() {
        warn!("Cannot set {} in Redis, ignoring", key);
    }
    value.to_owned()
}

fn redis_cache_hash_value(redis: &redis::Connection, hash_name: &str, key: &str, value: &str) {
    let set_result: RedisResult<()> = redis.hset_nx(hash_name, key, value);
    if set_result.is_err() {
        warn!("Cannot set {} in Redis, ignoring", key);
    }
}

fn latest_buildpack_release(redis_result: &RedisResult<redis::Connection>) -> String {
    if let Ok(ref redis) = *redis_result {
        if let Ok(buildpack_release) = redis.get("latest_buildpack_release") {
            buildpack_release
        } else {
            let buildpack_release = download_latest_buildpack_release();
            redis_cache_value(redis, "latest_buildpack_release", &buildpack_release[..])
        }
    } else {
        download_latest_buildpack_release()
    }
}

fn cached_version_from_buildpack_release(
    buildpack_release: &str,
    redis_result: &RedisResult<redis::Connection>,
) -> Option<String> {
    if let Ok(ref redis) = *redis_result {
        if let Ok(version) = redis.hget("bundler_version", buildpack_release) {
            Some(version)
        } else {
            None
        }
    } else {
        None
    }
}

fn bundler_version_from_ruby_buildpack(
    redis_result: &RedisResult<redis::Connection>,
) -> Option<String> {
    let buildpack_release = latest_buildpack_release(redis_result);
    if let Some(cached_version) =
        cached_version_from_buildpack_release(&buildpack_release[..], redis_result)
    {
        return Some(cached_version);
    }
    let ruby_langpack_url = format!(
        "https://raw.githubusercontent.com/\
         heroku/heroku-buildpack-ruby/{}/lib/language_pack/\
         ruby.rb",
        buildpack_release
    );
    let ruby_file = &download_url(&ruby_langpack_url[..]).expect("Could not download ruby.rb!")[..];
    let regex = Regex::new(r#"BUNDLER_VERSION += "(.+?)""#).expect("Invalid regular expression!");
    if regex.is_match(ruby_file) {
        let captures = regex.captures(ruby_file).expect("Could not match?!");
        let version_match = captures.get(1).expect("Capture not found?!");
        let version = version_match.as_str();
        if let Ok(ref redis) = *redis_result {
            redis_cache_hash_value(redis, "bundler_version", &buildpack_release[..], version);
        }
        Some(version.to_owned())
    } else {
        None
    }
}

fn is_bundler_upgraded(redis_result: &RedisResult<redis::Connection>) -> bool {
    let bundler_version_result = bundler_version_from_ruby_buildpack(redis_result);
    if let Some(buildpack_bundler_version_str) = bundler_version_result {
        let min_version =
            Version::parse(&min_bundler_version()[..]).expect("Could not parse min version!");
        let new_version = Version::parse(&buildpack_bundler_version_str[..])
            .expect("Could not parse new version!");
        min_version < new_version
    } else {
        false
    }
}

fn determine_content_type(headers: &hyper::Headers) -> ContentType {
    use std::ops::Deref;
    if headers.has::<Accept>() {
        let accept = headers
            .get::<Accept>()
            .expect("Accept header not found?!")
            .deref();
        let use_json = accept
            .into_iter()
            .any(|qitem| qitem.item == "application/json");

        if use_json {
            ContentType::json()
        } else {
            ContentType::html()
        }
    } else {
        ContentType::html()
    }
}

fn result_to_json(result: bool) -> String {
    let mut map = HashMap::new();
    map.insert("result".to_owned(), result);
    serde_json::to_string(&map).expect("Could not serialize result!")
}

fn result_to_html(result: bool) -> String {
    let result_str = if result {
        r#"
Yes
"#
    } else {
        r#"
No
"#
    };
    match File::open("index.html") {
        Ok(mut html_file) => {
            let mut html = String::new();
            html_file
                .read_to_string(&mut html)
                .expect("Could not read HTML file!");
            html.replace("{{ is_bundler_upgraded }}", result_str)
                .replace("{{ MIN_BUNDLER_VERSION }}", &min_bundler_version()[..])
        }
        Err(error) => format!("HTML NOT FOUND: {}", error),
    }
}

fn min_bundler_version() -> String {
    match env::var("MIN_BUNDLER_VERSION") {
        Ok(version) => version,
        _ => String::from(DEFAULT_MIN_BUNDLER_VERSION),
    }
}

fn server_port() -> String {
    match env::var("PORT") {
        Ok(port) => port,
        _ => format!("{}", DEFAULT_SERVER_PORT),
    }
}

fn connect_to_redis() -> RedisResult<redis::Connection> {
    if let Ok(redis_url) = env::var("REDIS_URL") {
        let client = redis::Client::open(&redis_url[..]).expect("Cannot connect to Redis");
        client.get_connection()
    } else {
        Err(RedisError::from(io::Error::new(
            io::ErrorKind::Other,
            "REDIS_URL not found",
        )))
    }
}

struct HBBUYServer;

impl Service for HBBUYServer {
    type Request = Request;
    type Response = Response;
    type Error = hyper::Error;
    type Future = futures::future::FutureResult<Self::Response, Self::Error>;

    fn call(&self, req: Request) -> Self::Future {
        let response = match (req.uri().path(), req.method()) {
            ("/", &Get) => {
                let redis = connect_to_redis();
                let result = is_bundler_upgraded(&redis);
                let content_type = determine_content_type(req.headers());
                let data = match &format!("{}", content_type)[..] {
                    "application/json" => result_to_json(result),
                    _ => result_to_html(result),
                };

                Response::new().with_header(content_type).with_body(data)
            }
            (_, &Get) => Response::new().with_status(StatusCode::NotFound),
            (_, _) => Response::new().with_status(StatusCode::MethodNotAllowed),
        };

        futures::future::ok(response)
    }
}

fn main() {
    env_logger::try_init().expect("Could not initialize env_logger!");
    let addr = format!("0.0.0.0:{}", server_port())
        .parse()
        .expect("Could not parse address/port");
    let server = Http::new()
        .bind(&addr, || Ok(HBBUYServer))
        .expect("Could not create server!");
    server
        .run()
        .expect("Could not set up HTTP request handler!");
}
<|endoftext|>


<commit_before>#![deny(warnings)]

extern crate getopts;

use std::{env, io};
use std::io::{Read, Write};
use std::error::Error;

use getopts::Options;

mod error;

mod options;
use options::{DeleteOption, GitOptions};

mod branches;
use branches::Branches;

mod commands;
use commands::*;

const VERSION: &'static str = env!("CARGO_PKG_VERSION");

fn main() {
    let args: Vec<String> = env::args().collect();

    let mut opts = Options::new();
    opts.optflag("l", "locals", "only delete local branches");
    opts.optflag("r", "remotes", "only delete remote branches");
    opts.optflag("y", "yes", "skip the check for deleting branches");
    opts.optflag("s",
                 "squashes",
                 "check for squashes by finding branches incompatible with master");
    opts.optopt("R",
                "remote",
                "changes the git remote used (default is origin)",
                "REMOTE");
    opts.optopt("b",
                "branch",
                "changes the base for merged branches (default is master)",
                "BRANCH");
    opts.optmulti("i", "ignore", "ignores given branches", "BRANCH");
    opts.optflag("h", "help", "print this help menu");
    opts.optflag("v", "version", "print the version");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(e) => {
            println!("{}", e);
            print_help(opts);
            return;
        }
    };

    if matches.opt_present("h") {
        print_help(opts);
        return;
    }

    if matches.opt_present("version") {
        print_version();
        return;
    }

    validate_git_installation().unwrap_or_else(print_and_exit);

    let git_options = GitOptions::new(&matches);
    git_options.validate().unwrap_or_else(print_and_exit);

    let branches = merged_branches(&git_options);

    if branches.string.is_empty() {
        println!("No branches to delete, you're clean!");
        return;
    }

    let del_opt = DeleteOption::new(&matches);

    if !matches.opt_present("y") {
        print_warning(&branches, &del_opt);

        // Read the user's response on continuing
        let mut input = String::new();
        io::stdin().read_line(&mut input).unwrap();

        match input.to_lowercase().as_ref() {
            "y\n" | "yes\n" | "\n" => (),
            _ => return,
        }
    }

    let msg = delete_branches(&branches, &del_opt, &git_options);
    println!("\n{}", msg);
}

fn print_version() {
    println!("git-clean version {}", VERSION);
}

fn print_help(opts: Options) {
    print!("{}", opts.usage("Usage: git-clean [options]"));
}

fn print_warning(branches: &Branches, del_opt: &DeleteOption) {
    println!("{}", del_opt.warning_message());
    println!("{}", branches.format_columns());
    print!("Continue? (Y/n) ");
    io::stdout().flush().unwrap();
}

fn merged_branches(git_options: &GitOptions) -> Branches {
    let mut branches: Vec<String> = vec![];
    println!("Updating remote {}", git_options.remote);
    run_command_with_no_output(&["git", "remote", "update", &git_options.remote, "--prune"]);

    let merged_branches_regex = format!("\\*{branch}|\\s{branch}",
                                        branch = &git_options.base_branch);
    let merged_branches_filter = spawn_piped(&["grep", "-vE", &merged_branches_regex]);
    let merged_branches_cmd = run_command(&["git", "branch", "--merged"]);

    {
        merged_branches_filter.stdin.unwrap().write_all(&merged_branches_cmd.stdout).unwrap();
    }

    let mut merged_branches_output = String::new();
    merged_branches_filter.stdout.unwrap().read_to_string(&mut merged_branches_output).unwrap();
    let merged_branches =
        merged_branches_output.split('\n').map(|b| b.trim().into()).collect::<Vec<String>>();

    let local_branches_regex = format!("\\*{branch}|\\s{branch}",
                                       branch = &git_options.base_branch);
    let local_branches_filter = spawn_piped(&["grep", "-vE", &local_branches_regex]);
    let local_branches_cmd = run_command(&["git", "branch"]);

    {
        local_branches_filter.stdin.unwrap().write_all(&local_branches_cmd.stdout).unwrap();
    }

    let mut local_branches_output = String::new();
    local_branches_filter.stdout.unwrap().read_to_string(&mut local_branches_output).unwrap();

    let local_branches = local_branches_output.split('\n')
        .map(|b| b.trim().into())
        .filter(|branch| !git_options.ignored_branches.contains(branch))
        .collect::<Vec<String>>();

    let remote_branches_regex = format!("(HEAD|{})", &git_options.base_branch);
    let remote_branches_filter = spawn_piped(&["grep", "-vE", &remote_branches_regex]);
    let remote_branches_cmd = run_command(&["git", "branch", "-r"]);

    {
        remote_branches_filter.stdin.unwrap().write_all(&remote_branches_cmd.stdout).unwrap();
    }

    let mut remote_branches_output = String::new();
    remote_branches_filter.stdout.unwrap().read_to_string(&mut remote_branches_output).unwrap();
    let remote_branches =
        remote_branches_output.split('\n').map(|b| b.trim().into()).collect::<Vec<String>>();

    for branch in local_branches {
        // First check if the local branch doesn't exist in the remote, it's the cheapest and easiest
        // way to determine if we want to suggest to delete it.
        if !remote_branches.contains(&format!("{}/{}", &git_options.remote, branch)) {
            branches.push(branch.to_owned());
            continue;
        }

        // If it does exist in the remote, check to see if it's listed in git branches --merged. If
        // it is, that means it wasn't merged using Github squashes, and we can suggest it.
        if merged_branches.contains(&branch) {
            branches.push(branch.to_owned());
            continue;
        }

        // If neither of the above matched, merge master into the branch and see if it succeeds.
        // If it can't cleanly merge, then it has likely been merged with Github squashes, and we
        // can suggest it.
        if git_options.squashes {
            run_command(&["git", "checkout", &branch]);
            match run_command_with_status(&["git",
                                            "pull",
                                            "--ff-only",
                                            &git_options.remote,
                                            &git_options.base_branch]) {
                Ok(status) => {
                    if !status.success() {
                        println!("why");
                        branches.push(branch.into());
                    }
                }
                Err(err) => {
                    println!("Encountered error trying to update branch {} with branch {}: {}",
                             branch,
                             git_options.base_branch,
                             err);
                    continue;
                }
            }

            run_command(&["git", "reset", "--hard"]);
            run_command(&["git", "checkout", &git_options.base_branch]);
        }
    }

    // if deleted in remote, list
    //
    // g branch -d -r <remote>/<branch>
    // g branch -d <branch>

    Branches::new(branches)
}

fn delete_branches(branches: &Branches,
                   options: &DeleteOption,
                   git_options: &GitOptions)
                   -> String {
    match *options {
        DeleteOption::Local => delete_local_branches(branches),
        DeleteOption::Remote => delete_remote_branches(branches, git_options),
        DeleteOption::Both => {
            let local_output = delete_local_branches(branches);
            let remote_output = delete_remote_branches(branches, git_options);
            ["Remote:".to_owned(), remote_output, "\nLocal:".to_owned(), local_output].join("\n")
        }
    }
}

fn print_and_exit<E: Error>(e: E) {
    println!("{}", e);
    std::process::exit(1);
}

#[cfg(test)]
mod test {
    use options::DeleteOption;
    use branches::Branches;

    use super::print_warning;

    #[test]
    fn test_print_warning() {
        print_warning(&Branches::new(vec!["branch".to_owned()]),
                      &DeleteOption::Both);
    }
}
<commit_msg>Pass by reference instead of by value<commit_after>#![deny(warnings)]

extern crate getopts;

use std::{env, io};
use std::io::{Read, Write};
use std::error::Error;

use getopts::Options;

mod error;

mod options;
use options::{DeleteOption, GitOptions};

mod branches;
use branches::Branches;

mod commands;
use commands::*;

const VERSION: &'static str = env!("CARGO_PKG_VERSION");

fn main() {
    let args: Vec<String> = env::args().collect();

    let mut opts = Options::new();
    opts.optflag("l", "locals", "only delete local branches");
    opts.optflag("r", "remotes", "only delete remote branches");
    opts.optflag("y", "yes", "skip the check for deleting branches");
    opts.optflag("s",
                 "squashes",
                 "check for squashes by finding branches incompatible with master");
    opts.optopt("R",
                "remote",
                "changes the git remote used (default is origin)",
                "REMOTE");
    opts.optopt("b",
                "branch",
                "changes the base for merged branches (default is master)",
                "BRANCH");
    opts.optmulti("i", "ignore", "ignores given branches", "BRANCH");
    opts.optflag("h", "help", "print this help menu");
    opts.optflag("v", "version", "print the version");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(e) => {
            println!("{}", e);
            print_help(&opts);
            return;
        }
    };

    if matches.opt_present("h") {
        print_help(&opts);
        return;
    }

    if matches.opt_present("version") {
        print_version();
        return;
    }

    validate_git_installation().unwrap_or_else(|e| print_and_exit(&e));

    let git_options = GitOptions::new(&matches);
    git_options.validate().unwrap_or_else(|e| print_and_exit(&e));

    let branches = merged_branches(&git_options);

    if branches.string.is_empty() {
        println!("No branches to delete, you're clean!");
        return;
    }

    let del_opt = DeleteOption::new(&matches);

    if !matches.opt_present("y") {
        print_warning(&branches, &del_opt);

        // Read the user's response on continuing
        let mut input = String::new();
        io::stdin().read_line(&mut input).unwrap();

        match input.to_lowercase().as_ref() {
            "y\n" | "yes\n" | "\n" => (),
            _ => return,
        }
    }

    let msg = delete_branches(&branches, &del_opt, &git_options);
    println!("\n{}", msg);
}

fn print_version() {
    println!("git-clean version {}", VERSION);
}

fn print_help(opts: &Options) {
    print!("{}", opts.usage("Usage: git-clean [options]"));
}

fn print_warning(branches: &Branches, del_opt: &DeleteOption) {
    println!("{}", del_opt.warning_message());
    println!("{}", branches.format_columns());
    print!("Continue? (Y/n) ");
    io::stdout().flush().unwrap();
}

fn merged_branches(git_options: &GitOptions) -> Branches {
    let mut branches: Vec<String> = vec![];
    println!("Updating remote {}", git_options.remote);
    run_command_with_no_output(&["git", "remote", "update", &git_options.remote, "--prune"]);

    let merged_branches_regex = format!("\\*{branch}|\\s{branch}",
                                        branch = &git_options.base_branch);
    let merged_branches_filter = spawn_piped(&["grep", "-vE", &merged_branches_regex]);
    let merged_branches_cmd = run_command(&["git", "branch", "--merged"]);

    {
        merged_branches_filter.stdin.unwrap().write_all(&merged_branches_cmd.stdout).unwrap();
    }

    let mut merged_branches_output = String::new();
    merged_branches_filter.stdout.unwrap().read_to_string(&mut merged_branches_output).unwrap();
    let merged_branches =
        merged_branches_output.split('\n').map(|b| b.trim().into()).collect::<Vec<String>>();

    let local_branches_regex = format!("\\*{branch}|\\s{branch}",
                                       branch = &git_options.base_branch);
    let local_branches_filter = spawn_piped(&["grep", "-vE", &local_branches_regex]);
    let local_branches_cmd = run_command(&["git", "branch"]);

    {
        local_branches_filter.stdin.unwrap().write_all(&local_branches_cmd.stdout).unwrap();
    }

    let mut local_branches_output = String::new();
    local_branches_filter.stdout.unwrap().read_to_string(&mut local_branches_output).unwrap();

    let local_branches = local_branches_output.split('\n')
        .map(|b| b.trim().into())
        .filter(|branch| !git_options.ignored_branches.contains(branch))
        .collect::<Vec<String>>();

    let remote_branches_regex = format!("(HEAD|{})", &git_options.base_branch);
    let remote_branches_filter = spawn_piped(&["grep", "-vE", &remote_branches_regex]);
    let remote_branches_cmd = run_command(&["git", "branch", "-r"]);

    {
        remote_branches_filter.stdin.unwrap().write_all(&remote_branches_cmd.stdout).unwrap();
    }

    let mut remote_branches_output = String::new();
    remote_branches_filter.stdout.unwrap().read_to_string(&mut remote_branches_output).unwrap();
    let remote_branches =
        remote_branches_output.split('\n').map(|b| b.trim().into()).collect::<Vec<String>>();

    for branch in local_branches {
        // First check if the local branch doesn't exist in the remote, it's the cheapest and easiest
        // way to determine if we want to suggest to delete it.
        if !remote_branches.contains(&format!("{}/{}", &git_options.remote, branch)) {
            branches.push(branch.to_owned());
            continue;
        }

        // If it does exist in the remote, check to see if it's listed in git branches --merged. If
        // it is, that means it wasn't merged using Github squashes, and we can suggest it.
        if merged_branches.contains(&branch) {
            branches.push(branch.to_owned());
            continue;
        }

        // If neither of the above matched, merge master into the branch and see if it succeeds.
        // If it can't cleanly merge, then it has likely been merged with Github squashes, and we
        // can suggest it.
        if git_options.squashes {
            run_command(&["git", "checkout", &branch]);
            match run_command_with_status(&["git",
                                            "pull",
                                            "--ff-only",
                                            &git_options.remote,
                                            &git_options.base_branch]) {
                Ok(status) => {
                    if !status.success() {
                        println!("why");
                        branches.push(branch.into());
                    }
                }
                Err(err) => {
                    println!("Encountered error trying to update branch {} with branch {}: {}",
                             branch,
                             git_options.base_branch,
                             err);
                    continue;
                }
            }

            run_command(&["git", "reset", "--hard"]);
            run_command(&["git", "checkout", &git_options.base_branch]);
        }
    }

    // if deleted in remote, list
    //
    // g branch -d -r <remote>/<branch>
    // g branch -d <branch>

    Branches::new(branches)
}

fn delete_branches(branches: &Branches,
                   options: &DeleteOption,
                   git_options: &GitOptions)
                   -> String {
    match *options {
        DeleteOption::Local => delete_local_branches(branches),
        DeleteOption::Remote => delete_remote_branches(branches, git_options),
        DeleteOption::Both => {
            let local_output = delete_local_branches(branches);
            let remote_output = delete_remote_branches(branches, git_options);
            ["Remote:".to_owned(), remote_output, "\nLocal:".to_owned(), local_output].join("\n")
        }
    }
}

fn print_and_exit<E: Error>(e: &E) {
    println!("{}", e);
    std::process::exit(1);
}

#[cfg(test)]
mod test {
    use options::DeleteOption;
    use branches::Branches;

    use super::print_warning;

    #[test]
    fn test_print_warning() {
        print_warning(&Branches::new(vec!["branch".to_owned()]),
                      &DeleteOption::Both);
    }
}
<|endoftext|>


<commit_before>// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementation of running at_exit routines
//!
//! Documentation can be found on the `rt::at_exit` function.

use core::prelude::*;

use alloc::boxed::Box;
use collections::MutableSeq;
use collections::vec::Vec;
use core::atomics;
use core::mem;

use exclusive::Exclusive;

type Queue = Exclusive<Vec<proc():Send>>;

static mut QUEUE: atomics::AtomicUint = atomics::INIT_ATOMIC_UINT;
static mut RUNNING: atomics::AtomicBool = atomics::INIT_ATOMIC_BOOL;

pub fn init() {
    let state: Box<Queue> = box Exclusive::new(Vec::new());
    unsafe {
        rtassert!(!RUNNING.load(atomics::SeqCst));
        rtassert!(QUEUE.swap(mem::transmute(state), atomics::SeqCst) == 0);
    }
}

pub fn push(f: proc():Send) {
    unsafe {
        // Note that the check against 0 for the queue pointer is not atomic at
        // all with respect to `run`, meaning that this could theoretically be a
        // use-after-free. There's not much we can do to protect against that,
        // however. Let's just assume a well-behaved runtime and go from there!
        rtassert!(!RUNNING.load(atomics::SeqCst));
        let queue = QUEUE.load(atomics::SeqCst);
        rtassert!(queue != 0);
        (*(queue as *const Queue)).lock().push(f);
    }
}

pub fn run() {
    let cur = unsafe {
        rtassert!(!RUNNING.load(atomics::SeqCst));
        let queue = QUEUE.swap(0, atomics::SeqCst);
        rtassert!(queue != 0);

        let queue: Box<Queue> = mem::transmute(queue);
        let v = mem::replace(&mut *queue.lock(), Vec::new());
        v
    };

    for to_run in cur.move_iter() {
        to_run();
    }
}
<commit_msg>rustrt: Don't conditionally init the at_exit QUEUE<commit_after>// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementation of running at_exit routines
//!
//! Documentation can be found on the `rt::at_exit` function.

use core::prelude::*;

use alloc::boxed::Box;
use collections::MutableSeq;
use collections::vec::Vec;
use core::atomics;
use core::mem;

use exclusive::Exclusive;

type Queue = Exclusive<Vec<proc():Send>>;

static mut QUEUE: atomics::AtomicUint = atomics::INIT_ATOMIC_UINT;
static mut RUNNING: atomics::AtomicBool = atomics::INIT_ATOMIC_BOOL;

pub fn init() {
    let state: Box<Queue> = box Exclusive::new(Vec::new());
    unsafe {
        rtassert!(!RUNNING.load(atomics::SeqCst));
        assert!(QUEUE.swap(mem::transmute(state), atomics::SeqCst) == 0);
    }
}

pub fn push(f: proc():Send) {
    unsafe {
        // Note that the check against 0 for the queue pointer is not atomic at
        // all with respect to `run`, meaning that this could theoretically be a
        // use-after-free. There's not much we can do to protect against that,
        // however. Let's just assume a well-behaved runtime and go from there!
        rtassert!(!RUNNING.load(atomics::SeqCst));
        let queue = QUEUE.load(atomics::SeqCst);
        rtassert!(queue != 0);
        (*(queue as *const Queue)).lock().push(f);
    }
}

pub fn run() {
    let cur = unsafe {
        rtassert!(!RUNNING.load(atomics::SeqCst));
        let queue = QUEUE.swap(0, atomics::SeqCst);
        rtassert!(queue != 0);

        let queue: Box<Queue> = mem::transmute(queue);
        let v = mem::replace(&mut *queue.lock(), Vec::new());
        v
    };

    for to_run in cur.move_iter() {
        to_run();
    }
}
<|endoftext|>


<commit_before>extern crate iron;
extern crate serde;
extern crate serde_json;

#[macro_use]
extern crate serde_derive;

extern crate router;

use router::Router;
use iron::prelude::*;
use iron::{status, headers};
use iron::method::Method;
use iron::modifiers::Header;

use std::io::Read;
use std::process::Command;

#[derive(Debug, Deserialize, Serialize)]
struct Address {
    address: String
}

#[derive(Debug, Deserialize, Serialize)]
struct TxId {
	txid: String
}

#[derive(Debug, Deserialize, Serialize)]
struct OmniTransaction {
	#[serde(rename = "type")]
	type_type: String,
	txid: String,
	fee: String,
	sendingaddress: String,
	#[serde(default="default_string")]
	referenceaddress: String,
	ismine: bool,
	version: u8,
	type_int: u8,
	propertyid: u8,
	divisible: bool,
	amount: String,
	valid: bool,
	blockhash: String,
	blocktime: u32,
	positioninblock: u32,
	block: u32,
	confirmations: u32,
}

#[derive(Debug, Deserialize, Serialize)]
struct OmniInfo {
	omnicoreversion_int: u32,
	omnicoreversion: String,
	mastercoreversion: String,
	bitcoincoreversion: String,
	block: u32,
	blocktime: u32,
	blocktransactions: u32,
	totaltrades: u32,
	alerts: Vec<String>
}

fn default_string() -> String {
	"reference".to_string()
}
#[derive(Debug, Deserialize, Serialize)]
struct RawTxn {
	rawtx: String,
}

#[derive(Debug, Deserialize, Serialize)]
struct unconfirmedTransactions {
	txid: String,
	fee: String,
	sendingaddress: String,
	referenceaddress: String,
	ismine: bool,
	version: u32,
	type_int: u32,
	#[serde(rename = "type")]
	type_type: String,
	propertyid: u32,
	divisible: bool,
	amount: String,
	confirmations: u32
}

#[derive(Debug, Deserialize, Serialize)]
struct Payload {
	amount: String,
}

#[derive(Debug, Deserialize, Serialize)]
struct SafexTransaction {
	incomplete_tx: String,
	amount: String
}

fn main() {
	let mut router = Router::new();

	router.post("/balance", move |r: &mut Request| get_balance(r), "get_balance");
	router.post("/transactions", move |r: &mut Request| get_transactions(r), "get_transactions");
	router.post("/broadcast", move |r: &mut Request| broadcast(r), "broadcast");
	router.post("/unconfirmed", move |r: &mut Request| unconfirmed(r), "unconfirmed");
	router.post("/getsafextxn", move |r: &mut Request| getsafextxn(r), "getsafextxn");
	router.get("/getfee", move |r: &mut Request| getfee(r), "getfee");
	router.get("/blockheight", get_blockheight, "get_blockheight");

	//route for get balance, accepts a public key, and a property identifier

	fn get_balance(req: &mut Request) -> IronResult<Response> {

		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let address: Address = serde_json::from_str(&payload).unwrap();
		let balance = Command::new("omnicore-cli").arg("omni_getbalance").arg(address.address).arg("56").output().expect("failed");

		let output = balance.stdout;
		let mut response = Response::with((status::Ok, output));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn getsafextxn(req: &mut Request) -> IronResult<Response> {
		println!("hello");
		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let parameters: SafexTransaction = serde_json::from_str(&payload).unwrap();
		println!("{:?}", parameters);
		let payload = Command::new("omnicore-cli").arg("omni_createpayload_simplesend").arg("56").arg(parameters.amount).output().expect("failed");
		let mut payload = String::from_utf8(payload.stdout).unwrap();
		payload.pop();
		println!("{:?}", &payload);

		let complete_txn = Command::new("omnicore-cli").arg("omni_createrawtx_opreturn").arg(parameters.incomplete_tx).arg(payload).output().expect("failed");
		let mut complete_txn = String::from_utf8(complete_txn.stdout).unwrap();
		complete_txn.pop();
		println!("{:?}", &complete_txn);

		let mut response = Response::with((status::Ok, complete_txn));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn getfee(_: &mut Request) -> IronResult<Response> {

		let fee = Command::new("omnicore-cli").arg("estimatefee").arg("10").output().expect("failed");

		 let mut s = String::from_utf8(fee.stdout).unwrap();
    		s.pop();
		let mut response = Response::with((status::Ok, s));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn unconfirmed(req: &mut Request) -> IronResult<Response> {
		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let address: Address = serde_json::from_str(&payload).unwrap();
		let output = Command::new("omnicore-cli").arg("omni_listpendingtransactions").arg(&address.address).output().expect("failed");
		let output = String::from_utf8(output.stdout).unwrap();
		let output: Vec<unconfirmedTransactions> = serde_json::from_str(&output).unwrap();
		let mut pending_balance = 0;
		for txn in output {
			if address.address == txn.sendingaddress {
				pending_balance -= txn.amount.parse::<i32>().unwrap();
			} else {
				pending_balance += txn.amount.parse::<i32>().unwrap();
			}
		}

		let mut response = Response::with((status::Ok, pending_balance.to_string()));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn broadcast(req: &mut Request) -> IronResult<Response> {
		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let txn: RawTxn = serde_json::from_str(&payload).unwrap();
		let output = Command::new("omnicore-cli").arg("sendrawtransaction").arg(txn.rawtx).output().expect("failed");

		let output = output.stdout;
		let mut response = Response::with((status::Ok, output));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn get_transactions(req: &mut Request) -> IronResult<Response> {
		println!("{:?}", req);
		//todo remove unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		println!("got through read to string");
		let txid: TxId = serde_json::from_str(&payload).unwrap();
		println!("didnt get through txid");

		let transaction = Command::new("omnicore-cli").arg("omni_gettransaction").arg(txid.txid).output().expect("failed");

		println!("got the command in");

		let output = transaction.stdout;

		let string_output = String::from_utf8_lossy(&output);

		let safex_tx: OmniTransaction = serde_json::from_str(&string_output).unwrap();

		if safex_tx.propertyid == 56 {

			let mut response = Response::with((status::Ok, serde_json::to_string(&safex_tx).unwrap()));
			response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
			response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));

			Ok(response)
		} else {

			Ok(Response::with((status::Ok)))
		}

	}

	fn get_blockheight(_: &mut Request) -> IronResult<Response> {
		let block_info = Command::new("omnicore-cli").arg("omni_getinfo").output().expect("failed");

		let output = block_info.stdout;

		let string_output = String::from_utf8_lossy(&output);
		let block_info: OmniInfo = serde_json::from_str(&string_output).unwrap();

		let mut response = Response::with((status::Ok, serde_json::to_string(&block_info).unwrap()));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));

		Ok(response)
	}

	Iron::new(router).http("localhost:3001").unwrap();
}
<commit_msg>push wip<commit_after>extern crate iron;
extern crate serde;
extern crate serde_json;

#[macro_use]
extern crate serde_derive;

extern crate router;

use router::Router;
use iron::prelude::*;
use iron::{status, headers};
use iron::method::Method;
use iron::modifiers::Header;

use std::io::Read;
use std::process::Command;

	router.post("/balance", move |r: &mut Request| get_balance(r), "get_balance");
	router.post("/transactions", move |r: &mut Request| get_transactions(r), "get_transactions");
	router.post("/broadcast", move |r: &mut Request| broadcast(r), "broadcast");
	router.post("/unconfirmed", move |r: &mut Request| unconfirmed(r), "unconfirmed");
	router.post("/getsafextxn", move |r: &mut Request| getsafextxn(r), "getsafextxn");
	router.get("/getfee", move |r: &mut Request| getfee(r), "getfee");
	router.get("/blockheight", get_blockheight, "get_blockheight");

//balance post
//transactions post
//broadcast post
//unconfirmed post
//get safex txn post
//get fee
//get blockheight

#[derive(Debug, Deserialize, Serialize)]
struct Address {
    address: String
}

#[derive(Debug, Deserialize, Serialize)]
struct TxId {
	txid: String
}

#[derive(Debug, Deserialize, Serialize)]
struct OmniTransaction {
	#[serde(rename = "type")]
	type_type: String,
	txid: String,
	fee: String,
	sendingaddress: String,
	#[serde(default="default_string")]
	referenceaddress: String,
	ismine: bool,
	version: u8,
	type_int: u8,
	propertyid: u8,
	divisible: bool,
	amount: String,
	valid: bool,
	blockhash: String,
	blocktime: u32,
	positioninblock: u32,
	block: u32,
	confirmations: u32,
}

#[derive(Debug, Deserialize, Serialize)]
struct OmniInfo {
	omnicoreversion_int: u32,
	omnicoreversion: String,
	mastercoreversion: String,
	bitcoincoreversion: String,
	block: u32,
	blocktime: u32,
	blocktransactions: u32,
	totaltrades: u32,
	alerts: Vec<String>
}

fn default_string() -> String {
	"reference".to_string()
}
#[derive(Debug, Deserialize, Serialize)]
struct RawTxn {
	rawtx: String,
}

#[derive(Debug, Deserialize, Serialize)]
struct unconfirmedTransactions {
	txid: String,
	fee: String,
	sendingaddress: String,
	referenceaddress: String,
	ismine: bool,
	version: u32,
	type_int: u32,
	#[serde(rename = "type")]
	type_type: String,
	propertyid: u32,
	divisible: bool,
	amount: String,
	confirmations: u32
}

#[derive(Debug, Deserialize, Serialize)]
struct Payload {
	amount: String,
}

#[derive(Debug, Deserialize, Serialize)]
struct SafexTransaction {
	incomplete_tx: String,
	amount: String
}

fn main() {
	let mut router = Router::new();

	router.post("/balance", move |r: &mut Request| get_balance(r), "get_balance");
	router.post("/transactions", move |r: &mut Request| get_transactions(r), "get_transactions");
	router.post("/broadcast", move |r: &mut Request| broadcast(r), "broadcast");
	router.post("/unconfirmed", move |r: &mut Request| unconfirmed(r), "unconfirmed");
	router.post("/getsafextxn", move |r: &mut Request| getsafextxn(r), "getsafextxn");
	router.get("/getfee", move |r: &mut Request| getfee(r), "getfee");
	router.get("/blockheight", get_blockheight, "get_blockheight");

	router.post("/pull_safex_data", pull_safex_data, "pull_safex_data");

	fn pull_safex_data(req: &mut Request) -> IronResult<Response> {
		let mut payload = String::new();

		req.body.read_to_string(&mut payload).expect("failed parsing payload");

		let address: Address
	}
	//route for get balance, accepts a public key, and a property identifier

	fn get_balance(req: &mut Request) -> IronResult<Response> {

		//todo get rid of unwraps
		let mut payload = String::new();

		req.body.read_to_string(&mut payload).unwrap();

		let address: Address = serde_json::from_str(&payload).unwrap();
		let balance = Command::new("omnicore-cli").arg("omni_getbalance").arg(address.address).arg("56").output().expect("failed");

		let output = balance.stdout;
		let mut response = Response::with((status::Ok, output));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn getsafextxn(req: &mut Request) -> IronResult<Response> {
		println!("hello");
		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let parameters: SafexTransaction = serde_json::from_str(&payload).unwrap();
		println!("{:?}", parameters);
		let payload = Command::new("omnicore-cli").arg("omni_createpayload_simplesend").arg("56").arg(parameters.amount).output().expect("failed");
		let mut payload = String::from_utf8(payload.stdout).unwrap();
		payload.pop();
		println!("{:?}", &payload);

		let complete_txn = Command::new("omnicore-cli").arg("omni_createrawtx_opreturn").arg(parameters.incomplete_tx).arg(payload).output().expect("failed");
		let mut complete_txn = String::from_utf8(complete_txn.stdout).unwrap();
		complete_txn.pop();
		println!("{:?}", &complete_txn);

		let mut response = Response::with((status::Ok, complete_txn));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn getfee(_: &mut Request) -> IronResult<Response> {

		let fee = Command::new("omnicore-cli").arg("estimatefee").arg("10").output().expect("failed");

		 let mut s = String::from_utf8(fee.stdout).unwrap();
    		s.pop();
		let mut response = Response::with((status::Ok, s));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn unconfirmed(req: &mut Request) -> IronResult<Response> {
		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let address: Address = serde_json::from_str(&payload).unwrap();
		let output = Command::new("omnicore-cli").arg("omni_listpendingtransactions").arg(&address.address).output().expect("failed");
		let output = String::from_utf8(output.stdout).unwrap();
		let output: Vec<unconfirmedTransactions> = serde_json::from_str(&output).unwrap();
		let mut pending_balance = 0;
		for txn in output {
			if address.address == txn.sendingaddress {
				pending_balance -= txn.amount.parse::<i32>().unwrap();
			} else {
				pending_balance += txn.amount.parse::<i32>().unwrap();
			}
		}

		let mut response = Response::with((status::Ok, pending_balance.to_string()));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn broadcast(req: &mut Request) -> IronResult<Response> {
		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let txn: RawTxn = serde_json::from_str(&payload).unwrap();
		let output = Command::new("omnicore-cli").arg("sendrawtransaction").arg(txn.rawtx).output().expect("failed");

		let output = output.stdout;
		let mut response = Response::with((status::Ok, output));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn get_transactions(req: &mut Request) -> IronResult<Response> {
		println!("{:?}", req);
		//todo remove unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		println!("got through read to string");
		let txid: TxId = serde_json::from_str(&payload).unwrap();
		println!("didnt get through txid");

		let transaction = Command::new("omnicore-cli").arg("omni_gettransaction").arg(txid.txid).output().expect("failed");

		println!("got the command in");

		let output = transaction.stdout;

		let string_output = String::from_utf8_lossy(&output);

		let safex_tx: OmniTransaction = serde_json::from_str(&string_output).unwrap();

		if safex_tx.propertyid == 56 {

			let mut response = Response::with((status::Ok, serde_json::to_string(&safex_tx).unwrap()));
			response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
			response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));

			Ok(response)
		} else {

			Ok(Response::with((status::Ok)))
		}

	}

	fn get_blockheight(_: &mut Request) -> IronResult<Response> {
		let block_info = Command::new("omnicore-cli").arg("omni_getinfo").output().expect("failed");

		let output = block_info.stdout;

		let string_output = String::from_utf8_lossy(&output);
		let block_info: OmniInfo = serde_json::from_str(&string_output).unwrap();

		let mut response = Response::with((status::Ok, serde_json::to_string(&block_info).unwrap()));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));

		Ok(response)
	}

	Iron::new(router).http("localhost:3001").unwrap();
}
<|endoftext|>


<commit_before>#[macro_use] extern crate clap;
extern crate migrant;

use std::env;
use std::path::PathBuf;
use clap::{Arg, App, SubCommand};
use migrant::Error;
use migrant::Config;
use migrant::Direction;

fn main() {
    let matches = App::new("Migrant")
        .version(crate_version!())
        .author("James K. <james.kominick@gmail.com>")
        .about("Postgres migration manager")
        .subcommand(SubCommand::with_name("init")
            .about("Initialize project"))
        .subcommand(SubCommand::with_name("list")
            .about("List status of applied and available migrations"))
        .subcommand(SubCommand::with_name("apply")
            .about("Moves up or down (applies up/down.sql) one migration. Default direction is up unless specified with `-d/--down`.")
            .arg(Arg::with_name("down")
                .long("down")
                .short("d")
                .help("Applies `down.sql` migrations"))
            .arg(Arg::with_name("all")
                .long("all")
                .short("a")
                .help("Applies all available migrations"))
            .arg(Arg::with_name("force")
                .long("force")
                .help("Applies the migration and treats it as if it were successful"))
            .arg(Arg::with_name("fake")
                .long("fake")
                .help("Updates the `.migrant.toml` file as if the specified migration was applied")))
        .subcommand(SubCommand::with_name("new")
            .about("Create new migration up/down files")
            .arg(Arg::with_name("TAG")
                 .required(true)
                 .help("tag to use for new migration")))
        .subcommand(SubCommand::with_name("shell")
            .about("Open a repl connection"))
        .subcommand(SubCommand::with_name("which-config")
            .about("Display the path to the configuration file being used"))
        .get_matches();

    let dir = env::current_dir().expect("Unable to retrieve current directory");

    if let Err(ref e) = run(&dir, &matches) {
        println!("error: {}", e);
        ::std::process::exit(1);
    }
}

fn run(dir: &PathBuf, matches: &clap::ArgMatches) -> Result<(), Error> {
    let config_path = migrant::search_for_config(dir);

    if matches.is_present("init") || config_path.is_none() {
        let _ = migrant::Config::init(dir)?;
        return Ok(())
    }

    let config_path = config_path.unwrap();    // absolute path of `.migrant` file

    let config = Config::load(&config_path)?;

    match matches.subcommand() {
        ("list", _) => {
            migrant::list(&config)?;
        }
        ("new", Some(matches)) => {
            let tag = matches.value_of("TAG").unwrap();
            migrant::new(&config, tag)?;
            migrant::list(&config)?;
        }
        ("apply", Some(matches)) => {
            let force = matches.is_present("force");
            let fake = matches.is_present("fake");
            let all = matches.is_present("all");
            let direction = if matches.is_present("down") { Direction::Down } else { Direction::Up };

            migrant::Migrator::with_config(&config)
                .direction(direction)
                .force(force)
                .fake(fake)
                .all(all)
                .apply()?;

            let config = Config::load(&config_path)?;
            migrant::list(&config)?;
        }
        ("shell", _) => {
            migrant::shell(&config)?;
        }
        ("which-config", _) => {
            println!("{}", config_path.to_str().unwrap());
        }
        _ => {
            println!("migrant: see `--help`");
        }
    };
    Ok(())
}
<commit_msg>`Config` api<commit_after>#[macro_use] extern crate clap;
extern crate migrant;

use std::env;
use std::path::PathBuf;
use clap::{Arg, App, SubCommand};
use migrant::Error;
use migrant::Config;
use migrant::Direction;

fn main() {
    let matches = App::new("Migrant")
        .version(crate_version!())
        .author("James K. <james.kominick@gmail.com>")
        .about("Postgres migration manager")
        .subcommand(SubCommand::with_name("init")
            .about("Initialize project"))
        .subcommand(SubCommand::with_name("list")
            .about("List status of applied and available migrations"))
        .subcommand(SubCommand::with_name("apply")
            .about("Moves up or down (applies up/down.sql) one migration. Default direction is up unless specified with `-d/--down`.")
            .arg(Arg::with_name("down")
                .long("down")
                .short("d")
                .help("Applies `down.sql` migrations"))
            .arg(Arg::with_name("all")
                .long("all")
                .short("a")
                .help("Applies all available migrations"))
            .arg(Arg::with_name("force")
                .long("force")
                .help("Applies the migration and treats it as if it were successful"))
            .arg(Arg::with_name("fake")
                .long("fake")
                .help("Updates the `.migrant.toml` file as if the specified migration was applied")))
        .subcommand(SubCommand::with_name("new")
            .about("Create new migration up/down files")
            .arg(Arg::with_name("TAG")
                 .required(true)
                 .help("tag to use for new migration")))
        .subcommand(SubCommand::with_name("shell")
            .about("Open a repl connection"))
        .subcommand(SubCommand::with_name("which-config")
            .about("Display the path to the configuration file being used"))
        .get_matches();

    let dir = env::current_dir().expect("Unable to retrieve current directory");

    if let Err(ref e) = run(&dir, &matches) {
        println!("error: {}", e);
        ::std::process::exit(1);
    }
}

fn run(dir: &PathBuf, matches: &clap::ArgMatches) -> Result<(), Error> {
    let config_path = migrant::search_for_config(dir);

    if matches.is_present("init") || config_path.is_none() {
        let _ = migrant::Config::init(dir)?;
        return Ok(())
    }

    let config_path = config_path.unwrap();    // absolute path of `.migrant` file

    let config = Config::load(&config_path)?;

    match matches.subcommand() {
        ("list", _) => {
            migrant::list(&config)?;
        }
        ("new", Some(matches)) => {
            let tag = matches.value_of("TAG").unwrap();
            migrant::new(&config, tag)?;
            migrant::list(&config)?;
        }
        ("apply", Some(matches)) => {
            let force = matches.is_present("force");
            let fake = matches.is_present("fake");
            let all = matches.is_present("all");
            let direction = if matches.is_present("down") { Direction::Down } else { Direction::Up };

            migrant::Migrator::with_config(&config)
                .direction(direction)
                .force(force)
                .fake(fake)
                .all(all)
                .apply()?;

            let config = config.reload()?;
            migrant::list(&config)?;
        }
        ("shell", _) => {
            migrant::shell(&config)?;
        }
        ("which-config", _) => {
            println!("{}", config_path.to_str().unwrap());
        }
        _ => {
            println!("migrant: see `--help`");
        }
    };
    Ok(())
}
<|endoftext|>


<commit_before>extern crate sdl;
extern crate rand;
extern crate time;

use rand::Rng;

use time::PreciseTime;

use sdl::video::{SurfaceFlag, VideoFlag, Surface};
use sdl::event::{Event, Key};

struct Color {
    r: u8,
    g: u8,
    b: u8
}

struct Stars_3D {
    speed: i32,
    spread: i32,
    stars_x: Vec<f32>,
    stars_y: Vec<f32>,
    stars_z: Vec<f32>
}

impl Stars_3D {
    pub fn new(num_stars: usize, _spread: i32, _speed: i32) -> Stars_3D {
        let mut obj = Stars_3D {spread: _spread, speed: _speed, stars_x: vec![0.0; num_stars], stars_y: vec![0.0; num_stars], stars_z: vec![0.0; num_stars] };

        for idx in 0..num_stars {
            obj.init_star(idx);
        }

        obj
    }

    fn init_star(&mut self, idx: usize) {
        let mut rng = rand::thread_rng();
        self.stars_x[idx] = (2 as f32) * (rng.next_f32() - 0.5) * (self.spread as f32);
        self.stars_y[idx] = (2 as f32) * (rng.next_f32() - 0.5) * (self.spread as f32);
        self.stars_z[idx] = (rng.next_f32() + 0.00001) * (self.spread as f32);
    }

    pub fn update_and_render(&mut self, screen: &Surface, delta: f32)
	{
        clear(screen);

        let color = Color{r:233, g:233, b:233};

		let halfWidth  = screen.get_width() as f32 / 2.0f32;
		let halfHeight = screen.get_height()as f32 / 2.0f32;
        for i in 0..self.stars_x.len() {
            self.stars_z[i] -= delta * self.speed as f32;

            if(self.stars_z[i] <= 0f32) {
                self.init_star(i);
            }

            let x = (self.stars_x[i]/self.stars_z[i] * halfWidth + halfWidth);
            let y = (self.stars_y[i]/self.stars_z[i] * halfHeight + halfHeight);

            if x < 0f32 || x >= screen.get_width() as f32 || y < 0f32 || y >= screen.get_height() as f32 {
                self.init_star(i);
            } else {
                set_pixel(x as i32, y as i32, &color, &screen);
            }
        }
	}
}

fn clear(screen: &Surface) {
    screen.fill_rect(Some(sdl::Rect {
                x: 0,
                y: 0,
                w: screen.get_width(),
                h: screen.get_height()
            }), sdl::video::Color::RGB(0,0,0));
}

fn set_pixel(_x: i32, _y:i32, color: &Color, screen: &Surface) {

    // println!("{}",screen.get_width());
    let x: usize = _x as usize * 4;
    let y: usize = _y as usize * 4;
    let idx_blue: usize = x + y * screen.get_width() as usize;
    let idx_green: usize = (x + y * screen.get_width() as usize) + 1;
    let idx_red: usize = (x + y * screen.get_width() as usize) + 2;
    let idx_alpha: usize = (x + y * screen.get_width() as usize) + 3;

    screen.with_lock(|pixels| {
        pixels[idx_blue] = color.b;
        pixels[idx_green] = color.g;
        pixels[idx_red] = color.r;
        pixels[idx_alpha] = 0;

        true
    });
}

fn draw_line(x0: i32, y0: i32, x1: i32, y1: i32, color: &Color, screen: &Surface) {
    for x in x0..x1 {
        // println!("{}", x);
        let t: f32 = (x-x0) as f32 /(x1-x0) as f32;
        let y: i32 = (y0 as f32 *(1.0-t) + y1 as f32 *t) as i32;
        // image.set(x, y, color);
        set_pixel(x, y, color, screen);
    }
}

fn main() {
    sdl::init(&[sdl::InitFlag::Video]);
    sdl::wm::set_caption("rust-sdl demo - video", "rust-sdl");

    let mut rng = rand::thread_rng();
    let screen = match sdl::video::set_video_mode(1024, 768, 32,
                                                  &[SurfaceFlag::HWSurface],
                                                  &[VideoFlag::DoubleBuf]) {
        Ok(screen) => screen,
        Err(err) => panic!("failed to set video mode: {}", err)
    };

    // let color = Color{r:233, g:233, b:233};

    // set_pixel(400, 300, &color, &screen);

    // draw_line(10, 10, 100, 100, &color, &screen);

    // draw_line(13, 20, 80, 40,  &color, &screen);
    // draw_line(20, 13, 40, 80,  &color, &screen);
    // draw_line(80, 40, 13, 20,  &color, &screen);

    let mut stars = Stars_3D::new(4000, 64, 20);

    let mut start = PreciseTime::now();

    'main : loop {
        'event : loop {
            match sdl::event::poll_event() {
                Event::Quit => break 'main,
                Event::None => break 'event,
                Event::Key(k, _, _, _)
                    if k == Key::Escape
                        => break 'main,
                _ => { }
            }
        }

        let end = PreciseTime::now();
        let delta = start.to(end);
        start = PreciseTime::now();

        println!("{} ms", delta.num_milliseconds());

        stars.update_and_render(&screen, delta.num_milliseconds() as f32 / 1000f32);
        screen.flip();

    }

    sdl::quit();
}
<commit_msg>format<commit_after>extern crate sdl;
extern crate rand;
extern crate time;

use rand::Rng;

use time::PreciseTime;

use sdl::video::{SurfaceFlag, VideoFlag, Surface};
use sdl::event::{Event, Key};

struct Color {
    r: u8,
    g: u8,
    b: u8
}

struct Stars_3D {
    speed: i32,
    spread: i32,
    stars_x: Vec<f32>,
    stars_y: Vec<f32>,
    stars_z: Vec<f32>
}

impl Stars_3D {
    pub fn new(num_stars: usize, _spread: i32, _speed: i32) -> Stars_3D {
        let mut obj = Stars_3D {
            spread: _spread,
            speed: _speed,
            stars_x: vec![0.0; num_stars],
            stars_y: vec![0.0; num_stars],
            stars_z: vec![0.0; num_stars] };

        for idx in 0..num_stars {
            obj.init_star(idx);
        }

        obj
    }

    fn init_star(&mut self, idx: usize) {
        let mut rng = rand::thread_rng();
        self.stars_x[idx] = (2 as f32) * (rng.next_f32() - 0.5) * (self.spread as f32);
        self.stars_y[idx] = (2 as f32) * (rng.next_f32() - 0.5) * (self.spread as f32);
        self.stars_z[idx] = (rng.next_f32() + 0.00001) * (self.spread as f32);
    }

    pub fn update_and_render(&mut self, screen: &Surface, delta: f32)
	{
        clear(screen);

        let color = Color{r:233, g:233, b:233};

		let halfWidth  = screen.get_width() as f32 / 2.0f32;
		let halfHeight = screen.get_height()as f32 / 2.0f32;
        for i in 0..self.stars_x.len() {
            self.stars_z[i] -= delta * self.speed as f32;

            if(self.stars_z[i] <= 0f32) {
                self.init_star(i);
            }

            let x = (self.stars_x[i]/self.stars_z[i] * halfWidth + halfWidth);
            let y = (self.stars_y[i]/self.stars_z[i] * halfHeight + halfHeight);

            if x < 0f32 || x >= screen.get_width() as f32 || y < 0f32 || y >= screen.get_height() as f32 {
                self.init_star(i);
            } else {
                set_pixel(x as i32, y as i32, &color, &screen);
            }
        }
	}
}

fn clear(screen: &Surface) {
    screen.fill_rect(Some(sdl::Rect {
                x: 0,
                y: 0,
                w: screen.get_width(),
                h: screen.get_height()
            }), sdl::video::Color::RGB(0,0,0));
}

fn set_pixel(_x: i32, _y:i32, color: &Color, screen: &Surface) {

    // println!("{}",screen.get_width());
    let x: usize = _x as usize * 4;
    let y: usize = _y as usize * 4;
    let idx_blue: usize = x + y * screen.get_width() as usize;
    let idx_green: usize = (x + y * screen.get_width() as usize) + 1;
    let idx_red: usize = (x + y * screen.get_width() as usize) + 2;
    let idx_alpha: usize = (x + y * screen.get_width() as usize) + 3;

    screen.with_lock(|pixels| {
        pixels[idx_blue] = color.b;
        pixels[idx_green] = color.g;
        pixels[idx_red] = color.r;
        pixels[idx_alpha] = 0;

        true
    });
}

fn draw_line(x0: i32, y0: i32, x1: i32, y1: i32, color: &Color, screen: &Surface) {
    for x in x0..x1 {
        // println!("{}", x);
        let t: f32 = (x-x0) as f32 /(x1-x0) as f32;
        let y: i32 = (y0 as f32 *(1.0-t) + y1 as f32 *t) as i32;
        // image.set(x, y, color);
        set_pixel(x, y, color, screen);
    }
}

fn main() {
    sdl::init(&[sdl::InitFlag::Video]);
    sdl::wm::set_caption("rust-sdl demo - video", "rust-sdl");

    let mut rng = rand::thread_rng();
    let screen = match sdl::video::set_video_mode(1024, 768, 32,
                                                  &[SurfaceFlag::HWSurface],
                                                  &[VideoFlag::DoubleBuf]) {
        Ok(screen) => screen,
        Err(err) => panic!("failed to set video mode: {}", err)
    };

    // let color = Color{r:233, g:233, b:233};

    // set_pixel(400, 300, &color, &screen);

    // draw_line(10, 10, 100, 100, &color, &screen);

    // draw_line(13, 20, 80, 40,  &color, &screen);
    // draw_line(20, 13, 40, 80,  &color, &screen);
    // draw_line(80, 40, 13, 20,  &color, &screen);

    let mut stars = Stars_3D::new(4000, 64, 20);

    let mut start = PreciseTime::now();

    'main : loop {
        'event : loop {
            match sdl::event::poll_event() {
                Event::Quit => break 'main,
                Event::None => break 'event,
                Event::Key(k, _, _, _)
                    if k == Key::Escape
                        => break 'main,
                _ => { }
            }
        }

        let end = PreciseTime::now();
        let delta = start.to(end);
        start = PreciseTime::now();

        println!("{} ms", delta.num_milliseconds());

        stars.update_and_render(&screen, delta.num_milliseconds() as f32 / 1000f32);
        screen.flip();

    }

    sdl::quit();
}
<|endoftext|>