sassoftware / sas-studio-custom-steps

Repository to share SAS Studio Custom Steps. A custom step enables you to create a user interface for SAS Studio users at your site to complete a specific task.
Apache License 2.0
49 stars 64 forks source link

[BUG] Create Listing of Directory - CLOD : Directories do not reflect in output even after option is selected. #163

Closed SundareshSankaran closed 2 months ago

SundareshSankaran commented 2 months ago

Describe the bug Hi @stephanweigandt , I provide some screenshots with the parameters I changed. I explicitly selected Yes to "Include Directories in Output" and chose to list contents only at root level (traverse = No).

I noticed a debug mode and ran it with 1. Log is shown below. I see only the files printed, not the directories.

Note

My ideal output is to list only folders within a directory. But there's no option to say list only folders (directories) in output. This might be a feature request in addition to resolving this issue :).

To Reproduce Steps to reproduce the behavior: Plain vanilla run of custom step in a flow, with only change made to "Traverse subdirectories - No" and Include directories - Yes.

Expected behavior

I expected to see all files and directories as part of output. Repeating note above.

Screenshots Added shots of parameter choices and output.

Screenshot 2024-08-28 at 3 01 52 PM Screenshot 2024-08-28 at 3 01 39 PM

193   /*===========================================================================*
194   * Node name:        PY_SAS_Create Listing Of Directory CLOD
195   * Node ID:          id-1724871581560-7807
196   *
197   * Output Tables:
198   *   WORK.FILENAMES_NEW
199   *
200   * Step name:        PY_SAS_Create Listing Of Directory CLOD
201   * Step path:        /dataFlows/steps/fb7b7264-bd26-4959-81d7-077122da2546
202   * Step description:
203   *----------------------------------------------------------------------------*/
204   
205   /* region: Generated step setup */
206   %_flw_action_start(id-1724871581560-7807);
_FLW_ACTION_START_|2024-08-28T15:05:58+00:00|id-1724871581560-7807
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

