Skip to content

Commit b379dee

Browse files
authored
Merge pull request #3 from composer-version-manager/hook-cmd-template
Hook command scaffolding
2 parents bdcf579 + 1fe4c66 commit b379dee

File tree

13 files changed

+173
-31
lines changed

13 files changed

+173
-31
lines changed

cvm/cli.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,18 @@
33
import sys
44
from typing import Optional
55

6-
from cvm.helpers.cli import colored_fore
76
from argparse_color_formatter import ColorRawTextHelpFormatter
87
from colorama import Fore
98

109
from cvm.commands.command import Command
11-
from cvm.commands.use_command import UseCommand
10+
from cvm.commands.hook_command import HookCommand
1211
from cvm.commands.install_command import InstallCommand
13-
from cvm.commands.scan_command import ScanCommand
1412
from cvm.commands.list_command import ListCommand
15-
13+
from cvm.commands.scan_command import ScanCommand
14+
from cvm.commands.use_command import UseCommand
15+
from cvm.helpers.cli import colored_fore
1616
from cvm.services.cache_service import CacheService
1717

18-
1918
COMMAND_NAME = 'cvm'
2019
COMMAND_DESC = 'Composer Version Manager\n' + colored_fore(Fore.WHITE, 'Author: @game-of-morgan (Morgan Wowk)')
2120
COMMAND_EPILOG = 'https://github.com/game-of-morgan/cvm\n\nSupport this project by giving it a GitHub star ⭐️'
@@ -24,7 +23,8 @@
2423
UseCommand.NAME: UseCommand,
2524
InstallCommand.NAME: InstallCommand,
2625
ScanCommand.NAME: ScanCommand,
27-
ListCommand.NAME: ListCommand
26+
ListCommand.NAME: ListCommand,
27+
HookCommand.NAME: HookCommand
2828
}
2929

3030

cvm/commands/hook_command.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from argparse import Action, Namespace
2+
3+
from cvm.commands.command import Command
4+
from cvm.services.shell_service import ShellService
5+
6+
7+
class HookCommand(Command):
8+
NAME = 'hook'
9+
DESCRIPTION = 'Hook cvm to a shell.'
10+
11+
def exec(self, args: Namespace):
12+
target = args.shell[0]
13+
14+
shell_service = ShellService()
15+
shell = shell_service.get_shell_by_name(target)
16+
17+
hook = shell.get_hook()
18+
19+
print(hook)
20+
21+
@staticmethod
22+
def define_signature(parser: Action):
23+
hook_parser = parser.add_parser(HookCommand.NAME, help=HookCommand.DESCRIPTION)
24+
hook_parser.add_argument(
25+
'shell',
26+
nargs=1,
27+
help='Shell name to hook onto.',
28+
metavar='{shell}'
29+
)

cvm/commands/list_command.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
from argparse import Action, Namespace
2-
from cvm.helpers.cli import green
3-
42

53
from cvm.commands.command import Command
4+
from cvm.services.cache_service import CacheService
65
from cvm.services.composer_service import ComposerService
76
from cvm.services.github_service import GitHubService
8-
from cvm.services.cache_service import CacheService
97

108

119
class ListCommand(Command):
@@ -23,7 +21,6 @@ def exec(self, args: Namespace):
2321
else:
2422
print(f"* {tag['name']}")
2523

26-
2724
@staticmethod
2825
def define_signature(parser: Action):
29-
use_parser = parser.add_parser(ListCommand.NAME, help=ListCommand.DESCRIPTION)
26+
parser.add_parser(ListCommand.NAME, help=ListCommand.DESCRIPTION)

cvm/commands/scan_command.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,36 @@
11
from argparse import Action, Namespace
22

33
from cvm.commands.command import Command
4+
from cvm.services.composer_service import ComposerService
5+
from cvm.services.config_service import ConfigService
6+
from cvm.services.github_service import GitHubService
47

58

69
class ScanCommand(Command):
710
NAME = 'scan'
811
DESCRIPTION = 'If present use .cvm_config from the current or specified directory.'
912

1013
def exec(self, args: Namespace):
11-
print("Scan command executed.")
12-
print(args)
14+
if not ConfigService.exists():
15+
return
16+
17+
data = ConfigService.read()
18+
if not ConfigService.validate(data):
19+
print("echo Invalid cvm config.")
20+
21+
github_service = GitHubService('composer', 'composer')
22+
composer_service = ComposerService(github_service)
23+
24+
install_path = composer_service.use_version(data['requires'])
25+
26+
print(f"export PATH=:{install_path}:$PATH; echo Updated path.")
1327

