Créez vos fonctions dans SIL

Bonjour à tous!

Dans cet article, je veux expliquer comment créer ma fonction dans SIL.

introduction


SIL signifie Simple Issue Language, a été créé par les développeurs cPrime pour automatiser les actions manuelles dans Atlassian Jira et Confluence.

Le principal avantage de SIL est que SIL contient des fonctions qui ne nécessitent pas la connaissance des API Atlassian Jira ou Atlassian Confluence pour les utiliser. Cela réduit considérablement le seuil d'entrée dans SIL et rend le code de programme SIL plus petit en volume que le code Java ou Groovy similaire.

Par exemple, vous souhaitez sélectionner des tickets dans Jira sur demande, afin de pouvoir effectuer certaines actions sur ceux-ci. Pour ce faire, en Java ou Groovy, il faudrait écrire une douzaine de lignes de code. Sur SIL, c'est une ligne:

selectIssues(" JQL ");

De plus, en Java ou Groovy, vous devez assurer la compatibilité du code sur Jira 7 et Jira 8. Dans SIL, vous n'avez pas besoin de penser à la compatibilité. SelectIssues fonctionnera sur toutes les versions de Jira prises en charge par SIL.

Vous pouvez en savoir plus sur SIL ici .
Mais que faire si j'ai besoin de faire quelque chose comme ça, pourquoi n'y a-t-il pas de fonctions dans SIL? Par exemple, j'ai besoin d'obtenir des données du plugin Table Grid Next Generation ou de générer un fichier PDF à l'aide de l'exportateur PDF pour le plugin Jira.

Dans ce cas, vous avez deux options:

  1. SIL Groovy Connector - ce plugin vous permet d'écrire du code à l'aide de l'API Java Jira en Java ou Groovy et d'appeler ce code à partir d'un script SIL.
  2. Écrivez votre plugin Jira qui ajoutera vos fonctions à SIL, puis utilisez vos fonctions dans les scripts SIL

Dans cet article, nous nous concentrerons sur la façon d'écrire votre plugin Jira pour étendre les fonctions de SIL. Pour répéter les étapes de cet article, vous aurez besoin du SDK Atlassian et de git.

Définir l'archétype maven


Un plugin qui étendra SIL doit contenir une logique qui ajoutera vos fonctions à SIL. Afin de ne pas ajouter cette logique au plugin à chaque fois, mais de me concentrer uniquement sur les fonctions d'écriture, j'ai créé l'archétype maven qui créera tout ce dont vous avez besoin dans le nouveau plugin.

Tout d'abord, clonez l'archétype du référentiel:

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

Le dossier sil-extenstion-archetype sera créé. Allons-y:

cd sil-extension-archetype

Installez maintenant l'archétype dans votre référentiel maven local:

atlas-mvn install

Créer un plugin


Accédez au dossier ci-dessus et créez un nouveau plugin

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

Des questions standard vous seront posées lors de la création d'un projet via maven. Je donne mes réponses aux questions. Vous pouvez les changer.

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

Après cela, le plugin sera créé.

Plugin de test


Allez dans le dossier créé (dans mon cas, c'est sil-extension) et exécutez Jira:

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

Vous verrez l'écran SIL Manager. Sélectionnez l'option Nouveau fichier:



créez un fichier test.sil avec le contenu suivant:

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

L'écran de Jira ressemblera à ceci:



Notre plugin a ajouté trois fonctions: SayHello, SayHello2, SayHello3. Test.sil vérifie que des fonctions ont été ajoutées à SIL.

Exécutez test.sil en cliquant sur le bouton Exécuter. Dans l'onglet Console, vous devriez voir le texte suivant:

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

Si vous avez vu un tel texte, nos fonctions ont été ajoutées avec succès à SIL.

Parlons maintenant de ce qui doit être changé dans le plugin afin de créer notre propre fonction.

Créer une classe Java pour notre fonction


Chaque fonction que vous souhaitez ajouter à SIL doit avoir sa propre classe. Cette classe doit être un descendant de la classe AbstractSILRoutine.

Afin de comprendre ce qui doit être ajouté à une nouvelle classe, regardons les exemples 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)"; }

