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

86 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-11-14 23:25 +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 dirty_repos.append(project) 

46 else: 

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

48 repo.git.checkout("master") 

49 

50 if len(dirty_repos) > 0: 

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

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

53 

54 return 

55 

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

57 

58 self._update_version_file(version, 

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

60 

61 prepcodeaction = PrepCodeAction() 

62 prepcodeaction.run(args) 

63 

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

65 

66 for project in utils.get_projects(config): 

67 print(project) 

68 

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

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

71 else: 

72 project_path = os.path.join(projects_dir) 

73 

74 self._commit_and_tag(project_path, version) 

75 

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

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

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

79 print(utils.get_repo_name(root_dir)) 

80 self._commit_and_tag(root_dir, version) 

81 

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

83 

84 def _commit_and_tag(self, path, version): 

85 repo = git.Repo(path) 

86 

87 if version in repo.tags: 

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

89 else: 

90 if repo.is_dirty(): 

91 repo.git.add(u=True) 

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

93 repo.remotes["origin"].push("master") 

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

95 repo.remotes["origin"].push(tag) 

96 

97 def _update_version_file(self, version, path): 

98 config = utils.get_config() 

99 

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

101 

102 version_file = open(version_file_path, "r") 

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

104 

105 for line in version_file: 

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

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

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

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

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

111 utils.get_copyright_name()) 

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

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

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

115 # TODO: implement other known types 

116 else: 

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

118 config["versionInfo"]["path"])) 

119 

120 new_version_file.close() 

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

122 

123 return 

124 

125 new_version_file.write(line) 

126 

127 version_file.close() 

128 new_version_file.close() 

129 

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

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