<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic SAS Packages Framework, version 20251231 in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/SAS-Packages-Framework-version-20251231/m-p/981401#M379111</link>
    <description>&lt;P&gt;Hi SAS-C!&lt;/P&gt;
&lt;P&gt;Just FYI.&lt;/P&gt;
&lt;P&gt;Bart&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H1&gt;SAS Packages Framework, version&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;20251231&lt;/CODE&gt;&lt;/H1&gt;
&lt;P&gt;&lt;FONT size="3"&gt;Available as usual in:&amp;nbsp;&lt;STRONG&gt;&lt;A title="https://github.com/yabwon/SAS_PACKAGES" href="https://github.com/yabwon/SAS_PACKAGES" target="_self"&gt;https://github.com/yabwon/SAS_PACKAGES&lt;/A&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This release introduce concept of&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;SAS packages bundles&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and two new macros to work with bundles. See detailed use case below to learn more about bundles.&lt;/P&gt;
&lt;HR /&gt;
&lt;H2&gt;Changes and modifications:&lt;/H2&gt;
&lt;P&gt;A) Two new macros were added:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A title="%bundlePackages()" href="https://github.com/yabwon/SAS_PACKAGES/blob/main/SPF/SPFinit.md#bundlepackages" target="_blank"&gt;&lt;CODE&gt;%bundlePackages()&lt;/CODE&gt;&lt;/A&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;macro that allows to combine multiple SAS packages into SAS bundle,&lt;/LI&gt;
&lt;LI&gt;the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A title="%unbundlePackages()" href="https://github.com/yabwon/SAS_PACKAGES/blob/main/SPF/SPFinit.md#unbundlepackages" target="_blank"&gt;&lt;CODE&gt;%unbundlePackages()&lt;/CODE&gt;&lt;/A&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;macro that allows to extract SAS packages from a SAS bundle.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;B) Bug fix in the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A title="%verifyPackage()" href="https://github.com/yabwon/SAS_PACKAGES/blob/main/SPF/SPFinit.md#verifypackage" target="_blank"&gt;&lt;CODE&gt;%verifyPackage()&lt;/CODE&gt;&lt;/A&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;macro.&lt;/P&gt;
&lt;P&gt;C) Minor updates in:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A title="%generatePackage()" href="https://github.com/yabwon/SAS_PACKAGES/blob/main/SPF/SPFinit.md#generatepackage" target="_blank"&gt;&lt;CODE&gt;%generatePackage()&lt;/CODE&gt;&lt;/A&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A title="%listPackages()" href="https://github.com/yabwon/SAS_PACKAGES/blob/main/SPF/SPFinit.md#listpackages" target="_blank"&gt;&lt;CODE&gt;%listPackages()&lt;/CODE&gt;&lt;/A&gt;, and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A title="%relocatePackage()" href="https://github.com/yabwon/SAS_PACKAGES/blob/main/SPF/SPFinit.md#relocatepackage" target="_blank"&gt;&lt;CODE&gt;%relocatePackage()&lt;/CODE&gt;&lt;/A&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;macros.&lt;/P&gt;
&lt;P&gt;D)&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://github.com/yabwon/SAS_PACKAGES/tree/main/SPF/Documentation" target="_blank"&gt;Documentation&lt;/A&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;updated.&lt;/P&gt;
&lt;HR /&gt;
&lt;H2&gt;SAS packages bundles:&lt;/H2&gt;
&lt;P&gt;In a single user environment, like local PC SAS or environments where users have their own separate space (e.g., SAS Workbench), keeping packages directories tidy and well organized may not necessary be a "highly required" demand, but in a setup where multiple users, or project teams, share centralized location for packages, the environment (e.g., packages versions) cannot be changed "just like that". Keeping the environment tidy can save programmers form so called "packages inferno", a situation where no one knows which version is where, which one is used, and "why my project is no longer working after packages update?".&lt;/P&gt;
&lt;P&gt;On multiple occasions I've been&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;EM&gt;highlighting&lt;/EM&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;how important the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;backward compatibility&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is in packages development. Unfortunately life happens and backward compatibility principle may not always be held...&lt;/P&gt;
&lt;P&gt;In such morbid situation, creating SAS packages bundles can be an interesting solution and can save your day.&lt;/P&gt;
&lt;P&gt;Definition: a&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;SAS packages bundle&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is a zip file containing one or more SAS packages and bundle metadata file inside the zip. Such a SAS bundle can be used as a container for a "snapshot" of the current SAS packages state in the SAS environment.&lt;/P&gt;
&lt;P&gt;The&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;%bundlePackages()&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;%unbundlePackages()&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;macros (both build atop of the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;%relocatePackage()&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;macro) serves that purpose. The following use case illustrates how (and when) those macros can help.&lt;/P&gt;
&lt;P&gt;The scenario goes as follows:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Company X keeps packages in a "central" directory&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/sas/packages&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and there are 17 different packages stored in the location.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;A very important project is processed in the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/projects/number42&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directory. Programs and data are kept inside the location.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;For their analysis The A-team is using packages&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;ABC&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;XYZ&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;located in&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/sas/packages&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directory.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;The project successfully ends December 31st, 2025, and the A-team "saves" current versions of&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;ABC&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;XYZ&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;packages into&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;bundleForProject42_20251231&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;bundle.&lt;/P&gt;
&lt;DIV class="highlight highlight-source-sas notranslate position-relative overflow-auto"&gt;
&lt;PRE&gt;&lt;SPAN class="pl-c1"&gt;filename&lt;/SPAN&gt; packages &lt;SPAN class="pl-s"&gt;"/sas/packages"&lt;/SPAN&gt;;
&lt;SPAN class="pl-k"&gt;&lt;SPAN class="pl-c1"&gt;%include&lt;/SPAN&gt; &lt;SPAN class="pl-en"&gt;packages&lt;/SPAN&gt;&lt;/SPAN&gt;(SPFinit.sas);

