<commit_before>#
# Copyright (c) 2008-2009 rPath, Inc.
#
# This program is distributed under the terms of the Common Public License,
# version 1.0. A copy of this license should have been distributed with this
# source file in a file called LICENSE. If it is not present, the license
# is always available at http://www.rpath.com/permanent/licenses/CPL-1.0.
#
# This program is distributed in the hope that it will be useful, but
# without any warranty; without even the implied warranty of merchantability
# or fitness for a particular purpose. See the Common Public License for
# full details.
#
"""
Checkout command and related utilities.
"""
import os
import tempfile

from conary.lib import util

from rbuild import errors
from rbuild import pluginapi
from rbuild.pluginapi import command

from rbuild_plugins.checkout import derive

#TODO: separate out determining what checkout to get from actually creating
# that checkout to allow for other interfaces

class CheckoutCommand(command.BaseCommand):
    """
    Check out a package, creating a new package if necessary.

    If the product's platform contains a package by the same name,
    then you must specify whether to shadow or derive from that
    upstream version, or to create a new package by the same name
    that is not related to the upstream version.

    A derived package starts with the contents of the binary
    package from the platform, generally used to make modifications
    that do not require rebuilding binaries.

    A shadow allows you to make changes relative to the platform's
    source package, changing how the package is built, and requiring
    rebuilding binaries.
    """
    help = 'Check out packages and groups for editing'
    paramHelp = '[<options>] <packagename>'

    commands = ['checkout']
    docs = {'derive' : "Create derived package (based on upstream binary)",
            'shadow' : "Create shadowed package (based on upstream source)",
            'new' : ("Create a new version of the package even if"
                     " an upstream version exists") }

    def addLocalParameters(self, argDef):
        argDef['derive'] = command.NO_PARAM
        argDef['shadow'] = command.NO_PARAM
        argDef['new']    = command.NO_PARAM

    def runCommand(self, handle, argSet, args):
        packageName, = self.requireParameters(args, ['packageName'])[1:]
        derive = argSet.pop('derive', False)
        new = argSet.pop('new', False)
        shadow = argSet.pop('shadow', False)
        self.runCheckoutCommand(handle, packageName, new=new, shadow=shadow,
                            derive=derive)

    def runCheckoutCommand(self, handle, packageName, new=False, shadow=False, 
                       derive=False):
        if [new, shadow, derive].count(True) > 1:
            raise errors.ParseError(
                'Only one of --new, --derive, or --shadow may be specified')
        if new:
            return handle.Checkout.newPackage(packageName)
        elif shadow:
            return handle.Checkout.shadowPackage(packageName)
        elif derive:
            return handle.Checkout.derivePackage(packageName)
        else:
            return handle.Checkout.checkoutPackageDefault(packageName)

