<commit_before>// Copyright (C) 2017, 2018 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0
use argh::FromArgs;
use slog_scope::info;

#[derive(FromArgs)]
/// Top-level command.
struct TopLevel {
    #[argh(subcommand)]
    entry_point: EntryPoints,
}

#[derive(FromArgs)]
#[argh(subcommand)]
enum EntryPoints {
    Cli(CliOptions),
    Server(ServerOptions),
}

#[derive(FromArgs)]
/// Cli subcommand
#[argh(subcommand, name = "cli")]
struct CliOptions {
    #[argh(subcommand)]
    commands: CliCommands,
}

#[derive(FromArgs)]
#[argh(subcommand)]
enum CliCommands {
    Probe(SubCommandProbe),
    ProbeCustom(SubCommandProbeCustom),
    Info(SubCommandInfo),
    Log(SubCommandLog),
    Abort(SubCommandAbort),
    Download(SubCommandDownload),
}

#[derive(FromArgs)]
/// Probe subcommand
#[argh(subcommand, name = "probe")]
struct SubCommandProbe {}

#[derive(FromArgs)]
/// Info subcommand
#[argh(subcommand, name = "info")]
struct SubCommandInfo {}

#[derive(FromArgs)]
/// Log subcommand
#[argh(subcommand, name = "log")]
struct SubCommandLog {}

#[derive(FromArgs)]
/// Abort subcommand
#[argh(subcommand, name = "abort")]
struct SubCommandAbort {}

#[derive(FromArgs)]
/// Download subcommand
#[argh(subcommand, name = "download")]
struct SubCommandDownload {}

#[derive(FromArgs)]
/// Probe custom subcommand
#[argh(subcommand, name = "probe-custom")]
struct SubCommandProbeCustom {
    /// custom address to try probe
    #[argh(positional)]
    server: String,
}

#[derive(FromArgs)]
/// Server subcommand
#[argh(subcommand, name = "server")]
struct ServerOptions {
    /// increase the verboseness level
    #[argh(option, short = 'v', from_str_fn(verbosity_level))]
    verbose: Option<slog::Level>,
}

fn verbosity_level(value: &str) -> Result<slog::Level, String> {
    use std::str::FromStr;
    slog::Level::from_str(value).map_err(|_| format!("Failed to parse verbosity level: {}", value))
}

async fn server_main(cmd: ServerOptions) -> updatehub::Result<()> {
    updatehub::logger::init(cmd.verbose.unwrap_or(slog::Level::Info));
    info!("Starting UpdateHub Agent {}", updatehub::version());

    let settings = updatehub::Settings::load()?;
    updatehub::run(settings).await?;

    Ok(())
}

async fn cli_main(cmd: CliCommands) -> updatehub::Result<()> {
    let client = sdk::Client::new("localhost:8080");

    let res = match cmd {
        CliCommands::Info(_) => client.info().await,
        CliCommands::Probe(_) => todo!("probe"),
        CliCommands::Log(_) => todo!("log"),
        CliCommands::Abort(_) => todo!("abort"),
        CliCommands::Download(_) => todo!("Download"),
        CliCommands::ProbeCustom(input) => todo!("Probe custom {:?}", input.server),
    };

    dbg!(res).unwrap();

    Ok(())
}

#[actix_rt::main]
async fn main() {
    let cmd: TopLevel = argh::from_env();

    let res = match cmd.entry_point {
        EntryPoints::Cli(cli) => cli_main(cli.commands).await,
        EntryPoints::Server(cmd) => server_main(cmd).await,
    };

    if let Err(e) = res {
        eprintln!("{}", e);
        std::process::exit(1);
    }
}<commit_msg>updatehub: Finish commands on client<commit_after>// Copyright (C) 2017, 2018 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0
use argh::FromArgs;
use slog_scope::info;
use std::path::PathBuf;

#[derive(FromArgs)]
/// Top-level command.
struct TopLevel {
    #[argh(subcommand)]
    entry_point: EntryPoints,
}

#[derive(FromArgs)]
#[argh(subcommand)]
enum EntryPoints {
    Client(ClientOptions),
    Server(ServerOptions),
}

