Author: ai0867
Date: Thu Nov 10 15:49:35 2011
New Revision: 51936

URL: http://svn.gna.org/viewcvs/wesnoth?rev=51936&view=rev
Log:
Further implement libgithub.

Most functions from libsvn that are used now have an equivalent.

Modified:
    trunk/data/tools/wesnoth/libgithub.py
    trunk/data/tools/wesnoth/wescamp.py

Modified: trunk/data/tools/wesnoth/libgithub.py
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/data/tools/wesnoth/libgithub.py?rev=51936&r1=51935&r2=51936&view=diff
==============================================================================
--- trunk/data/tools/wesnoth/libgithub.py (original)
+++ trunk/data/tools/wesnoth/libgithub.py Thu Nov 10 15:49:35 2011
@@ -10,7 +10,7 @@
 try:
     # Externally distributed, usually more up-to-date
     import simplejson as json
-except:
+except ImportError:
     # Distributed with python since 2.6
     import json
 import subprocess
@@ -54,16 +54,81 @@
         Returns whether anything changed.
         """
         logging.debug("Updating add-on {0}".format(self.name))
-        out, err = self._execute(["git", "pull"])
+        out, err = self._execute(["git", "pull"], check_error=True)
         #TODO: make this less hacky
         return len(out.split("\n")) > 2
 
-    #TODO: any commit has to be ended with "git push -u origin master"
-
+    def sync_from(self, src, exclude):
+        """Synchronises add-on from another directory.
+
+        src: Directory with new add-on version.
+        exclude: List of files to ignore.
+        Returns whether anything changed.
+        Raises libgithub.Error if the checkout is not clean.
+        """
+        logging.debug("Syncing add-on {0} from add-on server 
({1})".format(self.name, src))
+
+        status = self._status()
+        if status:
+            raise Error("Checkout is not 
clean:\n{0}".format("\n".join(status)))
+
+        self._rmtree(".", exclude)
+        #actual copying
+        shutil.copytree(src, self._get_dir(), ignore=lambda src,names: [n for 
n in names if n in exclude])
+        self._execute(["git", "add", self._get_dir()], check_error=True)
+
+        status = self._status()
+        return len(status) > 0
+
+    def commit(self, message):
+        """Commits and pushes add-on to git repo.
+
+        message: Commit message.
+        Raises libgithub.Error if something went wrong
+        """
+        logging.debug("Committing and pushing add-on {0}".format(self.name))
+
+        tmpname = os.tmpnam()
+        tmpfile = open(tmpname)
+        tmpfile.write(message)
+        tmpfile.close()
+        self._execute(["git", "commit", "-F", tmpname], check_error=True)
+        os.remove(tmpname)
+        self._execute(["git", "push", "-u", "origin", "master"], 
check_error=True)
+
+    # Internal functions
+
+    def _rmtree(self, directory, exclude):
+        logging.debug("Deleting tree {0}, except for {1}".format(self.name, 
",".join(exclude)))
+
+        # Ensure the os calls all happen in the right directory
+        # not needed for _execute, as that does the cwd manipulation itself
+        # so only the os.chdir and os.path.isdir here need it
+        # Another option would be to os.path.join with self._get_dir
+        os.chdir(self._get_dir())
+        for entry in os.listdir(directory):
+            if entry in exclude:
+                continue
+            if entry == ".git":
+                continue
+
+            relpath = os.path.join(directory, entry)
+
+            if os.path.isdir(relpath):
+                self._rmtree(relpath, exclude)
+                self._execute(["rmdir", "--ignore-fail-on-non-empty", relpath])
+            else:
+                self._execute(["git", "rm", relpath], check_error=True)
+
+    def _status(self):
+        out, err = self._execute(["git", "status", "--porcelain"])
+        if err:
+            raise Error("Status failed with message: {0}".format(err))
+        return [line for line in out.split('\n') if len(line)]
     def _get_dir(self):
         return os.path.join(self.github.directory, self.name)
-    def _execute(self, command):
-        return self.github._execute(command, cwd=self._get_dir())
+    def _execute(self, command, check_error = False):
+        return self.github._execute(command, cwd=self._get_dir(), 
check_error=check_error)
 
 _GITHUB_API_BASE = "https://api.github.com/";
 _GITHUB_API_REPOS = "orgs/wescamp/repos"
@@ -76,8 +141,8 @@
     def __init__(self, directory, version):
         """Initializes a GitHub object.
 
