|
| 1 | +#!/usr/bin/env python |
| 2 | + |
| 3 | +from __future__ import print_function |
| 4 | +import optparse |
| 5 | +import os |
| 6 | +import platform |
| 7 | +import random |
| 8 | +import subprocess |
| 9 | +import sys |
| 10 | +import time |
| 11 | +from optparse import OptionParser |
| 12 | + |
| 13 | +if not sys.version_info[0] == 3: |
| 14 | + # pylint:disable=W0622 |
| 15 | + input = raw_input |
| 16 | + # pylint:enable=W0622 |
| 17 | + |
| 18 | +def isUnix(): |
| 19 | + return platform.system() != "Windows" |
| 20 | + |
| 21 | +child_process = None |
| 22 | + |
| 23 | +def redirect_all(executable): |
| 24 | + old_sysin = sys.stdin |
| 25 | + old_sysout = sys.stdout |
| 26 | + old_syserr = sys.stderr |
| 27 | + p = subprocess.Popen([executable], stdin=subprocess.PIPE, stdout=old_sysout, stderr=old_syserr) |
| 28 | + sys.stdout = p.stdin |
| 29 | + sys.stderr = p.stdin |
| 30 | + old_sysout.close() |
| 31 | + global child_process |
| 32 | + child_process = p |
| 33 | + |
| 34 | +def WaitForProcess(): |
| 35 | + if not isUnix(): |
| 36 | + global child_process |
| 37 | + if child_process: |
| 38 | + child_process.stdin.close() |
| 39 | + child_process.wait() |
| 40 | + |
| 41 | + |
| 42 | +def main(): |
| 43 | + usage = "Usage: %prog [options] REPO_GIT" |
| 44 | + parser = OptionParser(usage) |
| 45 | + parser.add_option("-u", "--manifest-url", |
| 46 | + dest='manifest_url', |
| 47 | + help='manifest repository location', metavar='URL') |
| 48 | + parser.add_option("-s", "--no-sync", |
| 49 | + action="store_true", dest="no_sync", default=False, |
| 50 | + help="do not sync after init") |
| 51 | + parser.add_option("-c", "--clean", |
| 52 | + action="store_true", dest="clean", default=False, |
| 53 | + help="clean gits after init") |
| 54 | + parser.add_option("-i", "--interactive", |
| 55 | + action="store_true", dest="interactive", default=False, |
| 56 | + help="wait for user input after each step") |
| 57 | + parser.add_option("-q", "--quiet", |
| 58 | + action="store_false", dest="verbose", default=True, |
| 59 | + help="don't print status messages to stdout") |
| 60 | + |
| 61 | + (options, args) = parser.parse_args() |
| 62 | + |
| 63 | + repo_dir = sys.argv[1] |
| 64 | + |
| 65 | + env = os.environ |
| 66 | + if len(args) < 1: |
| 67 | + print("Missing REPO_GIT argument") |
| 68 | + exit(1) |
| 69 | + if options.verbose: |
| 70 | + env["REPO_TRACE"] = "1" |
| 71 | + |
| 72 | + if options.manifest_url.find('Test') < 0: |
| 73 | + print("Warning: aborting due to manifest url has no 'Test' substring. Make sure to create special manifest for this test util since it will not care for any git fetched!") |
| 74 | + exit(1) |
| 75 | + |
| 76 | + redirect_all('cat') |
| 77 | + |
| 78 | + repo = "%s/repo" % args[0] |
| 79 | + abs_repo = os.path.abspath(args[0]) |
| 80 | + prefix = '# ' |
| 81 | + |
| 82 | + def p(s=""): |
| 83 | + print('\033[47m\033[32m' + (prefix + s).ljust(80) + '\033[0m') |
| 84 | + |
| 85 | + def check_repository(min_git_count): |
| 86 | + dirs = filter(lambda x: not x == '.repo' and not x.find('Test') > -1, os.listdir('.')) |
| 87 | + if len(dirs) > 0: |
| 88 | + p("Warning: aborting due existing folders without 'Test' in name in repository! (folders: %s)" % (' '.join(dirs))) |
| 89 | + exit(1) |
| 90 | + |
| 91 | + dirs = filter(lambda x: not x == '.repo', os.listdir('.')) |
| 92 | + if len(dirs) < min_git_count: |
| 93 | + p("Warning: exit since not enough repositories found: required=%s, found=%s" % (min_git_count, len(dirs))) |
| 94 | + exit(1) |
| 95 | + |
| 96 | + |
| 97 | + def clean(): |
| 98 | + dirs = filter(lambda x: not x.startswith('.') and os.path.isdir(os.path.join('.', x)), os.listdir('.')) |
| 99 | + for d in dirs: |
| 100 | + cmd = "git reset --hard" |
| 101 | + subprocess.call(cmd.split(), cwd="./%s" % d, env=env) |
| 102 | + cmd = "git clean -xfd" |
| 103 | + subprocess.call(cmd.split(), cwd="./%s" % d, env=env) |
| 104 | + |
| 105 | + def select_folder(folder_index): |
| 106 | + dirs = filter(lambda x: not x.startswith('.') and os.path.isdir(os.path.join('.', x)), os.listdir('.')) |
| 107 | + dirs = sorted(dirs) |
| 108 | + return dirs[folder_index] |
| 109 | + |
| 110 | + def repo_do(name, cmd, dry_run=False): |
| 111 | + print() |
| 112 | + p(name) |
| 113 | + |
| 114 | + cmd = ['python', repo] + cmd |
| 115 | + if options.verbose: |
| 116 | + p(' '.join(cmd)) |
| 117 | + |
| 118 | + if not dry_run: |
| 119 | + subprocess.call(cmd, env=env) |
| 120 | + else: |
| 121 | + p("Skipping") |
| 122 | + |
| 123 | + if options.interactive: |
| 124 | + key = input("{0}{0}{1}Press any key to continue or 'q' to exit".format(os.linesep, prefix)) |
| 125 | + if key == 'q': |
| 126 | + p("Exit") |
| 127 | + exit(1) |
| 128 | + else: |
| 129 | + time.sleep(1) |
| 130 | + |
| 131 | + def changeAnyFile(d): |
| 132 | + files = filter(lambda x: not x.startswith('.') and os.path.isfile(os.path.join(d, x)), os.listdir(d)) |
| 133 | + f = files[0] |
| 134 | + fh = open('%s/%s' % (d, f), 'w') |
| 135 | + fh.write(str(random.random())) |
| 136 | + fh.close() |
| 137 | + p("Changing file %s in %s" % (f, d)) |
| 138 | + |
| 139 | + def stageAllIn(d): |
| 140 | + cmd = "git add -u" |
| 141 | + subprocess.call(cmd.split(), cwd="./%s" % d, env=env) |
| 142 | + |
| 143 | + def commitIn(d): |
| 144 | + cmd = "git commit -m \"%s\"" % (str(random.random())) |
| 145 | + subprocess.call(cmd.split(), cwd="./%s" % d, env=env) |
| 146 | + |
| 147 | + def startChangeCommit(folder): |
| 148 | + repo_do("Start branch in folder %s" % folder, ["start", "fix", folder]) |
| 149 | + changeAnyFile(folder) |
| 150 | + repo_do("Changed file in folder %s" % folder, ["status"]) |
| 151 | + stageAllIn(folder) |
| 152 | + repo_do("Stage file in folder %s" % folder, ["status"]) |
| 153 | + commitIn(folder) |
| 154 | + repo_do("Commit changes in folder %s" % folder, ["status"]) |
| 155 | + |
| 156 | + repo_do("Test init", ["init", "-u", options.manifest_url, "--no-repo-verify", "--repo-url", abs_repo, "--repo-branch", "stable"]) |
| 157 | + |
| 158 | + if options.clean: |
| 159 | + clean() |
| 160 | + repo_do("Do clean", ["status"]) |
| 161 | + |
| 162 | + repo_do("Test sync", ["sync"], options.no_sync) |
| 163 | + check_repository(2) |
| 164 | + |
| 165 | + repo_do("Test status", ["status"]) |
| 166 | + repo_do("Test info", ["info", "-o"]) |
| 167 | + |
| 168 | + folder_index0 = select_folder(0) |
| 169 | + folder_index1 = select_folder(1) |
| 170 | + |
| 171 | + startChangeCommit(folder_index0) |
| 172 | + repo_do("Check single pushable branch", ["info", "-o"]) |
| 173 | + repo_do("Test single push", ["push"]) |
| 174 | + repo_do("Check nothing to push after commit", ["info", "-o"]) |
| 175 | + |
| 176 | + startChangeCommit(folder_index0) |
| 177 | + startChangeCommit(folder_index1) |
| 178 | + repo_do("Check two pushable branches", ["info", "-o"]) |
| 179 | + repo_do("Test multiple push with editor", ["push"]) |
| 180 | + repo_do("Check nothing to push after commit", ["info", "-o"]) |
| 181 | + repo_do("Check already pushed branches", ["status"]) |
| 182 | + repo_do("Do prune", ["prune"]) |
| 183 | + repo_do("Check prune", ["status"]) |
| 184 | + |
| 185 | + repo_do("Test forall with env varibales", ["forall", "-c", "printenv", "REPO_PROJECT"]) |
| 186 | + |
| 187 | + print() |
| 188 | + p("Done") |
| 189 | + |
| 190 | + WaitForProcess() |
| 191 | + |
| 192 | +if __name__ == "__main__": |
| 193 | + main() |
0 commit comments