O compositor.lock deve ser comprometido com o controle de versão?

529

Estou um pouco confuso com o composer.lockusado em um aplicativo com um repositório.

Vi muitas pessoas dizendo que não deveríamos .gitignore composer.lockdo repositório.

Se eu atualizar minhas bibliotecas no meu ambiente de desenvolvimento, terei um novo, composer.lockmas não poderei atualizá-las para produção, pois não?

Isso não gerará conflitos nesse arquivo?

Pierre de LESPINAY
fonte
1
Esse link agora está morto @markus
Kyrre

Respostas:

674

Se você atualizar suas bibliotecas, também deseja confirmar o arquivo de bloqueio. Ele basicamente afirma que seu projeto está bloqueado para as versões específicas das bibliotecas que você está usando.

Se você confirmar suas alterações e alguém extrair seu código e atualizar as dependências, o arquivo de bloqueio não deverá ser modificado. Se for modificado, significa que você tem uma nova versão de algo.

Tê-lo no repositório garante que cada desenvolvedor esteja usando as mesmas versões.

meza
fonte
5
Ok, mas imagine se eu atualizar as bibliotecas do ambiente de produção, composer.lock será substituído de modo a próxima atração da produção vai me pedir para mesclar esse arquivo ...
Pierre de LESPINAY
7
Se o composer.lock for modificado, você precisará enviar as modificações de volta ao repositório. Se você deseja vincular o software a determinadas versões das bibliotecas, faça-o explicitamente na configuração. Dessa forma, a fechadura nunca muda. Pense no arquivo de bloqueio como um indicador de um problema de gerenciamento de dependências que precisa ser resolvido de uma maneira ou de outra.
meza
361
Na produção, você não deve atualizar suas dependências, deve executar o composer installque irá ler o arquivo de bloqueio e não alterar nada.
Seldaek
112
"Na produção, você não deve atualizar suas dependências" deve ser escrito em maiúsculas
Joaquín L. Robles
75
@ JoaquínL.Robles NA PRODUÇÃO, VOCÊ NÃO DEVE ATUALIZAR SUAS DEPENDÊNCIAS! :)
Елин Й.
201

Para aplicativos / projetos : Definitivamente, sim.

A documentação do compositor declara isso (com ênfase):

Confirme o composer.lock do seu aplicativo (junto com o composer.json) no controle de versão.

Como o @meza disse: Você deve confirmar o arquivo de bloqueio para que você e seus colaboradores estejam trabalhando no mesmo conjunto de versões e impedindo-o de dizer algo como "Mas funcionou no meu computador". ;-)

Para bibliotecas : Provavelmente não.

A documentação do compositor observa sobre este assunto:

Nota: Para bibliotecas, não é necessariamente recomendável confirmar o arquivo de bloqueio (...)

E afirma aqui :

Para sua biblioteca, você pode confirmar o arquivo composer.lock, se desejar. Isso pode ajudar sua equipe a testar sempre as mesmas versões de dependência. No entanto, esse arquivo de bloqueio não terá efeito em outros projetos que dependem dele. Isso só afeta o projeto principal.

Para bibliotecas, concordo com a resposta de Josh Johnson.

Jeroen Fiege
fonte
Por que tratar os projetos no trabalho de maneira diferente das "bibliotecas"?
Josh Johnson
4
Talvez o uso da palavra "colegas de trabalho" tenha sido confuso aqui, eu mudei para colaboradores. A principal diferença é "projeto principal" x biblioteca, em que um projeto principal consiste em uma ou mais bibliotecas e código para integrá-las. Ao executar o compositor a partir do projeto principal, ele não usa o arquivo composer.lock de uma biblioteca e, portanto, instala suas dependências na versão mais recente. Eu acho que isso deve ser semelhante ao testar sua biblioteca.
Jeroen Fiege
2
Confirmar o arquivo de bloqueio com uma biblioteca é provavelmente uma coisa boa - os arquivos de arquivo de bloqueio documentam quais versões de dependências foram instaladas quando o conjunto de teste foi executado. Isso é particularmente importante em uma equipe e, especialmente, em ambientes de integração contínua.
mindplay.dk
Conflitos não triviais podem surgir ao se reintegrar nas ramificações do tronco 2 em que ambos têm novos pacotes instalados por meio do compositor. Aconteceu agora :)
g4b0
2
@tonix, posso responder com alguma autoridade! A razão pela qual não comprometo o composer.lock para minhas bibliotecas é que meu IC cria mestre todas as noites, não importa o quê. Ele garante que, se alguma das dependências da biblioteca tiver problemas de atualização que um usuário da biblioteca teria, o IC falhará. Works good!
Theodore R. Smith
86