&lt;SPAN class="pl-c1"&gt;libname&lt;/SPAN&gt; b &lt;SPAN class="pl-s"&gt;"/sas/bundles"&lt;/SPAN&gt;;

&lt;SPAN class="pl-k"&gt;&lt;SPAN class="pl-c1"&gt;%let&lt;/SPAN&gt; &lt;SPAN class="pl-en"&gt;date&lt;/SPAN&gt;&lt;/SPAN&gt;=&lt;SPAN class="pl-c1"&gt;20251231&lt;/SPAN&gt;;

%bundlePackages(
  bundleForProject42_&lt;SPAN class="pl-smi"&gt;&amp;amp;date&lt;/SPAN&gt;.
, packagesList=ABC XYZ
, &lt;SPAN class="pl-c1"&gt;path&lt;/SPAN&gt;=&lt;SPAN class="pl-k"&gt;/&lt;/SPAN&gt;sas&lt;SPAN class="pl-k"&gt;/&lt;/SPAN&gt;bundles
, &lt;SPAN class="pl-c1"&gt;ods&lt;/SPAN&gt;=b.SHA256forProject42_&lt;SPAN class="pl-smi"&gt;&amp;amp;date&lt;/SPAN&gt;.
)&lt;/PRE&gt;
&lt;DIV class="zeroclipboard-container position-absolute right-0 top-0"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;P&gt;The snippet above assigns&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;packages&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;fileref to&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/sas/packages&lt;/CODE&gt;, enables the framework (personally I'd keep those 2 lines in the autoexec), sets library&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;b&lt;/CODE&gt;, and creates convenience macro variable&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;date&lt;/CODE&gt;. The&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;%bundlePackages()&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;macro takes packages&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;ABC&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;XYZ&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;from the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;packages&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;fileref and bundles them into the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;bundleForProject42_&amp;amp;date.&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;bundle.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;After execution the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;bundleforproject42_20251231.bundle.zip&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;file and the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;SHA256forProject42_20251231.sas7bdat&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;data set (containing the bundle's SHA256 checks sum) are stored in the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/sas/bundles&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directory.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Some time passes and newer versions of packages&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;ABC&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;XYZ&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;are developed and installed in the central packages directory. Hopefully developers followed the backward compatibility principle when they were updating/modifying those packages, but with the bundle the A-team doesn't have to worry.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Some time later The A-team gets a request to re-run project 42 on newly delivered data.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;To ensure expected behavior of&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;ABC&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;XYZ&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;the A-team extracts the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;bundleForProject42_20251231&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;bundle file from the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/sas/bundles&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directory to a temporary location in&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/adhoc/for42&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(they also, optionally, verify if the bundle was not modified by someone from a "hostile" B-team).&lt;/P&gt;
&lt;DIV class="highlight highlight-source-sas notranslate position-relative overflow-auto"&gt;
&lt;PRE&gt;&lt;SPAN class="pl-c1"&gt;filename&lt;/SPAN&gt; packages &lt;SPAN class="pl-s"&gt;"/sas/packages"&lt;/SPAN&gt;;
&lt;SPAN class="pl-k"&gt;&lt;SPAN class="pl-c1"&gt;%include&lt;/SPAN&gt; &lt;SPAN class="pl-en"&gt;packages&lt;/SPAN&gt;&lt;/SPAN&gt;(SPFinit.sas);

