Coverage for sparkle/CLI/_cli_.py: 93%

45 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2025-09-29 10:17 +0000

1#!/usr/bin/env python3 

2"""Sparkle CLI entry point.""" 

3 

4import sys 

5import os 

6from pathlib import Path 

7 

8module_path = Path(__file__).parent.resolve() 

9 

10package_cli_entry_points = [ 

11 module_path.parent / "solver" / "solver_cli.py", 

12 module_path.parent / "selector" / "selector_cli.py", 

13 module_path.parent / "selector" / "extractor_cli.py", 

14 module_path.parent / "configurator" / "configurator_cli.py", 

15] 

16 

17 

18def commands() -> list[str]: 

19 """Get list of available commands.""" 

20 module_path = Path(__file__).parent.resolve() 

21 self_name = Path(__file__).name 

22 return [ 

23 path.stem 

24 for path in module_path.iterdir() 

25 if path.is_file() 

26 and path.suffix == ".py" 

27 and path.name != self_name 

28 and path.name != "__init__.py" 

29 ] 

30 

31 

32def main() -> None: 

33 """Pass through command to launch CLI commands.""" 

34 max_space = max( 

35 [path.name.count("_") for path in module_path.iterdir() if path.is_file()] 

36 ) 

37 if len(sys.argv) < 2: 

38 print("Usage: sparkle <command>") 

39 sys.exit(1) 

40 # Support spaces instead of _ 

41 possible_commands = commands() 

42 command, command_file = "", Path() 

43 for i in range(1, min(max_space, len(sys.argv))): 

44 if "--" in sys.argv[i]: # Parameter is never part of the command 

45 break 

46 command = "_".join(sys.argv[1 : i + 1]) 

47 args = sys.argv[i + 1 :] 

48 command_file = module_path / f"{command}.py" 

49 if command in possible_commands: 

50 break 

51 

52 if command_file.is_file(): 

53 os.system(f"python3 {command_file} {' '.join(args)}") 

54 sys.exit(0) 

55 elif command == "install_autocomplete": 

56 script_path = module_path / "autocomplete.sh" 

57 bash_profile = Path.home() / ".bash_profile" 

58 if not bash_profile.exists(): 

59 bash_profile.open("w+").close() 

60 bash_profile.open("a").write( 

61 "\n#----- Sparkle AutoComplete ----\n" 

62 f"source {script_path.absolute()}" 

63 "\n#----- Sparkle AutoComplete ----\n" 

64 ) 

65 print( 

66 f"Sparkle autocomplete installed! To enable, run `source {bash_profile}` " 

67 "or restart your terminal." 

68 ) 

69 sys.exit(0) 

70 else: 

71 print(f"Sparkle does not understand command <{command}>", end="") 

72 from difflib import SequenceMatcher 

73 

74 similarities = [ 

75 SequenceMatcher(None, command, alt).ratio() for alt in possible_commands 

76 ] 

77 

78 if max(similarities) > 0.6: 

79 alternative = possible_commands[similarities.index(max(similarities))] 

80 print(f". Did you mean <{alternative}>?") 

81 sys.exit(-2) 

82 

83 sys.exit(-1) 

84 

85 

86if __name__ == "__main__": 

87 main()