Coverage for heliumcli/actions/buildrelease.py: 85.06%

87 statements  

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

1import datetime 

2import os 

3import shutil 

4 

5import git 

6 

7from .. import utils 

8from .prepcode import PrepCodeAction 

9 

10__author__ = "Alex Laird" 

11__copyright__ = "Copyright 2018, Helium Edu" 

12__version__ = "1.5.0" 

13 

14 

15class BuildReleaseAction: 

16 def __init__(self): 

17 self.name = "build-release" 

18 self.help = "Build a release version for all projects, tagging when complete" 

19 

20 def setup(self, subparsers): 

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

22 parser.add_argument("version", help="The version number to be tagged") 

23 parser.add_argument("--roles", action="store", type=str, nargs="*", 

24 help="Limit the project roles to be built/tagged") 

25 parser.set_defaults(action=self) 

26 

27 def run(self, args): 

28 config = utils.get_config() 

29 projects_dir = utils.get_projects_dir() 

30 

31 # First ensure all repos are in a clean state with all changes committed 

32 dirty_repos = [] 

33 for project in utils.get_projects(config): 

34 if args.roles and project not in args.roles: 

35 continue 

36 

37 if config["projectsRelativeDir"] != ".": 

38 project_path = os.path.join(projects_dir, project) 

39 else: 

40 project_path = os.path.join(projects_dir) 

41 

42 repo = git.Repo(project_path) 

43 

44 if repo.untracked_files or repo.is_dirty(): 

45 print("Untracked files in {}: {}".format(project, repo.untracked_files)) 

46 

47 dirty_repos.append(project) 

48 else: 

49 repo.git.fetch(tags=True, prune=True) 

50 repo.git.checkout(config["branchName"]) 

51 

52 if len(dirty_repos) > 0: 

53 print("WARN: this operation cannot be performed when a repo is dirty. Commit all changes to the following " 

54 "repos before proceeding: {}".format(dirty_repos)) 

55 

56 return 

57 

58 version = args.version.lstrip("v") 

59 

60 self._update_version_file(version, 

61 os.path.join(config["versionInfo"]["project"], config["versionInfo"]["path"])) 

62 

63 prepcodeaction = PrepCodeAction() 

64 prepcodeaction.run(args) 

65 

66 print("Committing changes and creating release tags ...") 

67 

68 for project in utils.get_projects(config): 

69 print(project) 

70 

71 if config["projectsRelativeDir"] != ".": 

72 project_path = os.path.join(projects_dir, project) 

73 else: 

74 project_path = os.path.join(projects_dir) 

75 

76 self._commit_and_tag(project_path, version, config["remoteName"], config["branchName"]) 

77 

78 if config["projectsRelativeDir"] != ".": 

79 root_dir = os.path.abspath(os.path.join(projects_dir, "..")) 

80 if os.path.exists(os.path.join(root_dir, ".git")): 

81 print(utils.get_repo_name(root_dir, config["remoteName"])) 

82 self._commit_and_tag(root_dir, version, config["remoteName"], config["branchName"]) 

83 

84 print("... release version {} built.".format(version)) 

85 

86 def _commit_and_tag(self, path, version, remote_name, branch_name): 

87 repo = git.Repo(path) 

88 

89 if version in repo.tags: 

90 print("Version already exists, not doing anything.") 

91 else: 

92 if repo.is_dirty(): 

93 repo.git.add(u=True) 

94 repo.git.commit(m="[heliumcli] Release {}".format(version)) 

95 repo.remotes[remote_name].push(branch_name) 

96 tag = repo.create_tag(version, m="") 

97 repo.remotes[remote_name].push(tag) 

98 

99 def _update_version_file(self, version, path): 

100 config = utils.get_config() 

101 

102 version_file_path = os.path.join(utils.get_projects_dir(), path) 

103 

104 version_file = open(version_file_path, "r") 

105 new_version_file = open(version_file_path + ".tmp", "w") 

106 

107 for line in version_file: 

108 if version_file_path.endswith(".py"): 

109 if line.strip().startswith("__version__ ="): 

110 line = "__version__ = \"{}\"\n".format(version) 

111 elif line.strip().startswith("__copyright__ = "): 

112 line = "__copyright__ = \"Copyright {}, {}\"\n".format(str(datetime.date.today().year), 

113 utils.get_copyright_name()) 

114 elif version_file.name == "package.json": 

115 if line.strip().startswith("\"version\":"): 

116 line = " \"version\": \"{}\",\n".format(version) 

117 # TODO: implement other known types 

118 else: 

119 print("WARN: helium-cli does not know how to process this type of file for version file: {}".format( 

120 config["versionInfo"]["path"])) 

121 

122 new_version_file.close() 

123 os.remove(version_file_path + ".tmp") 

124 

125 return 

126 

127 new_version_file.write(line) 

128 

129 version_file.close() 

130 new_version_file.close() 

131 

132 shutil.copy(version_file_path + ".tmp", version_file_path) 

133 os.remove(version_file_path + ".tmp")