人気Pythonプロジェクトのルートにある〇〇ファイル is 何？

# 前置き

*setup.py*とか*requirements.txt*とかPythonプロジェクトでよく見るファイルについてちゃんと理解したいなー、そもそもどんなファイルがあるんだろ？と思っていろいろ調べていました。
とりあえず先人に倣えということで、GitHubで人気のPythonプロジェクトの中身を見ていたところいろんなツールの設定ファイルがあり、へーこんなツールあるんだーふむふむ、他にはどんなツールが使われているんでしょう？と当初の趣旨とは違うところで興味が出てきたわけです。

というわけで**GitHubのPythonプロジェクトでスターが最も多いプロジェクト約700個**を対象にルートにおいてあるファイルをカウントして多く使われているファイルを集計、なんのツールが使っているファイルなのか調べてみました。

# ルール

* [GitHubのPythonトピック](https://github.com/topics/python?l=python&o=desc&s=stars)から"Most Starts"でソート、このページで取れるだけ全部のリポジトリを検索。総数は**689**。
* よく使われてそうなファイルについて記載、わからないものは簡単に調べた結果を記載
* 以下のファイルは除外
  * git関係ファイル
      * *.gitignore*、*.gitattributes* など
  * ドキュメント系
      * *README.md*、*CONTRIBUTING.md* など
  * あんまり使われている数が少ないもの
  * そのほかプロジェクト固有のものなど
* 表記ゆれのあるものは合計してカウント
  * *codecov.yml* と *.codecov.yml* など
* 検索したすべての結果は[Gist](https://gist.github.com/enven-omiomi/7e685e3f3e2cd4aa4a029077cd469590#file-items-json)に置いといたので興味があればどうぞ。
* 説明の間違い、捕捉、このファイルが足りないなどご指摘歓迎

# Pythonプロジェクトでよく見る系
## setup.py

◆ 使用プロジェクト数: 503
◆ 使用ツール: [setuptools](https://github.com/pypa/setuptools)


Pythonプロジェクトをライブラリとしてビルド、配布、インストールする際のすべての挙動を記述する。
*setup.py*が配置されているディレクトリがPythonプロジェクトと認識されるので、*setup.py*が配置されているローカルディレクトリ、ローカルのzipファイル、Gitリポジトリなどを指定して`pip install`できるようになる。

```
pip install path/prj/dir
pip install path/dir/file.zip
pip install git+https://github.com/{user-name}/{repo-name}
```

pipはsetup.pyの記述にしたがってパッケージをインストールする。


プロジェクトをライブラリとしてパッケージングする場合には`python setup.py sdist`もしくは`python setup.py bdist_wheel`を指定して実行する.

```
# ソースコード配布物を作成する場合
python setup.py sdist

# ビルド済み配布物を作成する場合 wheelが必要
pip install wheel
python setup.py bdist_wheel
```

参考: [Building and Distributing Packages with Setuptools](https://setuptools.readthedocs.io/en/latest/setuptools.html)

## MANIFEST.in

◆ 使用プロジェクト数: 402
◆ 使用ツール: [setuptools](https://github.com/pypa/setuptools)

ソースコード以外のファイルを配布物に含める場合はこのファイルに記述する
`Setup()`の引数（もしくは*setup.cfg*?）に`include_package_data=True`と記載するとこのファイルを処理する

`package_data`パラメータを指定するとより詳細な条件でファイルを指定できる

参考: https://setuptools.readthedocs.io/en/latest/setuptools.html#including-data-files

## setup.cfg

◆ 使用プロジェクト数: 344
◆ 使用ツール: [setuptools](https://github.com/pypa/setuptools)

プロジェクトをパッケージングする際には*setup.py*の`setup()`関数の引数に諸々書く必要があった。しかし
書きにくい、*setuptools*以外のツールが解釈しづらい、などの問題があった。そこで一連の設定はまとめて別ファイルにかけるように*setup.cfg*が作られた。

これにより`setup()`に引数を書く必要はなくなった。（ただし古いビルドツールを使用する場合は引数の記載が必要）

参考

* [Configuring setup() using setup.cfg files](https://setuptools.readthedocs.io/en/latest/setuptools.html#configuring-setup-using-setup-cfg-files)
* [PEP 517 -- A build-system independent format for source trees](https://www.python.org/dev/peps/pep-0517/)
* [PEP 518 -- Specifying Minimum Build System Requirements for Python Projects](https://www.python.org/dev/peps/pep-0518/)

## requirements.txt

◆ 使用プロジェクト数: 261
◆ 使用ツール: [pip](https://github.com/pypa/pip)

*setup.py*および*setup.cfg*で依存するパッケージのバージョン指定は行えない。そこで依存パッケージのバージョンを記載したファイルが*requirements.txt*。
ただしファイル名は任意なので別の名前でも問題ない。  

コマンドライン上で`pip freeze`と打つとコマンドラインに依存情報が出力される。`pip freeze > requirements.txt`とすればそのままファイルに出力される。virtualenv(venv)環境に入っていればvirtualenv内のパッケージが出力される。
freezeで出力されるパッケージには*pip*、*setuptools*、*wheel*といったパッケージ管理のためのパッケージは含まれない。

```requirements.txtの例
appdirs==1.4.3
astroid==2.3.3
botocore==1.15.6

略
```

依存関係をインストールする場合は以下のような感じ

```
pip install -r requirements.txt
```

書き方: https://pip.pypa.io/en/latest/reference/pip_install/#example-requirements-file

使用ツールは主にpipだが、Pipenvでも*requirements.txt*からのパッケージのインストール、逆に*Pipfile*から*requirements.txt*の生成など行える。Poetryはできないっぽい？


## pyproject.toml

◆ 使用プロジェクト数: 102
◆ 使用ツール: [Poetry](https://github.com/python-poetry/poetry), [flit](https://github.com/takluyver/flit), [setuptools](https://github.com/pypa/setuptools), [Pyflow](https://github.com/David-OConnor/pyflow), [black](https://github.com/psf/black) 他

*pyproject.toml*は*setuptools*に依存している*setup.py*や*setup.cfg*に代わりパッケージングのための諸々の情報や依存関係を記すための形式で、[PEP 518](https://www.python.org/dev/peps/pep-0518/)で策定されている。
ほかにも*pyproject.toml*を用いることで*requirements.txt*、 *MANIFEST.in*、 *Pipfile*といったファイルを置き換えることができる。

`pip install`でインストールしたいパッケージがsdist形式で配布されており、利用者側でビルドする必要がある場合、
pipのバージョンがv19.0以降かつ対象のパッケージに*pyproject.toml*ファイルがあれば、PEP 517に従ってパッケージがビルドされる。
*pyproject.toml*を用いたパッケージのビルドは[Poetry](https://github.com/python-poetry/poetry)、[Pyflow](https://github.com/David-OConnor/pyflow)といったツールが対応しているが、一応*setuptools*も最近のバージョンでは対応しているらしい。

PEP 518の[tool table](https://www.python.org/dev/peps/pep-0518/#tool-table)の項に記載されているように、\[tool\]テーブルにはビルドツール以外のPythonプロジェクトに関するツールの設定を記述できる。\[tool\]内のサブテーブルを使用する必要があり、 [flit](https://github.com/takluyver/flit)の場合は`[tool.flit.metadata]`、[black](https://github.com/psf/black)の場合は`[tool.black]`のように記載して各ツールの設定を記述することができる。


* 参考
  * [setuptools: setup.cfg-only projects](https://setuptools.readthedocs.io/en/latest/setuptools.html#setup-cfg-only-projects)
  * [PEP 453 -- Explicit bootstrapping of pip in Python installations](https://www.python.org/dev/peps/pep-0453/)
  * [PEP 517 -- A build-system independent format for source trees](https://www.python.org/dev/peps/pep-0517/)
  * [PEP 518 -- Specifying Minimum Build System Requirements for Python Projects](https://www.python.org/dev/peps/pep-0518/)

## requirements-dev.txt

◆ 使用プロジェクト数: 51+
◆ 使用ツール: [pip](https://github.com/pypa/pip)

開発・テスト環境用のrequirements.txt。前述のように*requirements.txt*のファイル名は任意なので、
テスト環境でしか使わない依存パッケージの情報は*requirements.txt*とは別の名称で保存される。
とはいえかなり名前の揺れが多く、他にも:

* dev-requirements.txt
* test-requirements.txt
* requirements_dev.txt
* requirements-test.txt
* requirements_test.txt
* docs-requirements.txt
* test_requirements.txt
* requirements-docs.txt
* requirements_docs.txt
* optional-requirements.txt
* requirements-build.txt

などがあった。

## Pipfile

◆ 使用プロジェクト数: 26
◆ 使用ツール: [Pipenv](https://github.com/pypa/pipenv)

[Pipenv](https://github.com/pypa/pipenv)で使用する依存パッケージ情報を記述するファイル。
このファイルを元に*Pipfile.lock*が作成される。
依存パッケージ情報のほかにスクリプトなども書けて、`pipenv run script-name`のような感じで実行できる。

## Pipfile.lock

◆ 使用プロジェクト数: 22
◆ 使用ツール: [Pipenv](https://github.com/pypa/pipenv)

[Pipenv](https://github.com/pypa/pipenv)生成される依存パッケージの情報を記述したlockファイル。  
npmで言うところの*package-lock.json*のようなもの。`pipenv sync`（dev-packageもインストールする場合は`pipenv sync -d`）でlockファイルに記述されたパッケージをそのままインストールするので、開発環境/運用環境、複数ユーザー間で同一の環境を再現できる。

*pipfile.lock*も1件あった。（使えるのか？）

*Pipfile*と数が合わないが、皆さんlockファイルはちゃんとGit管理しましょう。
…と思っていたが、[Pipenvのドキュメント](https://pipenv.pypa.io/en/latest/basics/#general-recommendations-version-control)によれば、「複数バージョンのPythonをターゲットにしている場合はlockファイルをバージョンコントロールすな」とのことらしい。

> * Generally, keep both Pipfile and Pipfile.lock in version control.
> * Do not keep Pipfile.lock in version control if multiple versions of Python are being targeted.

## poetry.lock

◆ 使用プロジェクト数: 15
◆ 使用ツール: [Poetry](https://github.com/python-poetry/poetry)

[Poetry](https://github.com/python-poetry/poetry)で生成される依存パッケージの情報を記述したlockファイル。
*pyproject.toml*に記述されている内容をもとに生成される。

# その他Pythonライブラリ系
## tox.ini

◆ 使用プロジェクト数: 225
◆ 使用ツール: [tox](https://github.com/tox-dev/tox)

複数のPythonバージョンおよびインタプリタでテストを行うためのvirtualenv管理及びコマンドラインツール。
*tox.ini*に設定を書き込むが*pyproject.toml*にも対応しているっぽい

[ドキュメント](https://tox.readthedocs.io/en/latest/)

## .coveragerc

◆ 使用プロジェクト数: 189
◆ 使用ツール: [coverage](https://pypi.org/project/coverage/)

テストカバレッジ計測用ツールの設定ファイル。

[ドキュメント](https://coverage.readthedocs.io/en/coverage-5.2.1/)

## codecov.yml

◆ 使用プロジェクト数: 102
◆ 使用ツール:[codecov](https://codecov.io/)

こちらも別のカバレッジ計測ツールの設定ファイル。
*.coveragerc*よりは少ないもののこちらも結構な数のプロジェクトで使われている印象。
*.codecov.yml*とも。

[ドキュメント](https://docs.codecov.io/docs)

## .pylintrc

◆ 使用プロジェクト数: 80
◆ 使用ツール: [pylint](https://pypi.org/project/pylint/)

linterツール*pylint*の設定ファイル。
*pylintrc*とも。

[ドキュメント](http://pylint.pycqa.org/en/latest/)

## pytest.ini

◆ 使用プロジェクト数: 69
◆ 使用ツール: [pytest](https://github.com/pytest-dev/pytest/)

*pytest*の設定ファイル。実行時のオプションなど記載する。

[ドキュメント](https://docs.pytest.org/en/stable/)

## .flake8

◆ 使用プロジェクト数: 55
◆ 使用ツール: [flake8](https://pypi.org/project/flake8/)

おなじみ静的解析ツール*flake8*の設定ファイル。

[ドキュメント](https://flake8.pycqa.org/en/latest/)

## conftest.py

◆ 使用プロジェクト数: 32
◆ 使用ツール: [pytest](https://github.com/pytest-dev/pytest/)

*pytest*で共通のfixtureやutil関数などを定義するためのファイル。
package内に作成するとそのパッケージ配下でのみ使用できるので、使用したいスコープに合わせて配置できる。

## mypy.ini

◆ 使用プロジェクト数: 28
◆ 使用ツール: [mypy](https://github.com/python/mypy)

静的型チェックツール*mypy*の設定ファイル。.
*.mypy.ini*も一件あった。

[ドキュメント](https://mypy.readthedocs.io/en/stable/introduction.html)

## .isort.cfg

◆ 使用プロジェクト数: 23
◆ 使用ツール: [isort](https://github.com/timothycrosley/isort)

Pythonコードのimportをルールに沿ってソートしてくれるツール*isort*の設定ファイル。

[ドキュメント](https://pycqa.github.io/isort/)

## .bumpversion.cfg

◆ 使用プロジェクト数: 21
◆ 使用ツール: [bumpversion](https://github.com/peritus/bumpversion)

[bumpversion](https://github.com/peritus/bumpversion)はソースコード内に定義されてるもろもろのバージョンを適切に増加させて書き換えてくれるコマンドラインツール。
*.bumpversion.cfg*はその設定ファイル。*.bumpversion.cfg*が存在しない場合は*setup.cfg*を見に行くらしい。

## manage.py

◆ 使用プロジェクト数: 20
◆ 使用ツール: [django](https://www.djangoproject.com/) の設定スクリプト？

djangoよくわかってないですがだいたいこんな感じのことが書いてありました。
[zulip/manage.py](https://github.com/zulip/zulip/blob/master/manage.py)

```python
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "zproject.settings")
    from django.conf import settings
    from django.core.management import execute_from_command_line
    from django.core.management.base import CommandError

    from scripts.lib.zulip_tools import log_management_command

    log_management_command(" ".join(sys.argv), settings.MANAGEMENT_LOG_PATH)

    os.environ.setdefault("PYTHONSTARTUP", os.path.join(BASE_DIR, "scripts/lib/pythonrc.py"))
    if "--no-traceback" not in sys.argv and len(sys.argv) > 1:
        sys.argv.append("--traceback")
    try:
        execute_from_command_line(sys.argv)
    except CommandError as e:
        print(e, file=sys.stderr)
        sys.exit(1)
```

## versioneer.py

◆ 使用プロジェクト数: 15
◆ 使用ツール: [versioneer](https://pypi.org/project/versioneer/)

こちらもプロジェクトのバージョンを自動で上げてくれるツール。

## .pyup.yml

◆ 使用プロジェクト数: 14
◆ 使用ツール: [pyup](https://github.com/pyupio/pyup)

GitHub/GitLabのプルリクを介してプロジェクトのPython依存ファイルを更新してくれるらしいです。よくわかってない。

## .pep8speaks.yml

◆ 使用プロジェクト数: 11
◆ 使用ツール: [pep8speaks](https://github.com/OrkoHunter/pep8speaks)

「プルリクエストでPythonコードスタイルを自動的に確認するGitHubアプリ」だそうです。

## .style.yapf

◆ 使用プロジェクト数: 9
◆ 使用ツール: [YAPF](https://github.com/google/yapf)

Google製のPythonコードフォーマッタ.「Yet Another Python Formatter」の略だそうです。

## tasks.py

◆ 使用プロジェクト数: 9
◆ 使用ツール: [Invoke](http://www.pyinvoke.org/) ?

参考：https://equal-001.hatenablog.com/entry/2016/03/31/113000

> pyinvokeは、いろんなコマンドをまるっと纏めることができるモジュール。

公式ドキュメントから引用。以下のように関数に`@task`デコレータをつけておくと、

```python
from invoke import task

@task
def clean(c, docs=False, bytecode=False, extra=''):
    patterns = ['build']
    if docs:
        patterns.append('docs/_build')
    if bytecode:
        patterns.append('**/*.pyc')
    if extra:
        patterns.append(extra)
    for pattern in patterns:
        c.run("rm -rf {}".format(pattern))

@task
def build(c, docs=False):
    c.run("python setup.py build")
    if docs:
        c.run("sphinx-build docs docs/_build")
```

CLIから簡単にタスクとして呼び出せるらしい

```
$ invoke clean build
```


## .landscape.yml

◆ 使用プロジェクト数: 8
◆ 使用ツール: [Prospector](https://inspecode.rocro.com/help/tools/prospector.html) ?

> Prospector is a tool to analyse Python code and output information about errors, potential problems, convention violations and complexity.

コード解析ツールらしいです。

## noxfile.py

◆ 使用プロジェクト数: 7
◆ 使用ツール: [Nox](https://nox.thea.codes/en/stable/)

toxに似たライブラリ

# その他

CI/CD系、Docker/Vagrant、ドキュメント生成などPython専用ではないツールの設定ファイルなど。

## .travis.yml

◆ 使用プロジェクト数: 386
◆ 使用ツール: [Travis CI](https://travis-ci.org/)

CI。

## Dockerfile

◆ 使用プロジェクト数: 111
◆ 使用ツール: Docker

dockerfile.

## .readthedocs.yml

◆ 使用プロジェクト数: 90 
◆ 使用ツール: [readthedocs](https://readthedocs.org/)

ドキュメント生成ツール
*.readthedocs.yml*と*readthedocs.yml*がある？

結構多くのプロジェクトで使われているようで、実際にこれまで書いたツールでもこれでドキュメント作っているものが多くみられた。

## .pre-commit-config.yaml
◆ 使用プロジェクト数: 88
◆ 使用ツール: [pre-commit](https://pre-commit.com/)

*pre-commit*は[Gitフック](https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA-Git-%E3%83%95%E3%83%83%E3%82%AF)の*pre-commit*を管理するためのツールで、
*pre-commit*自体がPython製というだけでPython以外のプロジェクトでも使える


## .editorconfig

◆ 使用プロジェクト数: 83
◆ 使用ツール: [editorconfig](https://editorconfig.org/)

様々なエディタやIDEでコードフォーマットを行うためのツール。Python以外でも使える。

## .appveyor.yml

◆ 使用プロジェクト数: 79
◆ 使用ツール: [appveyor](https://www.appveyor.com/)

CI/CD サービス。

## .dockerignore

◆ 使用プロジェクト数: 76
◆ 使用ツール: Docker

Dockerで無視するファイルの定義

## mkdocs.yml

◆ 使用プロジェクト数: 34
◆ 使用ツール: [mkdocs](https://www.mkdocs.org/)

プロジェクトドキュメント構築のための高速でシンプルかつ豪華な静的サイトジェネレーター、だそうです。

## docker-compose.yml

◆ 使用プロジェクト数: 33
◆ 使用ツール: docker-compose

docker-compose.

## package.json

◆ 使用プロジェクト数: 32
◆ 使用ツール: npm

npmのパッケージファイル。

[frappe/frappe](https://github.com/frappe/frappe)などPythonとJavaScriptで作られているプロジェクトではjs側のパッケージ管理は御多分に漏れず*package.json*で行っている様子。

## azure-pipelines.yml

◆ 使用プロジェクト数: 28
◆ 使用ツール: Azure Pipelines


## .deepsource.toml

◆ 使用プロジェクト数: 14
◆ 使用ツール: [deepsource](https://deepsource.io/docs/)

ソースコード解析？ Python以外でも使えるっぽい

## environment.yml

◆ 使用プロジェクト数: 13
◆ 使用ツール: conda?

https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html#creating-an-environment-from-an-environment-yml-file


## Vagrantfile

◆ 使用プロジェクト数: 12
◆ 使用ツール: Vagrant

## package-lock.json

◆ 使用プロジェクト数: 12
◆ 使用ツール: npm

npmのlockファイル。package.jsonと一緒に管理されてる。

## _config.yml

◆ 使用プロジェクト数: 11
◆ 使用ツール: [jekyll](https://jekyllrb.com/)

jekyllは静的サイトの生成を行うためのRuby製ツール。
例えば[これ](https://github.com/microsoft/forecasting)が[こんな風](https://microsoft.github.io/forecasting/)に？

## Jenkinsfile

◆ 使用プロジェクト数: 10
◆ 使用ツール: Jenkins

## .eslintrc

◆ 使用プロジェクト数: 16
◆ 使用ツール: Eslint

Python関係ないはず。JS用かな？

*.eslintrc.js* *.eslintrc.json* *.eslintrc.yml* など

## Procfile

◆ 使用プロジェクト数: 10
◆ 使用ツール: Heroku

Herokuで起動時にアプリによって実行されるコマンドを指定するファイル。

## .codeclimate.yml

◆ 使用プロジェクト数: 10
◆ 使用ツール: [CodeClimate](https://codeclimate.com/) ?

コードの品質チェック、カバレッジ測定など。Python以外でも使える。

## yarn.lock

◆ 使用プロジェクト数: 9
◆ 使用ツール: yarn

yarnのlockファイル。*package.json*と合わせて管理されてる。

## runtime.txt

◆ 使用プロジェクト数: 7
◆ 使用ツール: Heroku

Herokuにデプロイする際のランタイムを指定する設定ファイル

# 終わりに

スターの多い順に取得したので、今どきのツールを使ってるプロジェクトは少ないかな？という印象がありました。
Pythonプロジェクトの構成や、テスト・リリースのスクリプトなど、有名リポジトリから学べる事は多そうなので、興味のある方は調べてみると楽しいかもしれません。
他にもよく使われているツール・おすすめツールあったら教えてください。