|
1 | 1 | import os |
2 | 2 | import shutil |
3 | 3 | import hashlib |
| 4 | +import re |
| 5 | +import json |
4 | 6 |
|
5 | 7 | import six |
6 | 8 | from git.repo import Repo |
|
11 | 13 | ALL_PACKS = '*' |
12 | 14 | PACK_REPO_ROOT = 'packs' |
13 | 15 | MANIFEST_FILE = 'pack.yaml' |
| 16 | +CONFIG_FILE = 'config.yaml' |
| 17 | +GITINFO_FILE = '.gitinfo' |
14 | 18 | PACK_RESERVE_CHARACTER = '.' |
15 | 19 |
|
16 | 20 |
|
17 | 21 | class InstallGitRepoAction(Action): |
18 | | - def run(self, packs, repo_url, abs_repo_base, verifyssl=True, branch='master'): |
19 | | - repo_name = repo_url[repo_url.rfind('/') + 1: repo_url.rfind('.')] |
| 22 | + def run(self, packs, repo_url, abs_repo_base, verifyssl=True, branch='master', subtree=False): |
| 23 | + self._subtree = self._eval_subtree(repo_url, subtree) |
| 24 | + self._repo_url = self._eval_repo_url(repo_url) |
| 25 | + |
| 26 | + repo_name = self._repo_url[self._repo_url.rfind('/') + 1: self._repo_url.rfind('.')] |
20 | 27 | lock_name = hashlib.md5(repo_name).hexdigest() + '.lock' |
21 | 28 |
|
22 | 29 | with LockFile('/tmp/%s' % (lock_name)): |
23 | | - abs_local_path = self._clone_repo(repo_url=repo_url, verifyssl=verifyssl, |
| 30 | + abs_local_path = self._clone_repo(repo_url=self._repo_url, verifyssl=verifyssl, |
24 | 31 | branch=branch) |
25 | 32 | try: |
26 | | - # st2-contrib repo has a top-level packs folder that actually contains the |
27 | | - pack_abs_local_path = os.path.join(abs_local_path, PACK_REPO_ROOT) |
| 33 | + if self._subtree: |
| 34 | + # st2-contrib repo has a top-level packs folder that actually contains the |
| 35 | + pack_abs_local_path = os.path.join(abs_local_path, PACK_REPO_ROOT) |
| 36 | + else: |
| 37 | + pack_abs_local_path = abs_local_path |
| 38 | + |
| 39 | + self._tag_pack(pack_abs_local_path, packs, self._subtree) |
28 | 40 | result = self._move_packs(abs_repo_base, packs, pack_abs_local_path) |
29 | 41 | finally: |
30 | 42 | self._cleanup_repo(abs_local_path) |
@@ -58,6 +70,10 @@ def _move_packs(self, abs_repo_base, packs, abs_local_path): |
58 | 70 | if os.path.exists(dest_pack_path): |
59 | 71 | self.logger.debug('Removing existing pack %s in %s to replace.', pack, |
60 | 72 | dest_pack_path) |
| 73 | + # Ensure to preserve any existing configuration |
| 74 | + old_config_file = os.path.join(dest_pack_path, CONFIG_FILE) |
| 75 | + new_config_file = os.path.join(abs_pack_temp_location, CONFIG_FILE) |
| 76 | + shutil.move(old_config_file, new_config_file) |
61 | 77 | shutil.rmtree(dest_pack_path) |
62 | 78 | self.logger.debug('Moving pack from %s to %s.', abs_pack_temp_location, to) |
63 | 79 | shutil.move(abs_pack_temp_location, to) |
@@ -115,3 +131,38 @@ def _validate_result(result, packs, repo_url): |
115 | 131 | raise Exception(message) |
116 | 132 |
|
117 | 133 | return sanitized_result |
| 134 | + |
| 135 | + @staticmethod |
| 136 | + def _eval_subtree(repo_url, subtree): |
| 137 | + st2_repos = re.compile("st2(contrib|incubator)") |
| 138 | + match = True if st2_repos.search(repo_url) else False |
| 139 | + return subtree ^ match |
| 140 | + |
| 141 | + @staticmethod |
| 142 | + def _eval_repo_url(repo_url): |
| 143 | + """Allow passing short GitHub style URLs""" |
| 144 | + if len(repo_url.split('/')) == 2 and not "git@" in repo_url: |
| 145 | + return "https://github.com/{}.git".format(repo_url) |
| 146 | + else: |
| 147 | + return "{}.git".format(repo_url) |
| 148 | + |
| 149 | + @staticmethod |
| 150 | + def _tag_pack(pack_dir, packs, subtree): |
| 151 | + """Add git information to pack directory for retrieval later""" |
| 152 | + for pack in packs: |
| 153 | + repo = Repo(pack_dir) |
| 154 | + payload = { |
| 155 | + "branch": repo.active_branch.name, |
| 156 | + "ref": repo.head.commit.hexsha |
| 157 | + } |
| 158 | + |
| 159 | + if subtree: |
| 160 | + info_file = os.path.join(pack_dir, pack, GITINFO_FILE) |
| 161 | + else: |
| 162 | + info_file = os.path.join(pack_dir, GITINFO_FILE) |
| 163 | + |
| 164 | + try: |
| 165 | + gitinfo = open(info_file, "w") |
| 166 | + gitinfo.write(json.dumps(payload)) |
| 167 | + finally: |
| 168 | + gitinfo.close() |
0 commit comments