207   /* endregion */
208   
209   /* region: Generated macro initialization */
210   
211   /* Define utility macros - BEGIN */
212   
213   /* Macro to get a list of column names */
214   %macro _flw_get_column_list(_flw_prefix = %nrstr(), _delim=%str( ));
215      %do _flw_index=1 %to %unquote(&&&_flw_prefix._count);%unquote(&&&_flw_prefix._&_flw_index._name)%if
215 ! &_flw_index.<%unquote(&&&_flw_prefix._count)%then&_delim.; %end;
216   %mend;
217   
218   /* Macro to delete macro variables with names passed in */
219   %macro _flw_del_macro_vars(_flw_macro_vars_to_delete,_flw_no_warn=Y);
220      %if "&_flw_no_warn"="Y" %then %symdel &_flw_macro_vars_to_delete/NOWARN;
221      %else %symdel &_flw_macro_vars_to_delete;
222   %mend;
223   
224   /* Macro to delete a list of macros with names passed in */
225   %macro _flw_del_macros(_flw_macro_names,_flw_no_warn=Y);
226      %let num=1;
227      %let _flw_local_macros_to_delete=%scan(&_flw_macro_names,&num);
228      %do %while (&_flw_local_macros_to_delete ne );
229         %if "&_flw_no_warn"="Y" %then %sysmacdelete &_flw_local_macros_to_delete/NOWARN;
230         %else %sysmacdelete &_flw_local_macros_to_delete;
231         %let num=%eval(&num+1);
232         %let _flw_local_macros_to_delete=%scan(&_flw_macro_names,&num);
233      %end;
234   %mend;
235   
236   /* Define utility macros - END */
237   
238   /* Macro variables derived from user input to this step - BEGIN */
239   
240   /* Macro variable(s) for UI control with ID of Extension_ui */
241   %let Extension_ui=%nrquote(*);
242   
243   /* Macro variable(s) for UI control with ID of cas_promote_ui */
244   %let cas_promote_ui=0;
245   
246   /* Macro variable(s) for UI control with ID of cas_save_on_disk_ui */
247   %let cas_save_on_disk_ui=0;
248   
249   /* Macro variable(s) for UI control with ID of clod_traverse_directories_ui */
250   %let clod_traverse_directories_ui=0;
251   
252   /* Macro variable(s) for UI control with ID of debug_mode_ui */
253   %let debug_mode_ui=1;
254   
255   /* Macro variable(s) for UI control with ID of include_directories_ui */
256   %let include_directories_ui=1;
257   
258   /* Macro variable(s) for UI control with ID of log_file_path_ui */
259   %let log_file_path_ui=;
260   
261   /* Macro variable(s) for UI control with ID of options_seq_ui */
262   %let options_seq_ui=;
263   
264   /* Macro variable(s) for UI control with ID of outputtable_ui */
265   %let outputtable_ui=WORK.FILENAMES_NEW;
266   %let outputtable_ui_engine=V9;
267   %let outputtable_ui_label=;
268   %let outputtable_ui_lib=WORK;
269   %let outputtable_ui_name=FILENAMES_NEW;
270   %let outputtable_ui_name_base=FILENAMES_NEW;
271   %let outputtable_ui_tblType=table;
272   %let outputtable_ui_type=dataTable;
273   
274   /* Macro variable(s) for UI control with ID of root_directory_ui */
275   %let root_directory_ui=%nrquote(sasserver:/mnt/viya-share/data/sas-studio-custom-steps);
276   
277   /* Macro variable(s) for UI control with ID of write_log_into_file_ui */
278   %let write_log_into_file_ui=0;
279   
280   /* Macro variables derived from user input to this step - END */
281   
282   /* endregion */
283   /* SAS code provided in template section of Custom Step - BEGIN */
284   /******************************************************************************
285   %adjust_option_setings_controlled
286   ________
287   Helps to maintain option changes in a program flow.
288   ______________________________________________________________________________
289   
290   USAGE:                         %adjust_option_setings_controlled(aosc_option_seq = ,
291   aosc_temp_option_storage_ds = ,
292   aosc_running_mode = ,
293   aosc_validvarname_setting =
294   )
295   ______________________________________________________________________________
296   
297   DESCRIPTION:
298   
299   When option changes occur (only single word options allowed), then this macro
300   helps to maintain the original option setting, so at the end, the system can
301   revert back to the original settings.
302   ______________________________________________________________________________
303   
304   INPUT PARAMETERS AND KEYWORDS:
305   
306   aosc_option_seq                    This can be a blank separated list of single word
307   SAS options (e.g. like: source, notes, etc...).
308   If empty nothing happens in CHANGE mode.
309   aosc_temp_option_storage_ds     provide the full dataset name (e.g. work._aosc_setting_storage)
310   where the original option values (of the ones that are
311   provided in AOSC_OPTION_SEQ) are stored.
312   aosc_running_mode                2 modes available:
313   CHANGE: takes settings from AOSC_OPTION_SEQ and applies
314   those
315   RESET: if AOSC_TEMP_OPTION_STORAGE_DS exists, this mode
316   will set options back according to content of
317   this dataset.
318   aosc_validvarname_setting         if not blank, validvarname will be set to the value
319   as provided with this parameter
320   _________________________________________________________________________
321   
322   CALLS: none.
323   ______________________________________________________________________________
324   
325   NOTES: (Initials, date, summary)
326   
327   Stephan Weigandt    20220922  First officially Released Version
328   ______________________________________________________________________________
329   
330   *******************************************************************************/
331   
332   %macro adjust_option_setings_controlled(
333   aosc_option_seq = ,
334   aosc_temp_option_storage_ds = work._aosc_temp_option_storage_ds,
335   aosc_running_mode = ,
336   aosc_validvarname_setting =
337   );
338   
339   
340   %if %upcase("&aosc_running_mode") = "CHANGE" %then
341   %do;
342   data &aosc_temp_option_storage_ds;
343   length
344   new_setting $24.
345   original_setting $24.
346   new_single_setting_seq $256.
347   ;
348   new_setting = "";
349   original_setting = "";
350   new_single_setting_seq = "";
351   numberofsettings = 0;
352   additional_option_setting = 0;
353   if 0;
354   run;
355   
356   %if "&aosc_option_seq" ne "" or
357   "&aosc_validvarname_setting" ne "" %then
358   %do;
359   data &aosc_temp_option_storage_ds;
360   length
361   new_setting $24.
362   original_setting $24.
363   new_single_setting_seq $256.
364   ;
365   new_single_setting_seq = strip("&aosc_option_seq");
366   %if "&aosc_validvarname_setting" ne "" %then
367   %do;
368   original_setting = getoption("validvarname");
369   additional_option_setting = 1;
370   new_setting = "&aosc_validvarname_setting";
371   output;
372   call execute("option validvarname = "||new_Setting||";");
373   %end;
374   %if "&aosc_option_seq" ne "" %then
375   %do;
376   numberofsettings = count(new_single_setting_seq, " ") + 1;
377   additional_option_setting = 0;
378   do i = 1 to numberofsettings;
379   new_setting = "";
380   new_setting = scan(new_single_setting_seq, i, " ");
381   if not missing(new_setting) then
382   do;
383   original_setting = getoption(new_setting);
384   output;
385   call execute("option "||new_Setting||";");
386   end;
387   end;
388   %end;
389   run;
390   %end;
391   %end;
392   
393   %if %upcase("&aosc_running_mode") = "RESET" %then
394   %do;
395   %if %sysfunc(exist(&aosc_temp_option_storage_ds)) %then
396   %do;
397   data _null_;
398   set &aosc_temp_option_storage_ds;
399   if additional_option_setting = 1 then
400   do;
401   call execute("option validvarname = "||original_setting||";");
402   end; else
403   do;
404   call execute("option "||original_setting||";");
405   end;
406   run;
407   %end;
408   %end;
409   %mend adjust_option_setings_controlled;
410   
411   /** FOR TESTING ***
412   option nomprint nosource notes ;
413   %let option_seq = mprint notes source;
414   %let running_mode = CHANGE;
415   %let validvarname_setting = any;
416   
417   %put PRECHANGE;
418   %put VALIDVARNAME: %sysfunc(getoption(validvarname));
419   %put SOURCE: %sysfunc(getoption(source));
420   %put NOTES: %sysfunc(getoption(notes));
421   %put MPRINT: %sysfunc(getoption(mprint));
422   
423   %adjust_option_setings_controlled(
424   aosc_option_seq = &option_seq,
425   aosc_running_mode = &running_mode,
426   aosc_validvarname_setting = &validvarname_setting
427   );
428   
429   %put POSTCHANGE;
430   %put VALIDVARNAME: %sysfunc(getoption(validvarname));
431   %put SOURCE: %sysfunc(getoption(source));
432   %put NOTES: %sysfunc(getoption(notes));
433   %put MPRINT: %sysfunc(getoption(mprint));
434   
435   
436   %let running_mode = RESET;
437   
438   %adjust_option_setings_controlled(
439   aosc_running_mode = &running_mode
440   );
441   
442   %put POSTRESET;
443   %put VALIDVARNAME: %sysfunc(getoption(validvarname));
444   %put SOURCE: %sysfunc(getoption(source));
445   %put NOTES: %sysfunc(getoption(notes));
446   %put MPRINT: %sysfunc(getoption(mprint));
447   
448   
449   
450   *********************/
451   
452   /**
453   store current SAS options settings, so they can be reset
454   at the end of processing
455   **/
456   
457   
458   %adjust_option_setings_controlled(
459   aosc_option_seq = &options_seq_ui,
460   aosc_running_mode = CHANGE,
461   aosc_validvarname_setting = any
462   );
NOTE: The data set WORK._AOSC_TEMP_OPTION_STORAGE_DS has 0 observations and 5 variables.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

