Skip to content

Commit

Permalink
Simplify tool and env matching logic by using globs
Browse files Browse the repository at this point in the history
  • Loading branch information
neoxelox committed Aug 24, 2022
1 parent 52e07ba commit d9f4fe0
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 134 deletions.
5 changes: 3 additions & 2 deletions superinvoke/collections/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,15 @@ def switch(context, environment):

if not new_env:
context.fail(f"{environment} is not a valid environment")
new_env = new_env[0]

if new_env == old_env:
context.info(f"{environment} is already the current environment")
context.info(f"{new_env} is already the current environment")
return

context.create(utils.path(constants.Paths.ENV), data=[new_env], dir=False)

if new_env != __ENVS__.Current:
context.fail(f"Cannot switch to environment {environment}")
context.fail(f"Cannot switch to environment {new_env}")

context.print(f"Switched to environment [green3]{new_env}[/green3] from {old_env}")
151 changes: 37 additions & 114 deletions superinvoke/collections/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ def run(context, args):
"""Execute an available tool."""
from ..main import __TOOLS__

tool, args = utils.next_arg(args)
tool = __TOOLS__.ByName(tool)
tool_name, args = utils.next_arg(args)
tool = __TOOLS__.ByName(tool_name)

if not tool:
context.fail("Unknown tool")
context.fail(f"{tool_name} is not a valid tool")
tool = tool[0]

install(context, include=tool.name, exclude="", yes=False)

Expand All @@ -51,8 +52,8 @@ def run(context, args):

@task(
help={
"include": "Tags, all or tool names that will be installed. Example: ops,golang-migrate,all...",
"exclude": "Tags, all or tool names that will be excluded. Example: golangci-lint,ci...",
"include": "Tags, globs or tool names that will be installed. Example: ops,golang-migrate,*...",
"exclude": "Tags, globs or tool names that will be excluded. Example: golangci-lint,ci,dev*...",
"yes": "Automatically say yes to all prompts.",
}
)
Expand All @@ -61,68 +62,29 @@ def install(context, include, exclude="", yes=False):
from ..main import __TOOLS__

include = {tool for tool in include.split(",") if tool and tool != ","}

include_tools = set()
for name_or_tag in include:
if name_or_tag == "all":
for tool in __TOOLS__.All:
if tool._managed:
if not context.has(tool, version=tool.version):
include_tools.add(tool)
else:
context.info(f"{tool.name} already installed")
else:
context.info(f"{tool.name} not managed")
continue

tool = __TOOLS__.ByName(name_or_tag)
if tool:
if tool._managed:
if not context.has(tool, version=tool.version):
include_tools.add(tool)
else:
context.info(f"{tool.name} already installed")
continue
else:
context.info(f"{tool.name} not managed")

tools = __TOOLS__.ByTag(name_or_tag)
if tools:
for tool in tools:
if tool._managed:
if not context.has(tool, version=tool.version):
include_tools.add(tool)
else:
context.info(f"{tool.name} already installed")
else:
context.info(f"{tool.name} not managed")
continue

context.warn(f"Ignoring {name_or_tag}")
include_tools.update(__TOOLS__.ByName(name_or_tag))
include_tools.update(__TOOLS__.ByTag(name_or_tag))

exclude = {tool for tool in exclude.split(",") if tool and tool != ","}

exclude_tools = set()
for name_or_tag in exclude:
if name_or_tag == "all":
exclude_tools.update(__TOOLS__.All)
continue
exclude_tools.update(__TOOLS__.ByName(name_or_tag))
exclude_tools.update(__TOOLS__.ByTag(name_or_tag))

tool = __TOOLS__.ByName(name_or_tag)
if tool:
exclude_tools.add(tool)
continue

tools = __TOOLS__.ByTag(name_or_tag)
if tools:
exclude_tools.update(tools)
continue

context.warn(f"Ignoring {name_or_tag}")

tools = include_tools - exclude_tools
tools = set()
for tool in include_tools - exclude_tools:
if tool._managed:
if not context.has(tool, version=tool.version):
tools.add(tool)
else:
context.info(f"{tool.name} already installed")
else:
context.info(f"{tool.name} not managed")

if not tools:
context.warn("No tools matched")
return

context.info(f"Tool(s) {', '.join([tool.name for tool in tools])} will be [bold green3]installed[/bold green3]")
Expand Down Expand Up @@ -171,8 +133,8 @@ def install(context, include, exclude="", yes=False):

@task(
help={
"include": "Tags, all or tool names that will be uninstalled. Example: ops,golang-migrate,all...",
"exclude": "Tags, all or tool names that will be excluded. Example: golangci-lint,ci...",
"include": "Tags, globs or tool names that will be uninstalled. Example: ops,golang-migrate,*...",
"exclude": "Tags, globs or tool names that will be excluded. Example: golangci-lint,ci,dev*...",
"yes": "Automatically say yes to all prompts.",
}
)
Expand All @@ -181,68 +143,29 @@ def remove(context, include, exclude="", yes=False):
from ..main import __TOOLS__