class Checkout(pluginapi.Plugin):
    name = 'checkout'

    def registerCommands(self):
        self.handle.Commands.registerCommand(CheckoutCommand)

    def checkoutPackageDefault(self, packageName):
        existingPackage = self._getExistingPackage(packageName)
        if existingPackage:
            rc = self.checkoutPackage(packageName)
            self.handle.ui.info('Checked out existing package %r', packageName)
            return rc
        upstreamLatest = self._getUpstreamPackage(packageName)
        if upstreamLatest:
            raise errors.PluginError('\n'.join((
                    'The upstream source provides a version of this package.',
                    'Please specify:',
                    '  --shadow to shadow this package',
                    '  --derive to derive from it',
                    '  --new to replace it with a new version')))
        self.newPackage(packageName)


    def checkoutPackage(self, packageName):
        currentLabel = self.handle.productStore.getActiveStageLabel()
        self.handle.facade.conary.checkout(packageName, currentLabel)
        return True

    def derivePackage(self, packageName):
        upstreamLatest = self._getUpstreamPackage(packageName)
        if not upstreamLatest:
            raise errors.PluginError(
                        'cannot derive %s: no upstream binary' % packageName)
        derive.derive(self.handle, upstreamLatest)
        self.handle.ui.info('Derived %s from %s=%s[%s].', 
            packageName, *upstreamLatest)
        self.handle.ui.info(
                'Edit recipe to add changes your changes to the binary package')

    def shadowPackage(self, packageName):
        origName, version, flavor = self.handle.facade.conary.parseTroveSpec(packageName)
        package = None

        if version:
            package = self._getRemotePackage(origName, version)
            if package is None:
                raise errors.PluginError(
                        '%s:source does not exist on label %s.' % \
                        (origName, version))
        else:
            package = self._getUpstreamPackage(packageName)
            if package is None:
                raise errors.PluginError(
                        'cannot shadow %s: no upstream binary' % packageName)

        name, version, flavor = package            

        currentLabel = self.handle.productStore.getActiveStageLabel()
        self.handle.facade.conary.shadowSourceForBinary(name, version, flavor,
                                                        currentLabel)
        self.checkoutPackage(origName)
        self.handle.ui.info('Shadowed package %r', packageName)

    def newPackage(self, packageName, message=None):
        currentLabel = self.handle.productStore.getActiveStageLabel()
        existingPackage = self._getExistingPackage(packageName)

        if existingPackage:
            if existingPackage[1].isShadow() and \
               self.handle.ui.getYn(
                '%s is shadowed on the current label.\n'
                'Do you want to detach this package from its parent? (Y/N): ' \
                % packageName ):
                self.handle.facade.conary.detachPackage(
                    existingPackage, '/' + currentLabel, message)
                self.handle.ui.info('Divorced package %s from its shadow.' \
                    % packageName)
            else:                    
                raise errors.PluginError('\n'.join((
                    'This package already exists in the product.',<commit_msg>RBLD-30 fix bugs<commit_after>#
# Copyright (c) 2008-2009 rPath, Inc.
#
# This program is distributed under the terms of the Common Public License,
# version 1.0. A copy of this license should have been distributed with this
# source file in a file called LICENSE. If it is not present, the license
# is always available at http://www.rpath.com/permanent/licenses/CPL-1.0.
#
# This program is distributed in the hope that it will be useful, but
# without any warranty; without even the implied warranty of merchantability
# or fitness for a particular purpose. See the Common Public License for
# full details.
#
"""
Checkout command and related utilities.
"""
import os
import tempfile

from conary.lib import util

from rbuild import errors
from rbuild import pluginapi
from rbuild.pluginapi import command

from rbuild_plugins.checkout import derive

#TODO: separate out determining what checkout to get from actually creating
# that checkout to allow for other interfaces

class CheckoutCommand(command.BaseCommand):
    """
    Check out a package, creating a new package if necessary.

    If the product's platform contains a package by the same name,
    then you must specify whether to shadow or derive from that
    upstream version, or to create a new package by the same name
    that is not related to the upstream version.

    A derived package starts with the contents of the binary
    package from the platform, generally used to make modifications
    that do not require rebuilding binaries.

    A shadow allows you to make changes relative to the platform's
    source package, changing how the package is built, and requiring
    rebuilding binaries.
    """
    help = 'Check out packages and groups for editing'
    paramHelp = '[<options>] <packagename>'

    commands = ['checkout']
    docs = {'derive' : "Create derived package (based on upstream binary)",
            'shadow' : "Create shadowed package (based on upstream source)",
            'new' : ("Create a new version of the package even if"
                     " an upstream version exists") }

    def addLocalParameters(self, argDef):
        argDef['derive'] = command.NO_PARAM
        argDef['shadow'] = command.NO_PARAM
        argDef['new']    = command.NO_PARAM

    def runCommand(self, handle, argSet, args):
        packageName, = self.requireParameters(args, ['packageName'])[1:]
        derive = argSet.pop('derive', False)
        new = argSet.pop('new', False)
        shadow = argSet.pop('shadow', False)
        self.runCheckoutCommand(handle, packageName, new=new, shadow=shadow,
                            derive=derive)

    def runCheckoutCommand(self, handle, packageName, new=False, shadow=False, 
                       derive=False):
        if [new, shadow, derive].count(True) > 1:
            raise errors.ParseError(
                'Only one of --new, --derive, or --shadow may be specified')
        if new:
            return handle.Checkout.newPackage(packageName)
        elif shadow:
            return handle.Checkout.shadowPackage(packageName)
        elif derive:
            return handle.Checkout.derivePackage(packageName)
        else:
            return handle.Checkout.checkoutPackageDefault(packageName)

class Checkout(pluginapi.Plugin):
    name = 'checkout'

    def registerCommands(self):
        self.handle.Commands.registerCommand(CheckoutCommand)

    def checkoutPackageDefault(self, packageName):
        existingPackage = self._getExistingPackage(packageName)
        if existingPackage:
            rc = self.checkoutPackage(packageName)
            self.handle.ui.info('Checked out existing package %r', packageName)
            return rc
        upstreamLatest = self._getUpstreamPackage(packageName)
        if upstreamLatest:
            raise errors.PluginError('\n'.join((
                    'The upstream source provides a version of this package.',
                    'Please specify:',
                    '  --shadow to shadow this package',
                    '  --derive to derive from it',
                    '  --new to replace it with a new version')))
        self.newPackage(packageName)


    def checkoutPackage(self, packageName):
        currentLabel = self.handle.productStore.getActiveStageLabel()
        self.handle.facade.conary.checkout(packageName, currentLabel)
        return True

    def derivePackage(self, packageName):
        upstreamLatest = self._getUpstreamPackage(packageName)
        if not upstreamLatest:
            raise errors.PluginError(
                        'cannot derive %s: no upstream binary' % packageName)
        derive.derive(self.handle, upstreamLatest)
        self.handle.ui.info('Derived %s from %s=%s[%s].', 
            packageName, *upstreamLatest)
        self.handle.ui.info(
                'Edit recipe to add changes your changes to the binary package')

    def shadowPackage(self, packageName):
        origName, version, flavor = self.handle.facade.conary.parseTroveSpec(packageName)
        package = None

        if version:
            package = self._getRemotePackage(origName, version)
            if package is None:
                raise errors.PluginError(
                        '%s:source does not exist on label %s.' % \
                        (origName, version))
        else:
            package = self._getUpstreamPackage(packageName)
            if package is None:
                raise errors.PluginError(
                        'cannot shadow %s: no upstream binary' % packageName)

        name, version, flavor = package            

        currentLabel = self.handle.productStore.getActiveStageLabel()
        self.handle.facade.conary.shadowSourceForBinary(name, version, flavor,
                                                        currentLabel)
        self.checkoutPackage(origName)
        self.handle.ui.info('Shadowed package %r', packageName)

    def newPackage(self, packageName, message=None):
        currentLabel = self.handle.productStore.getActiveStageLabel()
        existingPackage = self._getExistingPackage(packageName)

        if existingPackage:
            if existingPackage[1].isShadow(): 
                confirmDetach = self.handle.ui.getYn(
                    '%s is shadowed on the current label.\n'
                    'Do you want to detach this package from its '
                    'parent? (Y/N): '  % packageName )
                if not confirmDetach:
                    return
                self.handle.facade.conary.detachPackage(
                    existingPackage, '/' + currentLabel, message)
                self.handle.ui.info('Divorced package %s from its shadow.' \
                    % packageName)
            else:                    
                raise errors.PluginError('\n'.join((
                    'This package already exists in the product.',
{'fraction_non_alphanumeric': 0.08027859237536657, 'fraction_numerical': 0.002346041055718475, 'mean_word_length': 2.2957236047354432, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2201785', 'n_tokens_mistral': 3473, 'n_tokens_neox': 3339, 'n_words': 1149}