Depois de fazer as duas coisas em alguns projetos, minha posição é que composer.locknão deve ser comprometida como parte do projeto.

composer.locké criar metadados que não fazem parte do projeto. O estado das dependências deve ser controlado através de como você as está versionando (manualmente ou como parte do seu processo de compilação automatizado) e não arbitrariamente pelo último desenvolvedor para atualizá-las e confirmar o arquivo de bloqueio.

Se você está preocupado com a alteração de suas dependências entre as atualizações do compositor, não há confiança no seu esquema de versão. As versões (1.0, 1.1, 1.2, etc.) devem ser imutáveis ​​e você deve evitar curingas "dev-" e "X. *" fora do desenvolvimento inicial de recursos.

A confirmação do arquivo de bloqueio é uma regressão para o seu sistema de gerenciamento de dependências, já que a versão da dependência voltou a ser definida implicitamente.

Além disso, seu projeto nunca deve ser reconstruído ou ter suas dependências readquiridas em cada ambiente, especialmente prod. Seu produto (tar, zip, phar, um diretório etc.) deve ser imutável e promovido por ambientes sem alterações.

Josh Johnson
fonte
19
Acordado. Eu sinto que faz mais sentido especificar versões de dependência nas composer.jsonquais as versões necessárias são declaradas mais explicitamente. Mas se você não definir versões específicas, é melhor confirmar composer.lock. É confuso se as versões especificadas em composer.jsonforem diferentes daquelas instaladas conforme a composer.lock. Também depende do aplicativo (versão interna ou geral) e seu ciclo de desenvolvimento. Obviamente, os documentos do compositor dizem , em negrito, "Confirme o composer.lock do seu aplicativo (junto com o composer.json) no controle de versão" . Escolha sabiamente =)
Quinn Comendant
10
Depois de muita pesquisa, decidi, neste ponto, que os documentos do compositor estão errados :) Eu tenho uma regra que não adiciono material gerado ao VCS; Eu permito que o processo de compilação lide com isso.
Josh Johnson
10
O código criado com os seus pressionadores de tecla biomecânicos não é "material gerado"? Não tenho certeza se esse é um critério sólido para basear uma política. =)
Comendador de Quinn 21/03
5
@borfast Eu sei que estou um pouco atrasado para conversar, então você já deve ter visto isso a essa altura, mas pode especificar um hash no composer.json. Na requireseção, você pode colocar: "repo": "dev-master#2633721877cae79ad461f3ca06f3f77fb4fce02e". Isso 1) irá para a ramificação, 2) fará o checkout desse hash, 3) se o hash não for encontrado na ramificação, no entanto, fará o checkout do cabeçalho da ramificação especificada (neste caso, mestre).
CEPA
5
@CEPA - Isso é estranho. Eu esperava que falhasse se o hash não fosse encontrado. Parece perigoso.
Nathan JB
31
  1. Você não deve atualizar suas dependências diretamente na produção.
  2. Você deve controlar a versão do seu arquivo composer.lock .
  3. Você não deve controlar a versão de suas dependências reais.

1. Você não deve atualizar suas dependências diretamente no Production , porque não sabe como isso afetará a estabilidade do seu código. Pode haver erros introduzidos com as novas dependências, isso pode mudar a maneira como o código se comporta, afetando as suas próprias, pode ser incompatível com outras dependências, etc. .

2. Você deve controlar a versão do seu arquivo composer.lock , porque isso armazena informações sobre suas dependências e sobre as dependências de suas dependências que permitirão replicar o estado atual do código. Isso é importante porque todos os seus testes e desenvolvimento foram feitos com base em códigos específicos. Não se importar com a versão real do código que você possui é semelhante ao upload de alterações de código no seu aplicativo e não testá-las. Se você estiver atualizando as versões de suas dependências, isso deve ser um ato voluntário e você deve tomar os cuidados necessários para garantir que tudo ainda funcione. Perder uma ou duas horas de funcionamento revertendo para uma versão anterior pode custar muito dinheiro.

Um dos argumentos que você verá sobre a ausência do compositor.lock é que você pode definir a versão exata necessária no seu arquivo composer.json e, dessa forma, toda vez que alguém executar composer install, os instalará da mesma forma. código. Isso não é verdade, porque suas dependências têm suas próprias dependências e sua configuração pode ser especificada em um formato que permita atualizações para subversões, ou talvez até versões inteiras.

