/
niceSOFT
/
python3-hatchling
Обзор
Документация
Войти
/
niceSOFT
/
python3-hatchling
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/hatch/cli/new/__init__.py
162 строки
6 KB
Dimitri Papadopoulos Orfanos
Upgrade Ruff to 0.13.2 (#1890)
28 сен 2025, 21:20
Не верифицирован
28 сен 2025, 21:20
aff6f39
Код
Авторство
О чём код?
import click @click.command(short_help="Create or initialize a project") @click.argument("name", required=False) @click.argument("location", required=False) @click.option("--interactive", "-i", "interactive", is_flag=True, help="Interactively choose details about the project") @click.option("--cli", "feature_cli", is_flag=True, help="Give the project a command line interface") @click.option("--init", "initialize", is_flag=True, help="Initialize an existing project") @click.option("-so", "setuptools_options", multiple=True, hidden=True) @click.pass_obj def new(app, name, location, interactive, feature_cli, initialize, setuptools_options): """Create or initialize a project.""" import sys from copy import deepcopy from datetime import datetime, timezone from hatch.config.model import TemplateConfig from hatch.project.core import Project from hatch.template import File from hatch.utils.fs import Path if location: location = Path(location).resolve() migration_possible = False if initialize: interactive = True location = location or Path.cwd() if (location / "setup.py").is_file() or (location / "setup.cfg").is_file(): migration_possible = True if not name: name = "temporary" if not name: if not interactive: app.abort("Missing required argument for the project name, use the -i/--interactive flag.") name = app.prompt("Project name") normalized_name = Project.canonicalize_name(name, strict=False) if not location: location = Path(normalized_name).resolve() needs_config_update = False if location.is_file(): app.abort(f"Path `{location}` points to a file.") elif location.is_dir() and any(location.iterdir()): if not initialize: app.abort(f"Directory `{location}` is not empty.") needs_config_update = (location / "pyproject.toml").is_file() if migration_possible: from hatch.cli.new.migrate import migrate from hatch.venv.core import TempVirtualEnv try: with ( app.status("Migrating project metadata from setuptools"), TempVirtualEnv(sys.executable, app.platform) as venv, ): app.platform.run_command(["python", "-m", "pip", "install", "-q", "setuptools"]) migrate(str(location), setuptools_options, venv.sys_path) except Exception as e: # noqa: BLE001 app.display_error(f"Could not automatically migrate from setuptools: {e}") if name == "temporary": name = app.prompt("Project name") else: return default_config = { "description": "", "dependencies": set(), "package_name": normalized_name.replace("-", "_"), "project_name": name, "project_name_normalized": normalized_name, "args": {"cli": feature_cli}, } if interactive: default_config["description"] = app.prompt("Description", default="") app.display_info() if needs_config_update: app.project.initialize(str(location / "pyproject.toml"), default_config) app.display_success("Updated: pyproject.toml") return template_config = deepcopy(app.config.template.raw_data) if "plugins" in template_config and not template_config["plugins"]: del template_config["plugins"] TemplateConfig(template_config, ("template",)).parse_fields() plugin_config = template_config.pop("plugins") # Set up default config for template files template_config.update(default_config) template_classes = app.plugins.template.collect() templates = [] for template_name, template_class in sorted(template_classes.items(), key=lambda item: -item[1].PRIORITY): if template_name in plugin_config: templates.append( template_class(plugin_config.pop(template_name), app.cache_dir, datetime.now(timezone.utc)) ) if not templates: app.abort(f"None of the defined plugins were found: {', '.join(sorted(plugin_config))}") elif plugin_config: app.abort(f"Some of the defined plugins were not found: {', '.join(sorted(plugin_config))}") for template in templates: template.initialize_config(template_config) template_files = [] for template in templates: for possible_template_file in template.get_files(config=deepcopy(template_config)): template_file = ( possible_template_file(deepcopy(template_config), template.plugin_config) if possible_template_file.__class__ is not File else possible_template_file ) if template_file.path is None or (initialize and str(template_file.path) != "pyproject.toml"): continue template_files.append(template_file) for template in templates: template.finalize_files(config=deepcopy(template_config), files=template_files) for template_file in template_files: template_file.write(location) if initialize: app.display_success("Wrote: pyproject.toml") return from rich.markup import escape from rich.tree import Tree def recurse_directory(directory, tree): paths = sorted(Path(directory).iterdir(), key=lambda p: (p.is_file(), p.name)) for path in paths: if path.is_dir(): recurse_directory( path, tree.add(f"[bold magenta][link={app.platform.format_file_uri(path)}]{escape(path.name)}") ) else: tree.add(f"[green][link={app.platform.format_file_uri(path)}]{escape(path.name)}") root = Tree( f"[bold magenta][link={app.platform.format_file_uri(location)}]{escape(location.name)}", guide_style="bright_blue", hide_root=location == Path.cwd(), ) recurse_directory(location, root) app.output(root, markup=True)