Source: Infranology Blog

Infranology Blog Composer: gerencie as dependências de seu projeto como um maestro

Quando o Symfony2 foi lançado, escrevi um post onde dizia que o framework estava liderando a inovação no mundo PHP. Foi exatamente assim que iniciei a minha palestra no PHP Conference Brasil no final do ano passado e não &eacute; apenas uma questão de entusiasmo. A comunidade Symfony tem criado novas e interessantes bibliotecas e ferramentas e isso tem tido um impacto consider&aacute;vel na formação de um ecossistema na comunidade PHP. E uma dessas ferramentas, apesar de ainda muito recente, resolve um dos grandes problemas existentes em projetos PHP: o gerenciamento das dependências.O Composer &eacute; esta ferramenta. Trata-se de um gerenciador de pacotes para bibliotecas PHP, disponível como utilit&aacute;rio de linha de comando.Guia r&aacute;pido de 1 minutoTalvez você se questione e/ou sofre antes do tempo: "Mais uma ferramenta para aprender? Não tenho paciência para isso!". Mas calma, aprender o b&aacute;sico de como usar o Composer não demora 1 minuto. E você ver&aacute; que vale a pena!Você precisa do PHP 5.3.0 para executar o Composer.O Composer &eacute; distribuído como um arquivo Phar. Digamos que você esteja interessado em criar um webscrapper usando algumas bibliotecas PHP 5.3: Buzz, Symfony DomCrawler e Symfony CssSelector. Vamos instalar o Composer em nosso diret&oacute;rio de projeto:Crie o arquivo composer.json com o seguinte conteúdo:Execute o utilit&aacute;rio Composer:Ap&oacute;s o download das dependências, você pode começar a usar as classes das bibliotecas no seu projeto. O Composer gera um autoloader automaticamente, basta incluir o mesmo no seu c&oacute;digo:Agora você tem todas as dependências para fazer o seu webscrapping em PHP:De onde veio o c&oacute;digo?Você deve estar se perguntando de onde veio o c&oacute;digo. O Composer &eacute; apenas um utilit&aacute;rio que faz o download de um pacote atrav&eacute;s de um reposit&oacute;rio de pacotes chamado Packagist. Desenvolvedores submetem o endereço do reposit&oacute;rio público de suas bibliotecas para o Packagist que então monitora o reposit&oacute;rio e cria novos pacotes quando uma nova tag &eacute; criada no mesmo.Todas as informações ficam disponíveis na web atrav&eacute;s do site Packagist. Cada biblioteca de nosso webscrapper tem uma p&aacute;gina no Packagist (veja: Buzz, Symfony CssSelector e Symfony DomCrawler) com informações úteis como autor, licença, link para o reposit&oacute;rio público, versões disponíveis, dependências, entre outras. Essas informações são extraídas do arquivo composer.json.Para publicar um pacote Composer no Packagist, &eacute; necess&aacute;rio criar um arquivo composer.json no diret&oacute;rio raiz do projeto. Esse arquivo precisa conter, al&eacute;m de quaisquer dependências, informações úteis como as j&aacute; citadas anteriormente. Consulte a documentação do Packagist para mais informações caso esteja interessado em disponibilizar algum c&oacute;digo de sua autoria como pacote Composer.É possível visualizar essas informações atrav&eacute;s do Composer, com o comando show:Note o atributo "psr-0" nas informações do pacote Symfony Locale. Isso significa que o pacote tem conformidade com o padrão PSR-0. O Composer adiciona automaticamente pacotes PSR-0 no autoloader.Você tamb&eacute;m pode pesquisar pelos pacotes disponíveis no Packagist atrav&eacute;s do Composer com o comando search:Como incorporar pacotes não disponíveis no PackagistO Packagist, assim como o Composer, &eacute; muito recente e com isso talvez uma biblioteca desejada por você não esteja publicada como um pacote Packagist. Mas isso não &eacute; um problema: você pode adicionar reposit&oacute;rios de pacotes adicionais no seu arquivo composer.json, uma referência para o reposit&oacute;rio da biblioteca desejada ou at&eacute; mesmo uma referência para um pacote PEAR!Um reposit&oacute;rio de pacote &eacute; um reposit&oacute;rio Composer. O Packagist &eacute; um reposit&oacute;rio Composer e você pode usar o c&oacute;digo-fonte do mesmo (est&aacute; disponível no GitHub) para subir o seu pr&oacute;prio reposit&oacute;rio Composer. Um reposit&oacute;rio Composer pode ser configurado da seguinte forma no composer.json:Você não precisa, no entanto, manter um site como o Packagist para distribuir seus pacotes. Caso o reposit&oacute;rio de sua biblioteca seja o Git, você pode adicion&aacute;-lo como reposit&oacute;rio de pacote (para isso deve existir um arquivo composer.json no diret&oacute;rio raiz do pacote):Ok, mas e se você não tiver acesso ao reposit&oacute;rio para criar o composer.json? Não tem problema, você pode especificar a informação do pacote diretamente no composer.json de seu projeto:Note especificamos aqui duas fontes para o pacote: dist e source. Por padrão, a fonte dist sempre &eacute; usada. source &eacute; usada quando você usa a opção --dev junto com o comando install ou update do composer.phar. Caso especifique os dois, tenha certeza que ambas as fontes possuem a mesma versão do c&oacute;digo, evitando assim surpresas causadas por c&oacute;digo diferente entre as fontes (quebra da API, correções de bug, entre outras).Por último e não menos importante, &eacute; possível tamb&eacute;m usar pacotes PEAR:E se a biblioteca ao qual você depende não estiver em conformidade com o PSR-0 (ex: bibliotecas PHP 5.2 seguindo as conversões de nomeação PEAR)? Como alternativa você pode usar o componente Symfony ClassLoader e criar você mesmo o arquivo de autoloading. Adicione no seu composer.json:Crie um arquivo autoload.php na raiz do seu projeto com o seguinte c&oacute;digo:Não &eacute; tão &aacute;gil quanto usar o autoloader gerado pelo Composer mas ainda assim &eacute; muito simples de configurar.Legal! Mas qual era o problema mesmo?O problema ao qual o Composer se propõe a resolver &eacute; o de reuso de c&oacute;digo. Ao tornar a incorporação de dependências um processo mais simples, os autores de bibliotecas ganham agilidade e praticidade para reusar c&oacute;digo de outras bibliotecas ao inv&eacute;s de reinventar a roda. Desenvolvedores clientes (que usam as referidas bibliotecas) tamb&eacute;m ganham com a praticidade j&aacute; que fica f&aacute;cil explicitar as dependências de um projeto no arquivo composer.json, que &eacute; muito mais simples do que configurar atributos de VCS como o SVN externals e Git submodules.E comparado com o PEAR, o Composer tem uma filosofia bastante diferente: o Composer gerencia pacotes no diret&oacute;rio do projeto enquanto o PEAR gerencia pacotes no nível do sistema (semelhante ao aptitude, yum, entre outros). O problema de lidar com dependências dessa forma &eacute; quando você tem muitos projetos executando em uma m&aacute;quina com os diferentes projetos dependendo de diferentes versões de uma mesma biblioteca. Não h&aacute; uma forma f&aacute;cil de instalar as diferentes versões das dependências e caso não haja um procedimento de empacotamento dessas dependências com o build (se houver) do projeto, fica f&aacute;cil esquecer a instalação de uma dependência.Como as dependências em um projeto usando o Composer ficam explícitas, existe tamb&eacute;m o benefício de visualiz&aacute;-las mais rapidamente. Você nem mesmo precisa versionar as bibliotecas instaladas pelo Composer no diret&oacute;rio vendor/ (o que reduz o tamanho total do reposit&oacute;rio de seu projeto): qualquer pessoa que fizer uma c&oacute;pia do reposit&oacute;rio do projeto e executar o comando composer.phar update ir&aacute; fazer o download das dependências como especificado nos arquivos composer.json ou composer.lock. Dessa forma se evita surpresas como algum outro desenvolvedor ter problemas porque instalou uma dependência em uma versão diferente, seja mais nova ou mais velha, com diferenças no comportamento na API ou bugs.Quanto a especificação de versão de uma dependência, eu tenho a tendência de ser conservador, preferindo especificar uma dependência exata para ter previsibilidade na implantação do c&oacute;digo nos ambientes de produção/stagging/testing. Se você usar uma dependência usando um operador de desigualdade (>, >=, <, <=), o Composer ir&aacute; escolher a maior versão disponível (se for ">X.Y.Z", por exemplo, você poder&aacute; pegar uma versão baseada na &aacute;rvore principal de desenvolvimento, com c&oacute;digo inst&aacute;vel - claro, dependendo de como o projeto organiza seu reposit&oacute;rio).Isso &eacute; potencialmente mais perigoso quando não se versiona o diret&oacute;rio com o c&oacute;digo-fonte das dependências (vendor/ nesse caso) j&aacute; que seu processo de implantação ir&aacute; requerer a geração de um pacote (build) com a execução do comando composer.phar install. Procure basear a sua especificação de dependência levando em conta a maturidade do processo de desenvolvimento do pacote que ir&aacute; adotar (os componentes do Symfony, por exemplo, possuem o compromisso de não quebrar a compatibilidade de API em m&eacute;todos públicos marcados com a tag @api, sendo mais seguros para definir com um operador de desigualdade), seja mais específico caso não encontrar compromissos com compatibilidade de API ou um processo de release previsível.ConclusõesO Composer, como bem definiu Henri Bergius, resolve o problema do compartilhamento de c&oacute;digo no mundo PHP. O utilit&aacute;rio &eacute; simples e, somente no Packagist, temos 227 pacotes disponíveis. É um número bastante expressivo j&aacute; que todos os pacotes são PHP 5.3+, para uma referência, o PEAR (1 e 2) cont&eacute;m ao todo 592 pacotes sendo 192 PHP 5+.Diante desses números, &eacute; evidente que o Composer j&aacute; causou seu impacto na comunidade PHP. Est&aacute; promovendo reuso de c&oacute;digo e est&aacute; tornando simples o que outrora era um processo falho (instalação no nível do sistema via PEAR) ou desajeitado (SVN externals, Git submodules). A ferramenta, como j&aacute; frisada, &eacute; nova e ainda tem um longo caminho para melhorias como adicionar suporte para autoloading de c&oacute;digo não PSR-0 (como

Read full article »
Est. Annual Revenue
$100K-5.0M
Est. Employees
1-25
CEO Avatar

CEO

Update CEO

CEO Approval Rating

- -/100