Spark 명령 만들기

컨트롤러를 CLI에서 다른 라우트처럼 사용할 수 있는 기능은 편리하지만, 때로는 조금 다른 방식이 필요할 수 있습니다. 이때 Spark 명령이 유용합니다. Spark 명령은 라우트를 정의할 필요가 없는 단순한 클래스이므로, 마이그레이션 처리나 데이터베이스 시딩, cron 작업 상태 확인, 회사용 커스텀 코드 생성기 제작 같은 개발 작업을 더 쉽게 만들어 주는 도구를 만들기에 적합합니다.

새 명령 만들기

개발에 사용할 새 명령은 아주 쉽게 만들 수 있습니다. 각 클래스는 반드시 별도 파일에 있어야 하며, CodeIgniter\CLI\BaseCommand 를 확장하고 run() 메서드를 구현해야 합니다.

CLI 명령 목록에 표시되고 도움말 기능을 추가하려면 다음 속성들을 사용해야 합니다:

  • $group: 명령 목록에서 이 명령이 속한 그룹을 설명하는 문자열입니다. 예: Database

  • $name: 명령 이름을 설명하는 문자열입니다. 예: make:controller

  • $description: 명령을 설명하는 문자열입니다. 예: Generates a new controller file.

  • $usage: 명령 사용법을 설명하는 문자열입니다. 예: make:controller <name> [options]

  • $arguments: 각 명령 인자를 설명하는 문자열 배열입니다. 예: 'name' => 'The controller class name.'

  • $options: 각 명령 옵션을 설명하는 문자열 배열입니다. 예: '--force' => 'Force overwrite existing file.'

도움말 설명은 위 매개변수를 기준으로 자동 생성됩니다.

파일 위치

명령은 Commands 라는 이름의 디렉터리에 저장해야 합니다. 다만 Autoloader 가 찾을 수 있도록 그 디렉터리는 PSR-4 네임스페이스 안에 있어야 합니다. 예를 들어 app/Commands 이거나, 프로젝트 전반에서 사용할 명령을 모아두는 Acme/Commands 같은 디렉터리가 될 수 있습니다.

참고

명령이 실행되면 CodeIgniter CLI 환경 전체가 로드되므로, 환경 정보와 경로 정보를 얻고 컨트롤러를 만들 때 사용하는 것과 같은 도구들을 사용할 수 있습니다.

예제 명령

데모용으로 애플리케이션 자체에 대한 기본 정보를 보고하는 기능만 가진 예제 명령을 살펴보겠습니다. 먼저 app/Commands/AppInfo.php 에 새 파일을 만들고 다음 코드를 넣습니다:

<?php

namespace App\Commands;

use CodeIgniter\CLI\BaseCommand;
use CodeIgniter\CLI\CLI;

class AppInfo extends BaseCommand
{
    protected $group       = 'Demo';
    protected $name        = 'app:info';
    protected $description = 'Displays basic application information.';

    public function run(array $params)
    {
        // ...
    }
}

list 명령을 실행하면 새 명령이 자체 Demo 그룹 아래에 표시됩니다. 자세히 보면 동작 방식을 쉽게 이해할 수 있습니다. $group 속성은 이 명령을 다른 명령들과 어떻게 묶어 표시할지, 어떤 제목 아래에 나열할지를 알려 줍니다.

$name 속성은 이 명령을 호출할 때 사용하는 이름입니다. 공백을 포함해서는 안 되며, 모든 문자는 명령줄에서 유효해야 합니다. 관례적으로는 명령을 소문자로 작성하고, 명령 이름에 콜론을 사용해 세부 그룹을 나눕니다. 이렇게 하면 여러 명령의 이름 충돌을 줄일 수 있습니다.

마지막 속성 $descriptionlist 명령에 표시되는 짧은 문자열로, 이 명령이 무엇을 하는지 설명해야 합니다.

run()

run() 메서드는 명령이 실행될 때 호출되는 메서드입니다. $params 배열은 명령 이름 뒤에 오는 CLI 인자 목록입니다. CLI 문자열이 다음과 같다면:

php spark foo bar baz

그렇다면 foo 가 명령 이름이고, $params 배열은 다음과 같습니다:

<?php

$params = ['bar', 'baz'];

