mirror of
https://github.com/yabwon/SAS_PACKAGES.git
synced 2026-01-08 23:40:06 +00:00
version 20191215
module for developer's tests added, two new macroparameters: testPackage=Y and packages= the first one turns on testing, the second one points to location of the folder with packages (in case when generated package has dependencies)
This commit is contained in:
@@ -36,7 +36,7 @@
|
|||||||
*/
|
*/
|
||||||
/**#############################################################################**/
|
/**#############################################################################**/
|
||||||
|
|
||||||
/* Macros to generate SAS packages, version 20191118 */
|
/* Macros to generate SAS packages, version 20191215 */
|
||||||
/* A SAS package is a zip file containing a group
|
/* A SAS package is a zip file containing a group
|
||||||
of SAS codes (macros, functions, datasteps generating
|
of SAS codes (macros, functions, datasteps generating
|
||||||
data, etc.) wrapped up together and %INCLUDEed by
|
data, etc.) wrapped up together and %INCLUDEed by
|
||||||
@@ -50,6 +50,8 @@
|
|||||||
%macro generatePackage(
|
%macro generatePackage(
|
||||||
/* location of package files */
|
/* location of package files */
|
||||||
filesLocation=%sysfunc(pathname(work))/%lowcase(&packageName.)
|
filesLocation=%sysfunc(pathname(work))/%lowcase(&packageName.)
|
||||||
|
,testPackage=Y
|
||||||
|
,packages=
|
||||||
)/secure;
|
)/secure;
|
||||||
/*** HELP END ***/
|
/*** HELP END ***/
|
||||||
%local zipReferrence filesWithCodes _DESCR_ _LIC_ _RC_ _PackageFileref_;
|
%local zipReferrence filesWithCodes _DESCR_ _LIC_ _RC_ _PackageFileref_;
|
||||||
@@ -693,12 +695,13 @@ data _null_;
|
|||||||
|
|
||||||
do until(eof);
|
do until(eof);
|
||||||
set &filesWithCodes. end = EOF nobs=NOBS;
|
set &filesWithCodes. end = EOF nobs=NOBS;
|
||||||
if (upcase(type) in: ('CLEAN' 'LAZYDATA')) then continue; /* cleaning files are only included in unload.sas */
|
if (upcase(type) in: ('CLEAN' 'LAZYDATA' 'TEST')) then continue; /* cleaning files are only included in unload.sas */
|
||||||
/* lazy data are only loaded on demand
|
/* lazy data are only loaded on demand
|
||||||
%loadPackage(packagename, lazyData=set1 set2 set3)
|
%loadPackage(packagename, lazyData=set1 set2 set3)
|
||||||
*/
|
test files are used only during package generation
|
||||||
|
*/
|
||||||
/* test for supported types */
|
/* test for supported types */
|
||||||
if not (upcase(type) in: ('LIBNAME' 'MACRO' 'DATA' 'FUNCTION' 'FORMAT' 'EXEC' 'CLEAN' 'LAZYDATA')) then
|
if not (upcase(type) in: ('LIBNAME' 'MACRO' 'DATA' 'FUNCTION' 'FORMAT' 'EXEC' 'CLEAN' 'LAZYDATA' 'TEST')) then
|
||||||
do;
|
do;
|
||||||
putlog 'WARNING: Type ' type 'is not yet supported.';
|
putlog 'WARNING: Type ' type 'is not yet supported.';
|
||||||
continue;
|
continue;
|
||||||
@@ -1061,6 +1064,8 @@ data _null_;
|
|||||||
do until(EOFDS);
|
do until(EOFDS);
|
||||||
/* content is created during package creation */
|
/* content is created during package creation */
|
||||||
set &filesWithCodes. end = EOFDS nobs = NOBS curobs = CUROBS;
|
set &filesWithCodes. end = EOFDS nobs = NOBS curobs = CUROBS;
|
||||||
|
if upcase(type) in: ('TEST') then continue; /* exclude tests */
|
||||||
|
|
||||||
put 'put @5 "' CUROBS +(-1) ')" @10 "' type '" @21 "' fileshort '";';
|
put 'put @5 "' CUROBS +(-1) ')" @10 "' type '" @21 "' fileshort '";';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -1118,6 +1123,8 @@ data _null_;
|
|||||||
do until(EOFDS);
|
do until(EOFDS);
|
||||||
/* content is created during package creation */
|
/* content is created during package creation */
|
||||||
set &filesWithCodes. end = EOFDS;
|
set &filesWithCodes. end = EOFDS;
|
||||||
|
if upcase(type) in: ('TEST') then continue; /* exclude tests */
|
||||||
|
|
||||||
select;
|
select;
|
||||||
when (upcase(type) in ("DATA" "LAZYDATA")) fileshort2 = fileshort;
|
when (upcase(type) in ("DATA" "LAZYDATA")) fileshort2 = fileshort;
|
||||||
when (upcase(type) = "MACRO") fileshort2 = cats('%',fileshort,'()');
|
when (upcase(type) = "MACRO") fileshort2 = cats('%',fileshort,'()');
|
||||||
@@ -1186,6 +1193,7 @@ data _null_;
|
|||||||
if NOBS = 0 then stop;
|
if NOBS = 0 then stop;
|
||||||
|
|
||||||
set &filesWithCodes. nobs = NOBS;
|
set &filesWithCodes. nobs = NOBS;
|
||||||
|
if (upcase(type) not in: ('TEST')); /* test files are not to be copied */
|
||||||
|
|
||||||
call execute(cat ('filename _IN_ "', catx('/', base, folder, file), '";'));
|
call execute(cat ('filename _IN_ "', catx('/', base, folder, file), '";'));
|
||||||
call execute(cats("filename _OUT_ ZIP '", base, "/%lowcase(&packageName.).zip' member='_", folder, ".", file, "';") );
|
call execute(cats("filename _OUT_ ZIP '", base, "/%lowcase(&packageName.).zip' member='_", folder, ".", file, "';") );
|
||||||
@@ -1211,11 +1219,227 @@ data _null_;
|
|||||||
call execute('filename _IN_ clear;');
|
call execute('filename _IN_ clear;');
|
||||||
call execute('filename _OUT_ clear;');
|
call execute('filename _OUT_ clear;');
|
||||||
run;
|
run;
|
||||||
|
/*
|
||||||
|
proc sql;
|
||||||
|
drop table &filesWithCodes.;
|
||||||
|
quit;
|
||||||
|
*/
|
||||||
|
filename &zipReferrence. clear;
|
||||||
|
|
||||||
|
/* tests of package are executed by default */
|
||||||
|
%if %bquote(&testPackage.) ne Y %then
|
||||||
|
%do;
|
||||||
|
%put WARNING: ** NO TESTING WILL BE EXECUTED **;
|
||||||
|
%GOTO NOTESTING;
|
||||||
|
%end;
|
||||||
|
/* check if systask is available */
|
||||||
|
%if %sysfunc(GETOPTION(XCMD)) = NOXCMD %then
|
||||||
|
%do;
|
||||||
|
%put WARNING: ** NO TESTING WILL BE EXECUTED DUE TO NOXCMD **;
|
||||||
|
%GOTO NOTESTING;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
|
||||||
|
/* locate sas binaries */
|
||||||
|
filename sasroot "!SASROOT";
|
||||||
|
%let SASROOT=%sysfunc(PATHNAME(sasroot));
|
||||||
|
filename sasroot;
|
||||||
|
%put *&SASROOT.*;
|
||||||
|
%let SASEXE=&SASROOT./sas;
|
||||||
|
%put *&SASEXE.*;
|
||||||
|
%let SASWORK=%sysfunc(GETOPTION(work));
|
||||||
|
%put *&SASWORK.*;
|
||||||
|
|
||||||
|
options DLCREATEDIR; /* turns-on creation of subdirectories */
|
||||||
|
/* temporary location for tests results */
|
||||||
|
libname TEST "&SASWORK./test_%lowcase(%sysfunc(datetime(),b8601dt19.))";
|
||||||
|
libname TESTWORK "%sysfunc(pathname(TEST))/work";
|
||||||
|
|
||||||
|
/* remember location of sessions current directory */
|
||||||
|
filename currdir ".";
|
||||||
|
filename currdir list;
|
||||||
|
|
||||||
|
/* if your package uses any other packages this points to their location */
|
||||||
|
/* if no one is provided the filesLocation is used as a repalacement */
|
||||||
|
%if %bquote(&packages.)= %then %let packages=&filesLocation.;
|
||||||
|
filename packages "&packages.";
|
||||||
|
filename packages list;
|
||||||
|
|
||||||
|
/* replace current dir with the temporary one for tests */
|
||||||
|
%put *NOTE: changing current folder to:*;
|
||||||
|
%put *%sysfunc(DLGCDIR(%sysfunc(pathname(TEST))))*;
|
||||||
|
|
||||||
|
/* the first test is for loading package, testing help and unloading */
|
||||||
|
/*-1-*/
|
||||||
|
data _null_;
|
||||||
|
file "./loading.sas";
|
||||||
|
|
||||||
|
put "filename packages '&packages.';" /;
|
||||||
|
put '%include packages(loadpackage.sas);' /;
|
||||||
|
/* load */
|
||||||
|
put '%loadpackage'"(&packageName.,";
|
||||||
|
put " path=&filesLocation.)" /;
|
||||||
|
/* help */
|
||||||
|
put '%helpPackage'"(&packageName.,";
|
||||||
|
put " path=&filesLocation.)" /;
|
||||||
|
put '%helpPackage'"(&packageName.,*,";
|
||||||
|
put " path=&filesLocation.)" /;
|
||||||
|
put '%helpPackage'"(&packageName.,License,";
|
||||||
|
put " path=&filesLocation.)" /;
|
||||||
|
/* unload */
|
||||||
|
put '%unloadPackage'"(&packageName.,";
|
||||||
|
put " path=&filesLocation.) " /;
|
||||||
|
run;
|
||||||
|
|
||||||
|
systask kill sas0 wait;
|
||||||
|
%local sasstat0 TEST_0 TESTRC_0;;
|
||||||
|
%let TEST_0 = loading;
|
||||||
|
systask command
|
||||||
|
"""&SASEXE.""
|
||||||
|
-sysin ""./&TEST_0..sas""
|
||||||
|
-print ""./&TEST_0..lst""
|
||||||
|
-log ""./&TEST_0..log""
|
||||||
|
-config ""&SASROOT./sasv9.cfg""
|
||||||
|
-work ""./work""
|
||||||
|
-noterminal"
|
||||||
|
taskname=sas0
|
||||||
|
status=sasstat0
|
||||||
|
WAIT
|
||||||
|
;
|
||||||
|
%let TESTRC_0 = &SYSRC.;
|
||||||
|
%put *&=sasstat0.*&=TESTRC_0.*;
|
||||||
|
data _null_;
|
||||||
|
infile "./loading.log" dlm='0a0d'x end=EOF;
|
||||||
|
input;
|
||||||
|
if _N_ > 10; /* due to "Unable to copy SASUSER registry to WORK registry." */
|
||||||
|
if _INFILE_ =: 'WARNING:' then
|
||||||
|
do;
|
||||||
|
warning+1;
|
||||||
|
put _N_= _INFILE_;
|
||||||
|
end;
|
||||||
|
if _INFILE_ =: 'ERROR:' then
|
||||||
|
do;
|
||||||
|
error+1;
|
||||||
|
put _N_= _INFILE_;
|
||||||
|
end;
|
||||||
|
if EOF then
|
||||||
|
do;
|
||||||
|
put (_ALL_) (=/);
|
||||||
|
call symputX("TESTW_0", warning, "L");
|
||||||
|
call symputX("TESTE_0", error, "L");
|
||||||
|
end;
|
||||||
|
run;
|
||||||
|
/*-1-*/
|
||||||
|
|
||||||
|
|
||||||
|
/* other tests are provided by the developer */
|
||||||
|
%local numberOfTests;
|
||||||
|
%let numberOfTests = 0;
|
||||||
|
data _null_;
|
||||||
|
/* break if no data */
|
||||||
|
if NOBS = 0 then stop;
|
||||||
|
|
||||||
|
set &filesWithCodes. nobs = NOBS;
|
||||||
|
if (upcase(type) in: ('TEST')); /* only test files are used */
|
||||||
|
|
||||||
|
test + 1; /* count the number of tests */
|
||||||
|
|
||||||
|
_RC_ = filename(cats("_TIN_",test), catx("/", base, folder, file));
|
||||||
|
_RC_ = filename(cats("_TOUT_",test), cats("./", file));
|
||||||
|
|
||||||
|
_RC_ = fcopy(cats("_TIN_",test), cats("_TOUT_", test));
|
||||||
|
|
||||||
|
call symputX(cats("TEST_", test), fileshort, "L");
|
||||||
|
call symputX("numberOfTests", test, "L");
|
||||||
|
run;
|
||||||
|
|
||||||
|
/* each test is executed with autoexec loading the package */
|
||||||
|
data _null_;
|
||||||
|
file "./autoexec.sas";
|
||||||
|
|
||||||
|
put "filename packages '&packages.';" /;
|
||||||
|
put '%include packages(loadpackage.sas);' /;
|
||||||
|
put '%loadpackage'"(&packageName.,";
|
||||||
|
put " path=&filesLocation.) " /;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%local t;
|
||||||
|
%do t = 1 %to &numberOfTests.;
|
||||||
|
systask kill sas&t. wait;
|
||||||
|
%local sasstat&t. TESTRC_&t;
|
||||||
|
systask command
|
||||||
|
"""&SASEXE.""
|
||||||
|
-sysin ""./&&TEST_&t...sas""
|
||||||
|
-print ""./&&TEST_&t...lst""
|
||||||
|
-log ""./&&TEST_&t...log""
|
||||||
|
-config ""&SASROOT./sasv9.cfg""
|
||||||
|
-work ""./work""
|
||||||
|
-noterminal"
|
||||||
|
taskname=sas&t.
|
||||||
|
status=sasstat&t.
|
||||||
|
WAIT
|
||||||
|
;
|
||||||
|
%let TESTRC_&t = &SYSRC.;
|
||||||
|
%put *sasstat&t.=&&sasstat&t.*TESTRC_&t=&&TESTRC_&t*;
|
||||||
|
data _null_;
|
||||||
|
infile "./&&TEST_&t...log" dlm='0a0d'x end=EOF;
|
||||||
|
input;
|
||||||
|
if _N_ > 10; /* due to "Unable to copy SASUSER registry to WORK registry." */
|
||||||
|
if _INFILE_ =: 'WARNING:' then
|
||||||
|
do;
|
||||||
|
warning+1;
|
||||||
|
/*length warningline $ 1024;
|
||||||
|
warningline = catx(',', strip(warningline), _N_);*/
|
||||||
|
put _N_= _INFILE_;
|
||||||
|
end;
|
||||||
|
if _INFILE_ =: 'ERROR:' then
|
||||||
|
do;
|
||||||
|
error+1;
|
||||||
|
/*length errorline $ 1024;
|
||||||
|
errorline = catx(',', strip(errorline), _N_);*/
|
||||||
|
put _N_= _INFILE_;
|
||||||
|
end;
|
||||||
|
if EOF then
|
||||||
|
do;
|
||||||
|
put (_ALL_) (=/);
|
||||||
|
call symputX("TESTW_&t.", warning, "L");
|
||||||
|
call symputX("TESTE_&t.", error, "L");
|
||||||
|
end;
|
||||||
|
run;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
data test.tests_summary;
|
||||||
|
length testName $ 128;
|
||||||
|
do _N_ = 0 to &numberOfTests.;
|
||||||
|
testName = symget(cats("TEST_", _N_));
|
||||||
|
systask = input(symget(cats("SASSTAT", _N_)), best32.);
|
||||||
|
sysrc = input(symget(cats("TESTRC_", _N_)), best32.);
|
||||||
|
error = input(symget(cats("TESTE_", _N_)), best32.);
|
||||||
|
warning = input(symget(cats("TESTW_", _N_)), best32.);
|
||||||
|
output;
|
||||||
|
end;
|
||||||
|
run;
|
||||||
|
title1 "Summary of tests.";
|
||||||
|
title2 "details can be found in:";
|
||||||
|
title3 "%sysfunc(pathname(TEST))";
|
||||||
|
footnote;
|
||||||
|
proc print data = test.tests_summary;
|
||||||
|
run;
|
||||||
|
title;
|
||||||
|
|
||||||
|
/*%put _local_;*/
|
||||||
|
|
||||||
|
%put *NOTE: changing current folder to:*;
|
||||||
|
%put *%sysfunc(DLGCDIR(%sysfunc(pathname(currdir))))*;
|
||||||
|
|
||||||
|
|
||||||
|
/* if you do not want any test to be executed */
|
||||||
|
%NOTESTING:
|
||||||
|
|
||||||
proc sql;
|
proc sql;
|
||||||
drop table &filesWithCodes.;
|
drop table &filesWithCodes.;
|
||||||
quit;
|
quit;
|
||||||
filename &zipReferrence. clear;
|
|
||||||
%mend generatePackage;
|
%mend generatePackage;
|
||||||
|
|
||||||
|
|
||||||
@@ -1227,7 +1451,7 @@ TODO: (in Polish)
|
|||||||
|
|
||||||
- wewnętrzna nazwaz zmiennej z nazwa pakietu (na potrzeby kompilacji) [v]
|
- wewnętrzna nazwaz zmiennej z nazwa pakietu (na potrzeby kompilacji) [v]
|
||||||
|
|
||||||
- weryfikacja srodaowiska [ ]
|
- weryfikacja srodowiska [ ]
|
||||||
|
|
||||||
- weryfikacja "niepustosci" obowiazkowych argumentow [v]
|
- weryfikacja "niepustosci" obowiazkowych argumentow [v]
|
||||||
|
|
||||||
@@ -1249,7 +1473,7 @@ TODO: (in Polish)
|
|||||||
|
|
||||||
- infolista o required packahes w unloadPackage [v]
|
- infolista o required packahes w unloadPackage [v]
|
||||||
|
|
||||||
- dodac ICEloadPackage() [ ]
|
- dodac ICEloadPackage() [v]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*** HELP START ***/
|
/*** HELP START ***/
|
||||||
|
|||||||
Reference in New Issue
Block a user