include = {tool for tool in include.split(",") if tool and tool != ","}

include_tools = set()
for name_or_tag in include:
if name_or_tag == "all":
for tool in __TOOLS__.All:
if tool._managed:
if context.has(tool, version=tool.version):
include_tools.add(tool)
else:
context.info(f"{tool.name} not installed")
else:
context.info(f"{tool.name} not managed")
continue

tool = __TOOLS__.ByName(name_or_tag)
if tool:
if tool._managed:
if context.has(tool, version=tool.version):
include_tools.add(tool)
else:
context.info(f"{tool.name} not installed")
else:
context.info(f"{tool.name} not managed")
continue

tools = __TOOLS__.ByTag(name_or_tag)
if tools:
for tool in tools:
if tool._managed:
if context.has(tool, version=tool.version):
include_tools.add(tool)
else:
context.info(f"{tool.name} not installed")
else:
context.info(f"{tool.name} not managed")
continue

context.warn(f"Ignoring {name_or_tag}")
include_tools.update(__TOOLS__.ByName(name_or_tag))
include_tools.update(__TOOLS__.ByTag(name_or_tag))

exclude = {tool for tool in exclude.split(",") if tool and tool != ","}

exclude_tools = set()
for name_or_tag in exclude:
if name_or_tag == "all":
exclude_tools.update(__TOOLS__.All)
continue

tool = __TOOLS__.ByName(name_or_tag)
if tool:
exclude_tools.add(tool)
continue

tools = __TOOLS__.ByTag(name_or_tag)
if tools:
exclude_tools.update(tools)
continue

context.warn(f"Ignoring {name_or_tag}")

tools = include_tools - exclude_tools
exclude_tools.update(__TOOLS__.ByName(name_or_tag))
exclude_tools.update(__TOOLS__.ByTag(name_or_tag))

tools = set()
for tool in include_tools - exclude_tools:
if tool._managed:
if context.has(tool, version=tool.version):
tools.add(tool)
else:
context.info(f"{tool.name} not installed")
else:
context.info(f"{tool.name} not managed")

if not tools:
context.warn("No tools matched")
return

context.info(f"Tool(s) {', '.join([tool.name for tool in tools])} will be [bold red1]uninstalled[/bold red1]")
Expand Down
2 changes: 1 addition & 1 deletion superinvoke/objects/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
class Tags(utils.StrEnum):
@utils.classproperty
def ALL(cls):
return "all"
return "*"
16 changes: 7 additions & 9 deletions superinvoke/objects/env.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import fnmatch
from typing import Any, Callable, List, Optional

from .. import constants, utils
Expand Down Expand Up @@ -48,21 +49,18 @@ def All(cls) -> List[Env]:
@utils.classproperty
def Current(cls) -> Optional[Env]:
if utils.exists(utils.path(constants.Paths.ENV)) == "file":
return cls.ByName(utils.read(utils.path(constants.Paths.ENV))[0])
env = cls.ByName(utils.read(utils.path(constants.Paths.ENV))[0])
return env[0] if env else None

if hasattr(cls, "Default") and cls.Default is not None:
return cls.Default(cls)

return None

@classmethod
def ByTag(cls, tag) -> List[Env]:
return [env for env in cls.All if tag in env.tags or Tags.ALL in env.tags]
def ByTag(cls, tag: str) -> List[Env]:
return [env for env in cls.All if fnmatch.filter(env.tags, tag) or Tags.ALL in env.tags]

@classmethod
def ByName(cls, name) -> Optional[Env]:
for env in cls.All:
if name == env.name:
return env

return None
def ByName(cls, name: str) -> List[Env]:
return [env for env in cls.All if fnmatch.filter([env.name], name)]
13 changes: 5 additions & 8 deletions superinvoke/objects/tool.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import fnmatch
from typing import List, Optional

from .. import constants, utils
Expand Down Expand Up @@ -72,13 +73,9 @@ def All(cls) -> List[Tool]:
return all

@classmethod
def ByTag(cls, tag) -> List[Tool]:
return [tool for tool in cls.All if tag in tool.tags or Tags.ALL in tool.tags]
def ByTag(cls, tag: str) -> List[Tool]:
return [tool for tool in cls.All if fnmatch.filter(tool.tags, tag) or Tags.ALL in tool.tags]

@classmethod
def ByName(cls, name) -> Optional[Tool]:
for tool in cls.All:
if name == tool.name:
return tool

return None
def ByName(cls, name: str) -> List[Tool]:
return [tool for tool in cls.All if fnmatch.filter([tool.name], name)]

0 comments on commit d9f4fe0

Please sign in to comment.