Isso significa que, mesmo quando você especifica que deseja o Laravel 4.1.31 no seu composer.json , o Laravel no seu composer.json arquivo pode ter suas próprias dependências necessárias como Symfony event-dispatcher: 2. *. Com esse tipo de configuração, você pode terminar com o Laravel 4.1.31 com o Symfony event-dispatcher 2.4.1, e outra pessoa em sua equipe pode ter o Laravel 4.1.31 com o event-dispatcher 2.6.5, tudo depende de quando foi a última vez que você executou a instalação do compositor.

Portanto, ter seu arquivo composer.lock no sistema de versões armazenará a versão exata dessas subdependências; portanto, quando você e seu colega de equipe instalam um compositor (é dessa maneira que você instalará suas dependências com base em um compositor. bloqueio ), vocês dois terão as mesmas versões.

E se você quiser atualizar? Então, no seu ambiente de desenvolvimento composer update, execute:, isso gerará um novo arquivo composer.lock (se houver algo novo) e depois de testá-lo, e o teste de QA e regressão testarão tudo isso. Você pode pressioná-lo para que todos os outros façam o download do novo compositer.lock , pois é seguro atualizá-lo.

3. Você não deve controlar a versão de suas dependências reais , porque não faz sentido. Com o compositer.lock, você pode instalar a versão exata das dependências e não precisá-las. Por que você adicionaria ao seu repositório 10000 arquivos de dependências, quando não deveria estar atualizando-os. Se você precisar alterar uma delas, faça uma bifurcação e faça as alterações nela. E se você estiver preocupado com a necessidade de buscar as dependências reais cada vez que uma compilação ou versão, o compositor tem maneiras diferentes de aliviar esse problema, cache, arquivos zip, etc.

Lebobbi
fonte
1
Obrigado, acho que esta resposta explica por que você deve fazer a versão composer.lock e, se não, quais são as consequências e se você pode conviver com elas.
José Lozano Hernandez
8

Em seguida, você confirma o composer.jsonprojeto e todos os outros membros da equipe podem executar a instalação do compositor para instalar as dependências do projeto.

O objetivo do arquivo de bloqueio é registrar as versões exatas que estão instaladas para que possam ser reinstaladas. Isso significa que, se você possui uma especificação de versão 1. * e seu colega de trabalho executa a atualização do compositor que instala a 1.2.4 e, em seguida, confirma o arquivo composer.lock, quando você instala o compositor, você também obtém a versão 1.2.4, se 1.3.0 foi lançado. Isso garante que todos os que trabalham no projeto tenham a mesma versão exata.

Isso significa que, se alguma coisa foi confirmada desde a última vez em que a instalação do compositor foi concluída, sem um arquivo de bloqueio, você receberá um novo código de terceiros .

Novamente, isso é um problema se você estiver preocupado com a quebra de código. E é uma das razões pelas quais é importante pensar no Composer como centrado no arquivo composer.lock.

Fonte: Compositor: É tudo sobre o arquivo de bloqueio .


Confirme o composer.lock do seu aplicativo (junto com o composer.json) no controle de versão. Isso é importante porque o comando install verifica se um arquivo de bloqueio está presente e, se estiver, ele baixa as versões especificadas nele (independentemente do que o compositer.json diz). Isso significa que qualquer pessoa que configure o projeto baixará exatamente a mesma versão das dependências. Seu servidor de IC, máquinas de produção, outros desenvolvedores da sua equipe, tudo e todos são executados nas mesmas dependências, o que reduz o potencial de erros que afetam apenas algumas partes das implantações. Mesmo se você se desenvolver sozinho, em seis meses ao reinstalar o projeto, você poderá se sentir confiante de que as dependências instaladas ainda estão funcionando, mesmo que suas dependências tenham lançado muitas novas versões desde então.

Fonte: Compositor - Uso Básico .

waanders
fonte
1

Se você estiver preocupado com a quebra do código, confirme composer.lockcom o sistema de controle de versão para garantir que todos os colaboradores do seu projeto estejam usando a mesma versão do código. Sem um arquivo de bloqueio, você receberá um novo código de terceiros a cada vez.

A exceção é quando você usa um meta aplicativos, bibliotecas em que as dependências devem ser atualizadas na instalação (como o Zend Framework 2 Skeleton App ). Portanto, o objetivo é obter as dependências mais recentes sempre que você desejar iniciar o desenvolvimento.

Fonte: Compositor: É tudo sobre o arquivo de bloqueio

