コマンドの作成
Aceコマンドを使用するだけでなく、アプリケーションのコードベースの一部としてカスタムコマンドを作成することもできます。コマンドはcommands
ディレクトリ(ルートレベル)に格納されます。次のコマンドを実行してコマンドを作成できます。
参考:makeコマンド
node ace make:command greet
上記のコマンドはcommands
ディレクトリ内にgreet.ts
ファイルを作成します。Aceコマンドはクラスで表され、コマンドの指示を実行するためにrun
メソッドを実装する必要があります。
コマンドのメタデータ
コマンドのメタデータには、コマンド名、説明、ヘルプテキスト、およびコマンドの動作を設定するオプションが含まれます。
import { BaseCommand } from '@adonisjs/core/ace'
import { CommandOptions } from '@adonisjs/core/types/ace'
export default class GreetCommand extends BaseCommand {
static commandName = 'greet'
static description = 'ユーザーを名前で挨拶する'
static options: CommandOptions = {
startApp: false,
allowUnknownFlags: false,
staysAlive: false,
}
}
- commandName
-
commandName
プロパティはコマンド名を定義するために使用されます。コマンド名にはスペースを含めることはできません。また、コマンド名に*
、&
、またはスラッシュなどの不慣れな特殊文字を使用しないことをオススメします。コマンド名はネームスペースの下に配置することもできます。たとえば、
make
ネームスペースの下にコマンドを定義するには、make:
を接頭辞として付けることができます。 - description
-
コマンドの説明はコマンドリストとコマンドのヘルプ画面に表示されます。説明は短く保ち、より長い説明にはヘルプテキストを使用してください。
- help
-
ヘルプテキストはより長い説明や使用例を表示するために使用されます。
export default class GreetCommand extends BaseCommand {static help = ['挨拶コマンドはユーザーを名前で挨拶するために使用されます','','ユーザーに花を送ることもできます。更新された住所がある場合は','{{ binaryName }} greet --send-flowers',]}{{ binaryName }}
変数の置換は、aceコマンドを実行するために使用されるバイナリへの参照です。 - aliases
-
aliases
プロパティを使用して、コマンド名に1つ以上のエイリアスを定義できます。export default class GreetCommand extends BaseCommand {static commandName = 'greet'static aliases = ['welcome', 'sayhi']} - options.startApp
-
デフォルトでは、AdonisJSはAceコマンドを実行する際にアプリケーションを起動しません。これにより、コマンドの実行が迅速に行われ、シンプルなタスクにアプリケーションの起動フェーズを経由しないようになります。
ただし、コマンドがアプリケーションの状態に依存する場合は、Aceにコマンドを実行する前にアプリを起動するように指示できます。
import { BaseCommand } from '@adonisjs/core/ace'import { CommandOptions } from '@adonisjs/core/types/ace'export default class GreetCommand extends BaseCommand {static options: CommandOptions = {startApp: true}} - options.allowUnknownFlags
-
デフォルトでは、Aceはコマンドに未知のフラグを渡すとエラーを表示します。ただし、
options.allowUnknownFlags
プロパティを使用して、コマンドレベルで厳密なフラグの解析を無効にできます。import { BaseCommand } from '@adonisjs/core/ace'import { CommandOptions } from '@adonisjs/core/types/ace'export default class GreetCommand extends BaseCommand {static options: CommandOptions = {allowUnknownFlags: true}} - options.staysAlive
-
AdonisJSは、コマンドの
run
メソッドを実行した後にアプリを終了します。ただし、コマンド内で長時間実行されるプロセスを開始する場合は、プロセスを終了しないようにAceに指示する必要があります。参考:アプリの終了およびアプリの終了前のクリーンアップセクション。
import { BaseCommand } from '@adonisjs/core/ace'import { CommandOptions } from '@adonisjs/core/types/ace'export default class GreetCommand extends BaseCommand {static options: CommandOptions = {staysAlive: true}}
コマンドのライフサイクルメソッド
コマンドクラスで以下のライフサイクルメソッドを定義でき、Aceはそれらを事前に定義された順序で実行します。
import { BaseCommand, args, flags } from '@adonisjs/core/ace'
export default class GreetCommand extends BaseCommand {
async prepare() {
console.log('準備中')
}
async interact() {
console.log('対話中')
}
async run() {
console.log('実行中')
}
async completed() {
console.log('完了')
}
}
メソッド | 説明 |
---|---|
prepare
|
これはコマンドで最初に実行されるメソッドです。このメソッドでは、コマンドを実行するために必要な状態やデータを設定できます。 |
interact
|
prepare メソッドの後に実行されるinteract メソッドです。ユーザーにプロンプトを表示するために使用できます。 |
run
|
コマンドのメインロジックはrun メソッドに記述します。このメソッドはinteract メソッドの後に呼び出されます。 |
completed
|
他のライフサイクルメソッドの実行後にcompleted メソッドが呼び出されます。このメソッドはクリーンアップを実行したり、他のメソッドで発生したエラーを処理したりするために使用できます。 |
依存性の注入
AceコマンドはIoCコンテナを使用して構築および実行されます。そのため、コマンドのライフサイクルメソッドに依存関係を型指定し、@inject
デコレータを使用して解決できます。
デモンストレーションのために、すべてのライフサイクルメソッドにUserService
クラスを注入してみましょう。
import { inject } from '@adonisjs/core'
import { BaseCommand } from '@adonisjs/core/ace'
import UserService from '#services/user_service'
export default class GreetCommand extends BaseCommand {
@inject()
async prepare(userService: UserService) {
}
@inject()
async interact(userService: UserService) {
}
@inject()
async run(userService: UserService) {
}
@inject()
async completed(userService: UserService) {
}
}
エラーの処理と終了コード
コマンドで発生した例外はCLIロガーを使用して表示され、コマンドのexitCode
は1
に設定されます(非ゼロのエラーコードはコマンドが失敗したことを意味します)。
ただし、try/catch
ブロックでコードをラップするか、completed
ライフサイクルメソッドを使用してエラーを処理することで、エラーをキャプチャすることもできます。いずれの場合でも、コマンドのexitCode
とerror
プロパティを更新することを忘れないでください。
try/catchでエラーを処理する
import { BaseCommand } from '@adonisjs/core/ace'
export default class GreetCommand extends BaseCommand {
async run() {
try {
await runSomeOperation()
} catch (error) {
this.logger.error(error.message)
this.error = error
this.exitCode = 1
}
}
}
completedメソッド内でエラーを処理する
import { BaseCommand } from '@adonisjs/core/ace'
export default class GreetCommand extends BaseCommand {
async run() {
await runSomeOperation()
}
async completed() {
if (this.error) {
this.logger.error(this.error.message)
/**
* エラーが処理されたことをAceに通知します
*/
return true
}
}
}
アプリの終了
デフォルトでは、Aceはコマンドの実行後にアプリケーションを終了します。ただし、staysAlive
オプションを有効にしている場合は、this.terminate
メソッドを使用して明示的にアプリケーションを終了する必要があります。
たとえば、サーバーメモリを監視するためにRedis接続を作成し、接続が失敗した場合にアプリを終了するとします。
import { BaseCommand } from '@adonisjs/core/ace'
import { CommandOptions } from '@adonisjs/core/types/ace'
export default class GreetCommand extends BaseCommand {
static options: CommandOptions = {
staysAlive: true
}
async run() {
const redis = createRedisConnection()
redis.on('error', (error) => {
this.logger.error(error)
this.terminate()
})
}
}
アプリの終了前のクリーンアップ
アプリケーションの終了は、SIGTERM
シグナルを含む複数のイベントによってトリガーされる場合があります。そのため、コマンド内でterminating
フックをリッスンしてクリーンアップを実行する必要があります。
prepare
ライフサイクルメソッド内でterminating
フックをリッスンできます。
import { BaseCommand } from '@adonisjs/core/ace'
import { CommandOptions } from '@adonisjs/core/types/ace'
export default class GreetCommand extends BaseCommand {
static options: CommandOptions = {
staysAlive: true
}
prepare() {
this.app.terminating(() => {
// クリーンアップを実行する
})
}
async run() {
}
}