はじめに
PyCloneは、my-python-templateを効率的に利用するために私が作成したコマンドラインユーティリティです。このツールを使用すると、プロジェクトのクローン、セットアップ、GitHubへの初期バージョンのコミットを素早く行うことができます。my-python-templateに関するZennの記事はこちらをご覧ください。
セットアップ
PyCloneを使用するためには、まずpyclone
関数をシェルの設定ファイルにコピーする必要があります。Bashユーザーの場合は.bashrc
、ZSHユーザーの場合は.zshrc
となります。
関数の宣言は以下のようになります:
pyclone() {
...
}
環境変数
PyCloneを使用するためには、以下の2つの環境変数を定義する必要があります:
-
PYCLONE_PATH
: この変数には、新しいプロジェクトディレクトリを作成したいディレクトリへのパスを含める必要があります。 -
GITHUB_TOKEN
: ここにはGitHubのアクセストークンを含める必要があります。このトークンはGitHub上に新しいリポジトリを作成する際に使用されます。GitHubのアクセストークンについての詳細は、こちらをクリックしてください。
使用方法
PyCloneは、ターミナルでpyclone
を呼び出すだけで起動できます。PyCloneに自動的に新しいリポジトリをGitHub上に作成し、初期コミットを行うように指示する場合は、-g
オプションを使用できます:
pyclone -g
実行中に、PyCloneは仮想環境の名前を尋ねます。これは新しいプロジェクトのディレクトリ名としても使用されます。ディレクトリがすでに存在する場合、PyCloneはそれを上書きするかどうかを尋ねます。-g
オプションが使用された場合、PyCloneは新しいリポジトリをGitHub上に公開するかどうかも尋ねます。
PyCloneのコード解説
以下に、PyCloneの主要な部分のコードを抜粋し、それぞれが何をしているのかを詳細に説明します。
1. 環境変数のチェック
if [ -z "${PYCLONE_PATH}" ]; then
echo "Error: PYCLONE_PATH is not defined. Please define PYCLONE_PATH."
return 1
fi
clone_path=${PYCLONE_PATH}
clone_git_path=${clone_path}/git/
ここでは、環境変数PYCLONE_PATH
が定義されているかどうかをチェックします。この環境変数は新しいプロジェクトディレクトリを作成する場所を指定するためのものです。定義されていない場合、エラーメッセージが表示され、関数は終了します。これにより、ユーザーは自分の環境に合わせてプロジェクトの保存場所を自由に設定できます。
2. オプションの解析
while getopts "g" opt; do
case $opt in
g)
git_flag=1
;;
\?)
echo "Invalid option: -$OPTARG"
return 1
;;
esac
done
shift $((OPTIND -1))
この部分では、getopts
を使用してコマンドラインオプションを解析します。-g
オプションが指定された場合、git_flag
が1に設定され、後でGitHubに新しいリポジトリを作成するために使用されます。これにより、ユーザーは新しいプロジェクトをローカルだけでなくGitHubにも作成することが可能になります。
3. ディレクトリ名の入力と上書きの確認
echo -n "What is the virtual environment name? [$default_dir_name]: "
read dir_name
dir_name=${dir_name:-$default_dir_name}
if [ -d "${clone_path}/${dir_name}" ] || [ -d "${clone_git_path}/${dir_name}" ]; then
default_overwrite="no"
while : ; do
echo -n "The directory ${dir_name} already exists. Overwrite? (yes/no) [$default_overwrite]: "
read overwrite
overwrite=${overwrite:-$default_overwrite}
if [[ "$overwrite" == "yes" ]] || [[ "$overwrite" == "no" ]]; then
break
else
echo "Please enter either 'yes' or 'no'."
fi
done
if [[ "$overwrite" == "no" ]]; then
echo "Operation cancelled by user."
return 1
fi
fi
ここでは、ユーザーに仮想環境の名前(新しいプロジェクトのディレクトリ名)を入力してもらいます。その後、指定された名前のディレクトリがすでに存在する場合は、それを上書きするかどうかをユーザーに尋ねます。上書きを拒否した場合、関数は終了します。これにより、既存のプロジェクトを誤って上書きすることなく、安全に新しいプロジェクトを作成することができます。
4. リポジトリの公開設定
if [ $git_flag -eq 1 ]; then
while : ; do
echo -n "Do you publish the repository? (yes/no) [$default_publish]: "
read publish
publish=${publish:-$default_publish}
if [[ "$publish" == "yes" ]] || [[ "$publish" == "no" ]]; then
break
else
echo "Please enter either 'yes' or 'no'."
fi
done
fi
この部分は、-g
オプションが指定された場合にのみ実行されます。ユーザーに新しいリポジトリを公開するかどうかを尋ねます。公開する場合はyes
、公開しない場合はno
を入力します。これにより、ユーザーは新しいプロジェクトを公開するかプライベートにするかを自由に選択することができます。
5. リポジトリのクローンと初期設定
git clone https://github.com/C-Naoki/my-python-templete.git $dir_name
cd $dir_name
sed -i "" "s/my-python-templete/$dir_name/g" pyproject.toml
rm -rf .git
make install
git init
echo "# $dir_name" > README.md
この部分では、まずmy-python-templateリポジトリをクローンし、そのディレクトリに移動します。次に、pyproject.toml
ファイル内のプロジェクト名を新しいディレクトリ名に置き換えます。これにより、仮想環境名がmy-python-templateのままになることを防ぎます。その後、.git
ディレクトリを削除し、新しいgitリポジトリを初期化します。最後に、新しいREADME.md
ファイルを作成し、その中に新しいディレクトリ名を書き込みます。これにより、新しいプロジェクトの基本的のセットアップを一気に行うことが可能となっています。
6. PyGithubのインストールチェックとリポジトリ存在チェック
if [ $git_flag -eq 1 ]; then
repo_check_file="repo_check_$$.txt"
python -c "
import pkg_resources
import time
try:
pkg_resources.get_distribution('PyGithub')
except pkg_resources.DistributionNotFound:
import subprocess
subprocess.run(['pip', 'install', 'PyGithub'])
finally:
import os
from github import Github
g = Github(os.getenv('GITHUB_TOKEN'))
username = g.get_user().login
try:
g.get_user().get_repo('$dir_name')
print('The repository $dir_name already exists on GitHub.')
except:
pass
" > $repo_check_file
if grep -q "The repository $dir_name already exists on GitHub." $repo_check_file; then
echo "The repository $dir_name already exists on GitHub."
rm $repo_check_file
return 1
fi
rm $repo_check_file
...
fi
この部分では、まずPythonのパッケージ管理ツールpkg_resources
を使って、PyGithub
がインストールされているかどうかをチェックします。PyGithub
はGitHubのAPIをPythonから利用するためのライブラリで、このスクリプトではGitHubに新しいリポジトリを作成するために使用されます。PyGithub
がインストールされていない場合、スクリプトは自動的にpip install PyGithub
を実行してPyGithub
をインストールします。これにより、ユーザーは手動でライブラリをインストールする手間を省くことができます。
その後、指定された名前のリポジトリがGitHub上にすでに存在するかどうかをチェックします。存在する場合はエラーメッセージが表示され、関数は終了します。これにより、既存のリポジトリを誤って上書きすることなく、安全に新しいリポジトリを作成することができます。また、repo_check_file
の命名にはプロセスIDを含めることで、既存のファイルを上書きすることなく一時ファイルを作成しています。これにより、複数のプロセスが同時に実行される場合でも安全に一時ファイルを扱うことが可能となっています。
7. GitHubリポジトリの作成と初期コミット
if [ $git_flag -eq 1 ]; then
...
username=$(python -c "
import os
import time
from github import Github
g = Github(os.getenv('GITHUB_TOKEN'))
username = g.get_user().login
repo = g.get_user().create_repo('$dir_name', private=('$publish' == 'no'))
while repo.clone_url is None:
time.sleep(0.5)
repo = g.get_repo(f'{username}/{dir_name}')
print(username)")
url="https://github.com/${username}/${dir_name}.git"
git remote add origin $url
git add .
git commit -m ":tada: initial commit"
git push -u origin master
fi
この部分は、-g
オプションが指定された場合にのみ実行されます。まず、新しいGitHubリポジトリを作成し、そのURLを取得します。次に、新しいリポジトリをgitのリモートとして追加し、すべてのファイルをステージングします。その後、初期コミットを作成し、それをGitHubにプッシュします。これにより、新しいプロジェクトがGitHub上にも作成され、初期の状態がコミットされます。これにより、新しいプロジェクトのバージョン管理がすぐに始められます。(シンタックスハイライトがバグっています。修正方法をご存知の方は教えていただきたいです。。。)
まとめ
以上が、PyCloneの紹介とその主要なコードの解説でした。PyCloneは、Pythonプロジェクトのテンプレートであるmy-python-templateを効率的に利用するためのツールです。このツールを使用することで、新しいプロジェクトのクローン、セットアップ、GitHubへの初期バージョンのコミットを素早く行うことができます。
また、コードの解説を通じて、PyCloneがどのように動作しているか、どのような処理を行っているかの詳細な説明も行いました。これにより、ユーザーは自身のニーズに合わせてPyCloneをカスタマイズすることも可能です。
PyCloneは、Pythonプロジェクトの初期設定を効率化するための強力なツールです。これを活用することで、開発者は新しいプロジェクトのセットアップにかかる時間を大幅に削減し、より重要な開発作業に集中することができます。
もし何かバグを見つけたり、あったほうがより便利になる機能があれば、ぜひGitHubのissueに投稿してください。皆様のフィードバックは、このテンプレートをより良いものにするための大切な情報源です。皆様からのご意見、ご感想をお待ちしております。