#[derive(FromArgs)]
/// Client subcommand
#[argh(subcommand, name = "client")]
struct ClientOptions {
    #[argh(subcommand)]
    commands: ClientCommands,
}

#[derive(FromArgs)]
#[argh(subcommand)]
enum ClientCommands {
    Info(Info),
    Log(Log),
    Probe(Probe),
    AbortDownload(AbortDownload),
    LocalInstall(LocalInstall),
    RemoteInstall(RemoteInstall),
}

#[derive(FromArgs)]
/// Fetches information about the current state of the agent
#[argh(subcommand, name = "info")]
struct Info {}

#[derive(FromArgs)]
/// Fetches the available log entries for the last update cycle
#[argh(subcommand, name = "log")]
struct Log {}

#[derive(FromArgs)]
/// Checks if the server has a new update for this device.
///
/// A custom server for the update cycle can be specified via the ´--server´
#[argh(subcommand, name = "probe")]
struct Probe {
    /// custom address to try probe
    #[argh(option)]
    server: Option<String>,
}

#[derive(FromArgs)]
/// Abort current running download
#[argh(subcommand, name = "abort-download")]
struct AbortDownload {}

#[derive(FromArgs)]
/// Request agent to install a local update package
#[argh(subcommand, name = "local-install")]
struct LocalInstall {
    /// path to the update package
    #[argh(positional)]
    file: PathBuf,
}

#[derive(FromArgs)]
/// Request agent to download and install a package from a direct URL
#[argh(subcommand, name = "remote-install")]
struct RemoteInstall {
    /// the URL to get the update package
    #[argh(positional)]
    url: String,
}

#[derive(FromArgs)]
/// Server subcommand
#[argh(subcommand, name = "server")]
struct ServerOptions {
    /// increase the verboseness level
    #[argh(option, short = 'v', from_str_fn(verbosity_level))]
    verbosity: Option<slog::Level>,
}

fn verbosity_level(value: &str) -> Result<slog::Level, String> {
    use std::str::FromStr;
    slog::Level::from_str(value).map_err(|_| format!("Failed to parse verbosity level: {}", value))
}

async fn server_main(cmd: ServerOptions) -> updatehub::Result<()> {
    updatehub::logger::init(cmd.verbosity.unwrap_or(slog::Level::Info));
    info!("Starting UpdateHub Agent {}", updatehub::version());

    let settings = updatehub::Settings::load()?;
    updatehub::run(settings).await?;

    Ok(())
}

async fn client_main(cmd: ClientCommands) -> updatehub::Result<()> {
    let client = sdk::Client::new("localhost:8080");

    match cmd {
        ClientCommands::Info(_) => println!("{:#?}", client.info().await),
        ClientCommands::Log(_) => println!("{:#?}", client.log().await),
        ClientCommands::Probe(Probe { server }) => println!("{:#?}", client.probe(server).await),
        ClientCommands::AbortDownload(_) => println!("{:#?}", client.abort_download().await),
        ClientCommands::LocalInstall(LocalInstall { file }) => {
            let file =
                if file.is_absolute() { file } else { std::env::current_dir().unwrap().join(file) };
            println!("{:#?}", client.local_install(file).await)
        }
        ClientCommands::RemoteInstall(RemoteInstall { url }) => {
            println!("{:#?}", client.remote_install(url).await)
        }
    }

    Ok(())
}

#[actix_rt::main]
async fn main() {
    let cmd: TopLevel = argh::from_env();

    let res = match cmd.entry_point {
        EntryPoints::Client(client) => client_main(client.commands).await,
        EntryPoints::Server(cmd) => server_main(cmd).await,
    };

    if let Err(e) = res {
        eprintln!("{}", e);
        std::process::exit(1);
    }
}
{'fraction_non_alphanumeric': 0.17473535638673254, 'fraction_numerical': 0.004234297812279464, 'mean_word_length': 4.105187319884727, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 34, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 15, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '882271', 'n_tokens_mistral': 2288, 'n_tokens_neox': 2363, 'n_words': 499}