Add url parameter to install_xbuildenv. ### Description

Resolve #3567 

Adds url paramter to `install_xbuildenv`, which helps installing xbuildenv from arbitrary URL. This is mostly for developers / maintainers who want to test tot xbuildenv.

This PR also adds a private CLI entrypoint `pyodide xbuildenv install`.

### Checklists

- [x] Add / update tests

[tool.mypy]
python_version = "3.10"
mypy_path = ["src/py", "pyodide-build"]
show_error_codes = true
warn_unreachable = true
enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
plugins = ["pydantic.mypy"]

# Strict checks
warn_unused_configs = true
check_untyped_defs = true
disallow_any_generics = true
disallow_subclassing_any = false
disallow_untyped_calls = false
disallow_untyped_defs = false
disallow_incomplete_defs = true
disallow_untyped_decorators = true
no_implicit_optional = true
warn_redundant_casts = true
warn_unused_ignores = true
warn_return_any = false
no_implicit_reexport = true
strict_equality = true

[[tool.mypy.overrides]]
module = [
  "_pyodide_core",
  "docutils.parsers.rst",
  "js",
  "pyodide_js",
  "ruamel.yaml",
  "matplotlib.*",
  "PIL.*",
  "virtualenv",
  "termcolor",
  "test",
  "tomllib",
  "tomli",
  "typer",
  "loky",
]
ignore_missing_imports = true

[tool.ruff]
select = [
  "E",     # pycodestyles
  "W",     # pycodestyles
  "F",     # pyflakes
  "B0",    # bugbear (all B0* checks enabled by default)
  "B904",  # bugbear (Within an except clause, raise exceptions with raise ... from err)
  "B905",  # bugbear (zip() without an explicit strict= parameter set.)
  "UP",    # pyupgrade
  "I",     # isort
  "PGH",   # pygrep-hooks
]
# Remove E999 once pattern matching is supported
# https://github.com/charliermarsh/ruff/issues/282
ignore = ["E402", "E501", "E731", "E741", "E999"]
target-version = "py311"

[tool.ruff.per-file-ignores]
"src/py/_pyodide/_base.py" = [
  "PGH001",  # No builtin `eval()` allowed
]
"src/tests/test_typeconversions.py" = [
  "PGH001",  # No builtin `eval()` allowed
]


[tool.ruff.isort]
known-first-party = [
  "pyodide",
  "pyodide_js",
  "micropip",
  "pyodide_build",
  "_pyodide",
  "js",
]
known-third-party = [
  "build",
]

[tool.ruff.flake8-bugbear]
extend-immutable-calls = ["typer.Argument", "typer.Option"]

[tool.pyodide]

[tool.mypy]
python_version = "3.10"
mypy_path = ["src/py", "pyodide-build"]
show_error_codes = true
warn_unreachable = true
enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
plugins = ["pydantic.mypy"]

# Strict checks
warn_unused_configs = true
check_untyped_defs = true
disallow_any_generics = true
disallow_subclassing_any = false
disallow_untyped_calls = false
disallow_untyped_defs = false
disallow_incomplete_defs = true
disallow_untyped_decorators = true
no_implicit_optional = true
warn_redundant_casts = true
warn_unused_ignores = true
warn_return_any = false
no_implicit_reexport = true
strict_equality = true

[[tool.mypy.overrides]]
module = [
  "_pyodide_core",
  "docutils.parsers.rst",
  "js",
  "pyodide_js",
  "ruamel.yaml",
  "matplotlib.*",
  "PIL.*",
  "virtualenv",
  "termcolor",
  "test",
  "tomllib",
  "tomli",
  "typer",
  "pytest_pyodide",
  "loky",
]
ignore_missing_imports = true

[tool.ruff]
select = [
  "E",     # pycodestyles
  "W",     # pycodestyles
  "F",     # pyflakes
  "B0",    # bugbear (all B0* checks enabled by default)
  "B904",  # bugbear (Within an except clause, raise exceptions with raise ... from err)
  "B905",  # bugbear (zip() without an explicit strict= parameter set.)
  "UP",    # pyupgrade
  "I",     # isort
  "PGH",   # pygrep-hooks
]
# Remove E999 once pattern matching is supported
# https://github.com/charliermarsh/ruff/issues/282
ignore = ["E402", "E501", "E731", "E741", "E999"]
target-version = "py311"

[tool.ruff.per-file-ignores]
"src/py/_pyodide/_base.py" = [
  "PGH001",  # No builtin `eval()` allowed
]
"src/tests/test_typeconversions.py" = [
  "PGH001",  # No builtin `eval()` allowed
]


[tool.ruff.isort]
known-first-party = [
  "pyodide",
  "pyodide_js",
  "micropip",
  "pyodide_build",
  "_pyodide",
  "js",
]
known-third-party = [
  "build",
]

[tool.ruff.flake8-bugbear]
extend-immutable-calls = ["typer.Argument", "typer.Option"]

[tool.pyodide]
