Code SIL propre

SIL est un langage de programmation pour automatiser le travail dans Atlassian Jira et Confluence. Vous pouvez en savoir plus sur SIL ici .

Je travaille souvent avec des scripts écrits en SIL, et je voudrais partager avec vous mes réflexions sur la façon de rendre le code SIL «propre».

Dans cet article, je vais d'abord formuler les règles que je respecte lors de l'écriture de code SIL, puis donner un exemple de code et effectuer la refactorisation à l'aide de ces règles.

règles


  1. Les structures de noms commencent par une majuscule.
  2. Ajoutez des éléments de tableau à l'aide de la méthode AddElement .
  3. Utilisez des routines définies par l'utilisateur pour diviser votre code en blocs logiques et vous débarrasser des commentaires dans le code.
  4. Apportez du code réutilisable aux bibliothèques ( inclusions ).
  5. Déclarez les structures avant le reste de la déclaration de variable.
  6. Donnez des noms significatifs aux structures et aux variables, dans ce cas, vous n'avez pas à ajouter de commentaires supplémentaires aux structures et aux variables.
  7. Nommez les variables et les fonctions conformément au guide de style Google Java .

Voyons maintenant un exemple de code 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;

En regardant le code, il est assez difficile de déterminer rapidement ce que fait le code. Les commentaires dans le code n'aident pas beaucoup non plus. Essayons de changer le code selon les règles ci-dessus.

Regardez d'abord la structure. Voici un exemple:

struct body {
    storage storage;
}

Nous voyons que le «stockage de stockage» semble incompréhensible. Il serait plus clair si le code était comme ceci:

struct body {
    Storage storage;
}

Nous voyons maintenant que nous définissons un champ dans la structure sous le nom de stockage de type Stockage. Pour que nous puissions écrire un tel code, nous devons mettre en majuscule la première lettre de chaque structure:

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

Maintenant, renommons la structure afin que le nom de la structure indique clairement pourquoi elle est nécessaire, et nous n'aurions pas à ajouter de commentaires:

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

À mon avis, de tels noms ne nécessitent pas de commentaires supplémentaires pour les structures. Nous déclarerons également les structures au tout début du code.

Nous avons utilisé les règles 1, 5, 6.

Regardons maintenant le code après la déclaration des structures:

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;

En regardant le code, nous ne pouvons pas comprendre rapidement ce qui se passe dans le code. Essayons d'abord de diviser le code en blocs logiques:

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

C'est-à-dire que nous obtenons d'abord le contenu de la nouvelle page dans Confluence, puis créons une demande http, créons une page dans Confluence et écrivons un commentaire dans la demande Jira que la page dans Confluence est créée. Maintenant, implémentons ces fonctions:

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;

Nous avons supprimé les blocs logiques de la fonction (règle 2). Maintenant, nous pouvons simplement écrire le code comme ceci:

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

Notre code contient quatre blocs logiques. Nous obtenons d'abord le json de la nouvelle page, puis créons la page dans Confluence, ajoutez un commentaire à la demande et renvoyons le statut de création de page à Confluence. Ces quatre lignes nous donnent une vue globale de ce que fait le script. Si nous voulons comprendre le contenu de la page dans Confluence, alors nous pouvons toujours aller sur getNewConfluencePageContent et voir le contenu de cette fonction. Cette fonction ne contient que du code pour créer le contenu de la page et rien de plus, ainsi, tout en étudiant le code de fonction, nous ne serons pas distraits par d'autres fonctionnalités.

Nous pouvons supposer que nous devrons créer des pages dans Confluence non seulement à partir d'un script. Par conséquent, créons le fichier confluence_helper.incl et mettons toutes les fonctions nécessaires pour créer une page dans Confluence dans ce fichier:

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

J'ai rendu la fonction createConfluencePage plus générale en y ajoutant un autre paramètre confluenceUrl. Ainsi, nous avons suivi la règle 4.

Maintenant, notre script principal ressemblera à ceci:

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;

Dans la première ligne, j'ai inclus le fichier confluence_helper.incl pour utiliser la fonction de création de page dans Confluence à partir de celui-ci.

J'ai enregistré l'adresse Confluence dans une variable constante et changé les noms de variable conformément au style de notation Google Java (règle 7).

Il me semble que cela peut être arrêté avec un refactoring. À la suite de la refactorisation, nous avons obtenu une fonction de création de page réutilisable dans Confluence, et notre code est devenu plus lisible et pris en charge.

All Articles