diff --git a/.gitpod.dockerfile b/.gitpod.dockerfile deleted file mode 100644 index 6b680a1..0000000 --- a/.gitpod.dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM gitpod/workspace-full - -RUN sudo apt-get update \ - && sudo apt-get install -y doxygen \ - && sudo apt-get install -y graphviz \ - && sudo rm -rf /var/lib/apt/lists/* diff --git a/.gitpod.yml b/.gitpod.yml deleted file mode 100644 index b825a64..0000000 --- a/.gitpod.yml +++ /dev/null @@ -1,27 +0,0 @@ -tasks: - - init: npm install -g npm - - command: npm i - - command: npm i -g @sasjs/cli - -image: - file: .gitpod.dockerfile -vscode: - extensions: - - sasjs.sasjs-for-vscode - -github: - prebuilds: - # enable for the master/default branch (defaults to true) - master: true - # enable for all branches in this repo (defaults to false) - branches: false - # enable for pull requests coming from this repo (defaults to true) - pullRequests: true - # enable for pull requests coming from forks (defaults to false) - pullRequestsFromForks: true - # add a "Review in Gitpod" button as a comment to pull requests (defaults to true) - addComment: true - # add a "Review in Gitpod" button to pull requests (defaults to false) - addBadge: false - # add a label once the prebuild is ready to pull requests (defaults to false) - addLabel: prebuilt-in-gitpod diff --git a/.npmignore b/.npmignore index 8ea87e4..c9a7666 100644 --- a/.npmignore +++ b/.npmignore @@ -1,6 +1,5 @@ all.sas build.py -.gitpod* tests/ sasjs/ .github/ diff --git a/all.sas b/all.sas index ae29d40..f008c4e 100644 --- a/all.sas +++ b/all.sas @@ -26428,6 +26428,7 @@ libname &libref1a JSON fileref=&fname1a; /* %put Getting object uri from &libref1a..items; */ data _null_; length contenttype name $1000; + call missing(of _all_); set &libref1a..items; if contenttype='jobDefinition' and upcase(name)="%upcase(&name)" then do; call symputx('uri',cats("&base_uri",uri),'l'); @@ -30910,6 +30911,117 @@ endsub; %end; %mend mcf_string2file;/** + @file mx_createjob.sas + @brief Create a job in SAS 9, Viya or SASjs + @details Creates a Stored Process in SAS 9, a Job Execution Service in SAS + Viya, or a Stored Program on SASjs Server - depending on the executing + environment. + +Usage: + + %* compile macros ; + filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas"; + %inc mc; + + %* write some code; + filename ft15f001 temp; + parmcards4; + data example1; + set sashelp.class; + run; + ;;;; + + %* create the job; + %mx_createjob(path=/Public/app/jobs,name=myjob,replace=YES) + +

SAS Macros

+ @li mf_getplatform.sas + @li mm_createstp.sas + @li ms_createfile.sas + @li mv_createjob.sas + + @param [in,out] path= The full folder path where the job will be created + @param [in,out] name= Job name. Avoid spaces. + @param [in] desc= The description of the job (optional) + @param [in] precode= Space separated list of filerefs, pointing to the code + that needs to be attached to the beginning of the job (optional) + @param [in] code= (ft15f001) Space seperated fileref(s) of the actual code to + be added + @param [in] replace= (YES) Select YES to replace any existing job in that + location + @param [in] mDebug= (0) set to 1 to show debug messages in the log + + @author Allan Bowe + +

Related Macros

+ @li mx_createjob.test.sas + @li mx_createwebservice.sas + +**/ + +%macro mx_createjob(path=HOME + ,name=initJob + ,precode= + ,code=ft15f001 + ,desc=This job was created by the mx_createjob macro + ,replace=YES + ,mdebug=0 +)/*/STORE SOURCE*/; + +%if &syscc ge 4 %then %do; + %put syscc=&syscc - &sysmacroname will not execute in this state; + %return; +%end; + +/* combine precode and code into a single file */ +%local tempref x fref freflist; +%let tempref=%mf_getuniquefileref(); +%local work tmpfile; +%let work=%sysfunc(pathname(work)); +%let tmpfile=&tempref..sas; +filename &tempref "&work/&tmpfile"; +%let freflist=&precode &code ; +%do x=1 %to %sysfunc(countw(&freflist)); + %let fref=%scan(&freflist,&x); + %put &sysmacroname: adding &fref; + data _null_; + file &tempref lrecl=3000 termstr=crlf mod; + infile &fref lrecl=3000; + input; + put _infile_; + run; +%end; + +%local platform; %let platform=%mf_getplatform(); +%if &platform=SASVIYA %then %do; + %if "&path"="HOME" %then %let path=/Users/&sysuserid/My Folder; + %mv_createjob(path=&path + ,name=&name + ,code=&tempref + ,desc=&desc + ,replace=&replace + ) +%end; +%else %if &platform=SASJS %then %do; + %if "&path"="HOME" %then %let path=/Users/&_sasjs_username/My Folder; + %ms_createfile(&path/&name..sas + ,inref=&tempref + ,mdebug=&mdebug + ) +%end; +%else %do; + %if "&path"="HOME" %then %let path=/User Folders/&_METAPERSON/My Folder; + %mm_createstp(stpname=&name + ,filename=&tmpfile + ,directory=&work + ,tree=&path + ,stpdesc=&desc + ,mDebug=&mdebug + ) +%end; +filename &tempref clear; +%mend mx_createjob; +/** @file mx_createwebservice.sas @brief Create a web service in SAS 9, Viya or SASjs @details Creates a SASJS ready Stored Process in SAS 9, a Job Execution @@ -30959,6 +31071,9 @@ Usage: @author Allan Bowe +

Related Macros

+ @li mx_createjob.sas + **/ %macro mx_createwebservice(path=HOME diff --git a/tests/x-platform/mx_createjob.test.sas b/tests/x-platform/mx_createjob.test.sas new file mode 100644 index 0000000..5c958d8 --- /dev/null +++ b/tests/x-platform/mx_createjob.test.sas @@ -0,0 +1,304 @@ +/** + @file + @brief Testing mx_createjob.sas macro + + Be sure to run %let mcTestAppLoc=/Public/temp/macrocore; when + running in Studio + +

SAS Macros

+ @li mx_createjob.sas + @li mp_assert.sas + @li mf_getuniquefileref.sas + @li mp_assertscope.sas + +**/ + +/** + * Test 1 - Basic job creation with default parameters + * Also checking for scope leakage + */ +filename ft15f001 temp; +parmcards4; + data example1; + set sashelp.class; + run; + %put Job executed successfully; +;;;; +%mp_assertscope(SNAPSHOT) +%mx_createjob(path=&mcTestAppLoc/jobs,name=testjob1,replace=YES) +%mp_assertscope(COMPARE) + +%mp_assert( + iftrue=(&syscc=0), + desc=Test 1: No errors after basic job creation, + outds=work.test_results +) + +/** + * Test 2 - Job creation with custom description + */ +filename ft15f001 temp; +parmcards4; + data example2; + set sashelp.cars; + run; +;;;; +%mx_createjob( + path=&mcTestAppLoc/jobs, + name=testjob2, + desc=Custom job description for testing, + replace=YES +) + +%mp_assert( + iftrue=(&syscc=0), + desc=Test 2: Job created with custom description, + outds=work.test_results +) + +/** + * Test 3 - Job creation with precode + */ +filename precode1 temp; +data _null_; + file precode1; + put '%let testvar=PreCodeValue;'; + put '%put &=testvar;'; +run; + +filename ft15f001 temp; +parmcards4; + data example3; + set sashelp.class; + precode_var="&testvar"; + run; +;;;; +%mx_createjob( + path=&mcTestAppLoc/jobs, + name=testjob3, + precode=precode1, + replace=YES +) + +%mp_assert( + iftrue=(&syscc=0), + desc=Test 3: Job created with precode parameter, + outds=work.test_results +) + +filename precode1 clear; + +/** + * Test 4 - Job creation with multiple code filerefs + */ +%let code1=%mf_getuniquefileref(); +%let code2=%mf_getuniquefileref(); + +filename &code1 temp; +data _null_; + file &code1; + put 'data work.part1;'; + put ' set sashelp.class(obs=5);'; + put 'run;'; +run; + +filename &code2 temp; +data _null_; + file &code2; + put 'data work.part2;'; + put ' set sashelp.class(firstobs=6);'; + put 'run;'; +run; + +%mx_createjob( + path=&mcTestAppLoc/jobs, + name=testjob4, + code=&code1 &code2, + replace=YES +) + +%mp_assert( + iftrue=(&syscc=0), + desc=Test 4: Job created with multiple code filerefs, + outds=work.test_results +) + +filename &code1 clear; +filename &code2 clear; + +/** + * Test 5 - Job creation with both precode and multiple code files + */ +%let pre1=%mf_getuniquefileref(); +%let pre2=%mf_getuniquefileref(); +%let main1=%mf_getuniquefileref(); + +filename &pre1 temp; +data _null_; + file &pre1; + put '%let globalvar1=Value1;'; +run; + +filename &pre2 temp; +data _null_; + file &pre2; + put '%let globalvar2=Value2;'; +run; + +filename &main1 temp; +data _null_; + file &main1; + put 'data work.combined;'; + put ' var1="&globalvar1";'; + put ' var2="&globalvar2";'; + put ' output;'; + put 'run;'; +run; + +%mx_createjob( + path=&mcTestAppLoc/jobs, + name=testjob5, + precode=&pre1 &pre2, + code=&main1, + desc=Job with multiple precode and code files, + replace=YES +) + +%mp_assert( + iftrue=(&syscc=0), + desc=Test 5: Job created with multiple precode and code files, + outds=work.test_results +) + +filename &pre1 clear; +filename &pre2 clear; +filename &main1 clear; + +/** + * Test 6 - Job creation with special characters in code + */ +filename ft15f001 temp; +parmcards4; + data example6; + length text $200; + text='Special chars: & % $ # @ !'; + output; + text="Quotes: 'single' and ""double"""; + output; + run; + %put Test with special characters; +;;;; +%mx_createjob( + path=&mcTestAppLoc/jobs, + name=testjob6, + desc=Job with special characters in code, + replace=YES +) + +%mp_assert( + iftrue=(&syscc=0), + desc=Test 6: Job created with special characters in code, + outds=work.test_results +) + +/** + * Test 7 - Job creation with macro code + */ +filename ft15f001 temp; +parmcards4; + %macro testmacro(); + data example7; + set sashelp.class; + where age > 12; + run; + %mend testmacro; + + %testmacro() +;;;; +%mx_createjob( + path=&mcTestAppLoc/jobs, + name=testjob7, + desc=Job containing macro definitions, + replace=YES +) + +%mp_assert( + iftrue=(&syscc=0), + desc=Test 7: Job created with macro code, + outds=work.test_results +) + +/** + * Test 8 - Job creation with empty code (edge case) + */ +filename ft15f001 temp; +data _null_; + file ft15f001; + put '/* Empty job for testing */'; +run; + +%mx_createjob( + path=&mcTestAppLoc/jobs, + name=testjob8, + desc=Job with minimal code, + replace=YES +) + +%mp_assert( + iftrue=(&syscc=0), + desc=Test 8: Job created with minimal code, + outds=work.test_results +) + +/** + * Test 9 - Job creation with long code block + */ +filename ft15f001 temp; +data _null_; + file ft15f001; + put 'data work.longtest;'; + do i=1 to 50; + put ' var' i +(-1) '=' i ';'; + end; + put ' output;'; + put 'run;'; +run; + +%mx_createjob( + path=&mcTestAppLoc/jobs, + name=testjob9, + desc=Job with many variables, + replace=YES +) + +%mp_assert( + iftrue=(&syscc=0), + desc=Test 9: Job created with long code block, + outds=work.test_results +) + +/** + * Test 10 - Replace existing job (replace=YES) + */ +filename ft15f001 temp; +parmcards4; + data example10_v1; + set sashelp.class; + run; +;;;; +%mx_createjob(path=&mcTestAppLoc/jobs,name=testjob10,replace=YES) + +/* Now replace it */ +filename ft15f001 temp; +parmcards4; + data example10_v2; + set sashelp.cars; + run; +;;;; +%mx_createjob(path=&mcTestAppLoc/jobs,name=testjob10,replace=YES) + +%mp_assert( + iftrue=(&syscc=0), + desc=Test 10: Job replaced successfully with replace=YES, + outds=work.test_results +) diff --git a/viya/mv_deletejes.sas b/viya/mv_deletejes.sas index 27532a4..994ce93 100644 --- a/viya/mv_deletejes.sas +++ b/viya/mv_deletejes.sas @@ -118,6 +118,7 @@ libname &libref1a JSON fileref=&fname1a; /* %put Getting object uri from &libref1a..items; */ data _null_; length contenttype name $1000; + call missing(of _all_); set &libref1a..items; if contenttype='jobDefinition' and upcase(name)="%upcase(&name)" then do; call symputx('uri',cats("&base_uri",uri),'l'); diff --git a/xplatform/mx_createjob.sas b/xplatform/mx_createjob.sas new file mode 100644 index 0000000..d4b10a5 --- /dev/null +++ b/xplatform/mx_createjob.sas @@ -0,0 +1,111 @@ +/** + @file mx_createjob.sas + @brief Create a job in SAS 9, Viya or SASjs + @details Creates a Stored Process in SAS 9, a Job Execution Service in SAS + Viya, or a Stored Program on SASjs Server - depending on the executing + environment. + +Usage: + + %* compile macros ; + filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas"; + %inc mc; + + %* write some code; + filename ft15f001 temp; + parmcards4; + data example1; + set sashelp.class; + run; + ;;;; + + %* create the job; + %mx_createjob(path=/Public/app/jobs,name=myjob,replace=YES) + +

SAS Macros

+ @li mf_getplatform.sas + @li mm_createstp.sas + @li ms_createfile.sas + @li mv_createjob.sas + + @param [in,out] path= The full folder path where the job will be created + @param [in,out] name= Job name. Avoid spaces. + @param [in] desc= The description of the job (optional) + @param [in] precode= Space separated list of filerefs, pointing to the code + that needs to be attached to the beginning of the job (optional) + @param [in] code= (ft15f001) Space seperated fileref(s) of the actual code to + be added + @param [in] replace= (YES) Select YES to replace any existing job in that + location + @param [in] mDebug= (0) set to 1 to show debug messages in the log + + @author Allan Bowe + +

Related Macros

+ @li mx_createjob.test.sas + @li mx_createwebservice.sas + +**/ + +%macro mx_createjob(path=HOME + ,name=initJob + ,precode= + ,code=ft15f001 + ,desc=This job was created by the mx_createjob macro + ,replace=YES + ,mdebug=0 +)/*/STORE SOURCE*/; + +%if &syscc ge 4 %then %do; + %put syscc=&syscc - &sysmacroname will not execute in this state; + %return; +%end; + +/* combine precode and code into a single file */ +%local tempref x fref freflist; +%let tempref=%mf_getuniquefileref(); +%local work tmpfile; +%let work=%sysfunc(pathname(work)); +%let tmpfile=&tempref..sas; +filename &tempref "&work/&tmpfile"; +%let freflist=&precode &code ; +%do x=1 %to %sysfunc(countw(&freflist)); + %let fref=%scan(&freflist,&x); + %put &sysmacroname: adding &fref; + data _null_; + file &tempref lrecl=3000 termstr=crlf mod; + infile &fref lrecl=3000; + input; + put _infile_; + run; +%end; + +%local platform; %let platform=%mf_getplatform(); +%if &platform=SASVIYA %then %do; + %if "&path"="HOME" %then %let path=/Users/&sysuserid/My Folder; + %mv_createjob(path=&path + ,name=&name + ,code=&tempref + ,desc=&desc + ,replace=&replace + ) +%end; +%else %if &platform=SASJS %then %do; + %if "&path"="HOME" %then %let path=/Users/&_sasjs_username/My Folder; + %ms_createfile(&path/&name..sas + ,inref=&tempref + ,mdebug=&mdebug + ) +%end; +%else %do; + %if "&path"="HOME" %then %let path=/User Folders/&_METAPERSON/My Folder; + %mm_createstp(stpname=&name + ,filename=&tmpfile + ,directory=&work + ,tree=&path + ,stpdesc=&desc + ,mDebug=&mdebug + ) +%end; +filename &tempref clear; +%mend mx_createjob; diff --git a/xplatform/mx_createwebservice.sas b/xplatform/mx_createwebservice.sas index 8e41978..ff2e1ac 100644 --- a/xplatform/mx_createwebservice.sas +++ b/xplatform/mx_createwebservice.sas @@ -48,6 +48,9 @@ Usage: @author Allan Bowe +

Related Macros

+ @li mx_createjob.sas + **/ %macro mx_createwebservice(path=HOME