NOTE: The data set WORK._AOSC_TEMP_OPTION_STORAGE_DS has 1 observations and 4 variables.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

NOTE: CALL EXECUTE generated line.
1    + option validvarname = any                     ;
463   
464   %let clod_delimiter = ;
465   %macro set_os_dependent_values(
466   sodv_delimiter = clod_delimiter
467   );
468   %if %upcase(&SYSSCP) = WIN %then
469   %do;
470   %let &sodv_delimiter = \;
471   %end; %else
472   %do;
473   %let &sodv_delimiter = /;
474   %end;
475   %mend set_os_dependent_values;
476   %set_os_dependent_values(
477   sodv_delimiter = clod_delimiter
478   );
479   
480   /******************************************************************************
481   
482   %list_all_files
483   ________
484   
485   
486   creates a list of files, based on the provided extensions, that are available
487   within a root directory. It automatically also checks all subdirectories.
488   
489   ______________________________________________________________________________
490   
491   
492   USAGE:                         see testing section on the bottom of this code
493   
494   ______________________________________________________________________________
495   
496   DESCRIPTION:
497   
498   This macro creates a SAS dataset that lists all files that can be found within a
499   root directory and all subdirectories under the provided root directory.
500   This can be applied to all available files (by choosing "*" as extension),
501   or for specific extensions.
502   ______________________________________________________________________________
503   
504   
505   INPUT PARAMETERS AND KEYWORDS:
506   
507   laf_root_dir                provide the top level directory from
508   where to search for files.
509   laf_extenstion_to_check     can be the wildcard "*" or
510   any extension, e.g. "CSV", "XLM" etc
511   (provide without quotes)
512   laf_output_ds_file_overview       provide SAS datasets providing
513   LIBNAME and SAS Dataset name
514   ______________________________________________________________________________
515   
516   NOTES: (Initials, date, summary)
517   
518   Stephan Weigandt    20200406  First officially Released Version
519   Stephan Weigandt    20220610  expanded functionality to also cover
520   SAS Content objects
521   ______________________________________________________________________________
522   
523   *******************************************************************************/
524   
525   %macro list_all_files(
526   laf_root_dir,
527   laf_extenstion_to_check,
528   laf_output_ds_file_overview,
529   laf_debug_mode = 0,
530   laf_directory_separator = /,
531   laf_traverse_directories = 1,
532   laf_is_sas_content_directory = 0,
533   laf_iteration_number = 0_0,
534   laf_include_directories = 0
535   );
536   %local
537   filrf
538   rc
539   did
540   memcnt
541   name
542   lal_append_flag
543   lal_length
544   tot_obs
545   table_append_seq
546   laf_full_file_name
547   i
548   laf_debug_text_
549   ;
550   
551   %let laf_debug_text_skipping = INFORMATION: Skipping due to extension:;
552   %let laf_debug_text_scanning = INFORMATION: Scanning next directory:;
553   %let lal_length = %length(&laf_root_dir);
554   %if "%substr(%trim(%left(&laf_root_dir)), &lal_length, 1)" ne
555   "%trim(%left(&laf_directory_separator))" %then
556   %do;
557   %let laf_root_dir = %trim(%left(&laf_root_dir))&laf_directory_separator;
558   %end;
559   %if &laf_iteration_number = 0_0 %then
560   %do;
561   proc datasets lib= work;
562   delete _LAF_spcl_list_files_:;
563   quit;
564   %end;
565   %let laf_do_processing = 1;
566   %if &laf_is_sas_content_directory = 0 %then
567   %do;
568   filename f&laf_iteration_number "&laf_root_dir";
569   %end; %else
570   %do;
571   %let laf_rc = 1;
572   data _null_;
573   length fref $ 8 folderPath $ 1024;
574   folderPath = "&laf_root_dir";
575   fref="__isdir";
576   rcf = filename(fref, ,
577   "filesrvc",
578   cats('folderpath=',quote(strip(folderPath)))
579   );
580   put rcf;
581   call symput ("laf_rc", strip(rcf));
582   run;
583   
584   %if &laf_rc = 0 %then
585   %do;
586   filename f&laf_iteration_number filesrvc folderpath="&laf_root_dir";
587   %end; %else
588   %do;
589   %let laf_do_processing = 0;
590   %end;
591   %end;
592   %let laf_next_iteration = %eval(%scan(&laf_iteration_number, 1, '_') + 1);
593   %let lal_append_flag = 0;
594   %if %sysfunc(exist(work._LAF_spcl_list_files_&laf_iteration_number)) %then
595   %do;
596   data work._LAF_spcl_list_files_&laf_iteration_number._inter;
597   set work._LAF_spcl_list_files_&laf_iteration_number
598   %if %sysfunc(exist(
599   work._LAF_spcl_list_files_&laf_iteration_number._inter
600   )) %then
601   %do;
602   work._LAF_spcl_list_files_&laf_iteration_number._inter
603   %end;
604   ;
605   run;
606   %let lal_append_flag = 1;
607   %end;
608   data work._LAF_spcl_list_files_&laf_iteration_number ;
609   keep
610   directory_path
611   full_file_name
612   file_name
613   is_in_SAS_Content_flag
614   %if &laf_include_directories = 1 %then
615   %do;
616   object_type
617   %end;
618   ;
619   length
620   directory_path $768
621   file_name $256
622   full_file_name $1024
623   %if &laf_include_directories = 1 %then
624   %do;
625   object_type $12
626   %end;
627   ;
628   is_in_SAS_Content_flag = &laf_is_sas_content_directory;
629   directory_path = symget("laf_root_dir");
630   %if &laf_do_processing = 1 %then
631   %do;
632   did = dopen("f&laf_iteration_number");
633   mcount = dnum(did);
634   /**
635   check if directory exists or the correct area is chosen.
636   if not set to 0 to prevent error message
637   **/
638   if missing(mcount) then
639   mcount = 0;
640   do i=1 to mcount;
641   file_name = dread(did, i);
642   fid = mopen(did, file_name);
643   fileext = find(file_name,'.');
644   extension = scan(file_name, -1, '.');
645   /* fid=0 means directory in most cases */
646   full_file_name = STRIP(directory_path)||STRIP(file_name);
647   if fid > 0 or fileext then
648   do;
649   if "&laf_extenstion_to_check" = "*" or
650   upcase(extension) = %upcase("&laf_extenstion_to_check") then
651   do;
652   %if &laf_debug_mode %then
653   %do;
654   put "INFORMATION: Found following file:" full_file_name;
655   %end;
656   %if &laf_include_directories = 1 %then
657   %do;
658   object_type = "file";
659   %end;
660   output;
661   end;
662   %if &laf_debug_mode %then
663   %do;
664   else
665   do;
666   put "&laf_debug_text_skipping" full_file_name;
667   end;
668   %end;
669   end;
670   %if &laf_traverse_directories = 1 %then
671   %do;
672   else
673   do;
674   %if &laf_debug_mode %then
675   %do;
676   put "&laf_debug_text_scanning" full_file_name;
677   %end;
678   %if &laf_include_directories = 1 %then
679   %do;
680   object_type = "folder";
681   output;
682   %end;
683   arg1 = cats('%nrstr(%list_all_files(',
684   full_file_name,
685   ", &laf_extenstion_to_check,"
686   );
687   arg2 = cats("&laf_output_ds_file_overview,
688   laf_debug_mode = &laf_debug_mode,"
689   );
690   arg3 = cats("laf_directory_separator =
691   &laf_directory_separator,
692   laf_traverse_directories =
693   &laf_traverse_directories,"
694   );
695   arg3b = cats("laf_include_directories =
696   &laf_include_directories, "
697   );
698   arg4 = cats("laf_is_sas_content_directory =
699   &laf_is_sas_content_directory,
700   laf_iteration_number =
701   &laf_next_iteration._",i,"))"
702   );
703   call execute(strip(arg1)||
704   strip(arg2)||
705   strip(arg3)||
706   strip(arg3b)||
707   strip(arg4)
708   );
709   end;
710   %end;
711   end;
712   rc = dclose(did);
713   %end;
714   %else
715   %do;
716   full_file_name = STRIP(substr(directory_path,
717   1,
718   length(directory_path)-1)
719   );
720   %if &laf_include_directories = 1 %then
721   %do;
722   object_type = "file";
723   %end;
724   
725   output;
726   %end;
727   run;
728   
729   
730   %let tot_obs = 0;
731   proc sql noprint;
732   select nobs into :tot_obs
733   from dictionary.tables
734   where upcase(libname)='WORK' and
735   upcase(memname)="_LAF_SPCL_LIST_FILES_&laf_iteration_number";
736   quit;
737   %put total records = &tot_obs.;
738   %if &tot_obs = 0 %then
739   %do;
740   proc datasets lib= work;
741   delete _LAF_SPCL_LIST_FILES_&laf_iteration_number;
742   quit;
743   %if lal_append_flag = 1 %then
744   %do;
745   data work._LAF_spcl_list_files_&laf_iteration_number.;
746   set work._LAF_spcl_list_files_&laf_iteration_number._inter;
747   run;
748   proc datasets lib= work;
749   delete _LAF_spcl_list_files_&laf_iteration_number._inter;
750   quit;
751   %end;
752   %end; %else
753   %do;
754   %if lal_append_flag = 1 %then
755   %do;
756   data work._LAF_spcl_list_files_&laf_iteration_number.;
757   set work._LAF_spcl_list_files_&laf_iteration_number.
758   work._LAF_spcl_list_files_&laf_iteration_number._inter;
759   run;
760   proc datasets lib= work;
761   delete _LAF_spcl_list_files_&laf_iteration_number._inter;
762   quit;
763   %end;
764   %end;
765   
766   %if &laf_iteration_number = 0_0 %then
767   %do;
768   %let table_append_seq = ;
769   proc sql noprint;
770   select memname into :table_append_seq separated by " "
771   from dictionary.tables
772   where upcase(libname)='WORK' and
773   upcase(memname)contains"_LAF_SPCL_LIST_FILES_";
774   quit;
775   %if "&table_append_seq" ne "" %then
776   %do;
777   data work._laf_file_overview_sort;
778   set &table_append_seq;
779   run;
780   proc sort data =work._laf_file_overview_sort;
781   by full_file_name
782   %if &laf_include_directories = 1 %then
783   %do;
784   descending object_type
785   %end;
786   ;
787   quit;
788   
789   data &laf_output_ds_file_overview;
790   set work._laf_file_overview_sort;
791   by full_file_name;
792   %if &laf_include_directories = 1 %then
793   %do;
794   if first.full_file_name ne last.full_file_name  then
795   do;
796   object_type = "file";
797   end;
798   %end;
799   if first.full_file_name;
800   run;
801   %end;
802   
803   
804   %end;
805   
806   %if &laf_do_processing = 1 %then
807   %do;
808   filename f&laf_iteration_number clear;
809   %end;
810   %mend list_all_files;
811   /** FOR TESTING ***
812   
813   
814   option mprint source notes;
815   %let root_directory = /Users/<<MYUSERID>>/My Folder/SAS Videos;
816   %let is_content_dir = 0;
817   %let delimiter = /;
818   %let delimiter = \;
819   %let include_directories = 1;
820   %let extension = *;
821   %let overview_ds = work.file_overview;
822   %let traverse_directories = 1;
823   %list_all_files(
824   &root_directory,
825   &extension,
826   &overview_ds,
827   laf_traverse_directories = &traverse_directories,
828   laf_debug_mode = 1,
829   laf_directory_separator = /,
830   laf_is_sas_content_directory = &is_content_dir,
831   laf_include_directories = &include_directories
832   );
833   
834   *********************/
835   /******************************************************************************
836   %wordcnt
837   ________
838   Counts the words in a list
839   ______________________________________________________________________________
840   
841   USAGE:                         %wordcnt(list,delim)
842   ______________________________________________________________________________
843   
844   DESCRIPTION:
845   
846   Finds the number of words/tokens in a string.  The user specifies a
847   delimiter e.g. # to identify what separates the words.  The macro should be
848   called in the following way:
849   e.g. %let x=%wordcnt(item1#item2 item2a#item3, '#').
850   After running the macro x will be assigned the value of wordcnt.
851   ______________________________________________________________________________
852   
853   INPUT PARAMETERS AND KEYWORDS:
854   
855   list            the name of the string.
856   delim           the delimiter e.g. '#'.
857   _________________________________________________________________________
858   
859   CALLS: none.
860   ______________________________________________________________________________
861   
862   NOTES: (Initials, date, summary)
863   
864   Stephan Weigandt    20200406  First officially Released Version
865   ______________________________________________________________________________
866   
867   *******************************************************************************/
868   %macro wordcnt(
869   list,
870   delim
871   )
872   ;
873   %local
874   word
875   wc_count;
876   %let wc_count = 0;
877   %if %quote(&list) ne %then
878   %do;
879   %let word = %scan(%quote(&list), 1, &delim);
880   %let word = %quote(&word);
881   %do %while (&word ne);
882   %let wc_count = %eval(&wc_count + 1);
883   %let word = %scan(%quote(&list), &wc_count+1, &delim);
884   %let word = %quote(&word);
885   %end;
886   %end;
887   &wc_count
888   %mend wordcnt;
889   /** FOR TESTING ***
890   option mprint source notes ;
891   %let item_seq = a b c#d$f g #h#i$j;
892   %let separator = '$' ;
893   %let separator = '#' ;
894   %let separator = ' ' ;
895   %let number_of_items = %wordcnt(&item_seq, &separator);
896   %put &=number_of_items;
897   
898   *********************/
899   %macro execute_all();
900   
901   %let write_log_to_file = &write_log_into_file_ui;
902   %if &write_log_to_file eq 1 %then
903   %do;
904   %let provide_default_log_path = %scan(&log_file_path_ui, 2, ":")/;
905   %let log_file_directory_source_ui = %scan(&log_file_path_ui, 1, ":");
906   
907   %if "%upcase(&log_file_directory_source_ui)" eq "SASSERVER" %then
908   %do;
909   %let log_file_in_SAS_Content = 0;
910   %end; %else
911   %do;
912   %let log_file_in_SAS_Content = 1;
913   %end;
914   
915   /**
916   determine and set todays date
917   **/
918   data _null_;
919   todaysdate = today();
920   year = year(todaysdate);
921   month = put(month(todaysdate), z2.);
922   day = put(day(todaysdate), z2.);
923   nowtime = time();
924   hour = put(hour(nowtime), z2.);
925   minute = put(minute(nowtime), z2.);
926   put minute;
927   timestamp = trim(left(year))||
928   trim(left(month))||
929   trim(left(day))||
930   "_"||
931   trim(left(hour))||
932   trim(left(minute));
933   call symput('timestamp', timestamp);
934   run;
935   %let timestamp = %trim(%left(&timestamp));
936   %if &debug_mode_ui = 1 %then
937   %do;
938   %put INFORMATION: Logfile location: &provide_default_log_path;
939   %put INFORMATION: Logfile name : clod_run_&timestamp..log;
940   %end;
941   
942   
943   %if &log_file_in_SAS_Content = 1 %then
944   %do;
945   filename logfl
946   filesrvc
947   folderpath = "&provide_default_log_path"
948   filename = "clod_run_&timestamp..log";
949   filename printfl
950   filesrvc
951   folderpath = "&provide_default_log_path"
952   filename = "clod_run_&timestamp..out";
953   %end; %else
954   %do;
955   filename logfl "&provide_default_log_path.clod_run_&timestamp..log";
956   filename printfl "&provide_default_log_path.clod_run_&timestamp..out";
957   %end;
958   proc printto
959   log=logfl new
960   print=printfl new;
961   quit;
962   %end;
963   
964   
965   
966   %put     &=debug_mode_ui    ;
967   %put     &=clod_traverse_directories_ui    ;
968   %put     &=extension_ui    ;
969   %put     &=root_directory_ui    ;
970   %put    &=log_file_path_ui;
971   %let target_libname_ui = &outputtable_ui_lib;
972   %let output_dataset_name_ui = &outputtable_ui_name;
973   %put     &=target_libname_ui    ;
974   %put     &=write_log_into_file_ui    ;
975   %put    &=output_dataset_name_ui;
976   %put    &=options_seq_ui;
977   %let root_directory = %scan(&root_directory_ui, 2, ":");
978   %let root_dir_src = %upcase(%scan(&root_directory_ui, 1, ":"));
979   %let is_content_dir = 0;
980   %if %upcase("&root_dir_src") eq "SASCONTENT" %then
981   %do;
982   %let is_content_dir = 1;
983   %end;
984   %put &=root_directory;
985   
986   %let     target_libname    =    &target_libname_ui    ;
987   %let     write_log_into_file    =    &write_log_into_file_ui    ;
988   
989   
990   %let provide_default_log_path = ;
991   %let log_file_directory_source_ui = ;
992   %if "&log_file_path_ui" ne "" %then
993   %do;
994   %let provide_default_log_path = %scan(&log_file_path_ui, 2, ":")/;
995   %let log_file_directory_source_ui = %scan(&log_file_path_ui, 1, ":");
996   %end;
997   %if "%upcase(&log_file_directory_source_ui)" eq "SASSERVER" %then
998   %do;
999   %let install_mode_in_SAS_Content = 0;
1000  %end; %else
1001  %do;
1002  %let install_mode_in_SAS_Content = 1;
1003  %end;
1004  %let target_environment = ;
1005  proc sql noprint;
1006  select distinct(engine)
1007  into :target_environment
1008  from dictionary.libnames
1009  where upcase(libname) = "%upcase(&target_libname_ui)"
1010  ;
1011  quit;
1012  
1013  %if %upcase(&target_environment) = CAS %then
1014  %do;
1015  %if &cas_promote_ui = 1 %then
1016  %do;
1017  proc casutil     incaslib="&target_libname_ui"
1018  outcaslib="&target_libname_ui";
1019  droptable casdata = "&output_dataset_name_ui" quiet;
1020  droptable casdata = "&output_dataset_name_ui" quiet;
1021  quit;
1022  %end;
1023  %end;
1024  
1025  
1026  %let include_directories = 1;
1027  %let overview_ds = &target_libname_ui..&output_dataset_name_ui;
1028  %let traverse_directories = 1;
1029  %list_all_files(
1030  &root_directory,
1031  &extension_ui,
1032  &overview_ds,
1033  laf_traverse_directories = &clod_traverse_directories_ui,
1034  laf_debug_mode = &debug_mode_ui,
1035  laf_directory_separator = &clod_delimiter,
1036  laf_is_sas_content_directory = &is_content_dir,
1037  laf_include_directories = &include_directories_ui
1038  );
1039  
1040  %if %upcase(&target_environment) = CAS %then
1041  %do;
1042  %if &cas_promote_ui = 1 %then
1043  %do;
1044  proc casutil     incaslib="&target_libname_ui"
1045  outcaslib="&target_libname_ui";
1046  promote casdata = "&output_dataset_name_ui"
1047  casout="&output_dataset_name_ui";
1048  %if &cas_save_on_disk_ui = 1 %then
1049  %do;
1050  save     casdata= "&output_dataset_name_ui"
1051  casout="&output_dataset_name_ui" replace;
1052  %end;
1053  quit;
1054  
1055  %end;
1056  
1057  %end;
1058  
1059  %if &write_log_to_file = 1 %then
1060  %do;
1061  proc printto ;
1062  quit;
1063  %end;
1064  
1065  %mend execute_all;
1066  
1067  %execute_all();
DEBUG_MODE_UI=1
CLOD_TRAVERSE_DIRECTORIES_UI=0
EXTENSION_UI=*
ROOT_DIRECTORY_UI=sasserver:/mnt/viya-share/data/sas-studio-custom-steps
LOG_FILE_PATH_UI=
TARGET_LIBNAME_UI=WORK
WRITE_LOG_INTO_FILE_UI=0
OUTPUT_DATASET_NAME_UI=FILENAMES_NEW
OPTIONS_SEQ_UI=
ROOT_DIRECTORY=/mnt/viya-share/data/sas-studio-custom-steps
NOTE: PROCEDURE SQL used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

                                                             Directory
