From 9d88d6a8c38e1a35f5749d06214f92513414ed67 Mon Sep 17 00:00:00 2001 From: Daniel Narvaez Date: Wed, 14 Nov 2012 16:50:21 +0000 Subject: Refactor dnbuild into devbot --- (limited to 'devbot') diff --git a/devbot/build.py b/devbot/build.py new file mode 100644 index 0000000..22c1ccf --- /dev/null +++ b/devbot/build.py @@ -0,0 +1,167 @@ +#!/usr/bin/python -u + +from distutils import sysconfig +import glob +import json +import os +import multiprocessing +import shutil +import sys +import subprocess + +from devbot import config +from devbot import environ + +state = { "built_modules": {} } + +def get_state_path(): + return os.path.join(config.devbot_dir, "state.json") + +def load_state(): + global state + + state_path = get_state_path() + if os.path.exists(state_path): + state = json.load(open(state_path)) + +def save_state(): + json.dump(state, open(get_state_path(), "w+")) + +def add_path(name, path): + if name not in os.environ: + os.environ[name] = path + return + + splitted = os.environ[name].split(":") + splitted.append(path) + + os.environ[name] = ":".join(splitted) + +def get_module_source_dir(module): + return os.path.join(config.source_dir, module["name"]) + +def get_module_build_dir(module): + return os.path.join(config.build_dir, module["name"]) + +def get_module_commit_id(module): + orig_cwd = os.getcwd() + os.chdir(get_module_source_dir(module)) + + commit_id = subprocess.check_output(["git", "rev-parse", "HEAD"]) + + os.chdir(orig_cwd) + + return commit_id.strip() + +def run_command(args): + print " ".join(args) + subprocess.check_call(args) + +def unlink_libtool_files(): + orig_cwd = os.getcwd() + os.chdir(config.lib_dir) + + for filename in glob.glob("*.la"): + os.unlink(filename) + + os.chdir(orig_cwd) + +def pull_source(module): + module_dir = get_module_source_dir(module) + + if os.path.exists(module_dir): + os.chdir(module_dir) + + run_command(["git", "remote", "set-url", "origin", module["repo"]]) + run_command(["git", "remote", "update", "origin"]) + else: + os.chdir(config.source_dir) + run_command(["git", "clone", "--progress", + module["repo"], module["name"]]) + os.chdir(module_dir) + + branch = module.get("branch", "master") + run_command(["git", "checkout", branch]) + +def build_autotools(module): + autogen = os.path.join(get_module_source_dir(module), "autogen.sh") + + jobs = multiprocessing.cpu_count() * 2 + + run_command([autogen, + "--prefix", config.install_dir, + "--libdir", config.lib_dir]) + + run_command(["make", "-j", "%d" % jobs]) + run_command(["make", "install"]) + + unlink_libtool_files() + +def build_activity(module): + run_command(["./setup.py", "install", "--prefix", config.install_dir]) + +def build_module(module): + module_source_dir = get_module_source_dir(module) + + if module.get("out-of-source", True): + module_build_dir = get_module_build_dir(module) + + if not os.path.exists(module_build_dir): + os.mkdir(module_build_dir) + + os.chdir(module_build_dir) + else: + os.chdir(module_source_dir) + + if os.path.exists(os.path.join(module_source_dir, "setup.py")): + build_activity(module) + elif os.path.exists(os.path.join(module_source_dir, "autogen.sh")): + build_autotools(module) + else: + print "Unknown build system" + sys.exit(1) + + state["built_modules"][module["name"]] = get_module_commit_id(module) + save_state() + +def clear_built_modules(modules, index): + if index < len(modules) - 1: + for module in modules[index + 1:]: + name = module["name"] + if name in state["built_modules"]: + del state["built_modules"][name] + +def rmtree(dir): + print "Deleting %s" % dir + shutil.rmtree(dir, ignore_errors=True) + +def build(): + environ.setup() + load_state() + + modules = config.load_modules() + + for i, module in enumerate(modules): + print "\n=== Building %s ===\n" % module["name"] + + try: + pull_source(module) + + old_commit_id = state["built_modules"].get(module["name"], None) + new_commit_id = get_module_commit_id(module) + + if old_commit_id is None or old_commit_id != new_commit_id: + clear_built_modules(modules, i) + build_module(module) + else: + print "\n* Already built, skipping *" + except subprocess.CalledProcessError: + sys.exit(1) + +def clean(): + rmtree(config.install_dir) + rmtree(config.build_dir) + + for module in config.load_modules(): + if not module.get("out-of-source", True): + rmtree(get_module_source_dir(module)) diff --git a/devbot/config.py b/devbot/config.py index b63c6e6..11a861c 100644 --- a/devbot/config.py +++ b/devbot/config.py @@ -3,11 +3,52 @@ import os from devbot import distro -config_path = None +config_dir = None +install_dir = None +source_dir = None +build_dir = None +lib_dir = None +devbot_dir = None +share_dir = None +bin_dir = None +etc_dir = None +use_lib64 = os.uname()[4] == "x86_64" -def set_path(path): - global config_path - config_path = path +if use_lib64: + system_lib_dir = "/usr/lib64" +else: + system_lib_dir = "/usr/lib" + +def set_config_dir(dir): + global config_dir + config_dir = dir + +def set_install_dir(dir): + global install_dir + global devbot_dir + global share_dir + global bin_dir + global etc_dir + global lib_dir + + install_dir = dir + devbot_dir = os.path.join(install_dir, "devbot") + share_dir = os.path.join(install_dir, "share") + bin_dir = os.path.join(install_dir, "bin") + etc_dir = os.path.join(install_dir, "etc") + + if use_lib64: + lib_dir = os.path.join(install_dir, "lib64") + else: + lib_dir = os.path.join(install_dir, "lib") + +def set_source_dir(dir): + global source_dir + source_dir = dir + +def set_build_dir(dir): + global build_dir + build_dir = dir def load_packages(): packages = _load_deps_json("packages-%s" % distro.get_system_version()) @@ -26,7 +67,22 @@ def load_checks(): return checks +def load_modules(): + version = distro.get_system_version() + + module_files = ["system-%s.json" % version, + "sugar.json", + "activities.json"] + + modules = [] + + for module_file in module_files: + path = os.path.join(config_dir, "modules", module_file) + modules.extend(json.load(open(path))) + + return modules + def _load_deps_json(name): - path = os.path.join(config_path, "%s.json" % name) + path = os.path.join(config_dir, "deps", "%s.json" % name) return json.load(open(path)) diff --git a/devbot/environ.py b/devbot/environ.py new file mode 100644 index 0000000..d18370d --- /dev/null +++ b/devbot/environ.py @@ -0,0 +1,85 @@ +from distutils import sysconfig +import os + +from devbot import config + +def setup(): + _setup_dirs() + _setup_gconf() + _setup_variables() + +def _add_path(name, path): + if name not in os.environ: + os.environ[name] = path + return + + splitted = os.environ[name].split(":") + splitted.append(path) + + os.environ[name] = ":".join(splitted) + +def _setup_variables(): + _add_path("LD_LIBRARY_PATH", config.lib_dir) + _add_path("PATH", config.bin_dir) + + _add_path("GIO_EXTRA_MODULES", + os.path.join(config.system_lib_dir, "gio", "modules")) + _add_path("GI_TYPELIB_PATH", + os.path.join(config.lib_dir, "girepository-1.0")) + _add_path("GI_TYPELIB_PATH", + os.path.join(config.system_lib_dir, "girepository-1.0")) + _add_path("PKG_CONFIG_PATH", + os.path.join(config.lib_dir, "pkgconfig")) + _add_path("GST_PLUGIN_PATH", + os.path.join(config.lib_dir , "gstreamer-1.0")) + _add_path("GST_REGISTRY", + os.path.join(config.devbot_dir, "gstreamer.registry")) + _add_path("PYTHONPATH", + sysconfig.get_python_lib(prefix=config.install_dir)) + _add_path("PYTHONPATH", + sysconfig.get_python_lib(prefix=config.install_dir, + plat_specific=True)) + + _add_path("XDG_DATA_DIRS", "/usr/share") + _add_path("XDG_DATA_DIRS", config.share_dir) + + _add_path("XDG_CONFIG_DIRS", "/etc") + _add_path("XDG_CONFIG_DIRS", config.etc_dir) + + os.environ["GTK_DATA_PREFIX"] = config.install_dir + os.environ["GTK_PATH"] = os.path.join(config.lib_dir, "gtk-2.0") + +def _setup_gconf(): + gconf_dir = os.path.join(config.etc_dir, "gconf") + gconf_pathdir = os.path.join(gconf_dir, "2") + + if not os.path.exists(gconf_pathdir): + os.makedirs(gconf_pathdir) + + gconf_path = os.path.join(gconf_pathdir, "path.jhbuild") + if not os.path.exists(gconf_path): + input = open("/etc/gconf/2/path") + output = open(gconf_path, "w") + + for line in input.readlines(): + if "/etc/gconf" in line: + output.write(line.replace("/etc/gconf", gconf_dir)) + output.write(line) + + output.close() + input.close() + + os.environ["GCONF_DEFAULT_SOURCE_PATH"] = gconf_path + + os.environ["GCONF_SCHEMA_INSTALL_SOURCE"] = \ + "xml:merged:" + os.path.join(gconf_dir, "gconf.xml.defaults") + +def _setup_dirs(): + for dir in [config.source_dir, + config.install_dir, + config.build_dir, + config.share_dir, + config.devbot_dir, + os.path.join(config.share_dir, "aclocal")]: + if not os.path.exists(dir): + os.mkdir(dir) diff --git a/devbot/run.py b/devbot/run.py new file mode 100644 index 0000000..c27862f --- /dev/null +++ b/devbot/run.py @@ -0,0 +1,9 @@ +#!/usr/bin/python -u + +import os + +from devbot import environ + +def run(args): + environ.setup() + os.execlp(args[0], *args) diff --git a/devbot/shell.py b/devbot/shell.py new file mode 100644 index 0000000..abe0695 --- /dev/null +++ b/devbot/shell.py @@ -0,0 +1,11 @@ +#!/usr/bin/python + +import os + +from devbot import environ + +def start(): + environ.setup() + + user_shell = os.environ.get("SHELL", "/bin/sh") + os.execlp(user_shell, user_shell) -- cgit v0.9.1