&lt;SPAN class="pl-k"&gt;&lt;SPAN class="pl-c1"&gt;%let&lt;/SPAN&gt; &lt;SPAN class="pl-en"&gt;bndls&lt;/SPAN&gt;&lt;/SPAN&gt;=&lt;SPAN class="pl-k"&gt;/&lt;/SPAN&gt;sas&lt;SPAN class="pl-k"&gt;/&lt;/SPAN&gt;bundles; &lt;SPAN class="pl-c"&gt;/* bundles location */&lt;/SPAN&gt;
&lt;SPAN class="pl-k"&gt;&lt;SPAN class="pl-c1"&gt;%let&lt;/SPAN&gt; &lt;SPAN class="pl-en"&gt;date&lt;/SPAN&gt;&lt;/SPAN&gt;=&lt;SPAN class="pl-c1"&gt;20251231&lt;/SPAN&gt;;

&lt;SPAN class="pl-c"&gt;/* verify bundle */&lt;/SPAN&gt;
&lt;SPAN class="pl-c1"&gt;libname&lt;/SPAN&gt; b &lt;SPAN class="pl-s"&gt;"&amp;amp;bndls."&lt;/SPAN&gt;;
&lt;SPAN class="pl-k"&gt;data&lt;/SPAN&gt; &lt;SPAN class="pl-en"&gt;_null_&lt;/SPAN&gt;;
  &lt;SPAN class="pl-c1"&gt;set&lt;/SPAN&gt; &lt;SPAN class="pl-en"&gt;b&lt;/SPAN&gt;.&lt;SPAN class="pl-en"&gt;SHA256forProject42_&lt;/SPAN&gt;&amp;amp;&lt;SPAN class="pl-en"&gt;date&lt;/SPAN&gt;.;
  &lt;SPAN class="pl-c1"&gt;call&lt;/SPAN&gt; symputX(&lt;SPAN class="pl-s"&gt;'bundleSHA256'&lt;/SPAN&gt;, bundleSHA256);
&lt;SPAN class="pl-k"&gt;run&lt;/SPAN&gt;;
%verifyPackage(
  bundleForProject42_&lt;SPAN class="pl-smi"&gt;&amp;amp;date..&lt;/SPAN&gt;bundle
, hash=&lt;SPAN class="pl-smi"&gt;&amp;amp;bundleSHA256&lt;/SPAN&gt;.
, &lt;SPAN class="pl-c1"&gt;path&lt;/SPAN&gt;=&lt;SPAN class="pl-smi"&gt;&amp;amp;bndls&lt;/SPAN&gt;.
)

