SIL-Code reinigen

SIL ist eine Programmiersprache zur Automatisierung der Arbeit in Atlassian Jira und Confluence. Sie können mehr über SIL lesen hier .

Ich arbeite oft mit in SIL geschriebenen Skripten und möchte Ihnen meine Gedanken darüber mitteilen, wie SIL-Code „sauber“ gemacht werden kann.

In diesem Artikel werde ich zuerst die Regeln formulieren, die ich beim Schreiben von SIL-Code befolge, dann ein Beispiel für den Code geben und das Refactoring unter Verwendung dieser Regeln durchführen.

Regeln


  1. Namen Strukturen beginnen mit einem Großbuchstaben.
  2. Fügen Sie Array-Elemente mit der AddElement- Methode hinzu .
  3. Verwenden Sie benutzerdefinierte Routinen , um Ihren Code in logische Blöcke zu unterteilen und Kommentare im Code zu entfernen.
  4. Bringen Sie wiederverwendbaren Code in Bibliotheken ( Einschlüsse ).
  5. Deklarieren Sie Strukturen vor dem Rest der Variablendeklaration.
  6. Geben Sie Strukturen und Variablen aussagekräftige Namen. In diesem Fall müssen Sie Strukturen und Variablen keine zusätzlichen Kommentare hinzufügen.
  7. Benennen Sie Variablen und Funktionen gemäß dem Google Java Style Guide .

Schauen wir uns nun ein Beispiel für SIL-Code an.

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;

Das Betrachten des Codes ist ziemlich schwierig, um schnell festzustellen, was der Code tut. Kommentare im Code helfen auch nicht viel. Versuchen wir, den Code gemäß den obigen Regeln zu ändern.

Schauen Sie sich zuerst die Struktur an. Hier ist ein Beispiel:

struct body {
    storage storage;
}

Wir sehen, dass "Speicher" unverständlich aussieht. Es wäre klarer, wenn der Code so wäre:

struct body {
    Storage storage;
}

Jetzt sehen wir, dass wir ein Feld in der Struktur unter dem Namen Speicher vom Typ Speicher definieren. Damit wir einen solchen Code schreiben können, müssen wir den ersten Buchstaben jeder Struktur groß schreiben:

// 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;
}

Benennen wir nun die Struktur um, damit der Name der Struktur deutlich macht, warum sie benötigt wird, und wir müssten keine Kommentare hinzufügen:

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;
}

Meiner Meinung nach erfordern solche Namen keine zusätzlichen Kommentare für Strukturen. Wir werden auch Strukturen ganz am Anfang des Codes deklarieren.

Wir haben die Regeln 1, 5, 6

verwendet. Schauen wir uns nun den Code nach der Deklaration der Strukturen an:

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;

Wenn wir uns den Code ansehen, können wir nicht schnell verstehen, was im Code passiert. Versuchen wir zunächst, den Code in logische Blöcke zu unterteilen:

getNewConfluencePageContent();
createHttpRequest();
createConfluencePage();
addCommentToJiraIssue();

Das heißt, zuerst erhalten wir den Inhalt der neuen Seite in Confluence, erstellen dann eine http-Anforderung, erstellen eine Seite in Confluence und schreiben einen Kommentar in die Jira-Anforderung, dass die Seite in Confluence erstellt wird. Lassen Sie uns nun diese Funktionen implementieren:

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;

Wir haben die logischen Blöcke in der Funktion entfernt (Regel 2). Jetzt können wir den Code einfach so schreiben:

string pageJson = getNewConfluencePageContent();
CreateConfluencePageResponse result = createConfluencePage(pageJson);
addCommentToJiraIssue(result.status);
return result.status;

Unser Code enthält vier logische Blöcke. Zuerst erhalten wir den JSON der neuen Seite, dann erstellen wir die Seite in Confluence, fügen der Anforderung einen Kommentar hinzu und geben den Status der Seitenerstellung an Confluence zurück. Diese vier Zeilen geben uns einen Überblick über die Funktionsweise des Skripts. Wenn wir den Inhalt der Seite in Confluence verstehen möchten, können wir jederzeit zu getNewConfluencePageContent gehen und den Inhalt dieser Funktion anzeigen. Diese Funktion enthält nur Code zum Erstellen des Inhalts der Seite und nichts weiter. Während wir den Funktionscode studieren, werden wir nicht von anderen Funktionen abgelenkt.

Wir können davon ausgehen, dass wir Seiten in Confluence nicht nur aus einem Skript erstellen müssen. Erstellen wir daher die Datei converuence_helper.incl und stellen alle erforderlichen Funktionen zum Erstellen einer Seite in Confluence für diese Datei bereit:

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;
}

Ich habe die Funktion createConfluencePage allgemeiner gestaltet, indem ich einen weiteren ConfluenceUrl-Parameter hinzugefügt habe. Daher haben wir Regel 4 befolgt.

Nun sieht unser Hauptskript folgendermaßen aus:

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;

In der ersten Zeile habe ich die Datei converuence_helper.incl eingefügt, um die Seitenerstellungsfunktion in Confluence daraus zu verwenden.

Ich habe die Confluence-Adresse in einer konstanten Variablen gespeichert und die Variablennamen gemäß dem Google Java-Notationsstil geändert (Regel 7).

Es scheint mir, dass dies durch Refactoring gestoppt werden kann. Durch das Refactoring haben wir in Confluence eine wiederverwendbare Funktion zum Erstellen von Seiten erhalten, und unser Code wurde lesbarer und unterstützter.

All Articles