<commit_before># Copyright (C) 2007, <NAME>
# See the README file for details, or visit http://0install.net.

import copy
import os, subprocess, shutil, tarfile
import urlparse, ftplib, httplib
from zeroinstall import SafeException
from zeroinstall.injector import model, qdom
from logging import info

release_status_file = os.path.abspath('release-status')

def check_call(*args, **kwargs):
	exitstatus = subprocess.call(*args, **kwargs)
	if exitstatus != 0:
		if type(args[0]) in (str, unicode):
			cmd = args[0]
		else:
			cmd = ' '.join(args[0])
		raise SafeException("Command failed with exit code %d:\n%s" % (exitstatus, cmd))

def show_and_run(cmd, args):
	print "Executing: %s %s" % (cmd, ' '.join("[%s]" % x for x in args))
	check_call(['sh', '-c', cmd, '-'] + args)

def suggest_release_version(snapshot_version):
	"""Given a snapshot version, suggest a suitable release version.
	>>> suggest_release_version('1.0-pre')
	'1.0'
	>>> suggest_release_version('0.9-post')
	'0.10'
	>>> suggest_release_version('3')
	Traceback (most recent call last):
		...
	SafeException: Version '3' is not a snapshot version (should end in -pre or -post)
	"""
	version = model.parse_version(snapshot_version)
	mod = version[-1]
	if mod == 0:
		raise SafeException("Version '%s' is not a snapshot version (should end in -pre or -post)" % snapshot_version)
	if mod > 0:
		# -post, so increment the number
		version[-2][-1] += 1
	version[-1] = 0	# Remove the modifier
	return model.format_version(version)

def publish(iface, **kwargs):
	args = [os.environ['0PUBLISH']]
	for k in kwargs:
		value = kwargs[k] 
		if value is True:
			args += ['--' + k.replace('_', '-')]
		elif value is not None:
			args += ['--' + k.replace('_', '-'), value]
	args.append(iface)
	info("Executing %s", args)
	check_call(args)

def get_singleton_impl(iface):
	impls = iface.implementations
	if len(impls) != 1:
		raise SafeException("Local feed '%s' contains %d versions! I need exactly one!" % (iface.uri, len(impls)))
	return impls.values()[0]

def backup_if_exists(name):
	if not os.path.exists(name):
		return
	backup = name + '~'
	if os.path.exists(backup):
		print "(deleting old backup %s)" % backup
		if os.path.isdir(backup):
			shutil.rmtree(backup)
		else:
			os.unlink(backup)
	os.rename(name, backup)
	print "(renamed old %s as %s; will delete on next run)" % (name, backup)

def get_choice(options):
	while True:
		choice = raw_input('/'.join(options) + ': ').lower()
		if not choice: continue
		for o in options:
			if o.lower().startswith(choice):
				return o

def make_archive_name(feed_name, version):
	return feed_name.lower().replace(' ', '-') + '-' + version

def in_PATH(prog):
	for x in os.environ['PATH'].split(':'):
		if os.path.isfile(os.path.join(x, prog)):
			return True
	return False

def show_diff(from_dir, to_dir):
	for cmd in [['meld'], ['xxdiff'], ['diff', '-ur']]:
		if in_PATH(cmd[0]):
			code = os.spawnvp(os.P_WAIT, cmd[0], cmd + [from_dir, to_dir])
			if code:
				print "WARNING: command %s failed with exit code %d" % (cmd, code)
			return

class Status(object):
	__slots__ = ['old_snapshot_version', 'release_version', 'head_before_release', 'new_snapshot_version',
		     'head_at_release', 'created_archive', 'src_tests_passed', 'tagged', 'verified_uploads', 'updated_master_feed']
	def __init__(self):
		for name in self.__slots__:
			setattr(self, name, None)

		if os.path.isfile(release_status_file):
			for line in file(release_status_file):
				assert line.endswith('\n')
				line = line[:-1]
				name, value = line.split('=')
				setattr(self, name, value)
				info("Loaded status %s=%s", name, value)

	def save(self):
		tmp_name = release_status_file + '.new'
		tmp = file(tmp_name, 'w')
		try:
			lines = ["%s=%s\n" % (name, getattr(self, name)) for name in self.__slots__ if getattr(self, name)]
			tmp.write(''.join(lines))
			tmp.close()
			os.rename(tmp_name, release_status_file)
			info("Wrote status to %s", release_status_file)<commit_msg>Serialize falsy values to the empty string, so they will be read back as falsey<commit_after># Copyright (C) 2007, <NAME>
# See the README file for details, or visit http://0install.net.