&lt;SPAN class="pl-c"&gt;/* extrat bundle to /adhoc/for42 */&lt;/SPAN&gt;
%unbundlePackages(
  bundleForProject42_&lt;SPAN class="pl-smi"&gt;&amp;amp;date&lt;/SPAN&gt;.
, &lt;SPAN class="pl-c1"&gt;path&lt;/SPAN&gt;=&lt;SPAN class="pl-smi"&gt;&amp;amp;bndls&lt;/SPAN&gt;.
, packagesPath=&lt;SPAN class="pl-k"&gt;/&lt;/SPAN&gt;adhoc&lt;SPAN class="pl-k"&gt;/&lt;/SPAN&gt;for42
, &lt;SPAN class="pl-c1"&gt;verify&lt;/SPAN&gt;=&lt;SPAN class="pl-c1"&gt;1&lt;/SPAN&gt;
)&lt;/PRE&gt;
&lt;DIV class="zeroclipboard-container position-absolute right-0 top-0"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;P&gt;Note that the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;.bundle&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;suffix was added to bundle name in the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;%verifyPackage()&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;macro call.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;After successful unbundling the A-team appends the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/adhoc/for42&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;path to the beginning of the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;packages&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;fileref.&lt;/P&gt;
&lt;DIV class="highlight highlight-source-sas notranslate position-relative overflow-auto"&gt;
&lt;PRE&gt;&lt;SPAN class="pl-c1"&gt;filename&lt;/SPAN&gt; packages (&lt;SPAN class="pl-s"&gt;"/adhoc/for42"&lt;/SPAN&gt; %extendPackagesFileref());&lt;/PRE&gt;
&lt;DIV class="zeroclipboard-container position-absolute right-0 top-0"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Packages&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;ABC&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;XYZ&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;can now be loaded with their historical versions.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;The A-team successfully re-runs the project.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;The (Happy) End.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;</description>
    <pubDate>Wed, 31 Dec 2025 15:26:36 GMT</pubDate>
    <dc:creator>yabwon</dc:creator>
    <dc:date>2025-12-31T15:26:36Z</dc:date>
    <item>
      <title>SAS Packages Framework, version 20251231</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-Packages-Framework-version-20251231/m-p/981401#M379111</link>
      <description>&lt;P&gt;Hi SAS-C!&lt;/P&gt;