Libref             WORK                                                                                                             
Engine             V9                                                                                                               
Physical Name      /opt/sas/viya/config/var/tmp/compsrv/default/42333e50-aa47-4021-a542-1c78ed1883c5/                               
                   SAS_work1C170000018D_sas-compute-server-63fcf1ec-796e-429b-8d19-78e8da61225b-3875                                
Filename           /opt/sas/viya/config/var/tmp/compsrv/default/42333e50-aa47-4021-a542-1c78ed1883c5/                               
                   SAS_work1C170000018D_sas-compute-server-63fcf1ec-796e-429b-8d19-78e8da61225b-3875                                
Inode Number       5678008                                                                                                          
Access Permission  rwx------                                                                                                        
Owner Name         UNKNOWN                                                                                                          
File Size          4KB                                                                                                              
File Size (bytes)  4096                                                                                                             
                                                         Member
                        #  Name                          Type         File Size  Last Modified
                        1  FILENAMES                     DATA             128KB  28/08/2024 19:05:58        
                        2  FILENAMES_NEW                 DATA             256KB  28/08/2024 19:00:58        
                        3  PROFILE                       CATALOG           12KB  28/08/2024 18:03:14        
                        4  REGSTRY                       ITEMSTOR          32KB  28/08/2024 18:03:14        
                        5  SASGOPT                       CATALOG           12KB  28/08/2024 18:04:16        
                        6  SASMAC3                       CATALOG           20KB  28/08/2024 19:05:57        
                        7  SASMACR                       CATALOG          240KB  28/08/2024 19:05:58        
                        8  _AOSC_TEMP_OPTION_STORAGE_DS  DATA             128KB  28/08/2024 19:05:58        
