C贸digo SIL limpio

SIL es un lenguaje de programaci贸n para automatizar el trabajo en Atlassian Jira y Confluence. Puedes leer m谩s sobre SIL aqu铆 .

A menudo trabajo con scripts escritos en SIL, y me gustar铆a compartir con ustedes mis pensamientos sobre c贸mo hacer que el c贸digo SIL sea "limpio".

En este art铆culo, primero formular茅 las reglas que me gu铆an al escribir c贸digo SIL, y luego dar茅 un ejemplo de c贸digo y refactorizar茅 usando estas reglas.

reglas


  1. Las estructuras de nombres comienzan con una letra may煤scula.
  2. Agregue elementos de matriz utilizando el m茅todo AddElement .
  3. Use rutinas definidas por el usuario para dividir su c贸digo en bloques l贸gicos y deshacerse de los comentarios en el c贸digo.
  4. Traiga c贸digo reutilizable a las bibliotecas ( inclusiones ).
  5. Declarar estructuras antes del resto de la declaraci贸n de variable.
  6. D茅 nombres significativos a las estructuras y variables, en este caso no tiene que agregar comentarios adicionales a las estructuras y variables.
  7. Nombre variables y funciones de acuerdo con la gu铆a de estilo Google Java .

Ahora veamos un ejemplo de c贸digo 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;

Mirar el c贸digo es bastante dif铆cil de determinar r谩pidamente qu茅 est谩 haciendo el c贸digo. Los comentarios en el c贸digo tampoco ayudan mucho. Intentemos cambiar el c贸digo de acuerdo con las reglas anteriores.

Primero mira la estructura. Aqu铆 hay un ejemplo:

struct body {
    storage storage;
}

Vemos que el "almacenamiento de almacenamiento" parece incomprensible. Ser铆a m谩s claro si el c贸digo fuera as铆:

struct body {
    Storage storage;
}

Ahora vemos que definimos un campo en la estructura bajo el nombre de almacenamiento de tipo Almacenamiento. Para que podamos escribir dicho c贸digo, necesitamos poner en may煤scula la primera letra de cada estructura:

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

Ahora cambiemos el nombre de la estructura para que el nombre de la estructura deje en claro por qu茅 es necesaria, y no tendr铆amos que agregar comentarios:

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

En mi opini贸n, dichos nombres no requieren comentarios adicionales para las estructuras. Tambi茅n declararemos estructuras al comienzo del c贸digo.

Usamos las Reglas 1, 5, 6.

Ahora veamos el c贸digo despu茅s de la declaraci贸n de estructuras:

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;

Mirando el c贸digo, no podemos entender r谩pidamente lo que est谩 sucediendo en el c贸digo. Primero intentemos dividir el c贸digo en bloques l贸gicos:

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

Es decir, primero obtenemos el contenido de la nueva p谩gina en Confluence, luego creamos una solicitud http, creamos una p谩gina en Confluence y escribimos un comentario en la solicitud de Jira de que se crea la p谩gina en Confluence. Ahora implementemos estas funciones:

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;

Eliminamos los bloques l贸gicos en la funci贸n (Regla 2). Ahora podemos simplemente escribir el c贸digo as铆:

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

Nuestro c贸digo contiene cuatro bloques l贸gicos. Primero obtenemos el json de la nueva p谩gina, luego creamos la p谩gina en Confluence, agregamos un comentario a la solicitud y devolvemos el estado de creaci贸n de la p谩gina a Confluence. Estas cuatro l铆neas nos dan una vista de nivel superior de lo que hace el script. Si queremos entender el contenido de la p谩gina en Confluence, siempre podemos ir a getNewConfluencePageContent y ver el contenido de esta funci贸n. Esta funci贸n contiene solo c贸digo para crear el contenido de la p谩gina y nada m谩s, por lo tanto, mientras estudiamos el c贸digo de la funci贸n, no nos distraeremos con otra funcionalidad.

Podemos suponer que necesitaremos crear p谩ginas en Confluence no solo a partir de un script. Por lo tanto, creemos el archivo confluence_helper.incl y publiquemos todas las funciones necesarias para crear una p谩gina en Confluence para este archivo:

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

Hice que la funci贸n createConfluencePage sea m谩s general al agregarle otro par谩metro confluenceUrl. Por lo tanto, seguimos la Regla 4.

Ahora nuestro script principal se ver谩 as铆:

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;

En la primera l铆nea, inclu铆 el archivo confluence_helper.incl para usar la funci贸n de creaci贸n de p谩gina en Confluence.

Guard茅 la direcci贸n de Confluence en una variable constante y cambi茅 los nombres de las variables de acuerdo con el estilo de notaci贸n de Java de Google (Regla 7).

Me parece que esto se puede detener con la refactorizaci贸n. Como resultado de la refactorizaci贸n, obtuvimos una funci贸n de creaci贸n de p谩gina reutilizable en Confluence, y nuestro c贸digo se volvi贸 m谩s legible y compatible.

All Articles