diff --git a/README.md b/README.md index b840e1b..67672df 100644 --- a/README.md +++ b/README.md @@ -86,3 +86,9 @@ $ pytest tests/e2e_tests -s --include-core-tests ``` Currently, CI tests only run unit and integration tests. There's an open task in django-simple-deploy to remove the dependence on poetry and pipenv for running tests. When that is implemented, e2e tests can run much more easily in CI. + +Documentation +--- + +For more information, see the [docs](docs/) directory. + diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..b3754fa --- /dev/null +++ b/docs/README.md @@ -0,0 +1,8 @@ +dsd-plugin-generator documentation +--- + +I'll probably make a full documentation site on read the docs before long for this project, but for now the most important information is in the main README and here. + +- [Plugin structure](plugin_structure.md): This page describes the structure of a plugin, and the naming conventions used. +- [End to end tests](e2e_tests.md): This page describes how the end to end tests are set up, and how they can be used for development purposes as well as for testing purposes. +- \ No newline at end of file diff --git a/docs/e2e_tests.md b/docs/e2e_tests.md new file mode 100644 index 0000000..1e14597 --- /dev/null +++ b/docs/e2e_tests.md @@ -0,0 +1,77 @@ +End to end tests +=== + +Currently, plugins can only be tested when they're installed into a django-simple-deploy test environment. + +To manage this, the end to end tests for this project do the following: + +- Get a temp dir from pytest. +- Make a shallow clone of django-simple-deploy into the temp dir. +- For each plugin test: + - Generate the plugin using `generate_plugin()`. + - Install the plugin to the temp django-simple-deploy env. + - Run django-simple-deploy's tests, which in turn run the plugin's tests. + - Uninstall the plugin from the django-simple-deploy env. + +CLI args +--- + +There are three CLI args that can help with e2e testing: + +`-s` +--- + +This is a pytest flag that streams output as the test runs. Since these are long running tests, it's almost always useful to include this flag. Otherwise it can look like the tests are hanging. + +`--run-core-tests` +--- + +This flag runs the full set of django-simple-deploy tests, for every test plugin. This takes a lot longer. The default behavior is to only use django-simple-deploy to run the plugin's tests. + +`--setup-plugins-only` +--- + +When we run this project's e2e tests, we're actually calling pytest within a temp django-simple-deploy env, once for every test plugin. That means the temp dirs such as `pytest-237` get garbage collected even before the test finishes running. That makes it difficult to see what kind of environment is being built. + +The `--setup-plugins-only` flag prevents any tests from being run. We just set up the temp dev environment for django-simple-deploy, and then generate the full series of test plugins. You can then drop into the latest temp pytest directory, and poke around the full test environment. + +Here's what that looks like: + +```sh +$ pytest tests/e2e_tests -s --setup-plugins-only +... +Building e2e test env at: /private/.../pytest-239/e2e_new_plugin_test0 +... + Built django-simple-deploy... + Built dsd-newfly... + Built dsd-newplatform... + Built dsd-my-plugin... +... +``` + +In just a few seconds, you have a development environment for django-simple-deploy, alongside a set of plugins generated by this project. + +You can cd to this folder, and do anything you want with these resources. Here's how to drop into that folder, see the plugins, install one to the django-simple-deploy environment, and run the new platform's integration tests: + +```sh +$ cd /private/.../pytest-239/e2e_new_plugin_test0 +e2e_new_plugin_test0$ ls -l +django-simple-deploy +dsd-my-plugin +dsd-newfly +dsd-newplatform +e2e_new_plugin_test0$ cd django-simple-deploy +django-simple-deploy$ source .venv/bin/activate +(.venv) django-simple-deploy$ uv pip install -e ../dsd-newplatform + Built dsd-newplatform +... +(.venv) django-simple-deploy$ pytest -k newplatform +========== test session starts ======================== +collected 77 items / 59 deselected / 18 selected +test_newplatform_config.py .................. [100%] +========== 18 passed, 59 deselected in 3.65s ========== +``` + +This is really helpful for maintaining the test suite, and for development work. + +**Note:** This can get a little flaky, because we're working in a temp environment that pytest will destroy when more resources are created. If you want to keep working with these resources, you can copy the entire `e2e_new_plugin_test0` directory to a more stable location. You'll have to rebuild the `django-simple-deploy/.venv` environment, but you'll have a useful, stable development environment to work with. You'll be able to run any tests you want from that environment. diff --git a/docs/plugin_structure.md b/docs/plugin_structure.md new file mode 100644 index 0000000..221abee --- /dev/null +++ b/docs/plugin_structure.md @@ -0,0 +1,67 @@ +Plugin project structure +=== + +This document describes the overall project structure, and naming conventions within the project. + +Example plugin +--- + +Consider a plugin that should be built from the following user input: + +```sh +$ python generate_plugin.py +What platform are you targeting? (Example: Fly.io) GreenHost +What's the name of your plugin package? (Example: dsd-flyio) dsd-greenhost-high-traffic +Will your plugin support the --automate-all CLI arg? (yes/no) y +What name do you want to appear in the LICENSE file? Eric +``` + +This is a plugin that will support high-traffic sites on a platform called GreenHost. + +Example project structure +--- + +Here's the project structure for the plugin that's generated: + +```sh +$ tree -L 3 dsd-greenhost-high-traffic +dsd-greenhost-high-traffic +├── CHANGELOG.md +├── LICENSE +├── MANIFEST.in +├── README.md +├── developer_resources +│   └── README.md +├── dsd_greenhost_high_traffic +│   ├── __init__.py +│   ├── deploy.py +│   ├── deploy_messages.py +│   ├── platform_deployer.py +│   ├── plugin_config.py +│   └── templates +│   ├── dockerfile_example +│   └── settings.py +├── pyproject.toml +└── tests + ├── conftest.py + ├── e2e_tests + │   ├── __init__.py + │   ├── test_deployment.py + │   └── utils.py + └── integration_tests + ├── reference_files + └── test_greenhost_config.py + +8 directories, 18 files +``` + +Notes +--- + +Here's what's important to note: + +- The outer project directory is the name of the plugin package. +- The main project directory is the plugin package name, with hyphens replaced by underscores. +- The main integration test for configuration changes is named `test__config.py`. + +Currently, plugin package names need to start with `dsd-`. This requirement will be removed before long. diff --git a/plugin_template/dsd_platformname/__init__.py b/plugin_template/plugin_pkg_name/__init__.py similarity index 100% rename from plugin_template/dsd_platformname/__init__.py rename to plugin_template/plugin_pkg_name/__init__.py diff --git a/plugin_template/dsd_platformname/deploy.py b/plugin_template/plugin_pkg_name/deploy.py similarity index 100% rename from plugin_template/dsd_platformname/deploy.py rename to plugin_template/plugin_pkg_name/deploy.py diff --git a/plugin_template/dsd_platformname/deploy_messages.py b/plugin_template/plugin_pkg_name/deploy_messages.py similarity index 100% rename from plugin_template/dsd_platformname/deploy_messages.py rename to plugin_template/plugin_pkg_name/deploy_messages.py diff --git a/plugin_template/dsd_platformname/platform_deployer.py b/plugin_template/plugin_pkg_name/platform_deployer.py similarity index 100% rename from plugin_template/dsd_platformname/platform_deployer.py rename to plugin_template/plugin_pkg_name/platform_deployer.py diff --git a/plugin_template/dsd_platformname/plugin_config.py b/plugin_template/plugin_pkg_name/plugin_config.py similarity index 100% rename from plugin_template/dsd_platformname/plugin_config.py rename to plugin_template/plugin_pkg_name/plugin_config.py diff --git a/plugin_template/dsd_platformname/templates/dockerfile_example b/plugin_template/plugin_pkg_name/templates/dockerfile_example similarity index 100% rename from plugin_template/dsd_platformname/templates/dockerfile_example rename to plugin_template/plugin_pkg_name/templates/dockerfile_example diff --git a/plugin_template/dsd_platformname/templates/settings.py b/plugin_template/plugin_pkg_name/templates/settings.py similarity index 100% rename from plugin_template/dsd_platformname/templates/settings.py rename to plugin_template/plugin_pkg_name/templates/settings.py diff --git a/tests/e2e_tests/conftest.py b/tests/e2e_tests/conftest.py index 35423e4..ed8a8ab 100644 --- a/tests/e2e_tests/conftest.py +++ b/tests/e2e_tests/conftest.py @@ -1,23 +1,103 @@ """Configuration for e2e test runs.""" +import json +import subprocess +import shlex from dataclasses import dataclass import pytest +from tests.e2e_tests.utils import e2e_utils + +# --- Custom CLI args --- def pytest_addoption(parser): parser.addoption( - "--include-core-tests", + "--run-core-tests", action="store_true", help="Run the full set of core django-simple-deploy tests for each new plugin.", ) + parser.addoption( + # Useful for troubleshooting this test env. May also be useful for poking around + # the full set of test plugins. + # In a full test run, this test runs many django-simple-deploy pytest calls. Each of + # those leads to a pytest-___ temp dir. That can make it difficult or impossible + # to find the dir associated with a specific failing test. + "--setup-plugins-only", + action="store_true", + help="Build full set of test dev env with test plugins, but don't run any tests." + ) @dataclass class CLIOptions: - include_core_tests: bool=False + run_core_tests: bool=False + setup_plugins_only: bool=False @pytest.fixture(scope="session") def cli_options(request): return CLIOptions( - include_core_tests=request.config.getoption("--include-core-tests"), + run_core_tests=request.config.getoption("--run-core-tests"), + setup_plugins_only=request.config.getoption("--setup-plugins-only"), ) + + +# --- Fixtures --- + +@pytest.fixture(scope="module") +def get_dev_env(tmp_path_factory, cli_options): + """Set up an env where plugins can be generated and tested within django-simple-deploy. + + - Set up a temp dir. + - Install dev env for django-simple-deploy. + - We can generate plugins, with this temp dir as target location. + - Then install newly-generated plugins to dsd dev env, and run tests from dsd. + """ + # Make the temp directory for the dsd development env. + tmp_path = tmp_path_factory.mktemp("e2e_new_plugin_test") + print(f"\nBuilding e2e test env at: {tmp_path.as_posix()}") + + # Clone django-simple-deploy in temp env. + path_dsd = tmp_path / "django-simple-deploy" + cmd = f"git clone https://github.com/django-simple-deploy/django-simple-deploy.git {path_dsd.as_posix()} --depth 1" + cmd_parts = shlex.split(cmd) + subprocess.run(cmd_parts) + + # Build a venv in the django-simple-deploy temp dir. + venv_dir = path_dsd / ".venv" + cmd = f"uv venv {venv_dir}" + cmd_parts = shlex.split(cmd) + subprocess.run(cmd_parts) + + # Make an editable install of django-simple-deploy in its environment. + path_to_python = venv_dir / "bin" / "python" + cmd = f'uv pip install --python {path_to_python} -e "{path_dsd.as_posix()}[dev]"' + cmd_parts = shlex.split(cmd) + subprocess.run(cmd_parts) + + if not cli_options.setup_plugins_only: + # Run core tests without a plugin installed. + e2e_utils.run_dsd_core_tests(path_dsd, path_to_python, cli_options) + + return tmp_path, path_to_python, path_dsd + +@pytest.fixture(scope="function", autouse=True) +def clear_plugins(get_dev_env): + """Remove any plugins from dev env. + + Most tests install a plugin to the dev env. Remove each plugin after its test runs. + """ + dev_env_dir, path_to_python, path_dsd = get_dev_env + + # Yield to let test function run, then clear any plugins that were installed. + yield + + cmd = f"uv pip list --python {path_to_python} --format=json" + cmd_parts = shlex.split(cmd) + package_dicts_str = subprocess.run(cmd_parts, capture_output=True).stdout + package_dicts = json.loads(package_dicts_str) + package_names = [pd["name"] for pd in package_dicts if pd["name"].startswith("dsd-")] + + for pkg_name in package_names: + cmd = f"uv pip uninstall {pkg_name} --python {path_to_python}" + cmd_parts = shlex.split(cmd) + subprocess.run(cmd_parts) \ No newline at end of file diff --git a/tests/e2e_tests/test_basic_plugin.py b/tests/e2e_tests/test_basic_plugin.py index a147b4f..e50b7a3 100644 --- a/tests/e2e_tests/test_basic_plugin.py +++ b/tests/e2e_tests/test_basic_plugin.py @@ -15,7 +15,6 @@ """ from argparse import Namespace -from pathlib import Path import subprocess import shlex @@ -23,20 +22,17 @@ from utils.plugin_config import PluginConfig from tests.e2e_tests.utils import e2e_utils -import generate_plugin as gp -@pytest.mark.skipif(not e2e_utils.uv_available(), reason="uv must be installed in order to run e2e tests.") -def test_new_plugin_e2e(tmp_path_factory, cli_options): - # Flag to temporarily disable running dsd and plugin tests. This is helpful when - # examining this environment. Otherwise pytest runs so many tests, this one can't - # easily be found. This is not a CLI arg, because it only needs to be modified when you're - # working on this test, not when you're just running it. - run_core_plugin_tests = True +# Skip these tests if uv is not available. +pytestmark = pytest.mark.skipif( + not e2e_utils.uv_available(), reason="uv must be installed in order to run e2e tests." +) - # Build a new plugin in temp dir. - tmp_path = tmp_path_factory.mktemp("e2e_new_plugin_test") - print(f"\nBuilding e2e test env at: {tmp_path.as_posix()}") + +def test_simple_plugin(get_dev_env, cli_options): + """Test a simple plugin config.""" + dev_env_dir, path_to_python, path_dsd = get_dev_env plugin_config = PluginConfig( platform_name = "NewFly", @@ -44,73 +40,37 @@ def test_new_plugin_e2e(tmp_path_factory, cli_options): support_automate_all = True, license_name = "eric", ) + e2e_utils.generate_plugin(get_dev_env, plugin_config) - args = Namespace(target_dir=tmp_path) - gp.generate_plugin(plugin_config, args) - - # Make sure we have the correct path to the new plugin. - path_new_plugin = tmp_path / "dsd-newfly" - assert path_new_plugin.exists() - - # Clone django-simple-deploy in temp env. - path_dsd = tmp_path / "django-simple-deploy" - cmd = f"git clone https://github.com/django-simple-deploy/django-simple-deploy.git {path_dsd.as_posix()} --depth 1" - cmd_parts = shlex.split(cmd) - subprocess.run(cmd_parts) - - # Build a venv in the django-simple-deploy temp dir. - venv_dir = path_dsd / ".venv" - cmd = f"uv venv {venv_dir}" - cmd_parts = shlex.split(cmd) - subprocess.run(cmd_parts) - - # Make an editable install of django-simple-deploy in its environment. - path_to_python = venv_dir / "bin" / "python" - cmd = f'uv pip install --python {path_to_python} -e "{path_dsd.as_posix()}[dev]"' - cmd_parts = shlex.split(cmd) - subprocess.run(cmd_parts) - - if run_core_plugin_tests: - # Run core tests without a plugin installed. - e2e_utils.run_core_tests(path_dsd, path_to_python, cli_options) - - # Install plugin editable to django-simple-deploy env. - cmd = f'uv pip install --python {path_to_python} -e "{path_new_plugin.as_posix()}[dev]"' - cmd_parts = shlex.split(cmd) - subprocess.run(cmd_parts) - - if run_core_plugin_tests: + if not cli_options.setup_plugins_only: e2e_utils.run_core_plugin_tests(path_dsd, plugin_config, cli_options) +def test_plugin_single_space_platform_name(get_dev_env, cli_options): + """Test a plugin for a platform with a space in the name.""" + dev_env_dir, path_to_python, path_dsd = get_dev_env - # Remove plugin, and test another one. - # This is much faster than having a completely separate test. We lose some test - # independence, but the speedup is worthwhile. - - # Uninstall previous plugin. - cmd = f'uv pip uninstall --python {path_to_python} dsd-newfly' - cmd_parts = shlex.split(cmd) - subprocess.run(cmd_parts) - - # Build "New Platform" plugin. plugin_config = PluginConfig( platform_name = "New Platform", pkg_name = "dsd-newplatform", support_automate_all = True, license_name = "eric", ) + e2e_utils.generate_plugin(get_dev_env, plugin_config) - args = Namespace(target_dir=tmp_path) - gp.generate_plugin(plugin_config, args) + if not cli_options.setup_plugins_only: + e2e_utils.run_core_plugin_tests(path_dsd, plugin_config, cli_options) - # Make sure we have the correct path to the new plugin. - path_new_plugin = tmp_path / "dsd-newplatform" - assert path_new_plugin.exists() +def test_plugin_different_plugin_platform_name(get_dev_env, cli_options): + """Test a plugin where platform and plugin names differ significantly.""" + dev_env_dir, path_to_python, path_dsd = get_dev_env - # Install plugin editable to django-simple-deploy env. - cmd = f'uv pip install --python {path_to_python} -e "{path_new_plugin.as_posix()}[dev]"' - cmd_parts = shlex.split(cmd) - subprocess.run(cmd_parts) + plugin_config = PluginConfig( + platform_name = "MyNewPlatform", + pkg_name = "dsd-my-plugin", + support_automate_all = True, + license_name = "eric", + ) + e2e_utils.generate_plugin(get_dev_env, plugin_config) - if run_core_plugin_tests: - e2e_utils.run_core_plugin_tests(path_dsd, plugin_config, cli_options) + if not cli_options.setup_plugins_only: + e2e_utils.run_core_plugin_tests(path_dsd, plugin_config, cli_options) \ No newline at end of file diff --git a/tests/e2e_tests/utils/e2e_utils.py b/tests/e2e_tests/utils/e2e_utils.py index e997a93..9bad2c5 100644 --- a/tests/e2e_tests/utils/e2e_utils.py +++ b/tests/e2e_tests/utils/e2e_utils.py @@ -1,10 +1,16 @@ """Utility functions for e2e tests.""" + +from argparse import Namespace import shlex import subprocess import re -from utils.generator_utils import get_platform_name_lower +import pytest + +import generate_plugin as gp +from utils.plugin_config import PluginConfig +from utils.generator_utils import _get_platform_name_lower def uv_available(): @@ -18,8 +24,25 @@ def uv_available(): # This is the exception raised on macOS when the command uv is unavailable. return False +def generate_plugin(dev_env, plugin_config): + """Generate a new plugin, and install it to the django-simple-deploy dev env. + """ + dev_env_dir, path_to_python, path_dsd = dev_env + + args = Namespace(target_dir=dev_env_dir) + gp.generate_plugin(plugin_config, args) + + # Make sure we have the correct path to the new plugin. + path_new_plugin = dev_env_dir / plugin_config.pkg_name + assert path_new_plugin.exists() + + # Install plugin editable to django-simple-deploy env. + cmd = f'uv pip install --python {path_to_python} -e "{path_new_plugin.as_posix()}[dev]"' + cmd_parts = shlex.split(cmd) + subprocess.run(cmd_parts) + -def run_core_tests(path_dsd, path_to_python, cli_options): +def run_dsd_core_tests(path_dsd, path_to_python, cli_options): """Run django-simple-deploy's test suite with no plugin installed.""" tests_dir = path_dsd / "tests" cmd = f"{path_to_python} -m pytest {tests_dir.as_posix()}" @@ -33,7 +56,7 @@ def run_core_tests(path_dsd, path_to_python, cli_options): def run_core_plugin_tests(path_dsd, plugin_config, cli_options): """Run django-simple-deploy's test suite with a plugin installed.""" tests_dir = path_dsd / "tests" - platform_name_lower = get_platform_name_lower(plugin_config.platform_name) + platform_name_lower = _get_platform_name_lower(plugin_config.platform_name) cmd = get_core_plugin_test_cmd(path_dsd, cli_options, platform_name_lower) output = subprocess.run(cmd, capture_output=True,shell=True) @@ -47,7 +70,7 @@ def get_core_plugin_test_cmd(path_dsd, cli_options, platform_name_lower): """Get the command for running django-simple-deploy tests after a new plugin has been installed.""" test_filename = f"test_{platform_name_lower}_config.py" - if cli_options.include_core_tests: + if cli_options.run_core_tests: # Run full set of core django-simple-deploy tests, and plugin integration tests. cmd = f"cd {path_dsd.as_posix()} && source .venv/bin/activate && pytest" else: @@ -69,7 +92,7 @@ def check_core_plugin_tests(stdout, cli_options, core_only=False): if core_only: # Core tests, no plugin installed. assert passed >= 31 - elif cli_options.include_core_tests: + elif cli_options.run_core_tests: # Core tests, and plugin's integrationtests. assert passed >= 65 else: diff --git a/tests/integration_tests/test_generator.py b/tests/integration_tests/test_generator.py index d3d7121..751221f 100644 --- a/tests/integration_tests/test_generator.py +++ b/tests/integration_tests/test_generator.py @@ -27,6 +27,7 @@ def test_no_spaces_anywhere(tmp_path_factory): path_ref_dir = Path(__file__).parent / "reference_files" / "dsd-newfly-no-space" path_test_plugin = tmp_path / "dsd-newfly" + assert path_test_plugin.exists() dc = dircmp(path_test_plugin, path_ref_dir, ignore=[".DS_Store", "__pycache__"]) assert_dirs_match(dc) @@ -51,6 +52,24 @@ def test_single_space_platform_name(tmp_path_factory): dc = dircmp(path_test_plugin, path_ref_dir, ignore=[".DS_Store", "__pycache__"]) assert_dirs_match(dc) +def test_reject_not_start_dsd_dash(tmp_path_factory): + """Test that a package name not starting with dsd- is rejected.""" + tmp_path = tmp_path_factory.mktemp("sample_plugin_no_space") + print(f"\nWriting plugin to: {tmp_path.as_posix()}") + + plugin_config = PluginConfig( + platform_name = "NewFly", + pkg_name = "newfly-deployer", + support_automate_all = True, + license_name = "eric", + ) + + args = Namespace(target_dir=tmp_path) + + with pytest.raises(AssertionError): + gp.generate_plugin(plugin_config, args) + + # --- Helper functions --- diff --git a/tests/unit_tests/test_generator_utils.py b/tests/unit_tests/test_generator_utils.py index a4aad04..e35475b 100644 --- a/tests/unit_tests/test_generator_utils.py +++ b/tests/unit_tests/test_generator_utils.py @@ -4,7 +4,7 @@ def test_get_platform_name_lower(): name = "NewFly" - assert gu.get_platform_name_lower(name) == "newfly" + assert gu._get_platform_name_lower(name) == "newfly" name = "New Fly" - assert gu.get_platform_name_lower(name) == "newfly" \ No newline at end of file + assert gu._get_platform_name_lower(name) == "newfly" \ No newline at end of file diff --git a/utils/generator_utils.py b/utils/generator_utils.py index 5f1c390..c872165 100644 --- a/utils/generator_utils.py +++ b/utils/generator_utils.py @@ -90,7 +90,6 @@ def validate_target_dir(args, plugin_config, path_root): sys.exit(msg) else: # Get permission to write to target directory. - # path_root = Path(__file__).parent path_root_new = path_root.parent / plugin_config.pkg_name if path_root_new.exists(): @@ -120,9 +119,12 @@ def build_new_plugin(args, plugin_config): # Make sure it's okay to write to the target directory. path_root_new = validate_target_dir(args, plugin_config, path_root) - platform_name_lower = get_platform_name_lower(plugin_config.platform_name) + platform_name_lower = _get_platform_name_lower(plugin_config.platform_name) + main_dir_name = _get_main_dir_name(plugin_config.pkg_name) + replacements = _get_replacements(plugin_config, platform_name_lower) + # Make new plugin dir, and required directory structure. print(f"\nMaking new directory: {path_root_new.as_posix()}") path_root_new.mkdir() @@ -132,7 +134,7 @@ def build_new_plugin(args, plugin_config): # Using mkdir(parents=True), only need to make most deeply nested dirs. new_dirs = [ "developer_resources", - f"dsd_{platform_name_lower}/templates", + f"{main_dir_name}/templates", "tests/integration_tests/reference_files", "tests/e2e_tests", ] @@ -149,7 +151,7 @@ def build_new_plugin(args, plugin_config): target_files = [ ".gitignore", "developer_resources/README.md", - "dsd_platformname/__init__.py", + "plugin_pkg_name/__init__.py", "tests/e2e_tests/__init__.py", "tests/integration_tests/reference_files/.gitignore", "tests/integration_tests/reference_files/Pipfile", @@ -161,7 +163,7 @@ def build_new_plugin(args, plugin_config): for target_file in target_files: print(f" Copying file: {target_file}") path_src = path_root / "plugin_template" / target_file - target_file_new = target_file.replace("dsd_platformname", f"dsd_{platform_name_lower}") + target_file_new = target_file.replace("plugin_pkg_name", main_dir_name) path_dest = path_root_new / target_file_new shutil.copy(path_src, path_dest) @@ -178,12 +180,12 @@ def build_new_plugin(args, plugin_config): "README.md", "CHANGELOG.md", "LICENSE", - "dsd_platformname/platform_deployer.py", - "dsd_platformname/deploy.py", - "dsd_platformname/plugin_config.py", - "dsd_platformname/templates/dockerfile_example", - "dsd_platformname/templates/settings.py", - "dsd_platformname/deploy_messages.py", + "plugin_pkg_name/platform_deployer.py", + "plugin_pkg_name/deploy.py", + "plugin_pkg_name/plugin_config.py", + "plugin_pkg_name/templates/dockerfile_example", + "plugin_pkg_name/templates/settings.py", + "plugin_pkg_name/deploy_messages.py", ] print("\nCustomizing files...") @@ -196,7 +198,8 @@ def build_new_plugin(args, plugin_config): for k, v in replacements.items(): contents = contents.replace(k, v) - target_file_new = target_file.replace("platformname", f"{platform_name_lower}") + target_file_new = target_file.replace("plugin_pkg_name", main_dir_name) + target_file_new = target_file_new.replace("test_platformname_config.py", f"test_{platform_name_lower}_config.py") path_new = path_root_new / target_file_new path_new.write_text(contents) @@ -209,7 +212,7 @@ def build_new_plugin(args, plugin_config): # Remove automate_all support if needed. if not plugin_config.support_automate_all: print("Commenting out support for --automate-all...") - path = path_root_new / f"dsd_{platform_name_lower}" / "deploy_messages.py" + path = path_root_new / main_dir_name / "deploy_messages.py" lines = path.read_text().splitlines() new_lines = [] for line_num, line in enumerate(lines): @@ -234,12 +237,17 @@ def show_summary(): msg += "\nshould pass." print(msg) -def get_platform_name_lower(platform_name): + +# --- Helper functions --- + +def _get_platform_name_lower(platform_name): """Return a lowercase version of the platform name.""" return platform_name.lower().replace("-", "").replace("_", "").replace(".", "").replace(" ", "") - -# --- Helper functions --- +def _get_main_dir_name(pkg_name): + """Return name of main dir. For dsd-new-platform, that's dsd_new_platform.""" + pkg_name_lower = pkg_name.lower().replace("-", "_") + return pkg_name_lower def _get_replacements(plugin_config, platform_name_lower): """Get substitions for...""" @@ -253,4 +261,3 @@ def _get_replacements(plugin_config, platform_name_lower): } return replacements - diff --git a/utils/plugin_config.py b/utils/plugin_config.py index baf6b10..8ee579c 100644 --- a/utils/plugin_config.py +++ b/utils/plugin_config.py @@ -15,4 +15,4 @@ class PluginConfig: def validate(self): """Validate the plugin config.""" assert self.platform_name - assert self.pkg_name \ No newline at end of file + assert self.pkg_name.startswith("dsd-") \ No newline at end of file