diff options
author | Norbert Preining <norbert@preining.info> | 2020-11-30 03:00:37 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2020-11-30 03:00:37 +0000 |
commit | cb68d38823870fa7adb5f0c2b68cf59205dd4bec (patch) | |
tree | 8d6e29ee5d082dcbf1ad936b7025db071e9cf573 /support/pkgcheck | |
parent | 0cc87411bcebcb1b0d2a3488d7a7093024b58650 (diff) |
CTAN sync 202011300300
Diffstat (limited to 'support/pkgcheck')
-rw-r--r-- | support/pkgcheck/CHANGES.md | 48 | ||||
-rw-r--r-- | support/pkgcheck/Cargo.toml | 11 | ||||
-rwxr-xr-x | support/pkgcheck/bin/pkgcheck | bin | 6109008 -> 6203840 bytes | |||
-rw-r--r-- | support/pkgcheck/docs/errorsd.tex | 47 | ||||
-rw-r--r-- | support/pkgcheck/docs/pkgcheck.pdf | bin | 75087 -> 77796 bytes | |||
-rw-r--r-- | support/pkgcheck/docs/title.tex | 2 | ||||
-rw-r--r-- | support/pkgcheck/src/filemagic.rs | 22 | ||||
-rw-r--r-- | support/pkgcheck/src/linkcheck.rs | 6 | ||||
-rw-r--r-- | support/pkgcheck/src/main.rs | 207 | ||||
-rw-r--r-- | support/pkgcheck/src/messages/errorsd.rs | 159 | ||||
-rw-r--r-- | support/pkgcheck/src/messages/informationd.rs | 1 | ||||
-rw-r--r-- | support/pkgcheck/src/messages/mod.rs | 72 | ||||
-rw-r--r-- | support/pkgcheck/src/messages/warningsd.rs | 1 | ||||
-rw-r--r-- | support/pkgcheck/src/utils.rs | 1 |
14 files changed, 394 insertions, 183 deletions
diff --git a/support/pkgcheck/CHANGES.md b/support/pkgcheck/CHANGES.md index dab0c748ab..9ef9e83474 100644 --- a/support/pkgcheck/CHANGES.md +++ b/support/pkgcheck/CHANGES.md @@ -6,7 +6,7 @@ # Changes -2018-12-09 (1.0.0) +2018-12-09 (1.0.0) - 1.0.0 First stable version 2018-12-16 (1.0.0) @@ -15,17 +15,17 @@ - devnotes.md: add documentation how to build your own binary 2018-12-26 (1.1.0) - - enhance check for generated files which now could reside in any + - enhance check for generated files which now could reside in any subdirectory in the package tree. This changes the format of the - e0019 message slightly where now the path of a generated file will be + e0019 message slightly where now the path of a generated file will be displayed in the e0019 message - change ordering of the sections in the pkgcheck.pdf document. First come the informational messages, then warnings and error messages and finally fatal messages. - - add a short info to the PDF documention about how to install pkgcheck + - add a short info to the PDF documention about how to install pkgcheck 2019-01-02 (1.2.0) - some code simplification - - **New feature**: checks that path names in the TDS zip archive contain the package name + - **New feature**: checks that path names in the TDS zip archive contain the package name (only exception is a man page path) - add test cases for messages e0026, e0028 @@ -33,19 +33,19 @@ - recompile with newest http library - checking URLs - when checking URLs we try to get the headers first. If this fails we try to get the web page. - - when checking URLs and a redirect has an invalid location containing 127.0.0.1 + - when checking URLs and a redirect has an invalid location containing 127.0.0.1 then we regard the url as ok - ignoring .tfm files when checking for duplicates - - now checking for UTF BOMs. If a README file contains a BOM we issue an error message, + - now checking for UTF BOMs. If a README file contains a BOM we issue an error message, if other files contain BOMs we issue a warning message 2019-03-11 (1.4.0) - - recognizing generated files in a .dtx file when they are included using a + - recognizing generated files in a .dtx file when they are included using a filecontents resp. filecontents* environment. 2019-03-14 (1.5.0) - a README can be a symlink which will now be detected properly - - if a symlink points to a file object outside of the package directory tree error message + - if a symlink points to a file object outside of the package directory tree error message e0030 will be issued 2019-03-29 (1.6.0) @@ -114,29 +114,41 @@ - old: -L, --correct-crlf Correct CRLF line endings - new: -L, --correct-le Correct line endings - other changes - - new message F0007 when tmp directory is not writable or the tmp directory is full + - new message F0007 when tmp directory is not writable or the tmp directory is full - some code simplifications - crates update - - when detecting an empty file also permissions will be checked and (if requested) corrected + - when detecting an empty file also permissions will be checked and (if requested) corrected - (Experimental) for latex-base-dev, latex-tools-dev, latex-graphics-dev and latex-amsmath-dev check for latex-dev in the path names in the TDS zip archive - if a file in a generated file statement contains a directory part it was correctly recognized but not compared correctly to the contents of the TDS zip archive 2020-02-07 (2.0.1) - - use the `-a` (convert text files) flag when temporarily unzipping the TDS archive + - use the `-a` (convert text files) flag when temporarily unzipping the TDS archive - crates update 2020-04-12 (2.1.0) - add new test case e0033 - don't issue error messages when a .bat file has 0755 permission - improvements regarding detection of generated files (error message e0019) - - generated REAME files caused e0019 error message when they were specified with + - generated REAME files caused e0019 error message when they were specified with a relative path name in the `\generate` statement in the .dtx resp. .ins file - don't issue error message when a pdf file, generated by .dtx/.ins, exists - don't issue error message when an existing .ins file is generated by a .dtx file - - improved text in error message e0019 - - call pdfinfo and unzip without specifying an absolute path so that it gets found - when it is outside of /usr/bin (reported by Arthur Reutenauer) - - + - improved text in error message e0019 + - call pdfinfo and unzip without specifying an absolute path so that it gets found + when it is outside of /usr/bin (reported by Arthur Reutenauer) + +2020-11-20 (2.2.0) + - small code changes due to new release of blake2 library + - replace deprecated tempdir crate by tempfile crate + - (Experimental) instead of latex-firstaid use latex/firstaid when checking path names + in TDS zip archive + - unpack TDS zip without -a flag which was introduced in 2.0.1. According to Petra this creates + more problems than it solves + - revive e0020 which checks for unwanted directories in the top level directory of a TDS zip + archive. + - new error message e0039: no doc/ top level directory in tds zip archive + - new error message e0040: too few top level directories in tds zip archive + - new error message e0041: map file found in path not starting with `fonts/map/dvips` + - add more test cases diff --git a/support/pkgcheck/Cargo.toml b/support/pkgcheck/Cargo.toml index 39fe8901b5..870304d75c 100644 --- a/support/pkgcheck/Cargo.toml +++ b/support/pkgcheck/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pkgcheck" -version = "2.1.0" +version = "2.2.0" authors = ["Manfred Lotz <manfred@ctan.org>"] description = "Command-line tool to check packages uploaded to CTAN." license = "MIT/Apache-2.0" @@ -10,24 +10,25 @@ edition = "2018" # https://doc.rust-lang.org/edition-guide/rust-2018/error-handling-and-panics/aborting-on-panic.html [profile.release] panic = "abort" +lto = true [dependencies] structopt = "0.3" walkdir = "2.3" scoped_threadpool = "0.1" num_cpus = "1" -blake2 = "0.8" +blake2 = "0.9" fnv = "1.0.6" unbytify = "0.2" regex = "1" glob = "0.3" -colored = "1" +colored = "2" linkify = "0.4" reqwest = { version = "0.10", features = ["blocking", "gzip"] } lazy_static = "1" -tempdir = "0.3" +tempfile = "3.1" assert_cmd = "1" predicates = "1" openssl-probe = "0.1.2" @@ -35,7 +36,7 @@ pest = "2.1" pest_derive = "2.1" escargot = "0.5" -threadpool = "1.7.1" +threadpool = "1.8" unicode-bom = "1" url = "2.1" diff --git a/support/pkgcheck/bin/pkgcheck b/support/pkgcheck/bin/pkgcheck Binary files differindex c00875db43..38a8dd0ae4 100755 --- a/support/pkgcheck/bin/pkgcheck +++ b/support/pkgcheck/bin/pkgcheck diff --git a/support/pkgcheck/docs/errorsd.tex b/support/pkgcheck/docs/errorsd.tex index 33e2ea6fd9..db76736db0 100644 --- a/support/pkgcheck/docs/errorsd.tex +++ b/support/pkgcheck/docs/errorsd.tex @@ -192,6 +192,22 @@ directory tree. For more details refer to: \href{http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html\#nogeneratedfiles}{http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html\#nogeneratedfiles} +\hypertarget{e0020----unwanted-directory-detected-in-the-top-level-directory-in-tds-zip-archive}{% +\subsection{E0020 -\/- Unwanted directory detected in the top level +directory in TDS zip +archive}\label{e0020----unwanted-directory-detected-in-the-top-level-directory-in-tds-zip-archive}} + +The name of a top level directory of a TDS archive must be one of those +listed here: \texttt{asymptote}, \texttt{bibtex}, \texttt{chktex}, +\texttt{context}, \texttt{doc}, \texttt{dvipdfmx}, \texttt{dvips}, +\texttt{fonts}, \texttt{hbf2gf}, \texttt{makeindex}, \texttt{metafont}, +\texttt{metapost}, \texttt{mft}, \texttt{omega}, \texttt{pbibtex}, +\texttt{psutils}, \texttt{scripts}, \texttt{source}, \texttt{tex}, +\texttt{tex4ht}, \texttt{texconfig}, \texttt{texdoc}, \texttt{texdoctk}, +\texttt{ttf2pk}, \texttt{web2c}, \texttt{xdvi}, \texttt{xindy}, + +Any other other directory at the top level is an error. + \hypertarget{e0021----error-when-reading-a-file}{% \subsection{E0021 -\/- Error when reading a file}\label{e0021----error-when-reading-a-file}} @@ -343,3 +359,34 @@ files should have UNIX style line endings. For more details refer to: \href{http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html\#crlf}{http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html\#crlf} + +\hypertarget{e0039----no-doc-directory-found-in-the-top-level-directory-of-the-tds-zip-archive}{% +\subsection{E0039 -\/- No doc/ directory found in the top level +directory of the TDS zip +archive}\label{e0039----no-doc-directory-found-in-the-top-level-directory-of-the-tds-zip-archive}} + +A TDS zip archive is required to contain a top level directory doc/. + +\hypertarget{e0040----too-few-top-level-directories-in-the-tds-zip-archive}{% +\subsection{E0040 -\/- Too few top level directories in the TDS zip +archive}\label{e0040----too-few-top-level-directories-in-the-tds-zip-archive}} + +The top level directory of a TDS zip archive must contain at least a +\texttt{doc} directory and one or more of the following directories: +\texttt{asymptote}, \texttt{bibtex}, \texttt{chktex}, \texttt{context}, +\texttt{dvipdfmx}, \texttt{dvips}, \texttt{fonts}, \texttt{hbf2gf}, +\texttt{makeindex}, \texttt{metafont}, \texttt{metapost}, \texttt{mft}, +\texttt{omega}, \texttt{pbibtex}, \texttt{psutils}, \texttt{scripts}, +\texttt{source}, \texttt{tex}, \texttt{tex4ht}, \texttt{texconfig}, +\texttt{texdoc}, \texttt{texdoctk}, \texttt{ttf2pk}, \texttt{web2c}, +\texttt{xdvi}, \texttt{xindy}, + +Any other other directory at the top level is an error. + +\hypertarget{e0041----one-or-more-map-file-found-for-the-package-but-none-of-them-is-in-a-path-starting-with-fontsmapdvips}{% +\subsection{E0041 -\/- One or more map file found for the package but +none of them is in a path starting with +fonts/map/dvips}\label{e0041----one-or-more-map-file-found-for-the-package-but-none-of-them-is-in-a-path-starting-with-fontsmapdvips}} + +At least one map file was found which was not in a path starting with +\texttt{fonts/map/dvips}. diff --git a/support/pkgcheck/docs/pkgcheck.pdf b/support/pkgcheck/docs/pkgcheck.pdf Binary files differindex cbad89da3d..9b8a0d7468 100644 --- a/support/pkgcheck/docs/pkgcheck.pdf +++ b/support/pkgcheck/docs/pkgcheck.pdf diff --git a/support/pkgcheck/docs/title.tex b/support/pkgcheck/docs/title.tex index de019a5346..0ee70ed152 100644 --- a/support/pkgcheck/docs/title.tex +++ b/support/pkgcheck/docs/title.tex @@ -1 +1 @@ -\title{pkgcheck Utility, v2.1.0} +\title{pkgcheck Utility, v2.2.0} diff --git a/support/pkgcheck/src/filemagic.rs b/support/pkgcheck/src/filemagic.rs index 2ae8bfae6e..aa9c50feda 100644 --- a/support/pkgcheck/src/filemagic.rs +++ b/support/pkgcheck/src/filemagic.rs @@ -19,7 +19,6 @@ use unicode_bom::Bom; // - https://filesignatures.net/ // - https://github.com/7h3rAm/cigma/blob/master/cigma/magicbytes.json - #[derive(Debug, PartialEq)] pub enum LineEnding { LF, @@ -49,7 +48,6 @@ pub enum Mimetype { BOM(Bom), } - pub struct Filetype { buffer: Vec<u8>, } @@ -318,11 +316,11 @@ fn is_archive(vec: &[u8]) -> Option<Mimetype> { r"^(?-u)\x52\x61\x72\x21\x1A\x07\x00", // RAR archive version 1.50 onwards r"^(?-u)\x52\x61\x72\x21\x1A\x07\x01\x00", // RAR archive version 5.0 onwards // https://en.wikipedia.org/wiki/LHA_(file_format) - r"^(?-u)..-lh[0124567d]", // LHarc (canonical LZH) - r"^(?-u)..-lh[89abce]", // LHarc (Joe Jared extensions) - r"^(?-u)..-lhx", // LHarc (UNLHA32 extensions) - r"^(?-u)..-(pc1|pm0|pm1|pm2|pms)", // LHarc (PMarc extensions) - r"^(?-u)..-lz[s234578]", // LHarc (LArc extensions) + r"^(?-u)..-lh[0124567d]", // LHarc (canonical LZH) + r"^(?-u)..-lh[89abce]", // LHarc (Joe Jared extensions) + r"^(?-u)..-lhx", // LHarc (UNLHA32 extensions) + r"^(?-u)..-(pc1|pm0|pm1|pm2|pms)", // LHarc (PMarc extensions) + r"^(?-u)..-lz[s234578]", // LHarc (LArc extensions) r"^(?-u)\x53\x5a\x44\x44\x88\xf0\x27\x33", // RAR archive version 5.0 onwards ]) .unwrap(); @@ -417,7 +415,10 @@ fn test_filetype() { assert!(ft.analyze("tests_filemagic/empty.zip").ok() == Some(Mimetype::Zip)); - assert!(ft.analyze("tests_filemagic/README").ok() == Some(Mimetype::Text(LineEnding::MIXED(0,0,0)))); + assert!( + ft.analyze("tests_filemagic/README").ok() + == Some(Mimetype::Text(LineEnding::MIXED(0, 0, 0))) + ); // assert!(ft.analyze("tests_filemagic/README1").ok() == Some(Mimetype::Text)); assert!(ft.analyze("tests_filemagic/cp").ok() == Some(Mimetype::Binary)); @@ -431,5 +432,8 @@ fn test_filetype() { assert!(ft.analyze("tests_filemagic/chap5.rtf").ok() == Some(Mimetype::Data)); assert!(ft.analyze("tests_filemagic/commons-math.jar").ok() == Some(Mimetype::Data)); - assert!(ft.analyze("tests_filemagic/8stbu11h.htm").ok() == Some(Mimetype::Text(LineEnding::MIXED(0,1,8710)))); + assert!( + ft.analyze("tests_filemagic/8stbu11h.htm").ok() + == Some(Mimetype::Text(LineEnding::MIXED(0, 1, 8710))) + ); } diff --git a/support/pkgcheck/src/linkcheck.rs b/support/pkgcheck/src/linkcheck.rs index f73a05c02b..d7d1671dcf 100644 --- a/support/pkgcheck/src/linkcheck.rs +++ b/support/pkgcheck/src/linkcheck.rs @@ -6,12 +6,10 @@ use linkify::{LinkFinder, LinkKind}; use std::fs::File; use std::io::prelude::*; -//use reqwest::Client; -use openssl_probe; -use reqwest; + use reqwest::header; use std::time::Duration; -//use std::thread; + use std::sync::Arc; use std::sync::Mutex; diff --git a/support/pkgcheck/src/main.rs b/support/pkgcheck/src/main.rs index cbb678729f..d4ef7d6db2 100644 --- a/support/pkgcheck/src/main.rs +++ b/support/pkgcheck/src/main.rs @@ -11,10 +11,10 @@ mod linkcheck; mod utils; mod recode; -use recode::{wrong_line_endings2lf, wrong_line_endings2crlf}; +use recode::{wrong_line_endings2crlf, wrong_line_endings2lf}; mod filemagic; -use filemagic::{LineEnding}; +use filemagic::LineEnding; use linkcheck::LinkCheck; use std::fmt; @@ -27,7 +27,8 @@ use std::os::unix::fs::MetadataExt; use scoped_threadpool::Pool; -use tempdir::TempDir; +use tempfile::Builder; + #[macro_use] extern crate lazy_static; use colored::*; @@ -51,6 +52,8 @@ use std::sync::atomic::{AtomicBool, Ordering}; use blake2::{Blake2b, Digest}; use fnv::{FnvHashMap as HashMap, FnvHashSet as HashSet}; use std::sync::mpsc::{channel, Sender}; + +use structopt::clap::Shell; use structopt::StructOpt; #[cfg(unix)] use walkdir::{DirEntry, WalkDir}; @@ -77,15 +80,13 @@ fn hash_file_inner(path: &PathBuf) -> io::Result<Vec<u8>> { let mut buf = [0u8; BLOCKSIZE]; let mut fp = File::open(&path)?; let mut digest = Blake2b::default(); - // When we compare byte-by-byte, we don't need to hash the whole file. - // Instead, hash a block of 4kB, skipping 100kB. loop { match fp.read(&mut buf)? { 0 => break, - n => digest.input(&buf[..n]), + n => digest.update(&buf[..n]), } } - Ok(digest.result().to_vec()) + Ok(digest.finalize().to_vec()) } fn hash_file(fsize: u64, path: PathBuf, tx: &HashSender) { @@ -95,7 +96,6 @@ fn hash_file(fsize: u64, path: PathBuf, tx: &HashSender) { } } - // returns false if an error occured fn fix_inconsistent_le(fname: &str) -> bool { i0004!(fname); @@ -111,7 +111,6 @@ fn fix_inconsistent_le(fname: &str) -> bool { } } - // returns false if an error occured fn make_crlf(fname: &str) -> bool { i0004!(fname); @@ -209,6 +208,8 @@ struct Args { correct_perms: bool, #[structopt(long = "no-colors", help = "Don't display messages in color")] no_colors: bool, + // #[structopt(long = "install-completion", help = "Install completion for the current shell")] + // install_completion: Option<String>, #[structopt(long = "urlcheck", help = "Check URLs found in README files")] urlcheck: bool, #[structopt(short = "T", long = "tds-zip", help = "tds zip archive", group = "tds")] @@ -296,6 +297,18 @@ impl DupPath { } } +// fn install_completion_bash() { +// Args::clap().gen_completions(env!("CARGO_PKG_NAME"), Shell::Bash, "bla"); +// } + +// fn install_completion_zsh() { +// Args::clap().gen_completions(env!("CARGO_PKG_NAME"), Shell::Zsh, "/home/manfred/.zfunc"); +// } + +// fn install_completion_fish() { +// Args::clap().gen_completions(env!("CARGO_PKG_NAME"), Shell::Fish, "target"); +// } + type DupHashes = HashMap<(u64, Vec<u8>), DupPath>; fn main() { @@ -307,6 +320,24 @@ fn main() { } } + // + // !!!!!! this should be activated when structop uses + // !!!!!! the new clap 3.0 + // + // match &ARGS.install_completion { + // None => { } + // Some(d) => { + // println!("{}", &d); + // match d.as_str() { + // "bash" => install_completion_bash(), + // "zsh" => install_completion_zsh(), + // "fish" => install_completion_fish(), + // _ => println!("Invalid shell name {} given", d) + // } + // process::exit(0); + // } + // } + if ARGS.explain_all { explains_all(); process::exit(0); @@ -506,7 +537,9 @@ fn check_generated_files(entry: &str, generated: &mut GeneratedHashMap) { continue; } - generated.entry(filename.to_string()).or_insert_with(|| entry.to_string()); + generated + .entry(filename.to_string()) + .or_insert_with(|| entry.to_string()); } }; } @@ -544,7 +577,7 @@ fn check_tds_archive_name(tds_zip: &Option<String>) -> Option<String> { } fn unzip_tds_archive(tds_zip: &str, tmp_dir: &str) { - match run_cmd("unzip", &["-a", "-q", "-d", tmp_dir, &tds_zip]) { + match run_cmd("unzip", &["-q", "-d", tmp_dir, &tds_zip]) { CmdReturn { status: true, .. } => (), CmdReturn { status: false, @@ -593,13 +626,14 @@ fn check_tds_archive(pkg_name: &str, tds_zip: &str, hashes: &DupHashes) { pkg_replacements.insert("latex-tools-dev", "latex-dev"); pkg_replacements.insert("latex-graphics-dev", "latex-dev"); pkg_replacements.insert("latex-amsmath-dev", "latex-dev"); + pkg_replacements.insert("latex-firstaid", "latex/firstaid"); let real_pkg_name = if let Some(real_name) = pkg_replacements.get(pkg_name) { real_name } else { pkg_name }; - let tmp_dir = match TempDir::new("pkgcheck") { + let tmp_dir = match Builder::new().prefix("pkgcheck").tempdir() { Ok(tdir) => tdir, Err(e) => { f0007!(e); @@ -632,6 +666,45 @@ fn check_tds_archive(pkg_name: &str, tds_zip: &str, hashes: &DupHashes) { let mut map_files_found = false; let mut map_dvips_found = false; + // those top level directories are the directories found in the + // texmf-dist/ directory of a texlive installation + let tds_toplevel_dirs: HashSet<String> = [ + "asymptote", + "bibtex", + "chktex", + "context", + "doc", + "dvipdfmx", + "dvips", + "fonts", + "hbf2gf", + "makeindex", + "metafont", + "metapost", + "mft", + "omega", + "pbibtex", + "psutils", + "scripts", + "source", + "tex", + "tex4ht", + "texconfig", + "texdoc", + "texdoctk", + "ttf2pk", + "web2c", + "xdvi", + "xindy", + ] + .iter() + .map(|&s| s.to_string()) + .collect(); + + // set to True if the TDS zip archive contains a top level directory doc/ + let mut doc_found = false; + // we track the number of toplevel directories which must at least be 2 + let mut number_of_toplevel_dirs = 0; for dir_entry in WalkDir::new(tmp_dir.path().to_str().unwrap()).follow_links(false) { match dir_entry { Ok(dir_entry) => { @@ -669,29 +742,42 @@ fn check_tds_archive(pkg_name: &str, tds_zip: &str, hashes: &DupHashes) { &dir_entry_str[tmp_dir_offset..] }; + ut.check_for_temporary_file(&dir_entry_display); + + // In the top level directory of a TDS zip archive + // ... no files are allowed + // ... only specific directories are allowed + if dir_entry.depth() == 1 { + if ft == FType::Regular { + e0034!(dir_entry_display); + continue; + } + if !tds_toplevel_dirs.contains(&file_name) { + e0020!(&file_name); + } else { + number_of_toplevel_dirs += 1; + if &file_name == "doc" { + doc_found = true; + } + } + continue; + } + if ft == FType::Directory { ut.check_for_empty_directory(&dir_entry_str, &dir_entry_display); ut.check_for_hidden_directory(&file_name, &dir_entry_display); ut.is_unwanted_directory(&file_name, dir_entry_str); - continue; - } - // We don't want to have other than directories in the top level - // directory of a TDS zip archive - if dir_entry.depth() == 1 && ft == FType::Regular { - e0034!(dir_entry_display); continue; } - ut.check_for_temporary_file(&dir_entry_display); - // The LaTeX team provides the file `.tex` as a file with an empty name // in order to make `\input\relax` work (explained by David Carlisle) // Therefore, we don't call check_for_hidden_file() in this case match (pkg_name, dir_entry_display) { ("latex-tools", "tex/latex/tools/.tex") => (), ("latex-tools-dev", "tex/latex-dev/tools/.tex") => (), - (_, _) => ut.check_for_hidden_file(&file_name, &dir_entry_display) + (_, _) => ut.check_for_hidden_file(&file_name, &dir_entry_display), }; let fsize = meta.len(); @@ -731,8 +817,14 @@ fn check_tds_archive(pkg_name: &str, tds_zip: &str, hashes: &DupHashes) { } } + if !doc_found { + e0039!(); + } + if number_of_toplevel_dirs < 2 { + e0040!(); + } if map_files_found && !map_dvips_found { - println!( "Map files found for package {} but none of them is in a path starting with fonts/map/dvips", pkg_name); + e0041!(); } }; @@ -871,8 +963,6 @@ fn check_package(root: &str, tds_zip: &Option<String>) -> Option<DupHashes> { let ut = Utils::new(utils::CheckType::PACKAGE); - - i0002!(root); // This hash contains all package file names. // @@ -977,7 +1067,6 @@ fn check_package(root: &str, tds_zip: &Option<String>) -> Option<DupHashes> { // 2. dealing with directories if ft == FType::Directory { - let lc_dir_entry_str = dir_entry_str.to_lowercase(); if let Some(_dir_name) = filename(&dir_entry_str) { let lcnref = &mut lcnames; @@ -1090,7 +1179,6 @@ fn check_package(root: &str, tds_zip: &Option<String>) -> Option<DupHashes> { sizeref.entry(fsize).or_insert_with(Vec::new).push(path); }; for (path, (meta, _file_name, is_readme)) in file_names.iter() { - //println!("DEBUG: path {:?}, file_name {:?}, is_readme: {} ", &path, &file_name, is_readme); let dir_entry_str = match path.to_str() { Some(d) => d, None => { @@ -1137,70 +1225,61 @@ fn check_package(root: &str, tds_zip: &Option<String>) -> Option<DupHashes> { match fext { // deal with Windows files - Some("bat") | Some("cmd") | Some("nsh") | Some("reg") => { - match ft { - filemagic::Mimetype::Text(LineEnding::CRLF) => (), - filemagic::Mimetype::Text(LineEnding::CR) => - { - e0037!(&dir_entry_str); - if ARGS.correct_le { - make_crlf(&dir_entry_str); - } - }, - filemagic::Mimetype::Text(LineEnding::MIXED(0, 0, 0) ) => (), - filemagic::Mimetype::Text(LineEnding::MIXED(cr, lf, crlf) ) => - { - e0038!(&dir_entry_str, cr, lf, crlf); - if ARGS.correct_le { - fix_inconsistent_le(&dir_entry_str); - } - }, - filemagic::Mimetype::Text(LineEnding::LF) => - { - w0008!(&dir_entry_str); - }, - fmm => println!("Should not occur: {} has {:?}", dir_entry_str, fmm), + Some("bat") | Some("cmd") | Some("nsh") | Some("reg") => match ft { + filemagic::Mimetype::Text(LineEnding::CRLF) => (), + filemagic::Mimetype::Text(LineEnding::CR) => { + e0037!(&dir_entry_str); + if ARGS.correct_le { + make_crlf(&dir_entry_str); + } + } + filemagic::Mimetype::Text(LineEnding::MIXED(0, 0, 0)) => (), + filemagic::Mimetype::Text(LineEnding::MIXED(cr, lf, crlf)) => { + e0038!(&dir_entry_str, cr, lf, crlf); + if ARGS.correct_le { + fix_inconsistent_le(&dir_entry_str); + } } + filemagic::Mimetype::Text(LineEnding::LF) => { + w0008!(&dir_entry_str); + } + fmm => println!("Should not occur: {} has {:?}", dir_entry_str, fmm), }, Some(_) | None => { match ft { - filemagic::Mimetype::Text(LineEnding::CRLF) => - { + filemagic::Mimetype::Text(LineEnding::CRLF) => { e0012!(&dir_entry_str); if ARGS.correct_le { fix_inconsistent_le(&dir_entry_str); } - }, - filemagic::Mimetype::Text(LineEnding::CR) => - { + } + filemagic::Mimetype::Text(LineEnding::CR) => { e0037!(&dir_entry_str); if ARGS.correct_le { fix_inconsistent_le(&dir_entry_str); } - }, - filemagic::Mimetype::Text(LineEnding::MIXED(0, 0, 0) ) => (), - filemagic::Mimetype::Text(LineEnding::MIXED(cr, lf, crlf) ) => - { + } + filemagic::Mimetype::Text(LineEnding::MIXED(0, 0, 0)) => (), + filemagic::Mimetype::Text(LineEnding::MIXED(cr, lf, crlf)) => { //println!(">>>{}: {:?} {},{},{}", &dir_entry_str, ft, x, y, z); e0038!(&dir_entry_str, cr, lf, crlf); if ARGS.correct_le { fix_inconsistent_le(&dir_entry_str); } - }, + } filemagic::Mimetype::Text(LineEnding::LF) => (), fmm => println!("Should not occur: {} has {:?}", dir_entry_str, fmm), } - }, + } } - }, + } filemagic::Mimetype::BOM(b) => { //println!("{}: {} with BOM detected", dir_entry_str, b.as_ref()); w0004!(&dir_entry_str, b.as_ref()); check_and_correct_perms(&dir_entry_str, p); } - filemagic::Mimetype::Binary - | filemagic::Mimetype::Script(_) => { + filemagic::Mimetype::Binary | filemagic::Mimetype::Script(_) => { if !owner_has(p, 4) || !others_have(p, 4) { e0002!(&dir_entry_str, perms_to_string(p)); }; @@ -1353,5 +1432,3 @@ fn show_tmp_endings() { println!("{:23} {}", t, c); } } - - diff --git a/support/pkgcheck/src/messages/errorsd.rs b/support/pkgcheck/src/messages/errorsd.rs index b80e4d1245..c034301ad9 100644 --- a/support/pkgcheck/src/messages/errorsd.rs +++ b/support/pkgcheck/src/messages/errorsd.rs @@ -3,8 +3,7 @@ pub fn e0001d() { println!( - r#" -E0001 -- Bad characters in file name + r#"E0001 -- Bad characters in file name File name should not contain non-ascii characters. Additionally, file names should not contain control characters or other characters which @@ -18,8 +17,7 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#nounixspecialcharacte pub fn e0002d() { println!( - r#" -E0002 -- File Permissions + r#"E0002 -- File Permissions Files submitted to CTAN should be world readable. @@ -34,8 +32,7 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#filepermissions pub fn e0003d() { println!( - r#" -E0003 -- README is not a text file + r#"E0003 -- README is not a text file The README file specified in the error message must be a text file but it isn't. @@ -45,8 +42,7 @@ it isn't. pub fn e0004d() { println!( - r#" -E0004 -- Empty directory not allowed + r#"E0004 -- Empty directory not allowed Empty directories are considered as rubbish, and are usually not accepted as part of a package, neither in the package tree nor in the @@ -60,8 +56,7 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#noemptyfiles pub fn e0005d() { println!( - r#" -E0005 -- Empty files not allowed + r#"E0005 -- Empty files not allowed Empty files are considered as rubbish, and are usually not accepted as part of a package. @@ -74,8 +69,7 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#noemptyfiles pub fn e0006d() { println!( - r#" -E0006 -- Hidden directories not allowed + r#"E0006 -- Hidden directories not allowed A package should not contain hidden directories, neither in the package tree nor in the TDS zip archive. @@ -88,8 +82,7 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#noauxfiles pub fn e0007d() { println!( - r#" -E0007 -- Hidden files not allowed + r#"E0007 -- Hidden files not allowed A package should not contain hidden files, neither in the package tree nor in the TDS zip archive. @@ -102,8 +95,7 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#noauxfiles pub fn e0008d() { println!( - r#" -E0008 -- Temporary file detected + r#"E0008 -- Temporary file detected A temporary file was detected. These are typically files created by TeX & friends and should not be part of a package. @@ -118,8 +110,7 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#noauxfiles pub fn e0009d() { println!( - r#" -E0009 -- Package doesn't contain a README file + r#"E0009 -- Package doesn't contain a README file A package must contain at least one of README, README.md or README.txt file. @@ -132,8 +123,7 @@ http://mirrors.ibiblio.org/CTAN/help/ctan/CTAN-upload-addendum.html#readme pub fn e0010d() { println!( - r#" -E0010 -- Broken symlink detected + r#"E0010 -- Broken symlink detected A broken symlink was detected. "# @@ -142,8 +132,7 @@ A broken symlink was detected. pub fn e0011d() { println!( - r#" -E0011 -- Wrong permission for directory + r#"E0011 -- Wrong permission for directory Directories should have rwx for the owner and at least r-x for others (i.e. world readable). @@ -156,8 +145,7 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#filepermissions pub fn e0012d() { println!( - r#" -E0012 -- CRLF line endings detected + r#"E0012 -- CRLF line endings detected The file specified in the error message contains CRLF line endings. Text files should have UNIX style line endings. @@ -170,8 +158,7 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#crlf pub fn e0013d() { println!( - r#" -E0013 -- Socket special fie detected + r#"E0013 -- Socket special fie detected The file specified in the error message is a socket special file which is not allowed. @@ -181,8 +168,7 @@ is not allowed. pub fn e0014d() { println!( - r#" -E0014 -- Fifo special file detected + r#"E0014 -- Fifo special file detected The file specified in the error message is a fifo special file which is not allowed. @@ -192,8 +178,7 @@ not allowed. pub fn e0015d() { println!( - r#" -E0015 -- Bloch device file detected + r#"E0015 -- Bloch device file detected The file specified in the error message is a block device file which is not allowed. @@ -203,8 +188,7 @@ not allowed. pub fn e0016d() { println!( - r#" -E0016 -- Character device file detected + r#"E0016 -- Character device file detected The file specified in the error message is a character device file which is not allowed. @@ -214,8 +198,7 @@ is not allowed. pub fn e0017d() { println!( - r#" -E0017 -- PDF document is in error + r#"E0017 -- PDF document is in error The PDF document mentioned in the message is in error. @@ -237,8 +220,7 @@ Example: pub fn e0018d() { println!( - r#" -E0018 -- Unwanted directory detected + r#"E0018 -- Unwanted directory detected A directory was detected which should not be part of a package. Example: __MACOSX @@ -248,8 +230,7 @@ __MACOSX pub fn e0019d() { println!( - r#" -E0019 -- Generated file detected + r#"E0019 -- Generated file detected In order to avoid redundancy we don't want to have included files in a package which easily can be generated from other files in the @@ -266,10 +247,24 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#nogeneratedfiles ) } +pub fn e0020d() { + println!( + r#"E0020 -- Unwanted directory detected in the top level directory in TDS zip archive + +The name of a top level directory of a TDS archive must be one of those +listed here: asymptote, bibtex, chktex, context, doc, dvipdfmx, dvips, +fonts, hbf2gf, makeindex, metafont, metapost, mft, omega, pbibtex, +psutils, scripts, source, tex, tex4ht, texconfig, texdoc, texdoctk, +ttf2pk, web2c, xdvi, xindy, + +Any other other directory at the top level is an error. +"# + ) +} + pub fn e0021d() { println!( - r#" -E0021 -- Error when reading a file + r#"E0021 -- Error when reading a file An error was encountered when reading the file specified in the message. "# @@ -278,8 +273,7 @@ An error was encountered when reading the file specified in the message. pub fn e0022d() { println!( - r#" -E0022 -- Check of an URL in a README file failed + r#"E0022 -- Check of an URL in a README file failed URL checking is in effect. An error occcured when trying to retrieve an URL which was found in the specified README file. @@ -289,8 +283,7 @@ URL which was found in the specified README file. pub fn e0023d() { println!( - r#" -E0023 -- Follow up error when trying to read a directory with insufficient permissions + r#"E0023 -- Follow up error when trying to read a directory with insufficient permissions Error which is a follow-up error. For instance, when a directory could not be read. @@ -300,8 +293,7 @@ not be read. pub fn e0024d() { println!( - r#" -E0024 -- TDS zip archive has wrong permissions + r#"E0024 -- TDS zip archive has wrong permissions The TDS zip archive should have at least r-- for the owner and at least r-- for others (i.e. world readable). @@ -314,8 +306,7 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#filepermissions pub fn e0025d() { println!( - r#" -E0025 -- Duplicate names when ignoring letter case for files or directories + r#"E0025 -- Duplicate names when ignoring letter case for files or directories As there are operating systems which do not distinguish between myfile and MYFILE we don't want to have file names in a directory which are the @@ -329,8 +320,7 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#filenames pub fn e0026d() { println!( - r#" -E0026 -- Files not in TDS or different in TDS and non-install tree + r#"E0026 -- Files not in TDS or different in TDS and non-install tree The file mentioned in the error message is either not existing in the TDS zip archive, or it is different to the one in the non-install tree @@ -340,8 +330,7 @@ TDS zip archive, or it is different to the one in the non-install tree pub fn e0027d() { println!( - r#" -E0027 -- An I/O error occured + r#"E0027 -- An I/O error occured Some kind of I/O error occured. If you believe there is an error in pkgcheck please contact the author. @@ -351,12 +340,11 @@ pkgcheck please contact the author. pub fn e0028d() { println!( - r#" -E0028 -- A path name in a TDS zip archive must contain the package name + r#"E0028 -- A path name in a TDS zip archive must contain the package name The path names in a TDS zip archive must contain the package name. -EXAMPLE: Assume a package somepkg. Then path names should look like +Example: Assume a package somepkg. Then path names should look like follows: tex/latex/somepkg/somepkg.cls @@ -369,8 +357,7 @@ follows: pub fn e0029d() { println!( - r#" -E0029 -- README file: encoding with BOM detected + r#"E0029 -- README file: encoding with BOM detected A README file should be either ASCII or UTF-8 without BOM(byte order mark) @@ -383,8 +370,7 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#readme pub fn e0030d() { println!( - r#" -E0030 -- A symlink was found which points outside of the package directory tree + r#"E0030 -- A symlink was found which points outside of the package directory tree A symlink must not point to a file or directory outside of the package directory tree. @@ -394,8 +380,7 @@ directory tree. pub fn e0031d() { println!( - r#" -E0031 -- File name contains invalid UTF-8 character(s) + r#"E0031 -- File name contains invalid UTF-8 character(s) A file name contains invald UTF-8 character(s). "# @@ -404,8 +389,7 @@ A file name contains invald UTF-8 character(s). pub fn e0033d() { println!( - r#" -E0033 -- Error when unpacking tds archive + r#"E0033 -- Error when unpacking tds archive In order to investigate the contents of the TDS zip archive pkgcheck unpacks the TDS zip archive to a temporary location which failed for the @@ -416,8 +400,7 @@ reason given in the error message. pub fn e0034d() { println!( - r#" -E0034 -- Unwanted file detected in the top level directory in TDS zip archive + r#"E0034 -- Unwanted file detected in the top level directory in TDS zip archive A top level directory of a TDS archive should only contain certain directories but no files. @@ -427,8 +410,7 @@ directories but no files. pub fn e0035d() { println!( - r#" -E0035 -- Unwanted TDS archive detected in package directory tree + r#"E0035 -- Unwanted TDS archive detected in package directory tree A package directory should not contain a TDS zip archive. "# @@ -437,8 +419,7 @@ A package directory should not contain a TDS zip archive. pub fn e0036d() { println!( - r#" -E0036 -- .dtx/.ins files found in wrong directory in TDS zip archive + r#"E0036 -- .dtx/.ins files found in wrong directory in TDS zip archive In a TDS zip archive a .dtx resp. .ins file must be in a subdirectory of either of source/ or doc/ top level directories. @@ -448,8 +429,7 @@ either of source/ or doc/ top level directories. pub fn e0037d() { println!( - r#" -E0037 -- CR line endings detected + r#"E0037 -- CR line endings detected The file specified in the error message contains CR line endings. Text files should have UNIX style line endings. @@ -462,8 +442,7 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#crlf pub fn e0038d() { println!( - r#" -E0038 -- File has inconsistent line endings: CR: x, LF: y, CRLF: z + r#"E0038 -- File has inconsistent line endings: CR: x, LF: y, CRLF: z The file specified in the error message contains CR line endings. Text files should have UNIX style line endings. @@ -474,3 +453,37 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#crlf ) } +pub fn e0039d() { + println!( + r#"E0039 -- No doc/ directory found in the top level directory of the TDS zip archive + +A TDS zip archive is required to contain a top level directory doc/. +"# + ) +} + +pub fn e0040d() { + println!( + r#"E0040 -- Too few top level directories in the TDS zip archive + +The top level directory of a TDS zip archive must contain at least a doc +directory and one or more of the following directories: asymptote, +bibtex, chktex, context, dvipdfmx, dvips, fonts, hbf2gf, makeindex, +metafont, metapost, mft, omega, pbibtex, psutils, scripts, source, tex, +tex4ht, texconfig, texdoc, texdoctk, ttf2pk, web2c, xdvi, xindy, + +Any other other directory at the top level is an error. +"# + ) +} + +pub fn e0041d() { + println!( + r#"E0041 -- One or more map file found for the package but none of them is in a path starting with fonts/map/dvips + +At least one map file was found which was not in a path starting with +fonts/map/dvips. +"# + ) +} + diff --git a/support/pkgcheck/src/messages/informationd.rs b/support/pkgcheck/src/messages/informationd.rs index 340ade4766..1f1b64dcad 100644 --- a/support/pkgcheck/src/messages/informationd.rs +++ b/support/pkgcheck/src/messages/informationd.rs @@ -87,4 +87,3 @@ Wrong line endings could be CR, CRLF or a mixture of line endings. "# ) } - diff --git a/support/pkgcheck/src/messages/mod.rs b/support/pkgcheck/src/messages/mod.rs index 842c693718..65dcbc502a 100644 --- a/support/pkgcheck/src/messages/mod.rs +++ b/support/pkgcheck/src/messages/mod.rs @@ -260,7 +260,11 @@ macro_rules! e0011 { macro_rules! e0012 { ($fmt:expr) => { error_occured!(); - print!("{} File {} has CRLF line endings\n", msgid!("E0012"), $fmt); + print!( + "{} File {} has CRLF line endings\n", + msgid!("E0012"), + $fmt + ); }; } @@ -326,6 +330,17 @@ macro_rules! e0019 { }; } +macro_rules! e0020 { + ($fmt:expr) => { + error_occured!(); + print!( + "{} Unwanted directory `{}` detected in the top level directory of a TDS archive\n", + msgid!("E0020"), + $fmt + ); + }; +} + macro_rules! e0021 { ($fmt1:expr, $fmt2:expr, $fmt3:expr) => { error_occured!(); @@ -501,9 +516,39 @@ macro_rules! e0037 { macro_rules! e0038 { ($fmt1:expr, $fmt2:expr, $fmt3:expr, $fmt4:expr) => { error_occured!(); - print!("{} File {} has inconsistent line endings: CR={}, LF={}, CRLF={}\n", msgid!("E0038"), $fmt1, $fmt2, $fmt3, $fmt4); + print!( + "{} File {} has inconsistent line endings: CR={}, LF={}, CRLF={}\n", + msgid!("E0038"), + $fmt1, + $fmt2, + $fmt3, + $fmt4 + ); + }; +} + +macro_rules! e0039 { + () => { + error_occured!(); + print!("{} No doc/ directory found\n", msgid!("E0039")); }; } + +macro_rules! e0040 { + () => { + error_occured!(); + print!("{} Too few top level directories in the TDS zip archive\n", msgid!("E0040")); + }; +} + +macro_rules! e0041 { + () => { + error_occured!(); + print!("{} One or more map file found for the package but none of them is in a path starting with fonts/map/dvips\n", msgid!("E0041")); + }; +} + + macro_rules! w0001 { ($fmt:expr) => { print!( @@ -570,14 +615,22 @@ macro_rules! w0006 { macro_rules! w0007 { ($fmt:expr) => { error_occured!(); - print!("{} Empty directory {} detected in TDS zip archive\n", msgid!("W0007"), $fmt); + print!( + "{} Empty directory {} detected in TDS zip archive\n", + msgid!("W0007"), + $fmt + ); }; } macro_rules! w0008 { ($fmt:expr) => { error_occured!(); - print!("{} Windows file {} has Unix line endings\n", msgid!("W0008"), $fmt); + print!( + "{} Windows file {} has Unix line endings\n", + msgid!("W0008"), + $fmt + ); }; } @@ -643,7 +696,6 @@ macro_rules! i0007 { }; } - pub fn explains(err: &str) { let err_upp = err.to_ascii_uppercase(); match err_upp.as_str() { @@ -674,6 +726,7 @@ pub fn explains(err: &str) { "E0017" => e0017d(), "E0018" => e0018d(), "E0019" => e0019d(), + "E0020" => e0020d(), "E0021" => e0021d(), "E0022" => e0022d(), "E0023" => e0023d(), @@ -691,6 +744,9 @@ pub fn explains(err: &str) { "E0036" => e0036d(), "E0037" => e0037d(), "E0038" => e0038d(), + "E0039" => e0039d(), + "E0040" => e0040d(), + "E0041" => e0041d(), // "I0001" => i0001d!(), "I0001" => i0001d(), @@ -744,6 +800,7 @@ pub fn explains_all() { explains("E0017"); explains("E0018"); explains("E0019"); + explains("E0020"); explains("E0021"); explains("E0022"); explains("E0023"); @@ -759,6 +816,11 @@ pub fn explains_all() { explains("E0034"); explains("E0035"); explains("E0036"); + explains("E0037"); + explains("E0038"); + explains("E0039"); + explains("E0040"); + explains("E0041"); explains("I0001"); explains("I0002"); diff --git a/support/pkgcheck/src/messages/warningsd.rs b/support/pkgcheck/src/messages/warningsd.rs index cea814c8ce..7358cc562e 100644 --- a/support/pkgcheck/src/messages/warningsd.rs +++ b/support/pkgcheck/src/messages/warningsd.rs @@ -105,4 +105,3 @@ We regard a file as a Windows file if its name ends with: "# ) } - diff --git a/support/pkgcheck/src/utils.rs b/support/pkgcheck/src/utils.rs index d047a97cb0..2dedc94ecd 100644 --- a/support/pkgcheck/src/utils.rs +++ b/support/pkgcheck/src/utils.rs @@ -114,7 +114,6 @@ impl Utils { // fname is the base name without the directory part pub fn check_for_hidden_directory(&self, fname: &str, dir_entry_str: &str) { - // We have to single out '.' and './' as they denote just the current directory // That case may happen if pkgcheck gets called like: `pkgcheck -d .` or `pkgcheck -d ./` if fname == "." || fname == "./" { |