-        Directory: Directory in which the git repos for this wesnoth branch 
live.
-        Version: The version of this wesnoth branch.
+        directory: Directory in which the git repos for this wesnoth branch 
live.
+        version: The version of this wesnoth branch.
         """
         logging.debug("GitHub created with directory {0} and version 
{1}".format(directory, version))
         self.directory = directory
@@ -116,7 +181,7 @@
     def create_addon(self, name):
         """Creates a new add-on on github.
 
-        name: Name of the add-on
+        name: Name of the add-on.
         Returns an Addon object for the new add-on.
         """
         logging.debug("Creating new add-on {0}".format(name))
@@ -130,10 +195,10 @@
 
     def _clone(self, name, url):
         target = self._absolute_path(name)
-        self._execute(["git", "clone", url, target])
+        self._execute(["git", "clone", url, target], check_error=True)
 
     def _get_new_addons(self):
-        """Checks out any new add-ons
+        """Check out any new add-ons.
 
         Returns whether anything changed.
         """
@@ -170,7 +235,7 @@
                 for repo in repos if repo["name"].endswith(version_suffix)]
 
     def _github_repos_create(self, name):
-        """Create a new repository
+        """Create a new repository.
 
         name: The name of the add-on for which the repository will be created.
         """
@@ -188,11 +253,14 @@
         except IOError as e:
             raise Error("GitHub API failure: " + str(e))
 
-    def _execute(self, command, cwd=None):
+    def _execute(self, command, cwd=None, check_error=False):
         """Executes a command.
 
-        command: The command to execute
-        Returns stdout, stderr
+        command: The command to execute.
+        cwd: Directory to execute the command from.
+        check_error: Whether to raise an exception if there's stderr output.
+        Returns stdout, stderr.
+        Raises libgithub.Error if check_error and len(err).
         """
         logging.debug("execute command = '%s'", command)
 
@@ -209,5 +277,8 @@
         logging.debug("===== stdout ====\n\n\n%s\n\n\n===== stdout ====", out)
         logging.debug("===== stderr ====\n\n\n%s\n\n\n===== stderr ====", err)
 
+        if check_error and len(err):
+            raise Error("Failure executing command '{0}': {1}".format(" 
".join(command), err))
+
         return out, err
 

Modified: trunk/data/tools/wesnoth/wescamp.py
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/data/tools/wesnoth/wescamp.py?rev=51936&r1=51935&r2=51936&view=diff
==============================================================================
--- trunk/data/tools/wesnoth/wescamp.py (original)
+++ trunk/data/tools/wesnoth/wescamp.py Thu Nov 10 15:49:35 2011
@@ -184,9 +184,11 @@
         # The other files are present in wescamp and shouldn't be deleted.
         ignore_list = ["translations", "po", "campaign.def",
             "config.status", "Makefile"]
-        if(svn.copy_to_svn(temp_dir, ignore_list) and not use_git): #TODO: 
use_git
-
-            svn.commit("wescamp_client: automatic update of addon '"
+        if(addon_obj.sync_from(temp_dir, ignore_list)
+            if use_git
+            else svn.copy_to_svn(temp_dir, ignore_list)):
+
+            (addon_obj if use_git else svn).commit("wescamp_client: automatic 
update of addon '"
                 + addon + "'")
             logging.info("New version of addon '%s' uploaded.", addon)
         else:


_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits

Reply via email to