sasjs / cli

Command line interface for creating, compiling, and building SAS® projects

Home Page:https://cli.sasjs.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

sasjs fs compile {localFolder} {outputProgram}

allanbowe opened this issue · comments

Sometimes (well - oftentimes) when running SAS remotely, it is necessary to configure files (code, data, config) on the server filesystem.

In the absence of ssh or ftp this usually involves a manual process with a client tool or web app.

The purpose of this new command (sasjs fs compile) will be to generate a SAS program that contains the contents of a local directory. By simply running this program in SAS Studio (or wherever), the developer can create a remote copy of a local filesystem.

The generated program will have the following components:

  1. Target Directory switch
  2. Dependent SAS Macros
  3. Directory creation section
  4. Files creation section

In terms of implementation, all the necessary logic should be in the @sasjs/utils repo, so that the functionality may be re-used by SASjs Server and the SASjs VS Code Extension.

The syntax will be as follows:

sasjs fs compile {localFolder} {outputProgram} 
  • "fs" is a new command. compile is the first action. In future we will also have fs create (to run a compiled FS), fs sync (to synchronise a local and remote), fs delete (to delete remote content) and fs move / fs copy (to move / copy remote content)
  • {localFolder} is the local directory in which all content should be added to a SAS program
  • {outputProgram} is the full or relative (to cwd) path to the generated SAS program

Target Directory Switch

The {outputProgram} will NOT contain details of the target folder - allowing a folder to be initially compiled, then subsequently deployed to one or more different target locations.

The implementation is simply to have the following code at the start of the program:

%global fsTarget;
%let compiled_fsTarget=%sysfunc(pathname(work));
%let fsTarget=%sysfunc(coalescec(&fsTarget,&compiled_fsTarget));
options nobomfile;

This will mean that a compiled FS will be deployed to the temporary SAS WORK folder if an fsTarget variable has not been supplied.

Dependent SAS Macros

The following macros should be compiled into the start of the program:

  • mf_mkdir.sas

Directory Creation

A unique set of subdirectories should be extracted, and the following code executed for each child:

%mf_mkdir(&fsTarget/${SUBDIR})
  • ${SUBDIR} should be replaced with the relative child path

Files Creation

Each file must be base64 encoded in a similar way that we do for sasjs web.

The generated SAS for each input file will be as follows:

filename _in64 temp lrecl=99999999;
data _null_;
  file _in64;
  ${COMPILED_CONTENT}
run;
filename _out64 "&fsTarget/${SUBDIR}";
/* convert from base64 */
data _null_;
  length filein 8 fileout 8;
  filein = fopen("_in64",'I',4,'B');
  fileout = fopen("_out64",'A',1,'B');
  char= '20'x;
  do while(fread(filein)=0);
    length raw $4 ;
    do i=1 to 4;
      rc=fget(filein,char,1);
      substr(raw,i,1)=char;
    end;
    rc = fput(fileout, input(raw,$base64X4.));
    rc =fwrite(fileout);
  end;
  rc = fclose(filein);
  rc = fclose(fileout);
run;
filename _in64 clear;
filename _out64 clear;
  • ${COMPILED_CONTENT} should be the base64 encoded version of the file, wrapped in put statements
  • ${SUBDIR} should be replaced with the relative child path

🎉 This issue has been resolved in version 3.20.0 🎉

The release is available on:

Your semantic-release bot 📦🚀