Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,6 @@ component-detection-pip-report.json
**/.pydevproject
**/.settings
.github/prompts/copilot-instructions.md

# No uv lock for now
uv.lock
Empty file.
93 changes: 93 additions & 0 deletions eng/tools/azure-sdk-tools/azpysdk/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
"""azpysdk CLI

A minimal command-line interface using argparse. This file provides a
`main()` entrypoint so the package can be invoked as a module
(e.g. `python -m azpysdk.main`) or installed as a console script.
"""

from __future__ import annotations

import argparse
import sys
from typing import Sequence, Optional

__all__ = ["main", "build_parser"]
__version__ = "0.0.0"


def _cmd_greet(args: argparse.Namespace) -> int:
"""Simple greet command: prints a greeting."""
name = args.name or "world"
print(f"Hello, {name}!")
return 0


def _cmd_echo(args: argparse.Namespace) -> int:
"""Echo command: prints back the provided message."""
print(args.message)
return 0


def _cmd_run(args: argparse.Namespace) -> int:
"""Run command: placeholder for running a task or pipeline."""
print(f"Running task: {args.task}")
# TODO: implement real behaviour
return 0


def build_parser() -> argparse.ArgumentParser:
"""Create and return the top-level ArgumentParser for the CLI."""
parser = argparse.ArgumentParser(
prog="azpysdk", description="Azure SDK Python tools (minimal CLI)"
)
parser.add_argument("-V", "--version", action="version", version=__version__)

subparsers = parser.add_subparsers(title="commands", dest="command")

# greet
p = subparsers.add_parser("greet", help="Greet someone")
p.add_argument("-n", "--name", help="Name to greet")
p.set_defaults(func=_cmd_greet)

# echo
p = subparsers.add_parser("echo", help="Echo a message")
p.add_argument("message", help="Message to echo")
p.set_defaults(func=_cmd_echo)

# run
p = subparsers.add_parser("run", help="Run a placeholder task")
p.add_argument("-t", "--task", default="default", help="Task name to run")
p.set_defaults(func=_cmd_run)

return parser


def main(argv: Optional[Sequence[str]] = None) -> int:
"""CLI entrypoint.

Args:
argv: Optional list of arguments to parse (defaults to sys.argv[1:]).

Returns:
Exit code to return to the OS.
"""
parser = build_parser()
args = parser.parse_args(argv)

if not hasattr(args, "func"):
parser.print_help()
return 1

try:
result = args.func(args)
return int(result or 0)
except KeyboardInterrupt:
print("Interrupted by user", file=sys.stderr)
return 130
except Exception as exc: # pragma: no cover - simple top-level error handling
print(f"Error: {exc}", file=sys.stderr)
return 2


if __name__ == "__main__":
raise SystemExit(main())
64 changes: 64 additions & 0 deletions eng/tools/azure-sdk-tools/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,67 @@
[build-system]
requires = ["setuptools>=42", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "azure-sdk-tools"
version = "0.0.0"
description = "Build and test tooling for the Azure SDK for Python"
readme = "README.md"
authors = [
{ name = "Microsoft Corporation", email = "[email protected]" }
]
urls = { "Homepage" = "https://github.com/Azure/azure-sdk-for-python" }

dependencies = [
"packaging",
"wheel",
"Jinja2",
"json-delta>=2.0",
"pytest-cov",
"pytest>=3.5.1",
"python-dotenv",
"PyYAML",
"urllib3",
"tomli-w==1.0.0",
"azure-core",
"ConfigArgParse>=0.12.0",
"pytest-asyncio>=0.9.0; python_version >= '3.5'",
"tomli; python_version < '3.11'",
]

[project.scripts]
generate_package = "packaging_tools.generate_package:generate_main"
generate_sdk = "packaging_tools.generate_sdk:generate_main"
generate_client = "packaging_tools.generate_client:generate_main"
multiapi_combiner = "packaging_tools.multiapi_combiner:combine"
perfstress = "devtools_testutils.perfstress_tests:run_perfstress_cmd"
perfstressdebug = "devtools_testutils.perfstress_tests:run_perfstress_debug_cmd"
sdk_generator = "packaging_tools.sdk_generator:generate_main"
sdk_build = "ci_tools.build:build"
sdk_build_package = "ci_tools.build:build_package"
sdk_build_conda = "ci_tools.conda:entrypoint"
sdk_set_dev_version = "ci_tools.versioning.version_set_dev:version_set_dev_main"
sdk_set_version = "ci_tools.versioning.version_set:version_set_main"
sdk_increment_version = "ci_tools.versioning.version_increment:version_increment_main"
sdk_analyze_deps = "ci_tools.dependency_analysis:analyze_dependencies"
sdk_find_invalid_versions = "ci_tools.versioning.find_invalid_versions:find_invalid_versions_main"
sdk_verify_keywords = "ci_tools.keywords_verify:entrypoint"
systemperf = "devtools_testutils.perfstress_tests:run_system_perfstress_tests_cmd"
azpysdk = "azpysdk.main:main"

[project.optional-dependencies]
build = ["setuptools", "pyparsing", "certifi", "cibuildwheel", "pkginfo", "build"]
conda = ["beautifulsoup4"]
systemperf = ["aiohttp>=3.0", "requests>=2.0", "tornado==6.0.3", "httpx>=0.21", "azure-core"]
ghtools = ["GitPython", "PyGithub>=1.59.0", "requests>=2.0"]

[tool.setuptools]
include-package-data = true

[tool.setuptools.packages.find]
where = ["."]
exclude = ["tests*"]

[tool.black]
line-length=120
exclude="packaging_tools/templates/setup.py"
64 changes: 0 additions & 64 deletions eng/tools/azure-sdk-tools/setup.py

This file was deleted.

15 changes: 7 additions & 8 deletions eng/tools/azure-sdk-tools/tests/test_parse_functionality.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
)
scenarios_folder = os.path.join(os.path.dirname(__file__), "integration", "scenarios")
metapackage_scenario = os.path.join(scenarios_folder, "setup_py_metapackage")
setup_project_scenario = os.path.join(scenarios_folder, "setup_py_project_def")
pyproject_scenario = os.path.join(scenarios_folder, "pyproject_project_def")
pyproject_extension_scenario = os.path.join(scenarios_folder, "pyproject_project_def_with_extension")

