๐Ÿšฅ ์–ด๋–ป๊ฒŒ ์ž‘์—… ํ๋ฆ„์—์„œ ์ฝ”๋“œ ํ’ˆ์งˆ ๊ฒ€์‚ฌ๋ฅผ ์ž๋™์œผ๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๊นŒ?โš™

23969 ๋‹จ์–ด gitbashautomationcleancode

์นดํƒˆ๋กœ๊ทธ


  • How to embed code analysis tools in your workflowโ“
  • ๐Ÿ“ In your editor or IDE
  • ๐ŸŒฑ With git hooks
  • โš™ Automatisation through Composer
  • ๐Ÿš‰ In your CI/CD pipeline
  • โญ To go further
  • ์ด์ „์— ์šฐ๋ฆฌ๋Š” ์ฃผ๋กœ ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ์‚ฌ์šฉ๋˜๋Š” PHP ์ฝ”๋“œ ํ’ˆ์งˆ ๋„๊ตฌ(phpcs, phpmd๊ณผ php-cs-fixer)๋ฅผ ์ฃผ๋ชฉํ–ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์–ป์€ ๊ฒฐ๋ก ์€ ์ด ๋„๊ตฌ๋“ค์ด ์šฐ๋ฆฌ์˜ ์ฝ”๋“œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ํฌํ•จ๋˜์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

    This article is not particularly focused on PHP, but on controlling the quality of your codebase at every stage of your workflow (editing => versioning => building). Thus, it can be helpful for any kind of project (front or back, Go or JS, ...). You just have to find the right tools for your language.

    For the most impatient of you, I created a template project on gitlab.com to allow you to quickly bootstrap a PHP project with ready-to-use quality tools.


    ์–ด๋–ป๊ฒŒ ์ž‘์—… ํ๋ฆ„์— ์ฝ”๋“œ ๋ถ„์„ ๋„๊ตฌ๋ฅผ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๊นŒโ“

    Using the CLI to manually check your code is cool (really? ๐Ÿค”), but not very productive. Let's automatize โš™ that a bit!

    ๐Ÿ“ ํŽธ์ง‘๊ธฐ ๋˜๋Š” IDE์—์„œ

    Personally, I use Atom๊ณผ Neovim.๋‘˜ ๋‹ค ๋งŽ์€ ๊ณ ํ’ˆ์งˆ ๋„๊ตฌ์— ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.๊ทธ๋Ÿฌ๋‚˜ ๋ชจ๋“  ๊ธฐ์กด ํŽธ์ง‘๊ธฐ(Emacs, Sublimitext, VSCode...)๋ฐ IDE(Intellij, PhpStorm...)์ด ๋ชฉ์ ์„ ์œ„ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
    ๐Ÿ’ก Atom์— ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ค์น˜:
    apm install linter-phpmd \
                linter-phpcs \
                linter-php \
                php-cs-fixer
    
    Installing linter-phpmd to /home/boris/.atom/packages โœ“
    Installing linter-phpcs to /home/boris/.atom/packages โœ“
    Installing linter-php to /home/boris/.atom/packages โœ“
    Installing php-cs-fixer to /home/boris/.atom/packages โœ“
    
    ๊ทธ๋Ÿฐ ๋‹ค์Œ ๊ด€๋ จ ๋„๊ตฌ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๋„๋ก ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๊ตฌ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: linter-phpcs).โžœ ./vendor/bin/phpcs ).
    Composer(composer global require xx/xx)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ „ ์„ธ๊ณ„์— ์„ค์น˜ํ–ˆ๋‹ค๋ฉด ~/.config/composer/vendor/bin์„ $PATH์— ๋„ฃ์œผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.Atom์—์„œ ๊ตฌ์„ฑํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
    ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ PHPC(phpcs.xml.dist), phpmd(phpmd.xml.dist), phpcsfixer(.php_cs.dist)์˜ ํ‘œ์ค€ ํŒŒ์ผ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ทœ์น™ ์ง‘ํ•ฉ์„ ์ •์˜ํ•˜๋ฉด Atom์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ์— ์˜ํ•ด ์ž๋™์œผ๋กœ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค.
    Atom์˜ ๋ชจ์–‘์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

    ์ด ์„ธ ๊ฐ€์ง€ ๋„๊ตฌ(phpcs, phpmd ๋ฐ php-cs-fixer)๋ฅผ ์กฐํ•ฉํ•˜์—ฌ ํ˜„์žฌ ํŒŒ์ผ์— ๋Œ€ํ•œ ์‹ค์‹œ๊ฐ„ ์ง„๋‹จ์„ ์‹ค์‹œํ•˜๊ณ , ์˜จ๋ผ์ธ์œผ๋กœ ๊ฒ€์ถœ๋œ ์œ„๋ฐ˜ ํ–‰์œ„๋ฅผ ๊ฐ•์กฐ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ค๋ฅ˜๋Š” ๋ฐ‘์ค„์„ ๊ธ‹๊ณ , ๋งˆ์šฐ์Šค๊ฐ€ ๋ฉˆ์ถ”๋ฉด ๋„๊ตฌ ์•Œ๋ฆผ์ด ๋‚˜ํƒ€๋‚˜๋ฉฐ, ๊ด€๋ จ ์ค„์˜ ์—ฌ๋ฐฑ์— ๋„ํ‘œ๊ฐ€ ํ‘œ์‹œ๋จ). php-cs-fixer์€ ์ €์žฅํ•  ๋•Œ ์ž๋™์œผ๋กœ ์˜ค๋ฅ˜๋ฅผ ๋ณต๊ตฌํ•ฉ๋‹ˆ๋‹ค.
    nvim์—์„œ๋„ ํ˜„์žฌ ํŒŒ์ผ ์•„๋ž˜์˜ ์ „์šฉ ๋ฒ„ํผ์— ์˜ค๋ฅ˜๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ํŒŒ์ผ ์ž์ฒด์— ์ƒํ•˜๋ฌธ ์ •๋ณด๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

    ๋งŒ์•ฝvim/neovim์˜ ๊ฐœ๋ฐœ ์ฒดํ—˜์„ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด ๊ธฐ์กด์˜ ํ•ด๊ฒฐ ๋ฐฉ์•ˆ์„ ์ฐพ๊ณ  ์žˆ๋‹ค๋ฉด ์ด ์ข‹์€ ํ•ด๊ฒฐ ๋ฐฉ์•ˆ์„ ๋ณด์‹ญ์‹œ์˜ค๐Ÿš€ ํ•ญ๋ชฉ:

    SpaceVim ํšŒ์‚ฌ / SpaceVim ํšŒ์‚ฌ


    ์ง€์—ญ์‚ฌํšŒ ๊ตฌ๋™์˜ ๋ชจ๋“ˆํ™”vim ๋ถ„ํฌ - ์ตœ์ข…vim ์„ค์ •



    Wiki |
    Community |
    Sponsors |
    |
    Gitter Chat |
    ไธญๆ–‡ๅฎ˜็ฝ‘







    SpaceVim์€ ์ง€์—ญ ์‚ฌํšŒ๊ฐ€ ๊ตฌ๋™ํ•˜๋Š” ๋ชจ๋“ˆํ™”๋œ Vim ๋ถ„๋ฐฐ์ด๋‹ค.๋ชจ์Œ ๊ด€๋ฆฌ
    ํ”Œ๋Ÿฌ๊ทธ์ธ์˜ ๊ณ„์ธตํ™”. ์ด๋Š” ๊ด€๋ จ ํŒจํ‚ค์ง€๋ฅผ ํ•œ๋ฐ ๋ชจ์•„ IDE์™€ ์œ ์‚ฌํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋œ๋‹ค.
    ๋งˆ์ง€๋ง‰ ๋ฒ„์ „์€ v1.6.0์ž…๋‹ˆ๋‹ค. following-HEAD ํŽ˜์ด์ง€๋ฅผ ๋ณด๊ณ  ์ง€๋‚œ๋ฒˆ ๋ฐœํ‘œ ์ดํ›„ ๋ฐœ์ƒํ•œ ์ผ์„ ์•Œ์•„๋ณด์‹ญ์‹œ์˜ค.
    ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

  • Quick Start Guide: ์ดˆ๋ณด์ž์˜ ๊ฐ„๋‹จํ•œ ์•ˆ๋‚ด์„œ.

  • Documentation: SpaceVim ์‚ฌ์šฉ์— ๋Œ€ํ•œ ์ „์ฒด ๋ฌธ์„œ

  • Available Layers: SpaceVim์— ํฌํ•จ๋œ ๋ชจ๋“  ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ ˆ์ด์–ด์˜ ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค.
  • SpaceVim ์ง€์›


    ์ด ํ”„๋กœ์ ํŠธ์˜ ์กด์žฌ์— ๊ฐ์‚ฌ ๋ชจ๋“  contributed
    ์šฐ๋ฆฌ๋Š” ์ง€์—ญ ์‚ฌํšŒ์˜ ์–ด๋–ค ๊ณตํ—Œ์—๋„ ๊ฐ์‚ฌํ•œ๋‹ค.

    SpaceVim์„ ์ง€์›ํ•˜๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ์˜ค๋ฅ˜๋ฅผ ๋ณด๊ณ ํ•˜์—ฌ ํž˜์„ ๊ธฐ์—ฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
    Gitter Chat์—์„œ ์ง€์—ญ ์‚ฌํšŒ๋ฅผ ๋•๊ฑฐ๋‚˜pull ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
    ์ž์„ธํ•œ ๋‚ด์šฉ์€ development guidelines์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.
    SpaceVim์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ...
    View on GitHub

    ๐ŸŒฑ git ์—ฐ๊ฒฐ

    Check the code in the editor is good, but do it before pushing to git is better!

    Git comes with a set of hooks that you can use at many steps of the workflow (pre-commit, pre-push, post-update...). A git hook is just a script that will be executed before or after a particular event. It can be a shell script, a PHP script, a perl script, a python script or whatever scripting language. It can even be a binary. It just needs to be an executable.

    Here is the list of all available hooks:


    ์šฐ๋ฆฌ๋Š” pre-commit๊ฐˆ๊ณ ๋ฆฌ๋ฅผ ์ฃผ๋ชฉํ•  ๊ฒƒ์ด๋‹ค.
    ์šฐ๋ฆฌ์˜ ์ƒ๊ฐ์€ pre-commit ๊ฐˆ๊ณ ๋ฆฌ์˜ ํ’ˆ์งˆ ๋„๊ตฌ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ๊ท€ํ•˜๊ฐ€ ํ”„๋กœ์ ํŠธ์— ์ •์˜ํ•œ ํ‘œ์ค€์— ๋ถ€ํ•ฉ๋˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.๋”ฐ๋ผ์„œ ์˜ค๋ฅ˜ ์ฝ”๋“œ๋ฅผ ์ œ์ถœํ•˜์ง€ ์•Š๋„๋ก ํ•˜์‹ญ์‹œ์˜ค.
    โš ๏ธ pre-commit ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํŽธ์ง‘ํ•˜๊ธฐ ์ „์— ์•Œ์•„์•ผ ํ•  ๊ฒƒ์€ ์ผ๋ถ€ ๋„๊ตฌ๊ฐ€ ์˜ค๋ฅ˜ ์ฝ”๋“œ๋ฅผ ๋˜๋Œ๋ ค์ฃผ๋ฉด ์ œ์ถœ ๊ณผ์ •์„ ์ค‘๋‹จํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.์ด๊ฒƒ์ด ๋ฐ”๋กœ ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
    ๐Ÿ“œ ๋‹ค์Œ์€ ๊ฐœ์ธ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๊ทœ์น™์ž…๋‹ˆ๋‹ค.
  • pre-commit ๊ฐˆ๊ณ ๋ฆฌ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ œ์ถœํ•œ ํŒŒ์ผ๋งŒ ๊ฒ€์‚ฌํ•˜๊ณ  ๋ณต๊ตฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.์ „์ฒด ์ฝ”๋“œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ฒ€์‚ฌ/๋ณต๊ตฌํ•ด์•ผ ํ•œ๋‹ค๋ฉด, ํ•ฉ๋ณ‘ ์ง€์˜ฅ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ํŒ€์— ์ˆ˜๋™์œผ๋กœ ์‹คํ–‰ํ•˜๊ณ  ํ†ต์ง€ํ•˜์‹ญ์‹œ์˜ค.
  • ๊ฐˆ๊ณ ๋ฆฌ๋กœ ์ˆ˜์ •๋œ ํŒŒ์ผ์€git ์ธ๋ฑ์Šค์— ์ž๋™์œผ๋กœ ๋‹ค์‹œ ์ถ”๊ฐ€ํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค.์ด๊ฒƒ์€ ๋ฐ˜๋“œ์‹œ ์‚ฌ์šฉ์ž๊ฐ€ ์™„์„ฑํ•ด์„œ ๊ทธ๊ฐ€ ์ง„์ •์œผ๋กœ ์ œ์ถœํ•œ ๋‚ด์šฉ์„ ํ†ต์ œํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์•ผ ํ•œ๋‹ค.
  • ๋จผ์ € .git/hooks/pre-commit.sample์—์„œ .git/hooks/pre-commit์˜ ํŒŒ์ผ ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    ๊ทธ๋ฆฌ๊ณ git ์ธ๋ฑ์Šค์— ์ถ”๊ฐ€๋œ ํŒŒ์ผ ๋ชฉ๋ก์„ ๊ฒ€์ƒ‰ํ•˜๊ณ  ํ•„์š”ํ•œ ํŒŒ์ผ ํ™•์žฅ์ž (.php,.go,.py...) ๋ฅผ ํ•„ํ„ฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    #!/bin/bash
    
    STAGED_FILES_CMD=`git diff --cached --name-only --diff-filter=ACMR HEAD | grep \\\\.php`
    
    ์—ฌ๊ธฐ์—์„œ ๋‚˜๋Š” ๋ชจ๋“  ์ปดํ“จํ„ฐ์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์ด์‹ ๊ฐ€๋Šฅํ•œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊ฐ€์ง€๊ธฐ ์œ„ํ•ด bash์„ ์‚ฌ์šฉํ•œ๋‹ค.๊ทธ๋Ÿฌ๋‚˜ ๋ชจ๋“  ์Šคํฌ๋ฆฝํŠธ ์–ธ์–ด๋Š” ๋ฐ›์•„๋“ค์ผ ์ˆ˜ ์žˆ๋‹ค.
    ์ด์ œ ๊ฐ ํ’ˆ์งˆ ๋„๊ตฌ์— ์ž„์‹œ ์ €์žฅ ํŒŒ์ผ ๋ชฉ๋ก์„ ์ œ๊ณตํ•˜์—ฌ ์•„๋ž˜์— ํ˜ธ์ถœ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ 1๋กœ ์ข…๋ฃŒํ•˜์—ฌ ์ œ์ถœ์„ ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค.
    #!/bin/bash
    
    echo "Running pre-commit hook"
    
    PROJECT=`php -r "echo dirname(dirname(dirname(realpath('$0'))));"`
    STAGED_FILES_CMD=`git diff --cached --name-only --diff-filter=ACMR HEAD | grep \\\\.php`
    
    echo "Checking PHP Lint..."
    for FILE in $STAGED_FILES_CMD
    do
        php -l -d display_errors=0 $PROJECT/$FILE
        if [ $? != 0 ]
        then
            echo "Fix the error before(s) commit."
            exit 1
        fi
        FILES="$FILES $PROJECT/$FILE"
    done
    
    echo "Running PHP Code Beautifier and Fixer (phpcbf)..."
    phpcbf --standard=phpcs.xml.dist $STAGED_FILES_CMD --colors --report=summary
    if [ $? != 0 ]
    then
        echo "Fix the error before(s) commit."
        exit 1
    fi
    
    echo "Running PHP-CS-FIXER..."
    
    PHP_CS_STATUS=0
    
    for FILE in $STAGED_FILES_CMD
    do
        php-cs-fixer fix $FILE
        PHP_CS_STATUS=$(( $PHP_CS_STATUS + $? ))
    done
    
    if [ $PHP_CS_STATUS != 0 ]
    then
        echo "Fix the error(s) before commit."
    fi
    
    echo "End of pre-commit hook"
    
    exit $PHP_CS_STATUS
    
    ์—ฌ๊ธฐ์—์„œ ๋‚˜๋Š” phpcs๊ณผ phpmd์„ ์‹คํ–‰ํ•˜์ง€ ์•Š๋Š”๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๊ทธ๊ฒƒ๋“ค์€ ๊ณ ๋„์˜ ๋งž์ถคํ˜•์ด ์žˆ์–ด์•ผ๋งŒ git ๊ฐˆ๊ณ ๋ฆฌ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋Œ€๋Ÿ‰์˜ ์˜ค๋ฅ˜/๊ฒฝ๊ณ ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  ์ œ์ถœ์„ ๋ง‰์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.๋„ˆ์™€ ๋„ˆ์˜ ๋™๋ฃŒ๊ฐ€ ์ค€๋น„๊ฐ€ ๋‹ค ๋˜์—ˆ์„ ๋•Œ๋งŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.๋งŒ์•ฝ ๋„ค๊ฐ€ ๋„ˆ๋ฌด ์ผ์ฐ ํ•œ๋‹ค๋ฉด, ๋„ˆ์™€ ๋„ˆ์˜ ํŒ€์„ ๋‚™๋‹ด์‹œํ‚ฌ ์ˆ˜๋„ ์žˆ๋‹ค.
    ๋งŒ์•ฝ ๋„ค๊ฐ€ ์ค€๋น„๊ฐ€ ๋œ๋‹ค๋ฉด, ์ด phpmd file์€ ์ข‹์€ ์‹œ์ž‘์ด ๋  ๊ฒƒ์ด๋‹ค.
    ๋‚˜๋Š” ๋˜ํ•œ PHP linter(php -l)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‚˜์˜ ๋ชจ๋“  PHP ํŒŒ์ผ์ด ๋ฌธ๋ฒ•์ ์œผ๋กœ ์ •ํ™•ํ•˜๋‹ค๋Š” ๊ฒƒ์„ ํ™•๋ณดํ•œ๋‹ค.phpunit์— ๋Œ€ํ•œ ํ˜ธ์ถœ๋„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ œ์ถœ์ด ๋นจ๋ผ์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ช‡ ์ดˆ ์ด์ƒ ์ง€์†๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
    git ๊ฐˆ๊ณ ๋ฆฌ์˜ ํ•œ๊ณ„๋Š” ๋‹จ์ง€ ๋„ˆ์˜ ์ƒ์ƒ ์ค‘์˜ ํ•˜๋‚˜์ผ ๋ฟ์ด๋‹ค.๋‚˜๋Š” ๊ทธ๊ฒƒ์œผ๋กœ ๋‚˜์˜ ๋งŽ์€ ํ”„๋กœ์ ํŠธ ํŒŒ์ผ์„ lintํ•œ๋‹ค: JSON, XML, swagger ์ŠคํŽ™, ๋งˆํฌ๋‹ค์šด, ์…ธ ์Šคํฌ๋ฆฝํŠธ...

  • swagger-cli:lint ๋‹น์‹ ์˜ ํ”๋“ค๋ฆผ ํŒŒ์ผ!
  • ์ž‘๊ณก๊ฐ€ ๊ฒ€์ฆ:lint ๋‹น์‹ ์˜ ์ž‘๊ณก๊ฐ€.json!

  • dockerlint: lint ๋‹น์‹ ์˜ Dockerfile!

  • shellcheck:lint ๋‹น์‹ ์˜ ์…ธ ์Šคํฌ๋ฆฝํŠธ!
  • ๋งŒ์•ฝ ๋‹น์‹ ์˜ ํŒŒ์ผ์— ๋Œ€๋“ค๋ณด๊ฐ€ ์—†๋‹ค๋ฉด, ๋‹น์‹ ์˜ ๋Œ€๋“ค๋ณด๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”!์˜ˆ๋ฅผ ๋“ค์–ด, ๋‚˜๋Š” i18n ์ž์› ํŒŒ์ผ์ด ๋ชจ๋“  ์–ธ์–ด์—์„œ ๋™์งˆ์ธ์ง€ ํ™•์ธํ•˜๋Š” ๊ฐ„๋‹จํ•œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.
    ๋งˆ์ง€๋ง‰์œผ๋กœgit ์ธ๋ฑ์Šค์— ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์ œ์ถœํ•ด์„œ ๊ฐˆ๊ณ ๋ฆฌ๋ฅผ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.pre-commit ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ž๋™์œผ๋กœ ํ„ฐ์น˜๋ฉ๋‹ˆ๋‹ค.์—†์œผ๋ฉด ์‹คํ–‰ ์œ„์น˜๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด
    chmod +x .git/hooks/pre-commit
    

    โš™ Composer๋ฅผ ํ†ตํ•œ ์ž๋™ํ™”

    In , I introduced three tools and how to automatize their installation within Composer. This way, each developer can install them just by running composer install at the project's root.

    But how to ensure that each of them will use them each time they modify a single line of code? Fortunately, Composer comes also with a set of hooks allowing you to automatize some of your tasks.

    Thus, instead of manually creating a pre-commit script for every developers, the idea is to put the script somewhere in your codebase (e.g. in /contrib ), and to ask Composer to install it automatically when installing or updating your project.

    Just add a new section in your composer.json :

    {
        "scripts": {
            "post-update-cmd": [
                "mv .git/hooks/pre-commit .git/hooks/pre-commit.bak",
                "cp contrib/pre-commit .git/hooks/pre-commit",
                "chmod a+x .git/hooks/pre-commit"
            ],
            "post-install-cmd": [
                "mv .git/hooks/pre-commit .git/hooks/pre-commit.bak",
                "cp contrib/pre-commit .git/hooks/pre-commit",
                "chmod a+x .git/hooks/pre-commit"
            ]
        }
    }
    

    That way, anytime a dev will be running composer install or composer update , the script will be installed.

    ๐Ÿš‰ CI/CD ํŒŒ์ดํ•‘์—์„œ

    The goal of the quality control in the CI/CD pipeline is twofold:

    • first check the whole codebase against your project's quality rules, and break the build in case of any error (like a unit test would do)
    • (optionnally) perform a deeper analysis and publish a detailed build report that can be consulted by the devs at any time

    Of course, it doesn't make sense to use a fixer ( phpcbf , php-cs-fixer ) in the pipeline as it would modify the code after it has been pulled from the repo, and we don't want the code to be modified without any control of the devs.

    โš  Checking your whole codebase will have a significant impact on the build time. It can vary from few seconds to few minutes, depending on your code size.
    For your information, on a 40 000 LoC project, it takes approximately 5 seconds for phpcs and 40 seconds for phpmd , with a relatively ยซlightยป analysis.

    Regarding the deeper analysis, we'll use phpcs and phpmd to raise errors/warnings and to publish the results, either in ยซhuman-readableยป reports for devs (e.g. on a static website) with a notification in Slack, or in a standard format ( junit , checkstyle , other...) to be integrated in a statistics tool like Sonar or PhpMetrics .

    Here is a simple example of a gitlab-ci's pipeline allowing to build, test & check a PHP app and to publish the reports to gitlab pages:

    image: composer
    
    stages:
      - test
      - deploy
    
    test:app:
      stage: test
      script:
        - apk add --no-cache $PHPIZE_DEPS
        - pecl install xdebug-2.6.0
        - docker-php-ext-enable xdebug
        - composer install
        - ./vendor/bin/phpunit --testsuite=unit --coverage-text --colors=never --log-junit reports/phpunit-junit.log --testdox-html reports/phpunit-report.html
        - ./vendor/bin/phpcs -sw --standard=phpcs_squiz.xml.dist src --basepath=. --report=full --report-file=reports/phpcs-report.log || echo "ok"
        - ./vendor/bin/phpmd src html phpmd.xml.dist --reportfile reports/phpmd-report.html --ignore-violations-on-exit
      artifacts:
        paths:
          - reports
        expire_in: 30m
    
    pages:
      stage: deploy
      dependencies:
        - test:app
      script:
        - mkdir public
        - cp ci/pages/index.html public/
        - cp reports/* public/
      artifacts:
        paths:
          - public
      only:
        - master
    
    You can find all you need to bootstrap a PHP project with quality tools and git+gitlab integration on my template project .
    ์ฐธ๊ณ ๋กœ ํ”„๋กœ์ ํŠธ์— Gitlab Pages์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ํŒŒ์ดํ”„์— pages์ด๋ผ๋Š” ์ž‘์—…์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค./public์— ์ž…๋ ฅํ•œ ๋ชจ๋“  ๋‚ด์šฉ์€ ๋‹ค์Œ URL์„ ํ†ตํ•ด ํ”„๋กœ์ ํŠธ ์ •์  ์‚ฌ์ดํŠธ์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: https://<group-or-username>.pages.forge.orange-labs.fr/<project-name>.Gitlab Pages์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•œ ์ด์ƒ API ๋ฌธ์„œ (PHPDoc, JavaDoc ๋˜๋Š” ๊ธฐํƒ€), ์ฝ”๋“œ ๋ฎ์–ด์“ฐ๊ธฐ๊ฐ€ ์žˆ๋Š” ํ…Œ์ŠคํŠธ ๋ณด๊ณ ์„œ, Swagger ๋ฌธ์„œ๋ฅผ ํ˜ธ์ŠคํŒ…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    โญ ์ง„์ผ๋ณดํ•˜๋‹ค

    There are many frameworks to manage the git hooks. Some of them are language specific (Node.js, PHP, Go, ...), and some others are language agnostic. They support many types of stacks. Just pick yours!

    If you're interested in this topic, you can have a look at the Python pre-commit ์ด๊ฒƒ์€ ๋งค์šฐ ๊ฐ•๋ ฅํ•˜๋‹ค.๊ทธ๋Ÿฌ๋‚˜ ๊ฐ„๋‹จํ•œ ํ”„๋กœํ•„์„ ํ†ตํ•ด ๋ฏธ๋ฆฌ ์ œ์ถœํ•œ ๋‹จ๊ณ„๋ฅผ ์ผ๋ จ์˜ ์—ฐ๊ฒฐ๋กœ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ณผ ๋งŒํ•˜๋‹ค.์ž์‹ ์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ž‘์„ฑํ•ด์„œ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
    PHP์˜ ๊ฒฝ์šฐ DigitalPulp plugins์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.
    ๐ŸŒŸ ๋งŒ์•ฝ ๋‹น์‹ ์ด ํ•„์š”ํ•˜๋‹ค๋ฉด, ๋‚˜๋Š” ๊ธฐ๊บผ์ด ๋‹น์‹ ์—๊ฒŒ ๋” ๋งŽ์€ ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ ๋ง์„ค์ด์ง€ ๋งˆ์„ธ์š”!

    ์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