Consulte também: Quais são as diferenças entre a atualização e a instalação do compositor?

kenorb
fonte
1

Não há resposta exata para isso.

De um modo geral, o compositor não deve estar fazendo o que o sistema de compilação deve fazer e você não deve colocar o compositor.lock no VCS. O compositor pode estranhamente tê-lo ao contrário. Os usuários finais, em vez de produzir, não devem usar arquivos de bloqueio. Normalmente, seu sistema de compilação mantém instantâneos, diretórios reutilizáveis ​​etc., em vez de um diretório vazio a cada vez. As pessoas que fazem check-out de uma lib do compositor podem querer que a lib use um bloqueio, para que as dependências carregadas pela lib tenham sido testadas.

Por outro lado, isso aumenta significativamente a carga do gerenciamento de versões, onde você quase certamente desejaria várias versões de cada biblioteca, pois as dependências serão estritamente bloqueadas. Se é provável que todas as bibliotecas possuam uma versão ligeiramente diferente, você precisa de algum suporte para várias bibliotecas e também pode ver rapidamente o tamanho das dependências necessárias, daí o conselho para mantê-la na folha.

Levando isso em consideração, eu realmente não acho que os arquivos de bloqueio sejam úteis, seja em bibliotecas ou em suas próprias equipes de trabalho. Seu único uso é na minha plataforma de construção / teste, que persiste todos os ativos adquiridos externamente, apenas atualizando-os quando solicitados, fornecendo construções repetíveis para teste, construção e implantação. Enquanto isso pode ser mantido no VCS, nem sempre é mantido com a árvore de origem, as árvores de construção estarão em outro lugar na estrutura do VCS ou gerenciadas por outro sistema em outro lugar. Se ele é armazenado em um VCS, é discutível mantê-lo no mesmo repositório que as árvores de origem, caso contrário, cada puxão pode trazer uma massa de ativos de construção. Eu gosto bastante de ter tudo em um repositório bem organizado, com exceção das credenciais de produção / sensíveis e inchaço.

O SVN pode fazer isso melhor do que o git, pois não força você a adquirir o repositório inteiro (embora eu suspeite que isso também não seja estritamente necessário para o git, mas o suporte a ele é limitado e geralmente não é usado). Os repositórios de construção simples geralmente são apenas uma ramificação de sobreposição na qual você mescla / exporta a árvore de construção. Algumas pessoas combinam recursos externos em sua árvore de origem ou separam outras árvores externas, de construção e de origem. Geralmente, ele serve a dois propósitos, criar cache e compilações repetíveis, mas, às vezes, mantê-la separada em pelo menos algum nível também permite compilações novas / em branco e várias compilações facilmente.

Existem várias estratégias para isso e nenhuma delas funciona particularmente bem com a persistência da lista de fontes, a menos que você mantenha uma fonte externa em sua árvore de fontes.

Eles também possuem itens como hashes no arquivo. Como isso ocorre quando duas pessoas atualizam pacotes? Isso por si só deve fazer você pensar que talvez isso seja mal interpretado.

Os argumentos apresentados pelas pessoas para arquivos de bloqueio são casos em que eles adotam uma visão muito específica e restritiva do problema. Deseja construções repetíveis e construções consistentes? Inclua a pasta do fornecedor no VCS. Além disso, você também acelera a busca de ativos e não precisa depender de recursos externos potencialmente danificados durante a compilação. Nenhum dos pipelines de criação e implantação criados exige acesso externo, a menos que seja absolutamente necessário. Se você precisar atualizar um recurso externo, é uma e apenas uma vez. O que o compositor está tentando obter faz sentido para um sistema distribuído, exceto como mencionado anteriormente, não faz sentido, porque acabaria com a dependência da biblioteca para atualizações de bibliotecas com conflitos e atualizações comuns tão lentos quanto o pacote de atualização mais lento.

Além disso, eu atualizo ferozmente. Toda vez que desenvolvo, atualizo e testo tudo. Há uma janela muito pequena para que ocorra o desvio significativo de versões. Realisticamente, também, quando o versionamento semântico é mantido, o que tende a ser para o compositor, você não deve ter tantos problemas de compatibilidade ou quebras.

