SIL是一种用于在Atlassian Jira和Confluence中实现工作自动化的编程语言。您可以在此处阅读有关SIL的更多信息。我经常使用SIL编写的脚本,并且希望与您分享我对如何使SIL代码“干净”的想法。在本文中,我将首先制定编写SIL代码时要遵循的规则,然后给出代码示例并使用这些规则进行重构。规则
- 名称结构以大写字母开头。
- 使用AddElement方法添加数组元素。
- 使用用户定义的例程将代码分成逻辑块,并消除代码中的注释。
- 将可重用的代码带到库(包含)中。
- 在变量声明的其余部分之前声明结构。
- 为结构和变量指定有意义的名称,在这种情况下,您不必为结构和变量添加其他注释。
- 根据Google Java样式指南命名变量和函数。
现在,让我们来看一个SIL代码示例。string USER = currentUser();
struct returnData {
string status;
}
struct space {
string key;
}
struct storage {
string value;
string representation;
}
struct body {
storage storage;
}
struct reqData {
string type;
string title;
space space;
body body;
}
reqData data;
data.type = "page";
data.title = "Page for issue " + key + " " + summary + ".";
data.space.key = project;
data.body.storage.value = "<p> Author:"+userFullName(USER) + " description: " + description + "</p>";
data.body.storage.representation = "storage";
HttpRequest request;
HttpHeader header = httpCreateHeader("Content-Type", "application/json");
HttpHeader authHeader = httpBasicAuthHeader("admin", "admin");
request.headers += header;
request.headers += authHeader;
logPrint("WARN", request);
string JSONData = toJson(data);
logPrint("WARN", JSONData);
returnData result = httpPost("http://192.168.54.203:8090/rest/api/content/", request, JSONData);
string errMsg = httpGetErrorMessage();
logPrint("ERROR", "Last error message: " + errMsg);
logPrint("WARN", result);
string COMMENT = "Page created in Confluence " + updated + " by " + userFullName(USER) + " Status : " +result.status + ".";
addComment(key, USER, COMMENT);
return result.status;
查看代码很难快速确定代码在做什么。代码中的注释也无济于事。让我们尝试根据上述规则更改代码。首先看一下结构。这是一个例子:struct body {
storage storage;
}
我们看到“存储存储”看起来难以理解。如果代码像下面这样会更清楚:struct body {
Storage storage;
}
现在我们看到我们在结构中以Storage类型名称存储定义了一个字段。为了使我们编写这样的代码,我们需要将每个结构的首字母大写:
struct ReturnData {
string status;
}
struct Space {
string key;
}
struct Storage {
string value;
string representation;
}
struct Body {
Storage storage;
}
struct ReqData {
string type;
string title;
Space space;
Body body;
}
现在让我们重命名该结构,以便该结构的名称可以清楚说明其用途,而不必添加注释:struct Space {
string key;
}
struct Storage {
string value;
string representation;
}
struct Body {
Storage storage;
}
struct CreateConfluencePageRequest {
string type;
string title;
Space space;
Body body;
}
struct CreateConfluencePageResponse {
string status;
}
我认为,此类名称不需要对结构进行其他注释。我们还将在代码的开头声明结构。我们使用了规则1、5、6。现在,让我们看一下结构声明后的代码:string USER = currentUser();
CreateConfluencePageRequest data;
data.type = "page";
data.title = "Page for issue " + key + " " + summary + ".";
data.space.key = project;
data.body.storage.value = "<p> Author:"+userFullName(USER) + " description: " + description + "</p>";
data.body.storage.representation = "storage";
HttpRequest request;
HttpHeader header = httpCreateHeader("Content-Type", "application/json");
HttpHeader authHeader = httpBasicAuthHeader("admin", "admin");
request.headers += header;
request.headers += authHeader;
logPrint("WARN", request);
string JSONData = toJson(data);
logPrint("WARN", JSONData);
CreateConfluencePageResponse result = httpPost("http://192.168.54.203:8090/rest/api/content/", request, JSONData);
string errMsg = httpGetErrorMessage();
logPrint("ERROR", "Last error message: " + errMsg);
logPrint("WARN", result);
string COMMENT = "Page created in Confluence " + updated + " by " + userFullName(USER) + " Status : " +result.status + ".";
addComment(key, USER, COMMENT);
return result.status;
查看代码,我们无法快速了解代码中正在发生的事情。让我们首先尝试将代码分解为逻辑块:getNewConfluencePageContent();
createHttpRequest();
createConfluencePage();
addCommentToJiraIssue();
也就是说,首先我们在Confluence中获取新页面的内容,然后创建一个http请求,在Confluence中创建一个页面,并在Jira请求中写一个注释,以创建Confluence中的页面。现在让我们实现以下功能:function getNewConfluencePageContent() {
CreateConfluencePageRequest data;
data.type = "page";
data.title = "Page for issue " + key + " " + summary + ".";
data.space.key = project;
data.body.storage.value = "<p> Author:"+userFullName(currentUser()) + " description: " + description + "</p>";
data.body.storage.representation = "storage";
return toJson(data);
}
function createHttpRequest() {
HttpRequest request;
HttpHeader header = httpCreateHeader("Content-Type", "application/json");
HttpHeader authHeader = httpBasicAuthHeader("admin", "admin");
request.headers = addElement(request.headers, header);
request.headers += addElement(request.headers, authHeader);
logPrint("WARN", request);
return request;
}
function createConfluencePage(string pageJson) {
HttpRequest request = createHttpRequest();
CreateConfluencePageResponse result = httpPost("http://192.168.54.203:8090/rest/api/content/", request, pageJson);
logPrint("ERROR", "Last error message: " + httpGetErrorMessage());
logPrint("WARN", result);
return result;
}
function addCommentToJiraIssue(string resultStatus) {
string COMMENT = "Page created in Confluence " + updated + " by " + userFullName(currentUser()) + " Status : " +resultStatus + ".";
addComment(key, currentUser(), COMMENT);
}
string pageJson = getNewConfluencePageContent();
CreateConfluencePageResponse result = createConfluencePage(pageJson);
addCommentToJiraIssue(result.status);
return result.status;
我们删除了函数中的逻辑块(规则2)。现在我们可以简单地编写如下代码:string pageJson = getNewConfluencePageContent();
CreateConfluencePageResponse result = createConfluencePage(pageJson);
addCommentToJiraIssue(result.status);
return result.status;
我们的代码包含四个逻辑块。首先,我们获取新页面的json,然后在Confluence中创建页面,在请求中添加注释,并将页面创建状态返回给Confluence。这四行代码为我们提供了脚本功能的顶级视图。如果我们想了解Confluence中页面的内容,那么我们总是可以转到getNewConfluencePageContent并查看此函数的内容。此功能仅包含用于创建页面内容的代码,仅此而已,因此,在学习功能代码时,我们不会因其他功能而分心。我们可以假设我们不仅需要从一个脚本中在Confluence中创建页面。因此,让我们创建confluence_helper.incl文件,并为在Confluence中为此文件提供创建页面所需的所有功能:struct Space {
string key;
}
struct Storage {
string value;
string representation;
}
struct Body {
Storage storage;
}
struct CreateConfluencePageRequest {
string type;
string title;
Space space;
Body body;
}
struct CreateConfluencePageResponse {
string status;
}
function createHttpRequest() {
HttpRequest request;
HttpHeader header = httpCreateHeader("Content-Type", "application/json");
HttpHeader authHeader = httpBasicAuthHeader("admin", "admin");
request.headers = addElement(request.headers, header);
request.headers += addElement(request.headers, authHeader);
logPrint("INFO", request);
return request;
}
function createConfluencePage(string confluenceUrl, string pageJson) {
HttpRequest request = createHttpRequest();
CreateConfluencePageResponse result = httpPost(confluenceUrl, request, pageJson);
logPrint("ERROR", "Last error message: " + httpGetErrorMessage());
logPrint("INFO", result);
return result;
}
通过向其添加另一个confluenceUrl参数,使createConfluencePage函数更通用。因此,我们遵循规则4。现在,我们的主脚本将如下所示:include "confluence_helper.incl";
function getNewConfluencePageContent() {
CreateConfluencePageRequest data;
data.type = "page";
data.title = "Page for issue " + key + " " + summary + ".";
data.space.key = project;
data.body.storage.value = "<p> Author:"+userFullName(currentUser()) + " description: " + description + "</p>";
data.body.storage.representation = "storage";
return toJson(data);
}
function addCommentToJiraIssue(string resultStatus) {
string comment = "Page created in Confluence " + updated + " by " + userFullName(currentUser()) + " Status : " +resultStatus + ".";
addComment(key, currentUser(), comment);
}
const string CONFLUENCE_URL = "http://192.168.54.203:8090/rest/api/content/";
string pageJson = getNewConfluencePageContent();
CreateConfluencePageResponse result = createConfluencePage(CONFLUENCE_URL, pageJson);
addCommentToJiraIssue(result.status);
return result.status;
在第一行中,我包含了confluence_helper.incl文件,以从中使用Confluence中的页面创建功能。我将Confluence地址保存在一个常量变量中,并根据Google Java表示法样式(规则7)更改了变量名称。在我看来,这可以通过重构停止。重构的结果是,我们在Confluence中获得了可重用的页面创建功能,并且我们的代码变得更加可读和受支持。