NOTE: The file WORK._LAF_SPCL_LIST_FILES_: (memtype=DATA) was not found, but appears on a DELETE statement.
NOTE: PROCEDURE DATASETS used (Total process time):
      real time           0.01 seconds
      cpu time            0.02 seconds

INFORMATION: Found following file:/mnt/viya-share/data/sas-studio-custom-steps/CUSTOM_STEPS_LIST.md
INFORMATION: Found following file:/mnt/viya-share/data/sas-studio-custom-steps/SUPPORT.md
INFORMATION: Found following file:/mnt/viya-share/data/sas-studio-custom-steps/CONTRIBUTING.md
INFORMATION: Found following file:/mnt/viya-share/data/sas-studio-custom-steps/README.md
INFORMATION: Found following file:/mnt/viya-share/data/sas-studio-custom-steps/ContributorAgreement.txt
INFORMATION: Found following file:/mnt/viya-share/data/sas-studio-custom-steps/LICENSE
NOTE: The data set WORK._LAF_SPCL_LIST_FILES_0_0 has 6 observations and 5 variables.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.01 seconds

NOTE: PROCEDURE SQL used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

total records =        6
NOTE: PROCEDURE SQL used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

NOTE: There were 6 observations read from the data set WORK._LAF_SPCL_LIST_FILES_0_0.
NOTE: The data set WORK._LAF_FILE_OVERVIEW_SORT has 6 observations and 5 variables.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

