Composer:
Dependency Manager

Vitor Mattos

Fotografem, comentem, twittem!

@VitorMattosRJ

Quem sou eu?

Realizador de sonhos desde 2003
Amante de opensource
Palestrante
PHP Zend Certified Engineer ( ZEND024235 )
PHPRio ( https://telegram.me/phprio )

CTO Lyseon Tech
Redes sociais: ( VitorMattos ou VitorMattosRJ )

Falaremos sobre...

Só que não

Roteiro

  • Introdução e breve histórico
  • Uso do packagist como consumidor
  • Criação de um pacote (tornando-se um mantenedor)
  • Formas de distribuir este pacote
  • Criação de scripts

Resumindo:

https://getcomposer.org

O que é Composer e para que serve?

Gestão de dependências em projetos PHP inspirado no NPM (node JS) e bundler (Ruby)

 

Isola dependências externas evitando necessidade de versionamento das mesmas (vendor)

O que é Composer e

para que serve?

Gestão de dependências em projetos PHP inspirado no NPM (node JS) e bundler (Ruby)

 

Isola dependências externas evitando necessidade de versionamento das mesmas (vendor)

O que são dependências?

Todo artefato de software seu ou de terceiros cuja finalidade é o reaproveitamento de código.

Voltando: O que é Composer e para que serve?

Declaração de quais são todas as dependências externas e suas versões (composer.json)

Voltando: O que é Composer e para que serve?

Isola dependências externas evitando necessidade de versionamento das mesmas

Voltando: O que é Composer e para que serve?

Possui um agregador de repositórios central

Voltando: O que é Composer e para que serve?

Possibilidade de uso de repositório privado

Voltando: O que é Composer e para que serve?

Responsabilidade única das partes do projeto

O que é Composer e

para que serve?

Você declara somente o que VOCÊ precisa. O composer encontra as bibliotecas declaradas e as instala com todas as suas dependências satisfeitas.

O que é Composer e

para que serve?

Reduz o tamanho dos projetos

O que é Composer e

para que serve?

Reduz esforço

O que é Composer e

para que serve?

Facilita redistribuição de projetos

Um pouco de história

Suporte a namespaces no PHP lançado no PHP 5.3 em 2009

<?php
 namespace TheProject;

Um pouco de história

Surgimento do PHP-FIG em 2009

Um pouco de história

Lançamento da PSR-0 com primeiras definições de autoload

em 2010

Um pouco de história

Criação do Composer em 2012 após o PHP-FIG

Um pouco de história

Adoção do Composer por parte de grandes frameworks e ferramentas

Um pouco de história

Lançamento da PSR-4 com melhorias nas definições de autoload

em 2014

Visão do consumidor: instalação

curl -s https://getcomposer.org/installer | php
sudo apt install composer

Ou...

composer self-update

Visão do consumidor: Atualização do composer

O que é um phar?

Simples:

 

phar = PHP Archive

 

https://php.net/phar

O que é um JSON?

JSON

JSON, um acrônimo para "JavaScript Object Notation", é um formato leve para intercâmbio de dados computacionais. JSON é um subconjunto da notação de objeto de JavaScript, mas seu uso não requer JavaScript exclusivamente. O formato JSON foi originalmente criado por Douglas Crockford e é descrito no RFC 4627. O media-type oficial do JSON é application/json e a extensão é.json.

Mais em Wikipedia (PT)

O que é um JSON?

Resumindo: uma linguagem para formatar dados de forma leve e legível para humanos.

 

Simples e de fácil aprendizado. Permite estruturar e formatar dados em objetos.

Instalando a primeira dependência

Crie um arquivo composer.json e coloque a sua dependência nele:

{
    "require-dev": {
        "vlucas/phpdotenv": "^4.0"
    }
}

Instalando a primeira dependência

Crie um arquivo composer.json e coloque a sua dependência nele:

{
    "require-dev": {
        "vlucas/phpdotenv": "^4.0"
    }
}
composer require <maintainer>/<dependency-name>

Exemplo:

composer require vlucas/phpdotenv

Instalando a primeira dependência

O que acontece após instalar?

Arquivos criados:

composer.json

        Informações diversas sobre seu projeto,
        dependências instaladas, etc

composer.lock

        Todas as versões que foram instalads

vendor

        Todas as dependências instaladas

.gitignore

O que devemos ignorar?

composer.lock

Fixa as versões a serem instaladas garantindo que suas dependências e suas sub-dependências estão exatamente na mesma versão.

 

SEMPRE versione este arquivo!

Usando a primeira dependência

<?php

require_once 'vendor/autoload.php';

if (file_exists('.env')) {
    $dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
    $dotenv->load();
}

echo getenv('TESTE');

require e require-dev

require é para ambiente de produção

{
    "require": {
        "php": ">=7.2.0",
        "cocur/slugify": "^3.2"
    }
}

require e require-dev

require-dev é APENAS para ambiente de produção

{
    "require-dev": {
        "phpunit/phpunit": "^8.4"
    }
}
composer require phpunit/phpunit --dev

Exemplo: phpunit, behat, phpcs, phpcbf, phpmd, phpstan, etc

Instalar ou atualizar?

Instalar sempre, atualizar apenas quando necessitar atualizar a versão das dependências

composer install

Estrutura do composer.json

Mantenedor

{
  "name": "vitormattos/blueprint-sdk-maker",
  "description": "Create SDK client from API Blueprint",
  "license": "MIT",
  "type": "library",
  "homepage": "https://github.com/vitormattos/blueprint-sdk-maker",
  "authors": [
    {
      "name": "Vitor Mattos",
      "homepage": "https://github.com/vitormattos"
    }
  ],
  "support": {
    "source": "https://github.com/vitormattos/blueprint-sdk-maker/tree/master",
    "issues": "https://github.com/vitormattos/blueprint-sdk-maker/issues"
  },
  "keywords": [
    "api",
    "blueprint",
    "parser",
    "apib"
  ],
  "autoload": {
    "psr-4": {
      "BlueprintSdkMaker\\": "src/Sdk"
    }
  }
}
Nome do pacote
Descrição
Licença
Autores
Suporte
Palavras chaves
Tipo

Estrutura do composer.json

Mantenedor

  "autoload": {
    "psr-4": {
      "BlueprintSdkMaker\\": "src/Sdk"
    }
  },
  "require": {
    "php": ">=7",
    "symfony/console": "^3.2",
    "brianseitel/oasis-mson-parser": "dev-newest"
  },
  "require-dev": {
    "nikic/php-parser": "^4.2",
    "ext-tokenizer": "*",
    "squizlabs/php_codesniffer": "3.*",
    "overtrue/phplint": "^1.1",
    "php-coveralls/php-coveralls": "^2.1",
    "phpunit/phpunit": "^8",
    "phpstan/phpstan": "^0.11.16"
  }
Regras de autoload
Namespace
Versão do PHP
Require dev
Requre
Extensões

Estrutura do composer.json

Mantenedor

  "scripts": {
    "phpcs": "phpcs --standard=PSR2 -n src",
    "phpcbf": "phpcbf --standard=PSR2 -n src",
    "unit": "phpunit --coverage-clover ./tests/log/clover.xml --colors=always",
    "phplint": "phplint ./ --exclude=vendor",
    "phpstan": "phpstan analyse src --level 7",
    "test": [
      "@phplint",
      "@unit",
      "@phpcs"
    ]
  },
  "bin": [
    "bin/blueprint-sdk-maker"
  ],
  "repositories": [
    {
      "type": "vcs",
      "url": "https://github.com/vitormattos/oasis-mson-parser"
    }
  ]
Scripts
Binários
Agrupando scripts
Repositórios
Tipo de repositório
  • pre-install-cmd: occurs before the install command is executed with a lock file present.
  • post-install-cmd: occurs after the install command has been executed with a lock file present.
  • pre-update-cmd: occurs before the update command is executed, or before the install command is executed without a lock file present.
  • post-update-cmd: occurs after the update command has been executed, or after the install command has been executed without a lock file present.
  • post-status-cmd: occurs after the status command has been executed.
  • pre-archive-cmd: occurs before the archive command is executed.
  • post-archive-cmd: occurs after the archive command has been executed.
  • pre-autoload-dump: occurs before the autoloader is dumped, either during install/update, or via the dump-autoload command.
  • post-autoload-dump: occurs after the autoloader has been dumped, either during install/update, or via the dump-autoload command.
  • post-root-package-install: occurs after the root package has been installed, during the create-project command.
  • post-create-project-cmd: occurs after the create-project command has been executed.

Scripts

Scripts: exemplo Laravel

  "scripts": {
    "post-root-package-install": [
      "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
    ],
    "post-create-project-cmd": [
      "@php artisan key:generate"
    ],
    "post-autoload-dump": [
      "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
      "@php artisan package:discover"
    ]
  }

Indo para produção

composer install --prefer-dist --no-dev --optimize-autoload

Plugins

hirak/prestissimo

Plugins

Plugins

{
    "extra": {
        "hooks": {
            "pre-commit": [
                "echo committing as $(git config user.name)",
                "php-cs-fixer fix ." // fix style
            ],
            // verify commit message. ex: ABC-123: Fix everything
            "commit-msg": "grep -q '[A-Z]+-[0-9]+.*' $1",
            "pre-push": [
                "php-cs-fixer fix --dry-run ." // check style
                "phpunit"
            ],
            "post-merge": "composer install"
            "...": "..."
        }
    }
}

brainmaestro/composer-git-hooks

Um bom caminho:

Boas práticas

Um bom caminho:

Boas práticas

Vitor Mattos

vitor@LT.coop.br

t.me/VitorMattos