CDKプロジェクト初期化を一発で！ for Windows

# 簡略化の動機
CDK(python)で新たなプロジェクトディレクトリを作成する際に以下のコマンドが必要
`mkdir`→`cd`→`cdk init app --language python`
→`.venv\Scripts\activate.bat`→`pip install -r requirements.txt`
このように複数のコマンドを一つずつ実行するのは面倒なので、簡単にしたい。
  ~~コマンド5つなので、大して面倒ではない~~

# スクリプト
早速ですが、作成したbatです。

```bat:newcdkpj.bat
@echo off
setlocal enabledelayedexpansion

:: Check if the first argument is a language
@echo off
setlocal enabledelayedexpansion

:: Check if the first argument is a language
set "IS_LANGUAGE=0"
for %%i in (python typescript ts py) do (
    if /i "%~1"=="%%i" set "IS_LANGUAGE=1"
)

:: Get directory name
if "%~1"=="" (
    set /p "DIR_NAME=Directory name: "
) else if %IS_LANGUAGE%==1 (
    if "%~2"=="" (
        set /p "DIR_NAME=Directory name: "
    ) else (
        set "DIR_NAME=%~2"
    )
) else (
    set "DIR_NAME=%~1"
)

:: Check if directory already exists
if exist "%DIR_NAME%\" (
    echo Directory '%DIR_NAME%' already exists.
    exit /b 1
)

:: Get language
if "%~2"=="" (
    if %IS_LANGUAGE%==1 (
        set "LANGUAGE=%~1"
    ) else (
        :language_prompt
        set /p "LANGUAGE=Language (ts/py): "
    )
) else (
    if %IS_LANGUAGE%==1 (
        set "LANGUAGE=%~1"
    ) else (
        set "LANGUAGE=%~2"
    )
)

:: Convert language abbreviations to full names
if /i "%LANGUAGE%"=="py" set "LANGUAGE=python"
if /i "%LANGUAGE%"=="ts" set "LANGUAGE=typescript"

:: Check if language is supported
set "SUPPORTED=0"
for %%i in (python typescript) do (
    if /i "%LANGUAGE%"=="%%i" set "SUPPORTED=1"
)
if %SUPPORTED%==0 (
    echo Language '%LANGUAGE%' is not supported.
    echo Supported languages: python, typescript
    goto language_prompt
)

:: Create directory and move into it
mkdir "%DIR_NAME%"
cd "%DIR_NAME%"

:: Initialize CDK project
call cdk init app --language %LANGUAGE%

:: Language-specific setup
if /i "%LANGUAGE%"=="python" (
    call .venv\Scripts\activate.bat
    pip install -r requirements.txt
    echo Virtual environment activated and dependencies installed.
    echo To deactivate the virtual environment, type 'deactivate'.
    echo To activate it again, run '.venv\Scripts\activate.bat' from this directory.
) else if /i "%LANGUAGE%"=="typescript" (
    call npm install
    echo Dependencies installed.
)

echo CDK project '%DIR_NAME%' created with %LANGUAGE%.
echo Current directory: %CD%

:: Keep the command prompt open in the project directory
if /i "%LANGUAGE%"=="python" (
    echo To start working, the virtual environment is already activated.
) else (
    echo To start working, you are already in the project directory.
)

cmd /k

```

当初は、pythonを使用している自分用でpythonのみで作成していましたが、
CDKで74%ものシェアを誇るTypescript[^1]を無視することが出来ず、
Typescriptにも対応しました。

## 動作環境
このスクリプトは以下の環境で動作確認しています。

OS: Microsoft Windows [Version 10.0.19045.4651]
Node.js: v20.15.1
npm: 10.7.0
Python: 3.12.3
AWS CDK: 2.149.0 (build c8e5924)

動作確認済みターミナル環境
Windows コマンドプロンプト
Visual Studio Code 統合ターミナル（コマンドプロンプト）

## スクリプトの動作

1. カレントディレクトリ直下に指定された名前のフォルダを生成します。

2. 生成したフォルダ内で `cdk init app` コマンドを実行し、
基本的なCDKプロジェクト構造を作成します。

3. プロジェクトに必要な基本的なモジュールとパッケージのインストールをします。
   これは `cdk init app` コマンドで生成された
   依存関係に関するファイルをもとにインストールします。
　- Python の場合: requirements.txt
　- TypeScript の場合: package.json

4. プロジェクト作成とセットアップが完了したことをユーザーに通知します。
　- Python の場合:仮想環境の有効化も完了

改善した階層構造は以下の通りです：

## スクリプトの使用方法と特徴

:::note info
**前提条件**
このバッチファイルを `newcdkpj.bat` として保存し、
ファイルのあるディレクトリをPATHに追加した状態で説明します。
:::

### 基本的な使用方法

使用方法は以下の通りです。
```
newcdkpj <言語> <プロジェクト名>
```

### サポートされている言語

サポートされている言語は以下の通りです。
- Python
- TypeScript

### スクリプトの特徴

#### 1. 引数の柔軟な処理
- 引数の順序を固定せず、言語とフォルダ名のどちらを先に指定しても動作します。
- 言語の指定方法として、略称（py, ts）と完全名（python, typescript）の
両方をサポートしています。

<details><summary>言語指定 該当箇所抜粋</summary>

```batch
set "IS_LANGUAGE=0"
for %%i in (python typescript ts py) do (
    if /i "%~1"=="%%i" set "IS_LANGUAGE=1"
)
```
</details>

#### 2. 引数が不足している場合の動作

**引数が0個の場合**
フォルダ名と言語の入力がそれぞれ促されます。
```
newcdkpj        
Directory name: dir-name
Language (ts/py):  
```

**引数が1個の場合**
言語を入力していればフォルダ名の入力が促されます。
言語の入力でなければ、それをフォルダ名にして言語の入力が促されます。
```
newcdkpj py
Directory name: 
newcdkpj dirname
Language (ts/py): 
```

# まとめ
オーバーエンジニアリングだとは思いますが、
より規模の大きいタスクの自動化への一歩になったと思います。

[^1]:https://matthewbonig.com/posts/community-survey-2023/