이 값은 CLI 라이브러리를 통해서도 접근할 수 있지만, 그 경우에는 이미 명령 이름이 문자열에서 제거되어 있습니다. 이 매개변수들은 스크립트 동작을 사용자 정의하는 데 사용할 수 있습니다.

데모 명령의 run() 메서드는 대략 다음과 같을 수 있습니다:

<?php

namespace App\Commands;

use CodeIgniter\CLI\BaseCommand;
use CodeIgniter\CLI\CLI;

class AppInfo extends BaseCommand
{
    // ...

    public function run(array $params)
    {
        CLI::write('PHP Version: ' . CLI::color(PHP_VERSION, 'yellow'));
        CLI::write('CI Version: ' . CLI::color(\CodeIgniter\CodeIgniter::CI_VERSION, 'yellow'));
        CLI::write('APPPATH: ' . CLI::color(APPPATH, 'yellow'));
        CLI::write('SYSTEMPATH: ' . CLI::color(SYSTEMPATH, 'yellow'));
        CLI::write('ROOTPATH: ' . CLI::color(ROOTPATH, 'yellow'));
        CLI::write('Included files: ' . CLI::color(count(get_included_files()), 'yellow'));
    }
}

자세한 내용은 CLI Library 페이지를 참고하세요.

명령 종료

기본적으로 명령은 성공 코드 0 으로 종료됩니다. 명령을 실행하는 동안 오류가 발생하면 run() 메서드에서 종료 코드를 포함한 return 구문으로 명령을 종료할 수 있습니다.

예를 들면 return EXIT_ERROR;

이 방식은 예를 들어 명령이 crontab을 통해 실행될 때 시스템 수준의 디버깅에 도움이 됩니다.

app/Config/Constants.php 파일에 정의된 EXIT_* 종료 코드 상수를 사용할 수 있습니다.

BaseCommand

모든 명령이 확장해야 하는 BaseCommand 클래스에는 직접 명령을 만들 때 알아두면 좋은 유틸리티 메서드가 몇 가지 있습니다. 또한 $this->logger 에서 사용할 수 있는 Logger 도 있습니다.

class CodeIgniter\CLI\BaseCommand
call(string $command[, array $params = []])
매개변수:
  • $command (string) – 호출할 다른 명령의 이름입니다.

  • $params (array) – 해당 명령에서 사용할 수 있도록 추가 CLI 인자를 전달합니다.

이 메서드는 현재 명령을 실행하는 동안 다른 명령을 실행할 수 있게 해줍니다:

<?php

$this->call('command_one');
$this->call('command_two', $params);
showError(Throwable $e)
매개변수:
  • $e (Throwable) – 오류 보고에 사용할 예외입니다.

CLI에 일관되고 명확한 오류 출력을 유지하기 위한 편의 메서드입니다:

<?php

try {
    // ...
} catch (\Exception $e) {
    $this->showError($e);
}
showHelp()

명령 도움말을 표시하는 메서드입니다: (usage,arguments,description,options)

setPad(string $item, int $max, int $extra = 2, int $indent = 0) string
매개변수:
  • $item (string) – 문자열 항목입니다.

  • $max (integer) – 최대 크기입니다.

  • $extra (integer) – 끝에 추가할 공백 수입니다.

  • $indent (integer) – 들여쓰기 공백 수입니다.

문자열을 패딩하여 모든 제목 길이를 같게 만들고, 설명이 보기 좋게 맞춰지도록 합니다:

use CodeIgniter\CLI\CLI;

$length = max(array_map('strlen', array_keys($this->options)));

foreach ($this->options as $option => $description) {
    CLI::write(CLI::color($this->setPad($option, $length, 2, 2), 'green') . $description);
}
/*
 * Output will be:
 *  -n     Set migration namespace
 *  -g     Set database group
 *  --all  Set for all namespaces, will ignore (-n) option
 */
getPad($array, $pad)

버전 4.0.5부터 폐지됨: 대신 CodeIgniter\CLI\BaseCommand::setPad() 를 사용하세요.

매개변수:
  • $array (array) – $key => $value 배열입니다.

  • $pad (integer) – 패딩 공백입니다.

$key => $value 배열 출력의 패딩을 계산하는 메서드입니다. 이 패딩은 CLI에서 보기 좋게 정렬된 표를 출력하는 데 사용할 수 있습니다.