Existem dois esquemas para implementar um release de um aplicativo: é possível substituir todos os objetos no aplicativo ou apenas aqueles que foram alterados. Muitos aplicativos no IBM® i são implementados instalando correções ou fixes sobre um conjunto base de objetos. Chamamos de "fix pack" esse conjunto de novos objetos. À medida que um aplicativo é movido pelos releases, ele acumula um conjunto de fix packs e, com o tempo, haverá diversos fix packs para uma base específica. É possível construir estes fix packs de forma que eles precisem ser aplicados serialmente ou de forma que sejam acumulativos. Também é possível construir fix packs de forma que substituam objetos existentes ou configurem o caminho da procura da lista de bibliotecas de forma que os objetos do fix pack sejam resolvidos em vez dos objetos existentes.
Considere este exemplo. Um aplicativo consiste em vários programas, arquivos e outros objetos, todos residentes em um pequeno conjunto de bibliotecas. Essas bibliotecas estão todas presentes na lista de bibliotecas quando um usuário executa o aplicativo. Um fix pack para o aplicativo substitui alguns dos objetos dessas bibliotecas por versões mais recentes, deixando os outros objetos intactos. Devido à natureza de ligação tardia de programas de serviços em ILE e de programas em geral no OPM, a substituição desses objetos resulta em uma nova versão do aplicativo que está sendo disponibilizado.
Como alternativa, o usuário pode optar por colocar as bibliotecas do fix pack antes do aplicativo base na lista de bibliotecas e permitir que a ligação dinâmica seja realizada usando a lista de bibliotecas. Se toda a ligação for executada usando a lista de bibliotecas, isso se aplicará efetivamente ao fix pack, sem substituir nenhum dos objetos na biblioteca base.
É possível usar o Rational Team Concert para construir fix packs de qualquer tipo.
Neste exemplo, assumiremos que temos duas bibliotecas de origem: FIX e BASE. Para simplificar, também assumiremos que os objetos de aplicativo serão criados diretamente na biblioteca FIX. O arquivo de origem BASE/QRPGLESRC contém os membros A e B. O arquivo de origem BASE/QRPGLEINC contém o membro I. I é um membro incluído, usado por A e B. Neste exemplo, todas as origens de inclusão serão inseridas em QRPGLEINC e o tipo de origem RPGLE será atribuído. Consideramos que BASE seja somente leitura. Todas as mudanças são feitas em FIX. Também suponha que BASE contenha todos os objetos criados a partir da origem em BASE e que FIX contenha os objetos que incluirão o fix pack. Inicialmente, FIX está vazio.
A programadora deseja modificar QRPGLESRC(A). Para fazer isso, ela deverá copiar QRPGLESRC(A) de BASE para FIX. Ela faz isso e modifica o membro. Uma construção deve criar o módulo FIX/A a partir dessa origem.
A programadora agora deseja modificar QRPGLEINC(I). Ela copia isso para QRPGLEINC(I) de BASE para FIX e faz a modificação. Uma construção agora deverá criar o módulo FIX/A a partir dessa origem, mas também criará o módulo FIX/B. Não existe módulo associado a QRPGLEINC(I), embora ele seja do tipo RPGLE, pois ele é um membro incluído e não deve ser compilado.
A organização do projeto, a configuração da construção e o processo de construção devem ser flexíveis o suficiente para determinar o seguinte:
A organização básica do projeto para este exemplo no suporte do i Projects no Rational Developer for Power Systems Software é muito simples. Existe um único projeto com dois arquivos de origem: QRPGLESRC e QRPGLEINC. Cada arquivo de origem contém os membros mencionados acima. Observe que existe apenas um projeto. Como o repositório acompanha todo o histórico desse projeto, seu conteúdo pode variar com o tempo. Não há necessidade de estabelecer um projeto separado para fazer um aprimoramento ou corrigir um aplicativo.
Podemos compartilhar esse projeto em um fluxo do repositório. Dentro desse fluxo, criaremos um instantâneo que será a base para esse aplicativo. Neste exemplo, assumiremos que a biblioteca BASE já terá sido preenchida.
À medida que começarmos a fazer mudanças no aplicativo, o fluxo conterá as mudanças feitas. Associamos uma área de trabalho de construção e sua definição de construção a esse fluxo. A definição de construção terá a biblioteca FIX no IBM i como sua biblioteca de objetos e de carregamento. Essa definição de construção terá a biblioteca BASE em sua definição de construção como a única de suas bibliotecas de referência.
Antes de uma construção ser submetida, o processo de carregamento do instantâneo mantém a biblioteca FIX e a área de trabalho de construção sincronizadas. À medida que as mudanças forem feitas no fluxo, elas fluirão para sua área de trabalho de construção e, a partir dela, para a biblioteca FIX no sistema IBM i. No entanto, como estabelecemos um instantâneo base, somente arquivos diferentes da base serão carregados na biblioteca de correções.
Em nosso exemplo, a programadora faz uma mudança em QRPGLESRC(A) e, em seguida, entrega essa mudança ao fluxo. Isso faz com que a mudança flua para a área de trabalho de construção. Como é uma mudança sobre a base, o membro é carregado na biblioteca FIX do sistema IBM i. Da mesma forma, QRPGLEINC(I) foi alterado e flui para a biblioteca FIX. Nossa biblioteca FIX agora contém dois membros de origem.
Uma lista de bibliotecas consiste em quatro seções: a lista de bibliotecas do sistema, a biblioteca atual, uma ou duas bibliotecas do produto e a lista de bibliotecas de usuário. Por enquanto, ignoraremos as seções de sistema e produto da lista de bibliotecas. A biblioteca atual é uma biblioteca única. A lista de bibliotecas de usuário é formada por múltiplas bibliotecas. Uma biblioteca pode ser a biblioteca atual e também aparecer na lista de bibliotecas de usuário, mas não pode haver duplicatas na lista de bibliotecas de usuário.
Usando nosso exemplo anterior, está claro que desejamos compilar em FIX. Essa deve ser nossa biblioteca atual. Todos os comandos de criação criarão objetos nessa biblioteca por padrão. Como estamos compilando objetos em FIX, especificamos isso na definição de construção.
BASE também precisa estar na lista de bibliotecas para que os membros sejam localizados pelos compiladores. Esta será a única biblioteca em nossa lista de bibliotecas de usuário. Ela será especificada em nossa definição de construção como uma biblioteca de referência.
A lista de bibliotecas também pode conter outra biblioteca depois de BASE. No entanto, estamos procurando candidatos para compilação, mas desejamos procurar apenas em FIX e BASE e não nas bibliotecas subsequentes.
A especificação de construção direciona o processo de construção descrevendo o que é construído e como deve ser construído. Em nosso exemplo, a especificação de construção para o projeto tem dois conjuntos de comandos: um para o RPG do ILE e outro para criar quaisquer programas a partir dos módulos. A especificação de construção também tem dois construtores, um que descreve o que compilar para RPG e outro para criar o programa. Geralmente, conseguimos reutilizar os conjuntos de comandos entre múltiplos construtores, mas desde que esse seja um exemplo simples, não há reutilização.
Para resumir, temos QRPGLESRC(A) do tipo de origem RPGLE em FIX e BASE. Temos QRPGLEINC(I) do tipo de origem RPGLE em FIX e BASE. Temos QRPGLESRC(B) em BASE. A e B incluem I.
O processo de construção precisa examinar todos os candidatos de compilação em QRPGLESRC do tipo RPGLE. Como a lista de bibliotecas pode conter bibliotecas diferentes de FIX e BASE, descrevemos a lista de candidatos usando a variável especial &SP. Essa variável contém as bibliotecas do projeto que devem ser pesquisadas ao procurar a origem a ser compilada. Em nosso caso, &SP é configurado pelo mecanismo de construção para ser a lista (FIX BASE).
Em nossa definição de construtor, definimos a expressão de candidatos de compilação da seguinte forma:
Também definimos a lista de possíveis dependências como:
A aplicação da primeira expressão a nosso exemplo nos fornece os seguintes candidatos de compilação depois que FIX/QRPGLESRC(A) foi criado e modificado:
A aplicação da segunda expressão a nosso exemplo nos fornece a seguinte lista de dependências para estes candidatos:
Sendo assim, alterar QRPGLEINC(I) fará com que FIX/QRPGLESRC(A) e BASE/QRPGLESRC(B) compile a criação dos módulos FIX/A e FIX/B. Alterar apenas QRPGLESRC(A) fará com que apenasFIX/QRPGLESRC(A) compile a criação do módulo FIX/A. Dessa forma, a biblioteca FIX conterá apenas aqueles módulos necessários para um fix pack.
Consulte o Jazz.net para obter mais informações.