Add support for multiple repositories in `emerge --sync`.
authorArfrever Frehtes Taifersar Arahesis <Arfrever@Apache.Org>
Mon, 22 Jul 2013 22:06:58 +0000 (00:06 +0200)
committerArfrever Frehtes Taifersar Arahesis <Arfrever@Apache.Org>
Mon, 22 Jul 2013 22:06:58 +0000 (00:06 +0200)
Configuration of synchronization is specified by new attributes
supported in repos.conf: sync-cvs-repo, sync-type, sync-uri.

SYNC variable is no longer supported, since it could not override
gentoo.sync-uri attribute now set in default configuration of
repositories (/usr/share/portage/config/repos.conf).

12 files changed:
RELEASE-NOTES
bin/emerge-webrsync
cnf/make.globals
cnf/repos.conf
man/emerge.1
man/make.conf.5
man/portage.5
pym/_emerge/actions.py
pym/portage/dbapi/bintree.py
pym/portage/package/ebuild/_config/special_env_vars.py
pym/portage/package/ebuild/config.py
pym/portage/repository/config.py

index e509a52131e97a534e6351ab667fe36c0b234c89..191eb31f080b66db605fd35b911fd096a9fba7bf 100644 (file)
@@ -13,6 +13,8 @@ portage-2.1.12.14
 
 * FEATURES=userpriv and usersandbox are enabled by default.
 * FEATURES=usersync is enabled by default.
+* New sync-cvs-repo, sync-type and sync-uri attributes in repos.conf replace
+  SYNC variable.
 
 portage-2.1.12
 ==================================
index 261e7df687a1275f35f97703d7de444fcf808b84..85730a2cf4fa6dd9306bf668c9fd71c76f3aede6 100755 (executable)
@@ -44,7 +44,7 @@ eval "$("${portageq}" envvar -v DISTDIR EPREFIX FEATURES \
        PORTAGE_BIN_PATH PORTAGE_CONFIGROOT PORTAGE_GPG_DIR \
        PORTAGE_NICENESS PORTAGE_REPOSITORIES PORTAGE_RSYNC_EXTRA_OPTS \
        PORTAGE_RSYNC_OPTS PORTAGE_TMPDIR \
-       SYNC USERLAND http_proxy ftp_proxy)"
+       USERLAND http_proxy ftp_proxy)"
 export http_proxy ftp_proxy
 
 source "${PORTAGE_BIN_PATH}"/isolated-functions.sh || exit 1
@@ -55,6 +55,7 @@ if [[ -z ${repo_location} ]]; then
        eecho "Repository '${repo_name}' not found"
        exit 1
 fi
+repo_sync_type=$(__repo_key "${repo_name}" sync-type)
 
 # If PORTAGE_NICENESS is overriden via the env then it will
 # still pass through the portageq call and override properly.
