-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue/3110 modules v2 moduletool commands #3473
Changes from 7 commits
b60dff5
2674cc7
29d4ebd
4442790
c67b9f6
e77ffc8
6e66b68
6a1a407
b97b196
a3cbe11
f9b3d56
9aa1b87
015174e
9c3a55f
c260154
b741c78
942d659
2ffbdcf
bb0df92
64d645a
2af1531
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
description: Reviewed all moduletool commands for v2 compatibility | ||
change-type: major | ||
sections: | ||
deprecation-note: "The `inmanta module list -r` command has been deprecated in favor of `inmanta project freeze`" | ||
destination-branches: | ||
- master |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,7 +30,7 @@ | |
from argparse import ArgumentParser | ||
from collections import OrderedDict | ||
from configparser import ConfigParser | ||
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Pattern, Set | ||
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Pattern, Sequence, Set | ||
|
||
import texttable | ||
import yaml | ||
|
@@ -387,6 +387,9 @@ def modules_parser_config(cls, parser: ArgumentParser) -> None: | |
|
||
create = subparser.add_parser("create", help="Create a new module") | ||
create.add_argument("name", help="The name of the module") | ||
create.add_argument( | ||
"--v1", dest="v1", help="Create a v1 module. By default a v2 module is created.", action="store_true" | ||
) | ||
|
||
freeze = subparser.add_parser("freeze", help="Set all version numbers in project.yml") | ||
freeze.add_argument( | ||
|
@@ -528,7 +531,20 @@ def get_modules(self, module: Optional[str] = None) -> List[Module]: | |
else: | ||
return self.get_project(load=True).sorted_modules() | ||
|
||
def create(self, name: str) -> None: | ||
def create(self, name: str, v1: bool) -> None: | ||
if v1: | ||
self._create_v1(name) | ||
else: | ||
module_dir: str = name | ||
if os.path.exists(module_dir): | ||
raise Exception(f"Directory {module_dir} already exists") | ||
cookiecutter( | ||
"https://github.com/inmanta/inmanta-module-template.git", | ||
checkout="v2", | ||
extra_context={"module_name": name}, | ||
) | ||
|
||
def _create_v1(self, name: str) -> None: | ||
project = self.get_project() | ||
mod_root = project.modulepath[-1] | ||
LOGGER.info("Creating new module %s in %s", name, mod_root) | ||
|
@@ -568,6 +584,9 @@ def create(self, name: str) -> None: | |
|
||
def do(self, command: str, module: str) -> None: | ||
for mod in self.get_modules(module): | ||
if not isinstance(mod, ModuleV1): | ||
LOGGER.warning("Skipping module %s: v2 modules do not support this operation.") | ||
continue | ||
try: | ||
mod.execute_command(command) | ||
except Exception as e: | ||
|
@@ -578,48 +597,55 @@ def list(self, requires: bool = False) -> None: | |
List all modules in a table | ||
""" | ||
table = [] | ||
name_length = 10 | ||
version_length = 10 | ||
|
||
project = Project.get() | ||
project.get_complete_ast() | ||
|
||
names = sorted(project.modules.keys()) | ||
specs = project.collect_imported_requirements() | ||
names: Sequence[str] = sorted(project.modules.keys()) | ||
specs: Dict[str, List[InmantaModuleRequirement]] = project.collect_imported_requirements() | ||
for name in names: | ||
|
||
name_length = max(len(name), name_length) | ||
mod = Project.get().modules[name] | ||
mod: Module = Project.get().modules[name] | ||
version = str(mod.version) | ||
if name not in specs: | ||
specs[name] = [] | ||
|
||
try: | ||
if project.install_mode == InstallMode.master: | ||
reqv = "master" | ||
else: | ||
release_only = project.install_mode == InstallMode.release | ||
versions = ModuleV1.get_suitable_version_for(name, specs[name], mod._path, release_only=release_only) | ||
if versions is None: | ||
reqv = "None" | ||
else: | ||
reqv = str(versions) | ||
except Exception: | ||
LOGGER.exception("Problem getting version for module %s" % name) | ||
reqv = "ERROR" | ||
generation: str = str(mod.GENERATION.name) | ||
|
||
version_length = max(len(version), len(reqv), version_length) | ||
reqv: str | ||
matches: bool | ||
editable: bool | ||
if isinstance(mod, ModuleV1): | ||
try: | ||
if project.install_mode == InstallMode.master: | ||
reqv = "master" | ||
else: | ||
release_only = project.install_mode == InstallMode.release | ||
versions = ModuleV1.get_suitable_version_for(name, specs[name], mod._path, release_only=release_only) | ||
if versions is None: | ||
reqv = "None" | ||
else: | ||
reqv = str(versions) | ||
except Exception: | ||
LOGGER.exception("Problem getting version for module %s" % name) | ||
reqv = "ERROR" | ||
matches = version == reqv | ||
editable = True | ||
else: | ||
reqv = ",".join(req.version_spec_str() for req in specs[name] if req.specs) or "*" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The usage of
Isn't this strange? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree somewhat strange, though both Wouter and I are of the opinion that the v2 format is an improvement. I opted to stick with the stricter approach for v1 because it needs to take the compiler version into account, making it more complex than just the version specs. We could clean that up as well but I'm not sure it's worth the effort for v1. |
||
matches = all(version in req for req in specs[name]) | ||
editable = mod.is_editable() | ||
|
||
table.append((name, version, reqv, version == reqv)) | ||
table.append((name, generation, editable, version, reqv, matches)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
|
||
if requires: | ||
print("requires:") | ||
for name, version, reqv, _ in table: | ||
LOGGER.warning("The `inmanta module list -r` command has been deprecated.") | ||
for name, _, _, version, _, _ in table: | ||
print(" - %s==%s" % (name, version)) | ||
else: | ||
t = texttable.Texttable() | ||
t.set_deco(texttable.Texttable.HEADER | texttable.Texttable.BORDER | texttable.Texttable.VLINES) | ||
t.header(("Name", "Installed version", "Expected in project", "Matches")) | ||
t.header(("Name", "Generation", "Editable", "Installed version", "Expected in project", "Matches")) | ||
for row in table: | ||
t.add_row(row) | ||
print(t.draw()) | ||
|
@@ -736,13 +762,19 @@ def status(self, module: Optional[str] = None) -> None: | |
Run a git status on all modules and report | ||
""" | ||
for mod in self.get_modules(module): | ||
if not isinstance(mod, ModuleV1): | ||
LOGGER.warning("Skipping module %s: v2 modules do not support this operation.", mod.name) | ||
continue | ||
mod.status() | ||
|
||
def push(self, module: Optional[str] = None) -> None: | ||
""" | ||
Push all modules | ||
""" | ||
for mod in self.get_modules(module): | ||
if not isinstance(mod, ModuleV1): | ||
LOGGER.warning("Skipping module %s: v2 modules do not support this operation.", mod.name) | ||
continue | ||
mod.push() | ||
|
||
def verify(self) -> None: | ||
|
@@ -768,6 +800,8 @@ def commit( | |
""" | ||
# find module | ||
module = self.get_module(module) | ||
if not isinstance(module, ModuleV1): | ||
raise CLIException(f"{module.name} is a v2 module and does not support this operation.", exitcode=1) | ||
# get version | ||
old_version = parse_version(str(module.version)) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we perform a checkout from master? The intention is to have the V2 template on the master branch after the release, no? It looks like no
v2
branch exist at the moment. Was this functionality tested?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I expect we will need the V1 a little longer until we have set up the proper distribution channels for v2 modules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd discussed both this and #3473 (comment) with Wouter yesterday but I'd forgotten to share the conclusions. The main reason we need to keep v1 on master for now is that new v2 modules require a v2 std, which we haven't decided how to distribute yet. The
v2
branch does not exist yet but this is part of inmanta/inmanta-module-template#13.