第一章:项目初始化——打好地基,后面才不慌
说实话,很多新手做自动化构建,上来就写脚本、配流水线。结果呢?项目结构乱成一锅粥,Git 提交记录惨不忍睹,虚拟环境更是搞得一团糟。我见过太多这样的案例了。
我个人习惯是,先把地基打牢。项目初始化这一步,看似简单,其实决定了后续开发的幸福感。今天我们就来聊聊,怎么把这一步做得漂亮。
1.1 创建项目目录结构
先问大家一个问题:你见过那种所有文件都堆在根目录下的项目吗?我见过。那感觉就像走进一个没有分类的仓库,找个螺丝钉得翻半天。
一个清晰的项目结构,应该让人一眼就知道:源码在哪、配置在哪、文档在哪。我常用的结构是这样的:
my_auto_build/
├── src/ # 源代码
│ ├── commands/ # 自定义命令
│ ├── utils/ # 工具函数
│ └── main.py # 入口文件
├── tests/ # 测试用例
├── docs/ # 文档
├── config/ # 配置文件
├── scripts/ # 辅助脚本
├── .gitignore # Git 忽略规则
├── README.md # 项目说明
└── requirements.txt # 依赖清单
嗯,这里要注意:不要照搬别人的结构。我刚开始做项目时,就喜欢抄大厂的项目结构,结果发现很多目录根本用不上。说白了,结构是为内容服务的。
1.2 初始化 Git 仓库
Git 的重要性,不用我多说了吧?但很多人初始化仓库时,就是简单敲个 git init 完事。这其实不够。
我每次初始化,都会做三件事:
- 创建 .gitignore 文件——把虚拟环境、缓存文件、IDE 配置等统统忽略掉
- 创建 README.md——哪怕只写一句话,也要告诉别人这个项目是干嘛的
- 做第一次提交——提交信息写 "chore: project initialization"
为什么会强调第一次提交?因为这是项目的起点。我曾经接手过一个项目,Git 历史里第一条提交就是 "fix bug",你想想看,这得多让人抓狂。
下面是我常用的 .gitignore 模板:
# 虚拟环境
venv/
.venv/
env/
# Python 缓存
__pycache__/
*.py[cod]
*.so
# IDE 配置
.vscode/
.idea/
# 系统文件
.DS_Store
Thumbs.db
# 构建产物
dist/
build/
*.egg-info/
1.3 配置虚拟环境
Python 项目最怕什么?依赖冲突。我见过太多人直接在全局环境里装包,结果项目 A 要 Django 3.0,项目 B 要 Django 4.0,最后两个项目都跑不起来。
虚拟环境就是解决这个问题的。说白了,就是给每个项目一个独立的 Python 解释器和包管理空间。
我个人习惯用 venv,因为它是 Python 自带的,不需要额外安装。操作也很简单:
# 创建虚拟环境
python -m venv venv
# 激活虚拟环境(Windows)
venv\Scripts\activate
# 激活虚拟环境(macOS/Linux)
source venv/bin/activate
# 安装依赖
pip install -r requirements.txt
这里有个细节:虚拟环境的名字最好统一叫 venv。这样不管是自己还是同事,一看就知道这是虚拟环境目录,而且 .gitignore 里也方便统一忽略。
| 工具 | 优点 | 缺点 |
|---|---|---|
| venv | Python 内置,无需额外安装 | 功能相对基础 |
| virtualenv | 支持 Python 2/3 混用 | 需要单独安装 |
| conda | 支持非 Python 依赖管理 | 体积大,启动慢 |
| poetry | 依赖解析更智能 | 学习成本稍高 |
你可能会问:到底选哪个?我的建议是:团队用啥你用啥。如果就自己玩,venv 完全够用。我在小项目里一直用 venv,从来没出过问题。
1.4 初始化脚本自动化
上面这些步骤,每次新建项目都要重复一遍。你想想看,是不是很烦?
所以我自己写了个初始化脚本,一键搞定:
#!/usr/bin/env python3
"""项目初始化脚本"""
import os
import subprocess
import sys
def create_project_structure(project_name):
"""创建项目目录结构"""
dirs = [
f"{project_name}/src/commands",
f"{project_name}/src/utils",
f"{project_name}/tests",
f"{project_name}/docs",
f"{project_name}/config",
f"{project_name}/scripts",
]
for dir_path in dirs:
os.makedirs(dir_path, exist_ok=True)
# 在每个目录下创建 __init__.py
init_file = os.path.join(dir_path, "__init__.py")
if not os.path.exists(init_file):
with open(init_file, "w") as f:
f.write("# 初始化文件\n")
print(f"✅ 项目结构创建完成: {project_name}")
def init_git_repo(project_path):
"""初始化 Git 仓库"""
os.chdir(project_path)
subprocess.run(["git", "init"], check=True)
subprocess.run(["git", "add", "."], check=True)
subprocess.run(["git", "commit", "-m", "chore: project initialization"], check=True)
print("✅ Git 仓库初始化完成")
def setup_virtual_env(project_path):
"""配置虚拟环境"""
os.chdir(project_path)
subprocess.run([sys.executable, "-m", "venv", "venv"], check=True)
print("✅ 虚拟环境创建完成")
print("💡 请运行以下命令激活虚拟环境:")
if sys.platform == "win32":
print(" venv\\Scripts\\activate")
else:
print(" source venv/bin/activate")
if __name__ == "__main__":
project_name = input("请输入项目名称: ").strip()
if not project_name:
print("❌ 项目名称不能为空")
sys.exit(1)
create_project_structure(project_name)
init_git_repo(project_name)
setup_virtual_env(project_name)
print("\n🎉 项目初始化完成!")
好了,第一章的内容就到这里。记住:好的开始是成功的一半。把项目初始化这一步做扎实了,后面写代码、配流水线都会轻松很多。
下一章,我们来聊聊怎么定义自定义命令的接口规范。到时候见!