&lt;P&gt;Just FYI.&lt;/P&gt;
&lt;P&gt;Bart&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H1&gt;SAS Packages Framework, version&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;20251231&lt;/CODE&gt;&lt;/H1&gt;
&lt;P&gt;&lt;FONT size="3"&gt;Available as usual in:&amp;nbsp;&lt;STRONG&gt;&lt;A title="https://github.com/yabwon/SAS_PACKAGES" href="https://github.com/yabwon/SAS_PACKAGES" target="_self"&gt;https://github.com/yabwon/SAS_PACKAGES&lt;/A&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This release introduce concept of&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;SAS packages bundles&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and two new macros to work with bundles. See detailed use case below to learn more about bundles.&lt;/P&gt;
&lt;HR /&gt;
&lt;H2&gt;Changes and modifications:&lt;/H2&gt;
&lt;P&gt;A) Two new macros were added:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A title="%bundlePackages()" href="https://github.com/yabwon/SAS_PACKAGES/blob/main/SPF/SPFinit.md#bundlepackages" target="_blank"&gt;&lt;CODE&gt;%bundlePackages()&lt;/CODE&gt;&lt;/A&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;macro that allows to combine multiple SAS packages into SAS bundle,&lt;/LI&gt;
&lt;LI&gt;the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A title="%unbundlePackages()" href="https://github.com/yabwon/SAS_PACKAGES/blob/main/SPF/SPFinit.md#unbundlepackages" target="_blank"&gt;&lt;CODE&gt;%unbundlePackages()&lt;/CODE&gt;&lt;/A&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;macro that allows to extract SAS packages from a SAS bundle.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;B) Bug fix in the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A title="%verifyPackage()" href="https://github.com/yabwon/SAS_PACKAGES/blob/main/SPF/SPFinit.md#verifypackage" target="_blank"&gt;&lt;CODE&gt;%verifyPackage()&lt;/CODE&gt;&lt;/A&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;macro.&lt;/P&gt;
&lt;P&gt;C) Minor updates in:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A title="%generatePackage()" href="https://github.com/yabwon/SAS_PACKAGES/blob/main/SPF/SPFinit.md#generatepackage" target="_blank"&gt;&lt;CODE&gt;%generatePackage()&lt;/CODE&gt;&lt;/A&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A title="%listPackages()" href="https://github.com/yabwon/SAS_PACKAGES/blob/main/SPF/SPFinit.md#listpackages" target="_blank"&gt;&lt;CODE&gt;%listPackages()&lt;/CODE&gt;&lt;/A&gt;, and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A title="%relocatePackage()" href="https://github.com/yabwon/SAS_PACKAGES/blob/main/SPF/SPFinit.md#relocatepackage" target="_blank"&gt;&lt;CODE&gt;%relocatePackage()&lt;/CODE&gt;&lt;/A&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;macros.&lt;/P&gt;
&lt;P&gt;D)&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://github.com/yabwon/SAS_PACKAGES/tree/main/SPF/Documentation" target="_blank"&gt;Documentation&lt;/A&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;updated.&lt;/P&gt;
&lt;HR /&gt;
&lt;H2&gt;SAS packages bundles:&lt;/H2&gt;
&lt;P&gt;In a single user environment, like local PC SAS or environments where users have their own separate space (e.g., SAS Workbench), keeping packages directories tidy and well organized may not necessary be a "highly required" demand, but in a setup where multiple users, or project teams, share centralized location for packages, the environment (e.g., packages versions) cannot be changed "just like that". Keeping the environment tidy can save programmers form so called "packages inferno", a situation where no one knows which version is where, which one is used, and "why my project is no longer working after packages update?".&lt;/P&gt;
&lt;P&gt;On multiple occasions I've been&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;EM&gt;highlighting&lt;/EM&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;how important the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;backward compatibility&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is in packages development. Unfortunately life happens and backward compatibility principle may not always be held...&lt;/P&gt;
&lt;P&gt;In such morbid situation, creating SAS packages bundles can be an interesting solution and can save your day.&lt;/P&gt;
&lt;P&gt;Definition: a&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;SAS packages bundle&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is a zip file containing one or more SAS packages and bundle metadata file inside the zip. Such a SAS bundle can be used as a container for a "snapshot" of the current SAS packages state in the SAS environment.&lt;/P&gt;
&lt;P&gt;The&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;%bundlePackages()&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;%unbundlePackages()&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;macros (both build atop of the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;%relocatePackage()&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;macro) serves that purpose. The following use case illustrates how (and when) those macros can help.&lt;/P&gt;
&lt;P&gt;The scenario goes as follows:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Company X keeps packages in a "central" directory&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/sas/packages&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and there are 17 different packages stored in the location.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;A very important project is processed in the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/projects/number42&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directory. Programs and data are kept inside the location.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;For their analysis The A-team is using packages&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;ABC&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;XYZ&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;located in&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/sas/packages&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directory.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;The project successfully ends December 31st, 2025, and the A-team "saves" current versions of&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;ABC&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;XYZ&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;packages into&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;bundleForProject42_20251231&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;bundle.&lt;/P&gt;
&lt;DIV class="highlight highlight-source-sas notranslate position-relative overflow-auto"&gt;
&lt;PRE&gt;&lt;SPAN class="pl-c1"&gt;filename&lt;/SPAN&gt; packages &lt;SPAN class="pl-s"&gt;"/sas/packages"&lt;/SPAN&gt;;
&lt;SPAN class="pl-k"&gt;&lt;SPAN class="pl-c1"&gt;%include&lt;/SPAN&gt; &lt;SPAN class="pl-en"&gt;packages&lt;/SPAN&gt;&lt;/SPAN&gt;(SPFinit.sas);

