aboutsummaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
authorTill Höppner2016-03-09 16:59:15 +0100
committerTill Höppner2016-03-09 17:01:04 +0100
commiteca90a051b4daebe12a8421c6c4f57d5b5b9fbbd (patch)
tree4af753d758b1349b105d4b79dc2ac740cff28581 /cli
parente15f184edc228b991ee87ca39a6a177e6938d9c6 (diff)
downloadilc-eca90a051b4daebe12a8421c6c4f57d5b5b9fbbd.tar.gz
ilc-eca90a051b4daebe12a8421c6c4f57d5b5b9fbbd.tar.xz
ilc-eca90a051b4daebe12a8421c6c4f57d5b5b9fbbd.zip
Allow ARM failure
Diffstat (limited to 'cli')
-rw-r--r--cli/Cargo.toml7
-rw-r--r--cli/build.rs15
-rw-r--r--cli/src/lib.rs120
-rw-r--r--cli/src/stats.rs73
4 files changed, 142 insertions, 73 deletions
diff --git a/cli/Cargo.toml b/cli/Cargo.toml
index 8e66b7e..e958ef5 100644
--- a/cli/Cargo.toml
+++ b/cli/Cargo.toml
@@ -6,6 +6,7 @@ homepage = "https://github.com/tilpner/ilc"
license = "Apache-2.0"
repository = "https://github.com/tilpner/ilc"
authors = ["Till Höppner <till@hoeppner.ws>"]
+build = "build.rs"
[features]
default = ["ilc-format-weechat", "ilc-format-energymech"]
@@ -14,9 +15,15 @@ default = ["ilc-format-weechat", "ilc-format-energymech"]
log = "0.3.5"
clap = "2.1.2"
chrono = "0.2.19"
+serde = "~0.7"
+serde_json = "~0.7"
env_logger = "0.3.2"
glob = "0.2.10"
ilc-base = "~0.2"
ilc-ops = "~0.1"
ilc-format-weechat = { optional = true, version = "~0.2" }
ilc-format-energymech = { optional = true, version = "~0.2" }
+includedir = "~0.2"
+
+[build-dependencies]
+includedir_codegen = "~0.2"
diff --git a/cli/build.rs b/cli/build.rs
new file mode 100644
index 0000000..e83c21a
--- /dev/null
+++ b/cli/build.rs
@@ -0,0 +1,15 @@
+extern crate includedir_codegen;
+
+use std::env;
+
+use includedir_codegen::Compression;
+
+fn main() {
+ let mut cg = includedir_codegen::start("FILES");
+ if env::var("PASSTHROUGH").is_ok() {
+ cg.passthrough();
+ }
+ cg.dir("../templates", Compression::Gzip)
+ .build("data.rs")
+ .unwrap();
+}
diff --git a/cli/src/lib.rs b/cli/src/lib.rs
index 9469cfb..ba7f792 100644
--- a/cli/src/lib.rs
+++ b/cli/src/lib.rs
@@ -1,17 +1,3 @@
-// Copyright 2015 Till Höppner
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
extern crate ilc_base;
extern crate ilc_ops;
extern crate ilc_format_weechat;
@@ -22,10 +8,11 @@ extern crate clap;
#[macro_use]
extern crate log;
extern crate env_logger;
+extern crate serde;
+extern crate serde_json;
extern crate glob;
use ilc_base::{Context, Decode, Encode};
-use ilc_ops::*;
use ilc_format_weechat::Weechat;
use ilc_format_energymech::Energymech;
@@ -40,19 +27,26 @@ use std::fs::File;
use std::path::{Path, PathBuf};
use std::ffi::OsStr;
use std::io::{self, BufRead, BufReader, BufWriter, Write};
-use std::{process, usize};
+use std::process;
use std::error::Error;
mod chain;
+mod stats;
+
+pub struct Cli {
+ pub version: String,
+ pub master_hash: String,
+}
-pub fn main() {
+pub fn main(cli: Cli) {
env_logger::init().unwrap();
if option_env!("FUSE").is_some() {
info!("Compiled with FUSEs")
}
+ let version = format!("{} ({})", cli.version, cli.master_hash);
let args = App::new("ilc")
- .version(crate_version!())
+ .version(&version[..])
.setting(AppSettings::GlobalVersion)
.setting(AppSettings::VersionlessSubcommands)
.setting(AppSettings::ArgRequiredElseHelp)
@@ -115,12 +109,12 @@ pub fn main() {
.about("Parse the input, checking the format"))
.subcommand(SubCommand::with_name("convert")
.about("Convert from a source to a target format"))
- .subcommand(SubCommand::with_name("freq")
+ .subcommand(SubCommand::with_name("stats")
.about("Analyse the activity of users by certain metrics")
- .arg(Arg::with_name("count")
+ /*.arg(Arg::with_name("count")
.help("The number of items to be displayed")
.takes_value(true)
- .long("count")))
+ .long("count"))*/)
.subcommand(SubCommand::with_name("seen")
.about("Print the last line a nick was active")
.arg(Arg::with_name("nick")
@@ -139,68 +133,61 @@ pub fn main() {
let res = match args.subcommand() {
("parse", Some(args)) => {
let e = Environment(&args);
- parse::parse(&e.context(), &mut e.input(), &mut *e.decoder())
+ ilc_ops::parse::parse(&e.context(), &mut e.input(), &mut *e.decoder())
}
("convert", Some(args)) => {
let e = Environment(&args);
- convert::convert(&e.context(),
- &mut e.input(),
- &mut *e.decoder(),
- &mut *e.output(),
- &*e.encoder())
+ ilc_ops::convert::convert(&e.context(),
+ &mut e.input(),
+ &mut *e.decoder(),
+ &mut *e.output(),
+ &*e.encoder())
}
- ("freq", Some(args)) => {
+ ("stats", Some(args)) => {
let e = Environment(&args);
- let count = value_t!(args, "count", usize).unwrap_or(usize::MAX);
- freq::freq(count,
- &e.context(),
- &mut e.input(),
- &mut *e.decoder(),
- &mut e.output())
+ let stats = ilc_ops::stats::stats(&e.context(), &mut e.input(), &mut *e.decoder())
+ .unwrap_or_else(|e| error(Box::new(e)));
+
+ stats::output_as_json(&args, &cli, stats)
}
("seen", Some(args)) => {
let e = Environment(&args);
let nick = args.value_of("nick").expect("Required argument <nick> not present");
- seen::seen(nick,
- &e.context(),
- &mut e.input(),
- &mut *e.decoder(),
- &mut *e.output(),
- &Weechat)
+ ilc_ops::seen::seen(nick,
+ &e.context(),
+ &mut e.input(),
+ &mut *e.decoder(),
+ &mut *e.output(),
+ &Weechat)
}
("sort", Some(args)) => {
let e = Environment(&args);
- sort::sort(&e.context(),
- &mut e.input(),
- &mut *e.decoder(),
- &mut *e.output(),
- &*e.encoder())
+ ilc_ops::sort::sort(&e.context(),
+ &mut e.input(),
+ &mut *e.decoder(),
+ &mut *e.output(),
+ &*e.encoder())
}
("dedup", Some(args)) => {
let e = Environment(&args);
- dedup::dedup(&e.context(),
- &mut e.input(),
- &mut *e.decoder(),
- &mut *e.output(),
- &*e.encoder())
+ ilc_ops::dedup::dedup(&e.context(),
+ &mut e.input(),
+ &mut *e.decoder(),
+ &mut *e.output(),
+ &*e.encoder())
}
("merge", Some(args)) => {
let e = Environment(&args);
let mut inputs = e.inputs();
- // let mut decoders = e.decoders();
-
let borrowed_inputs = inputs.iter_mut()
.map(|a| a as &mut BufRead)
.collect();
- // let borrowed_decoders = decoders.iter_mut()
- // .map(|a| &mut **a as &mut Decode)
- // .collect();
- merge::merge(&e.context(),
- borrowed_inputs,
- &mut *e.decoder(),
- &mut *e.output(),
- &*e.encoder())
+ ilc_ops::merge::merge(&e.context(),
+ borrowed_inputs,
+ &mut *e.decoder(),
+ &mut *e.output(),
+ &*e.encoder())
}
(sc, _) if !sc.is_empty() => panic!("Unimplemented subcommand `{}`, this is a bug", sc),
_ => die("No command specified"),
@@ -302,19 +289,6 @@ impl<'a> Environment<'a> {
force_decoder(self.0.value_of("format").or(self.0.value_of("input_format")))
}
- /* pub fn decoders(&self) -> Vec<Box<Decode>> {
- * self.0
- * .value_of("format")
- * .into_iter()
- * .chain(self.0
- * .values_of("input_formats")
- * .map(|i| Box::new(i) as Box<Iterator<Item = _>>)
- * .unwrap_or(Box::new(iter::empty()) as Box<Iterator<Item = _>>))
- * .map(Option::Some)
- * .map(force_decoder)
- * .collect()
- * } */
-
pub fn encoder(&self) -> Box<Encode> {
force_encoder(self.0.value_of("format").or(self.0.value_of("output_format")))
}
diff --git a/cli/src/stats.rs b/cli/src/stats.rs
new file mode 100644
index 0000000..390a200
--- /dev/null
+++ b/cli/src/stats.rs
@@ -0,0 +1,73 @@
+use clap::ArgMatches;
+
+use chrono::Local;
+
+use serde_json;
+use serde::ser::{MapVisitor, Serialize, Serializer};
+
+use ilc_base;
+use ilc_ops::stats::Stats;
+use Environment;
+use Cli;
+use error;
+
+struct StatFormat {
+ version: String,
+ master_hash: String,
+ time: String,
+ stats: Stats,
+}
+
+impl Serialize for StatFormat {
+ fn serialize<S>(&self, s: &mut S) -> Result<(), S::Error>
+ where S: Serializer
+ {
+ struct Visitor<'a>(&'a StatFormat);
+ impl<'a> MapVisitor for Visitor<'a> {
+ fn visit<S>(&mut self, s: &mut S) -> Result<Option<()>, S::Error>
+ where S: Serializer
+ {
+ try!(s.serialize_struct_elt("version", &self.0.version));
+ try!(s.serialize_struct_elt("master_hash", &self.0.master_hash));
+ try!(s.serialize_struct_elt("time", &self.0.time));
+ try!(s.serialize_struct_elt("stats", &self.0.stats));
+ Ok(None)
+ }
+
+ fn len(&self) -> Option<usize> {
+ Some(4)
+ }
+ }
+ s.serialize_struct("StatFormat", Visitor(self))
+ }
+}
+
+
+pub fn output_as_json(args: &ArgMatches, cli: &Cli, stats: Stats) -> ilc_base::Result<()> {
+ let e = Environment(args);
+ // let count = value_t!(args, "count", usize).unwrap_or(usize::MAX);
+ // let mut stats: Vec<(String, Person)> = stats.into_iter().collect();
+ // stats.sort_by(|&(_, ref a), &(_, ref b)| b.words.cmp(&a.words));
+
+ // for &(ref name, ref stat) in stats.iter().take(count) {
+
+ let format = StatFormat {
+ version: cli.version.clone(),
+ master_hash: cli.master_hash.clone(),
+ time: Local::now().to_rfc2822(),
+ stats: stats,
+ };
+
+ serde_json::to_writer_pretty(&mut e.output(), &format).unwrap_or_else(|e| error(Box::new(e)));
+ /* write!(&mut *e.output(),
+ * "{}:\n\tTotal lines: {}\n\tLines without alphabetic characters: {}\n\tTotal \
+ * words: {}\n\tWords per line: {}\n",
+ * name,
+ * stat.lines,
+ * stat.lines - stat.alpha_lines,
+ * stat.words,
+ * stat.words as f32 / stat.lines as f32)
+ * .unwrap_or_else(|e| error(Box::new(e))); */
+ // }
+ Ok(())
+}