@sasjs/utils 2.49.0 → 2.49.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fs/internal/helper.js +19 -24
- package/fs/internal/helper.js.map +1 -1
- package/macros/mf_abort.sas +27 -0
- package/macros/mf_dedup.sas +53 -0
- package/macros/mf_deletefile.sas +31 -0
- package/macros/mf_existds.sas +30 -0
- package/macros/mf_existfeature.sas +59 -0
- package/macros/mf_existfileref.sas +33 -0
- package/macros/mf_existfunction.sas +37 -0
- package/macros/mf_existvar.sas +39 -0
- package/macros/mf_existvarlist.sas +56 -0
- package/macros/mf_fmtdttm.sas +42 -0
- package/macros/mf_getapploc.sas +78 -0
- package/macros/mf_getattrc.sas +34 -0
- package/macros/mf_getattrn.sas +34 -0
- package/macros/mf_getengine.sas +54 -0
- package/macros/mf_getfilesize.sas +64 -0
- package/macros/mf_getfmtlist.sas +61 -0
- package/macros/mf_getfmtname.sas +44 -0
- package/macros/mf_getkeyvalue.sas +32 -0
- package/macros/mf_getplatform.sas +75 -0
- package/macros/mf_getquotedstr.sas +57 -0
- package/macros/mf_getschema.sas +43 -0
- package/macros/mf_getuniquefileref.sas +60 -0
- package/macros/mf_getuniquelibref.sas +57 -0
- package/macros/mf_getuniquename.sas +22 -0
- package/macros/mf_getuser.sas +44 -0
- package/macros/mf_getvalue.sas +36 -0
- package/macros/mf_getvarcount.sas +49 -0
- package/macros/mf_getvarformat.sas +72 -0
- package/macros/mf_getvarlen.sas +56 -0
- package/macros/mf_getvarlist.sas +74 -0
- package/macros/mf_getvarnum.sas +58 -0
- package/macros/mf_getvartype.sas +52 -0
- package/macros/mf_getxengine.sas +43 -0
- package/macros/mf_increment.sas +29 -0
- package/macros/mf_isblank.sas +27 -0
- package/macros/mf_isdir.sas +34 -0
- package/macros/mf_isint.sas +36 -0
- package/macros/mf_islibds.sas +40 -0
- package/macros/mf_loc.sas +29 -0
- package/macros/mf_mkdir.sas +67 -0
- package/macros/mf_mval.sas +19 -0
- package/macros/mf_nobs.sas +26 -0
- package/macros/mf_trimstr.sas +50 -0
- package/macros/mf_uid.sas +21 -0
- package/macros/mf_verifymacvars.sas +72 -0
- package/macros/mf_wordsinstr1andstr2.sas +53 -0
- package/macros/mf_wordsinstr1butnotstr2.sas +54 -0
- package/macros/mf_writefile.sas +67 -0
- package/macros/mp_abort.sas +301 -0
- package/macros/mp_appendfile.sas +57 -0
- package/macros/mp_applyformats.sas +181 -0
- package/macros/mp_assert.sas +56 -0
- package/macros/mp_assertcols.sas +145 -0
- package/macros/mp_assertcolvals.sas +168 -0
- package/macros/mp_assertdsobs.sas +121 -0
- package/macros/mp_assertscope.sas +147 -0
- package/macros/mp_base64copy.sas +117 -0
- package/macros/mp_binarycopy.sas +79 -0
- package/macros/mp_chop.sas +194 -0
- package/macros/mp_cleancsv.sas +78 -0
- package/macros/mp_cntlout.sas +85 -0
- package/macros/mp_copyfolder.sas +84 -0
- package/macros/mp_coretable.sas +73 -0
- package/macros/mp_createconstraints.sas +70 -0
- package/macros/mp_createwebservice.sas +32 -0
- package/macros/mp_csv2ds.sas +140 -0
- package/macros/mp_deleteconstraints.sas +52 -0
- package/macros/mp_deletefolder.sas +70 -0
- package/macros/mp_dictionary.sas +52 -0
- package/macros/mp_dirlist.sas +262 -0
- package/macros/mp_distinctfmtvalues.sas +50 -0
- package/macros/mp_dropmembers.sas +46 -0
- package/macros/mp_ds2cards.sas +291 -0
- package/macros/mp_ds2csv.sas +212 -0
- package/macros/mp_ds2ddl.sas +30 -0
- package/macros/mp_ds2fmtds.sas +105 -0
- package/macros/mp_ds2inserts.sas +180 -0
- package/macros/mp_ds2md.sas +103 -0
- package/macros/mp_ds2squeeze.sas +120 -0
- package/macros/mp_dsmeta.sas +110 -0
- package/macros/mp_filtercheck.sas +251 -0
- package/macros/mp_filtergenerate.sas +105 -0
- package/macros/mp_filterstore.sas +254 -0
- package/macros/mp_filtervalidate.sas +105 -0
- package/macros/mp_getcols.sas +67 -0
- package/macros/mp_getconstraints.sas +115 -0
- package/macros/mp_getdbml.sas +335 -0
- package/macros/mp_getddl.sas +400 -0
- package/macros/mp_getformats.sas +124 -0
- package/macros/mp_getmaxvarlengths.sas +130 -0
- package/macros/mp_getpk.sas +281 -0
- package/macros/mp_gitadd.sas +45 -0
- package/macros/mp_gitreleaseinfo.sas +74 -0
- package/macros/mp_gitstatus.sas +67 -0
- package/macros/mp_gsubfile.sas +58 -0
- package/macros/mp_guesspk.sas +332 -0
- package/macros/mp_hashdataset.sas +91 -0
- package/macros/mp_hashdirectory.sas +164 -0
- package/macros/mp_include.sas +106 -0
- package/macros/mp_init.sas +76 -0
- package/macros/mp_jsonout.sas +406 -0
- package/macros/mp_lib2cards.sas +78 -0
- package/macros/mp_lib2inserts.sas +77 -0
- package/macros/mp_loadformat.sas +303 -0
- package/macros/mp_lockanytable.sas +243 -0
- package/macros/mp_lockfilecheck.sas +103 -0
- package/macros/mp_makedata.sas +107 -0
- package/macros/mp_md5.sas +58 -0
- package/macros/mp_perflog.sas +43 -0
- package/macros/mp_prevobs.sas +88 -0
- package/macros/mp_recursivejoin.sas +90 -0
- package/macros/mp_replace.sas +151 -0
- package/macros/mp_reseterror.sas +27 -0
- package/macros/mp_resetoption.sas +39 -0
- package/macros/mp_retainedkey.sas +247 -0
- package/macros/mp_runddl.sas +49 -0
- package/macros/mp_searchcols.sas +103 -0
- package/macros/mp_searchdata.sas +131 -0
- package/macros/mp_setkeyvalue.sas +55 -0
- package/macros/mp_sortinplace.sas +122 -0
- package/macros/mp_stackdiffs.sas +592 -0
- package/macros/mp_storediffs.sas +230 -0
- package/macros/mp_stprequests.sas +74 -0
- package/macros/mp_streamfile.sas +212 -0
- package/macros/mp_testjob.sas +92 -0
- package/macros/mp_testservice.sas +39 -0
- package/macros/mp_testwritespeedlibrary.sas +59 -0
- package/macros/mp_tree.sas +71 -0
- package/macros/mp_unzip.sas +90 -0
- package/macros/mp_updatevarlength.sas +93 -0
- package/macros/mp_validatecol.sas +97 -0
- package/macros/mp_wait4file.sas +35 -0
- package/macros/mp_webin.sas +59 -0
- package/macros/mp_zip.sas +85 -0
- package/package.json +5 -2
- package/scripts/copySASjsCore.ts +36 -0
- package/utils/index.d.ts +1 -2
- package/utils/index.js +2 -3
- package/utils/index.js.map +1 -1
- package/utils/utils.d.ts +1 -0
- package/utils/utils.js +7 -1
- package/utils/utils.js.map +1 -1
- package/utils/getNodeModulePath.d.ts +0 -2
- package/utils/getNodeModulePath.js +0 -83
- package/utils/getNodeModulePath.js.map +0 -1
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Extract the primary key fields from a table or library
|
|
4
|
+
@details Examines the constraints to identify primary key fields - indicated
|
|
5
|
+
by an explicit PK constraint, or a unique index that is also NOT NULL.
|
|
6
|
+
|
|
7
|
+
Can be executed at both table and library level. Supports both BASE engine
|
|
8
|
+
libraries and SQL Server.
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
|
|
12
|
+
proc sql;
|
|
13
|
+
create table work.example(
|
|
14
|
+
TX_FROM float format=datetime19.,
|
|
15
|
+
DD_TYPE char(16),
|
|
16
|
+
DD_SOURCE char(2048),
|
|
17
|
+
DD_SHORTDESC char(256),
|
|
18
|
+
constraint pk primary key(tx_from, dd_type,dd_source),
|
|
19
|
+
constraint unq unique(tx_from, dd_type),
|
|
20
|
+
constraint nnn not null(DD_SHORTDESC)
|
|
21
|
+
);
|
|
22
|
+
%mp_getpk(work,ds=example)
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
|
|
26
|
+
|libref:$8.|dsn:$32.|memtype:$8.|dbms_memtype:$32.|typemem:$8.|memlabel:$256.|nvar:best.|compress:$8.|pk_fields:$512.|
|
|
27
|
+
|---|---|---|---|---|---|---|---|---|
|
|
28
|
+
|WORK|EXAMPLE|DATA| |DATA| |4|NO|TX_FROM DD_TYPE DD_SOURCE|
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@param [in] lib The libref to examine
|
|
32
|
+
@param [in] ds= (0) Select the dataset to examine, else use 0 for all tables
|
|
33
|
+
@param [in] mdebug= (0) Set to 1 to preserve temp tables, print var values etc
|
|
34
|
+
@param [out] outds= (work.mp_getpk) The name of the output table to create.
|
|
35
|
+
|
|
36
|
+
<h4> SAS Macros </h4>
|
|
37
|
+
@li mf_existfeature.sas
|
|
38
|
+
@li mf_getengine.sas
|
|
39
|
+
@li mf_getschema.sas
|
|
40
|
+
@li mp_dropmembers.sas
|
|
41
|
+
@li mp_getconstraints.sas
|
|
42
|
+
|
|
43
|
+
<h4> Related Macros </h4>
|
|
44
|
+
@li mp_getpk.test.sas
|
|
45
|
+
@li mp_guesspk.sas
|
|
46
|
+
|
|
47
|
+
@version 9.3
|
|
48
|
+
@author Macro People Ltd
|
|
49
|
+
**/
|
|
50
|
+
|
|
51
|
+
%macro mp_getpk(
|
|
52
|
+
lib,
|
|
53
|
+
ds=0,
|
|
54
|
+
outds=work.mp_getpk,
|
|
55
|
+
mdebug=0
|
|
56
|
+
)/*/STORE SOURCE*/;
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
%local engine schema ds1 ds2 ds3 dsn tabs1 tabs2 sum pk4sure pkdefault finalpks
|
|
60
|
+
pkfromindex;
|
|
61
|
+
|
|
62
|
+
%let lib=%upcase(&lib);
|
|
63
|
+
%let ds=%upcase(&ds);
|
|
64
|
+
%let engine=%mf_getengine(&lib);
|
|
65
|
+
%let schema=%mf_getschema(&lib);
|
|
66
|
+
|
|
67
|
+
%let ds1=%mf_getuniquename(prefix=getpk_ds1);
|
|
68
|
+
%let ds2=%mf_getuniquename(prefix=getpk_ds2);
|
|
69
|
+
%let ds3=%mf_getuniquename(prefix=getpk_ds3);
|
|
70
|
+
%let tabs1=%mf_getuniquename(prefix=getpk_tabs1);
|
|
71
|
+
%let tabs2=%mf_getuniquename(prefix=getpk_tabs2);
|
|
72
|
+
%let sum=%mf_getuniquename(prefix=getpk_sum);
|
|
73
|
+
%let pk4sure=%mf_getuniquename(prefix=getpk_pk4sure);
|
|
74
|
+
%let pkdefault=%mf_getuniquename(prefix=getpk_pkdefault);
|
|
75
|
+
%let pkfromindex=%mf_getuniquename(prefix=getpk_pkfromindex);
|
|
76
|
+
%let finalpks=%mf_getuniquename(prefix=getpk_finalpks);
|
|
77
|
+
|
|
78
|
+
%local dbg;
|
|
79
|
+
%if &mdebug=1 %then %do;
|
|
80
|
+
%put &sysmacroname entry vars:;
|
|
81
|
+
%put _local_;
|
|
82
|
+
%end;
|
|
83
|
+
%else %let dbg=*;
|
|
84
|
+
|
|
85
|
+
proc sql;
|
|
86
|
+
create table &ds1 as
|
|
87
|
+
select libname as libref
|
|
88
|
+
,upcase(memname) as dsn
|
|
89
|
+
,memtype
|
|
90
|
+
,upcase(name) as name
|
|
91
|
+
,type
|
|
92
|
+
,length
|
|
93
|
+
,varnum
|
|
94
|
+
,label
|
|
95
|
+
,format
|
|
96
|
+
,idxusage
|
|
97
|
+
,notnull
|
|
98
|
+
from dictionary.columns
|
|
99
|
+
where upcase(libname)="&lib"
|
|
100
|
+
%if &ds ne 0 %then %do;
|
|
101
|
+
and upcase(memname)="&ds"
|
|
102
|
+
%end;
|
|
103
|
+
;
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
%if &engine=SQLSVR %then %do;
|
|
107
|
+
proc sql;
|
|
108
|
+
connect using &lib;
|
|
109
|
+
create table work.&ds2 as
|
|
110
|
+
select * from connection to &lib(
|
|
111
|
+
select
|
|
112
|
+
s.name as SchemaName,
|
|
113
|
+
t.name as memname,
|
|
114
|
+
tc.name as name,
|
|
115
|
+
ic.key_ordinal as KeyOrderNr
|
|
116
|
+
from
|
|
117
|
+
sys.schemas s
|
|
118
|
+
inner join sys.tables t on s.schema_id=t.schema_id
|
|
119
|
+
inner join sys.indexes i on t.object_id=i.object_id
|
|
120
|
+
inner join sys.index_columns ic on i.object_id=ic.object_id
|
|
121
|
+
and i.index_id=ic.index_id
|
|
122
|
+
inner join sys.columns tc on ic.object_id=tc.object_id
|
|
123
|
+
and ic.column_id=tc.column_id
|
|
124
|
+
where i.is_primary_key=1
|
|
125
|
+
and s.name=%str(%')&schema%str(%')
|
|
126
|
+
order by t.name, ic.key_ordinal ;
|
|
127
|
+
);disconnect from &lib;
|
|
128
|
+
create table &ds3 as
|
|
129
|
+
select a.*
|
|
130
|
+
,case when b.name is not null then 1 else 0 end as pk_ind
|
|
131
|
+
from work.&ds1 a
|
|
132
|
+
left join work.&ds2 b
|
|
133
|
+
on a.dsn=b.memname
|
|
134
|
+
and upcase(a.name)=upcase(b.name)
|
|
135
|
+
order by libref,dsn;
|
|
136
|
+
%end;
|
|
137
|
+
%else %do;
|
|
138
|
+
|
|
139
|
+
%if &ds = 0 %then %let dsn=;
|
|
140
|
+
|
|
141
|
+
/* get all constraints, in constraint order*/
|
|
142
|
+
%mp_getconstraints(lib=&lib,ds=&dsn,outds=work.&ds2)
|
|
143
|
+
|
|
144
|
+
/* extract cols that are clearly primary keys */
|
|
145
|
+
proc sql;
|
|
146
|
+
create table &pk4sure as
|
|
147
|
+
select libref
|
|
148
|
+
,table_name
|
|
149
|
+
,constraint_name
|
|
150
|
+
,constraint_order
|
|
151
|
+
,column_name as name
|
|
152
|
+
from work.&ds2
|
|
153
|
+
where constraint_type='PRIMARY'
|
|
154
|
+
order by 1,2,3,4;
|
|
155
|
+
|
|
156
|
+
/* extract unique constraints where every col is also NOT NULL */
|
|
157
|
+
proc sql;
|
|
158
|
+
create table &sum as
|
|
159
|
+
select a.libref
|
|
160
|
+
,a.table_name
|
|
161
|
+
,a.constraint_name
|
|
162
|
+
,count(a.column_name) as unq_cnt
|
|
163
|
+
,count(b.column_name) as nul_cnt
|
|
164
|
+
from work.&ds2(where=(constraint_type ='UNIQUE')) a
|
|
165
|
+
left join work.&ds2(where=(constraint_type ='NOT NULL')) b
|
|
166
|
+
on a.libref=b.libref
|
|
167
|
+
and a.table_name=b.table_name
|
|
168
|
+
and a.column_name=b.column_name
|
|
169
|
+
group by 1,2,3
|
|
170
|
+
having unq_cnt=nul_cnt;
|
|
171
|
+
|
|
172
|
+
/* extract cols from the relevant unique constraints */
|
|
173
|
+
create table &pkdefault as
|
|
174
|
+
select a.libref
|
|
175
|
+
,a.table_name
|
|
176
|
+
,a.constraint_name
|
|
177
|
+
,b.constraint_order
|
|
178
|
+
,b.column_name as name
|
|
179
|
+
from &sum a
|
|
180
|
+
left join &ds2(where=(constraint_type ='UNIQUE')) b
|
|
181
|
+
on a.libref=b.libref
|
|
182
|
+
and a.table_name=b.table_name
|
|
183
|
+
and a.constraint_name=b.constraint_name
|
|
184
|
+
order by 1,2,3,4;
|
|
185
|
+
|
|
186
|
+
/* extract cols from the relevant unique INDEXES */
|
|
187
|
+
create table &pkfromindex as
|
|
188
|
+
select libname as libref
|
|
189
|
+
,memname as table_name
|
|
190
|
+
,indxname as constraint_name
|
|
191
|
+
,indxpos as constraint_order
|
|
192
|
+
,name
|
|
193
|
+
from dictionary.indexes
|
|
194
|
+
where nomiss='yes' and unique='yes' and upcase(libname)="&lib"
|
|
195
|
+
%if &ds ne 0 %then %do;
|
|
196
|
+
and upcase(memname)="&ds"
|
|
197
|
+
%end;
|
|
198
|
+
order by 1,2,3,4;
|
|
199
|
+
|
|
200
|
+
/* create one table */
|
|
201
|
+
data &finalpks;
|
|
202
|
+
set &pkdefault &pk4sure &pkfromindex;
|
|
203
|
+
pk_ind=1;
|
|
204
|
+
/* if there are multiple unique constraints, take the first */
|
|
205
|
+
by libref table_name constraint_name;
|
|
206
|
+
retain keepme;
|
|
207
|
+
if first.table_name then keepme=1;
|
|
208
|
+
if first.constraint_name and not first.table_name then keepme=0;
|
|
209
|
+
if keepme=1;
|
|
210
|
+
run;
|
|
211
|
+
|
|
212
|
+
/* join back to starting table */
|
|
213
|
+
proc sql;
|
|
214
|
+
create table &ds3 as
|
|
215
|
+
select a.*
|
|
216
|
+
,b.constraint_order
|
|
217
|
+
,case when b.pk_ind=1 then 1 else 0 end as pk_ind
|
|
218
|
+
from work.&ds1 a
|
|
219
|
+
left join work.&finalpks b
|
|
220
|
+
on a.libref=b.libref
|
|
221
|
+
and a.dsn=b.table_name
|
|
222
|
+
and upcase(a.name)=upcase(b.name)
|
|
223
|
+
order by libref,dsn,constraint_order;
|
|
224
|
+
%end;
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
/* prepare tables */
|
|
228
|
+
proc sql;
|
|
229
|
+
create table work.&tabs1 as select
|
|
230
|
+
libname as libref
|
|
231
|
+
,upcase(memname) as dsn
|
|
232
|
+
,memtype
|
|
233
|
+
%if %mf_existfeature(DBMS_MEMTYPE)=1 %then %do;
|
|
234
|
+
,dbms_memtype
|
|
235
|
+
%end;
|
|
236
|
+
%else %do;
|
|
237
|
+
,'n/a' as dbms_memtype format=$32.
|
|
238
|
+
%end;
|
|
239
|
+
,typemem
|
|
240
|
+
,memlabel
|
|
241
|
+
,nvar
|
|
242
|
+
,compress
|
|
243
|
+
from dictionary.tables
|
|
244
|
+
where upcase(libname)="&lib"
|
|
245
|
+
%if &ds ne 0 %then %do;
|
|
246
|
+
and upcase(memname)="&ds"
|
|
247
|
+
%end;
|
|
248
|
+
;
|
|
249
|
+
data &tabs2;
|
|
250
|
+
set &ds3;
|
|
251
|
+
length pk_fields $512;
|
|
252
|
+
retain pk_fields;
|
|
253
|
+
by libref dsn constraint_order;
|
|
254
|
+
if first.dsn then pk_fields='';
|
|
255
|
+
if pk_ind=1 then pk_fields=catx(' ',pk_fields,name);
|
|
256
|
+
if last.dsn then output;
|
|
257
|
+
run;
|
|
258
|
+
|
|
259
|
+
proc sql;
|
|
260
|
+
create table &outds as
|
|
261
|
+
select a.libref
|
|
262
|
+
,a.dsn
|
|
263
|
+
,a.memtype
|
|
264
|
+
,a.dbms_memtype
|
|
265
|
+
,a.typemem
|
|
266
|
+
,a.memlabel
|
|
267
|
+
,a.nvar
|
|
268
|
+
,a.compress
|
|
269
|
+
,b.pk_fields
|
|
270
|
+
from work.&tabs1 a
|
|
271
|
+
left join work.&tabs2 b
|
|
272
|
+
on a.libref=b.libref
|
|
273
|
+
and a.dsn=b.dsn;
|
|
274
|
+
|
|
275
|
+
/* tidy up */
|
|
276
|
+
%mp_dropmembers(
|
|
277
|
+
&ds1 &ds2 &ds3 &dsn &tabs1 &tabs2 &sum &pk4sure &pkdefault &finalpks,
|
|
278
|
+
iftrue=(&mdebug=0)
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
%mend mp_getpk;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Stages files in a GIT repo
|
|
4
|
+
@details Uses the output dataset from mp_gitstatus.sas to determine the files
|
|
5
|
+
that should be staged.
|
|
6
|
+
|
|
7
|
+
If `STAGED ne "TRUE"` then the file is staged.
|
|
8
|
+
|
|
9
|
+
Usage:
|
|
10
|
+
|
|
11
|
+
%let dir=%sysfunc(pathname(work))/core;
|
|
12
|
+
%let repo=https://github.com/sasjs/core;
|
|
13
|
+
%put source clone rc=%sysfunc(GITFN_CLONE(&repo,&dir));
|
|
14
|
+
%mf_writefile(&dir/somefile.txt,l1=some content)
|
|
15
|
+
%mf_deletefile(&dir/package.json)
|
|
16
|
+
%mp_gitstatus(&dir,outds=work.gitstatus)
|
|
17
|
+
|
|
18
|
+
%mp_gitadd(&dir,inds=work.gitstatus)
|
|
19
|
+
|
|
20
|
+
@param [in] gitdir The directory containing the GIT repository
|
|
21
|
+
@param [in] inds= (work.mp_gitadd) The input dataset with the list of files
|
|
22
|
+
to stage. Will accept the output from mp_gitstatus(), else just use a table
|
|
23
|
+
with the following columns:
|
|
24
|
+
@li path $1024 - relative path to the file in the repo
|
|
25
|
+
@li staged $32 - whether the file is staged (TRUE or FALSE)
|
|
26
|
+
@li status $64 - either new, deleted, or modified
|
|
27
|
+
|
|
28
|
+
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages
|
|
29
|
+
|
|
30
|
+
<h4> Related Files </h4>
|
|
31
|
+
@li mp_gitadd.test.sas
|
|
32
|
+
@li mp_gitstatus.sas
|
|
33
|
+
|
|
34
|
+
**/
|
|
35
|
+
|
|
36
|
+
%macro mp_gitadd(gitdir,inds=work.mp_gitadd,mdebug=0);
|
|
37
|
+
|
|
38
|
+
data _null_;
|
|
39
|
+
set &inds;
|
|
40
|
+
if STAGED ne "TRUE";
|
|
41
|
+
rc=git_index_add("&gitdir",cats(path),status);
|
|
42
|
+
if rc ne 0 or &mdebug=1 then put rc=;
|
|
43
|
+
run;
|
|
44
|
+
|
|
45
|
+
%mend mp_gitadd;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Pulls latest release info from a GIT repository
|
|
4
|
+
@details Useful for grabbing the latest version number or other attributes
|
|
5
|
+
from a GIT server. Supported providers are GitLab and GitHub. Pull requests
|
|
6
|
+
are welcome if you'd like to see additional providers!
|
|
7
|
+
|
|
8
|
+
Note that each provider provides slightly different JSON output. Therefore
|
|
9
|
+
the macro simply extracts the JSON and assigns the libname (using the JSON
|
|
10
|
+
engine).
|
|
11
|
+
|
|
12
|
+
Example usage (eg, to grab latest release version from github):
|
|
13
|
+
|
|
14
|
+
%mp_gitreleaseinfo(GITHUB,sasjs/core,outlib=mylibref)
|
|
15
|
+
|
|
16
|
+
data _null_;
|
|
17
|
+
set mylibref.root;
|
|
18
|
+
putlog TAG_NAME=;
|
|
19
|
+
run;
|
|
20
|
+
|
|
21
|
+
@param [in] provider The GIT provider for the release info. Accepted values:
|
|
22
|
+
@li GITLAB
|
|
23
|
+
@li GITHUB - Tables include root, assets, author, alldata
|
|
24
|
+
@param [in] project The link to the repository. This has different formats
|
|
25
|
+
depending on the vendor:
|
|
26
|
+
@li GITHUB - org/repo, eg sasjs/core
|
|
27
|
+
@li GITLAB - project, eg 1343223
|
|
28
|
+
@param [in] server= (0) If your repo is self-hosted, then provide the domain
|
|
29
|
+
here. Otherwise it will default to the provider domain (eg gitlab.com).
|
|
30
|
+
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages
|
|
31
|
+
@param [out] outlib= (GITREL) The JSON-engine libref to be created, which will
|
|
32
|
+
point at the returned JSON
|
|
33
|
+
|
|
34
|
+
<h4> SAS Macros </h4>
|
|
35
|
+
@li mf_getuniquefileref.sas
|
|
36
|
+
|
|
37
|
+
<h4> Related Files </h4>
|
|
38
|
+
@li mp_gitreleaseinfo.test.sas
|
|
39
|
+
|
|
40
|
+
**/
|
|
41
|
+
|
|
42
|
+
%macro mp_gitreleaseinfo(provider,project,server=0,outlib=GITREL,mdebug=0);
|
|
43
|
+
%local url fref;
|
|
44
|
+
|
|
45
|
+
%let provider=%upcase(&provider);
|
|
46
|
+
|
|
47
|
+
%if &provider=GITHUB %then %do;
|
|
48
|
+
%if "&server"="0" %then %let server=https://api.github.com;
|
|
49
|
+
%let url=&server/repos/&project/releases/latest;
|
|
50
|
+
%end;
|
|
51
|
+
%else %if &provider=GITLAB %then %do;
|
|
52
|
+
%if "&server"="0" %then %let server=https://gitlab.com;
|
|
53
|
+
%let url=&server/api/v4/projects/&project/releases;
|
|
54
|
+
%end;
|
|
55
|
+
|
|
56
|
+
%let fref=%mf_getuniquefileref();
|
|
57
|
+
|
|
58
|
+
proc http method='GET' out=&fref url="&url";
|
|
59
|
+
%if &mdebug=1 %then %do;
|
|
60
|
+
debug level = 3;
|
|
61
|
+
%end;
|
|
62
|
+
run;
|
|
63
|
+
|
|
64
|
+
libname &outlib JSON fileref=&fref;
|
|
65
|
+
|
|
66
|
+
%if &mdebug=1 %then %do;
|
|
67
|
+
data _null_;
|
|
68
|
+
infile &fref;
|
|
69
|
+
input;
|
|
70
|
+
putlog _infile_;
|
|
71
|
+
run;
|
|
72
|
+
%end;
|
|
73
|
+
|
|
74
|
+
%mend mp_gitreleaseinfo;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Creates a dataset with the output from `GIT_STATUS()`
|
|
4
|
+
@details Uses `git_status()` to fetch the number of changed files, then
|
|
5
|
+
iterates with `git_status_get()`, inserting all attributes into an output
|
|
6
|
+
dataset.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
|
|
10
|
+
%let dir=%sysfunc(pathname(work))/core;
|
|
11
|
+
%let repo=https://github.com/sasjs/core;
|
|
12
|
+
%put source clone rc=%sysfunc(GITFN_CLONE(&repo,&dir));
|
|
13
|
+
%mf_writefile(&dir/somefile.txt,l1=some content)
|
|
14
|
+
%mf_deletefile(&dir/package.json)
|
|
15
|
+
|
|
16
|
+
%mp_gitstatus(&dir,outds=work.gitstatus)
|
|
17
|
+
|
|
18
|
+
More info on these functions is in this [helpful paper]
|
|
19
|
+
(https://www.sas.com/content/dam/SAS/support/en/sas-global-forum-proceedings/2019/3057-2019.pdf)
|
|
20
|
+
by Danny Zimmerman.
|
|
21
|
+
|
|
22
|
+
@param [in] gitdir The directory containing the GIT repository
|
|
23
|
+
@param [out] outds= (work.git_status) The output dataset to create. Vars:
|
|
24
|
+
@li gitdir $1024 - directory of repo
|
|
25
|
+
@li path $1024 - relative path to the file in the repo
|
|
26
|
+
@li staged $32 - whether the file is staged (TRUE or FALSE)
|
|
27
|
+
@li status $64 - either new, deleted, or modified
|
|
28
|
+
@li cnt - number of files
|
|
29
|
+
@li n - the "nth" file in the list from git_status()
|
|
30
|
+
|
|
31
|
+
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages
|
|
32
|
+
|
|
33
|
+
<h4> Related Files </h4>
|
|
34
|
+
@li mp_gitstatus.test.sas
|
|
35
|
+
@li mp_gitadd.sas
|
|
36
|
+
|
|
37
|
+
**/
|
|
38
|
+
|
|
39
|
+
%macro mp_gitstatus(gitdir,outds=work.mp_gitstatus,mdebug=0);
|
|
40
|
+
|
|
41
|
+
data &outds;
|
|
42
|
+
LENGTH gitdir path $ 1024 STATUS $ 64 STAGED $ 32;
|
|
43
|
+
call missing (of _all_);
|
|
44
|
+
gitdir=symget('gitdir');
|
|
45
|
+
cnt=git_status(trim(gitdir));
|
|
46
|
+
if cnt=-1 then do;
|
|
47
|
+
put "The libgit2 library is unavailable and no Git operations can be used.";
|
|
48
|
+
put "See: https://stackoverflow.com/questions/74082874";
|
|
49
|
+
end;
|
|
50
|
+
else if cnt=-2 then do;
|
|
51
|
+
put "The libgit2 library is available, but the status function failed.";
|
|
52
|
+
put "See the log for details.";
|
|
53
|
+
end;
|
|
54
|
+
else do n=1 to cnt;
|
|
55
|
+
rc=GIT_STATUS_GET(n,gitdir,'PATH',path);
|
|
56
|
+
rc=GIT_STATUS_GET(n,gitdir,'STAGED',staged);
|
|
57
|
+
rc=GIT_STATUS_GET(n,gitdir,'STATUS',status);
|
|
58
|
+
output;
|
|
59
|
+
%if &mdebug=1 %then %do;
|
|
60
|
+
putlog (_all_)(=);
|
|
61
|
+
%end;
|
|
62
|
+
end;
|
|
63
|
+
rc=git_status_free(gitdir);
|
|
64
|
+
drop rc cnt;
|
|
65
|
+
run;
|
|
66
|
+
|
|
67
|
+
%mend mp_gitstatus;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Performs a text substitution on a file
|
|
4
|
+
@details Makes use of the GSUB function in LUA to perform a text substitution
|
|
5
|
+
in a file - either in-place, or writing to a new location. The benefit of
|
|
6
|
+
using LUA is that the entire file can be loaded into a single variable,
|
|
7
|
+
thereby side stepping the 32767 character limit in a data step.
|
|
8
|
+
|
|
9
|
+
Usage:
|
|
10
|
+
|
|
11
|
+
%let file=%sysfunc(pathname(work))/file.txt;
|
|
12
|
+
%let str=replace/me;
|
|
13
|
+
%let rep=with/this;
|
|
14
|
+
data _null_;
|
|
15
|
+
file "&file";
|
|
16
|
+
put "&str";
|
|
17
|
+
run;
|
|
18
|
+
%mp_gsubfile(file=&file, patternvar=str, replacevar=rep)
|
|
19
|
+
data _null_;
|
|
20
|
+
infile "&file";
|
|
21
|
+
input;
|
|
22
|
+
list;
|
|
23
|
+
run;
|
|
24
|
+
|
|
25
|
+
@param file= (0) The file to perform the substitution on
|
|
26
|
+
@param patternvar= A macro variable containing the Lua
|
|
27
|
+
[pattern](https://www.lua.org/pil/20.2.html) to search for. Due to the use
|
|
28
|
+
of special (magic) characters in Lua patterns, it is safer to pass the NAME
|
|
29
|
+
of the macro variable containing the string, rather than the value itself.
|
|
30
|
+
@param replacevar= The name of the macro variable containing the replacement
|
|
31
|
+
_string_.
|
|
32
|
+
@param outfile= (0) The file to write the output to. If zero, then the file
|
|
33
|
+
is overwritten in-place.
|
|
34
|
+
|
|
35
|
+
<h4> SAS Macros </h4>
|
|
36
|
+
@li ml_gsubfile.sas
|
|
37
|
+
|
|
38
|
+
<h4> Related Macros </h4>
|
|
39
|
+
@li mp_gsubfile.test.sas
|
|
40
|
+
|
|
41
|
+
@version 9.4
|
|
42
|
+
@author Allan Bowe
|
|
43
|
+
**/
|
|
44
|
+
|
|
45
|
+
%macro mp_gsubfile(file=0,
|
|
46
|
+
patternvar=,
|
|
47
|
+
replacevar=,
|
|
48
|
+
outfile=0
|
|
49
|
+
)/*/STORE SOURCE*/;
|
|
50
|
+
|
|
51
|
+
%if "%substr(&sysver.XX,1,4)"="V.04" %then %do;
|
|
52
|
+
%put %str(ERR)OR: Viya 4 does not support the IO library in lua;
|
|
53
|
+
%return;
|
|
54
|
+
%end;
|
|
55
|
+
|
|
56
|
+
%ml_gsubfile()
|
|
57
|
+
|
|
58
|
+
%mend mp_gsubfile;
|