aboutsummaryrefslogtreecommitdiff
path: root/paludis/syncer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'paludis/syncer.cc')
-rw-r--r--paludis/syncer.cc288
1 files changed, 57 insertions, 231 deletions
diff --git a/paludis/syncer.cc b/paludis/syncer.cc
index 70f613a..2e7bbe6 100644
--- a/paludis/syncer.cc
+++ b/paludis/syncer.cc
@@ -1,8 +1,9 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ * Copyright (c) 2006, 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
* Copyright (c) 2006 Stephen Klimaszewski <steev@gentoo.org>
+ * Copyright (c) 2007 David Leverton <u01drl3@abdn.ac.uk>
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
@@ -19,8 +20,13 @@
*/
#include "syncer.hh"
+#include <paludis/about.hh>
+#include <paludis/environment.hh>
#include <paludis/util/fs_entry.hh>
+#include <paludis/util/log.hh>
#include <paludis/util/system.hh>
+#include <paludis/util/tokeniser.hh>
+#include <list>
/** \file
* Implementation for Syncer classes.
@@ -37,254 +43,74 @@ NoSuchSyncerError::NoSuchSyncerError(const std::string & format) throw () :
{
}
-namespace
-{
- /**
- * A Syncer for rsync:// syncing.
- *
- * \ingroup grpsyncer
- */
- class RsyncSyncer :
- public Syncer
- {
- private:
- std::string _local;
- std::string _remote;
-
- protected:
- RsyncSyncer(const std::string & local, const std::string & remote) :
- _local(local),
- _remote(remote)
- {
- if ((0 == _remote.compare(0, 4, "file", 0, 4)))
- _remote.erase(0, 7);
- }
-
- public:
- virtual void sync(const SyncOptions &) const;
-
- static Syncer::Pointer make(const std::string & local, const std::string & remote)
- {
- return Syncer::Pointer(new RsyncSyncer(local, remote));
- }
- };
-
- /**
- * A Syncer for svn:// (subversion) syncing.
- *
- * \ingroup grpsyncer
- */
- class SvnSyncer :
- public Syncer
- {
- private:
- std::string _local;
- std::string _remote;
-
- protected:
- SvnSyncer(const std::string & local, const std::string & remote) :
- _local(local),
- _remote(remote)
- {
- if ((0 == _remote.compare(0, 8, "svn+http", 0, 8)) || (0 == _remote.compare(0, 9, "svn+https", 0, 9)))
- _remote.erase(0, 4);
- }
-
- public:
- virtual void sync(const SyncOptions &) const;
- static Syncer::Pointer make(const std::string & local, const std::string & remote)
- {
- return Syncer::Pointer(new SvnSyncer(local, remote));
- }
- };
-
- /**
- * A Syncer for Git syncing.
- *
- * \ingroup grpsyncer
- */
- class GitSyncer :
- public Syncer
- {
- private:
- std::string _local;
- std::string _remote;
-
- protected:
- GitSyncer(const std::string & local, const std::string & remote) :
- _local(local),
- _remote(remote)
- {
- if (0 == _remote.compare(0, 8, "git+http", 0, 8))
- _remote.erase(0, 4);
- }
-
- public:
- virtual void sync(const SyncOptions &) const;
- static Syncer::Pointer make(const std::string & local, const std::string & remote)
- {
- return Syncer::Pointer(new GitSyncer(local, remote));
- }
- };
-
- /**
- * A Syncer for cvs+ext://, cvs+pserver:// (CVS) syncing.
- *
- * \ingroup grpsyncer
- */
- class CvsSyncer :
- public Syncer
- {
- private:
- std::string _local;
- std::string _remote;
- std::string _module;
-
- bool _pserver;
-
- protected:
- CvsSyncer(const std::string & local, const std::string & remote) :
- _local(local),
- _remote(remote),
- _pserver(false)
- {
- if (0 == _remote.compare(0, 11, "cvs+pserver", 0, 11))
- {
- _remote = ":pserver:" + _remote.erase(0, 14);
- _pserver = true;
- }
- else if ((0 == _remote.compare(0, 7, "cvs+ssh", 0, 7)) || (0 == _remote.compare(0, 7, "cvs+ext", 0, 7)))
- {
- _remote = ":ext:" + _remote.erase(0, 10);
- }
-
- std::string::size_type pos(_remote.find_last_of(":"));
-
- if (std::string::npos == pos)
- throw SyncCvsUrlInvalid(_remote);
-
- _module = std::string(_remote, pos + 1);
- _remote.erase(pos);
- }
-
- public:
- virtual void sync(const SyncOptions &) const;
- static Syncer::Pointer make(const std::string & local, const std::string & remote)
- {
- return Syncer::Pointer(new CvsSyncer(local, remote));
- }
- };
-}
-
-void
-RsyncSyncer::sync(const SyncOptions & opts) const
+SyncFailedError::SyncFailedError(const std::string & local, const std::string & remote) throw () :
+ PackageActionError("sync of '" + local + "' from '" + remote + "' failed")
{
- Context context("When performing sync via rsync from '" + _remote + "' to '"
- + _local + "':");
-
- FSEntry(_local).mkdir();
-
- std::string exclude;
- if (! opts.exclude_from.empty())
- exclude = "--exclude-from " + opts.exclude_from + " ";
-
- std::string cmd("rsync --recursive --links --safe-links --perms --times "
- "--compress --force --whole-file --delete --delete-after --stats "
- "--timeout=180 --exclude=/distfiles --exclude=/packages "
- "--exclude=/local --exclude=/.cache --progress " + exclude + "'" + _remote +
- "' '" + _local + "/'");
-
- if (0 != run_command(cmd))
- throw SyncFailedError(_local, _remote);
}
-void
-SvnSyncer::sync(const SyncOptions &) const
+SyncFailedError::SyncFailedError(const std::string & msg) throw () :
+ PackageActionError(msg)
{
- Context context("When performing sync via subversion from '" + _remote + "' to '"
- + _local + "':");
-
- std::string cmd("svn checkout '" + _remote + "' '" + _local + "/'");
-
- if (0 != run_command(cmd))
- throw SyncFailedError(_local, _remote);
}
-void
-GitSyncer::sync(const SyncOptions &) const
+DefaultSyncer::DefaultSyncer(const SyncerParams & params)
+ : _local(params.local), _remote(params.remote), _environment(params.environment)
{
- Context context("When performing sync via git from '" + _remote + "' to '"
- + _local + "':");
-
- FSEntry git_dir(_local + "/.git");
- FSEntry repo_dir(_local);
- int status;
+ std::string::size_type p(_remote.find("://")), q(_remote.find(":"));
+ if (std::string::npos == p)
+ throw NoSuchSyncerError(_remote);
- if (repo_dir.is_directory() && ! git_dir.is_directory())
- throw SyncGitDirectoryExists(_local);
+ const std::string & format = _remote.substr(0, std::min(p, q));
+ if (q < p)
+ _remote = _remote.substr(q < p ? q + 1 : 0);
- if (git_dir.is_directory())
- status = run_command_in_directory("git pull", repo_dir);
- else
- status = run_command("git clone '"+ _remote + "' '" + _local + "'");
+ std::list<std::string> syncers_dirs;
+ WhitespaceTokeniser::get_instance()->tokenise(_environment->syncers_dirs(),
+ std::back_inserter(syncers_dirs));
- if (0 != status)
- throw SyncFailedError(_local, _remote);
-}
-
-void
-CvsSyncer::sync(const SyncOptions &) const
-{
- Context context("When performing sync via CVS from '" + _remote + "' to '"
- + _local + "':");
-
- std::string cmd("cvs -d '" + _remote + "' login");
- FSEntry d(FSEntry(_local).dirname());
+ Log::get_instance()->message(ll_debug, lc_context, "looking for syncer protocol '"
+ + stringify(format) + "'");
- if (_pserver)
+ FSEntry syncer("/var/empty");
+ bool ok(false);
+ for (std::list<std::string>::const_iterator d(syncers_dirs.begin()),
+ d_end(syncers_dirs.end()) ; d != d_end && ! ok; ++d)
{
- if (0 != run_command_in_directory(cmd, d))
- throw SyncFailedError(_local, _remote + ":" + _module);
- }
+ syncer = FSEntry(*d) / ("do" + format);
+ if (syncer.exists() && syncer.has_permission(fs_ug_owner, fs_perm_execute))
+ ok = true;
- cmd = std::string("cvs -d '" + _remote + "' checkout '" + _module + "'");
- if (0 != run_command_in_directory(cmd, d))
- throw SyncFailedError(_local, _remote + ":" + _module);
-}
+ Log::get_instance()->message(ll_debug, lc_no_context, "Trying '" + stringify(syncer) + "': "
+ + (ok ? "ok" : "not ok"));
+ }
-SyncFailedError::SyncFailedError(const std::string & local, const std::string & remote) throw () :
- PackageActionError("sync of '" + local + "' from '" + remote + "' failed")
-{
-}
+ if (! ok)
+ throw NoSuchSyncerError(format);
-SyncFailedError::SyncFailedError(const std::string & msg) throw () :
- PackageActionError(msg)
-{
+ _syncer = stringify(syncer);
}
-SyncGitDirectoryExists::SyncGitDirectoryExists(const std::string & local) throw () :
- SyncFailedError("'" + local + "' exists but it is not a Git repository")
+void
+DefaultSyncer::sync(const SyncOptions & opts) const
{
-}
-SyncCvsUrlInvalid::SyncCvsUrlInvalid(const std::string & url) throw () :
- SyncFailedError("'" + url + "' is not a valid URL for a CVS repository")
-{
-}
-
-SyncerMaker::SyncerMaker()
-{
- register_maker("rsync", &RsyncSyncer::make);
- register_maker("file", &RsyncSyncer::make);
- register_maker("svn", &SvnSyncer::make);
- register_maker("svn+ssh", &SvnSyncer::make);
- register_maker("svn+http", &SvnSyncer::make);
- register_maker("svn+https", &SvnSyncer::make);
- register_maker("git", &GitSyncer::make);
- register_maker("git+ssh", &GitSyncer::make);
- register_maker("git+http", &GitSyncer::make);
- register_maker("cvs+ext", &CvsSyncer::make);
- register_maker("cvs+ssh", &CvsSyncer::make);
- register_maker("cvs+pserver", &CvsSyncer::make);
+ MakeEnvCommand cmd(make_env_command(stringify(_syncer) + " '" + _local + "' '" + _remote + "'")
+ ("PKGMANAGER", PALUDIS_PACKAGE "-" + stringify(PALUDIS_VERSION_MAJOR) + "." +
+ stringify(PALUDIS_VERSION_MINOR) + "." +
+ stringify(PALUDIS_VERSION_MICRO) +
+ (std::string(PALUDIS_SUBVERSION_REVISION).empty() ?
+ std::string("") : "-r" + std::string(PALUDIS_SUBVERSION_REVISION)))
+ ("PALUDIS_CONFIG_DIR", SYSCONFDIR "/paludis/")
+ ("PALUDIS_BASHRC_FILES", _environment->bashrc_files())
+ ("PALUDIS_HOOK_DIRS", _environment->hook_dirs())
+ ("PALUDIS_FETCHERS_DIRS", _environment->fetchers_dirs())
+ ("PALUDIS_SYNCERS_DIRS", _environment->syncers_dirs())
+ ("PALUDIS_COMMAND", _environment->paludis_command())
+ ("PALUDIS_EBUILD_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
+ ("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis"))
+ ("PALUDIS_SYNC_EXCLUDE_FROM", opts.exclude_from));
+
+ if (run_command(cmd))
+ throw SyncFailedError(_local, _remote);
}