&lt;SPAN class="pl-c1"&gt;libname&lt;/SPAN&gt; b &lt;SPAN class="pl-s"&gt;"/sas/bundles"&lt;/SPAN&gt;;

&lt;SPAN class="pl-k"&gt;&lt;SPAN class="pl-c1"&gt;%let&lt;/SPAN&gt; &lt;SPAN class="pl-en"&gt;date&lt;/SPAN&gt;&lt;/SPAN&gt;=&lt;SPAN class="pl-c1"&gt;20251231&lt;/SPAN&gt;;

%bundlePackages(
  bundleForProject42_&lt;SPAN class="pl-smi"&gt;&amp;amp;date&lt;/SPAN&gt;.
, packagesList=ABC XYZ
, &lt;SPAN class="pl-c1"&gt;path&lt;/SPAN&gt;=&lt;SPAN class="pl-k"&gt;/&lt;/SPAN&gt;sas&lt;SPAN class="pl-k"&gt;/&lt;/SPAN&gt;bundles
, &lt;SPAN class="pl-c1"&gt;ods&lt;/SPAN&gt;=b.SHA256forProject42_&lt;SPAN class="pl-smi"&gt;&amp;amp;date&lt;/SPAN&gt;.
)&lt;/PRE&gt;
&lt;DIV class="zeroclipboard-container position-absolute right-0 top-0"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;P&gt;The snippet above assigns&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;packages&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;fileref to&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/sas/packages&lt;/CODE&gt;, enables the framework (personally I'd keep those 2 lines in the autoexec), sets library&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;b&lt;/CODE&gt;, and creates convenience macro variable&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;date&lt;/CODE&gt;. The&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;%bundlePackages()&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;macro takes packages&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;ABC&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;XYZ&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;from the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;packages&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;fileref and bundles them into the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;bundleForProject42_&amp;amp;date.&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;bundle.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;After execution the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;bundleforproject42_20251231.bundle.zip&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;file and the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;SHA256forProject42_20251231.sas7bdat&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;data set (containing the bundle's SHA256 checks sum) are stored in the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/sas/bundles&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directory.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Some time passes and newer versions of packages&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;ABC&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;XYZ&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;are developed and installed in the central packages directory. Hopefully developers followed the backward compatibility principle when they were updating/modifying those packages, but with the bundle the A-team doesn't have to worry.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Some time later The A-team gets a request to re-run project 42 on newly delivered data.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;To ensure expected behavior of&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;ABC&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;XYZ&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;the A-team extracts the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;bundleForProject42_20251231&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;bundle file from the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/sas/bundles&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directory to a temporary location in&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/adhoc/for42&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(they also, optionally, verify if the bundle was not modified by someone from a "hostile" B-team).&lt;/P&gt;
&lt;DIV class="highlight highlight-source-sas notranslate position-relative overflow-auto"&gt;
&lt;PRE&gt;&lt;SPAN class="pl-c1"&gt;filename&lt;/SPAN&gt; packages &lt;SPAN class="pl-s"&gt;"/sas/packages"&lt;/SPAN&gt;;
&lt;SPAN class="pl-k"&gt;&lt;SPAN class="pl-c1"&gt;%include&lt;/SPAN&gt; &lt;SPAN class="pl-en"&gt;packages&lt;/SPAN&gt;&lt;/SPAN&gt;(SPFinit.sas);

&lt;SPAN class="pl-k"&gt;&lt;SPAN class="pl-c1"&gt;%let&lt;/SPAN&gt; &lt;SPAN class="pl-en"&gt;bndls&lt;/SPAN&gt;&lt;/SPAN&gt;=&lt;SPAN class="pl-k"&gt;/&lt;/SPAN&gt;sas&lt;SPAN class="pl-k"&gt;/&lt;/SPAN&gt;bundles; &lt;SPAN class="pl-c"&gt;/* bundles location */&lt;/SPAN&gt;
&lt;SPAN class="pl-k"&gt;&lt;SPAN class="pl-c1"&gt;%let&lt;/SPAN&gt; &lt;SPAN class="pl-en"&gt;date&lt;/SPAN&gt;&lt;/SPAN&gt;=&lt;SPAN class="pl-c1"&gt;20251231&lt;/SPAN&gt;;