@@ -500,14 +501,14 @@ main() {
 
        # This is a sanity check to help prevent people like funtoo users
        # from accidentally wiping out their git tree.
-       if [[ -n $SYNC && ${SYNC#rsync:} = $SYNC ]] ; then
-               echo "The current SYNC variable setting does not refer to an rsync URI:" >&2
+       if [[ -n ${repo_sync_type} && ${repo_sync_type} != rsync ]] ; then
+               echo "The current sync-type attribute of repository 'gentoo' is not set to 'rsync':" >&2
                echo >&2
-               echo "  SYNC=$SYNC" >&2
+               echo "  sync-type=${repo_sync_type}" >&2
                echo >&2
                echo "If you intend to use emerge-webrsync then please" >&2
-               echo "adjust SYNC to refer to an rsync URI." >&2
-               echo "emerge-webrsync exiting due to abnormal SYNC setting." >&2
+               echo "adjust sync-type and sync-uri attributes to refer to rsync." >&2
+               echo "emerge-webrsync exiting due to abnormal sync-type setting." >&2
                exit 1
        fi
 
index c4ed900d95947c737c90b7177a63d6971d85b364..3c3ddc56e5eff75b12ed391e66a06ee280fafc5c 100644 (file)
@@ -19,9 +19,6 @@ LDFLAGS=""
 FFLAGS=""
 FCFLAGS=""
 
-# Default rsync mirror
-SYNC="rsync://rsync.gentoo.org/gentoo-portage"
-
 # Default distfiles mirrors. This rotation has multiple hosts and is reliable.
 # Approved by the mirror-admin team.
 GENTOO_MIRRORS="http://distfiles.gentoo.org"
index 8bdf2bfaf9a8a1420cdfa11db2f51da3558d3a49..8c657daae3259e42e01ea05c689b74293b5224a7 100644 (file)
@@ -3,3 +3,5 @@ main-repo = gentoo
 
 [gentoo]
 location = /usr/portage
+sync-type = rsync
+sync-uri = rsync://rsync.gentoo.org/gentoo-portage
index da6bcbab77d11b89d5c9ee96f878d65a3d9acb9b..cd4595d9a136dd357aa7cc8348cec0021fd1c5a2 100644 (file)
@@ -1,4 +1,4 @@
-.TH "EMERGE" "1" "May 2013" "Portage VERSION" "Portage"
+.TH "EMERGE" "1" "Jul 2013" "Portage VERSION" "Portage"
 .SH "NAME"
 emerge \- Command\-line interface to the Portage system
 .SH "SYNOPSIS"
@@ -235,20 +235,15 @@ the package name.  \fBTake caution\fR as the descriptions are also
 matched as regular expressions.
 .TP
 .BR \-\-sync
-This updates the portage tree that is located in the
-directory that the PORTDIR variable refers to (default
-location is /usr/portage). The SYNC variable specifies
-the remote URI from which files will be synchronized.
+Updates repositories, for which sync\-type and sync\-uri attributes are
+set in repos.conf. See \fBportage\fR(5) for more information.
 The \fBPORTAGE_SYNC_STALE\fR variable configures
 warnings that are shown when emerge \-\-sync has not
 been executed recently.
 
 \fBWARNING:\fR
-The emerge \-\-sync action will modify and/or delete
-files located inside the directory that the PORTDIR
-variable refers to (default location is /usr/portage).
-For more information, see the PORTDIR documentation in
-the make.conf(5) man page.
+The emerge \-\-sync action will revert local changes (e.g. modifications or
+additions of files) inside repositories synchronized using rsync.
 
 \fBNOTE:\fR
 The \fBemerge\-webrsync\fR program will download the entire
index fcab08decf965e204b8b058fc633cc4d4477fe4f..6a34cc9c9df4a0a3fc3a1593affa53c669a68f90 100644 (file)
@@ -966,28 +966,6 @@ Defines the location where created RPM packages will be stored.
 .br
 Defaults to ${PORTDIR}/rpm.
 .TP
-\fBSYNC\fR = \fI[RSYNC]\fR
-Insert your preferred rsync mirror here.  This rsync server
-is used to sync the local portage tree when `emerge \-\-sync` is run.
-.br
-Defaults to rsync://rsync.gentoo.org/gentoo\-portage
-.RS
-.TP
-.B Usage:
-(rsync|ssh)://[username@]hostname[:port]/(module|path)
-.TP
-.B Examples:
-rsync://private\-mirror.com/portage\-module
-.br
-rsync://rsync\-user@private\-mirror.com:873/gentoo\-portage
-.br
-ssh://ssh\-user@192.168.0.1:22/usr/portage
-.br
-ssh://ssh\-user@192.168.0.1:22/\\${HOME}/portage\-storage
-.TP
-Note: For the ssh:// scheme, key\-based authentication might be of interest.
-.RE
-.TP
 \fBUNINSTALL_IGNORE\fR = \fI[space delimited list of fnmatch patterns]\fR
 This variable prevents uninstallation of files that match
 specific \fBfnmatch\fR(3) patterns. In order to ignore file
index 81a026abe9503288296f50c3568b3b0f66f42154..48b7ea94a2db5beb8fd783e085a3b9539fe15f39 100644 (file)
@@ -819,6 +819,39 @@ since operations performed by these tools are inherently
 .TP
 .B priority
 Specifies priority of given repository.
+.TP
+.B sync\-cvs\-repo
+Specifies CVS repository.
+.TP
+.B sync\-type
+Specifies type of synchronization.
+.br
+Valid values: cvs, git, rsync
+.TP
+.B sync\-uri
+Specifies URI of repository used for synchronization performed by `emerge \-\-sync`.
+.RS
+.TP
+Syntax:
+cvs: [cvs://]:access_method:[username@]hostname[:port]:/path
+.br
+git: (git|git+ssh|http|https)://[username@]hostname[:port]/path
+.br
+rsync: (rsync|ssh)://[username@]hostname[:port]/(module|path)
+.TP
+Examples:
+.RS
+rsync://private\-mirror.com/portage\-module
+.br
+rsync://rsync\-user@private\-mirror.com:873/gentoo\-portage
+.br
+ssh://ssh\-user@192.168.0.1:22/usr/portage
+.br
+ssh://ssh\-user@192.168.0.1:22/\\${HOME}/portage\-storage
+.RE
+.TP
+Note: For the ssh:// scheme, key\-based authentication might be of interest.
+.RE
 .RE
 
 .I Example:
@@ -856,6 +889,7 @@ masters = gentoo kde
 masters =
 .fi
 .RE
+.RE
 .TP
 .BR /etc/portage/env/
 .RS
index 6d5d535ef8e5664121743e1d7c42a4602e8a1362..80afb0b6226213831dd4ef87faedf97a1237c423 100644 (file)
@@ -1644,7 +1644,7 @@ def action_info(settings, trees, myopts, myfiles):
                          'PORTDIR_OVERLAY', 'PORTAGE_BUNZIP2_COMMAND',
                          'PORTAGE_BZIP2_COMMAND',
                          'USE', 'CHOST', 'CFLAGS', 'CXXFLAGS',
-                         'ACCEPT_KEYWORDS', 'ACCEPT_LICENSE', 'SYNC', 'FEATURES',
+                         'ACCEPT_KEYWORDS', 'ACCEPT_LICENSE', 'FEATURES',
                          'EMERGE_DEFAULT_OPTS']
 
                myvars.extend(portage.util.grabfile(settings["PORTDIR"]+"/profiles/info_vars"))
@@ -2009,37 +2009,62 @@ def action_search(root_config, myopts, myfiles, spinner):
                                sys.exit(1)
                        searchinstance.output()
 
-def action_sync(settings, trees, mtimedb, myopts, myaction):
-       enter_invalid = '--ask-enter-invalid' in myopts
+def action_sync(settings, trees, myopts):
        xterm_titles = "notitles" not in settings.features
        emergelog(xterm_titles, " === sync")
+
+       for repo in settings.repositories:
+               if repo.sync_type is not None:
+                       returncode = _sync_repo(repo, settings, trees, myopts)
+                       if returncode != os.EX_OK:
+                               return returncode
+
+       # Reload the whole config from scratch.
+       portage._sync_disabled_warnings = False
+       settings, trees, mtimedb = load_emerge_config(trees=trees)
+       adjust_configs(myopts, trees)
        portdb = trees[settings['EROOT']]['porttree'].dbapi
-       myportdir = portdb.porttree_root
-       if not myportdir:
-               myportdir = settings.get('PORTDIR', '')
-               if myportdir and myportdir.strip():
-                       myportdir = os.path.realpath(myportdir)
-               else:
-                       myportdir = None
+       root_config = trees[settings['EROOT']]['root_config']
+
+       if myopts.get('--package-moves') != 'n' and _global_updates(trees, mtimedb["updates"], quiet=("--quiet" in myopts)):
+               mtimedb.commit()
+               # Reload the whole config from scratch.
+               settings, trees, mtimedb = load_emerge_config(trees=trees)
+               adjust_configs(myopts, trees)
+               portdb = trees[settings['EROOT']]['porttree'].dbapi
+               root_config = trees[settings['EROOT']]['root_config']
+
+       mybestpv = portdb.xmatch("bestmatch-visible", portage.const.PORTAGE_PACKAGE_ATOM)
+       mypvs = portage.best(trees[settings['EROOT']]['vartree'].dbapi.match(portage.const.PORTAGE_PACKAGE_ATOM))
+
+       chk_updated_cfg_files(settings["EROOT"], portage.util.shlex_split(settings.get("CONFIG_PROTECT", "")))
+
+       if mybestpv != mypvs and "--quiet" not in myopts:
+               print()
+               print(warn(" * ")+bold("An update to portage is available.")+" It is _highly_ recommended")
+               print(warn(" * ")+"that you update portage now, before any other packages are updated.")
+               print()
+               print(warn(" * ")+"To update portage, run 'emerge --oneshot portage' now.")
+               print()
+
+       display_news_notification(root_config, myopts)
+       return os.EX_OK
+
+def _sync_repo(repo, settings, trees, myopts):
+       enter_invalid = '--ask-enter-invalid' in myopts
+       xterm_titles = "notitles" not in settings.features
+       msg = ">>> Synchronization of repository '%s' located in '%s'..." % (repo.name, repo.location)
+       emergelog(xterm_titles, msg)
+       writemsg_level(msg + "\n")
        out = portage.output.EOutput()
-       global_config_path = GLOBAL_CONFIG_PATH
-       if portage.const.EPREFIX:
-               global_config_path = os.path.join(portage.const.EPREFIX,
-                               GLOBAL_CONFIG_PATH.lstrip(os.sep))
-       if not myportdir:
-               sys.stderr.write("!!! PORTDIR is undefined.  " + \
-                       "Is %s/make.globals missing?\n" % global_config_path)
-               sys.exit(1)
-       if myportdir[-1]=="/":
-               myportdir=myportdir[:-1]
        try:
-               st = os.stat(myportdir)
+               st = os.stat(repo.location)
        except OSError:
                st = None
        if st is None:
-               print(">>>",myportdir,"not found, creating it.")
-               portage.util.ensure_dirs(myportdir, mode=0o755)
-               st = os.stat(myportdir)
+               print(">>> '%s' not found, creating it." % repo.location)
+               portage.util.ensure_dirs(repo.location, mode=0o755)
+               st = os.stat(repo.location)
 
        usersync_uid = None
        spawn_kwargs = {}
@@ -2072,24 +2097,15 @@ def action_sync(settings, trees, mtimedb, myopts, myaction):
                if rval != os.EX_OK:
                        return rval
 
-       syncuri = settings.get("SYNC", "").strip()
-       if not syncuri:
-               writemsg_level("!!! SYNC is undefined. " + \
-                       "Is %s/make.globals missing?\n" % global_config_path,
-                       noiselevel=-1, level=logging.ERROR)
-               return 1
+       syncuri = repo.sync_uri
 
        vcs_dirs = frozenset(VCS_DIRS)
-       vcs_dirs = vcs_dirs.intersection(os.listdir(myportdir))
+       vcs_dirs = vcs_dirs.intersection(os.listdir(repo.location))
 
        os.umask(0o022)
        dosyncuri = syncuri
        updatecache_flg = False
-       git = False
-       if myaction == "metadata":
-               print("skipping sync")
-               updatecache_flg = True
-       elif ".git" in vcs_dirs:
+       if repo.sync_type == "git":
                # Update existing git repository, and ignore the syncuri. We are
                # going to trust the user and assume that the user is in the branch
                # that he/she wants updated. We'll let the user manage branches with
@@ -2101,32 +2117,31 @@ def action_sync(settings, trees, mtimedb, myopts, myaction):
                                writemsg_level("!!! %s\n" % l,
                                        level=logging.ERROR, noiselevel=-1)
                        return 1
-               msg = ">>> Starting git pull in %s..." % myportdir
+               msg = ">>> Starting git pull in %s..." % repo.location
                emergelog(xterm_titles, msg )
                writemsg_level(msg + "\n")
                exitcode = portage.process.spawn_bash("cd %s ; git pull" % \
-                       (portage._shell_quote(myportdir),),
+                       (portage._shell_quote(repo.location),),
                        **portage._native_kwargs(spawn_kwargs))
                if exitcode != os.EX_OK:
-                       msg = "!!! git pull error in %s." % myportdir
+                       msg = "!!! git pull error in %s." % repo.location
                        emergelog(xterm_titles, msg)
                        writemsg_level(msg + "\n", level=logging.ERROR, noiselevel=-1)
                        return exitcode
-               msg = ">>> Git pull in %s successful" % myportdir
+               msg = ">>> Git pull in %s successful" % repo.location
                emergelog(xterm_titles, msg)
                writemsg_level(msg + "\n")
-               git = True
-       elif syncuri[:8]=="rsync://" or syncuri[:6]=="ssh://":
+       elif repo.sync_type == "rsync":
                for vcs_dir in vcs_dirs:
                        writemsg_level(("!!! %s appears to be under revision " + \
                                "control (contains %s).\n!!! Aborting rsync sync.\n") % \
-                               (myportdir, vcs_dir), level=logging.ERROR, noiselevel=-1)
+                               (repo.location, vcs_dir), level=logging.ERROR, noiselevel=-1)
                        return 1
                rsync_binary = portage.process.find_binary("rsync")
                if rsync_binary is None:
                        print("!!! /usr/bin/rsync does not exist, so rsync support is disabled.")
                        print("!!! Type \"emerge net-misc/rsync\" to enable rsync support.")
-                       sys.exit(1)
+                       return os.EX_UNAVAILABLE
                mytimeout=180
 
                rsync_opts = []
@@ -2200,7 +2215,7 @@ def action_sync(settings, trees, mtimedb, myopts, myaction):
 
                # Real local timestamp file.
                servertimestampfile = os.path.join(
-                       myportdir, "metadata", "timestamp.chk")
+                       repo.location, "metadata", "timestamp.chk")
 
                content = portage.util.grabfile(servertimestampfile)
                mytimestamp = 0
@@ -2231,7 +2246,7 @@ def action_sync(settings, trees, mtimedb, myopts, myaction):
                                r"(rsync|ssh)://([^:/]+@)?(\[[:\da-fA-F]*\]|[^:/]*)(:[0-9]+)?",
                                syncuri, maxsplit=4)[1:5]
                except ValueError:
-                       writemsg_level("!!! SYNC is invalid: %s\n" % syncuri,
+                       writemsg_level("!!! sync-uri is invalid: %s\n" % syncuri,
                                noiselevel=-1, level=logging.ERROR)
                        return 1
 
@@ -2452,7 +2467,7 @@ def action_sync(settings, trees, mtimedb, myopts, myaction):
                                        print(">>> In order to force sync, remove '%s'." % servertimestampfile)
                                        print(">>>")
                                        print()
-                                       sys.exit(0)
+                                       return os.EX_OK
                                elif (servertimestamp != 0) and (servertimestamp < mytimestamp):
                                        emergelog(xterm_titles,
                                                ">>> Server out of date: %s" % dosyncuri)
@@ -2466,7 +2481,7 @@ def action_sync(settings, trees, mtimedb, myopts, myaction):
                                        exitcode = SERVER_OUT_OF_DATE
                                elif (servertimestamp == 0) or (servertimestamp > mytimestamp):
                                        # actual sync
-                                       mycommand = rsynccommand + [dosyncuri+"/", myportdir]
+                                       mycommand = rsynccommand + [dosyncuri+"/", repo.location]
                                        exitcode = portage.process.spawn(mycommand,
                                                **portage._native_kwargs(spawn_kwargs))
                                        if exitcode in [0,1,3,4,11,14,20,21]:
@@ -2494,23 +2509,23 @@ def action_sync(settings, trees, mtimedb, myopts, myaction):
                if (exitcode==0):
                        emergelog(xterm_titles, "=== Sync completed with %s" % dosyncuri)
                elif exitcode == SERVER_OUT_OF_DATE:
-                       sys.exit(1)
+                       return 1
                elif exitcode == EXCEEDED_MAX_RETRIES:
                        sys.stderr.write(
                                ">>> Exceeded PORTAGE_RSYNC_RETRIES: %s\n" % maxretries)
-                       sys.exit(1)
+                       return 1
                elif (exitcode>0):
                        msg = []
                        if exitcode==1:
                                msg.append("Rsync has reported that there is a syntax error. Please ensure")
-                               msg.append("that your SYNC statement is proper.")
-                               msg.append("SYNC=" + settings["SYNC"])
+                               msg.append("that sync-uri attribute for repository '%s' is proper." % repo.name)
+                               msg.append("sync-uri: '%s'" % repo.sync_uri)
                        elif exitcode==11:
                                msg.append("Rsync has reported that there is a File IO error. Normally")
                                msg.append("this means your disk is full, but can be caused by corruption")
-                               msg.append("on the filesystem that contains PORTDIR. Please investigate")
+                               msg.append("on the filesystem that contains repository '%s'. Please investigate" % repo.name)
                                msg.append("and try again after the problem has been fixed.")
-                               msg.append("PORTDIR=" + settings["PORTDIR"])
+                               msg.append("Location of repository: '%s'" % repo.location)
                        elif exitcode==20:
                                msg.append("Rsync was killed before it finished.")
                        else:
@@ -2521,117 +2536,76 @@ def action_sync(settings, trees, mtimedb, myopts, myaction):
                                msg.append("(and possibly your system's filesystem) configuration.")
                        for line in msg:
                                out.eerror(line)
-                       sys.exit(exitcode)
-       elif syncuri[:6]=="cvs://":
+                       return exitcode
+       elif repo.sync_type == "cvs":
                if not os.path.exists("/usr/bin/cvs"):
                        print("!!! /usr/bin/cvs does not exist, so CVS support is disabled.")
                        print("!!! Type \"emerge dev-vcs/cvs\" to enable CVS support.")
-                       sys.exit(1)
-               cvsroot=syncuri[6:]
-               cvsdir=os.path.dirname(myportdir)
-               if not os.path.exists(myportdir+"/CVS"):
+                       return os.EX_UNAVAILABLE
+               cvs_root = syncuri
+               if cvs_root.startswith("cvs://"):
+                       cvs_root = cvs_root[6:]
+               if not os.path.exists(os.path.join(repo.location, "CVS")):
                        #initial checkout
                        print(">>> Starting initial cvs checkout with "+syncuri+"...")
-                       if os.path.exists(cvsdir+"/gentoo-x86"):
-                               print("!!! existing",cvsdir+"/gentoo-x86 directory; exiting.")
-                               sys.exit(1)
                        try:
-                               os.rmdir(myportdir)
+                               os.rmdir(repo.location)
                        except OSError as e:
                                if e.errno != errno.ENOENT:
                                        sys.stderr.write(
-                                               "!!! existing '%s' directory; exiting.\n" % myportdir)
-                                       sys.exit(1)
+                                               "!!! existing '%s' directory; exiting.\n" % repo.location)
+                                       return 1
                                del e
                        if portage.process.spawn_bash(
-                                       "cd %s; exec cvs -z0 -d %s co -P gentoo-x86" % \
-                                       (portage._shell_quote(cvsdir), portage._shell_quote(cvsroot)),
+                                       "cd %s; exec cvs -z0 -d %s co -P -d %s %s" %
+                                       (portage._shell_quote(os.path.dirname(repo.location)), portage._shell_quote(cvs_root),
+                                       portage._shell_quote(os.path.basename(repo.location)), portage._shell_quote(repo.sync_cvs_repo)),
                                        **portage._native_kwargs(spawn_kwargs)) != os.EX_OK:
                                print("!!! cvs checkout error; exiting.")
-                               sys.exit(1)
-                       os.rename(os.path.join(cvsdir, "gentoo-x86"), myportdir)
+                               return 1
                else:
                        #cvs update
                        print(">>> Starting cvs update with "+syncuri+"...")
                        retval = portage.process.spawn_bash(
                                "cd %s; exec cvs -z0 -q update -dP" % \
-                               (portage._shell_quote(myportdir),),
+                               (portage._shell_quote(repo.location),),
                                **portage._native_kwargs(spawn_kwargs))
                        if retval != os.EX_OK:
                                writemsg_level("!!! cvs update error; exiting.\n",
                                        noiselevel=-1, level=logging.ERROR)
-                               sys.exit(retval)
+                               return retval
                dosyncuri = syncuri
-       else:
-               writemsg_level("!!! Unrecognized protocol: SYNC='%s'\n" % (syncuri,),
-                       noiselevel=-1, level=logging.ERROR)
-               return 1
 
        # Reload the whole config from scratch.
-       portage._sync_disabled_warnings = False
        settings, trees, mtimedb = load_emerge_config(trees=trees)
        adjust_configs(myopts, trees)
-       root_config = trees[settings['EROOT']]['root_config']
        portdb = trees[settings['EROOT']]['porttree'].dbapi
 
-       if git:
+       if repo.sync_type == "git":
                # NOTE: Do this after reloading the config, in case
                # it did not exist prior to sync, so that the config
                # and portdb properly account for its existence.
-               exitcode = git_sync_timestamps(portdb, myportdir)
+               exitcode = git_sync_timestamps(portdb, repo.location)
                if exitcode == os.EX_OK:
                        updatecache_flg = True
 
-       if updatecache_flg and  \
-               myaction != "metadata" and \
-               "metadata-transfer" not in settings.features:
+       if updatecache_flg and "metadata-transfer" not in settings.features:
                updatecache_flg = False
 
        if updatecache_flg and \
-               os.path.exists(os.path.join(myportdir, 'metadata', 'cache')):
+               os.path.exists(os.path.join(repo.location, 'metadata', 'cache')):
 
-               # Only update cache for myportdir since that's
+               # Only update cache for repo.location since that's
                # the only one that's been synced here.
-               action_metadata(settings, portdb, myopts, porttrees=[myportdir])
-
-       if myopts.get('--package-moves') != 'n' and \
-               _global_updates(trees, mtimedb["updates"], quiet=("--quiet" in myopts)):
-               mtimedb.commit()
-               # Reload the whole config from scratch.
-               settings, trees, mtimedb = load_emerge_config(trees=trees)
-               adjust_configs(myopts, trees)
-               portdb = trees[settings['EROOT']]['porttree'].dbapi
-               root_config = trees[settings['EROOT']]['root_config']
+               action_metadata(settings, portdb, myopts, porttrees=[repo.location])
 
-       mybestpv = portdb.xmatch("bestmatch-visible",
-               portage.const.PORTAGE_PACKAGE_ATOM)
-       mypvs = portage.best(
-               trees[settings['EROOT']]['vartree'].dbapi.match(
-               portage.const.PORTAGE_PACKAGE_ATOM))
-
-       chk_updated_cfg_files(settings["EROOT"],
-               portage.util.shlex_split(settings.get("CONFIG_PROTECT", "")))
-
-       if myaction != "metadata":
-               postsync = os.path.join(settings["PORTAGE_CONFIGROOT"],
-                       portage.USER_CONFIG_PATH, "bin", "post_sync")
-               if os.access(postsync, os.X_OK):
-                       retval = portage.process.spawn(
-                               [postsync, dosyncuri], env=settings.environ())
-                       if retval != os.EX_OK:
-                               writemsg_level(
-                                       " %s spawn failed of %s\n" % (bad("*"), postsync,),
-                                       level=logging.ERROR, noiselevel=-1)
-
-       if(mybestpv != mypvs) and not "--quiet" in myopts:
-               print()
-               print(warn(" * ")+bold("An update to portage is available.")+" It is _highly_ recommended")
-               print(warn(" * ")+"that you update portage now, before any other packages are updated.")
-               print()
-               print(warn(" * ")+"To update portage, run 'emerge --oneshot portage' now.")
-               print()
+       postsync = os.path.join(settings["PORTAGE_CONFIGROOT"], portage.USER_CONFIG_PATH, "bin", "post_sync")
+       if os.access(postsync, os.X_OK):
+               retval = portage.process.spawn([postsync, dosyncuri], env=settings.environ())
+               if retval != os.EX_OK:
+                       writemsg_level(" %s spawn failed of %s\n" % (bad("*"), postsync,),
+                               level=logging.ERROR, noiselevel=-1)
 
-       display_news_notification(root_config, myopts)
        return os.EX_OK
 
 def action_uninstall(settings, trees, ldpath_mtimes,
@@ -3869,8 +3843,7 @@ def run_action(emerge_config):
 
        if "sync" == emerge_config.action:
                return action_sync(emerge_config.target_config.settings,
-                       emerge_config.trees, emerge_config.target_config.mtimedb,
-                       emerge_config.opts, emerge_config.action)
+                       emerge_config.trees, emerge_config.opts)
        elif "metadata" == emerge_config.action:
                action_metadata(emerge_config.target_config.settings,
                        emerge_config.target_config.trees['porttree'].dbapi,
index 77b28868623e896f256647c1aa2957babae4719a..7e30208a3e254fbfebefc09351351c744458d4ff 100644 (file)
@@ -317,7 +317,7 @@ class binarytree(object):
                                "ACCEPT_KEYWORDS", "ACCEPT_LICENSE",
                                "ACCEPT_PROPERTIES", "ACCEPT_RESTRICT", "CBUILD",
                                "CONFIG_PROTECT", "CONFIG_PROTECT_MASK", "FEATURES",
-                               "GENTOO_MIRRORS", "INSTALL_MASK", "SYNC", "USE"])
+                               "GENTOO_MIRRORS", "INSTALL_MASK", "USE"])
                        self._pkgindex_default_pkg_data = {
                                "BUILD_TIME"         : "",
                                "DEFINED_PHASES"     : "",
index 285572213eb1651d95e75126795eebd484eb52d3..84000cdf69c33a0707e36c529ff7309754d2af55 100644 (file)
@@ -179,10 +179,15 @@ environ_filter += [
        "RESUMECOMMAND", "RESUMECOMMAND_FTP",
        "RESUMECOMMAND_HTTP", "RESUMECOMMAND_HTTPS",
        "RESUMECOMMAND_RSYNC", "RESUMECOMMAND_SFTP",
-       "SYNC", "UNINSTALL_IGNORE", "USE_EXPAND_HIDDEN", "USE_ORDER",
+       "UNINSTALL_IGNORE", "USE_EXPAND_HIDDEN", "USE_ORDER",
        "__PORTAGE_HELPER"
 ]
 
+# No longer supported variables
+environ_filter += [
+       "SYNC"
+]
+
 environ_filter = frozenset(environ_filter)
 
 # Variables that are not allowed to have per-repo or per-package
index 7a359dbe9b84ea803cb7a7c025c20ffa85bd5ed6..619d0724018491bb93a099eec8370a16d32fa1e4 100644 (file)
@@ -529,7 +529,7 @@ class config(object):
                        if portdir_overlay:
                                for ov in portdir_overlay:
                                        ov = normalize_path(ov)
-                                       if isdir_raise_eaccess(ov):
+                                       if isdir_raise_eaccess(ov) or portage._sync_disabled_warnings:
                                                new_ov.append(portage._shell_quote(ov))
                                        else:
                                                writemsg(_("!!! Invalid PORTDIR_OVERLAY"
@@ -877,11 +877,6 @@ class config(object):
                                        self[k] = self[k].lower()
                                        self.backup_changes(k)
 
-                       if main_repo is not None and not main_repo.sync:
-                               main_repo_sync = self.get("SYNC")
-                               if main_repo_sync:
-                                       main_repo.sync = main_repo_sync
-
                        # The first constructed config object initializes these modules,
                        # and subsequent calls to the _init() functions have no effect.
                        portage.output._init(config_root=self['PORTAGE_CONFIGROOT'])
index 8ded078252428bc48362b9f565abb40f8d8d3977..232e9cba0681d57d2e7b50899a8b7ab44e7d7e41 100644 (file)
@@ -82,9 +82,9 @@ class RepoConfig(object):
                'find_invalid_path_char', 'format', 'local_config', 'location',
                'main_repo', 'manifest_hashes', 'masters', 'missing_repo_name',
                'name', 'portage1_profiles', 'portage1_profiles_compat', 'priority',
-               'profile_formats', 'sign_commit', 'sign_manifest', 'sync',
-               'thin_manifest', 'update_changelog', 'user_location',
-               '_eapis_banned', '_eapis_deprecated')
+               'profile_formats', 'sign_commit', 'sign_manifest', 'sync_cvs_repo',
+               'sync_type', 'sync_uri', 'thin_manifest', 'update_changelog',
+               'user_location', '_eapis_banned', '_eapis_deprecated')
 
        def __init__(self, name, repo_opts, local_config=True):
                """Build a RepoConfig with options in repo_opts
@@ -135,11 +135,20 @@ class RepoConfig(object):
                                priority = None
                self.priority = priority
 
-               # Not implemented.
-               sync = repo_opts.get('sync')
-               if sync is not None:
-                       sync = sync.strip()
-               self.sync = sync
+               sync_cvs_repo = repo_opts.get('sync-cvs-repo')
+               if sync_cvs_repo is not None:
+                       sync_cvs_repo = sync_cvs_repo.strip()
+               self.sync_cvs_repo = sync_cvs_repo or None
+
+               sync_type = repo_opts.get('sync-type')
+               if sync_type is not None:
+                       sync_type = sync_type.strip()
+               self.sync_type = sync_type or None
+
+               sync_uri = repo_opts.get('sync-uri')
+               if sync_uri is not None:
+                       sync_uri = sync_uri.strip()
+               self.sync_uri = sync_uri or None
 
                # Not implemented.
                format = repo_opts.get('format')
@@ -150,7 +159,7 @@ class RepoConfig(object):
                location = repo_opts.get('location')
                self.user_location = location
                if location is not None and location.strip():
-                       if os.path.isdir(location):
+                       if os.path.isdir(location) or portage._sync_disabled_warnings:
                                location = os.path.realpath(location)
                else:
                        location = None
@@ -160,9 +169,12 @@ class RepoConfig(object):
                missing = True
                self.name = name
                if self.location is not None:
-                       eapi = read_corresponding_eapi_file(os.path.join(self.location, REPO_NAME_LOC))
-                       self.name, missing = self._read_valid_repo_name(self.location)
-               elif name == "DEFAULT": 
+                       if os.path.isdir(location):
+                               eapi = read_corresponding_eapi_file(os.path.join(self.location, REPO_NAME_LOC))
+                               self.name, missing = self._read_valid_repo_name(self.location)
+                       else:
+                               missing = not portage._sync_disabled_warnings
+               elif name == "DEFAULT":
                        missing = False
 
                self.eapi = eapi
@@ -338,8 +350,12 @@ class RepoConfig(object):
                        repo_msg.append(indent + "format: " + self.format)
                if self.user_location:
                        repo_msg.append(indent + "location: " + self.user_location)
-               if self.sync:
-                       repo_msg.append(indent + "sync: " + self.sync)
+               if self.sync_cvs_repo:
+                       repo_msg.append(indent + "sync-cvs-repo: " + self.sync_cvs_repo)
+               if self.sync_type:
+                       repo_msg.append(indent + "sync-type: " + self.sync_type)
+               if self.sync_uri:
+                       repo_msg.append(indent + "sync-uri: " + self.sync_uri)
                if self.masters:
                        repo_msg.append(indent + "masters: " + " ".join(master.name for master in self.masters))
                if self.priority is not None:
@@ -347,7 +363,7 @@ class RepoConfig(object):
                if self.aliases:
                        repo_msg.append(indent + "aliases: " + " ".join(self.aliases))
                if self.eclass_overrides:
-                       repo_msg.append(indent + "eclass_overrides: " + \
+                       repo_msg.append(indent + "eclass-overrides: " + \
                                " ".join(self.eclass_overrides))
                repo_msg.append("")
                return "\n".join(repo_msg)
@@ -519,15 +535,35 @@ class RepoConfigLoader(object):
                                optdict[oname] = parser.get(sname, oname)
 
                        repo = RepoConfig(sname, optdict, local_config=local_config)
-                       if repo.name != sname:
-                               writemsg_level("!!! %s\n" %
-                                  _("Section name '%s' set in repos.conf differs from name '%s' set inside repository") %
+
+                       if repo.name != sname and not portage._sync_disabled_warnings:
+                               writemsg_level("!!! %s\n" % _("Section name '%s' set in repos.conf differs from name '%s' set inside repository") %
                                        (sname, repo.name), level=logging.ERROR, noiselevel=-1)
                                continue
 
-                       if repo.location and not exists_raise_eaccess(repo.location):
-                               writemsg(_("!!! Invalid repos.conf entry '%s'"
-                                       " (not a dir): '%s'\n") % (sname, repo.location), noiselevel=-1)
+                       if repo.location and not exists_raise_eaccess(repo.location) and not portage._sync_disabled_warnings:
+                               writemsg_level("!!! %s\n" % _("Repository '%s' has location attribute set to nonexistent directory: '%s'") %
+                                       (sname, repo.location), level=logging.ERROR, noiselevel=-1)
+                               continue
+
+                       if repo.sync_type is not None and repo.sync_uri is None:
+                               writemsg_level("!!! %s\n" % _("Repository '%s' has sync-type attribute, but is missing sync-uri attribute") %
+                                       sname, level=logging.ERROR, noiselevel=-1)
+                               continue
+
+                       if repo.sync_uri is not None and repo.sync_type is None:
+                               writemsg_level("!!! %s\n" % _("Repository '%s' has sync-uri attribute, but is missing sync-type attribute") %
+                                       sname, level=logging.ERROR, noiselevel=-1)
+                               continue
+
+                       if repo.sync_type not in (None, "cvs", "git", "rsync"):
+                               writemsg_level("!!! %s\n" % _("Repository '%s' has sync-type attribute set to unsupported value: '%s'") %
+                                       (sname, repo.sync_type), level=logging.ERROR, noiselevel=-1)
+                               continue
+
+                       if repo.sync_type == "cvs" and repo.sync_cvs_repo is None:
+                               writemsg_level("!!! %s\n" % _("Repository '%s' has sync-type=cvs, but is missing sync-cvs-repo attribute") %
+                                       sname, level=logging.ERROR, noiselevel=-1)
                                continue
 
                        if repo.name in prepos:
@@ -780,7 +816,7 @@ class RepoConfigLoader(object):
                                if r.location is None:
                                        writemsg(_("!!! Location not set for repository %s\n") % name, noiselevel=-1)
                                else:
-                                       if not isdir_raise_eaccess(r.location):
+                                       if not isdir_raise_eaccess(r.location) and not portage._sync_disabled_warnings:
                                                self.prepos_order.remove(name)
                                                writemsg(_("!!! Invalid Repository Location"
                                                        " (not a dir): '%s'\n") % r.location, noiselevel=-1)
@@ -832,7 +868,7 @@ class RepoConfigLoader(object):
                return repo_name in self.prepos
 
        def config_string(self):
-               str_or_int_keys = ("format", "location", "main_repo", "priority", "sync")
+               str_or_int_keys = ("format", "location", "main_repo", "priority", "sync_cvs_repo", "sync_type", "sync_uri")
                str_tuple_keys = ("aliases", "eclass_overrides")
                repo_config_tuple_keys = ("masters",)
                keys = str_or_int_keys + str_tuple_keys + repo_config_tuple_keys