Première ligne:

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

Cette ligne définit les types et le nombre de paramètres qui seront transmis à votre fonction. La fonction dans SIL ressemble à ceci:

mymethod(myparameter);

Par conséquent, {{TypeInst.STRING}} signifie que nous aurons un paramètre et que son type sera String. Si vous souhaitez passer deux paramètres de type String, vous devez modifier la chaîne comme ceci:

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

Dans SIL, vous pouvez appeler votre fonction comme ceci:

mymethod(myparameter1, myparameter2);

Si votre fonction peut accepter un ou deux paramètres. Ce terme ressemblera à ceci:

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

Vient ensuite:

public class SayHello extends AbstractSILRoutine<MutableString>

Nous héritons notre classe de AbstractSILRoutine, ce qui signifie que notre classe renverra un paramètre de type String.

Plus loin:

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

Ceci est le constructeur. Vous n'aurez probablement rien à y changer.

Plus loin:

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

Ici, nous déterminons le type du paramètre renvoyé. Dans notre cas, c'est String.

Plus loin:

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

Il s'agit du principal point d'entrée pour votre fonction. Lorsque vous exécutez une fonction dans SIL, vous y arriverez. Toute la logique est là.

Cette fonction prend deux paramètres:

silContext - vous permet d'obtenir les variables Jira et SIL.

Par exemple, votre script SIL fonctionne comme une fonction de publication et vous souhaitez recevoir un ticket sous lequel le script est exécuté:

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

list - vous permet d'obtenir les valeurs des paramètres passés à la fonction SIL.

SILValue param = list.get(0); 

Ligne:

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

renvoie la valeur. Vous devez renvoyer des valeurs que SIL comprend, utilisez donc SILValueFactory pour générer les valeurs.

Plus loin:

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

Ceci définit le type de fonction dans SIL Manager. Lorsque vous commencez à taper dans le gestionnaire SIL, vous obtenez un aperçu des fonctions disponibles. Dans notre cas, vous verrez:

yourmethod(name)

Ajoutez notre classe au moteur SIL


Vous avez créé votre classe. Vous devez maintenant informer SIL de votre fonction. Cela se fait dans le fichier ESLauncher.java. Ce fichier contient ces lignes:

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

Cette ligne indique que nous ajoutons la classe SayHello à SIL sous le nom SayHello. Le nom et la fonction de la classe peuvent ne pas correspondre.

Ensuite, ajoutez la ligne suivante:

RoutineRegistry.unregister("SayHello");

Remplacez SayHello par le nom de votre fonction. Cette ligne déchargera votre fonction de SIL si vous supprimez votre plugin de Jira.

En savoir plus sur SIL


Dans la classe SayHello2, nous renvoyons une liste.

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

Pour que cela fonctionne, vous devez également modifier la valeur de retour en TypeInst.STRING_ARR et hériter de AbstractSILRoutine avec KeyableArraySILObject.

Dans SIL, vous appelez SayHello2 comme ceci:

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

Dans SayHello3, nous retournons la carte:

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

Dans SIL, vous pouvez appeler SayHello3 comme ceci:

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

Dans ce cas, nous obtenons les éléments du tableau non pas par index, mais par clés.

Si vous regardez le code en Java, dans les deux cas, nous travaillons avec KeyableArraySILObject. Le fait est que dans SIL List et Map sont implémentés par la classe KeyableArraySILObject. Ceux. n'importe quel tableau dans SIL est accessible soit par index, soit par clé.

On passe un tableau en paramètre


Nous pouvons renvoyer un tableau à partir de la fonction SIL. Voyons maintenant comment passer un tableau en tant que paramètre.

Le code ressemblera à ceci:

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

Tout d'abord, nous obtenons l'objet de la classe GenericArraySILObject à partir du paramètre, puis nous obtenons la carte de celui-ci.

Dans SIL, vous pouvez passer un tableau comme celui-ci:

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

Cela conclut cet article. J'espère que vous avez acquis suffisamment de connaissances pour écrire votre fonction en SIL.

All Articles