mcpField
S
sasjs-core

sasjs-core

github.com/sasjs开发31.1k 次安装2 天前更新
代码仓库

关于 sasjs-core

@sasjs/core 是面向 SAS 应用开发者的 MIT 许可 SAS 宏库,适用于 SAS 9、Viya 和 SASjs server。本技能提供代码规范、测试和构建方面的静态参考,不会执行代码或访问外部系统。

主要功能

  1. 01SAS 宏编码规范
  2. 02目录和宏前缀约定
  3. 03安全中止处理指导
  4. 04宏测试与作用域检查
  5. 05Lint 和生成文件规则

适用场景

  1. 01添加 SAS 宏时遵循代码约定
  2. 02测试宏是否泄漏变量作用域
  3. 03按 lint 和构建规则检查变更

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sasjs/skills --skill sasjs-core

安装后在 Claude Code 中输入/sasjs-core确认已加载。

详细介绍

@sasjs/core - SAS 宏库

@sasjs/core 是一个采用 MIT 许可的库,包含适用于 SAS 应用开发的生产级 SAS 宏,可在 SAS 9(meta)、Viya 和 SASjs server 上移植使用。

编码规范(必须遵守)

  • 每个文件只包含一个宏;文件名必须与宏名一致(小写,不含空格)
  • 宏定义必须使用括号:%macro x();,不能写成 %macro x;
  • 宏调用末尾不得加分号:%my_macro(),不能写成 %my_macro();
  • 所有宏变量都必须声明为 %local,以防止作用域泄漏
  • 赋值 fileref 时始终使用 mf_getuniquefileref,赋值 libref 时始终使用 mf_getuniquelibref(绝不硬编码或手动创建唯一引用)
  • 缩进使用 2 个空格,不使用制表符,不留尾随空格,不使用不可见字符;行长最多为 300 字符(硬性 lint 限制),但尽可能将行长控制在 80 字符以内
  • 每个文件都必须包含 Doxygen 头部:
/**
  @file
  @brief One-line description of the macro

  <h4> SAS Macros </h4>
  @li mf_othermacro.sas

  @param [in] paramname Description
  @param [out] outparam Description

  <h4> Related Macros </h4>
  @li mp_related.sas

  @version 9.4
  @author Your Name
**/

文件夹/前缀约定

文件夹前缀平台
base/mf_(函数式)、mp_(过程式)所有平台
meta/mm_SAS 9 元数据
metax/mmx_SAS 9 元数据(依赖 OS 命令)
viya/mv_Viya
server/ms_SASjs server
xplatform/mx_运行时平台检测
fcmp/、lua/、ddl/-PROC FCMP 函数、LUA 封装、DDL

当宏返回的值可用于表达式时,使用 mf_ 宏;对于生成代码/语句的过程式宏,使用 mp_。

跨套件规则:mp_ 宏绝不能引用 mx_ 宏。平台分发(SAS 9/Viya/SASjs server)应放在 mx_ 套件中,由其按平台调用 ms_/mv_/PROC STP。如果某个 mp_ 宏看起来需要平台专属行为,那么该宏本身应放在 xplatform/ 中,作为 mx_ 宏。

优先复用,再编写

编写新宏之前,请先检查库中是否已有可用宏——常见工具已经存在,例如 mp_abort(已弃用的 mf_abort 为保持向后兼容而保留;新代码中不要使用它)、mf_existds、mf_existvar、mf_existfileref、mf_getuser、mp_jsonout(将 SAS 数据集转换为 JSON,输出到 _webout)、mp_ds2ddl、mp_hashdataset。meta/、viya/、server/ 下有平台专用变体,由 CLI 在编译时选择。

安全地中止

绝不要在 %if/%else 代码块中调用 %mp_abort——作为过程式宏,宏处理器可能会在中止生效前继续执行其中的语句。请改用 iftrue= 条件参数:

%mp_abort(iftrue= (&syscc ne 0)
  ,mac=&_program
  ,msg=%str(Something went wrong)
)

循环中也一样。在 %do %while 或 %do %to 循环体内调用 %mp_abort 可能导致循环继续运行:中止会取消当前步骤,而宏处理器随后会继续下一次迭代;如果循环正在等待一个永远不会出现的进度,那么中止本身就会再次触发,导致任务不断运行而不是失败。设置一个标志,退出循环本身,然后在 %end 之后中止:

%let stuck=0;
%do %while (&left>0);
  /* ...work that may make no progress... */
  %if &nready=0 %then %do;
    %let stuck=1;
    %let left=0;   /* the loop condition, so it cannot re-enter */
  %end;
%end;

%mp_abort(iftrue= (&stuck=1)
  ,mac=&sysmacroname
  ,msg=%str(No progress could be made)
)

经验法则:中止应放在结构末尾,绝不要放在结构内部——%mp_abort 是向步骤发出的请求,不是从宏中执行的 return。另一种相关情况是:在 %if <count> >0 %then %do ... %end 中包裹验证中止,并在其中设置 iftrue=1;应改为在调用时将计数传给 iftrue=,这样中止就不依赖外围代码块。

从 %include 代码块内部调用 %mp_abort 时,SAS 无法正常退出(例如退出到 _webout)。请在 include 之后(宏包装之外)调用 %mp_abort(mode=INCLUDE)——它会检查 work.mp_abort_errds 中的中止状态:

%mp_abort(mode=INCLUDE)

注意:宏内的 %include 应使用 %mp_include() 执行,以设置 _SYSINCLUDEFILEDEVICE 指示器,并将中止数据集(work.mp_abort_errds)传回调用程序。

测试宏(强制约定)

  • 始终在待测宏外使用 %mp_assertscope,以捕获作用域泄漏(宏变量必须保持为 %local):
%mp_assertscope(SNAPSHOT)
%mx_foo(args)
%mp_assertscope(COMPARE,
  desc=Test 1: mx_foo does not leak scope,
  outds=work.test_results
)
  • 断言通过 %mp_assert(iftrue=(...), desc=..., outds=work.test_results) 写入 work.test_results。

Lint 和构建

  • 每次更改后都运行 sasjs lint;通过之前不要认为工作已完成
  • 绝不要提升 package.json 中的版本(由 semantic-release 处理)
  • 不要手动编辑生成的文件:all.sas、mc_*.sas、lua/ 包装器和 sasjsbuild/ 输出均由 CI 构建生成
  • Markdown 文件:绝不要强制换行;每行写一个段落

限制

此技能是 @sasjs/core 宏库的静态参考资料,提供编码标准、前缀约定和测试指导。它不会执行 SAS 代码、运行 shell 命令、访问文件系统、连接数据库或发起网络请求。所有代码示例仅供参考,必须由用户提交到 SAS 会话中执行。

评论

支持 Markdown