blob: c064094fc9e95f32f1278e62184746a38c4f1d29 [file]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
import tempfile
import unittest
from pathlib import Path
from plan import PROJECT_DIR
from plan import Package
from plan import plan
from plan import plan_from_metadata
def package(
root: Path,
name: str,
*,
dependencies: list[dict[str, object]] | None = None,
publish: list[str] | None = None,
) -> dict[str, object]:
return {
"id": f"path+file://{root / name}#{name}@1.0.0",
"name": name,
"version": "1.0.0",
"manifest_path": str(root / name / "Cargo.toml"),
"publish": publish,
"dependencies": dependencies or [],
}
def dependency(root: Path, name: str, *, kind: str | None = None):
return {
"name": name,
"kind": kind,
"path": str(root / name),
}
class ReleaseRustPlanTest(unittest.TestCase):
def test_current_workspace_plan_contains_new_aws_crates(self):
packages = plan(PROJECT_DIR)
positions = {package.name: index for index, package in enumerate(packages)}
self.assertIn("reqsign-aws-core", positions)
self.assertIn("reqsign-aws-v4a", positions)
self.assertLess(positions["reqsign-core"], positions["reqsign-aws-core"])
self.assertLess(positions["reqsign-aws-core"], positions["reqsign-aws-v4"])
self.assertLess(positions["reqsign-aws-core"], positions["reqsign-aws-v4a"])
self.assertLess(positions["reqsign-aws-v4"], positions["reqsign-google"])
self.assertEqual(packages[-1].name, "reqsign")
def test_plan_is_topological_and_ignores_dev_dependencies(self):
with tempfile.TemporaryDirectory() as tmpdir:
root = Path(tmpdir).resolve()
core = package(root, "core")
service = package(
root,
"service",
dependencies=[dependency(root, "core")],
)
facade = package(
root,
"facade",
dependencies=[
dependency(root, "service"),
dependency(root, "dev-only", kind="dev"),
],
)
dev_only = package(root, "dev-only")
packages = [facade, service, dev_only, core]
metadata = {
"packages": packages,
"workspace_members": [package["id"] for package in packages],
}
result = plan_from_metadata(metadata, root)
self.assertEqual(
result,
[
Package("core", "1.0.0", "core"),
Package("dev-only", "1.0.0", "dev-only"),
Package("service", "1.0.0", "service"),
Package("facade", "1.0.0", "facade"),
],
)
def test_unpublishable_workspace_dependency_fails_closed(self):
with tempfile.TemporaryDirectory() as tmpdir:
root = Path(tmpdir).resolve()
internal = package(root, "internal", publish=[])
public = package(
root,
"public",
dependencies=[dependency(root, "internal")],
)
packages = [internal, public]
metadata = {
"packages": packages,
"workspace_members": [package["id"] for package in packages],
}
with self.assertRaisesRegex(RuntimeError, "unpublished workspace package"):
plan_from_metadata(metadata, root)
def test_cycle_fails_closed(self):
with tempfile.TemporaryDirectory() as tmpdir:
root = Path(tmpdir).resolve()
first = package(
root,
"first",
dependencies=[dependency(root, "second")],
)
second = package(
root,
"second",
dependencies=[dependency(root, "first")],
)
packages = [first, second]
metadata = {
"packages": packages,
"workspace_members": [package["id"] for package in packages],
}
with self.assertRaisesRegex(RuntimeError, "dependency cycle"):
plan_from_metadata(metadata, root)
if __name__ == "__main__":
unittest.main()