diff options
author | Norbert Preining <norbert@preining.info> | 2022-05-27 03:01:31 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2022-05-27 03:01:31 +0000 |
commit | 84a5593d3fb9d03aac5677678bcc4c92e8c9a9c4 (patch) | |
tree | 0212ba38147bcfe80e5c1a853071a6e6a45b87d7 /support/pkgcheck | |
parent | 02d941fa9c9895bb08a84ac9afe3559abd1ba8ad (diff) |
CTAN sync 202205270301
Diffstat (limited to 'support/pkgcheck')
22 files changed, 1239 insertions, 842 deletions
diff --git a/support/pkgcheck/CHANGES.md b/support/pkgcheck/CHANGES.md index fc9e145fd2..ade233c38d 100644 --- a/support/pkgcheck/CHANGES.md +++ b/support/pkgcheck/CHANGES.md @@ -1,100 +1,97 @@ -# General remarks +# Changelog -- the x.y.z is the version of the Rust source code which follows semantic versioning +- the x.y.z is the version of the source code which follows semantic versioning - the combination of version and version date designates the version of the package as it is uploaded to CTAN # Changes -2018-12-09 (1.0.0) - - 1.0.0 First stable version - -2018-12-16 (1.0.0) - - quick_intro.txt: improve wording - - build_ctan_zip.p6: add source files to be included into CTAN zip archive - - 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 - subdirectory in the package tree. This changes the format of the - 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 - -2019-01-02 (1.2.0) - - some code simplification - - **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 - -2019-03-09 (1.3.0) - - 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 - 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, - 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 - 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 - e0030 will be issued - -2019-03-29 (1.6.0) - - new error message e0031 when a filename contains invalid UTF-8 characters - -2019-06-30 (1.7.0) - - when symlinks occur in e0025 they are reported as files - - improved error message e0025 now displaying the paths of the affected - files/directories/symlinks - - if a found http(s) link ends with "`" then the trailing "`" will be discarded - - compiled with rust edition 2018 - -2019-07-20 (1.8.0) - - add a check to detect temporary files in the TDS zip archive - -2019-07-21 (1.8.1) - - correct typo in e0008 message text - -2019-08-07 (1.8.2) - - updating crates, requiring slight code changes in integration.rs - - ignore windows files .nsh and .reg when checking for LF line endings - - new error message e0034 for unwanted files in top level directory of a TDS zip archive - - e0020 now reporting only unwanted directory in top level directory of a TDS zip archive +## 2022-05-26 (3.0.0) +### Added + - fatal messages Fnnnn go to stderr instead of stdout + - add generation of shell completion support for various shells, + which are bash, elvish, fish, powershell, zsh + - now a config file can be specified + - currently only exceptions can be specified when checking + the paths of files in the TDS archive + - new messages F0008, F0009 and F0010 regarding reading config file + - new message I0008 to tell which config file is used + - new messages I0009, W0009 giving more information about config file + usage (only if --verbose is given) + - enhance documentation +### Changed + - (devel) reformatting source code + - (devel) using clap with derive feature instead of structopt-derive + - reorganized this changelog + - in w0002 output remove empty line at end + - don't complain if filename contains `@` , `=`, or `:` characters. These + characters are not recommended to be used but there could be a necessity. + +## 2022-01-15 (2.4.0) +### Changed + - for latex-lab and latex-lab-dev use the real directory name 'latex' resp. + 'latex-dev' when checking path names in the TDS zip archive -2019-10-01 (1.8.3) - - (Experimental) issue warning if a file in the package tree (W0005) or in the TDS zip archive (W0006) is - larger than 40MiB - - (Experimental) for babel-base.tds.zip use the real package name 'babel' (instead of 'babel-base') in order - to check if the path name contains the package name +## 2022-01-02 +### Added + - add .xray to temporary file endings + - (experimental) when URL checking decode some html entities if they appear in URLs +### Changed + - switch to Rust edition 2021 + - switch from blake2 to blake3 library for checksumming + - unzipping now done internally. /usr/bin/unzip no longer required - Both features are regarded as experimental because both contain a hard coded check. If required - things will be changed in the future. +## 2021-10-03 (2.3.0) +### Added + - add temporary file endings .hd and tpt (pointed to by Karl Berry) + - add option `--ignore-same-named` to ignore same named files + - add `.lua` to file endings recognized as scripts + - add latex-firstaid-dev to exceptions when checking paths in the TDS archive +### Changed + - if a URL ends with '。', which is an ideographic full stop (U+3002), remove that character + - ignore if generated files with ending .html or .css exist (merge request from Vít Novotný). + Reason is that documentation could also exist as html. + - some code simplifications most of them by clippy recommendations -2019-11-04 (1.9.0) - - (Experimental) for latex-base, latex-tools, latex-graphics and latex-amsmath use the real - directory name 'latex' when checking path names in the TDS zip archive - - New error message e0035 if a TDS zip archive is found in the unpacked directory tree - - add testcases for w0005, w0006 and e0035 +## 2020-11-20 (2.2.0) +### Added + - (Experimental) instead of latex-firstaid use latex/firstaid when checking path names + in 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 +### Changed + - small code changes due to new release of blake2 library + - replace deprecated tempdir crate by tempfile crate + - revive e0020 which checks for unwanted directories in the top level directory of a TDS zip + archive. +### Fixed + - unpack TDS zip without -a flag which was introduced in 2.0.1. According to Petra this creates + more problems than it solves -2019-11-27 (1.9.1) - - recognize .bat files as script type - - add test case for .bat file recognition +## 2020-04-12 (2.1.0) +### Added + - add new test case e0033 +### Changed + - improvements regarding detection of generated files (error message e0019) + - 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 +### Fixed + - don't issue error messages when a .bat file has 0755 permission + - 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) -2019-11-28 (1.10.0) - - remove message E0020 to report unwanted top level directory in a TDS zip archive - - more checks for a TDS zip archive - - check for temporary files or directories +## 2020-02-07 (2.0.1) +### Changed + - use the `-a` (convert text files) flag when temporarily unzipping the TDS archive + - crates update -2020-01-17 (2.0.0) +## 2020-01-17 (2.0.0) +### Added - more error checking in TDS zip archives - detecting if a .dtx or .ins file is not in a subdirectory of source/ or doc/ toplevel directories (E0036) - detecting empty directories (W0007) @@ -102,6 +99,7 @@ - detecting temporary files (E0008) - as a special case tex/latex/tools/.tex is allowed for package latex-tools. The same applies for latex-tools-dev package +### Changed - revamped handling of line ending checks - reporting if a file has CR line endings only (E0037) - reporting if a file has inconsistent line endings (E0038) @@ -123,50 +121,118 @@ - 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 - - crates update +## 2019-11-28 (1.10.0) +### Added + - more checks for a TDS zip archive + - check for temporary files or directories +### Changed + - remove message E0020 to report unwanted top level directory in a TDS zip archive -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 - 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) -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 -2021-10-03 (2.3.0) - - if a URL ends with '。', which is an ideographic full stop (U+3002), remove that character - - add temporary file endings .hd and tpt (pointed to by Karl Berry) - - add option `--ignore-same-named` to ignore same named files - - add `.lua` to file endings recognized as scripts - - add latex-firstaid-dev to exceptions when checking paths in the TDS archive - - ignore if generated files with ending .html or .css exist (merge request from Vít Novotný). - Reason is that documentation could also exist as html. - - some code simplifications most of them by clippy recommendations -2022-01-02 - - switch to Rust edition 2021 - - switch from blake2 to blake3 library for checksumming - - add .xray to temporary file endings - - (experimental) when URL checking decode some html entities if they appear in URLs - - unzipping now done internally. /usr/bin/unzip no longer required -2022-01-15 (2.4.0) - - for latex-lab and latex-lab-dev use the real directory name 'latex' resp. - 'latex-dev' when checking path names in the TDS zip archive +## 2019-11-27 (1.9.1) +### Added + - recognize .bat files as script type + - add test case for .bat file recognition + +### 2019-11-04 (1.9.0) +### Added + - (Experimental) for latex-base, latex-tools, latex-graphics and latex-amsmath use the real + directory name 'latex' when checking path names in the TDS zip archive + - New error message e0035 if a TDS zip archive is found in the unpacked directory tree + - add testcases for w0005, w0006 and e0035 + +## 2019-10-01 (1.8.3) +### Added + - (Experimental) issue warning if a file in the package tree (W0005) or in the TDS zip archive (W0006) is + larger than 40MiB + - (Experimental) for babel-base.tds.zip use the real package name 'babel' (instead of 'babel-base') in order + to check if the path name contains the package name + + Both features are regarded as experimental because both contain a hard coded check. If required + things will be changed in the future. + +## 2019-08-07 (1.8.2) +### Changed + - updating crates, requiring slight code changes in integration.rs + - ignore windows files .nsh and .reg when checking for LF line endings + +### Added + - new error message e0034 for unwanted files in top level directory of a TDS zip archive + - e0020 now reporting only unwanted directory in top level directory of a TDS zip archive + +## 2019-07-21 (1.8.1) +### Fixed + - correct typo in e0008 message text + +## 2019-07-20 (1.8.0) +### Added + - add a check to detect temporary files in the TDS zip archive + +## 2019-06-30 (1.7.0) +### Changed + - compiled with rust edition 2018 + - if a found http(s) link ends with "`" then the trailing "`" will be discarded + +### Fixed + - improved error message e0025 now displaying the paths of the affected + files/directories/symlinks + - when symlinks occur in e0025 they are reported as files + +## 2019-03-29 (1.6.0) +### Changed + - new error message e0031 when a filename contains invalid UTF-8 characters + +## 2019-03-14 (1.5.0) +### Changed + - if a symlink points to a file object outside of the package directory tree error message + e0030 will be issued + +### Fixed + - a README can be a symlink which will now be detected properly + +## 2019-03-11 (1.4.0) +### Added + - recognizing generated files in a .dtx file when they are included using a + filecontents resp. filecontents* environment. + +## 2019-03-09 (1.3.0) +### Changed + - 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 + 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, + if other files contain BOMs we issue a warning message + - recompile with newest http library + +## 2019-01-02 (1.2.0) +### Added + - add test cases for messages e0026, e0028 + - **New feature**: checks that path names in the TDS zip archive contain the package name + (only exception is a man page path) + +### Changed + - some code simplification + +## 2018-12-26 (1.1.0) +### Added + - 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 + displayed in the e0019 message + - add a short info to the PDF documention about how to install pkgcheck + +### Changed + - change ordering of the sections in the pkgcheck.pdf document. First come the + informational messages, then warnings and error messages and finally fatal messages. + +## 2018-12-16 (1.0.0) +### Added + - quick_intro.txt: improve wording + - build_ctan_zip.p6: add source files to be included into CTAN zip archive + - devnotes.md: add documentation how to build your own binary + +## 2018-12-09 (1.0.0) + + - 1.0.0 First stable release diff --git a/support/pkgcheck/Cargo.toml b/support/pkgcheck/Cargo.toml index 29048feda9..f7120709d4 100644 --- a/support/pkgcheck/Cargo.toml +++ b/support/pkgcheck/Cargo.toml @@ -1,12 +1,15 @@ [package] name = "pkgcheck" -version = "2.4.0" +version = "3.0.0" authors = ["Manfred Lotz <manfred@ctan.org>"] description = "Command-line tool to check packages uploaded to CTAN." license = "MIT/Apache-2.0" readme = "README.md" edition = "2021" +[[bin]] +name = "pkgcheck" + # with this option binaries are smaller # https://doc.rust-lang.org/edition-guide/rust-2018/error-handling-and-panics/aborting-on-panic.html [profile.release] @@ -14,37 +17,41 @@ panic = "abort" lto = true [dependencies] -structopt = "0.3" -walkdir = "2.3" -scoped_threadpool = "0.1" -num_cpus = "1" -blake3 = "1.2.0" -rustc-hash = "1.1" -unbytify = "0.2" -regex = "1" -glob = "0.3" +blake3 = "1.3" +clap = { version = "3.1.6", features = ["derive"] } +clap_complete = "3.1.1" colored = "2" +config = "0.13" +escargot = "0.5" +fern = "0.6" +glob = "0.3" +home = "0.5.3" +once_cell = "1.10.0" +#lazy_static = "1" linkify = "0.8" - -reqwest = { version = "0.11", features = ["blocking", "gzip"] } -tokio = { version = "1", features = ["full"] } - -lazy_static = "1" -tempfile = "3.1" -assert_cmd = "2" -predicates = "2" +log = "0.4" +num_cpus = "1" openssl-probe = "0.1.4" pest = "2.1" pest_derive = "2.1" -escargot = "0.5" - +regex = "1" +reqwest = { version = "0.11", features = ["blocking", "gzip"] } +rustc-hash = "1.1" +scoped_threadpool = "0.1" +serde = { version = "1.0", features = ["derive"] } +serde_yaml = "0.8" +tempfile = "3.1" threadpool = "1.8" +tokio = { version = "1", features = ["full"] } +unbytify = "0.2" unicode-bom = "1" - url = "2.1" +walkdir = "2.3" +zip = { version = "^0.6", default-features = false, features = ["deflate"] } -zip = { version = "0.5", default-features = false } -zip-extensions = "0.6" +[dev-dependencies] +assert_cmd = "2" +predicates = "2" [package.metadata.deb] section = "utility" diff --git a/support/pkgcheck/LICENSE-MIT b/support/pkgcheck/LICENSE-MIT index b1694f86ae..c16200e5c0 100644 --- a/support/pkgcheck/LICENSE-MIT +++ b/support/pkgcheck/LICENSE-MIT @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2018-2020 Manfred Lotz +Copyright (c) 2018-2022 Manfred Lotz Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/support/pkgcheck/README.md b/support/pkgcheck/README.md index 96d6b16716..d014061799 100644 --- a/support/pkgcheck/README.md +++ b/support/pkgcheck/README.md @@ -21,10 +21,8 @@ There is no Windows version planned. The `pkgcheck` binary is a 64-bit statically linked binary, and thus it should run also on older Linux versions. -It uses the following external programs: +It uses `pdfinfo` for checking pdf documents. -- `pdfinfo` for checking pdf documents -- `unzip` for temporarily unpacking a TDS zip archive # Installing the binary @@ -32,6 +30,7 @@ Copy the binary from `bin/pkgcheck` to a suitable location on your hard disk, an (recommended) make sure the directory is in the `PATH` or call `pkgcheck` using an absolute path name. + # Documentation The documentation is `docs/pkgcheck.pdf`. It contains @@ -48,18 +47,16 @@ cd docs lualatex -shell-escape pkgcheck.tex ``` - - # License Licensed under either of - Apache License, Version 2.0 - + - See file LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0 - MIT license - + - See file LICENSE-MIT or http://opensource.org/licenses/MIT at your option. diff --git a/support/pkgcheck/bin/pkgcheck b/support/pkgcheck/bin/pkgcheck Binary files differindex 5f7df9aaa2..04da19b362 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 e9b689610f..7fb3509791 100644 --- a/support/pkgcheck/docs/errorsd.tex +++ b/support/pkgcheck/docs/errorsd.tex @@ -218,7 +218,7 @@ An error was encountered when reading the file specified in the message. \subsection{E0022 -\/- Check of an URL in a README file failed}\label{e0022----check-of-an-url-in-a-readme-file-failed}} -URL checking is in effect. An error occcured when trying to retrieve an +URL checking is in effect. An error occcurred when trying to retrieve an URL which was found in the specified \texttt{README} file. \hypertarget{e0023----follow-up-error-when-trying-to-read-a-directory-with-insufficient-permissions}{% @@ -259,11 +259,11 @@ tree}\label{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 -\hypertarget{e0027----an-io-error-occured}{% +\hypertarget{e0027----an-io-error-occurred}{% \subsection{E0027 -\/- An I/O error -occured}\label{e0027----an-io-error-occured}} +occurred}\label{e0027----an-io-error-occurred}} -Some kind of I/O error occured. If you believe there is an error in +Some kind of I/O error occurred. If you believe there is an error in \texttt{pkgcheck} please contact the author. \hypertarget{e0028----a-path-name-in-a-tds-zip-archive-must-contain-the-package-name}{% @@ -305,7 +305,7 @@ directory tree. \subsection{E0031 -\/- File name contains invalid UTF-8 character(s)}\label{e0031----file-name-contains-invalid-utf-8-characters}} -A file name contains invald UTF-8 character(s). +A file name contains invalid UTF-8 character(s). \hypertarget{e0033----error-when-unpacking-tds-archive}{% \subsection{E0033 -\/- Error when unpacking tds @@ -390,3 +390,9 @@ fonts/map/dvips}\label{e0041----one-or-more-map-file-found-for-the-package-but-n At least one map file was found which was not in a path starting with \texttt{fonts/map/dvips}. + +\hypertarget{e0042----config-file--doesnt-exist}{% +\subsection{\texorpdfstring{E0042 -\/- Config file doesn't +exist}{E0042 -\/- Config file doesn't exist}}\label{e0042----config-file--doesnt-exist}} + +The config file specified at the command line doesn't exist. diff --git a/support/pkgcheck/docs/fatald.tex b/support/pkgcheck/docs/fatald.tex index ef26ff30cf..aa80e74e28 100644 --- a/support/pkgcheck/docs/fatald.tex +++ b/support/pkgcheck/docs/fatald.tex @@ -9,7 +9,7 @@ to check a directory \subsection{F0002 -\/- Specified directory does not exist. Exiting...}\label{f0002----specified-directory-does-not-exist-exiting}} -The directory specified at the command line does not exit. +The directory specified at the command line does not exist. \hypertarget{f0003----specified-tds-archive-does-not-exist-or-is-no-file}{% \subsection{F0003 -\/- Specified TDS archive does not exist or is no @@ -45,3 +45,24 @@ archive}\label{f0007----could-not-create-temporary-directory-for-unzipping-the-t Make sure the temp directory is writable and/or the temp directory has enough space. + +\hypertarget{f0008----config-file--doesnt-exist-exiting}{% +\subsection{\texorpdfstring{F0008 -\/- Config file doesn't exist. +Exiting...}{F0008 -\/- Config file doesn't exist. Exiting...}}\label{f0008----config-file--doesnt-exist-exiting}} + +The config file specified at the command line doesn't exist. + +\hypertarget{f0009----error-reading-config-file-config_file--exiting}{% +\subsection{\texorpdfstring{F0009 -\/- Error reading config file +\textless config\_file\textgreater: +Exiting...}{F0009 -\/- Error reading config file \textless config\_file\textgreater: Exiting...}}\label{f0009----error-reading-config-file-config_file--exiting}} + +The config file \textless config\_file\textgreater{} could not be read. + +\hypertarget{f0010----config-files-content-could-no-be-read-properly--exiting}{% +\subsection{\texorpdfstring{F0010 -\/- Config file's content could no be +read properly: +Exiting...}{F0010 -\/- Config file's content could no be read properly: Exiting...}}\label{f0010----config-files-content-could-no-be-read-properly--exiting}} + +The content of the config has errors as given in . Please correct and +rerun. diff --git a/support/pkgcheck/docs/informationd.tex b/support/pkgcheck/docs/informationd.tex index cc53641fc7..80e68f0255 100644 --- a/support/pkgcheck/docs/informationd.tex +++ b/support/pkgcheck/docs/informationd.tex @@ -29,9 +29,9 @@ like) line endings. For more details refer to: \url{http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html\#crlf} -\hypertarget{i0005----corrections-permissions-for-file-or-directory}{% -\subsection{I0005 -\/- Corrections permissions for file or -directory}\label{i0005----corrections-permissions-for-file-or-directory}} +\hypertarget{i0005----correcting-permissions-for-file-or-directory}{% +\subsection{I0005 -\/- Correcting permissions for file or +directory}\label{i0005----correcting-permissions-for-file-or-directory}} \texttt{pkgcheck} corrects wrong permsissions for package files and directories. It runs the \texttt{chmod} command in verbose mode. @@ -59,3 +59,41 @@ CRLF}\label{i0007----successfully-corrected-wrong-line-endings-to-lf-resp-crlf}} endings or to CRLF line endings if it the file was a Windows text file. Wrong line endings could be CR, CRLF or a mixture of line endings. + +\hypertarget{i0008----using-config-file-}{% +\subsection{\texorpdfstring{I0008 -\/- Using config file +}{I0008 -\/- Using config file }}\label{i0008----using-config-file-}} + +Tells the user which config file is used. + +\hypertarget{i0009----updating-entry-pkgname---tpkg-with-pkgname---new-tpkg-from-config-file}{% +\subsection{\texorpdfstring{I0009 -\/- Updating entry +\texttt{\textless{}pkgname\textgreater{}} -\textgreater{} +\texttt{\textless{}tpkg\textgreater{}} with +\texttt{\textless{}pkgname\textgreater{}} -\textgreater{} +\texttt{\textless{}new\ tpkg\textgreater{}} from config +file",}{I0009 -\/- Updating entry \textless pkgname\textgreater{} -\textgreater{} \textless tpkg\textgreater{} with \textless pkgname\textgreater{} -\textgreater{} \textless new tpkg\textgreater{} from config file",}}\label{i0009----updating-entry-pkgname---tpkg-with-pkgname---new-tpkg-from-config-file}} + +This message can only show up if \texttt{pkgcheck} got called with +\texttt{-\/-config}. It is required that the path names in the TDS zip +archive contain the package name. There are exceptions however, and if +such an exception is defined in the config file \texttt{pkgcheck} +reports the usage of an exception. + +Example: \texttt{tex/latex/microtype/microtype-luatex.de} in the TDS zip +archive \texttt{microtype.tds.zip} contains the package name +\texttt{microtype} + +There are exceptions, however. + +Example: The file names in \texttt{latex-amsmath.tds.zip} do not contain +\texttt{latex-amsmath} but just \texttt{latex} + +These exceptions are hard-coded in pkgcheck but can be overridden in the +\texttt{pkgcheck.yml} config file like in the following example + +\begin{verbatim} +tds_path_exceptions: + - pkg: latex-amsmath + tpkg: latexnew +\end{verbatim} diff --git a/support/pkgcheck/docs/pkgcheck.pdf b/support/pkgcheck/docs/pkgcheck.pdf Binary files differindex a1f12200dc..29df6c8e4a 100644 --- a/support/pkgcheck/docs/pkgcheck.pdf +++ b/support/pkgcheck/docs/pkgcheck.pdf diff --git a/support/pkgcheck/docs/pkgcheck.tex b/support/pkgcheck/docs/pkgcheck.tex index ab96cc390a..a41a7db1ad 100644 --- a/support/pkgcheck/docs/pkgcheck.tex +++ b/support/pkgcheck/docs/pkgcheck.tex @@ -42,7 +42,7 @@ % \pdfinfo{ % /Author (Manfred Lotz) % /Title pkgcheck Utility -% } +% } %\title{pkgcheck utility} \include{title} @@ -59,6 +59,8 @@ \end{abstract} +\newpage + \section{Introduction} Uploaded packages to CTAN must satisfy various requirements in order to get @@ -67,7 +69,7 @@ installed on CTAN. A first introduction is given here \url{https://ctan.org/help/upload-pkg}. Even more details are to be found in the excellent CTAN-upload addendum -\url{https://ctan.org/file/help/ctan/CTAN-upload-addendum} written by Petra Rübe-Pugliese. +\url{https://ctan.org/file/help/ctan/CTAN-upload-addendum} written by Petra Rübe-Pugliese. The \pkgcheck utility which runs on Linux systems only checks those requirements which can be checked by a program. @@ -89,22 +91,14 @@ information for a certain error. The \pkgcheck is a 64-bit statically linked binary, and should work an any 64-bit Linux. It is available in the repository in directory \verb|bin/|. -Currently, the only external programs required are: -\begin{itemize} -\item \verb|/usr/bin/unzip| - -Used only, when a TDS zip archive will be extracted. +Currently, the only external program required is \verb|/usr/bin/pdfinfo|. It is +used when a PDF document will be checked. -\item \verb|/usr/bin/pdfinfo| - -Used only, when a PDF document will be checked. - -\end{itemize} \section{Installation} -Copy the binary from \verb|bin/pkgcheck| to a suitable location on your hard disk, and -(recommended) make sure the directory is in the \verb|PATH| or call \verb|pkgcheck| using an +Copy the binary from \verb|bin/pkgcheck| to a suitable location on your hard disk, and +(recommended) make sure the directory is in the \verb|PATH| or call \verb|pkgcheck| using an absolute path name. \section{Utility usage} @@ -116,32 +110,109 @@ Running \verb|pkgcheck --help| shows the available command line options. Here a sample output: +{\small + \begin{verbatim} -pkgcheck 1.0.0 +pkgcheck 3.0.0 Manfred Lotz <manfred@ctan.org> -A checker for uploaded packages to CTAN. +Command-line tool to check packages uploaded to CTAN. USAGE: - pkgcheck [FLAGS] [OPTIONS] - -FLAGS: - -L, --correct-crlf Correct CRLF line endings - -C, --correct-perms Correct permissions - --explain-all Explains all error or warning messages - -h, --help Prints help information - -I, --ignore-dupes Ignore dupes - --no-colors Don't display messages in color - --show-temp-endings Show file endings for temporary files - --urlcheck Check URLs found in README files - -V, --version Prints version information - -v, --verbose Verbose operation? + pkgcheck [OPTIONS] OPTIONS: - -e, --explain <explain> Explain error or warning message - -d, --package-dir <pkg_dir> Package directory - -T, --tds-zip <tds_zip> tds zip archive - + -C, --correct-perms Correct permissions + --config-file <CONFIG_FILE> Specify config file to use + -d, --package-dir <PKG_DIR> Package directory + -e, --explain <EXPLAIN> Explain error or warning message + --explain-all Explains all error or warning messages + --generate-completion <GENERATOR> [possible values: bash, elvish, fish, + powershell, zsh] + -h, --help Print help information + -I, --ignore-dupes Ignore dupes + --ignore-same-named Ignore same-named files + -L, --correct-le Correct line endings + --no-colors Don't display messages in color + --show-temp-endings Show file endings for temporary files + -T, --tds-zip <TDS_ZIP> tds zip archive + --urlcheck Check URLs found in README files + -v, --verbose Verbose operation? + -V, --version Print version information \end{verbatim} +} + +\subsection{Config file} + +It is now possible to have a config file for \pkgcheck which then is a YAML +file. A config file can be +specified by using the command line option \verb|--config-file|. If no config +file is specified during invocation of \pkgcheck then \pkgcheck checks two +locations for existence of a config file. + +\begin{itemize} + \item \verb|~/.ctan/pkgcheck.yml| + \item \verb|.config/ctan/pkgcheck.yml| +\end{itemize} + +Currently, the config file may contain only TDS path exceptions. For more +details see message +\hyperlink{i0009----updating-entry-pkgname---tpkg-with-pkgname---new-tpkg-from-config-file}{I0009x}. + + +\subsection{Generate shell completions} + +\pkgcheck offers an option to generate shell completions for various shells, +most notably \texttt{bash}, \texttt{zsh }and \texttt{fish}. + + + +\subsubsection{bash completion} + +In \texttt{bash} one recommendation is to put completions directly into +the \verb|~/.bash_completion| file. + +Example: + +\begin{minted}[linenos=true,frame=single,fontsize=\footnotesize]{sh} +pkgcheck -generate-completion bash >> ~/.bash-completion +\end{minted} + +\subsubsection{zsh completion} + +\texttt{zsh} doesn't recommend a specific location for completions. One +possibility is the following: + + + +\begin{minted}[linenos=true,frame=single,fontsize=\footnotesize]{sh} +# Prepare +mkdir -p ~/.zfunc/completions +pkgcheck -generate-completion zsh >> ~/.zfunc/completions/_pkgcheck +\end{minted} + +Put the following into \verb|~/.zshrc| + +\begin{minted}[linenos=true,frame=single,fontsize=\footnotesize]{sh} +fpath+=~/.zfunc/completions +autoload -Uz compinit +zstyle ':completion:*' menu select +compinit +\end{minted} + +\subsubsection{fish completion} + +\texttt{fish} is pretty straight forward as it offers the \texttt{~/.config/fish/completions/} +directory for completions. + + +Run + +\begin{minted}[linenos=true,frame=single,fontsize=\footnotesize]{sh} +pkgcheck -generate-completion fish > ~/.config/fish/completions/pkgcheck.fish +\end{minted} + + + \subsection{Check a package} @@ -151,7 +222,7 @@ tar archive. The package must have a top level directory. After unpacking the archive of a package \texttt{mypkg} into directory \texttt{mypkg/} it can be checked by running \pkgcheck with -option verb|--package-dir| or shorter \verb|-d|. +option \verb|--package-dir| or shorter \verb|-d|. \begin{minted}[linenos=true,frame=single,fontsize=\footnotesize]{sh} @@ -161,19 +232,19 @@ option verb|--package-dir| or shorter \verb|-d|. \pkgcheck returns 1 if there are any errors, otherwise 0. - + \subsection{Check a package which has a TDS archive} If a package contains a TDS ZIP archive it is supposed to be in the top level directory of a package. -In order to check the TDS ZIP archive the option +In order to check the TDS ZIP archive the option \verb|-T <tds_zip>| or \verb|--tds-zip <tds_zip>| can be used. Please note that a TDS ZIP archive will always be checked together with the non-install tree of the package which means that -\verb|--tds-zip| requires option \verb|--package-dir| as well. - +\verb|--tds-zip| requires option \verb|--package-dir| as well. + Checking package \texttt{mypkg} \pkgcheck will be invoked like follows: \begin{minted}[linenos=true,frame=single,fontsize=\footnotesize]{sh} @@ -230,7 +301,7 @@ file from CRLF to LF line endings. \item \verb|-V| Outputs \pkgcheck's version number. - + \item \verb|--help| \verb|--help| shows the available command line options. @@ -262,7 +333,7 @@ OPTIONS: \end{verbatim} -\item \verb|--explain <explain| +\item \verb|--explain <explain| This option explains an error message in more detail. @@ -273,7 +344,7 @@ OPTIONS: \end{minted} -\item \verb|--explain-all| +\item \verb|--explain-all| Outputs a list of explanations of all messages. @@ -293,7 +364,7 @@ text file has CRLF line endings. It is very important to note that determining file types is not bullet proof. So, it might happen in some cases that \pkgcheck makes mistakes when determining -a file type. This could lead to a subseqent mistake when complaining about an +a file type. This could lead to a subsequent mistake when complaining about an x-bit, or complaining about CRF line ending. @@ -306,7 +377,7 @@ x-bit, or complaining about CRF line ending. From an installation point of view the files and directories of a package \begin{itemize} \item must be at least world readable -\item must be writable by owner or group +\item must be writable by owner or group \item must not have the x-bit on for the owner if the file isn't an executable, i.e. a script or binary \end{itemize} @@ -314,7 +385,7 @@ From an installation point of view the files and directories of a package The reason for this minimal requirement is that the installation utility used by the CTAN team (which by the way was written by Rainer Schöpf a long time ago) sets permissions correctly if the owner permission is set correctly. - + Examples: \begin{itemize} @@ -335,29 +406,31 @@ are accepted. \begin{description} \item[Innnn] Informational messages - These are message which announce \pkgcheck actions. - + These are message which usually announce \pkgcheck actions. + \item[Fnnnn] Fatal messages - Fatal messages report unrecoverable errors. In this case \pkgcheck's only - option is to terminate. If for example, the package directory specified at - the command line doesn't exist then the only option is to terminate. - + Fatal messages are related to environmental issues and not related to + packages. They are usually unrecoverable errors, and \pkgcheck's only + option is to terminate. Fatal messages are written to standard error. + + If for example, the package directory specified at + the command line doesn't exist then the only option is to issue + a message and to terminate. + \item[Ennnn] Error messages Error messages report errors which must be fixed before installing a package. - + \item[Wnnnn] Warning messages Warning messages denote possible errors depending upon the situation. For example, for a font package having many duplicate files might be ok. For another package it could be regarded as an error. +\end{description} - - -\end{description} \section{Informational messages} \input{informationd} diff --git a/support/pkgcheck/docs/title.tex b/support/pkgcheck/docs/title.tex index 5a37d84767..020feb2956 100644 --- a/support/pkgcheck/docs/title.tex +++ b/support/pkgcheck/docs/title.tex @@ -1 +1 @@ -\title{pkgcheck Utility, v2.4.0} +\title{pkgcheck Utility, v3.0.0} diff --git a/support/pkgcheck/docs/warningsd.tex b/support/pkgcheck/docs/warningsd.tex index cf21cb63d4..b681972557 100644 --- a/support/pkgcheck/docs/warningsd.tex +++ b/support/pkgcheck/docs/warningsd.tex @@ -80,3 +80,13 @@ We regard a file as a Windows file if its name ends with: \item \texttt{.reg} \end{itemize} + +\hypertarget{w0009----replacing-----with-the-same-from-config-file}{% +\subsection{\texorpdfstring{W0009 -\/- Replacing -\textgreater{} ` with +the same from config +file",}{W0009 -\/- Replacing -\textgreater{} ` with the same from config file",}}\label{w0009----replacing-----with-the-same-from-config-file}} + +This message can only show up if \texttt{pkgcheck} got called with +\texttt{-\/-config}. Indicates that an entry in the \texttt{pkgcheck} +config file does the same as the hard-coded entry. This helps to keep a +clean config file. diff --git a/support/pkgcheck/src/gparser.rs b/support/pkgcheck/src/gparser.rs index ac3e1e7289..136f6f41b1 100644 --- a/support/pkgcheck/src/gparser.rs +++ b/support/pkgcheck/src/gparser.rs @@ -1,3 +1,5 @@ +use log::*; + use pest::Parser; #[cfg(debug_assertions)] @@ -32,7 +34,7 @@ pub fn parse_generate(s: &str) -> Option<Vec<String>> { } Rule::EOI => (), e => { - println!("unreachable: {:?}", e); + error!("unreachable: {:?}", e); unreachable!() } }; diff --git a/support/pkgcheck/src/linkcheck.rs b/support/pkgcheck/src/linkcheck.rs index b0b33fb3b2..ba0cd73cea 100644 --- a/support/pkgcheck/src/linkcheck.rs +++ b/support/pkgcheck/src/linkcheck.rs @@ -1,3 +1,5 @@ +use log::*; + use threadpool::ThreadPool; use colored::*; @@ -6,10 +8,10 @@ use linkify::{LinkFinder, LinkKind}; use std::fs::File; use std::io::prelude::*; - use reqwest::header; use std::time::Duration; +use std::borrow::Cow; use std::sync::Arc; use std::sync::Mutex; @@ -104,7 +106,7 @@ fn check_link(url: &str, fname: &str, urlhash: &Arc<Mutex<UrlHash>>, print_all: } UrlStatus::UrlOk => { if print_all { - print_ok(no_colors!(), &url, &f); + print_ok(super::ARGS.no_colors, &url, &f); }; } UrlStatus::UrlError(e) => { @@ -122,7 +124,7 @@ fn check_link(url: &str, fname: &str, urlhash: &Arc<Mutex<UrlHash>>, print_all: if let Some(mut hs) = urlhash.get_mut(&url) { if print_all { for p in hs.paths.iter() { - print_ok(no_colors!(), &url, p); + print_ok(super::ARGS.no_colors, &url, p); } } hs.status = UrlStatus::UrlOk; @@ -152,29 +154,26 @@ fn get_links(fname: &str) -> Option<Vec<String>> { Ok(_bytes_read) => { return get_links_inner(&String::from_utf8_lossy(&buf)); } - Err(e) => println!("Error reading file {}: {:?}", fname, e), + Err(e) => error!("Error reading file {}: {:?}", fname, e), } } - Err(e) => println!("Error opening file {}: {}", fname, e), + Err(e) => error!("Error opening file {}: {}", fname, e), } None } -fn resolve_entities(url: &str) -> String { +fn resolve_entities(url: &str) -> Cow<'static, str> { if !url.contains('&') { - return String::from(url); + return String::from(url).into(); } - let v = vec![ - ("ö", "ö"), - ("ü", "ü"), - ]; + let v = vec![("ö", "ö"), ("ü", "ü")]; let mut url_new = String::from(url); - for (e,r) in v { + for (e, r) in v { url_new = url_new.replace(e, r); } - url_new + url_new.into() } // retrieves links in a string and then checks those links @@ -195,7 +194,7 @@ fn get_links_inner(s: &str) -> Option<Vec<String>> { // This is a workaround to prevent URLs ending with certain characters let url = resolve_entities(r.trim_end_matches(|c| c == '。' || c == '`')); - links.push(url); + links.push(url.into()); } if !links.is_empty() { Some(links) @@ -264,9 +263,9 @@ fn check_link_inner(l: &str, head: bool) -> UrlStatus { fn print_ok(no_colors: bool, url: &str, f: &str) { if no_colors { - println!("✔ {} in {}", &url, f); + info!("✔ {} in {}", &url, f); } else { // println!("✔ {} in {}", &url, f); - println!("{} {} in {}", "✔".bright_green().bold(), url, f); + info!("{} {} in {}", "✔".bright_green().bold(), url, f); } } diff --git a/support/pkgcheck/src/main.rs b/support/pkgcheck/src/main.rs index b18fd8793b..f0766cdeba 100644 --- a/support/pkgcheck/src/main.rs +++ b/support/pkgcheck/src/main.rs @@ -1,6 +1,8 @@ #[macro_use] extern crate pest_derive; +use log::*; + mod gparser; #[macro_use] @@ -14,6 +16,7 @@ mod recode; use recode::{wrong_line_endings2crlf, wrong_line_endings2lf}; mod filemagic; + use filemagic::LineEnding; use linkcheck::LinkCheck; @@ -23,14 +26,15 @@ use std::fmt::Display; use std::str; use utils::*; +use serde::{Deserialize, Serialize}; use std::os::unix::fs::MetadataExt; - +use std::borrow::Cow; use scoped_threadpool::Pool; use tempfile::Builder; -#[macro_use] -extern crate lazy_static; +use once_cell::sync::Lazy; // 1.3.1 + use colored::*; use regex::Regex; @@ -51,13 +55,140 @@ use std::sync::atomic::{AtomicBool, Ordering}; use rustc_hash::{FxHashMap, FxHashSet}; +use std::fmt::Arguments; use std::sync::mpsc::{channel, Sender}; -use structopt::clap::Shell; -use structopt::StructOpt; +use clap::{Command, CommandFactory, Parser, ValueHint}; +use clap_complete::{generate, Generator, Shell}; + #[cfg(unix)] use walkdir::{DirEntry, WalkDir}; +fn format_message(message: &Arguments, no_color: bool) -> Cow<'static, str> { + let msg_str = format!("{}", message); + if msg_str.starts_with(' ') { + return msg_str.into(); + } + let (left, right) = msg_str.split_once(' ').unwrap(); + if no_color { + msg_str.into() + } else { + let colored_msg = match &left.chars().next().unwrap() { + 'E' | 'F' => format!("{} {}", left.bright_red().bold(), right), + 'W' => format!("{} {}", left.bright_red(), right), + 'I' => format!("{} {}", left.bright_yellow().bold(), right), + _ => msg_str, + }; + colored_msg.into() + } +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct TdsException { + pub pkg: String, + pub tpkg: String, +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct PathExceptions { + pub tds_path_exceptions: Vec<TdsException>, +} + +fn get_config_file_name() -> Option<String> { + if let Some(config_file) = &ARGS.config_file { + if Path::new(&config_file).exists() { + return Some(config_file.to_string()) + } else { + f0008!(config_file); + std::process::exit(1); + } + } + let home_dir = match home::home_dir() { + Some(path) => path.display().to_string(), + None => panic!("Impossible to get your home dir!"), + }; + let config_files = [".ctan/pkgcheck.yml", ".config/ctan/pkgcheck.yml"]; + for f in config_files { + let config_file_abs_path = format!("{}/{}", home_dir, f); + if Path::new(&config_file_abs_path).exists() { + return Some(config_file_abs_path); + } + } + None +} + +fn read_yaml_config() -> FxHashMap<String, String> { + let mut pkg_replacements: FxHashMap<String, String> = FxHashMap::default(); + for (p, q) in [ + ("babel-base", "babel"), + ("latex-base", "latex"), + ("latex-lab", "latex"), + ("latex-tools", "latex"), + ("latex-graphics", "latex"), + ("latex-amsmath", "latex"), + ("latex-firstaid", "latex/firstaid"), + ("latex-base-dev", "latex-dev"), + ("latex-lab-dev", "latex-dev"), + ("latex-tools-dev", "latex-dev"), + ("latex-graphics-dev", "latex-dev"), + ("latex-amsmath-dev", "latex-dev"), + ("latex-firstaid-dev", "latex-dev/firstaid"), + ("vntex-nonfree", "vntex"), + ] { + pkg_replacements.insert(p.to_string(), q.to_string()); + } + + match get_config_file_name() { + Some(config_filename) => { + i0008!(config_filename); + + let data = match fs::read_to_string(&config_filename) { + Ok(str) => str, + Err(e) => { f0009!(&config_filename, e); std::process::exit(1); } + }; + + let path_exceptions = serde_yaml::from_str::<PathExceptions>(&data); + + match path_exceptions { + Ok(pb) => { + for play in &pb.tds_path_exceptions { + // check if package name is already in pkg_replacements hash + let old_val = pkg_replacements.get(&play.pkg); + if let Some(ov) = old_val { + if ARGS.verbose { + if ov == &play.tpkg { + w0009!(play.pkg, play.tpkg); + } else { + i0009!(play.pkg, ov, play.tpkg); + } + } + } + pkg_replacements.insert(play.pkg.clone(), play.tpkg.clone()); + } + pb + } + Err(e) => { f0010!(e); std::process::exit(1);}, + }; + pkg_replacements + } + None => pkg_replacements, + } +} + +fn setup_logger(no_color: bool) -> Result<(), fern::InitError> { + fern::Dispatch::new() + .format(move |out, message, _record| { + let msg_txt = format_message(message, no_color); + out.finish(format_args!("{}", msg_txt)) + }) + .level(log::LevelFilter::Info) + .chain(std::io::stdout()) + .apply()?; + Ok(()) +} + fn err(path: &Path, err: &io::Error) { e0027!(path.display(), err); } @@ -83,7 +214,9 @@ fn hash_file_inner(path: &Path) -> io::Result<Vec<u8>> { loop { match fp.read(&mut buf)? { 0 => break, - n => { digest.update(&buf[..n]); }, + n => { + digest.update(&buf[..n]); + } } } Ok(digest.finalize().as_bytes().to_vec()) @@ -96,7 +229,7 @@ fn hash_file(fsize: u64, path: PathBuf, tx: &HashSender) { } } -// returns false if an error occured +// returns false if an error occurred fn fix_inconsistent_le(fname: &str) -> bool { i0004!(fname); match wrong_line_endings2lf(fname) { @@ -111,7 +244,7 @@ fn fix_inconsistent_le(fname: &str) -> bool { } } -// returns false if an error occured +// returns false if an error occurred fn make_crlf(fname: &str) -> bool { i0004!(fname); match wrong_line_endings2crlf(fname) { @@ -192,48 +325,50 @@ fn _get_devno(entry: &DirEntry) -> u64 { } } -#[derive(StructOpt, Debug)] -#[structopt(about = "A checker for uploaded packages to CTAN.")] +#[derive(Parser, Debug, PartialEq)] +#[clap(author, version, about, long_about = None)] struct Args { - #[structopt(short = "I", long = "ignore-dupes", help = "Ignore dupes")] + #[clap(short = 'I', long = "ignore-dupes", help = "Ignore dupes")] ignore_dupes: bool, - #[structopt(long = "ignore-same-named", help = "Ignore same-named files")] + #[clap(long = "ignore-same-named", help = "Ignore same-named files")] ignore_same_named: bool, - #[structopt(short = "v", long = "verbose", help = "Verbose operation?")] + #[clap(short = 'v', long = "verbose", help = "Verbose operation?")] verbose: bool, - #[structopt(short = "L", long = "correct-le", help = "Correct line endings")] + #[clap(short = 'L', long = "correct-le", help = "Correct line endings")] correct_le: bool, - #[structopt(short = "C", long = "correct-perms", help = "Correct permissions")] + #[clap(short = 'C', long = "correct-perms", help = "Correct permissions")] correct_perms: bool, - #[structopt(long = "no-colors", help = "Don't display messages in color")] + #[clap(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")] + #[clap(long = "urlcheck", help = "Check URLs found in README files")] urlcheck: bool, - #[structopt(short = "T", long = "tds-zip", help = "tds zip archive", group = "tds")] + #[clap(short = 'T', long = "tds-zip", help = "tds zip archive", group = "tds", value_hint = ValueHint::FilePath)] tds_zip: Option<String>, - #[structopt( - short = "e", + #[clap( + short = 'e', long = "explain", help = "Explain error or warning message", group = "only_one" )] explain: Option<String>, - #[structopt( + #[clap( long = "explain-all", help = "Explains all error or warning messages", group = "only_one" )] explain_all: bool, - #[structopt( + #[clap(long = "generate-completion", group = "only_one", arg_enum)] + generator: Option<Shell>, + #[clap( long = "show-temp-endings", help = "Show file endings for temporary files", group = "only_one" )] show_tmp_endings: bool, - #[structopt(short = "d", long = "package-dir", help = "Package directory")] + #[clap(short = 'd', long = "package-dir", help = "Package directory", value_hint = ValueHint::DirPath)] pkg_dir: Option<String>, + #[clap(long = "config-file", help = "Specify config file to use", value_hint = ValueHint::FilePath)] + config_file: Option<String>, } // We take care to avoid visiting a single inode twice, @@ -248,10 +383,8 @@ fn check_inode(_: &mut FxHashSet<u64>, _: &Metadata) -> bool { true } -lazy_static! { - static ref ARGS: Args = Args::from_args(); - static ref ERROR_OCCURED: AtomicBool = AtomicBool::new(false); -} +static ARGS: Lazy<Args> = Lazy::new(Args::parse); +static ERROR_OCCURRED: AtomicBool = AtomicBool::new(false); #[derive(Debug, Clone, PartialEq, Eq)] pub enum DPath { @@ -296,21 +429,18 @@ impl DupPath { } } -// fn install_completion_bash() { -// Args::clap().gen_completions(env!("CARGO_PKG_NAME"), Shell::Bash, "bla"); -// } +type DupHashes = FxHashMap<(u64, Vec<u8>), DupPath>; -// fn install_completion_zsh() { -// Args::clap().gen_completions(env!("CARGO_PKG_NAME"), Shell::Zsh, "/home/manfred/.zfunc"); -// } +fn print_completions<G: Generator>(gen: G, cmd: &mut Command) { + generate(gen, cmd, cmd.get_name().to_string(), &mut io::stdout()); +} -// fn install_completion_fish() { -// Args::clap().gen_completions(env!("CARGO_PKG_NAME"), Shell::Fish, "target"); -// } +fn main() { + let _ = setup_logger(ARGS.no_colors); -type DupHashes = FxHashMap<(u64, Vec<u8>), DupPath>; + // read yaml config file if one is given explicitly or implicitly + let pkg_replace : FxHashMap<String, String> = read_yaml_config(); -fn main() { match &ARGS.explain { None => (), Some(e) => { @@ -319,23 +449,12 @@ 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 let Some(generator) = ARGS.generator { + let mut cmd = Args::command(); + eprintln!("Generating completion file for {:?}...", generator); + print_completions(generator, &mut cmd); + process::exit(0) + } if ARGS.explain_all { explains_all(); @@ -393,13 +512,13 @@ fn main() { if tds_zip.is_some() { if let Some(pn) = pkg_name { if let Some(s) = ARGS.tds_zip.as_ref() { - check_tds_archive(&pn, s, &hashes); + check_tds_archive(&pn, s, &hashes, &pkg_replace); } } } } - if ERROR_OCCURED.load(Ordering::Relaxed) { + if ERROR_OCCURRED.load(Ordering::Relaxed) { process::exit(1); } else { process::exit(0); @@ -428,20 +547,20 @@ fn print_duplicates(hashes: &DupHashes) { total_size += sz * (paths.plen - 1) as u64; total_dupes += (paths.plen - 1) as u64; - println!("Size: {}", sz); + info!("Size: {}", sz); for p in &paths.dupes { if let DPath::Both(p) = p { let ps = p.as_path().to_str().unwrap(); - println!(" >>> {}", ps); + info!(" >>> {}", ps); } } - println!(); + //eprintln!(); } if ARGS.verbose && total_dupes > 0 { - println!("Duplicate statistics"); - println!(" Found {} duplicate files", total_files); - println!(" Size of duplicate files: {}", total_size); + info!("Duplicate statistics"); + info!(" Found {} duplicate files", total_files); + info!(" Size of duplicate files: {}", total_size); } } @@ -532,7 +651,10 @@ fn check_generated_files(entry: &str, generated: &mut GeneratedHashMap) { } // Ignore generated pdf, html, and css files - if fname.ends_with(".pdf") || fname.ends_with(".html") || fname.ends_with(".css") { + if fname.ends_with(".pdf") + || fname.ends_with(".html") + || fname.ends_with(".css") + { continue; } @@ -542,10 +664,10 @@ fn check_generated_files(entry: &str, generated: &mut GeneratedHashMap) { } }; } - Err(e) => println!("Error reading file {}: {:?}", entry, e), + Err(e) => error!("Error reading file {}: {:?}", entry, e), } } - Err(e) => println!("Error opening file {}: {:?}", entry, e), + Err(e) => error!("Error opening file {}: {:?}", entry, e), } } @@ -592,7 +714,7 @@ fn check_tds_archive_name(tds_zip: &Option<String>) -> Option<String> { // } // } -fn check_tds_archive(pkg_name: &str, tds_zip: &str, hashes: &DupHashes) { +fn check_tds_archive(pkg_name: &str, tds_zip: &str, hashes: &DupHashes, pkg_replace: &FxHashMap<String, String>) { i0003!(tds_zip); let dir_entry = Path::new(tds_zip); @@ -607,29 +729,7 @@ fn check_tds_archive(pkg_name: &str, tds_zip: &str, hashes: &DupHashes) { let ut = Utils::new(utils::CheckType::Tds); - // We have a discrepancy between - // TDS zip archive name: babel-base.tds.zip - // and package name: babel - // which yields a false test when checking for the package name - // the path names of the TDS zip archive files. - // Therefore, we correct here. - // latex-tools, latex-graphics, latex-amsmath, latex-base => latex - // latex-tools-dev, latex-graphics-dev, latex-amsmath-dev, latex-base-dev => latex-dev - let mut pkg_replacements: FxHashMap<&str, &str> = FxHashMap::default(); - pkg_replacements.insert("babel-base", "babel"); - pkg_replacements.insert("latex-base", "latex"); - pkg_replacements.insert("latex-lab", "latex"); - pkg_replacements.insert("latex-tools", "latex"); - pkg_replacements.insert("latex-graphics", "latex"); - pkg_replacements.insert("latex-amsmath", "latex"); - pkg_replacements.insert("latex-firstaid", "latex/firstaid"); - pkg_replacements.insert("latex-base-dev", "latex-dev"); - pkg_replacements.insert("latex-lab-dev", "latex-dev"); - 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-dev", "latex-dev/firstaid"); - let real_pkg_name = if let Some(real_name) = pkg_replacements.get(pkg_name) { + let real_pkg_name = if let Some(real_name) = pkg_replace.get(pkg_name) { real_name } else { pkg_name @@ -647,10 +747,13 @@ fn check_tds_archive(pkg_name: &str, tds_zip: &str, hashes: &DupHashes) { let tmp_dir_str = tmp_dir.path().to_str().unwrap(); // unzip the TDS zip archive into a temporary directory match ut.unzip(tds_zip, tmp_dir_str) { - Ok(_) => {}, + Ok(_) => {} Err(e) => { - println!("Could not unpack `{}` into directory `{}`", tds_zip, tmp_dir_str); - println!("Error from unzip: {}", e); + error!( + "Could not unpack `{}` into directory `{}`", + tds_zip, tmp_dir_str + ); + error!("Error from unzip: {}", e); e0033!(&tds_zip, e); process::exit(1) } @@ -824,7 +927,7 @@ fn check_tds_archive(pkg_name: &str, tds_zip: &str, hashes: &DupHashes) { } } Err(e) => { - eprintln!("{}", e); + error!("{}", e); } } } @@ -911,7 +1014,7 @@ fn fix_perms(entry: &str) { if rc.status { if let Some(op) = rc.output { - print!("{}", op); + info!("{}", op); } } } @@ -934,7 +1037,9 @@ fn set_perms(entry: &str, p: u32) -> bool { if rc.status { if let Some(op) = rc.output { - print!("{}", op); + // we need to remove the `\n` in the `chmod` output + // as `info!` also adds a `\n` + info!("{}", op.trim_end()); } true } else { @@ -1164,7 +1269,7 @@ fn check_package(root: &str, tds_zip: &Option<String>) -> Option<DupHashes> { } Err(e) => { - eprintln!("{}", e); + error!("{}", e); } } } @@ -1255,7 +1360,7 @@ fn check_package(root: &str, tds_zip: &Option<String>) -> Option<DupHashes> { filemagic::Mimetype::Text(LineEnding::Lf) => { w0008!(&dir_entry_str); } - fmm => println!("Should not occur: {} has {:?}", dir_entry_str, fmm), + fmm => error!("Should not occur: {} has {:?}", dir_entry_str, fmm), }, Some(_) | None => { match ft { @@ -1280,7 +1385,7 @@ fn check_package(root: &str, tds_zip: &Option<String>) -> Option<DupHashes> { } } filemagic::Mimetype::Text(LineEnding::Lf) => (), - fmm => println!("Should not occur: {} has {:?}", dir_entry_str, fmm), + fmm => error!("Should not occur: {} has {:?}", dir_entry_str, fmm), } } } @@ -1303,7 +1408,7 @@ fn check_package(root: &str, tds_zip: &Option<String>) -> Option<DupHashes> { if !ret.status { e0017!(&dir_entry_str); if let Some(output) = ret.output { - println!("{}", &output); + info!("{}", &output); }; } } @@ -1336,7 +1441,7 @@ fn check_package(root: &str, tds_zip: &Option<String>) -> Option<DupHashes> { print_casefolding(&lcnames); print_generated(&doublenames, &generated); - if ! ARGS.ignore_same_named { + if !ARGS.ignore_same_named { print_doublenames(&doublenames); } @@ -1392,7 +1497,7 @@ fn print_casefolding(hashes: &FxHashMap<PathBuf, Vec<(PathBuf, FileKind)>>) { e0025!(k.display()); for (p, ty) in eles { - println!(" >>> {} ({})", p.display(), ty); + info!(" >>> {} ({})", p.display(), ty); } } } @@ -1435,7 +1540,7 @@ fn print_doublenames(hashes: &FxHashMap<PathBuf, Vec<PathBuf>>) { // println!(":: {}", k.display()); for p in paths { - println!(" >>> {}", p.display()); + info!(" >>> {}", p.display()); } } } @@ -1443,6 +1548,6 @@ fn print_doublenames(hashes: &FxHashMap<PathBuf, Vec<PathBuf>>) { fn show_tmp_endings() { i0006!(); for (t, c) in temp_file_endings() { - println!("{:23} {}", t, c); + info!("{:23} {}", t, c); } } diff --git a/support/pkgcheck/src/messages/errorsd.rs b/support/pkgcheck/src/messages/errorsd.rs index 0ea42eb23f..39a8ccb357 100644 --- a/support/pkgcheck/src/messages/errorsd.rs +++ b/support/pkgcheck/src/messages/errorsd.rs @@ -1,9 +1,12 @@ // This file is generated by a Perl script. The source is // in the docs/ directory of the repository. +use log::*; + pub fn e0001d() { - println!( - r#"E0001 -- Bad characters in file name + error!( + 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 @@ -16,8 +19,9 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#nounixspecialcharacte } pub fn e0002d() { - println!( - r#"E0002 -- File Permissions + error!( + r#" +E0002 -- File Permissions Files submitted to CTAN should be world readable. @@ -31,8 +35,9 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#filepermissions } pub fn e0003d() { - println!( - r#"E0003 -- README is not a text file + error!( + 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. @@ -41,8 +46,9 @@ it isn't. } pub fn e0004d() { - println!( - r#"E0004 -- Empty directory not allowed + error!( + 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 @@ -55,8 +61,9 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#noemptyfiles } pub fn e0005d() { - println!( - r#"E0005 -- Empty files not allowed + error!( + r#" +E0005 -- Empty files not allowed Empty files are considered as rubbish, and are usually not accepted as part of a package. @@ -68,8 +75,9 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#noemptyfiles } pub fn e0006d() { - println!( - r#"E0006 -- Hidden directories not allowed + error!( + r#" +E0006 -- Hidden directories not allowed A package should not contain hidden directories, neither in the package tree nor in the TDS zip archive. @@ -81,8 +89,9 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#noauxfiles } pub fn e0007d() { - println!( - r#"E0007 -- Hidden files not allowed + error!( + r#" +E0007 -- Hidden files not allowed A package should not contain hidden files, neither in the package tree nor in the TDS zip archive. @@ -94,8 +103,9 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#noauxfiles } pub fn e0008d() { - println!( - r#"E0008 -- Temporary file detected + error!( + 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. @@ -109,8 +119,9 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#noauxfiles } pub fn e0009d() { - println!( - r#"E0009 -- Package doesn't contain a README file + error!( + r#" +E0009 -- Package doesn't contain a README file A package must contain at least one of README, README.md or README.txt file. @@ -122,8 +133,9 @@ http://mirrors.ibiblio.org/CTAN/help/ctan/CTAN-upload-addendum.html#readme } pub fn e0010d() { - println!( - r#"E0010 -- Broken symlink detected + error!( + r#" +E0010 -- Broken symlink detected A broken symlink was detected. "# @@ -131,8 +143,9 @@ A broken symlink was detected. } pub fn e0011d() { - println!( - r#"E0011 -- Wrong permission for directory + error!( + r#" +E0011 -- Wrong permission for directory Directories should have rwx for the owner and at least r-x for others (i.e. world readable). @@ -144,8 +157,9 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#filepermissions } pub fn e0012d() { - println!( - r#"E0012 -- CRLF line endings detected + error!( + 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. @@ -157,8 +171,9 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#crlf } pub fn e0013d() { - println!( - r#"E0013 -- Socket special fie detected + error!( + r#" +E0013 -- Socket special fie detected The file specified in the error message is a socket special file which is not allowed. @@ -167,8 +182,9 @@ is not allowed. } pub fn e0014d() { - println!( - r#"E0014 -- Fifo special file detected + error!( + r#" +E0014 -- Fifo special file detected The file specified in the error message is a fifo special file which is not allowed. @@ -177,8 +193,9 @@ not allowed. } pub fn e0015d() { - println!( - r#"E0015 -- Bloch device file detected + error!( + r#" +E0015 -- Bloch device file detected The file specified in the error message is a block device file which is not allowed. @@ -187,8 +204,9 @@ not allowed. } pub fn e0016d() { - println!( - r#"E0016 -- Character device file detected + error!( + r#" +E0016 -- Character device file detected The file specified in the error message is a character device file which is not allowed. @@ -197,8 +215,9 @@ is not allowed. } pub fn e0017d() { - println!( - r#"E0017 -- PDF document is in error + error!( + r#" +E0017 -- PDF document is in error The PDF document mentioned in the message is in error. @@ -219,8 +238,9 @@ Example: } pub fn e0018d() { - println!( - r#"E0018 -- Unwanted directory detected + error!( + r#" +E0018 -- Unwanted directory detected A directory was detected which should not be part of a package. Example: __MACOSX @@ -229,8 +249,9 @@ __MACOSX } pub fn e0019d() { - println!( - r#"E0019 -- Generated file detected + error!( + 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 @@ -248,8 +269,9 @@ 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 + error!( + 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, @@ -263,8 +285,9 @@ Any other other directory at the top level is an error. } pub fn e0021d() { - println!( - r#"E0021 -- Error when reading a file + error!( + r#" +E0021 -- Error when reading a file An error was encountered when reading the file specified in the message. "# @@ -272,18 +295,20 @@ 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 + error!( + 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 checking is in effect. An error occcurred when trying to retrieve an 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 + error!( + 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. @@ -292,8 +317,9 @@ not be read. } pub fn e0024d() { - println!( - r#"E0024 -- TDS zip archive has wrong permissions + error!( + 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). @@ -305,8 +331,9 @@ 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 + error!( + 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 @@ -319,8 +346,9 @@ 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 + error!( + 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 @@ -329,18 +357,20 @@ 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 + error!( + r#" +E0027 -- An I/O error occurred -Some kind of I/O error occured. If you believe there is an error in +Some kind of I/O error occurred. If you believe there is an error in pkgcheck please contact the author. "# ) } pub fn e0028d() { - println!( - r#"E0028 -- A path name in a TDS zip archive must contain the package name + error!( + 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. @@ -356,8 +386,9 @@ follows: } pub fn e0029d() { - println!( - r#"E0029 -- README file: encoding with BOM detected + error!( + r#" +E0029 -- README file: encoding with BOM detected A README file should be either ASCII or UTF-8 without BOM(byte order mark) @@ -369,8 +400,9 @@ 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 + error!( + 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. @@ -379,17 +411,19 @@ directory tree. } pub fn e0031d() { - println!( - r#"E0031 -- File name contains invalid UTF-8 character(s) + error!( + r#" +E0031 -- File name contains invalid UTF-8 character(s) -A file name contains invald UTF-8 character(s). +A file name contains invalid UTF-8 character(s). "# ) } pub fn e0033d() { - println!( - r#"E0033 -- Error when unpacking tds archive + error!( + 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 @@ -399,8 +433,9 @@ reason given in the error message. } pub fn e0034d() { - println!( - r#"E0034 -- Unwanted file detected in the top level directory in TDS zip archive + error!( + 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. @@ -409,8 +444,9 @@ directories but no files. } pub fn e0035d() { - println!( - r#"E0035 -- Unwanted TDS archive detected in package directory tree + error!( + r#" +E0035 -- Unwanted TDS archive detected in package directory tree A package directory should not contain a TDS zip archive. "# @@ -418,8 +454,9 @@ 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 + error!( + 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. @@ -428,8 +465,9 @@ either of source/ or doc/ top level directories. } pub fn e0037d() { - println!( - r#"E0037 -- CR line endings detected + error!( + 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. @@ -441,8 +479,9 @@ 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 + error!( + 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. @@ -454,8 +493,9 @@ 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 + error!( + 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/. "# @@ -463,8 +503,9 @@ 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 + error!( + 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, @@ -478,8 +519,9 @@ 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 + error!( + 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/fatald.rs b/support/pkgcheck/src/messages/fatald.rs index ee02e47bde..ca81ea7d2f 100644 --- a/support/pkgcheck/src/messages/fatald.rs +++ b/support/pkgcheck/src/messages/fatald.rs @@ -1,8 +1,10 @@ // This file is generated by a Perl script. The source is // in the docs/ directory of the repository. +use log::*; + pub fn f0001d() { - println!( + error!( r#" F0001 -- Specify a directory to check (use option -d) @@ -13,17 +15,17 @@ directory } pub fn f0002d() { - println!( + error!( r#" F0002 -- Specified directory does not exist. Exiting... -The directory specified at the command line does not exit. +The directory specified at the command line does not exist. "# ) } pub fn f0003d() { - println!( + error!( r#" F0003 -- Specified TDS archive does not exist or is no file @@ -33,7 +35,7 @@ Specify a valid TDS zip archive when calling pkgcheck } pub fn f0004d() { - println!( + error!( r#" F0004 -- The file specified as TDS archive is no zip archive @@ -43,7 +45,7 @@ Specify a valid TDS zip archive when calling pkgcheck } pub fn f0005d() { - println!( + error!( r#" F0005 -- Bad file name for the zip archive @@ -54,7 +56,7 @@ with .tds.zip } pub fn f0006d() { - println!( + error!( r#" F0006 -- Unknown error code specified with option -e resp. ---explain. Exiting... @@ -65,7 +67,7 @@ code was specified. } pub fn f0007d() { - println!( + error!( r#" F0007 -- Could not create temporary directory for unzipping the TDS zip archive @@ -74,3 +76,35 @@ enough space. "# ) } + +pub fn f0008d() { + error!( + r#" +F0008 -- Config file doesn't exist. Exiting... + +The config file specified at the command line doesn't exist. +"# + ) +} + +pub fn f0009d() { + error!( + r#" +F0009 -- Error reading config file <config_file>: Exiting... + +The config file <config_file> could not be read. +"# + ) +} + +pub fn f0010d() { + error!( + r#" +F0010 -- Config file's content could no be read properly: Exiting... + +The content of the config has errors as given in . Please correct and +rerun. +"# + ) +} + diff --git a/support/pkgcheck/src/messages/informationd.rs b/support/pkgcheck/src/messages/informationd.rs index 1f1b64dcad..0eca9849a0 100644 --- a/support/pkgcheck/src/messages/informationd.rs +++ b/support/pkgcheck/src/messages/informationd.rs @@ -1,8 +1,10 @@ // This file is generated by a Perl script. The source is // in the docs/ directory of the repository. +use log::*; + pub fn i0001d() { - println!( + info!( r#" I0001 -- Successfully converted from CRLF to LF @@ -13,7 +15,7 @@ CRLF to LF line endings } pub fn i0002d() { - println!( + info!( r#" I0002 -- Checking package files in directory @@ -24,7 +26,7 @@ the unzipped directory trees } pub fn i0003d() { - println!( + info!( r#" I0003 -- Checking TDS zip archive @@ -34,7 +36,7 @@ Just an information that pkgcheck starts checking the TDS zip archive } pub fn i0004d() { - println!( + info!( r#" I0004 -- Correcting line endings for file @@ -48,9 +50,9 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#crlf } pub fn i0005d() { - println!( + info!( r#" -I0005 -- Corrections permissions for file or directory +I0005 -- Correcting permissions for file or directory pkgcheck corrects wrong permsissions for package files and directories. It runs the chmod command in verbose mode. @@ -62,7 +64,7 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#filepermissions } pub fn i0006d() { - println!( + info!( r#" I0006 -- Files having one of the following file name endings are regarded as temporary @@ -76,7 +78,7 @@ http://mirror.ctan.org/help/ctan/CTAN-upload-addendum.html#noauxfiles } pub fn i0007d() { - println!( + info!( r#" I0007 -- Successfully corrected wrong line endings to LF resp. CRLF @@ -87,3 +89,42 @@ Wrong line endings could be CR, CRLF or a mixture of line endings. "# ) } + +pub fn i0008d() { + info!( + r#" +I0008 -- Using config file + +Tells the user which config file is used. +"# + ) +} + +pub fn i0009d() { + info!( + r#" +I0009 -- Updating entry <pkgname> -> <tpkg> with <pkgname> -> <new tpkg> from config file", + +This message can only show up if pkgcheck got called with --config. It +is required that the path names in the TDS zip archive contain the +package name. There are exceptions however, and if such an exception is +defined in the config file pkgcheck reports the usage of an exception. + +Example: tex/latex/microtype/microtype-luatex.de in the TDS zip archive +microtype.tds.zip contains the package name microtype + +There are exceptions, however. + +Example: The file names in latex-amsmath.tds.zip do not contain +latex-amsmath but just latex + +These exceptions are hard-coded in pkgcheck but can be overridden in the +pkgcheck.yml config file like in the following example + + tds_path_exceptions: + - pkg: latex-amsmath + tpkg: latexnew +"# + ) +} + diff --git a/support/pkgcheck/src/messages/mod.rs b/support/pkgcheck/src/messages/mod.rs index f6819f1120..3de39bdb81 100644 --- a/support/pkgcheck/src/messages/mod.rs +++ b/support/pkgcheck/src/messages/mod.rs @@ -2,116 +2,87 @@ mod errorsd; mod fatald; mod informationd; mod warningsd; - +use colored::Colorize; use self::errorsd::*; use self::fatald::*; use self::informationd::*; use self::warningsd::*; -macro_rules! no_colors { +macro_rules! error_occurred { () => { - $crate::ARGS.no_colors + $crate::ERROR_OCCURRED.store(true, Ordering::Relaxed); }; } -macro_rules! error_occured { + +macro_rules! no_colors { () => { - $crate::ERROR_OCCURED.store(true, Ordering::Relaxed); + $crate::ARGS.no_colors }; } -// macro_rules! yellow { -// ($fmt:expr) => { -// if no_colors!() { -// $fmt.clear() -// } else { -// $fmt.bright_yellow() -// } -// }; -// } - -// macro_rules! red { -// ($fmt:expr) => { -// if no_colors!() { -// $fmt.clear() -// } else { -// $fmt.bright_red() -// } -// }; -// } -macro_rules! msgid { +macro_rules! fatal { ($fmt:expr) => { match (no_colors!(), &$fmt[..1]) { (true, _) => $fmt.clear(), - (false, "E") => $fmt.bright_red().bold(), - (false, "I") => $fmt.bright_yellow().bold(), - (false, "W") => $fmt.bright_red(), - (false, "F") => $fmt.bright_red().bold(), - (_, _) => $fmt.clear(), + (_, _) => $fmt.bright_red().bold(), } }; } macro_rules! f0001 { () => {{ - error_occured!(); - print!( - "{} Specify a directory to check (use option -d)\n", - msgid!("F0001") - ); + error_occurred!(); + eprintln!("{} Specify a directory to check (use option -d)", fatal!("F0001"),); }}; } macro_rules! f0002 { ($fmt1:expr) => {{ - error_occured!(); - print!( - "{} Specified directory {} does not exist. Exiting...\n", - msgid!("F0002"), - $fmt1 + error_occurred!(); + eprintln!( + "{} Specified directory {} does not exist. Exiting...", + fatal!("F0002"), $fmt1 ); }}; } macro_rules! f0003 { ($fmt1:expr) => {{ - error_occured!(); - print!( - "{} Specified TDS archive {} does not exist or is no file. Exiting...\n", - msgid!("F0003"), - $fmt1 + error_occurred!(); + eprintln!( + "{} Specified TDS archive {} does not exist or is no file. Exiting...", + fatal!("F0003"), $fmt1 ); }}; } macro_rules! f0004 { ($fmt1:expr) => {{ - error_occured!(); - print!( - "{} File {} specified as TDS archive is no zip archive. Exiting...\n", - msgid!("F0004"), - $fmt1 + error_occurred!(); + eprintln!( + "{} File {} specified as TDS archive is no zip archive. Exiting...", + fatal!("F0004"), $fmt1 ); }}; } macro_rules! f0005 { ($fmt1:expr) => {{ - error_occured!(); - print!( - "{} Bad filename {} for the tds.zip archive. Exiting...\n", - msgid!("F0005"), - $fmt1 + error_occurred!(); + eprintln!( + "{} Bad filename {} for the tds.zip archive. Exiting...", + fatal!("F0005"), $fmt1 ); }}; } // macro_rules! f0006 { // ($fmt1:expr) => { -// error_occured!(); -// print!( -// "{} Unknown error code `{}` specified with option -e resp. ---explain. Exiting...\n", -// msgid!("F0006"), +// error_occurred!(); +// error!( +// "{} Unknown error code `{}` specified with option -e resp. ---explain. Exiting...", +// "F0006", // $fmt1 // ); // }; @@ -119,584 +90,558 @@ macro_rules! f0005 { macro_rules! f0007 { ($fmt1:expr) => {{ - error_occured!(); - print!( - "{} Unable to create temporary directory for unzipping the TDS zip archive: {}. Exiting...\n", - msgid!("F0007"), + error_occurred!(); + eprintln!( + "{} Unable to create temporary directory for unzipping the TDS zip archive: {}. Exiting...", + fatal!("F0007"), $fmt1 ); }}; } +macro_rules! f0008 { + ($fmt:expr) => {{ + error_occurred!(); + eprintln!( + "{} Config file {} doesn't exist. Exiting...", + fatal!("F0007"), $fmt + ); + }}; +} + +macro_rules! f0009 { + ($fmt1:expr, $fmt2:expr) => {{ + error_occurred!(); + eprintln!( + "{} Error reading config file {}: {} Exiting...", + fatal!("F0009"), $fmt1, $fmt2 + ); + }}; +} + +macro_rules! f0010 { + ($fmt:expr) => {{ + error_occurred!(); + eprintln!( + "{} Config file's content could no be read properly: {} Exiting...", + fatal!("F0010"), $fmt + ); + }}; +} + macro_rules! e0001 { ($fmt1:expr, $fmt2:expr, $fmt3:expr) => {{ - error_occured!(); - print!( - "{} Bad character {} ({:#02x}) found in file name {} at offset {}\n", - msgid!("E0001"), - $fmt1, - $fmt1 as usize, - $fmt2, - $fmt3 + error_occurred!(); + error!( + "{} Bad character {} ({:#02x}) found in file name {} at offset {}", + "E0001", $fmt1, $fmt1 as usize, $fmt2, $fmt3 ); }}; } macro_rules! e0002 { ($fmt1:expr, $fmt2:expr) => {{ - error_occured!(); - print!( - "{} File {} has bad permissions: {}\n", - msgid!("E0002"), - $fmt1, - $fmt2 + error_occurred!(); + error!( + "{} File {} has bad permissions: {}", + "E0002", $fmt1, $fmt2 ); }}; } macro_rules! e0003 { ($fmt:expr) => {{ - error_occured!(); - print!("{} {} is no text file\n", msgid!("E0003"), $fmt); + error_occurred!(); + error!("{} {} is no text file", "E0003", $fmt); }}; } macro_rules! e0004 { ($fmt:expr) => {{ - error_occured!(); - print!("{} Empty directory {} detected\n", msgid!("E0004"), $fmt); + error_occurred!(); + error!("{} Empty directory {} detected", "E0004", $fmt); }}; } macro_rules! e0005 { ($fmt:expr) => {{ - error_occured!(); - print!("{} Empty file {} detected\n", msgid!("E0005"), $fmt); + error_occurred!(); + error!("{} Empty file {} detected", "E0005", $fmt); }}; } macro_rules! e0006 { ($fmt:expr) => {{ - error_occured!(); - print!("{} Hidden directory {} detected\n", msgid!("E0006"), $fmt); + error_occurred!(); + error!("{} Hidden directory {} detected", "E0006", $fmt); }}; } macro_rules! e0006t { ($fmt:expr) => {{ - error_occured!(); - print!( - "{} Hidden directory {} detected in TDS zip archive\n", - msgid!("E0006"), - $fmt + error_occurred!(); + error!( + "{} Hidden directory {} detected in TDS zip archive", + "E0006", $fmt ); }}; } macro_rules! e0007 { ($fmt:expr) => {{ - error_occured!(); - print!("{} Hidden file {} detected\n", msgid!("E0007"), $fmt); + error_occurred!(); + error!("{} Hidden file {} detected", "E0007", $fmt); }}; } macro_rules! e0007t { ($fmt:expr) => {{ - error_occured!(); - print!( - "{} Hidden file {} detected in TDS zip archive\n", - msgid!("E0007"), - $fmt + error_occurred!(); + error!( + "{} Hidden file {} detected in TDS zip archive", + "E0007", $fmt ); }}; } macro_rules! e0008 { ($fmt:expr) => {{ - error_occured!(); - print!("{} Temporary file {} detected\n", msgid!("E0008"), $fmt); + error_occurred!(); + error!("{} Temporary file {} detected", "E0008", $fmt); }}; } macro_rules! e0008t { ($fmt:expr) => {{ - error_occured!(); - print!( - "{} Temporary file {} detected in TDS zip archive\n", - msgid!("E0008"), - $fmt + error_occurred!(); + error!( + "{} Temporary file {} detected in TDS zip archive", + "E0008", $fmt ); }}; } macro_rules! e0009 { () => {{ - error_occured!(); - print!( - "{} One of README/README.md/README.txt must exist\n", - msgid!("E0009") + error_occurred!(); + error!( + "{} One of README/README.md/README.txt must exist", + "E0009", ); }}; } macro_rules! e0010 { ($fmt:expr) => {{ - error_occured!(); - print!("{} {} is a broken symlink\n", msgid!("E0010"), $fmt); + error_occurred!(); + error!("{} {} is a broken symlink", "E0010", $fmt); }}; } macro_rules! e0011 { ($fmt1:expr, $fmt2:expr) => {{ - error_occured!(); - print!( - "{} Directory {} has bad permissions: {}\n", - msgid!("E0011"), - $fmt1, - $fmt2 + error_occurred!(); + error!( + "{} Directory {} has bad permissions: {}", + "E0011", $fmt1, $fmt2 ); }}; } macro_rules! e0012 { ($fmt:expr) => {{ - error_occured!(); - print!( - "{} File {} has CRLF line endings\n", - msgid!("E0012"), - $fmt - ); + error_occurred!(); + error!("{} File {} has CRLF line endings", "E0012", $fmt); }}; } macro_rules! e0013 { ($fmt:expr) => {{ - error_occured!(); - print!("{} {} is a socket special file\n", msgid!("E0013"), $fmt); + error_occurred!(); + error!("{} {} is a socket special file", "E0013", $fmt); }}; } macro_rules! e0014 { ($fmt:expr) => {{ - error_occured!(); - print!("{} {} is a fifo file\n", msgid!("E0014"), $fmt); + error_occurred!(); + error!("{} {} is a fifo file", "E0014", $fmt); }}; } macro_rules! e0015 { ($fmt:expr) => {{ - error_occured!(); - print!("{} {} is a block device file\n", msgid!("E0015"), $fmt); + error_occurred!(); + error!("{} {} is a block device file", "E0015", $fmt); }}; } macro_rules! e0016 { ($fmt:expr) => {{ - error_occured!(); - print!( - "{} {} is a character device file\n", - msgid!("E0016"), - $fmt - ); + error_occurred!(); + error!("{} {} is a character device file", "E0016", $fmt); }}; } macro_rules! e0017 { ($fmt:expr) => {{ - error_occured!(); - print!("{} PDF error detected in {}\n", msgid!("E0017"), $fmt); + error_occurred!(); + error!("{} PDF error detected in {}", "E0017", $fmt); }}; } macro_rules! e0018 { ($fmt:expr) => {{ - error_occured!(); - print!( - "{} Unwanted directory {} detected\n", - msgid!("E0018"), - $fmt - ); + error_occurred!(); + error!("{} Unwanted directory {} detected", "E0018", $fmt); }}; } macro_rules! e0019 { ($fmt1:expr, $fmt2:expr) => {{ - error_occured!(); - print!( - "{} {} generated by {} exists\n", - msgid!("E0019"), - $fmt1, - $fmt2 - ); + error_occurred!(); + error!("{} {} generated by {} exists", "E0019", $fmt1, $fmt2); }}; } macro_rules! e0020 { ($fmt:expr) => {{ - error_occured!(); - print!( - "{} Unwanted directory `{}` detected in the top level directory of a TDS archive\n", - msgid!("E0020"), - $fmt + error_occurred!(); + error!( + "{} Unwanted directory `{}` detected in the top level directory of a TDS archive", + "E0020", $fmt ); }}; } macro_rules! e0021 { ($fmt1:expr, $fmt2:expr, $fmt3:expr) => {{ - error_occured!(); - print!( - "{} File {} : Error reading in line {}: {}\n", - msgid!("E0021"), - $fmt1, - $fmt2, - $fmt3 + error_occurred!(); + error!( + "{} File {} : Error reading in line {}: {}", + "E0021", $fmt1, $fmt2, $fmt3 ); }}; } macro_rules! e0022 { ($fmt1:expr, $fmt2:expr) => {{ - error_occured!(); - print!("{} {}: `{}`\n", msgid!("E0022"), $fmt1, $fmt2); + error_occurred!(); + error!("{} {}: `{}`", "E0022", $fmt1, $fmt2); }}; } macro_rules! e0023 { ($fmt:expr) => {{ - error_occured!(); - print!("{} {}\n", msgid!("E0023"), $fmt); + error_occurred!(); + error!("{} {}", "E0023", $fmt); }}; } macro_rules! e0024 { ($fmt1:expr, $fmt2:expr) => {{ - error_occured!(); - print!( - "{} The TDS zip archive {} has bad permissions: {}\n", - msgid!("E0024"), - $fmt1, - $fmt2 + error_occurred!(); + error!( + "{} The TDS zip archive {} has bad permissions: {}", + "E0024", $fmt1, $fmt2 ); }}; } macro_rules! e0025 { ($fmt:expr) => {{ - error_occured!(); - print!( - "{} Duplicate names when ignoring letter case for: {}\n", - msgid!("E0025"), - $fmt + error_occurred!(); + error!( + "{} Duplicate names when ignoring letter case for: {}", + "E0025", $fmt ); }}; } macro_rules! e0026 { ($fmt:expr) => {{ - error_occured!(); - print!( - "{} {} : file not in TDS or different in TDS and non-install tree\n", - msgid!("E0026"), - $fmt + error_occurred!(); + error!( + "{} {} : file not in TDS or different in TDS and non-install tree", + "E0026", $fmt ); }}; } macro_rules! e0027 { ($fmt1:expr, $fmt2:expr) => {{ - error_occured!(); - print!( - "{} {}: An I/O error occured -> {}\n", - msgid!("E0027"), - $fmt1, - $fmt2 - ); + error_occurred!(); + error!("{} {}: An I/O error occurred -> {}", "E0027", $fmt1, $fmt2); }}; } macro_rules! e0028 { ($fmt1:expr, $fmt2:expr) => {{ - error_occured!(); - print!( - "{} No directory {} (= package name) found in path {}\n", - msgid!("E0028"), - $fmt1, - $fmt2 + error_occurred!(); + error!( + "{} No directory {} (= package name) found in path {}", + "E0028", $fmt1, $fmt2 ); }}; } macro_rules! e0029 { ($fmt1:expr, $fmt2:expr) => {{ - error_occured!(); - print!( - "{} {}: {} encoding with BOM detected\n", - msgid!("E0029"), - $fmt1, - $fmt2 + error_occurred!(); + error!( + "{} {}: {} encoding with BOM detected", + "E0029", $fmt1, $fmt2 ); }}; } macro_rules! e0030 { ($fmt1:expr, $fmt2:expr) => {{ - error_occured!(); - print!( - "{} Symlink {} points to {} which is outside of the package directory tree\n", - msgid!("E0030"), - $fmt1, - $fmt2 + error_occurred!(); + error!( + "{} Symlink {} points to {} which is outside of the package directory tree", + "E0030", $fmt1, $fmt2 ); }}; } macro_rules! e0031 { ($fmt:expr) => {{ - error_occured!(); - print!( - "{} File name {} contains invalid UTF-8 character(s)\n", - msgid!("E0031"), - $fmt + error_occurred!(); + error!( + "{} File name {} contains invalid UTF-8 character(s)", + "E0031", $fmt ); }}; } macro_rules! e0033 { ($fmt1:expr, $fmt2:expr) => {{ - error_occured!(); - print!( - "{} Error `{}` when unpacking tds archive {}. Exiting...\n", - msgid!("E0033"), - $fmt2, - $fmt1 + error_occurred!(); + error!( + "{} Error `{}` when unpacking tds archive {}. Exiting...", + "E0033", $fmt2, $fmt1 ); }}; } macro_rules! e0034 { ($fmt:expr) => {{ - error_occured!(); - print!( - "{} Unwanted file `{}` detected in the top level directory of a TDS archive\n", - msgid!("E0034"), - $fmt + error_occurred!(); + error!( + "{} Unwanted file `{}` detected in the top level directory of a TDS archive", + "E0034", $fmt ); }}; } macro_rules! e0035 { ($fmt:expr) => {{ - error_occured!(); - print!( - "{} Unwanted TDS archive `{}` detected in package directory tree\n", - msgid!("E0035"), - $fmt + error_occurred!(); + error!( + "{} Unwanted TDS archive `{}` detected in package directory tree", + "E0035", $fmt ); }}; } macro_rules! e0036 { ($fmt:expr) => {{ - error_occured!(); - print!( - "{} File `{}` not below `source/` or `doc/` top level directory in TDS zip archive\n", - msgid!("E0036"), - $fmt + error_occurred!(); + error!( + "{} File `{}` not below `source/` or `doc/` top level directory in TDS zip archive", + "E0036", $fmt ); }}; } macro_rules! e0037 { ($fmt:expr) => {{ - error_occured!(); - print!("{} File {} has CR line endings\n", msgid!("E0037"), $fmt); + error_occurred!(); + error!("{} File {} has CR line endings", "E0037", $fmt); }}; } 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 + error_occurred!(); + error!( + "{} File {} has inconsistent line endings: CR={}, LF={}, CRLF={}", + "E0038", $fmt1, $fmt2, $fmt3, $fmt4 ); }}; } macro_rules! e0039 { () => {{ - error_occured!(); - print!("{} No doc/ directory found\n", msgid!("E0039")); + error_occurred!(); + error!("{} No doc/ directory found", "E0039"); }}; } macro_rules! e0040 { () => {{ - error_occured!(); - print!( - "{} Too few top level directories in the TDS zip archive\n", - msgid!("E0040") + error_occurred!(); + error!( + "{} Too few top level directories in the TDS zip archive", + "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")); + error_occurred!(); + error!("{} One or more map file found for the package but none of them is in a path starting with fonts/map/dvips", "E0041"); }}; } + macro_rules! w0001 { ($fmt:expr) => {{ - print!( - "{} Archive as package file detected: {}\n", - msgid!("W0001"), - $fmt - ); + warn!("{} Archive as package file detected: {}", "W0001", $fmt); }}; } macro_rules! w0002 { () => {{ - print!("{} Duplicate files detected\n", msgid!("W0002"),); + warn!("{} Duplicate files detected", "W0002",); }}; } macro_rules! w0003 { ($fmt:expr) => {{ - error_occured!(); - print!( - "{} Same named files detected in the package directory tree: {}\n", - msgid!("W0003"), - $fmt + error_occurred!(); + warn!( + "{} Same named files detected in the package directory tree: {}", + "W0003", $fmt ); }}; } macro_rules! w0004 { ($fmt1:expr, $fmt2:expr) => {{ - error_occured!(); - print!( - "{} {}: {} encoding with BOM detected\n", - msgid!("W0004"), - $fmt1, - $fmt2 + error_occurred!(); + warn!( + "{} {}: {} encoding with BOM detected", + "W0004", $fmt1, $fmt2 ); }}; } macro_rules! w0005 { ($fmt1:expr, $fmt2:expr) => {{ - error_occured!(); - print!( - "{} Very large file {} with size {}MiB detected\n", - msgid!("W0005"), - $fmt1, - $fmt2 + error_occurred!(); + warn!( + "{} Very large file {} with size {}MiB detected", + "W0005", $fmt1, $fmt2 ) }}; } macro_rules! w0006 { ($fmt1:expr, $fmt2:expr) => {{ - error_occured!(); - print!( - "{} Very large file {} with size {}MiB detected in TDS zip archive\n", - msgid!("W0006"), - $fmt1, - $fmt2 + error_occurred!(); + warn!( + "{} Very large file {} with size {}MiB detected in TDS zip archive", + "W0006", $fmt1, $fmt2 ) }}; } macro_rules! w0007 { ($fmt:expr) => {{ - error_occured!(); - print!( - "{} Empty directory {} detected in TDS zip archive\n", - msgid!("W0007"), - $fmt + error_occurred!(); + warn!( + "{} Empty directory {} detected in TDS zip archive", + "W0007", $fmt ); }}; } macro_rules! w0008 { ($fmt:expr) => {{ - error_occured!(); - print!( - "{} Windows file {} has Unix line endings\n", - msgid!("W0008"), - $fmt - ); + error_occurred!(); + warn!("{} Windows file {} has Unix line endings", "W0008", $fmt); }}; } +macro_rules! w0009 { + ($fmt1:expr, $fmt2:expr) => {{ + error_occurred!(); + warn!( + "{} Replacing `{} -> {}` with the same from config file", + "W0009", + $fmt1, + $fmt2 + ) + }}; +} + + macro_rules! i0002 { ($fmt:expr) => {{ - print!( - "{} {} {}\n", - msgid!("I0002"), - "Checking package files in directory", - $fmt + info!( + "{} {} {}", + "I0002", "Checking package files in directory", $fmt ); }}; } macro_rules! i0003 { ($fmt:expr) => {{ - print!( - "{} {} {}\n", - msgid!("I0003"), - "Checking TDS zip archive", - $fmt - ); + info!("{} {} {}", "I0003", "Checking TDS zip archive", $fmt); }}; } macro_rules! i0004 { ($fmt:expr) => {{ - print!( - "{} Correcting line endings for file {}\n", - msgid!("I0004"), - $fmt - ); + info!("{} Correcting line endings for file {}", "I0004", $fmt); }}; } macro_rules! i0005 { ($fmt:expr) => {{ - print!( - "{} Correcting permissions for {}\n", - msgid!("I0005"), - $fmt - ); + info!("{} Correcting permissions for {}", "I0005", $fmt); }}; } macro_rules! i0006 { () => {{ - print!( - "{} Files having one of the following file name endings are regarded as temporary\n", - msgid!("I0006") + info!( + "{} Files having one of the following file name endings are regarded as temporary", + "I0006", ); }}; } macro_rules! i0007 { ($fmt1:expr, $fmt2:expr) => {{ - print!( - "{} {}: Successfully corrected wrong line endings to {}\n", - msgid!("I0007"), - $fmt1, - $fmt2 + info!( + "{} {}: Successfully corrected wrong line endings to {}", + "I0007", $fmt1, $fmt2 ); }}; } +macro_rules! i0008 { + ($fmt1:expr) => {{ + info!("{} Using config file {}", "I0008", $fmt1); + }}; +} + +macro_rules! i0009 { + ($fmt1:expr, $fmt2:expr, $fmt3:expr) => {{ + error_occurred!(); + warn!( + "{} Updating entry `{} -> {}` with `{} -> {}` from config file", + "I0009", + $fmt1, + $fmt2, + $fmt1, + $fmt3 + ) + }}; +} + pub fn explains(err: &str) { let err_upp = err.to_ascii_uppercase(); match err_upp.as_str() { @@ -707,6 +652,9 @@ pub fn explains(err: &str) { "F0005" => f0005d(), "F0006" => f0006d(), "F0007" => f0007d(), + "F0008" => f0008d(), + "F0009" => f0009d(), + "F0010" => f0010d(), "E0001" => e0001d(), "E0002" => e0002d(), @@ -757,6 +705,8 @@ pub fn explains(err: &str) { "I0005" => i0005d(), "I0006" => i0006d(), "I0007" => i0007d(), + "I0008" => i0008d(), + "I0009" => i0009d(), "W0001" => w0001d(), "W0002" => w0002d(), @@ -766,9 +716,11 @@ pub fn explains(err: &str) { "W0006" => w0006d(), "W0007" => w0007d(), "W0008" => w0008d(), + "W0009" => w0009d(), - e => println!( - "F0006 Unknown error code `{}` specified with option -e resp. --explain. Exiting...", + e => eprintln!( + "{} Unknown error code `{}` specified with option -e resp. --explain. Exiting...", + fatal!("F0006"), e ), } @@ -781,6 +733,11 @@ pub fn explains_all() { explains("F0004"); explains("F0005"); explains("F0006"); + explains("F0006"); + explains("F0007"); + explains("F0008"); + explains("F0009"); + explains("F0010"); explains("E0001"); explains("E0002"); @@ -830,6 +787,8 @@ pub fn explains_all() { explains("I0005"); explains("I0006"); explains("I0007"); + explains("I0008"); + explains("I0009"); explains("W0001"); explains("W0002"); @@ -839,4 +798,5 @@ pub fn explains_all() { explains("W0006"); explains("W0007"); explains("W0008"); + explains("W0009"); } diff --git a/support/pkgcheck/src/messages/warningsd.rs b/support/pkgcheck/src/messages/warningsd.rs index 7358cc562e..44a6ad6d4e 100644 --- a/support/pkgcheck/src/messages/warningsd.rs +++ b/support/pkgcheck/src/messages/warningsd.rs @@ -1,8 +1,10 @@ // This file is generated by a Perl script. The source is // in the docs/ directory of the repository. +use log::*; + pub fn w0001d() { - println!( + warn!( r#" W0001 -- Archive as package file detected @@ -14,7 +16,7 @@ separate zip archive. } pub fn w0002d() { - println!( + warn!( r#" W0002 -- Duplicate files detected @@ -27,7 +29,7 @@ seen as an error in general. } pub fn w0003d() { - println!( + warn!( r#" W0003 -- Same named files detected in the package tree @@ -43,7 +45,7 @@ http://mirror.utexas.edu/ctan/help/ctan/CTAN-upload-addendum.html#uniquefilename } pub fn w0004d() { - println!( + warn!( r#" W0004 -- encoding with BOM detected @@ -57,7 +59,7 @@ that in some future time this could be reagarded as an error. } pub fn w0005d() { - println!( + warn!( r#" W0005 -- Very large file with size <size> detected in package @@ -68,7 +70,7 @@ W0005 -- Very large file with size <size> detected in package } pub fn w0006d() { - println!( + warn!( r#" W0006 -- Very large file with size <size> detected in TDS zip archive @@ -79,7 +81,7 @@ in the TDS zip archive. } pub fn w0007d() { - println!( + warn!( r#" W0007 -- Empty directory detected in the TDS zip archive @@ -90,7 +92,7 @@ don't create errors in the distribution we issue a warning only. } pub fn w0008d() { - println!( + warn!( r#" W0008 -- Windows file has Unix line endings @@ -105,3 +107,16 @@ We regard a file as a Windows file if its name ends with: "# ) } + +pub fn w0009d() { + warn!( + r#" +W0009 -- Replacing -> ` with the same from config file", + +This message can only show up if pkgcheck got called with --config. +Indicates that an entry in the pkgcheck config file does the same as the +hard-coded entry. This helps to keep a clean config file. +"# + ) +} + diff --git a/support/pkgcheck/src/recode.rs b/support/pkgcheck/src/recode.rs index 9a6b3d426d..efb8b932b6 100644 --- a/support/pkgcheck/src/recode.rs +++ b/support/pkgcheck/src/recode.rs @@ -57,11 +57,8 @@ impl Iterator for Bytes { pub fn wrong_line_endings2crlf(fname: &str) -> Result<(), io::Error> { let path = Path::new(fname); - let mut hdl_in; - match File::open(path) { - Ok(f) => { - hdl_in = f; - } + let mut hdl_in = match File::open(path) { + Ok(f) => f, Err(e) => return Err(e), }; let mut buffer: Vec<u8> = Vec::new(); @@ -73,11 +70,8 @@ pub fn wrong_line_endings2crlf(fname: &str) -> Result<(), io::Error> { let another_vec: Vec<u8> = fix_line_endings2crlf(&buffer); - let mut hdl_out; - match File::create(path) { - Ok(f) => { - hdl_out = f; - } + let mut hdl_out = match File::create(path) { + Ok(f) => f, Err(e) => return Err(e), }; @@ -93,11 +87,8 @@ pub fn wrong_line_endings2crlf(fname: &str) -> Result<(), io::Error> { pub fn wrong_line_endings2lf(fname: &str) -> Result<(), io::Error> { let path = Path::new(fname); - let mut hdl_in; - match File::open(path) { - Ok(f) => { - hdl_in = f; - } + let mut hdl_in = match File::open(path) { + Ok(f) => f, Err(e) => return Err(e), }; let mut buffer: Vec<u8> = Vec::new(); @@ -109,11 +100,8 @@ pub fn wrong_line_endings2lf(fname: &str) -> Result<(), io::Error> { let another_vec: Vec<u8> = fix_line_endings2lf(&buffer); - let mut hdl_out; - match File::create(path) { - Ok(f) => { - hdl_out = f; - } + let mut hdl_out = match File::create(path) { + Ok(f) => f, Err(e) => return Err(e), }; diff --git a/support/pkgcheck/src/utils.rs b/support/pkgcheck/src/utils.rs index 860b8c223b..b311453b66 100644 --- a/support/pkgcheck/src/utils.rs +++ b/support/pkgcheck/src/utils.rs @@ -1,3 +1,5 @@ +use log::*; + use std::fs::read_dir; use std::fs::read_link; use std::os::unix::fs::PermissionsExt; @@ -5,18 +7,17 @@ use std::path::Path; use std::path::PathBuf; use walkdir::DirEntry; +use once_cell::sync::Lazy; // 1.3.1 use regex::Regex; use std::borrow::Cow; use std::io; +use std::fs::File; use std::process::Command; - -use colored::*; +use zip::result::ZipResult; use std::sync::atomic::Ordering; use std::fs; -use zip_extensions::*; - #[derive(Debug, Clone, PartialEq, Eq)] pub enum CheckType { Tds, @@ -51,44 +52,28 @@ impl Utils { true } + // we check for the "good" characters, all other characters yield an + // error message pub fn filename_has_bad_chars(&self, entry: &DirEntry, dir_entry_str: &str) { let s = entry.file_name().to_str().unwrap(); - for (i, c) in s.char_indices() { match c { - '\x00'..='\x1f' => { - e0001!(c, dir_entry_str, i); - } - ' ' | '!' | '"' | '#' | '$' | '%' | '&' | '\'' => { - e0001!(c, dir_entry_str, i); - } - '(' | ')' | '*' => { - e0001!(c, dir_entry_str, i); - } - '+' | ',' | '-' | '.' => (), - '0'..='9' => (), - ':' | ';' | '<' | '=' | '>' | '?' | '@' => { - e0001!(c, dir_entry_str, i); - } - 'A'..='Z' => (), - '[' | '\\' | ']' | '^' => { - e0001!(c, dir_entry_str, i); - } - '_' => (), - '`' => { - e0001!(c, dir_entry_str, i); - } - 'a'..='z' => (), - '{' | '|' | '}' | '~' => { - e0001!(c, dir_entry_str, i); - } - '/' => return, + 'A'..='Z' + | '0'..='9' + | 'a'..='z' + | '+' + | ',' + | '-' + | '.' + | '/' + | ':' + | '=' + | '@' + | '_' => (), _ => { - return { - e0001!(c, dir_entry_str, i); - } + e0001!(c, dir_entry_str, i); } - }; + } } } @@ -136,9 +121,8 @@ impl Utils { } pub fn check_for_temporary_file(&self, dir_entry_str: &str) { - lazy_static! { - static ref RE: Regex = regex_temporary_file_endings(); - } + + static RE: Lazy<Regex> = Lazy::new(regex_temporary_file_endings); if RE.is_match(dir_entry_str) { match self.kind { @@ -177,11 +161,18 @@ impl Utils { } } - pub fn unzip(&self, zip_archive: &str, out_dir: &str) -> zip::result::ZipResult<()> { + // just copied from zip-extensions-rs + pub fn zip_extract(archive_file: &Path, target_dir: &Path) -> ZipResult<()> { + let file = File::open(archive_file)?; + let mut archive = zip::ZipArchive::new(file)?; + archive.extract(target_dir) + } + + pub fn unzip(&self, zip_archive: &str, out_dir: &str) -> ZipResult<()> { let archive_file = PathBuf::from(zip_archive); - let target_dir = PathBuf::from(out_dir); + let target_dir = PathBuf::from(out_dir); - zip_extract(&archive_file, &target_dir) + Utils::zip_extract(&archive_file, &target_dir) } } @@ -281,7 +272,9 @@ pub fn temp_file_endings() -> Vec<(String, String)> { // ( ".lyx~", "LyX related backup file" ), ]; - v.into_iter().map(|(i, j)| (i.to_string(), j.to_string())).collect() + v.into_iter() + .map(|(i, j)| (i.to_string(), j.to_string())) + .collect() } pub fn regex_temporary_file_endings() -> Regex { @@ -408,8 +401,8 @@ fn owner_match(p: u32, m: u32) -> bool { } // Formats a permission value to octal for output -pub fn perms_to_string(p: u32) -> String { - format!("{:04o}", p & 0o7777) +pub fn perms_to_string(p: u32) -> Cow<'static, str> { + format!("{:04o}", p & 0o7777).into() } pub struct CmdReturn { @@ -470,7 +463,7 @@ pub fn dirname(entry: &str) -> Option<&str> { if entry.len() == 1 { return Some(entry); } - return Some(stripped) + return Some(stripped); } let pos = entry.rfind('/'); |