NOTE: There were 6 observations read from the data set WORK._LAF_FILE_OVERVIEW_SORT.
NOTE: The data set WORK._LAF_FILE_OVERVIEW_SORT has 6 observations and 5 variables.
NOTE: PROCEDURE SORT used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

NOTE: There were 6 observations read from the data set WORK._LAF_FILE_OVERVIEW_SORT.
NOTE: The data set WORK.FILENAMES_NEW has 6 observations and 5 variables.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

NOTE: Fileref F0_0 has been deassigned.
1068  
1069  /**
1070  Restore original SAS options settings
1071  **/
1072  
1073  %adjust_option_setings_controlled(
1074  aosc_running_mode = RESET
1075  );
NOTE: There were 1 observations read from the data set WORK._AOSC_TEMP_OPTION_STORAGE_DS.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

NOTE: CALL EXECUTE generated line.
1    + option validvarname = ANY                     ;
1076  
1077  %if &debug_mode_ui ne 1 %then
1078  %do;
1079  proc datasets lib=work;
1080  delete
1081  _clod:
1082  _LAF_:
1083  _aosc:
1084  ;
1085  quit;
1086  %end;
1087  
1088  
1089  /* SAS code provided in template section of Custom Step - END */
1090  
1091  /* region: Generated macro cleanup */
1092  
1093  /* Cleanup macros and macro variables - BEGIN */
1094  /* Delete macro variables created in this step */
1095  
1096  %_flw_del_macro_vars( Extension_ui );
1097  %_flw_del_macro_vars( cas_promote_ui );
1098  %_flw_del_macro_vars( cas_save_on_disk_ui );
1099  %_flw_del_macro_vars( clod_traverse_directories_ui );
1100  %_flw_del_macro_vars( debug_mode_ui );
1101  %_flw_del_macro_vars( include_directories_ui );
1102  %_flw_del_macro_vars( log_file_path_ui );
1103  %_flw_del_macro_vars( options_seq_ui );
1104  %_flw_del_macro_vars( outputtable_ui outputtable_ui_engine outputtable_ui_label outputtable_ui_lib outputtable_ui_name
1104! outputtable_ui_name_base
1105                    outputtable_ui_tblType outputtable_ui_type );
1106  %_flw_del_macro_vars( root_directory_ui );
1107  %_flw_del_macro_vars( write_log_into_file_ui );
1108  /* Delete macros defined in this step */
1109  %_flw_del_macros(_flw_get_column_list _flw_del_macro_vars);
1110  
1111  /* Cleanup macros and macro variables - END */
1112  
1113  %sysmacdelete _flw_del_macros;
1114  
1115  /* endregion */
1116  
1117  
1118  /* region: Generated step cleanup for PY_SAS_Create Listing Of Directory CLOD */
1119  %_flw_action_end(id-1724871581560-7807, WORK.FILENAMES_NEW, WORK, "FILENAMES_NEW");
_FLW_ACTION_TABLE_|WORK|FILENAMES_NEW|1
_FLW_ACTION_END_|2024-08-28T15:05:58+00:00|id-1724871581560-7807
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.01 seconds

1120  /* endregion */
1121  
1122  /* region: Generated sub flow cleanup for Obtain a list of all folders with custom steps */
1123  %_flw_action_end(id-1724868400470-1799,,,);
_FLW_ACTION_TABLE_|| |1
_FLW_ACTION_END_|2024-08-28T15:05:58+00:00|id-1724868400470-1799
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

1124  /* endregion */
1125  
1126  /* region: Generated flow cleanup */
1127  %sysmacdelete _flw_action_start;
1128  %sysmacdelete _flw_action_end;
1129  /* endregion */
1130  /* region: Generated postamble */
1131  
1132  /* Close ODS destinations */
1133  &graphterm; ;*';*";*/;run;quit;
1134  quit;run;
1135  ods html5 (id=web) close;
1136  ods listing close;
1137  %if %sysfunc(fileref(_gsfname)) lt 0 %then %do;
1138      filename _gsfname clear;
NOTE: Fileref _GSFNAME has been deassigned.
1139  %end;
1140  
1141  /* endregion */
1142  
1143  
1144  

Environment (please complete the following information):

Additional context Add any other context about the problem here.

snlwih commented 2 months ago

Seems to be fixed by #164, which has been merged.