From c8388f2f2a7db78c1cb5f9d4f3c8fbde11067285 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 16 Feb 2015 22:14:11 +0000 Subject: ctan_chk (16feb15) git-svn-id: svn://tug.org/texlive/trunk@36299 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/support/ctan_chk/README | 36 ++ .../texmf-dist/doc/support/ctan_chk/ctan_chk.gawk | 227 ++++++++ .../texmf-dist/doc/support/ctan_chk/ctan_chk.pdf | Bin 0 -> 215201 bytes Master/texmf-dist/doc/support/ctan_chk/ctan_chk.w | 648 +++++++++++++++++++++ .../texmf-dist/doc/support/ctan_chk/ctan_chk_bash | 28 + Master/tlpkg/bin/tlpkg-ctan-check | 2 +- Master/tlpkg/tlpsrc/collection-binextra.tlpsrc | 1 + Master/tlpkg/tlpsrc/ctan_chk.tlpsrc | 0 8 files changed, 941 insertions(+), 1 deletion(-) create mode 100644 Master/texmf-dist/doc/support/ctan_chk/README create mode 100644 Master/texmf-dist/doc/support/ctan_chk/ctan_chk.gawk create mode 100644 Master/texmf-dist/doc/support/ctan_chk/ctan_chk.pdf create mode 100644 Master/texmf-dist/doc/support/ctan_chk/ctan_chk.w create mode 100755 Master/texmf-dist/doc/support/ctan_chk/ctan_chk_bash create mode 100644 Master/tlpkg/tlpsrc/ctan_chk.tlpsrc (limited to 'Master') diff --git a/Master/texmf-dist/doc/support/ctan_chk/README b/Master/texmf-dist/doc/support/ctan_chk/README new file mode 100644 index 00000000000..30620a61d6d --- /dev/null +++ b/Master/texmf-dist/doc/support/ctan_chk/README @@ -0,0 +1,36 @@ + +Project: Ctan guidelines verifier and corrector program for uploading projects +Distributed under license: GNU General Public License (version 3). +Distribution Date: 15 Feb. 2015 +Distribution version: 1.0 +Comments: Currently for the Unix flavoured Platforms running Gawk +Author: Dave Bone + +Contributors list: + Dave Bone + + +Basic Gawk program that uses Ctan's published guidelines for authors to help eliminate slopiness in uploaded files/project. +It is completely open for users to program additional guidelines and Ctan's future adjustments. +The program came about when I first attempted to upload ``Yacco2'' for Ctan consideration. +As Yacco2 was quite large, it took me 3 attempts to clean up my project. +Depending on how u develop your project, in my case the Yacco2 project for Ctan upload is a subset of the complete system +and so each uplift required the guideline assessment/purging process. + +This is my attempt to help both the author in getting the new system in shape for Ctan uplift +and to lower the Ctan volanteers interaction to aid in publishing on their servers. +It is my thank you to these volanteers / Ctan. + +1) License. +ctan_chk's distributed source code is subject to the terms of the GNU General Public License (version 3). +If a copy of the MPL was not distributed with this file, you can obtain one at https://gnu.org/licenses/gpl.html. + +2) Ctan_chk reference. +Unzip the ctan_chk.zip file. +Please read ctan_chk.pdf document. It instructs one in ``how to'' use the gawk ctan_chk.gawk program. + +3) Literate Programming. +ctan_chk.pdf is generated by Cweb system. Please consider using Cweb and to join +``www.tug.org''. + + diff --git a/Master/texmf-dist/doc/support/ctan_chk/ctan_chk.gawk b/Master/texmf-dist/doc/support/ctan_chk/ctan_chk.gawk new file mode 100644 index 00000000000..805f5ab82bb --- /dev/null +++ b/Master/texmf-dist/doc/support/ctan_chk/ctan_chk.gawk @@ -0,0 +1,227 @@ +# section no34:*/ +# section no12:*/ +# +# Program: ctan_chk.gawk +# +# Author: Dave Bone +# +# License: +# This Source Code Form is subject to the terms of the GNU General Public License (version 3). +# If a copy of the MPL was not distributed with this file, +# You can obtain one at: "https://gnu.org/licenses/gpl.html". +# +# Purpose: Implementation of some suggested CTAN guidelines that an upload project should respect. +# Correction functions help u cleanup the droppings. +# See www.ctan.org website for "upload guideline" document +# Read ctan_chk.pdf document describing the program with various run scenarios. +# +# +# section no:12*/ +# section no14:*/ +function is_file_a_directory(filename,filetype) +{ +x= "file \"%s\""; +y= sprintf(x,filename); +y|getline a; +close(y); +split(a,parts); +filetype[1]= parts[2]; +xx= parts[2]; +str= "^directory$"; +if(xx~str){ +return 1; +} +return 0; +} +# section no:14*/ +# section no15:*/ +function is_file_an_executable(filename,filetype) +{ +x= "file %s"; +y= sprintf(x,filename); +y|getline a; +close(y); +split(a,parts); +filetype[1]= parts[2]; +xx= parts[2]; +str= "(executable|POSIX|Mach-O|ELF)$"; +if(xx~str){ +return 1; +} +return 0; +} +# section no:15*/ +# section no17:*/ +function chk_auxiliary_files(filename) +{ +if(is_file_a_directory(filename)==1) +return 0; +str= "\\.(ps|gitignore|git|aux|log|bbl|bcf|blg|brf|ilg|ind|idx|glo|loa|lof|lot|nav|out|snm|vrb|toc|dvi|glg|gls|tmp|o|bak|mpx|scn|toc)$"; +if(filename~str){ +a= "\"%s\" 'Auxilary file to be deleted'"; +b= sprintf(a,filename); +print b; +#delete_file(filename); +return 1; +} +return 0; +} +# section no:17*/ +# section no25:*/ +function remove_file_s_extended_attributes(filename,message) +{ +x= "echo %s\";xattr -c %s"; +y= sprintf(x,message,filename); +print y; +#y|getline a; +#close(y); +} +# section no:25*/ +# section no21:*/ +function chk_file_permissions(filename) +{ +filetype[1]= ""; +if(is_file_a_directory(filename,filetype)==1) +return 0; +if(is_file_an_executable(filename,filetype)==1) +return 0; +x= "ls -al \"%s\""; +y= sprintf(x,filename); +y|getline a; +close(y); +number_fields= split(a,parts); +str= "x"; +if(parts[1]~str){ +a= "\"%s\" 'Write permissions %s to possibly delete file type: %s'"; +b= sprintf(a,filename,parts[1],filetype[1]); +print b; +return 1; +} +return 0; +} +# section no:21*/ +# section no18:*/ +function chk_extended_file_attributes(filename) +{ +x= "ls -al \"%s\""; +y= sprintf(x,filename); +y|getline a; +close(y); +number_of_fields= split(a,parts); +if(number_of_fields<9) +return 0; +xx= parts[1]; +str= "(@|+)$"; +if(xx!~str){ +return 0; +} +a= "\"%s\" 'Extended attributes %s'"; +b= sprintf(a,filename,parts[1]); +print b; +#remove_file_s_extended_attributes(filename,b); +return 1; +} +# section no:18*/ +# section no19:*/ +function chk_empty_files(filename) +{ +if(is_file_a_directory(filename)==1) +return 0; +x= "ls -al \"%s\""; +y= sprintf(x,filename); +y|getline a; +close(y); +number_of_fields= split(a,parts); +if(number_of_fields<9) +{ +print"ERROR ===> ls -al should be 9 fields and it isn't: "a" no fields: "number_of_fields; +return 0; +} +i= strtonum(parts[5]); +if(i> 0){ +return 0; +} +a= "\"%s\" 'Empty file to be deleted'"; +b= sprintf(a,filename); +print b; +#delete_file(filename); +return 1; +} +# section no:19*/ +# section no20:*/ +function chk_empty_directory(filename) +{ +if(is_file_a_directory(filename)==0) +return 0; +x= "du -sk \"%s\""; +y= sprintf(x,filename); +y|getline a; +close(y); +number_of_fields= split(a,parts); +i= strtonum(parts[1]); +if(i> 0) +return 0; +a= "\"%s\" 'Empty directory to be deleted or needs to add info.txt file inside it'"; +b= sprintf(a,filename); +print b; +return 1; +} +# section no:20*/ +# section no26:*/ +function delete_file(filename) +{ +x= "rm -i \"%s\""; +y= sprintf(x,filename); +y|getline a; +close(y); +} +# section no:26*/ +# section no22:*/ +function chk_file_to_bypass_in_zip(filename) +{ +str= ".(DS_Store|.nbattrs)$"; +if(filename~str){ +a= "\"%s\" 'Bypass file in zip'"; +b= sprintf(a,filename); +print b; +return 1; +} +return 0; +} +# section no:22*/ +# section no28:*/ +function pass1_guidelines_verify(filename) +{ +chk_auxiliary_files(filename); +chk_extended_file_attributes(filename); +chk_empty_files(filename); +chk_empty_directory(filename); +chk_file_permissions(filename); +chk_file_to_bypass_in_zip(filename); +} +# section no:28*/ +# section no29:*/ +function pass2_correct(filename,message) +{ +#remove_file_s_execute_attribute(filename,message); +#remove_file_s_extended_attributes(filename,message); +#delete_file(filename); +} +# section no:29*/ +# section no31:*/ +BEGIN{ +rec_cnt= 0; +} +# section no:31*/ +# section no32:*/ +{ +pass1_guidelines_verify($1); +#pass2_correct($1,$2); +} +# section no:32*/ +# section no33:*/ +END{ +#print "no records read: " NR; +} +# section no:33*/ +# section no:34*/ diff --git a/Master/texmf-dist/doc/support/ctan_chk/ctan_chk.pdf b/Master/texmf-dist/doc/support/ctan_chk/ctan_chk.pdf new file mode 100644 index 00000000000..e99c6671bcf Binary files /dev/null and b/Master/texmf-dist/doc/support/ctan_chk/ctan_chk.pdf differ diff --git a/Master/texmf-dist/doc/support/ctan_chk/ctan_chk.w b/Master/texmf-dist/doc/support/ctan_chk/ctan_chk.w new file mode 100644 index 00000000000..b00475c73d6 --- /dev/null +++ b/Master/texmf-dist/doc/support/ctan_chk/ctan_chk.w @@ -0,0 +1,648 @@ +% file: ctan_chk.w +% +\def\Tex{\TeX} +\def\cweb{\Cweb} +\def\Cweb{{\prgstyle Cweb}} +\def\prgstyle{\tt \sl } +\def\NOsign{ + {\tt{\char`\#}} +} +\def\Verticalbar{{\tt \char`|}} +\def\GTsign{ +\ifmmode + > +\else +$>$ +\fi +} +\def\Arrow{$\Rightarrow$} +\def\prtobrace{$\{$} +\def\prtcbrace{$\}$} +\def\Backslash{ +{\tt\char`\\} +} + +\def\printlistinglineno{\hskip .7 in \llap{\the\lineno:\quad}} +\def\ptindent#1{\line{\hskip.5in{#1}\hfill}} +\def\Yacco2{Ya$c_2o_2$} +\def\yacco2{\Yacco2} +\def\O2{$O_2$} +\def\o2{\O2} +\def\Cpp{C\kern-.25em \raise.25ex\hbox{\tt $+\kern-0.2ex+$}} +\def\Olinker{$O_{2}^{linker}$} +\def\olinker{$O_{2}^{linker}$} +\def\TILDE{\catcode`\~=11{}~} +\def\INDENT#1#2{\line{\hskip#1{#2}\hfill}} +\def\fbreak{\hfill\break} + + +@* Gawk program |ctan_chk.gawk|.\fbreak +Basic Gawk program that uses Ctan's published guidelines for authors to help eliminate slopiness in uploaded files/project. +It is completely open for users to program additional guidelines and Ctan's future adjustments. +The program came about when I first attempted to upload ``Yacco2'' for Ctan consideration. +As Yacco2 was quite large, it took me 3 attempts to clean up my project. +Depending on how u develop your project, in my case the Yacco2 project for Ctan upload is a subset of the complete system +and so each uplift required the guideline assessment/purging process. + +This is my attempt to help both the author in getting the new system in shape for Ctan uplift +and to lower the Ctan volanteers interaction to aid for publishing on their servers. +It is my thank you to these volanteers / Ctan. +\fbreak +\fbreak +This |gawk| program verifies whether an upload project for CTAN +follows its published guidelines on their website:\fbreak +\ptindent{http://ctan.org/upload/} +\fbreak +Here is the link to the awk/gawk reference manual for people needing a refresher to its programming statements:\fbreak +\ptindent{https://www.gnu.org/software/gawk/manual/gawk.html\#Reading-Files} + +@*1 License.\fbreak +ctan\_chk's distributed source code is subject to the terms of the GNU General Public License (version 3). +If a copy of the MPL was not distributed with this file, you can obtain one at https://gnu.org/licenses/gpl.html. +\fbreak +\fbreak +\ptindent{Project: ctan guidelines verifier and corrector program for uploading projects} +\ptindent{Distributed under license: GNU General Public License (version 3).} +\ptindent{Distribution Date: \today} +\ptindent{Distribution version: 1.0} +\ptindent{Comments: Currently for the Unix flavoured Platforms running Gawk} +\ptindent{Author: Dave Bone} +\fbreak +\ptindent{Contributors list:} +\ptindent{ Dave Bone} + +@*2 |Ctan_chk| reference.\fbreak +Unzip the |ctan_chk.zip| file. +Please read |ctan_chk.pdf| document. It instructs one in ``how to'' use the gawk |ctan_chk.gawk| program. + +@*2 Literate Programming genre.\fbreak +|ctan_chk.pdf| user manual and |ctan_chk.gawk| program are generated by the Cweb system's +{\it{cweave}} and {\it{ctangle}} programs along with the {\it{pdftex}}. +The |ctan_chk_bash| script does it all for u; have a read it doesn't bite. +Please consider using Cweb and joining +``www.tug.org'' where u'll find the Cweb system. + +@*1 Comments on program's functions.\fbreak +Normally u edit the |ctan_chk.gawk| file (using gawk comments) as to what "verification function" is called to check out your project's files. +Here is a list of the verification functions to call:\fbreak +Helper functions:\fbreak +\ptindent{|is_file_a_directory| --- is file a directory type rather than a data type?} +\ptindent{|is_file_an_executable| --- Maybe too platform dependent: is it an executable} +\fbreak +Verification functions:\fbreak +\ptindent{|chk_auxiliary_files| --- files that should be removed / deleted} +\ptindent{|chk_file_permissions| --- file execute permissions check} +\ptindent{|chk_extended_file_attributes| --- does file have extended attribute like @@} +\ptindent{|chk_empty_files| --- zero byte size file?} +\ptindent{|chk_empty_directory| --- empty folder} +\ptindent{|chk_file_to_bypass_in_zip| --- file to bypass by zip using its -x option} +\fbreak +Correction functions:\fbreak +\ptindent{|remove_file_s_execute_attribute| --- Read ``Remove file's execute attribute'' section for details} +\ptindent{|delete_file| --- interacts with user. Used by itself or from other functions like |chk_auxiliary_files|} +\ptindent{|remove_file_s_extended_attributes| --- Remove extended attribute from file (platform dependent)} + +@*2 Running Gawk program has 2 run/pass attitude.\fbreak +U run this program twice with appropriate editing sessions inbetween the run passes:\fbreak +\ptindent{run Pass 1 function where your edited functions to call and capturing output with {\it{tee}} utility} +\ptindent{\Arrow{} pass 1's input file is an absolute pathed files list. See |How to use this gawk program| section} +\ptindent{\Arrow{} assess the messages outputted as to what guidelines need to be corrected} +\ptindent{\Arrow{} outputted messages have 2 parts: part 1 the filename and part 2 the quoted message} +\fbreak +\ptindent{run Pass 2 function where u comment out pass 1 call and uncomment pass 2 function call} +\ptindent{\Arrow{} inside the |pass2_correct| function, uncomment the appropriate correction function to call} +\ptindent{\Arrow{} the captured messages from {\it{tee}} of pass 1 is its inputted file} +\ptindent{\Arrow{} in awk/gawk terms this |gawk|'s record is composed of fields where the field separator is space} +\ptindent{\Arrow{} so the 2nd pass receives the 2 fields filename, and message} +\fbreak +\fbreak +Output example of guideline violations from Pass 1:\fbreak +\ptindent{\Arrow{} "/yacco2/.DS\_Store" 'Extended attributes -rwxr-xr-x@@'} +\ptindent{\Arrow{} "/yacco2/.DS\_Store" 'Write permissions -rwxr-xr-x@@ to possibly delete file type: data'} +\ptindent{\Arrow{} "/yacco2/.DS\_Store" 'Bypass file in zip'} +\ptindent{\Arrow{} "/yacco2/.gitignore" 'Auxilary file to be deleted'} +\ptindent{\Arrow{} "/yacco2/.nbattrs" 'Extended attributes -rwxr-xr-x+'} +\ptindent{\Arrow{} "/yacco2/.nbattrs" 'Write permissions -rwxr-xr-x+ to possibly delete file type: XML'} +\ptindent{\Arrow{} "/yacco2/.nbattrs" 'Bypass file in zip'} +\ptindent{\Arrow{} "/yacco2/bin/.DS\_Store" 'Extended attributes -rwxr-xr-x@@'} +\ptindent{\Arrow{} "/yacco2/bin/.DS\_Store" 'Write permissions -rwxr-xr-x@@ to possibly delete file type: data'} +\ptindent{\Arrow{} "/yacco2/bin/.DS\_Store" 'Bypass file in zip'} +\ptindent{\Arrow{} "/yacco2/bin/man/man1/1lrerrors.log" 'Auxilary file to be deleted'} +\ptindent{\Arrow{} "/yacco2/bin/man/man1/1lrerrors.log" 'Empty file to be deleted'} +\ptindent{\Arrow{} "/yacco2/bin/man/man1/1lrtracings.log" 'Auxilary file to be deleted'} +\ptindent{\Arrow{} "/yacco2/bin/man/man1/1lrtracings.log" 'Empty file to be deleted'} +\ptindent{\Arrow{} "/yacco2/bin/man/man1/o2.man" 'Extended attributes -rw-r--r--@@'} +\ptindent{\Arrow{} "/yacco2/bin/man/man1/o2linker.man" 'Extended attributes -rw-r--r--@@'} +\ptindent{\Arrow{} "/yacco2/bin/man/man1/yacco2.man" 'Extended attributes -rw-r--r--@@'} +\ptindent{\Arrow{} "/yacco2/bin/man/man1/yacco2cmd.tmp" 'Auxilary file to be deleted'} +\ptindent{\Arrow{} "/yacco2/bin/man/man1/yacco2cmd.tmp" 'Empty file to be deleted'} +\ptindent{\Arrow{} "/yacco2/bld\_bash\_APPLE" 'Extended attributes -rwxr-xr-x@@'} +\ptindent{\Arrow{} "/yacco2/bld\_bash\_APPLE" 'Write permissions -rwxr-xr-x@@ to possibly delete file type: ASCII'} +\ptindent{\Arrow{} "/yacco2/book/appendix\_a.aux" 'Auxilary file to be deleted'} +\ptindent{\Arrow{} "/yacco2/book/ch\_fsm.tex" 'Write permissions -rwxr-xr-x@@ to possibly delete file type: LaTeX'} +\fbreak +Running the initial program could potentially output the above sampling. +If there are just 1 message type outputted then u would just focus on ``pass 2'' to correct it. +Having a mix of messages means ``pass 1'' should be edited to just deal with the 1 message type + at a time. This allows the homogenous output to be captured and edit the removal of files to bypass. +Now the program can be edited to support the message type action correcting the violation +and rerun. +Each listed guideline type would go thru this edit behaviour: ``pass 1'' to see the violations, analyse its outcome, +re-edit program, and then run the correction. + +@*2 Anatomy of this |gawk| program.\fbreak +It contains 3 |gawk| actions: BEGIN, Body, and END. +This program's BEGIN and END actions are just read record stats. +U can add your own code as this program is open to your creativity. +The action Body contains the 2 passes: |pass1_guidelines_verify| and |pass2_correct|. +To comment out a function call, add a \NOsign{} at the beginning of its line. +To activate a commented out function call, just remove its |gawk|'s comment character: \NOsign. + +@*2 How to generate the pdf document and this gawk program.\fbreak +The \Cweb{} ``literate programming'' framework is used to generate +its pdf document and its gawk program from |ctan_chk.w|. +Though Cweb emits a ``c'' type code, gawk code is very similar to ``c''.\fbreak +0) Run from a terminal using bash.\fbreak +\ptindent{{\bf{. ctan\_chk\_bash}}} +\ptindent{\Arrow{} The various utilities used are outputed on the terminal} + +U are open to add your own code to the |ctan_chk.w| program and rerun the above script. +If u do not have the \Cweb{} framework installed, u can +add the code to the |ctan_chk.gawk| file. + +@*2 How to use this gawk program.\fbreak +0) Run from a terminal using bash.\fbreak +1) Generate a file containing your project's files whose path is absolute\fbreak +\ptindent{{\bf{find /absolute path of your project \GTsign{} xxx}}} +\ptindent{\Arrow{} xxx is a holding file containing your project's files} +\ptindent{\Arrow{} example of an absolute path: {\bf {/usr/local/yacco2}}} +2) Edit |ctan_chk.gawk| to what function calls u want to use inside |pass1_guidelines_verify|\fbreak +3) Run gawk ctan\_chk program verifying your project\fbreak +\ptindent{{\bf{gawk -f ctan\_chk.gawk xxx}} \NOsign xxx is the file read containing the files to assess}\fbreak +\ptindent{\Arrow{} it outputs files to correct on the terminal with appropriate guideline message} +\ptindent{\Arrow{} no outputted messages means your project passed with flying colours :\prtcbrace} +\fbreak +\ptindent{\Arrow{} To capture the verification output:} +\ptindent{{\bf{gawk -f ctan\_chk.gawk xxx\Verticalbar{}tee yyy}}}\fbreak +\ptindent{\Arrow{} Use of {\it{tee}} utility to capture the output into yyy file} + +@*3 Example: Checking auxilary files to delete.\fbreak +Here are the steps to see whether there are files to remove/delete. +File xxx contains the files to verify as exampled earlier in this document.\fbreak +1) {\bf{gawk -f ctan\_chk.gawk xxx}}\fbreak +\fbreak +2) Its output should have messages similar to this:\fbreak +\ptindent{\Arrow{} "/yacco2/bin/man/man1/1lrerrors.log" 'Auxilary file to be deleted'} +\fbreak +3) Rerun {\bf{gawk -f ctan\_chk.gawk xxx\Verticalbar{}tee yyy}} where the output messages are put in {\bf{yyy}} file.\fbreak +\break +4) Edit: comment out pass1\_guidelines\_verify and uncomment \#pass2\_correct in Body action code:\fbreak +The gened |ctan_chk.gawk| program could have different commented ``section no:'' used in the below +edit session. What is important are function names referenced: for example, |pass1_guidelines_verify| which +you'll find in your |ctan_chk.gawk| program. Same comments apply against the other pieces of code being edited.\fbreak +\ptindent{\# section no:22*/} +\ptindent{\# section no28:*/} +\ptindent{\prtobrace} +\ptindent{ pass1\_guidelines\_verify(\$1);} +\ptindent{ \#pass2\_correct(\$1,\$2);} +\ptindent{\prtcbrace} +to\fbreak +\ptindent{\# section no:22*/} +\ptindent{\# section no28:*/} +\ptindent{\prtobrace} +\ptindent{ \#pass1\_guidelines\_verify(\$1);} +\ptindent{ pass2\_correct(\$1,\$2);} +\ptindent{\prtcbrace} +\fbreak +5) Edit: uncomment out \#delete\_file in pass2\_correct:\fbreak +\ptindent{\# section no:28*/} +\ptindent{\# section no29:*/} +\ptindent{function pass2\_correct(filename,message)} +\ptindent{\prtobrace} +\ptindent{ \#remove\_file\_s\_execute\_attribute(filename,message);} +\ptindent{ \#remove\_file\_s\_extended\_attributes(filename,message);} +\ptindent{ \#delete\_file(filename);} +\ptindent{\prtcbrace} +to\break +\ptindent{\# section no:28*/} +\ptindent{\# section no29:*/} +\ptindent{function pass2\_correct(filename,message)} +\ptindent{\prtobrace} +\ptindent{ \#remove\_file\_s\_execute\_attribute(filename,message);} +\ptindent{ \#remove\_file\_s\_extended\_attributes(filename,message);} +\ptindent{ delete\_file(filename);} +\ptindent{\prtcbrace} +\fbreak +\fbreak +\fbreak +\fbreak +\fbreak +\fbreak +6) Save edited |ctan_chk.gawk| program and rerun with {\bf{yyy}}:\fbreak +\ptindent{\Arrow{} {\bf {gawk -f ctan\_chk.gawk yyy}}} +Each file being deleted is questioned and allows u to bypass it.\fbreak +This is due to the {\bf{-i}} option used in {\it{rm -i file-to-delete}}\fbreak +\fbreak +Other guideline contraints would follow the same run / edit / rerun template above adjusting +the program accordingly.\fbreak +\ptindent{\Arrow{} {\bf{Just remember to reset the program back to its initial setting.}}} +As an aside comment, u could have uncommented the |delete_file| call inside the +|chk_auxiliary_files| function and do the correction while in the ``assess guideline'' pass. +So why did u not express this before :\prtobrace? +Well the normal correction pattern is see what guidelines are violated by ``pass 1', edit the program, +and then rerun against ``pass 2'' correction. +Once u are familiar with the program throw out my patterns and jig your own :\prtcbrace. +@* Function code sections. +@*2 ctan gawk's comments --- author, license etc. +@= +# +# Program: ctan_chk.gawk +# +# Author: Dave Bone +# +# License: +# This Source Code Form is subject to the terms of the GNU General Public License (version 3). +# If a copy of the MPL was not distributed with this file, +# You can obtain one at: "https://gnu.org/licenses/gpl.html". +# +# Purpose: Implementation of some suggested CTAN guidelines that an upload project should respect. +# Correction functions help u cleanup the droppings. +# See www.ctan.org website for "upload guideline" document +# Read ctan_chk.pdf document describing the program with various run scenarios. +# +# + +@*1 Helper functions. +@*2 Is file a directory.\fbreak +Directory found returns 1. +@<|is_file_a_directory|@>= +function is_file_a_directory(filename, filetype)@\ +{ + x="file \"%s\""; + y=sprintf(x,filename); + y|getline a; + close(y); + split(a,parts); + filetype[1] = parts[2]; + xx = parts[2]; + str= "^directory$"; + if (xx ~ str) { + return 1; + } + return 0; +} + +@*2 Is file an executable.\fbreak +This function {\bf{might be too platform dependent}}.\fbreak +If so then don't call it or find an alternative.\fbreak +A return 1 means it's an executable. +@<|is_file_an_executable|@>= +function is_file_an_executable(filename, filetype)@\ +{ + x="file %s"; + y=sprintf(x,filename); + y|getline a; + close(y); + split(a,parts); + filetype[1] = parts[2]; + xx = parts[2]; + str= "(executable|POSIX|Mach-O|ELF)$"; + if (xx ~ str) { + return 1; + } + return 0; +} + +@*1 Guideline assessment functions. +@*2 Check for auxiliary type files.\fbreak +``str'' contains a regular expression of file extensions to search for starting with a ``.'' followed by +the round bracket expression of extensions to search on ending by the end-of-string regular expression indicator: \$. +Inside the rounded bracket expression is the choice of extensions separated by \Verticalbar{} +which is the ``or'' operator of a regular expression.\fbreak +\fbreak +The double \Backslash{} in str is due to how gawk parses the program code: +it does a double pass:\fbreak +\ptindent{1) on the string: str} +\ptindent{2) on the regular expression called} +Just having a ``.'' at the start of regular expression means it is a single ``wild character'' to accept. +To accept a period ``.'' that starts the file extension, u have to escape it. +Pass 1 for the literal string is the first escape sequence on \Backslash{} the 2nd backslash. +In pass 2 for the regular expession called, the \Backslash{} escapes the ``.'' to not interpret +as the regular expression wild character.\fbreak +\fbreak +str can be added to. Make sure u include the added extension started with the \Verticalbar{} when appended to before +the closing off rounded bracked ``)''. \fbreak +\fbreak +|chk_auxiliary_files| outputs a 2 part message: file name and message it considers as an auxiliary file to be deleted. +Calling |delete_file| interacts with the user whether to delete it or not. +It is commented out so that the messages can saved and reviewed before the correction pass takes place: +See |Pass 2 --- correct violated guidelines| section providing more information. +U can uncomment the |delete_file| statement below if u prefer to delete the file in the assessment pass +rather than the correction pass. Your call and temperment. +@<|chk_auxiliary_files|@>= +function chk_auxiliary_files(filename)@\ +{ + if (is_file_a_directory(filename) == 1) + return 0; + + str= "\\.(ps|gitignore|git|aux|log|bbl|bcf|blg|brf|ilg|ind|idx|glo|loa|lof|lot|nav|out|snm|vrb|toc|dvi|glg|gls|tmp|o|bak|mpx|scn|toc)$"; + if (filename ~ str) { + a= "\"%s\" 'Auxilary file to be deleted'"; + b= sprintf(a,filename); + print b; + #delete_file(filename); + return 1; + } + return 0; +} + +@*2 Check for extended attributes.\fbreak +Basicly looks at the output from the ``ls -al'' of a file. +If there are extended attributes it will be displayed at the end of the first field as ``@@'' or ``+''. +It outputs the filename and message to the terminal. +Return 1 if found. +@<|chk_extended_file_attributes|@>= +function chk_extended_file_attributes(filename)@\ +{ + x="ls -al \"%s\""; + y=sprintf(x,filename); + y|getline a; + close(y); + number_of_fields = split(a,parts); + if (number_of_fields < 9) + return 0; + + xx=parts[1]; + str= "(@@|+)$"; + if (xx !~ str) { + return 0; + } + + a="\"%s\" 'Extended attributes %s'"; + b=sprintf(a,filename,parts[1]); + print b; + #remove_file_s_extended_attributes(filename,b); + return 1; +} +@*2 Check for empty files.\fbreak +Uncomment out the |delete_file| statement below if u want to remove it in the assessment phase. +Asks whether to delete the zero sized file and returns 1. +@<|chk_empty_files|@>= +function chk_empty_files(filename)@\ +{ + if (is_file_a_directory(filename) == 1) + return 0; + + x="ls -al \"%s\""; + y=sprintf(x,filename); + y|getline a; + close(y); + number_of_fields = split(a,parts); + if (number_of_fields < 9)@\ + { + print "ERROR ===> ls -al should be 9 fields and it isn't: " a " no fields: " number_of_fields; + return 0; + } + i=strtonum(parts[5]); + if (i > 0){ + return 0; + } + a="\"%s\" 'Empty file to be deleted'"; + + b=sprintf(a,filename); + print b; + #delete_file(filename); + return 1; +} + +@*2 Check for empty directory.\fbreak +Empty directory found returns a 1.\fbreak +This check requires u to assess what u want to do: delete it, or add an ``info.txt'' file inside it. +For example in the ``Yacco2'' project, it is a full +development framework of a compiler/compile, and its API library. +It has empty Debug folders. Its Release folders contained content. +Depending on what the user wanted to debug and link against, the empty Debug folder +provided consistency to the framework and hence it was needed. So an ``info.txt'' file +was created inside each Debug folder expressing their intent/use to the developer. + +@<|chk_empty_directory|@>= +function chk_empty_directory(filename)@\ +{ + if (is_file_a_directory(filename) == 0) + return 0; + + x="du -sk \"%s\""; + y=sprintf(x,filename); + y|getline a; + close(y); + number_of_fields = split(a,parts); + + i=strtonum(parts[1]); + if (i > 0) + return 0; + + a="\"%s\" 'Empty directory to be deleted or needs to add info.txt file inside it'"; + + b=sprintf(a,filename); + print b; + return 1; +} + + +@*2 Check file permissions.\fbreak +Bypass a directory. +If the file does not have an executable attribute then exit stage gracefully. + +@<|chk_file_permissions|@>= +function chk_file_permissions(filename)@\ +{ + filetype[1]=""; + if (is_file_a_directory(filename, filetype) == 1) + return 0; + if (is_file_an_executable(filename,filetype) == 1) + return 0; + + x="ls -al \"%s\""; + y=sprintf(x,filename); + y|getline a; + close(y); + + number_fields = split(a,parts); + + str= "x"; + if (parts[1] ~ str) { + a="\"%s\" 'Write permissions %s to possibly delete file type: %s'"; + b=sprintf(a,filename,parts[1],filetype[1]); + print b; + return 1; + } + return 0; +} + +@*2 Check file to bypass in zip.\fbreak +This is just a check function that lists files to bypass in the zip file creation process.\fbreak +An example of creating a zip file:\fbreak +\ptindent{{\bf{zip -r -ll yacco2.zip yacco2 -x '*DS\_Store' -x '*.nbattrs'}}} +\ptindent{\Arrow{} -r recurse through the folder getting all its subfolders and their contents} +\ptindent{\Arrow{} -ll parameter reduces carriage return/line feed combo to line feed} +\ptindent{\Arrow{} -x parameter lists by regular expression the file(s) to bypass} +\ptindent{\Arrow{} The bypassed exampled files are Apple OSX specific} + +@<|chk_file_to_bypass_in_zip|@>= +function chk_file_to_bypass_in_zip(filename) +{ + str= ".(DS_Store|.nbattrs)$"; + if (filename ~ str) { + a="\"%s\" 'Bypass file in zip'"; + b=sprintf(a,filename); + print b; + return 1; + } + return 0; +} + + +@*1 Correct guideline violations. +@*2 Remove file's execute attribute.\fbreak +Due to security reasons, u cannot have an indirect bash script run against a list of files +to change their ownership attributes. +It will run but nothing will be changed.\fbreak +So what to do?\fbreak +\ptindent{\Arrow{} gawk -f |ctan_chk.gawk| xxx \Verticalbar{}tee yyy} +\ptindent{\Arrow{} \ \ \ \ u can use your own temporary file name instead of yyy} +\ptindent{\Arrow{} \ \ \ \ just remember to substitute your file name in place of yyy} +\ptindent{\Arrow{} where the |chk_file_permissions| function is the only function run} +\ptindent{\Arrow{} and the other functions have been commented out} +\fbreak +\ptindent{Edit yyy file containing the list of potential files, removing files keeping their execute attribute.} +\break +\ptindent{Run this below gawk script interactively from your bash terminal} +\ptindent{\Arrow{} This means copy the below script line and paste it in the bash terminal} +\ptindent{\ \ \ \ \ gawk '\prtobrace x="chmod a-x \%s;";y=sprint(x,\$1);system(y);\prtcbrace' yyy} +\fbreak +Some comments on the above interactive |gawk| program:\fbreak +1) It reads the yyy file where each line read contains 2 fields: filename, and message separated by a space\fbreak +2) It runs the {\it{chmod}} utility by the {\bf{system}} statement\fbreak +3) Not sure about {\bf{chmod}} utility, do a ``man chmod'' on your bash terminal for more information\fbreak +4) If u boobooed on a file and removed the execute attribute, here is a correction:\fbreak +\ptindent{\Arrow{} {\bf{chmod a+x file-to-reimplement}}} + +@<|remove_file_s_execute_attribute|@>= +function remove_file_s_execute_attribute(filename, message)@\ +{ + print "Please read |ctan_chk.pdf| to find instructions on how remove execute attribute from a file"; +} + +@*2 Remove file's with extended attributes.\fbreak +This function is platform dependent. +The {\it{xattr}} is the utility to run on Apple's OSx platform to remove the extension. +@<|remove_file_s_extended_attributes|@>= +function remove_file_s_extended_attributes(filename, message)@\ +{ + x="echo %s\";xattr -c %s"; + y=sprintf(x,message,filename); + print y; + #y|getline a; + #close(y); +} + +@*2 Delete file.\fbreak +The file name passed to it is displayed and asks whether it should be deleted. +@<|delete_file|@>= +function delete_file(filename)@\ +{ + x="rm -i \"%s\""; + y=sprintf(x,filename); + y|getline a; + close(y); +} + + +@* Pass 1 / 2 guidelines assessment and correction.\fbreak +@*2 Pass 1 --- guidelines assessment.\fbreak +Using a text editor (un)comment out the appropriate function calls in |ctan_chk.gawk| that u'd like to verify. +For example checking just the files to be deleted, comment out all the below functions except +|chk_auxiliary_files|. + +U can run pass 1 as is to see whether any of your files for upload do not +pass the guidelines. +From there u can adjust what function to deal with by commenting out the others fuctions +and teeing out its found infidelities for pass 2 correction. + +@= +function pass1_guidelines_verify(filename) +{ + chk_auxiliary_files(filename); + chk_extended_file_attributes(filename); + chk_empty_files(filename); + chk_empty_directory(filename); + chk_file_permissions(filename); + chk_file_to_bypass_in_zip(filename); +} + +@*2 Pass 2 --- correct violated guidelines.\fbreak +There are 3 functions whereby 2 of them do usefull things.\fbreak +\ptindent{|delete_file| function asks whether its passed file should be deleted} +\ptindent{\Arrow{} Remove the -i in {\bf{rm -i}} statement if u don't want the interactive question} +\fbreak +\ptindent{|remove_file_s_extended_attributes| function is tailored to the Apple platform} +\ptindent{\Arrow{} Other platforms should have an equivalent {\it{xattr -c}} utility} +\ptindent{\Arrow{} {\bf{Caveat:}} know what utility to use and adjust accordingly to remove the extension attribute} +\ptindent{\Arrow{} Have a read at https://en.wikipedia.org/wiki/Extended\_file\_attributes\#cite\_note-14} +\fbreak +\ptindent{|remove_file_s_execute_attribute| tells u to read the {\bf{ctan\_chk.pdf}} document} +\ptindent{\Arrow{} on ``how to remove'' the execute attribute from a file} +\fbreak +Uncomment the appropriate below function to call. +And comment out |pass1_guidelines_verify| statement, and uncomment |pass2_correct| statement +in |Body| action before reruning this program. +@= +function pass2_correct(filename, message) +{ + #remove_file_s_execute_attribute(filename,message); + #remove_file_s_extended_attributes(filename,message); + #delete_file(filename); +} + +@* Gawk Begin, Body, End actions. +@*2 Begin. +@<|BEGIN|@>= +BEGIN{ +rec_cnt = 0; +} + +@*2 Body. +@<|Body|@>= +{ + pass1_guidelines_verify($1); + #pass2_correct($1,$2); +} + +@*2 END. +@<|END|@>= +END{ +#print "no records read: " NR; +} + + + +@ Write out gawk program. +@(ctan_chk.gawk@>= +@; +@<|is_file_a_directory|@>; +@<|is_file_an_executable|@>; +@<|chk_auxiliary_files|@>; +@<|remove_file_s_extended_attributes|@>; +@<|chk_file_permissions|@>; +@<|chk_extended_file_attributes|@>; +@<|chk_empty_files|@>; +@<|chk_empty_directory|@>; +@<|delete_file|@>; +@<|chk_file_to_bypass_in_zip|@>; +@; +@; +@<|BEGIN|@>; +@<|Body|@>; +@<|END|@>; + +@** Index. diff --git a/Master/texmf-dist/doc/support/ctan_chk/ctan_chk_bash b/Master/texmf-dist/doc/support/ctan_chk/ctan_chk_bash new file mode 100755 index 00000000000..79e3a3486e2 --- /dev/null +++ b/Master/texmf-dist/doc/support/ctan_chk/ctan_chk_bash @@ -0,0 +1,28 @@ +#! /bin/sh +# File: ctan_chk_bash +# Why: Creates the ctan_chk.gawk and ctan_chk.pdf from the ctan_chk.w ``literate program'' +# How to run: from bash command-terminal +# . ctan_chk_bash +# +echo "----------->ctan_chk_bash script<-----------" +echo "----------->cweave create the pdf doc of ctan_chk<-----------" +cweave ctan_chk +pdftex ctan_chk +echo "----------->ctangle create ctan_chk.gawk program<-----------" +ctangle -l +e ctan_chk.w +echo "----------->sed - change section no into a gawk comment<-----------" +sed 's/^\/\*/# section no/' ctan_chk.gawk>ctan_chk.tmp +echo "----------->gawk --- remove empty lines and #line lines<-----------" +gawk -e '{r=length($0);if(r==0) next; match($0,/^(\#line|;)/);if (RLENGTH > 0) next; print $0;}' ctan_chk.tmp > ctan_chk.tm1 +echo "----------->cp --- create the gawk edited program<-----------" +cp ctan_chk.tm1 ctan_chk.gawk +echo "----------->remove temporary files<-----------" +rm ctan_chk.tmp +rm ctan_chk.tm1 +rm *.idx +rm *.scn +rm *.toc +rm *.tex +rm *.log +rm *.c + diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check index 20eca3b90ce..a2758ba39fc 100755 --- a/Master/tlpkg/bin/tlpkg-ctan-check +++ b/Master/tlpkg/bin/tlpkg-ctan-check @@ -155,7 +155,7 @@ my @TLP_working = qw( cprotect crbox crop crossreference crossrefware crossword crosswrd cryst cs csbulletin cslatex csplain csquotes csquotes-de csvsimple csvtools cstex - ctanify ctanupload ctable ctex ctex-faq + ctan_chk ctanify ctanupload ctable ctex ctex-faq cursolatex cuisine currfile currvita curve curve2e curves custom-bib cutwin cv cv4tw cweb-latex cyklop cyrillic cyrplain diff --git a/Master/tlpkg/tlpsrc/collection-binextra.tlpsrc b/Master/tlpkg/tlpsrc/collection-binextra.tlpsrc index 9ee425e4177..36a49152d86 100644 --- a/Master/tlpkg/tlpsrc/collection-binextra.tlpsrc +++ b/Master/tlpkg/tlpsrc/collection-binextra.tlpsrc @@ -14,6 +14,7 @@ depend bibtex8 depend bibtexu depend bundledoc depend chktex +depend ctan_chk depend ctanify depend ctanupload depend ctie diff --git a/Master/tlpkg/tlpsrc/ctan_chk.tlpsrc b/Master/tlpkg/tlpsrc/ctan_chk.tlpsrc new file mode 100644 index 00000000000..e69de29bb2d -- cgit v1.2.3