&lt;SPAN class="pl-c"&gt;/* verify bundle */&lt;/SPAN&gt;
&lt;SPAN class="pl-c1"&gt;libname&lt;/SPAN&gt; b &lt;SPAN class="pl-s"&gt;"&amp;amp;bndls."&lt;/SPAN&gt;;
&lt;SPAN class="pl-k"&gt;data&lt;/SPAN&gt; &lt;SPAN class="pl-en"&gt;_null_&lt;/SPAN&gt;;
  &lt;SPAN class="pl-c1"&gt;set&lt;/SPAN&gt; &lt;SPAN class="pl-en"&gt;b&lt;/SPAN&gt;.&lt;SPAN class="pl-en"&gt;SHA256forProject42_&lt;/SPAN&gt;&amp;amp;&lt;SPAN class="pl-en"&gt;date&lt;/SPAN&gt;.;
  &lt;SPAN class="pl-c1"&gt;call&lt;/SPAN&gt; symputX(&lt;SPAN class="pl-s"&gt;'bundleSHA256'&lt;/SPAN&gt;, bundleSHA256);
&lt;SPAN class="pl-k"&gt;run&lt;/SPAN&gt;;
%verifyPackage(
  bundleForProject42_&lt;SPAN class="pl-smi"&gt;&amp;amp;date..&lt;/SPAN&gt;bundle
, hash=&lt;SPAN class="pl-smi"&gt;&amp;amp;bundleSHA256&lt;/SPAN&gt;.
, &lt;SPAN class="pl-c1"&gt;path&lt;/SPAN&gt;=&lt;SPAN class="pl-smi"&gt;&amp;amp;bndls&lt;/SPAN&gt;.
)

&lt;SPAN class="pl-c"&gt;/* extrat bundle to /adhoc/for42 */&lt;/SPAN&gt;
%unbundlePackages(
  bundleForProject42_&lt;SPAN class="pl-smi"&gt;&amp;amp;date&lt;/SPAN&gt;.
, &lt;SPAN class="pl-c1"&gt;path&lt;/SPAN&gt;=&lt;SPAN class="pl-smi"&gt;&amp;amp;bndls&lt;/SPAN&gt;.
, packagesPath=&lt;SPAN class="pl-k"&gt;/&lt;/SPAN&gt;adhoc&lt;SPAN class="pl-k"&gt;/&lt;/SPAN&gt;for42
, &lt;SPAN class="pl-c1"&gt;verify&lt;/SPAN&gt;=&lt;SPAN class="pl-c1"&gt;1&lt;/SPAN&gt;
)&lt;/PRE&gt;
&lt;DIV class="zeroclipboard-container position-absolute right-0 top-0"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;P&gt;Note that the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;.bundle&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;suffix was added to bundle name in the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;%verifyPackage()&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;macro call.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;After successful unbundling the A-team appends the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/adhoc/for42&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;path to the beginning of the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;packages&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;fileref.&lt;/P&gt;
&lt;DIV class="highlight highlight-source-sas notranslate position-relative overflow-auto"&gt;
&lt;PRE&gt;&lt;SPAN class="pl-c1"&gt;filename&lt;/SPAN&gt; packages (&lt;SPAN class="pl-s"&gt;"/adhoc/for42"&lt;/SPAN&gt; %extendPackagesFileref());&lt;/PRE&gt;
&lt;DIV class="zeroclipboard-container position-absolute right-0 top-0"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Packages&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;ABC&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;XYZ&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;can now be loaded with their historical versions.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;The A-team successfully re-runs the project.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;The (Happy) End.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Wed, 31 Dec 2025 15:26:36 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-Packages-Framework-version-20251231/m-p/981401#M379111</guid>
      <dc:creator>yabwon</dc:creator>
      <dc:date>2025-12-31T15:26:36Z</dc:date>
    </item>
  </channel>
</rss>