No compositer.json, você coloca os pacotes necessários e suas versões. Você pode bloquear as versões lá. No entanto, esses pacotes também têm dependências com versões dinâmicas que não serão bloqueadas pelo composer.json (embora eu não entenda por que você também não pode colocá-los lá se você quiser que a versão seja bloqueada), então alguém executando o compositer instala obtém algo diferente sem a trava. Você pode não se importar muito com isso ou pode se importar, depende. Você deveria se importar? Provavelmente, pelo menos um pouco, o suficiente para garantir que você esteja ciente disso em qualquer situação e impacto potencial, mas também pode não ser um problema se você sempre tiver tempo para apenas DRY executar primeiro e corrigir qualquer atualização.

Às vezes, o compositor de aborrecimentos está tentando evitar às vezes simplesmente não existe, e o aborrecimento que os arquivos de bloqueio do compositor podem fazer é significativo. Eles não têm absolutamente o direito de dizer aos usuários o que devem ou não fazer com relação à compilação versus os recursos de origem (se devem unir ou separar no VCS), já que isso não é da conta deles, eles não são o chefe de você ou de mim. "O compositor diz" não é uma autoridade, eles não são seus oficiais superiores nem dão a ninguém qualquer superioridade sobre esse assunto. Só você conhece sua situação real e o que é melhor para isso. No entanto, eles podem recomendar um curso de ação padrão para usuários que não entendem como as coisas funcionam. Nesse caso, convém seguir isso, mas pessoalmente não acho que ' é um substituto real para saber como as coisas funcionam e poder treinar adequadamente suas necessidades. Em última análise, a resposta para essa pergunta é o melhor palpite. As pessoas que fazem o compositor não sabem onde você deve guardá-lo. A única responsabilidade deles é contar o que é e o que faz. Fora isso, você precisa decidir o que é melhor para você.

Manter o arquivo de bloqueio é problemático para a usabilidade, pois o compositor é muito discreto sobre se ele usa bloqueio ou JSON e nem sempre é bom usar os dois juntos. Se você executar o install, ele usará apenas o arquivo de bloqueio que apareceria; se você adicionar algo ao composer.json, ele não será instalado porque não está no seu bloqueio. Não é intuitivo o que as operações realmente fazem e o que estão fazendo em relação ao arquivo json / lock e às vezes nem parecem fazer sentido (a ajuda diz que a instalação leva o nome de um pacote, mas ao tentar usá-lo, diz não )

Para atualizar o bloqueio ou basicamente aplicar alterações no json, você precisa usar o update e talvez não queira atualizar tudo. O bloqueio tem precedência para escolher o que deve ser instalado. Se houver um arquivo de bloqueio, é o que é usado. Você pode restringir a atualização um pouco, mas o sistema ainda está uma bagunça.

A atualização leva uma idade, shows de RAM. Eu também suspeito que, se você pegar um projeto que não foi tocado por um tempo, ele parecia a partir das versões anteriores, o que ocorrerá mais com o tempo e provavelmente não fará isso com eficiência, o que o estrangula.

Eles são muito sorrateiros quando se trata de ter comandos compostos secretos que você não poderia esperar ser composto. Por padrão, o comando de remoção do compositor aparece nos mapas para atualização do compositor e remoção do compositor, por exemplo.

A pergunta que você realmente precisa fazer não é se você deve manter o bloqueio em sua árvore de origem ou, alternativamente, se você deve persistir em algum lugar de alguma maneira ou não, mas sim se deve perguntar o que realmente faz, então você pode decidir por si mesmo quando você precisa persistir e onde.

Vou salientar que ter a capacidade de ter o bloqueio é uma grande conveniência quando você tem uma estratégia robusta de persistência de dependência externa, pois mantém o controle das informações úteis para rastrear essas (as origens) e atualizá-las, mas se você não tiver então não está aqui nem ali. Não é útil quando forçado na garganta como uma opção obrigatória para poluir suas árvores de origem. É uma coisa muito comum de se encontrar nas bases de código herdadas, onde as pessoas fizeram muitas alterações no compositer.json que realmente não foram aplicadas e estão quebradas quando as pessoas tentam usar o compositor. Sem compositer.lock, sem problema de dessincronização.

jgmjgm
fonte
0

Sim, obviamente.

Isso ocorre porque um compositor instalado localmente dará preferência ao arquivo composer.lock em vez de composer.json.

Se o arquivo de bloqueio não estiver disponível no vcs, o compositor apontará para o arquivo composer.json para instalar as dependências ou versões mais recentes.

O arquivo composer.lock mantém a dependência em maior profundidade, ou seja, aponta para o commit real da versão do pacote que incluímos em nosso software, portanto, este é um dos arquivos mais importantes que lida com a dependência de maneira mais precisa.

Dinesh Suthar
fonte