Crea tus funciones en SIL

¡Hola a todos!

En este artículo quiero decir cómo crear mi función en SIL.

Introducción


SIL significa Simple Issue Language, creado por los desarrolladores de cPrime para automatizar las acciones manuales en Atlassian Jira y Confluence.

La principal ventaja de SIL es que SIL contiene funciones que no requieren conocimiento de las API de Atlassian Jira o Atlassian Confluence para usarlas. Esto reduce significativamente el umbral para ingresar SIL y hace que el código del programa SIL sea más pequeño en volumen que el código Java o Groovy similar.

Por ejemplo, desea seleccionar tickets de Jira a pedido, para que pueda realizar algunas acciones en ellos. Para hacer esto, en Java o Groovy, tendría que escribir una docena de líneas de código. En SIL, esta es una línea:

selectIssues(" JQL ");

Además, en Java o Groovy, deberá garantizar la compatibilidad del código en Jira 7 y Jira 8. En SIL no necesita pensar en la compatibilidad. SelectIssues funcionará en todas las versiones de Jira compatibles con SIL.

Puede encontrar más sobre SIL aquí .
Pero, ¿qué pasa si necesito hacer algo como esto? ¿Por qué no hay funciones en SIL? Por ejemplo, necesito obtener datos del complemento Table Grid Next Generation o generar un archivo PDF utilizando el exportador PDF para el complemento Jira.

En este caso, tiene dos opciones:

  1. SIL Groovy Connector : este complemento le permite escribir código utilizando la API Jira Java en Java o Groovy y llamar a este código desde un script SIL.
  2. Escriba su complemento Jira que agregará sus funciones a SIL, y luego use sus funciones en scripts SIL

En este artículo, nos centraremos en cómo escribir su complemento Jira para ampliar las funciones de SIL. Para repetir los pasos de este artículo, necesitará Atlassian SDK y git.

Establecer el arquetipo maven


Un complemento que extenderá SIL debe contener lógica que agregará sus funciones a SIL. Para no agregar esta lógica al complemento cada vez, sino concentrarme solo en las funciones de escritura, creé el arquetipo de Maven que creará todo lo que necesita en el nuevo complemento.

Primero, clone el arquetipo del repositorio:

git clone https://alex1mmm@bitbucket.org/alex1mmm/sil-extension-archetype.git --branch v1 --single-branch

Se creará la carpeta sil-extenstion-archetype. Vamos a entrar en eso:

cd sil-extension-archetype

Ahora instale el arquetipo en su repositorio local de Maven:

atlas-mvn install

Crea un complemento


Vaya a la carpeta de arriba y cree un nuevo complemento

cd ..
atlas-mvn archetype:generate -DarchetypeCatalog=local

Se le harán preguntas estándar al crear un proyecto a través de Maven. Doy mis respuestas a las preguntas. Puedes cambiarlos.

Choose archetype:

1: local -> com.cprime.jira.sil.extension:sil-extension-archetype (This is the com.cprime.jira.sil.extension:sil-extension plugin for Atlassian JIRA.)
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 

Define value for property 'groupId': ru.matveev.alexey.sil.extension
Define value for property 'artifactId': sil-extension
Define value for property 'version' 1.0-SNAPSHOT: : 
Define value for property 'package' ru.matveev.alexey.sil.extension: : 

Confirm properties configuration:
groupId: ru.matveev.alexey.sil.extension
artifactId: sil-extension
version: 1.0-SNAPSHOT
package: ru.matveev.alexey.sil.extension

 Y: : Y

Después de eso, se creará el complemento.

Complemento de prueba


Vaya a la carpeta creada (en mi caso es sil-extension) y ejecute Jira:

cd sil-extension
atlas-run</code>
 Jira   
<code>http://localhost:2990/jira/plugins/servlet/silmanager?autoSelectTree=sil.scripts

Verá la pantalla SIL Manager. Seleccione la opción Nuevo archivo:



Cree un archivo test.sil con el siguiente contenido:

runnerLog(SayHello("Alexey"));
string[] res = SayHello2("Alexey", "Matveev");
runnerLog(res[0]);
runnerLog(res[1]);
res = SayHello3("Alexey", "Matveev");
runnerLog(res["param1"]);
runnerLog(res["param2"]);

La pantalla en Jira se verá así:



Nuestro complemento agregó tres funciones: SayHello, SayHello2, SayHello3. Test.sil comprueba que las funciones se han agregado a SIL.

Ejecute test.sil haciendo clic en el botón Ejecutar. En la pestaña Consola, debería ver el siguiente texto:

Hello Alexey
Hello Alexey
Hello Matveev
Hello Alexey
Hello Matveev
Done.

Si vio dicho texto, nuestras funciones se han agregado con éxito a SIL.

Ahora hablemos sobre lo que debe cambiarse en el complemento para crear nuestra propia función.

Crea una clase Java para nuestra función


Cada función que desee agregar a SIL debe tener su propia clase. Esta clase debe ser descendiente de la clase AbstractSILRoutine.

Para entender lo que debe agregarse a una nueva clase, veamos los ejemplos disponibles.

SayHello.java


public class SayHello extends AbstractSILRoutine<MutableString> { 
  private static final SILType[][] types = {{ TypeInst.STRING }};

  public SayHello(ClassLoader classLoader, String name) { 
    super(classLoader, name, types);
  }

  @Override 
  public SILType<MutableString> getReturnType() { return TypeInst.STRING; }

