清洁SIL代码

SIL是一种用于在Atlassian Jira和Confluence中实现工作自动化的编程语言。您可以在此处阅读有关SIL的更多信息

我经常使用SIL编写的脚本,并且希望与您分享我对如何使SIL代码“干净”的想法。

在本文中,我将首先制定编写SIL代码时要遵循的规则,然后给出代码示例并使用这些规则进行重构。

规则


  1. 名称结构以大写字母开头。
  2. 使用AddElement方法添加数组元素
  3. 使用用户定义的例程将代码分成逻辑块,并消除代码中的注释。
  4. 将可重用的代码带到库(包含)中。
  5. 在变量声明的其余部分之前声明结构。
  6. 为结构和变量指定有意义的名称,在这种情况下,您不必为结构和变量添加其他注释。
  7. 根据Google Java样式指南命名变量和函数

现在,让我们来看一个SIL代码示例。

string USER = currentUser();
// Response
struct returnData {
    string status;
}
// Project
struct space {
    string key;
}
// Inner part with content
struct storage {
    string value;
    string representation;
}
// Part for storage
struct body {
    storage storage;
}
// Main entity for sending to Confluence
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";
// Create request
HttpRequest request;
HttpHeader header = httpCreateHeader("Content-Type", "application/json");
HttpHeader authHeader = httpBasicAuthHeader("admin", "admin");
request.headers += header;
request.headers += authHeader;
logPrint("WARN", request);
//POST
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 Status
return result.status;

查看代码很难快速确定代码在做什么。代码中的注释也无济于事。让我们尝试根据上述规则更改代码。

首先看一下结构。这是一个例子:

struct body {
    storage storage;
}

我们看到“存储存储”看起来难以理解。如果代码像下面这样会更清楚:

struct body {
    Storage storage;
}

现在我们看到我们在结构中以Storage类型名称存储定义了一个字段。为了使我们编写这样的代码,我们需要将每个结构的首字母大写:

// Response
struct ReturnData {
    string status;
}
// Project
struct Space {
    string key;
}
// Inner part with content
struct Storage {
    string value;
    string representation;
}
// Part for storage
struct Body {
    Storage storage;
}
// Main entity for sending to Confluence
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";
// Create request
HttpRequest request;
HttpHeader header = httpCreateHeader("Content-Type", "application/json");
HttpHeader authHeader = httpBasicAuthHeader("admin", "admin");
request.headers += header;
request.headers += authHeader;
logPrint("WARN", request);
//POST
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 Status
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中获得了可重用的页面创建功能,并且我们的代码变得更加可读和受支持。

All Articles