Crie suas funções no SIL

Olá a todos!

Neste artigo, quero dizer como criar minha função no SIL.

Introdução


SIL significa Simple Issue Language, foi criado pelos desenvolvedores do cPrime para automatizar ações manuais no Atlassian Jira e Confluence.

A principal vantagem do SIL é que o SIL contém funções que não requerem conhecimento das APIs do Atlassian Jira ou Atlassian Confluence para usá-las. Isso reduz significativamente o limite de entrada do SIL e torna o código do programa SIL menor em volume que o código Java ou Groovy semelhante.

Por exemplo, você deseja selecionar tickets do Jira mediante solicitação, para poder executar algumas ações neles. Para fazer isso, em Java ou Groovy, você teria que escrever uma dúzia de linhas de código. No SIL, esta é uma linha:

selectIssues(" JQL ");

Além disso, em Java ou Groovy, você precisaria garantir a compatibilidade do código no Jira 7 e Jira 8. No SIL, você não precisa pensar em compatibilidade. O SelectIssues funcionará em todas as versões do Jira suportadas pelo SIL.

Você pode encontrar mais informações sobre o SIL aqui .
Mas e se eu precisar fazer algo assim, por que não há funções no SIL? Por exemplo, preciso obter dados do plug-in Table Grid Next Generation ou gerar um arquivo PDF usando o exportador de PDF para o plugin Jira.

Nesse caso, você tem duas opções:

  1. Conector SIL Groovy - esse plug-in permite escrever código usando a API Jira Java em Java ou Groovy e chamar esse código a partir de um script SIL.
  2. Escreva seu plugin Jira que adicionará suas funções ao SIL e, em seguida, use suas funções nos scripts SIL

Neste artigo, focaremos em como escrever seu plugin Jira para estender as funções do SIL. Para repetir as etapas deste artigo, você precisará do Atlassian SDK e git.

Defina o arquétipo do maven


Um plug-in que estenderá o SIL deve conter lógica que adicionará suas funções ao SIL. Para não adicionar essa lógica ao plugin todas as vezes, mas para me concentrar apenas nas funções de escrita, criei o arquétipo do maven que criará tudo o que você precisa no novo plugin.

Primeiro, clone o arquétipo do repositório:

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

A pasta sil-extenstion-archetype será criada. Vamos entrar nisso:

cd sil-extension-archetype

Agora instale o arquétipo no seu repositório maven local:

atlas-mvn install

Crie um plugin


Vá para a pasta acima e crie um novo plugin

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

Você receberá perguntas padrão ao criar um projeto através do maven. Eu dou minhas respostas para as perguntas. Você pode mudá-los.

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

Depois disso, o plugin será criado.

Plugin de teste


Vá para a pasta criada (no meu caso, é sil-extension) e execute o Jira:

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

Você verá a tela do SIL Manager. Selecione a opção Novo arquivo:



Crie um arquivo test.sil com o seguinte conteúdo:

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

A tela no Jira terá a seguinte aparência:



Nosso plug-in adicionou três funções: SayHello, SayHello2, SayHello3. Test.sil verifica se as funções foram adicionadas ao SIL.

Execute test.sil clicando no botão Executar. Na guia Console, você verá o seguinte texto:

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

Se você viu esse texto, nossas funções foram adicionadas com sucesso ao SIL.

Agora vamos falar sobre o que precisa ser alterado no plugin para criar nossa própria função.

Crie uma classe Java para nossa função


Cada função que você deseja adicionar ao SIL deve ter sua própria classe. Esta classe deve ser descendente da classe AbstractSILRoutine.

Para entender o que precisa ser adicionado a uma nova classe, vejamos os exemplos disponíveis.

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

Primeira linha:

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

Esta linha define os tipos e o número de parâmetros que serão passados ​​para sua função. A função no SIL se parece com isso:

mymethod(myparameter);

Assim, {{TypeInst.STRING}} significa que teremos um parâmetro e seu tipo será String. Se você deseja passar dois parâmetros do tipo String, precisará alterar a string assim:

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

No SIL, você pode chamar sua função assim:

mymethod(myparameter1, myparameter2);

Se sua função pode aceitar um ou dois parâmetros. Esse termo terá a seguinte aparência:

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

Em seguida vem:

public class SayHello extends AbstractSILRoutine<MutableString>

Herdamos nossa classe de AbstractSILRoutine, o que significa que nossa classe retornará um parâmetro do tipo String.

Mais longe:

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

Este é o construtor. Você provavelmente não terá que mudar nada.

Mais longe:

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

Aqui, determinamos o tipo do parâmetro retornado. No nosso caso, é String.

Mais longe:

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

Este é o principal ponto de entrada para sua função. Quando você executa uma função no SIL, você chega aqui. Toda a lógica está aqui.

Essa função usa dois parâmetros:

silContext - permite obter as variáveis ​​Jira e SIL.

Por exemplo, seu script SIL funciona como uma função de postagem e você deseja receber um ticket sob o qual o script é executado:

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

lista - permite obter os valores dos parâmetros passados ​​para a função SIL.

SILValue param = list.get(0); 

Linha:

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

retorna o valor Você deve retornar valores que o SIL entende, portanto, use SILValueFactory para gerar os valores.

Mais longe:

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

Isso define o tipo de função no SIL Manager. Ao começar a digitar no gerenciador do SIL, você recebe uma dica das funções disponíveis. No nosso caso, você verá:

yourmethod(name)

Adicione nossa classe ao mecanismo SIL


Você criou sua turma. Agora você precisa conscientizar o SIL sobre sua função. Isso é feito no arquivo ESLauncher.java. Este arquivo contém estas linhas:

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

Esta linha diz que estamos adicionando a classe SayHello ao SIL sob o nome SayHello. O nome e a função da classe podem não corresponder.

Em seguida, adicione a seguinte linha:

RoutineRegistry.unregister("SayHello");

Altere o SayHello para o nome da sua função. Esta linha descarregará sua função do SIL se você remover o plugin do Jira.

Mais sobre o SIL


Na classe SayHello2, retornamos uma 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 isso funcione, você também precisa alterar o valor de retorno para TypeInst.STRING_ARR e herdar de AbstractSILRoutine com KeyableArraySILObject.

No SIL, você chama SayHello2 assim:

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

No SayHello3, retornamos o 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);

No SIL, você pode chamar SayHello3 assim:

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

Nesse caso, obtemos os elementos da matriz não pelo índice, mas pelas chaves.

Se você observar o código em Java, nos dois casos, trabalharemos com KeyableArraySILObject. O fato é que na lista e no mapa SIL são implementados pela classe KeyableArraySILObject. Essa. qualquer matriz no SIL pode ser acessada por índice ou por chave.

Passamos uma matriz como parâmetro


Podemos retornar uma matriz da função SIL. Agora vamos ver como passar uma matriz como parâmetro.

O código ficará assim:

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

Primeiro, obtemos o objeto da classe GenericArraySILObject a partir do parâmetro e, em seguida, obtemos o mapa a partir dele.

No SIL, você pode transmitir uma matriz como esta:

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

Isso conclui este artigo. Espero que você tenha adquirido conhecimento suficiente para escrever sua função no SIL.

All Articles