Expand Down Expand Up @@ -110,22 +111,21 @@ def test_sdk_sample_setup(test_patch):
)
"""

result = ParsedSetup.from_path(package_root)
result = ParsedSetup.from_path(setup_project_scenario)

assert result.name == "azure-core"
assert result.version == "1.21.0"
assert result.python_requires == ">=3.7"
assert result.requires == ["requests>=2.18.4", "six>=1.11.0", "typing-extensions>=4.0.1"]
assert result.is_new_sdk == True
assert result.setup_filename == os.path.join(package_root, "setup.py")
assert result.setup_filename == os.path.join(setup_project_scenario, "setup.py")
assert "pytyped" in result.package_data
assert result.include_package_data == True
assert result.folder == package_root
assert result.folder == setup_project_scenario
assert len(result.classifiers) > 0
assert result.classifiers[0] == "Development Status :: 5 - Production/Stable"
assert result.classifiers[5] == "Programming Language :: Python :: 3.8"
assert result.keywords[0] == "azure sdk"
assert result.is_metapackage == False
assert len(result.keywords) == 2


Expand Down Expand Up @@ -191,24 +191,23 @@ def test_parse_recognizes_extensions(test_patch):
)
"""

result = ParsedSetup.from_path(package_root)
result = ParsedSetup.from_path(setup_project_scenario)

assert result.name == "azure-storage-extensions"
assert result.version == "1.21.0"
assert result.python_requires == ">=3.7"
assert result.requires == ["requests>=2.18.4", "six>=1.11.0", "typing-extensions>=4.0.1"]
# todo resolve this conflict assert result.is_new_sdk == True
assert result.setup_filename == os.path.join(package_root, "setup.py")
assert result.setup_filename == os.path.join(setup_project_scenario, "setup.py")
assert "pytyped" in result.package_data
assert result.include_package_data == True
assert result.folder == package_root
assert result.folder == setup_project_scenario
assert len(result.classifiers) > 0
assert result.classifiers[0] == "Development Status :: 5 - Production/Stable"
assert result.classifiers[5] == "Programming Language :: Python :: 3.8"
assert result.ext_package == "azure.storage.extensions"
assert result.ext_modules is not None
assert result.is_pyproject == False
assert result.is_metapackage == False
assert len(result.ext_modules) == 1
assert str(type(result.ext_modules[0])) == "<class 'setuptools.extension.Extension'>"

Expand Down
2 changes: 1 addition & 1 deletion scripts/dev_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def select_install_type(pkg, run_develop, exceptions):

packages = {
tuple(os.path.dirname(f).rsplit(os.sep, 1))
for f in glob.glob(os.path.join(root_dir, "sdk/*/azure-*/setup.py")) + glob.glob(os.path.join(root_dir, "eng/tools/azure-*/setup.py"))
for f in glob.glob(os.path.join(root_dir, "sdk/*/azure-*/setup.py")) + glob.glob(os.path.join(root_dir, "eng/tools/azure-sdk-tools/"))
}
# [(base_folder, package_name), ...] to {package_name: base_folder, ...}
packages = {package_name: base_folder for (base_folder, package_name) in packages}
Expand Down
17 changes: 17 additions & 0 deletions sdk/keyvault/azure-keyvault-keys/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,20 @@ pytyped = ["py.typed"]

[tool.azure-sdk-build]
pyright = false

[tool.uv.sources]
azure-core = { path = "../../core/azure-core" }
azure-keyvault-nspkg = { path = "../../nspkg/azure-keyvault-nspkg" }
azure-sdk-tools = { path = "../../../eng/tools/azure-sdk-tools" }

[dependency-groups]
dev = [
"aiohttp>=3.0",
"azure-core",
"azure-identity>=1.24.0",
"azure-keyvault-nspkg",
"azure-mgmt-keyvault==10.1.0",
"azure-sdk-tools",
"parameterized>=0.7.3",
"python-dateutil>=2.8.0",
]