Coverage for heliumcli/actions/init.py: 94.37%

71 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-11-22 22:16 +0000

1import os 

2import shutil 

3import subprocess 

4import sys 

5 

6import git 

7 

8from .. import utils 

9 

10__author__ = "Alex Laird" 

11__copyright__ = "Copyright 2022, Helium Edu" 

12__version__ = "1.6.5" 

13 

14 

15class InitAction: 

16 def __init__(self): 

17 self.name = "init" 

18 self.help = "Initialize a new project that is compatible with helium-cli" 

19 

20 def setup(self, subparsers): 

21 parser = subparsers.add_parser(self.name, help=self.help) 

22 parser.add_argument("--config-only", action="store_true", help="Only initialize the .heliumcli.yml config file") 

23 parser.add_argument("id", help="The ID (no spaces) to give to the new project") 

24 parser.add_argument("name", help="The friendly name to give to the new project") 

25 parser.add_argument("host", help="The hostname to give the project") 

26 parser.add_argument("github_user", help="The GitHub username or project name") 

27 parser.set_defaults(action=self) 

28 

29 def run(self, args): 

30 config_path = os.path.abspath(os.environ.get("HELIUMCLI_CONFIG_PATH", ".heliumcli.yml")) 

31 if os.path.exists(config_path): 

32 print("It looks like a helium-cli project already exists in this directory, not doing anything.") 

33 

34 sys.exit(1) 

35 

36 utils.get_config(True) 

37 

38 self._upper_slug = args.id.replace("-", "_").replace(" ", "_").upper() 

39 self._lower_slug = self._upper_slug.lower() 

40 

41 if not args.config_only: 

42 self._init_project(config_path, args) 

43 else: 

44 self._replace_in_file(os.path.dirname(config_path), os.path.basename(config_path), args) 

45 

46 print("A new helium-cli project has been initialized.") 

47 

48 def _init_project(self, config_path, args): 

49 project_dir = os.path.join(os.path.dirname(config_path), args.id) 

50 template_project_name = "template-project" 

51 template_version = os.environ.get("HELIUMCLI_TEMPLATE_PROJECT_VERSION", "1.2.3") 

52 

53 print("Cloning the template-project {} repo into this directory ...".format(template_version)) 

54 git.Repo.clone_from("{}/{}.git".format("https://github.com/HeliumEdu", template_project_name), 

55 project_dir, 

56 branch=template_version) 

57 

58 shutil.rmtree(os.path.join(project_dir, ".git")) 

59 

60 if os.path.exists(os.path.join(project_dir, ".travis.yml.template")): 

61 os.remove(os.path.join(project_dir, ".travis.yml")) 

62 os.rename(os.path.join(project_dir, ".travis.yml.template"), os.path.join(project_dir, ".travis.yml")) 

63 

64 if os.path.exists(os.path.join(project_dir, ".github", "workflows", "build.yml.template")): 

65 os.remove(os.path.join(project_dir, ".github", "workflows", "build.yml")) 

66 os.rename(os.path.join(project_dir, ".github", "workflows", "build.yml.template"), 

67 os.path.join(project_dir, ".github", "workflows", "build.yml")) 

68 

69 if os.path.exists(os.path.join(project_dir, "Makefile.template")): 

70 os.remove(os.path.join(project_dir, "Makefile")) 

71 os.rename(os.path.join(project_dir, "Makefile.template"), os.path.join(project_dir, "Makefile")) 

72 

73 repo = git.Repo.init(project_dir) 

74 

75 print("Updating template variables ...") 

76 

77 for dir_name, dirs, files in os.walk(project_dir): 

78 for filename in files: 

79 self._replace_in_file(dir_name, filename, args) 

80 

81 repo.git.add(A=True) 

82 

83 os.rename(os.path.join(project_dir, "project_id"), os.path.join(project_dir, self._lower_slug)) 

84 

85 print("Running make ...") 

86 

87 subprocess.call(["python3", "-m", "pip", "install", "virtualenv"]) 

88 subprocess.call(["python3", "-m", "virtualenv", os.path.join(project_dir, ".venv")]) 

89 subprocess.call(["make", "install", "-C", project_dir]) 

90 

91 def _replace_in_file(self, dir_name, filename, args): 

92 path = os.path.join(dir_name, filename) 

93 with open(path, "r") as f: 

94 s = f.read() 

95 s = s.replace("{%PROJECT_ID%}", args.id) 

96 s = s.replace("{%PROJECT_ID_UPPER%}", self._upper_slug) 

97 s = s.replace("{%PROJECT_ID_LOWER%}", self._lower_slug) 

98 s = s.replace("{%PROJECT_NAME%}", args.name) 

99 s = s.replace("{%PROJECT_GITHUB_USER%}", args.github_user) 

100 

101 with open(path, "w") as f: 

102 f.write(s)