SAS Packages Framework, version 20201001

SAS Packages Framework, version 20201001
- `%installPackage` macro allows to install/download the framework file like any other package, e.g. `%installPackage(SPFinit)`,
- improvement in testing if HASHING_FILE function is available,
- documentation updated.
This commit is contained in:
yabwon
2020-10-01 20:02:26 +02:00
parent b274d0dcda
commit 5ecccacdce
2 changed files with 86 additions and 63 deletions

View File

@@ -6,7 +6,7 @@ A **SAS package** is an automatically generated, single, stand alone *zip* file
The *purpose of a package* is to be a simple, and easy to access, code sharing medium, which will allow: on the one hand, to separate the code complex dependencies created by the developer from the user experience with the final product and, on the other hand, reduce developer's and user's unnecessary frustration related to a remote deployment process. The *purpose of a package* is to be a simple, and easy to access, code sharing medium, which will allow: on the one hand, to separate the code complex dependencies created by the developer from the user experience with the final product and, on the other hand, reduce developer's and user's unnecessary frustration related to a remote deployment process.
In this repository we are presenting the **SAS Packages Framework** which allows to develop and use SAS packages. The latest version of SPF is **`20200911`**. In this repository we are presenting the **SAS Packages Framework** which allows to develop and use SAS packages. The latest version of SPF is **`20201001`**.
To get started with SAS Packages try this [**`Getting Started with SAS Packages`**](https://github.com/yabwon/SAS_PACKAGES/blob/master/SPF/Documentation/Getting_Started_with_SAS_Packages.pdf "Getting Started with SAS Packages") presentation (see the `./SPF/Documentation` directory). To get started with SAS Packages try this [**`Getting Started with SAS Packages`**](https://github.com/yabwon/SAS_PACKAGES/blob/master/SPF/Documentation/Getting_Started_with_SAS_Packages.pdf "Getting Started with SAS Packages") presentation (see the `./SPF/Documentation` directory).
@@ -56,20 +56,20 @@ To create your own package:
#### If you have any questions, suggestions, or ideas do not hesitate to contact me! #### If you have any questions, suggestions, or ideas do not hesitate to contact me!
**Update**\[June 3rd, 2020\]**:** `%installPackage()` **macro is available**. The `%installPackage()` macro is embedded in the `loadpackage.sas` part of the framework. **Update**\[June 3rd, 2020\]**:** `%installPackage()` **macro is available**. The `%installPackage()` macro is embedded in the `loadpackage.sas` part of the framework.
**Update**\[June 10th, 2020\]**:** To see help info about framework macros and their parameters just run: `%generatePackage()`, `%installPackage()`, `%helpPackage()`, `%loadPackage()`, and `%unloadPackage()` with empty parameter list. **Update**\[June 10th, 2020\]**:** To see help info about framework macros and their parameters just run: `%generatePackage()`, `%installPackage()`, `%helpPackage()`, `%loadPackage()`, and `%unloadPackage()` with empty parameter list.
**Update**\[July 30th, 2020\]**:** All components of SAS Packages Framework are now in one file `SPFinit.sas` (located in the `./SPF` directory). Documentation moved to `./SPF/Documentation` directory. Packages zip files moved to `./packages` directory. **Update**\[July 30th, 2020\]**:** All components of SAS Packages Framework are now in one file `SPFinit.sas` (located in the `./SPF` directory). Documentation moved to `./SPF/Documentation` directory. Packages zip files moved to `./packages` directory.
## Available packages: ## Available packages:
Currently the following packages are available (see the `./packages` directory): Currently the following packages are available (see the `./packages` directory):
- **SQLinDS**\[2.2\], based on Mike Rhoads' article *Use the Full Power of SAS in Your Function-Style Macros*. The package allows to write SQL queries in the data step, e.g. - **SQLinDS**\[2.2\], based on Mike Rhoads' article *Use the Full Power of SAS in Your Function-Style Macros*. The package allows to write SQL queries in the data step, e.g.
``` ```
data class; data class;
set %SQL(select * from sashelp.class order by age); set %SQL(select * from sashelp.class order by age);
run; run;
``` ```
SHA256 digest for SQLinDS: B280D0B72DB77001ADAAE9C1612B67AD30C2C672371B27F1ACB12016C7A1363D SHA256 digest for SQLinDS: B280D0B72DB77001ADAAE9C1612B67AD30C2C672371B27F1ACB12016C7A1363D
@@ -125,5 +125,4 @@ SHA256 digest for BasePlus: 278621A6D8BBBB791DEA4C215D4261F2CB8F8B76B1397F7FA9B2
SHA256 digest for dynMacroArray: 066186B94B2976167C797C6A6E6217E361E8DEB10F2AB81906E0A325E5243084 SHA256 digest for dynMacroArray: 066186B94B2976167C797C6A6E6217E361E8DEB10F2AB81906E0A325E5243084
### ====== ### ======

View File

@@ -42,13 +42,13 @@
- to unload, or - to unload, or
- to generate SAS packages. - to generate SAS packages.
Version 20200911. Version 20201001.
See examples below. See examples below.
A SAS package is a zip file containing a group of files A SAS package is a zip file containing a group of files
with SAS code (macros, functions, data steps generating with SAS code (macros, functions, data steps generating
data, etc.) wrapped up together and %INCLUDEed by data, etc.) wrapped up together and %INCLUDEed by
a single load.sas file (also embedded inside the zip). a single load.sas file (also embedded inside the zip).
*/ */
/*** HELP END ***/ /*** HELP END ***/
@@ -81,7 +81,7 @@
*/ */
)/secure )/secure
/*** HELP END ***/ /*** HELP END ***/
des = 'Macro to load SAS package, version 20200911. Run %loadPackage() for help info.' des = 'Macro to load SAS package, version 20201001. Run %loadPackage() for help info.'
; ;
%if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then %if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then
%do; %do;
@@ -96,7 +96,7 @@ des = 'Macro to load SAS package, version 20200911. Run %loadPackage() for help
%put # This is short help information for the loadPackage macro #; %put # This is short help information for the loadPackage macro #;
%put ###############################################################################; %put ###############################################################################;
%put # #; %put # #;
%put # Macro to load SAS packages, version 20200911 #; %put # Macro to load SAS packages, version 20201001 #;
%put # #; %put # #;
%put # A SAS package is a zip file containing a group #; %put # A SAS package is a zip file containing a group #;
%put # of SAS codes (macros, functions, data steps generating #; %put # of SAS codes (macros, functions, data steps generating #;
@@ -248,7 +248,7 @@ des = 'Macro to load SAS package, version 20200911. Run %loadPackage() for help
*/ */
)/secure )/secure
/*** HELP END ***/ /*** HELP END ***/
des = 'Macro to unload SAS package, version 20200911. Run %unloadPackage() for help info.' des = 'Macro to unload SAS package, version 20201001. Run %unloadPackage() for help info.'
; ;
%if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then %if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then
%do; %do;
@@ -263,7 +263,7 @@ des = 'Macro to unload SAS package, version 20200911. Run %unloadPackage() for h
%put # This is short help information for the unloadPackage macro #; %put # This is short help information for the unloadPackage macro #;
%put ###############################################################################; %put ###############################################################################;
%put # #; %put # #;
%put # Macro to unload SAS packages, version 20200911 #; %put # Macro to unload SAS packages, version 20201001 #;
%put # #; %put # #;
%put # A SAS package is a zip file containing a group #; %put # A SAS package is a zip file containing a group #;
%put # of SAS codes (macros, functions, data steps generating #; %put # of SAS codes (macros, functions, data steps generating #;
@@ -383,7 +383,7 @@ des = 'Macro to unload SAS package, version 20200911. Run %unloadPackage() for h
*/ */
)/secure )/secure
/*** HELP END ***/ /*** HELP END ***/
des = 'Macro to get help about SAS package, version 20200911. Run %helpPackage() for help info.' des = 'Macro to get help about SAS package, version 20201001. Run %helpPackage() for help info.'
; ;
%if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then %if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then
%do; %do;
@@ -398,7 +398,7 @@ des = 'Macro to get help about SAS package, version 20200911. Run %helpPackage()
%put # This is short help information for the helpPackage macro #; %put # This is short help information for the helpPackage macro #;
%put ###############################################################################; %put ###############################################################################;
%put # #; %put # #;
%put # Macro to get help about SAS packages, version 20200911 #; %put # Macro to get help about SAS packages, version 20201001 #;
%put # #; %put # #;
%put # A SAS package is a zip file containing a group #; %put # A SAS package is a zip file containing a group #;
%put # of SAS codes (macros, functions, data steps generating #; %put # of SAS codes (macros, functions, data steps generating #;
@@ -504,7 +504,7 @@ TODO:
- add MD5(&packageName.) value hash instead "package" word in filenames [DONE] - add MD5(&packageName.) value hash instead "package" word in filenames [DONE]
*/ */
/* Macros to install SAS packages, version 20200911 */ /* Macros to install SAS packages, version 20201001 */
/* A SAS package is a zip file containing a group of files /* A SAS package is a zip file containing a group of files
with SAS code (macros, functions, data steps generating with SAS code (macros, functions, data steps generating
data, etc.) wrapped up together and %INCLUDEed by data, etc.) wrapped up together and %INCLUDEed by
@@ -518,8 +518,9 @@ TODO:
, replace = 1 /* 1 = replace if the package already exist, 0 = otherwise */ , replace = 1 /* 1 = replace if the package already exist, 0 = otherwise */
) )
/secure /secure
minoperator
/*** HELP END ***/ /*** HELP END ***/
des = 'Macro to install SAS package, version 20200911. Run %%installPackage() for help info.' des = 'Macro to install SAS package, version 20201001. Run %%installPackage() for help info.'
; ;
%if (%superq(packagesNames) = ) OR (%qupcase(&packagesNames.) = HELP) %then %if (%superq(packagesNames) = ) OR (%qupcase(&packagesNames.) = HELP) %then
%do; %do;
@@ -534,7 +535,7 @@ des = 'Macro to install SAS package, version 20200911. Run %%installPackage() fo
%put # This is short help information for the installPackage macro #; %put # This is short help information for the installPackage macro #;
%put #########################################################################################; %put #########################################################################################;
%put # #; %put # #;
%put # Macro to install SAS packages, version 20200911 #; %put # Macro to install SAS packages, version 20201001 #;
%put # #; %put # #;
%put # A SAS package is a zip file containing a group #; %put # A SAS package is a zip file containing a group #;
%put # of SAS codes (macros, functions, data steps generating #; %put # of SAS codes (macros, functions, data steps generating #;
@@ -552,11 +553,15 @@ des = 'Macro to install SAS package, version 20200911. Run %%installPackage() fo
%put # Required and not null, default use case: #; %put # Required and not null, default use case: #;
%put # %nrstr(%%installPackage(myPackage1 myPackage2)). #; %put # %nrstr(%%installPackage(myPackage1 myPackage2)). #;
%put # If empty displays this help information. #; %put # If empty displays this help information. #;
%put # If the package name is "SPFinit" or "SASPackagesFramework" #;
%put # then the framework itself is downloaded. #;
%put # #; %put # #;
%put # sourcePath= Location of the package, e.g. "www.some.web.page/" #; %put # sourcePath= Location of the package, e.g. "www.some.web.page/" #;
%put # Mind the "/" at the end of the path! #; %put # Mind the "/" at the end of the path! #;
%put # Current default location: #; %put # Current default location for packages is: #;
%put # https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/master/packages/ #; %put # https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/master/packages/ #;
%put # Current default location for the framework is: #;
%put # https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/master/SPF/ #;
%put # #; %put # #;
%put # replace= With default value of 1 it causes existing package file #; %put # replace= With default value of 1 it causes existing package file #;
%put # to be replaceed by new downloaded file. #; %put # to be replaceed by new downloaded file. #;
@@ -623,9 +628,21 @@ des = 'Macro to install SAS package, version 20200911. Run %%installPackage() fo
%let out = o%sysfunc(md5(&packageName.),hex7.); %let out = o%sysfunc(md5(&packageName.),hex7.);
/*options MSGLEVEL=i;*/ /*options MSGLEVEL=i;*/
%if %upcase(&packageName.) in (SPFINIT SASPACKAGEFRAMEWORK SASPACKAGESFRAMEWORK) %then
filename &in URL "&sourcePath.%lowcase(&packageName.).zip" recfm=N lrecl=1; %do;
filename &out "%sysfunc(pathname(packages))/%lowcase(&packageName.).zip" recfm=N lrecl=1; /* allows to install/download the framework file like any other package */
filename &in URL
"https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/master/SPF/SPFinit.sas"
recfm=N lrecl=1;
filename &out
"%sysfunc(pathname(packages))/SPFinit.sas"
recfm=N lrecl=1;
%end;
%else
%do;
filename &in URL "&sourcePath.%lowcase(&packageName.).zip" recfm=N lrecl=1;
filename &out "%sysfunc(pathname(packages))/%lowcase(&packageName.).zip" recfm=N lrecl=1;
%end;
/* /*
filename in list; filename in list;
filename out list; filename out list;
@@ -810,7 +827,7 @@ des = 'Macro to install SAS package, version 20200911. Run %%installPackage() fo
/* Macro to list SAS packages in packages folder. /* Macro to list SAS packages in packages folder.
Version 20200911 Version 20201001
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, data steps generating of SAS codes (macros, functions, data steps generating
@@ -830,7 +847,7 @@ des = 'Macro to install SAS package, version 20200911. Run %%installPackage() fo
%macro listPackages()/PARMBUFF %macro listPackages()/PARMBUFF
des = 'Macro to list SAS packages from `packages` fileref, type %listPackages(HELP) for help, version 20200911.' des = 'Macro to list SAS packages from `packages` fileref, type %listPackages(HELP) for help, version 20201001.'
; ;
%if %QUPCASE(&SYSPBUFF.) = %str(%(HELP%)) %then %if %QUPCASE(&SYSPBUFF.) = %str(%(HELP%)) %then
%do; %do;
@@ -845,7 +862,7 @@ des = 'Macro to list SAS packages from `packages` fileref, type %listPackages(HE
%put # This is short help information for the listPackages macro #; %put # This is short help information for the listPackages macro #;
%put ########################################################################################; %put ########################################################################################;
%put # #; %put # #;
%put # Macro to list available SAS packages, version 20200911 #; %put # Macro to list available SAS packages, version 20201001 #;
%put # #; %put # #;
%put # A SAS package is a zip file containing a group #; %put # A SAS package is a zip file containing a group #;
%put # of SAS codes (macros, functions, data steps generating #; %put # of SAS codes (macros, functions, data steps generating #;
@@ -975,7 +992,7 @@ options ls = &ls_tmp. ps = &ps_tmp. &notes_tmp. &source_tmp.;
/* Macro to generate SAS packages. /* Macro to generate SAS packages.
Version 20200911 Version 20201001
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, data steps generating of SAS codes (macros, functions, data steps generating
@@ -998,7 +1015,7 @@ options ls = &ls_tmp. ps = &ps_tmp. &notes_tmp. &source_tmp.;
dependencies in loading */ dependencies in loading */
)/secure )/secure
/*** HELP END ***/ /*** HELP END ***/
des = 'Macro to generate SAS packages, version 20200911. Run %generatePackage() for help info.' des = 'Macro to generate SAS packages, version 20201001. Run %generatePackage() for help info.'
; ;
%if (%superq(filesLocation) = ) OR (%qupcase(&filesLocation.) = HELP) %then %if (%superq(filesLocation) = ) OR (%qupcase(&filesLocation.) = HELP) %then
%do; %do;
@@ -1013,7 +1030,7 @@ des = 'Macro to generate SAS packages, version 20200911. Run %generatePackage()
%put # This is short help information for the generatePackage macro #; %put # This is short help information for the generatePackage macro #;
%put ###############################################################################; %put ###############################################################################;
%put # #; %put # #;
%put # Macro to generate SAS packages, version 20200911 #; %put # Macro to generate SAS packages, version 20201001 #;
%put # #; %put # #;
%put # A SAS package is a zip file containing a group #; %put # A SAS package is a zip file containing a group #;
%put # of SAS codes (macros, functions, data steps generating #; %put # of SAS codes (macros, functions, data steps generating #;
@@ -2215,7 +2232,7 @@ data _null_;
put ' end ; '; put ' end ; ';
%end; %end;
put 'put "***"; put "* SAS package generated by generatePackage, version 20200911 *"; put "***";'; put 'put "***"; put "* SAS package generated by generatePackage, version 20201001 *"; put "***";';
put 'run; ' /; put 'run; ' /;
@@ -2359,23 +2376,26 @@ filename &_LIC_. clear;
filename &zipReferrence. clear; filename &zipReferrence. clear;
/* create hash SHA256 id */ /* create hash SHA256 id */
filename &zipReferrence. "&filesLocation./%lowcase(&packageName.).zip"; %if %sysfunc(exist(sashelp.vfunc, VIEW)) %then
filename &zipReferrence. list; %do;
data _null_; filename &zipReferrence. "&filesLocation./%lowcase(&packageName.).zip";
set sashelp.vfunc(keep=fncname); filename &zipReferrence. list;
where fncname = "HASHING_FILE"; data _null_;
call execute(' set sashelp.vfunc(keep=fncname);
data the_SHA256_hash_id; where fncname = "HASHING_FILE";
SHA256 = HASHING_FILE("SHA256", "&zipReferrence.", 4); call execute('
lable SHA256 = "The SHA256 hash digest for package &packageName."; data the_SHA256_hash_id;
put SHA256=; SHA256 = HASHING_FILE("SHA256", "&zipReferrence.", 4);
run; lable SHA256 = "The SHA256 hash digest for package &packageName.:";
proc print data = the_SHA256_hash_id noobs label; put SHA256=;
run; run;
'); proc print data = the_SHA256_hash_id noobs label;
stop; run;
run; ');
filename &zipReferrence. clear; stop;
run;
filename &zipReferrence. clear;
%end;
/*+++++++++++++++++++++++*/ /*+++++++++++++++++++++++*/
@@ -2709,7 +2729,7 @@ TODO: (in Polish)
*/ */
)/secure )/secure
/*** HELP END ***/ /*** HELP END ***/
des = 'Macro to load multiple SAS packages at one run, version 20200911. Run %loadPackages() for help info.' des = 'Macro to load multiple SAS packages at one run, version 20201001. Run %loadPackages() for help info.'
parmbuff parmbuff
; ;
%if (%superq(packagesNames) = ) OR (%qupcase(&packagesNames.) = HELP) %then %if (%superq(packagesNames) = ) OR (%qupcase(&packagesNames.) = HELP) %then
@@ -2725,7 +2745,7 @@ parmbuff
%put # This is short help information for the loadPackageS macro #; %put # This is short help information for the loadPackageS macro #;
%put ###############################################################################; %put ###############################################################################;
%put # #; %put # #;
%put # Macro wrapper for the loadPackage macro, version 20200911 #; %put # Macro wrapper for the loadPackage macro, version 20201001 #;
%put # #; %put # #;
%put # A SAS package is a zip file containing a group #; %put # A SAS package is a zip file containing a group #;
%put # of SAS codes (macros, functions, data steps generating #; %put # of SAS codes (macros, functions, data steps generating #;
@@ -2780,7 +2800,7 @@ parmbuff
%let packagesNames = %qsysfunc(compress(%qsubstr(&syspbuff., 2, %eval(&lengthOfsyspbuff.-2)), %str((._,)), KDA)); %let packagesNames = %qsysfunc(compress(%qsubstr(&syspbuff., 2, %eval(&lengthOfsyspbuff.-2)), %str((._,)), KDA));
%let numberOfPackagesNames = %qsysfunc(countw(&packagesNames., %str(,))); %let numberOfPackagesNames = %qsysfunc(countw(&packagesNames., %str(,)));
%put NOTE: List op packages to be loaded contains &numberOfPackagesNames. element(s).; %put NOTE: List of packages to be loaded contains &numberOfPackagesNames. element(s).;
%put NOTE- The list is: &packagesNames..; %put NOTE- The list is: &packagesNames..;
%put NOTE- ; %put NOTE- ;
@@ -2810,7 +2830,7 @@ parmbuff
hashing_file() function, SAS 9.4M6 */ hashing_file() function, SAS 9.4M6 */
)/secure )/secure
/*** HELP END ***/ /*** HELP END ***/
des = 'Macro to verify SAS package with the hash digest, version 20200911. Run %verifyPackage() for help info.' des = 'Macro to verify SAS package with the hash digest, version 20201001. Run %verifyPackage() for help info.'
; ;
%if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then %if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then
%do; %do;
@@ -2825,7 +2845,7 @@ des = 'Macro to verify SAS package with the hash digest, version 20200911. Run %
%put # This is short help information for the verifyPackage macro #; %put # This is short help information for the verifyPackage macro #;
%put ###############################################################################; %put ###############################################################################;
%put # #; %put # #;
%put # Macro to verify SAS package with it hash digest, version 20200911 #; %put # Macro to verify SAS package with it hash digest, version 20201001 #;
%put # #; %put # #;
%put # A SAS package is a zip file containing a group #; %put # A SAS package is a zip file containing a group #;
%put # of SAS codes (macros, functions, data steps generating #; %put # of SAS codes (macros, functions, data steps generating #;
@@ -2901,12 +2921,16 @@ des = 'Macro to verify SAS package with the hash digest, version 20200911. Run %
/* create hash SHA256 id *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* create hash SHA256 id *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
%local HASHING_FILE_exist; %local HASHING_FILE_exist;
%let HASHING_FILE_exist = 0; %let HASHING_FILE_exist = 0;
data _null_;
set sashelp.vfunc(keep=fncname); %if %sysfunc(exist(sashelp.vfunc, VIEW)) %then
where fncname = "HASHING_FILE"; %do;
call symputX('HASHING_FILE_exist', 1, "L"); data _null_;
stop; set sashelp.vfunc(keep=fncname);
run; where fncname = "HASHING_FILE";
call symputX('HASHING_FILE_exist', 1, "L");
stop;
run;
%end;
%if &HASHING_FILE_exist. = 1 %then %if &HASHING_FILE_exist. = 1 %then
%do; %do;