import copy
import os, subprocess, shutil, tarfile
import urlparse, ftplib, httplib
from zeroinstall import SafeException
from zeroinstall.injector import model, qdom
from logging import info

release_status_file = os.path.abspath('release-status')

def check_call(*args, **kwargs):
	exitstatus = subprocess.call(*args, **kwargs)
	if exitstatus != 0:
		if type(args[0]) in (str, unicode):
			cmd = args[0]
		else:
			cmd = ' '.join(args[0])
		raise SafeException("Command failed with exit code %d:\n%s" % (exitstatus, cmd))

def show_and_run(cmd, args):
	print "Executing: %s %s" % (cmd, ' '.join("[%s]" % x for x in args))
	check_call(['sh', '-c', cmd, '-'] + args)

def suggest_release_version(snapshot_version):
	"""Given a snapshot version, suggest a suitable release version.
	>>> suggest_release_version('1.0-pre')
	'1.0'
	>>> suggest_release_version('0.9-post')
	'0.10'
	>>> suggest_release_version('3')
	Traceback (most recent call last):
		...
	SafeException: Version '3' is not a snapshot version (should end in -pre or -post)
	"""
	version = model.parse_version(snapshot_version)
	mod = version[-1]
	if mod == 0:
		raise SafeException("Version '%s' is not a snapshot version (should end in -pre or -post)" % snapshot_version)
	if mod > 0:
		# -post, so increment the number
		version[-2][-1] += 1
	version[-1] = 0	# Remove the modifier
	return model.format_version(version)

def publish(iface, **kwargs):
	args = [os.environ['0PUBLISH']]
	for k in kwargs:
		value = kwargs[k] 
		if value is True:
			args += ['--' + k.replace('_', '-')]
		elif value is not None:
			args += ['--' + k.replace('_', '-'), value]
	args.append(iface)
	info("Executing %s", args)
	check_call(args)

def get_singleton_impl(iface):
	impls = iface.implementations
	if len(impls) != 1:
		raise SafeException("Local feed '%s' contains %d versions! I need exactly one!" % (iface.uri, len(impls)))
	return impls.values()[0]

def backup_if_exists(name):
	if not os.path.exists(name):
		return
	backup = name + '~'
	if os.path.exists(backup):
		print "(deleting old backup %s)" % backup
		if os.path.isdir(backup):
			shutil.rmtree(backup)
		else:
			os.unlink(backup)
	os.rename(name, backup)
	print "(renamed old %s as %s; will delete on next run)" % (name, backup)

def get_choice(options):
	while True:
		choice = raw_input('/'.join(options) + ': ').lower()
		if not choice: continue
		for o in options:
			if o.lower().startswith(choice):
				return o

def make_archive_name(feed_name, version):
	return feed_name.lower().replace(' ', '-') + '-' + version

def in_PATH(prog):
	for x in os.environ['PATH'].split(':'):
		if os.path.isfile(os.path.join(x, prog)):
			return True
	return False

def show_diff(from_dir, to_dir):
	for cmd in [['meld'], ['xxdiff'], ['diff', '-ur']]:
		if in_PATH(cmd[0]):
			code = os.spawnvp(os.P_WAIT, cmd[0], cmd + [from_dir, to_dir])
			if code:
				print "WARNING: command %s failed with exit code %d" % (cmd, code)
			return

class Status(object):
	__slots__ = ['old_snapshot_version', 'release_version', 'head_before_release', 'new_snapshot_version',
		     'head_at_release', 'created_archive', 'src_tests_passed', 'tagged', 'verified_uploads', 'updated_master_feed']
	def __init__(self):
		for name in self.__slots__:
			setattr(self, name, None)

		if os.path.isfile(release_status_file):
			for line in file(release_status_file):
				assert line.endswith('\n')
				line = line[:-1]
				name, value = line.split('=')
				setattr(self, name, value)
				info("Loaded status %s=%s", name, value)

	def save(self):
		tmp_name = release_status_file + '.new'
		tmp = file(tmp_name, 'w')
		try:
			lines = ["%s=%s\n" % (name, getattr(self, name) or '') for name in self.__slots__ if hasattr(self, name)]
			tmp.write(''.join(lines))
			tmp.close()
			os.rename(tmp_name, release_status_file)
			info("Wrote status to %s", release_status_file)
{'fraction_non_alphanumeric': 0.1597655275629833, 'fraction_numerical': 0.008480917934647045, 'mean_word_length': 4.371064969859344, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7405236', 'n_tokens_mistral': 3048, 'n_tokens_neox': 2857, 'n_words': 796}