  @Override 
  protected SILValue<MutableString> runRoutine(SILContext silContext,                                   List<SILValue<?>> list) { 
    SILValue param = list.get(0); 
    return SILValueFactory.string( "Hello " + param.toStringValue());
 }
  @Override 
  public String getParams() { return "(name)"; }

Primera linea:

private static final SILType[][] types = {{ TypeInst.STRING }};

Esta línea define los tipos y el número de parámetros que se pasarán a su función. La función en SIL se ve así:

mymethod(myparameter);

En consecuencia, {{TypeInst.STRING}} significa que tendremos un parámetro y su tipo será String. Si desea pasar dos parámetros de tipo String, debe cambiar la cadena de esta manera:

private static final SILType[][] types = {{ TypeInst.STRING, TypeInst.STRING }};

En SIL, puede llamar a su función de esta manera:

mymethod(myparameter1, myparameter2);

Si su función puede aceptar uno o dos parámetros. Ese término se verá así:

private static final SILType[][] types = {{ TypeInst.STRING},  
                                                          {TypeInst.STRING, TypeInst.STRING }};

Luego viene:

public class SayHello extends AbstractSILRoutine<MutableString>

Heredamos nuestra clase de AbstractSILRoutine, lo que significa que nuestra clase devolverá un parámetro de tipo String.

Más lejos:

public SayHello(ClassLoader classLoader, String name) { 
  super(classLoader, name, types);
}

Este es el constructor. Probablemente no tendrá que cambiar nada en él.

Más lejos:

@Override 
public SILType<MutableString> getReturnType() { return TypeInst.STRING; }

Aquí determinamos el tipo del parámetro devuelto. En nuestro caso, es String.

Más lejos:

@Override 
protected SILValue<MutableString> runRoutine(SILContext silContext, List<SILValue<?>> list) { 
SILValue param = list.get(0); 
return SILValueFactory.string( "Hello " + param.toStringValue());
}

Este es el principal punto de entrada para su función. Cuando ejecutas una función en SIL, llegarás aquí. Toda la lógica está aquí.

Esta función toma dos parámetros:

silContext : le permite obtener las variables Jira y SIL.

Por ejemplo, su secuencia de comandos SIL funciona como una función de publicación y desea recibir un ticket bajo el cual se ejecuta la secuencia de comandos:

Issue issue = (Issue) silContext.getAllMetaInformation().get("issue");

lista: le permite obtener los valores de los parámetros pasados ​​a la función SIL.

SILValue param = list.get(0); 

Línea:

SILValueFactory.string( "Hello " + param.toStringValue());

devuelve el valor Debe devolver valores que SIL entienda, así que use SILValueFactory para generar los valores.

Más lejos:

@Override 
public String getParams() { return "(name)"; }

Esto define el tipo de función en SIL Manager. Cuando comience a escribir en el administrador SIL, se le presentará una pista de las funciones disponibles. En nuestro caso, verá:

yourmethod(name)

Agregue nuestra clase al motor SIL


Has creado tu clase. Ahora debe hacer que SIL conozca su función. Esto se hace en el archivo ESLauncher.java. Este archivo contiene estas líneas:

RoutineRegistry.register(new SayHello( classLoader,"SayHello")); 

Esta línea dice que estamos agregando la clase SayHello a SIL bajo el nombre SayHello. El nombre de la clase y la función pueden no coincidir.

A continuación, agregue la siguiente línea:

RoutineRegistry.unregister("SayHello");

Cambie SayHello al nombre de su función. Esta línea descargará su función de SIL si elimina su complemento de Jira.

Más acerca de SIL


En la clase SayHello2, devolvemos una Lista.

SILValue param1 = list.get(0); 
SILValue param2 = list.get(1); 
List<String> res = new ArrayList<>(); 
res.add("Hello " + param1.toStringValue()); 
res.add("Hello " + param2.toStringValue()); 
return SILValueFactory.stringArray(res);

Para que esto funcione, también debe cambiar el valor de retorno a TypeInst.STRING_ARR y heredar de AbstractSILRoutine con KeyableArraySILObject.

En SIL, llamas a SayHello2 así:

string[] res = SayHello2("Alexey", "Matveev");
runnerLog(res[0]);
runnerLog(res[1]);

En SayHello3 devolvemos Mapa:

SILValue param1 = list.get(0); 
SILValue param2 = list.get(1); 
Map<String, String> res = new HashMap<>(); 
res.put("param1","Hello " + param1.toStringValue()); 
res.put("param2","Hello " + param2.toStringValue()); 
return SILValueFactory.stringArray(res);

En SIL, puede llamar a SayHello3 de esta manera:

res = SayHello3("Alexey", "Matveev");
runnerLog(res["param1"]);
runnerLog(res["param2"]);

En este caso, obtenemos los elementos de la matriz no por índice, sino por claves.

Si observa el código en Java, en ambos casos trabajamos con KeyableArraySILObject. El hecho es que en SIL List y Map son implementados por la clase KeyableArraySILObject. Aquellos. Se puede acceder a cualquier matriz en SIL por índice o por clave.

Pasamos una matriz como parámetro


Podemos devolver una matriz desde la función SIL. Ahora veamos cómo pasar una matriz como parámetro.

El código se verá así:

@Override
protected SILValue<MutableString> runRoutine(SILContext silContext, List<SILValue<?>> list) {
    GenericArraySILObject rowsToUpdate =  (GenericArraySILObject) list.get(0).getObject();
    Map<String, int[]> keys = rowsToUpdate.getKeysMapping()
......
}

Primero, obtenemos el objeto de la clase GenericArraySILObject del parámetro, y luego obtenemos el Mapa de él.

En SIL, puede pasar una matriz como esta:

string[] arr;
arr["key1"] = "value1";
arr["key2"] = "value2";
yourmethod(arr);

Eso concluye este artículo. Espero que haya adquirido suficiente conocimiento para escribir su función en SIL.

All Articles