#!/bin/bash -e
cd `dirname $0`
-TESTNAME="mediawiki_continue_upgrade"
+TESTNAME="mediawiki_crlf_upgrade"
source ./setup
source ./mediawiki-install
default implementation uses :attr:`resolutions`.
"""
resolved = True
- sh = shell.Shell()
files = set()
- for status in sh.eval("git", "ls-files", "--unmerged").splitlines():
+ for status in shell.eval("git", "ls-files", "--unmerged").splitlines():
files.add(status.split()[-1])
for file in files:
# check for newline mismatch
# HACK: using git diff to tell if files are binary or not
- if not len(sh.eval("git", "diff", file).splitlines()) == 1 and util.mixed_newlines(file):
+ if not len(shell.eval("git", "diff", file).splitlines()) == 1 and util.mixed_newlines(file):
# this code only works on Unix
def get_newline(filename):
f = open(filename, "U")
return f.newlines
def create_reference(id):
f = tempfile.NamedTemporaryFile(prefix="wizardResolve", delete=False)
- sh.call("git", "cat-file", "blob", ":%d:%s" % (id, file), stdout=f)
+ shell.call("git", "cat-file", "blob", ":%d:%s" % (id, file), stdout=f)
f.close()
return get_newline(f.name), f.name
def convert(filename, dest_nl):
logging.info("Remerging %s", file)
with open(file, "wb") as f:
try:
- sh.call("git", "merge-file", "--stdout", our_file, common_file, their_file, stdout=f)
+ shell.call("git", "merge-file", "--stdout", our_file, common_file, their_file, stdout=f)
logging.info("New merge was clean")
- sh.call("git", "add", file)
+ shell.call("git", "add", file)
continue
except shell.CallError:
pass
logging.info("Did resolution with spec:\n" + spec)
open(file, "w").write(contents)
if not resolve.is_conflict(contents):
- sh.call("git", "add", file)
+ shell.call("git", "add", file)
else:
resolved = False
else:
"""
Database backups for MySQL using the :command:`mysqldump` utility.
"""
- sh = shell.Shell()
outfile = os.path.join(outdir, "db.sql")
try:
- sh.call("mysqldump", "--compress", "-r", outfile, *get_mysql_args(deployment.dsn))
- sh.call("gzip", "--best", outfile)
+ shell.call("mysqldump", "--compress", "-r", outfile, *get_mysql_args(deployment.dsn))
+ shell.call("gzip", "--best", outfile)
except shell.CallError as e:
raise BackupFailure(e.stderr)
"""
Database restoration for MySQL by piping SQL commands into :command:`mysql`.
"""
- sh = shell.Shell()
if not os.path.exists(backup_dir):
raise RestoreFailure("Backup %s doesn't exist", backup_dir.rpartition("/")[2])
sql = open(os.path.join(backup_dir, "db.sql"), 'w+')
- sh.call("gunzip", "-c", os.path.join(backup_dir, "db.sql.gz"), stdout=sql)
+ shell.call("gunzip", "-c", os.path.join(backup_dir, "db.sql.gz"), stdout=sql)
sql.seek(0)
- sh.call("mysql", *get_mysql_args(deployment.dsn), stdin=sql)
+ shell.call("mysql", *get_mysql_args(deployment.dsn), stdin=sql)
sql.close()
def remove_database(deployment):
Generic database removal function. Actually, not so generic because we
go and check if we're on scripts and if we are run a different command.
"""
- sh = shell.Shell()
if deployment.dsn.host == "sql.mit.edu":
try:
- sh.call("/mit/scripts/sql/bin/drop-database", deployment.dsn.database)
+ shell.call("/mit/scripts/sql/bin/drop-database", deployment.dsn.database)
return
except shell.CallError:
pass
raise app.RecoverableInstallFailure(error_messages)
os.rename('config/LocalSettings.php', 'LocalSettings.php')
def upgrade(self, d, version, options):
- sh = shell.Shell()
if not os.path.isfile("AdminSettings.php"):
- sh.call("git", "checkout", "-q", "mediawiki-" + str(version), "--", "AdminSettings.php")
+ shell.call("git", "checkout", "-q", "mediawiki-" + str(version), "--", "AdminSettings.php")
try:
- result = sh.eval("php", "maintenance/update.php", "--quick", log=True)
+ result = shell.eval("php", "maintenance/update.php", "--quick", log=True)
except shell.CallError as e:
raise app.UpgradeFailure("Update script returned non-zero exit code\nSTDOUT: %s\nSTDERR: %s" % (e.stdout, e.stderr))
results = result.rstrip().split()
def main(argv, baton):
options, args = parse_args(argv, baton)
reason = args[0]
- sh = shell.Shell()
# XXX: this should be abstracted away!
if os.path.exists(".git/WIZARD_REPO"):
- util.chdir(sh.eval('git', 'config', 'remote.origin.url'))
+ util.chdir(shell.eval('git', 'config', 'remote.origin.url'))
open('.scripts/blacklisted', 'w').write(reason + "\n")
def parse_args(argv, baton):
else:
ihandler.ask(options)
- sh = shell.Shell()
input.infobox("Copying files (this may take a while)...")
if not os.path.exists(dir):
- sh.call("git", "clone", "-q", "--shared", application.repository(old_options.srv_path), dir)
+ shell.call("git", "clone", "-q", "--shared", application.repository(old_options.srv_path), dir)
with util.ChangeDirectory(dir):
if not old_options.retry and version and version != "head-scripts": # for ease in testing
- sh.call("git", "reset", "-q", "--hard", appstr)
+ shell.call("git", "reset", "-q", "--hard", appstr)
input.infobox("Installing...")
application.install(distutils.version.LooseVersion(version), options)
if not old_options.no_commit:
def main(argv, baton):
options, args = parse_args(argv, baton)
- sh = shell.Shell()
wc = deploy.WorkingCopy(".")
wc.verify()
wc.verifyConfigured()
# worst case scenario protection
for file in wc.application.parametrized_files:
- sh.call("git", "add", file)
- sh.call("git", "commit", "--allow-empty", "-am", "Protection commit")
- sh.call("git", "reset", "HEAD~")
+ shell.call("git", "add", file)
+ shell.call("git", "commit", "--allow-empty", "-am", "Protection commit")
+ shell.call("git", "reset", "HEAD~")
wc.prepareConfig()
def parse_args(argv, baton):
def main(argv, baton):
options, args = parse_args(argv, baton)
- sh = shell.Shell()
check_directory(options)
if not os.path.exists(args[0]):
appname, _, version = args[0].partition("-")
with open(base, "w") as outfile:
infile = urllib.urlopen(url)
shutil.copyfileobj(infile, outfile)
- sh.call("tar", "xf", base)
+ shell.call("tar", "xf", base)
os.unlink(base)
else:
base = args[0]
- sh.call("tar", "xf", base)
+ shell.call("tar", "xf", base)
# extract the files, but be smart: if only one directory is output,
# move the contents of that directory here
items = [f for f in os.listdir(os.getcwd()) if f[0] != "."]
if len(items) == 1 and os.path.isdir(items[0]):
os.rename(items[0], "_wizard_source")
- sh.call("cp", "-R", "_wizard_source/.", ".")
+ shell.call("cp", "-R", "_wizard_source/.", ".")
shutil.rmtree("_wizard_source")
# populate empty directories with blank files
for dirpath, dirnames, filenames in os.walk(os.getcwd()):
if "/.git" in dirpath: continue
if not filenames and not dirnames:
open(os.path.join(dirpath, ".preserve-dir"), "w").write("")
- sh.call("git", "add", ".")
+ shell.call("git", "add", ".")
def parse_args(argv, baton):
usage = """usage: %prog prepare-pristine APP-VERSION
return options, args
def check_directory(options):
- sh = shell.Shell()
- files = sh.eval("git", "ls-files", "-o")
+ files = shell.eval("git", "ls-files", "-o")
if files:
raise Exception("Unversioned files exist, refusing to remove (override with --force)")
try:
- sh.call("git", "rev-parse", "HEAD")
+ shell.call("git", "rev-parse", "HEAD")
_, _, ref = open(".git/HEAD").read().rstrip().partition(' ')
if not options.force:
if ref != "refs/heads/pristine" and os.path.exists(os.path.join(".git", ref)):
raise Exception("Not on pristine branch (override with --force)")
try:
- sh.call("git", "status")
+ shell.call("git", "status")
raise Exception("Working copy is dirty (override with --force)")
except shell.CallError:
pass
options, show = parse_args(argv, baton)
appname = show[0]
application = app.applications()[appname]
- sh = shell.Shell()
deploys = deploy.parse_install_lines(show, options.versions_path)
stats = {}
iffy = 0
d.verifyConfigured()
with util.ChangeDirectory(d.location):
results = []
- out = sh.safeCall('git', 'diff', '--numstat', d.app_version.scripts_tag, strip=True)
+ out = shell.safeCall('git', 'diff', '--numstat', d.app_version.scripts_tag, strip=True)
total += 1
for line in out.split("\n"):
added, deleted, filename = line.split(None, 3)
d.verify()
d.verifyConfigured()
tag = "%s-%s" % (d.application.name, version)
- sh = shell.Shell()
try:
- sh.call("git", "rev-parse", tag)
+ shell.call("git", "rev-parse", tag)
except shell.CallError:
raise Exception("Tag %s doesn't exist in repository" % tag)
- sh.call("git", "reset", "-q", "--hard", tag)
+ shell.call("git", "reset", "-q", "--hard", tag)
d.restore(backup, options)
def parse_args(argv, baton):
if self.wc.resolveConflicts():
logging.info("Resolved conflicts with application specific knowledge")
shell.call("git", "commit", "-a", "-m", "merge")
+ return
files = set()
for line in shell.eval("git", "ls-files", "--unmerged").splitlines():
files.add(line.split(None, 3)[-1])
"""
repo = self.application.repository(srv_path)
try:
- shell.Shell().eval("git", "--git-dir", repo, "rev-parse", self.app_version.scripts_tag, '--')
+ shell.eval("git", "--git-dir", repo, "rev-parse", self.app_version.scripts_tag, '--')
except shell.CallError:
raise NoTagError(self.app_version.scripts_tag)
corresponds to the one in the remote repository.
"""
with util.ChangeDirectory(self.location):
- sh = shell.Shell()
repo = self.application.repository(srv_path)
def repo_rev_parse(tag):
- return sh.eval("git", "--git-dir", repo, "rev-parse", tag)
+ return shell.eval("git", "--git-dir", repo, "rev-parse", tag)
def self_rev_parse(tag):
try:
- return sh.safeCall("git", "rev-parse", tag, strip=True)
+ return shell.safeCall("git", "rev-parse", tag, strip=True)
except shell.CallError:
raise NoLocalTagError(tag)
def compare_tags(tag):
if not compare_tags(self.app_version.scripts_tag):
raise InconsistentScriptsTagError(self.app_version.scripts_tag)
parent = repo_rev_parse(self.app_version.scripts_tag)
- merge_base = sh.safeCall("git", "merge-base", parent, "HEAD", strip=True)
+ merge_base = shell.safeCall("git", "merge-base", parent, "HEAD", strip=True)
if merge_base != parent:
raise HeadNotDescendantError(self.app_version.scripts_tag)
except old_log.ScriptsVersionNoSuchFile:
pass
if not self._app_version:
- appname = shell.Shell().eval("git", "config", "remote.origin.url").rpartition("/")[2].partition(".")[0]
+ appname = shell.eval("git", "config", "remote.origin.url").rpartition("/")[2].partition(".")[0]
self._app_version = app.ApplicationVersion.make(appname, "unknown")
return self._app_version
@property
def describe():
"""Finds the output of git describe --tags of the current directory."""
- return shell.Shell().safeCall("git", "describe", "--tags", strip=True)
+ return shell.safeCall("git", "describe", "--tags", strip=True)
def commit_configure():
message = "Autoinstall configuration of %s locker.\n\n%s" % (util.get_dir_owner(), util.get_git_footer())
message += "\nConfigured-by: " + util.get_operator_git()
except util.NoOperatorInfo:
pass
- shell.Shell().call("git", "commit", "--allow-empty", "-a", "-m", message)
+ shell.call("git", "commit", "--allow-empty", "-a", "-m", message)
if self.application.database != "mysql":
raise StrategyFailed
try:
- self._triplet = shell.Shell().eval("/mit/scripts/sql/bin/get-password").split()
+ self._triplet = shell.eval("/mit/scripts/sql/bin/get-password").split()
except shell.CallError:
raise StrategyFailed
self._username = os.getenv('USER')
raise StrategyFailed
def execute(self, options):
"""Creates a new database for the user using ``get-next-database`` and ``create-database``."""
- sh = shell.Shell()
host, username, password = self._triplet
# race condition
- database = self._username + '+' + sh.eval("/mit/scripts/sql/bin/get-next-database", os.path.basename(self.dir))
- sh.call("/mit/scripts/sql/bin/create-database", database)
+ database = self._username + '+' + shell.eval("/mit/scripts/sql/bin/get-next-database", os.path.basename(self.dir))
+ shell.call("/mit/scripts/sql/bin/create-database", database)
options.dsn = sqlalchemy.engine.url.URL("mysql", username=username, password=password, host=host, database=database)
class ScriptsEmailStrategy(Strategy):