Coverage for heliumcli/actions/buildrelease.py: 85.23%
88 statements
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-02 23:15 +0000
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-02 23:15 +0000
1import datetime
2import os
3import shutil
4import sys
6import git
8from .. import utils
9from .prepcode import PrepCodeAction
11__author__ = "Alex Laird"
12__copyright__ = "Copyright 2018, Helium Edu"
13__version__ = "1.5.0"
16class BuildReleaseAction:
17 def __init__(self):
18 self.name = "build-release"
19 self.help = "Build a release version for all projects, tagging when complete"
21 def setup(self, subparsers):
22 parser = subparsers.add_parser(self.name, help=self.help)
23 parser.add_argument("version", help="The version number to be tagged")
24 parser.add_argument("--roles", action="store", type=str, nargs="*",
25 help="Limit the project roles to be built/tagged")
26 parser.set_defaults(action=self)
28 def run(self, args):
29 config = utils.get_config()
30 projects_dir = utils.get_projects_dir()
32 # First ensure all repos are in a clean state with all changes committed
33 dirty_repos = []
34 for project in utils.get_projects(config):
35 if args.roles and project not in args.roles:
36 continue
38 if config["projectsRelativeDir"] != ".":
39 project_path = os.path.join(projects_dir, project)
40 else:
41 project_path = os.path.join(projects_dir)
43 repo = git.Repo(project_path)
45 if repo.untracked_files or repo.is_dirty():
46 print("Untracked files in {}: {}".format(project, repo.untracked_files))
48 dirty_repos.append(project)
49 else:
50 repo.git.fetch(tags=True, prune=True)
51 repo.git.checkout(config["branchName"])
53 if len(dirty_repos) > 0:
54 print("Error: this operation cannot be performed when a repo is dirty. Commit all changes to the following "
55 "repos before proceeding: {}".format(dirty_repos))
57 sys.exit(1)
59 version = args.version.lstrip("v")
61 self._update_version_file(version,
62 os.path.join(config["versionInfo"]["project"], config["versionInfo"]["path"]))
64 prepcodeaction = PrepCodeAction()
65 prepcodeaction.run(args)
67 print("Committing changes and creating release tags ...")
69 for project in utils.get_projects(config):
70 print(project)
72 if config["projectsRelativeDir"] != ".":
73 project_path = os.path.join(projects_dir, project)
74 else:
75 project_path = os.path.join(projects_dir)
77 self._commit_and_tag(project_path, version, config["remoteName"], config["branchName"])
79 if config["projectsRelativeDir"] != ".":
80 root_dir = os.path.abspath(os.path.join(projects_dir, ".."))
81 if os.path.exists(os.path.join(root_dir, ".git")):
82 print(utils.get_repo_name(root_dir, config["remoteName"]))
83 self._commit_and_tag(root_dir, version, config["remoteName"], config["branchName"])
85 print("... release version {} built.".format(version))
87 def _commit_and_tag(self, path, version, remote_name, branch_name):
88 repo = git.Repo(path)
90 if version in repo.tags:
91 print("Version already exists, not doing anything.")
92 else:
93 if repo.is_dirty():
94 repo.git.add(u=True)
95 repo.git.commit(m="[heliumcli] Release {}".format(version))
96 repo.remotes[remote_name].push(branch_name)
97 tag = repo.create_tag(version, m="")
98 repo.remotes[remote_name].push(tag)
100 def _update_version_file(self, version, path):
101 config = utils.get_config()
103 version_file_path = os.path.join(utils.get_projects_dir(), path)
105 version_file = open(version_file_path, "r")
106 new_version_file = open(version_file_path + ".tmp", "w")
108 for line in version_file:
109 if version_file_path.endswith(".py"):
110 if line.strip().startswith("__version__ ="):
111 line = "__version__ = \"{}\"\n".format(version)
112 elif line.strip().startswith("__copyright__ = "):
113 line = "__copyright__ = \"Copyright {}, {}\"\n".format(str(datetime.date.today().year),
114 utils.get_copyright_name())
115 elif version_file.name == "package.json":
116 if line.strip().startswith("\"version\":"):
117 line = " \"version\": \"{}\",\n".format(version)
118 # TODO: implement other known types
119 else:
120 print("WARN: helium-cli does not know how to process this type of file for version file: {}".format(
121 config["versionInfo"]["path"]))
123 new_version_file.close()
124 os.remove(version_file_path + ".tmp")
126 return
128 new_version_file.write(line)
130 version_file.close()
131 new_version_file.close()
133 shutil.copy(version_file_path + ".tmp", version_file_path)
134 os.remove(version_file_path + ".tmp")