Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show Inaccuracy Warning on permission error #270

Merged
merged 8 commits into from
Nov 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions src/cli_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub const FALLBACK_ROW_LEN: usize = 79;
const NO_LANG_HEADER_ROW_LEN: usize = 67;
const NO_LANG_ROW_LEN: usize = 61;
const NO_LANG_ROW_LEN_NO_SPACES: usize = 54;
const IDENT_INACCURATE: &str = "(!)";

pub fn crate_version() -> String {
if Format::supported().is_empty() {
Expand Down Expand Up @@ -69,7 +70,7 @@ pub fn print_results<'a, I, W>(sink: &mut W, row: &str, languages: I, list_files
W: Write,
{
let path_len = row.len() - NO_LANG_ROW_LEN_NO_SPACES;
let lang_section_len = row.len() ;
let lang_section_len = row.len();
for (name, language) in languages.filter(isnt_empty) {
print_language(sink, lang_section_len, language, name.name())?;

Expand All @@ -96,14 +97,22 @@ pub fn print_language<W>(sink: &mut W,
-> io::Result<()>
where W: Write,
{
if language.inaccurate {
write!(sink, " {} {:<len$} ",
name, IDENT_INACCURATE,
len = lang_section_len - (NO_LANG_ROW_LEN + name.len() + 1))?;
} else {
write!(sink, " {:<len$} ", name, len = lang_section_len - NO_LANG_ROW_LEN)?;
}
writeln!(sink,
" {:<len$} {:>6} {:>12} {:>12} {:>12} {:>12}",
name,
"{:>6} {:>12} {:>12} {:>12} {:>12}",
language.stats.len(),
language.lines,
language.code,
language.comments,
language.blanks,
len = lang_section_len - NO_LANG_ROW_LEN)
language.blanks)
}

pub fn print_inaccuracy_warning<W>(sink: &mut W) -> io::Result<()> where W: Write {
writeln!(sink, "Note: results can be inaccurate for languages marked with '{}'", IDENT_INACCURATE)
}
26 changes: 13 additions & 13 deletions src/language/language_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,38 +17,38 @@ include!(concat!(env!("OUT_DIR"), "/language_type.rs"));

impl LanguageType {
/// Parses a given `Path` using the `LanguageType`. Returning `Stats`
/// on success.
pub fn parse(self, path: PathBuf) -> io::Result<Stats> {
/// on success and giving back ownership of PathBuf on error.
pub fn parse(self, path: PathBuf) -> Result<Stats, (io::Error, PathBuf)> {
XAMPPRocky marked this conversation as resolved.
Show resolved Hide resolved
let text = {
let f = File::open(&path)?;
let f = match File::open(&path) {
XAMPPRocky marked this conversation as resolved.
Show resolved Hide resolved
Ok(f) => f,
Err(e) => return Err((e, path)),
};
let mut s = String::new();
let mut reader = DecodeReaderBytes::new(f);

reader.read_to_string(&mut s)?;
if let Err(e) = reader.read_to_string(&mut s) {
XAMPPRocky marked this conversation as resolved.
Show resolved Hide resolved
return Err((e, path));
}
s
};

self.parse_from_str(path, &text)
Ok(self.parse_from_str(path, &text))
}

/// Parses the text provided. Returning `Stats` on success.
pub fn parse_from_str(self, path: PathBuf, text: &str)
-> io::Result<Stats>
pub fn parse_from_str(self, path: PathBuf, text: &str) -> Stats
XAMPPRocky marked this conversation as resolved.
Show resolved Hide resolved
{

let lines = text.lines();
let mut stats = Stats::new(path);

let stats = if self.is_blank() {
if self.is_blank() {
let count = lines.count();
stats.lines = count;
stats.code = count;
stats
} else {
self.parse_lines(lines, stats)
};

Ok(stats)
}
}

/// Attempts to parse the line as simply as possible if there are no multi
Expand Down
9 changes: 9 additions & 0 deletions src/language/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ pub struct Language {
pub lines: usize,
/// A collection of statistics based on the files provide from `files`
pub stats: Vec<Stats>,
/// Whether this language had problems with file parsing
pub inaccurate: bool,
}

impl Language {
Expand All @@ -48,6 +50,12 @@ impl Language {
self.stats.push(stat);
}

/// Marks this language as possibly not reflecting correct stats.
#[inline]
pub fn mark_inaccurate(&mut self) {
self.inaccurate = true;
}

/// Totals up all the statistics currently in the language.
pub fn total(&mut self) {
let mut blanks = 0;
Expand Down Expand Up @@ -104,6 +112,7 @@ impl AddAssign for Language {
self.blanks += rhs.blanks;
self.code += rhs.code;
self.stats.extend(mem::replace(&mut rhs.stats, Vec::new()));
self.inaccurate |= rhs.inaccurate
}
}

4 changes: 4 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ fn main() -> Result<(), Box<Error>> {

let mut stdout = io::BufWriter::new(io::stdout());

if languages.iter().any(|(_, lang)| lang.inaccurate) {
print_inaccuracy_warning(&mut stdout)?;
}

print_header(&mut stdout, &row, cli.columns)?;

if let Some(sort_category) = cli.sort {
Expand Down
28 changes: 21 additions & 7 deletions src/utils/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,16 @@ pub fn get_all_files(paths: &[&str],
walker.build_parallel().run(move|| {
let tx = tx.clone();
Box::new(move |entry| {

let entry = match entry {
Ok(entry) => entry,
Err(error) => {
use ignore::Error;
if let Error::WithDepth { err: ref error, .. } = error {
if let Error::WithPath { ref path, err: ref error } = **error {
error!("{} reading {}", error.description(), path.display());
return Continue;
}
}
error!("{}", error.description());
return Continue;
}
Expand All @@ -74,19 +80,27 @@ pub fn get_all_files(paths: &[&str],
types.map(|t| t.contains(&language)).unwrap()) ||
types.is_none()
{
return language.parse(entry.into_path())
.ok()
.and_then(|s| Some((language, s)))
match language.parse(entry.into_path()) {
Ok(s) => return Some((language, Some(s))),
Err((e, path)) => {
error!("{} reading {}", e.description(), path.display());
return Some((language, None));
},
}
}
}

None
}).collect();

for (language_type, stats) in iter {
languages.entry(language_type)
.or_insert_with(Language::new)
.add_stat(stats);
let entry = languages.entry(language_type).or_insert_with(Language::new);

if let Some(stats) = stats {
entry.add_stat(stats);
} else {
entry.mark_inaccurate();
}
}
}

Expand Down