1428
@staticmethod
1529
def define_signature(parser: Action):
16-
parser.add_parser(ScanCommand.NAME, help=ScanCommand.DESCRIPTION)
30+
scan_parser = parser.add_parser(ScanCommand.NAME, help=ScanCommand.DESCRIPTION)
31+
scan_parser.add_argument(
32+
'shell',
33+
nargs=1,
34+
help='Shell name to cvm within.',
35+
metavar='{shell}'
36+
)

cvm/services/cache_service.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import os
21
import logging
2+
import os
33
import pathlib
44
import sys
5-
from pathlib import Path
65

76

87
class CacheService:
@@ -21,7 +20,7 @@ def boot_cache() -> None:
2120
CacheService.SETUP_DIR.mkdir(parents=True, exist_ok=True)
2221

2322
@staticmethod
24-
def get_cache_folder(folder: str) -> pathlib.Path:
23+
def make_cache_folder(folder: str) -> pathlib.Path:
2524
fpath = CacheService.CACHE_DIR / folder
2625
fpath.mkdir(parents=True, exist_ok=True)
2726
return fpath

cvm/services/composer_service.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import sys
1+
import logging
22
import pathlib
3-
import requests
43
import subprocess
4+
import sys
5+
6+
import requests
57

68
from cvm.services.cache_service import CacheService
79
from cvm.services.github_service import GitHubService
8-
import logging
910

1011

1112
class ComposerService:
@@ -39,7 +40,7 @@ def cached_version_exists(tag_name: str) -> bool:
3940
:return: Bool
4041
'''
4142

42-
cache_path = CacheService.CACHE_DIR / tag_name
43+
cache_path = CacheService.CACHE_DIR / tag_name / 'composer'
4344
return cache_path.exists()
4445

4546
def _get_setup_path(self) -> pathlib.Path:
@@ -56,24 +57,25 @@ def _get_setup_path(self) -> pathlib.Path:
5657
setup_path.write_bytes(r.content)
5758
return setup_path
5859

59-
def install_version(self, tag_name: str) -> bool:
60+
def install_version(self, tag_name: str, quiet=False) -> pathlib.Path:
6061
if not self.tag_exists(tag_name):
6162
logging.error("Tag {} does not exist.".format(tag_name))
6263
sys.exit(1)
6364

6465
setup_path = self._get_setup_path()
65-
cache_path = CacheService.get_cache_folder(tag_name)
66+
cache_path = CacheService.make_cache_folder(tag_name)
67+
68+
if ComposerService.cached_version_exists(tag_name):
69+
return cache_path
6670

6771
cmd = ['php', str(setup_path), f'--install-dir={str(cache_path)}', '--filename=composer', f'--version={tag_name}']
6872
result = subprocess.run(cmd, stdout=subprocess.PIPE, check=True)
69-
print(result.stdout.decode('utf-8'))
70-
71-
return True
73+
if not quiet:
74+
print(result.stdout.decode('utf-8'))
7275

73-
def use_version(self, tag_name: str, check_exists: bool = True) -> bool:
74-
if check_exists and not ComposerService.cached_version_exists(tag_name):
75-
return False
76+
return cache_path
7677

77-
# TODO: Use cached version if exists
78+
def use_version(self, tag_name: str) -> str:
79+
install_path = self.install_version(tag_name, quiet=True)
7880

79-
return True
81+
return str(install_path)

cvm/services/config_service.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import json
2+
import pathlib
3+
4+
5+
class ConfigService:
6+
FILENAME = '.cvm_config'
7+
CONFIG_INPUT = pathlib.Path(FILENAME)
8+
9+
@staticmethod
10+
def exists() -> bool:
11+
return ConfigService.CONFIG_INPUT.exists()
12+
13+
@staticmethod
14+
def read():
15+
return json.load(ConfigService.CONFIG_INPUT.open('r'))
16+
17+
@staticmethod
18+
def validate(data) -> bool:
19+
if 'requires' not in data:
20+
return False
21+
return True

cvm/services/shell_service.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import logging
2+
import sys
3+
from typing import Optional
4+
5+
from cvm.shells.shell import Shell
6+
from cvm.shells.shell_bash import ShellBash
7+
from cvm.shells.shell_zsh import ShellZsh
8+
9+
SHELLS = {
10+
ShellZsh.NAME: ShellZsh,
11+
ShellBash.NAME: ShellBash
12+
}
13+
14+
15+
class ShellService:
16+
@staticmethod
17+
def get_shell_by_name(name: str) -> Optional[Shell]:
18+
shell = SHELLS.get(name, None)
19+
if shell is None:
20+
logging.error("Shell {} not found".format(name))
21+
sys.exit(1)
22+
23+
return shell()

cvm/shells/__init__.py

Whitespace-only changes.

cvm/shells/shell.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from abc import ABC, abstractmethod
2+
3+
4+
class Shell(ABC):
5+
6+
@staticmethod
7+
@abstractmethod
8+
def get_hook() -> str:
9+
pass

0 commit comments

Comments
 (0)