2009-03-02 15:03:06 +01:00
# Copyright (C) 2006 Novell Inc. All rights reserved.
2006-04-20 16:26:50 +02:00
# This program is free software; it may be used, copied, modified
# and distributed under the terms of the GNU General Public Licence,
2009-08-20 21:28:05 +02:00
# either version 2, or version 3 (at your option).
2006-04-20 16:26:50 +02:00
2022-08-26 16:23:48 +02:00
import argparse
2022-09-09 11:46:28 +02:00
import getpass
import glob
2023-03-29 16:23:22 +02:00
import importlib
2022-08-22 15:45:25 +02:00
import importlib . util
2013-06-13 19:57:34 +02:00
import inspect
2017-07-07 18:47:43 +02:00
import os
2023-03-29 16:23:22 +02:00
import pkgutil
2022-09-09 11:46:28 +02:00
import re
import subprocess
2022-07-28 12:28:33 +02:00
import sys
2022-09-09 11:46:28 +02:00
import textwrap
import tempfile
2022-07-28 12:28:33 +02:00
import time
2022-09-09 11:46:28 +02:00
import traceback
2022-07-28 12:28:33 +02:00
from functools import cmp_to_key
from operator import itemgetter
2022-10-07 17:25:33 +02:00
from pathlib import Path
2023-01-12 10:38:38 +01:00
from typing import List
2022-07-28 12:28:33 +02:00
from urllib . parse import urlsplit
from urllib . error import HTTPError
2006-04-20 16:26:50 +02:00
2022-10-12 15:20:06 +02:00
from . import _private
2022-09-09 11:46:28 +02:00
from . import build as osc_build
2022-07-28 12:28:33 +02:00
from . import cmdln
2023-03-29 16:23:22 +02:00
from . import commands as osc_commands
2022-07-28 12:28:33 +02:00
from . import conf
2023-07-27 13:29:38 +02:00
from . import git_scm
2022-07-28 12:28:33 +02:00
from . import oscerr
2022-10-14 14:25:54 +02:00
from . import store as osc_store
2013-04-09 11:35:53 +02:00
from . core import *
2022-09-09 11:46:28 +02:00
from . grabber import OscFileGrabber
from . meter import create_text_meter
from . util import cpio , rpmquery , safewriter
2022-07-29 22:00:41 +02:00
from . util . helper import _html_escape , format_table
2020-03-12 23:00:47 +01:00
2019-04-16 15:18:04 +02:00
2023-10-13 13:46:44 +02:00
# python3.6 requires reading sys.real_prefix to detect virtualenv
IN_VENV = getattr ( sys , " real_prefix " , sys . base_prefix ) != sys . prefix
2023-03-29 16:23:22 +02:00
class Command :
#: Name of the command as used in the argument parser.
name : str = None
#: Optional aliases to the command.
aliases : List [ str ] = [ ]
#: Whether the command is hidden from help.
#: Defaults to ``False``.
hidden : bool = False
#: Name of the parent command class.
#: Can be prefixed if the parent comes from a different location,
#: for example ``osc.commands.<ClassName>`` when extending osc command with a plugin.
#: See ``OscMainCommand.MODULES`` for available prefixes.
parent : str = None
def __init__ ( self , full_name , parent = None ) :
self . full_name = full_name
self . parent = parent
self . subparsers = None
if not self . name :
raise ValueError ( f " Command ' { self . full_name } ' has no ' name ' set " )
if parent :
self . parser = self . parent . subparsers . add_parser (
self . name ,
aliases = self . aliases ,
help = self . get_help ( ) ,
description = self . get_description ( ) ,
formatter_class = cmdln . HelpFormatter ,
conflict_handler = " resolve " ,
prog = f " { self . main_command . name } [global opts] { self . name } " ,
)
self . parser . set_defaults ( _selected_command = self )
else :
self . parser = argparse . ArgumentParser (
prog = self . name ,
description = self . get_description ( ) ,
formatter_class = cmdln . HelpFormatter ,
usage = " %(prog)s [global opts] <command> [--help] [opts] [args] " ,
)
# traverse the parent commands and add their options to the current command
2023-04-11 17:08:45 +02:00
commands = [ ]
2023-03-29 16:23:22 +02:00
cmd = self
while cmd :
2023-04-11 17:08:45 +02:00
commands . append ( cmd )
2023-03-29 16:23:22 +02:00
cmd = cmd . parent
2023-04-11 17:08:45 +02:00
# iterating backwards to give the command's options a priority over parent/global options
for cmd in reversed ( commands ) :
cmd . init_arguments ( )
2023-03-29 16:23:22 +02:00
def __repr__ ( self ) :
return f " <osc plugin { self . full_name } at { self . __hash__ ( ) : #x } > "
def get_help ( self ) :
"""
Return the help text of the command .
The first line of the docstring is returned by default .
"""
if self . hidden :
return argparse . SUPPRESS
if not self . __doc__ :
return " "
help_lines = self . __doc__ . strip ( ) . splitlines ( )
if not help_lines :
return " "
return help_lines [ 0 ]
def get_description ( self ) :
"""
Return the description of the command .
The docstring without the first line is returned by default .
"""
if not self . __doc__ :
return " "
help_lines = self . __doc__ . strip ( ) . splitlines ( )
if not help_lines :
return " "
# skip the first line that contains help text
help_lines . pop ( 0 )
# remove any leading empty lines
while help_lines and not help_lines [ 0 ] :
help_lines . pop ( 0 )
result = " \n " . join ( help_lines )
result = textwrap . dedent ( result )
return result
@property
def main_command ( self ) :
"""
Return reference to the main command that represents the executable
and contains the main instance of ArgumentParser .
"""
if not self . parent :
return self
return self . parent . main_command
def add_argument ( self , * args , * * kwargs ) :
"""
Add a new argument to the command ' s argument parser.
See ` argparse < https : / / docs . python . org / 3 / library / argparse . html > ` _ documentation for allowed parameters .
"""
cmd = self
# Let's inspect if the caller was init_arguments() method.
# In such case use the "parser" argument if specified.
frame_1 = inspect . currentframe ( ) . f_back
frame_1_info = inspect . getframeinfo ( frame_1 )
frame_2 = frame_1 . f_back
frame_2_info = inspect . getframeinfo ( frame_2 )
if ( frame_1_info . function , frame_2_info . function ) == ( " init_arguments " , " __init__ " ) :
# this method was called from init_arguments() that was called from __init__
# let's extract the command class from the 2nd frame and ad arguments there
cmd = frame_2 . f_locals [ " self " ]
# suppress global options from command help
if cmd != self and not self . parent :
kwargs [ " help " ] = argparse . SUPPRESS
# We're adding hidden options from parent commands to their subcommands to allow
# option intermixing. For all such added hidden options we need to suppress their
# defaults because they would override any option set in the parent command.
if cmd != self :
kwargs [ " default " ] = argparse . SUPPRESS
cmd . parser . add_argument ( * args , * * kwargs )
def init_arguments ( self ) :
"""
Override to add arguments to the argument parser .
. . note : :
Make sure you ' re adding arguments only by calling ``self.add_argument()``.
Using ` ` self . parser . add_argument ( ) ` ` directly is not recommended
because it disables argument intermixing .
"""
def run ( self , args ) :
"""
Override to implement the command functionality .
. . note : :
` ` args . positional_args ` ` is a list containing any unknown ( unparsed ) positional arguments .
. . note : :
Consider moving any reusable code into a library ,
leaving the command - line code only a thin wrapper on top of it .
If the code is generic enough , it should be added to osc directly .
In such case don ' t hesitate to open an `issue <https://github.com/openSUSE/osc/issues>`_.
"""
raise NotImplementedError ( )
def register ( self , command_class , command_full_name ) :
if not self . subparsers :
# instantiate subparsers on first use
self . subparsers = self . parser . add_subparsers ( dest = " command " , title = " commands " )
# Check for parser conflicts.
# This is how Python 3.11+ behaves by default.
if command_class . name in self . subparsers . _name_parser_map :
raise argparse . ArgumentError ( self . subparsers , f " conflicting subparser: { command_class . name } " )
for alias in command_class . aliases :
if alias in self . subparsers . _name_parser_map :
raise argparse . ArgumentError ( self . subparsers , f " conflicting subparser alias: { alias } " )
command = command_class ( command_full_name , parent = self )
return command
class MainCommand ( Command ) :
MODULES = ( )
def __init__ ( self ) :
super ( ) . __init__ ( self . __class__ . __name__ )
self . command_classes = { }
self . download_progress = None
def post_parse_args ( self , args ) :
pass
def run ( self , args ) :
cmd = getattr ( args , " _selected_command " , None )
if not cmd :
self . parser . error ( " Please specify a command " )
self . post_parse_args ( args )
cmd . run ( args )
def load_command ( self , cls , module_prefix ) :
mod_cls_name = f " { module_prefix } . { cls . __name__ } "
parent_name = getattr ( cls , " parent " , None )
if parent_name :
# allow relative references to classes in the the same module/directory
if " . " not in parent_name :
parent_name = f " { module_prefix } . { parent_name } "
try :
parent = self . main_command . command_classes [ parent_name ]
except KeyError :
msg = f " Failed to load command class ' { mod_cls_name } ' because it references parent ' { parent_name } ' that doesn ' t exist "
print ( msg , file = sys . stderr )
return None
cmd = parent . register ( cls , mod_cls_name )
else :
cmd = self . main_command . register ( cls , mod_cls_name )
cmd . full_name = mod_cls_name
self . main_command . command_classes [ mod_cls_name ] = cmd
return cmd
def load_commands ( self ) :
2023-10-13 13:46:44 +02:00
if IN_VENV :
_private . print_msg ( " Running in virtual environment, skipping loading plugins installed outside the virtual environment. " , print_to = " stderr " )
2023-03-29 16:23:22 +02:00
for module_prefix , module_path in self . MODULES :
module_path = os . path . expanduser ( module_path )
2023-04-05 15:53:17 +02:00
# some plugins have their modules installed next to them instead of site-packages
if module_path not in sys . path :
sys . path . append ( module_path )
2023-04-05 15:54:20 +02:00
for loader , module_name , _ in pkgutil . iter_modules ( path = [ module_path ] ) :
2023-03-29 16:23:22 +02:00
full_name = f " { module_prefix } . { module_name } "
spec = loader . find_spec ( full_name )
mod = importlib . util . module_from_spec ( spec )
try :
spec . loader . exec_module ( mod )
except Exception as e : # pylint: disable=broad-except
msg = f " Failed to load commands from module ' { full_name } ' : { e } "
print ( msg , file = sys . stderr )
continue
for name in dir ( mod ) :
if name . startswith ( " _ " ) :
continue
cls = getattr ( mod , name )
if not inspect . isclass ( cls ) :
continue
if not issubclass ( cls , Command ) :
continue
if cls . __module__ != full_name :
# skip classes that weren't defined directly in the loaded plugin module
continue
self . load_command ( cls , module_prefix )
def parse_args ( self , * args , * * kwargs ) :
namespace , unknown_args = self . parser . parse_known_args ( * args , * * kwargs )
unrecognized = [ i for i in unknown_args if i . startswith ( " - " ) ]
if unrecognized :
self . parser . error ( f " unrecognized arguments: " + " " . join ( unrecognized ) )
namespace . positional_args = list ( unknown_args )
return namespace
class OscCommand ( Command ) :
"""
Inherit from this class to create new commands .
The first line of the docstring becomes the help text ,
the remaining lines become the command description .
"""
class OscMainCommand ( MainCommand ) :
name = " osc "
MODULES = (
( " osc.commands " , osc_commands . __path__ [ 0 ] ) ,
)
2023-10-13 13:46:44 +02:00
if not IN_VENV :
MODULES + = (
( " osc.commands.usr_lib " , " /usr/lib/osc-plugins " ) ,
( " osc.commands.usr_local_lib " , " /usr/local/lib/osc-plugins " ) ,
( " osc.commands.home_local_lib " , " ~/.local/lib/osc-plugins " ) ,
( " osc.commands.home " , " ~/.osc-plugins " ) ,
)
2023-03-29 16:23:22 +02:00
def __init__ ( self ) :
super ( ) . __init__ ( )
self . args = None
self . download_progress = None
def init_arguments ( self ) :
self . add_argument (
" -v " ,
" --verbose " ,
action = " store_true " ,
help = " increase verbosity " ,
)
self . add_argument (
" -q " ,
" --quiet " ,
action = " store_true " ,
help = " be quiet, not verbose " ,
)
self . add_argument (
" --debug " ,
action = " store_true " ,
help = " print info useful for debugging " ,
)
self . add_argument (
" --debugger " ,
action = " store_true " ,
help = " jump into the debugger before executing anything " ,
)
self . add_argument (
" --post-mortem " ,
action = " store_true " ,
help = " jump into the debugger in case of errors " ,
)
self . add_argument (
" --traceback " ,
action = " store_true " ,
help = " print call trace in case of errors " ,
)
self . add_argument (
" -H " ,
" --http-debug " ,
action = " store_true " ,
help = " debug HTTP traffic (filters some headers) " ,
)
self . add_argument (
" --http-full-debug " ,
action = " store_true " ,
help = " debug HTTP traffic (filters no headers) " ,
)
self . add_argument (
" -A " ,
" --apiurl " ,
metavar = " URL " ,
help = " Open Build Service API URL or a configured alias " ,
)
self . add_argument (
" --config " ,
dest = " conffile " ,
metavar = " FILE " ,
help = " specify alternate configuration file " ,
)
2023-07-17 08:59:10 +02:00
self . add_argument (
" --setopt " ,
metavar = " KEY=VALUE " ,
action = " append " ,
default = [ ] ,
help = " set a config option for the current program run " ,
)
2023-03-29 16:23:22 +02:00
self . add_argument (
" --no-keyring " ,
action = " store_true " ,
help = " disable usage of desktop keyring system " ,
)
def post_parse_args ( self , args ) :
# apiurl hasn't been specified by the user
# we need to set it here because the 'default' option of an argument doesn't support lazy evaluation
if args . apiurl is None :
try :
# try reading the apiurl from the working copy
args . apiurl = osc_store . Store ( Path . cwd ( ) ) . apiurl
except oscerr . NoWorkingCopy :
2023-04-03 09:12:01 +02:00
# we can't use conf.config["apiurl"] because it contains the default "https://api.opensuse.org"
# let's leave setting the right value to conf.get_config()
pass
2023-03-29 16:23:22 +02:00
2023-07-17 08:59:10 +02:00
overrides = { }
for i in args . setopt :
key , value = i . split ( " = " )
overrides [ key ] = value
2023-04-11 11:27:34 +02:00
try :
conf . get_config (
override_apiurl = args . apiurl ,
override_conffile = args . conffile ,
override_debug = args . debug ,
override_http_debug = args . http_debug ,
override_http_full_debug = args . http_full_debug ,
override_no_keyring = args . no_keyring ,
override_post_mortem = args . post_mortem ,
override_traceback = args . traceback ,
override_verbose = args . verbose ,
2023-07-17 08:59:10 +02:00
overrides = overrides ,
2023-04-11 11:27:34 +02:00
)
except oscerr . NoConfigfile as e :
print ( e . msg , file = sys . stderr )
print ( f " Creating osc configuration file { e . file } ... " , file = sys . stderr )
conf . interactive_config_setup ( e . file , args . apiurl )
print ( " done " , file = sys . stderr )
self . post_parse_args ( args )
except oscerr . ConfigMissingApiurl as e :
print ( e . msg , file = sys . stderr )
conf . interactive_config_setup ( e . file , e . url , initial = False )
self . post_parse_args ( args )
except oscerr . ConfigMissingCredentialsError as e :
print ( e . msg , file = sys . stderr )
print ( " Please enter new credentials. " , file = sys . stderr )
conf . interactive_config_setup ( e . file , e . url , initial = False )
self . post_parse_args ( args )
2023-03-29 16:23:22 +02:00
# write config values back to args
# this is crucial mainly for apiurl to resolve an alias to full url
for i in [ " apiurl " , " debug " , " http_debug " , " http_full_debug " , " post_mortem " , " traceback " , " verbose " ] :
setattr ( args , i , conf . config [ i ] )
args . no_keyring = not conf . config [ " use_keyring " ]
if conf . config [ " show_download_progress " ] :
self . download_progress = create_text_meter ( )
2023-04-03 09:12:01 +02:00
if not args . apiurl :
self . parser . error ( " Could not determine apiurl, use -A/--apiurl to specify one " )
2023-03-29 16:23:22 +02:00
# needed for LegacyOsc class
self . args = args
def _wrap_legacy_command ( self , func_ ) :
class LegacyCommandWrapper ( Command ) :
func = func_
__doc__ = getattr ( func_ , " __doc__ " , " " )
aliases = getattr ( func_ , " aliases " , [ ] )
hidden = getattr ( func_ , " hidden " , False )
name = getattr ( func_ , " name " , func_ . __name__ [ 3 : ] )
def __repr__ ( self ) :
result = super ( ) . __repr__ ( )
result + = f " ( { self . func . __name__ } ) "
return result
def init_arguments ( self ) :
options = getattr ( self . func , " options " , [ ] )
for option_args , option_kwargs in options :
self . add_argument ( * option_args , * * option_kwargs )
def run ( self , args ) :
sig = inspect . signature ( self . func )
arg_names = list ( sig . parameters . keys ( ) )
if arg_names == [ " subcmd " , " opts " ] :
# handler doesn't take positional args via *args
if args . positional_args :
self . parser . error ( f " unrecognized arguments: " + " " . join ( args . positional_args ) )
self . func ( args . command , args )
else :
# handler takes positional args via *args
self . func ( args . command , args , * args . positional_args )
return LegacyCommandWrapper
def load_legacy_commands ( self ) :
# lazy links of attributes that would normally be initialized in the instance of Osc class
class LegacyOsc ( Osc ) : # pylint: disable=used-before-assignment
# pylint: disable=no-self-argument
@property
def argparser ( self_ ) :
return self . parser
# pylint: disable=no-self-argument
@property
def download_progress ( self_ ) :
return self . download_progress
# pylint: disable=no-self-argument
@property
def options ( self_ ) :
return self . args
# pylint: disable=no-self-argument
@options.setter
def options ( self_ , value ) :
pass
# pylint: disable=no-self-argument
@property
def subparsers ( self_ ) :
return self . subparsers
osc_instance = LegacyOsc ( )
for name in dir ( osc_instance ) :
if not name . startswith ( " do_ " ) :
continue
func = getattr ( osc_instance , name )
if not inspect . ismethod ( func ) and not inspect . isfunction ( func ) :
continue
cls = self . _wrap_legacy_command ( func )
self . load_command ( cls , " osc.commands.old " )
@classmethod
def main ( cls , argv = None , run = True ) :
"""
Initialize OscMainCommand , load all commands and run the selected command .
"""
cmd = cls ( )
cmd . load_commands ( )
cmd . load_legacy_commands ( )
if run :
args = cmd . parse_args ( args = argv )
cmd . run ( args )
else :
args = None
return cmd , args
def get_parser ( ) :
"""
Needed by argparse - manpage to generate man pages from the argument parser .
"""
main , _ = OscMainCommand . main ( run = False )
return main . parser
# ================================================================================
# The legacy code follows.
# Please do not use it if possible.
# ================================================================================
2022-05-10 10:16:55 +02:00
HELP_MULTIBUILD_MANY = """ Only work with the specified flavors of a multibuild package.
Globs are resolved according to _multibuild file from server .
Empty string is resolved to a package without a flavor . """
2022-05-10 10:44:33 +02:00
HELP_MULTIBUILD_ONE = " Only work with the specified flavor of a multibuild package. "
2022-05-10 10:16:55 +02:00
2023-01-12 10:38:38 +01:00
def pop_args (
args ,
arg1_name : str = None ,
arg1_is_optional : bool = False ,
arg1_default : str = None ,
arg2_name : str = None ,
arg2_is_optional : bool = False ,
arg2_default : str = None ,
) :
2022-11-01 10:04:58 +01:00
"""
2023-01-12 10:38:38 +01:00
Pop 2 arguments from ` args ` .
They may be either 2 individual entries or a single entry with values separated with " / " .
. . warning : :
The ` args ` list gets modified in this function call !
2022-11-01 10:04:58 +01:00
: param args : List of command - line arguments .
: type args : list ( str )
2023-01-12 10:38:38 +01:00
: param arg1_name : Name of the first argument
: type arg1_name : str
: param arg1_is_optional : Whether to error out when arg1 cannot be retrieved .
: type arg1_is_optional : bool
: param arg1_default : Used if arg1 is not specified in ` args ` .
: type arg1_default : bool
: param arg2_name : Name of the second argument
: type arg2_name : str
: param arg2_is_optional : Whether to error out when arg2 cannot be retrieved .
: type arg2_is_optional : bool
: param arg2_default : Used if arg2 is not specified in ` args ` .
: type arg2_default : bool
: returns : Project and package .
2022-11-01 10:04:58 +01:00
: rtype : tuple ( str )
"""
assert isinstance ( args , list )
2023-01-12 10:38:38 +01:00
assert isinstance ( arg1_name , str )
assert isinstance ( arg2_name , str )
2022-11-01 10:04:58 +01:00
2023-01-12 10:38:38 +01:00
if arg1_is_optional :
arg2_is_optional = True
2023-01-04 20:13:37 +01:00
2023-01-12 10:38:38 +01:00
used_arg1_default = False
2022-11-01 10:04:58 +01:00
try :
2023-01-12 10:38:38 +01:00
arg1 = args . pop ( 0 )
2022-11-01 10:04:58 +01:00
except IndexError :
2023-01-12 10:38:38 +01:00
if not arg1_is_optional and not arg1_default :
raise oscerr . OscValueError ( f " Please specify a { arg1_name } " ) from None
arg1 = arg1_default
used_arg1_default = True
2022-11-01 10:04:58 +01:00
2023-01-12 10:38:38 +01:00
if not isinstance ( arg1 , ( str , type ( None ) ) ) :
raise TypeError ( f " { arg1_name . capitalize ( ) } should be ' str ' , found: { type ( arg1 ) . __name__ } " )
2022-11-01 10:04:58 +01:00
2023-01-12 10:38:38 +01:00
arg2 = None
2022-11-01 10:04:58 +01:00
2023-01-12 10:38:38 +01:00
if arg1 and " / " in arg1 :
# project/package, repo/arch, etc.
if arg1 . count ( " / " ) != 1 :
raise oscerr . OscValueError ( f " Argument doesn ' t match the ' < { arg1_name } >/< { arg2_name } > ' pattern: { arg1 } " )
arg1 , arg2 = arg1 . split ( " / " )
2022-11-01 10:04:58 +01:00
2023-01-12 10:38:38 +01:00
if arg2 is None :
2022-11-01 10:04:58 +01:00
try :
2023-01-12 10:38:38 +01:00
arg2 = args . pop ( 0 )
2022-11-01 10:04:58 +01:00
except IndexError :
2023-01-12 10:38:38 +01:00
if not arg2_is_optional and not arg2_default and not used_arg1_default :
# arg2 is not optional and it wasn't specified together with arg1
raise oscerr . OscValueError ( f " Please specify a { arg2_name } " ) from None
arg2 = arg2_default
2022-11-07 10:36:03 +01:00
2023-01-12 10:38:38 +01:00
if not isinstance ( arg2 , ( str , type ( None ) ) ) :
raise TypeError ( f " { arg2_name . capitalize ( ) } should be ' str ' , found: { type ( arg2 ) . __name__ } " )
return arg1 , arg2
def pop_project_package_from_args (
args : List [ str ] ,
project_is_optional : bool = False ,
default_project : str = None ,
package_is_optional : bool = False ,
default_package : str = None ,
) :
"""
Pop project and package from given ` args ` .
They may be either 2 individual entries or a single entry with values separated with " / " .
. . warning : :
The ` args ` list gets modified in this function call !
: param args : List of command - line arguments .
: type args : list ( str )
: param project_is_optional : Whether to error out when project cannot be retrieved . Implies ` package_is_optional = False ` .
: type project_is_optional : bool
: param default_project : Used if project is not specified in ` args ` .
Resolved from the current working copy if set to ' . ' .
: type default_project : str
: param package_is_optional : Whether to error out when package cannot be retrieved .
: type package_is_optional : bool
: param default_package : Used if package is not specified in ` args ` .
Resolved from the current working copy if set to ' . ' .
: type default_package : str
: returns : Project and package .
: rtype : tuple ( str )
"""
project , package = pop_args (
args ,
arg1_name = " project " ,
arg1_is_optional = project_is_optional ,
arg1_default = default_project ,
arg2_name = " package " ,
arg2_is_optional = package_is_optional ,
arg2_default = default_package ,
)
2022-11-01 10:04:58 +01:00
2023-01-12 10:38:38 +01:00
path = Path . cwd ( )
2023-01-12 13:44:32 +01:00
project_store = None
package_store = None
2023-01-12 10:38:38 +01:00
if project == " . " :
# project name taken from the working copy
try :
2023-07-28 08:22:29 +02:00
project_store = osc_store . get_store ( path )
2023-01-12 13:44:32 +01:00
project = project_store . project
2023-01-12 10:38:38 +01:00
except oscerr . NoWorkingCopy :
if not project_is_optional :
raise
project = None
2022-11-01 10:04:58 +01:00
if package == " . " :
# package name taken from the working copy
try :
2023-07-28 08:22:29 +02:00
package_store = osc_store . get_store ( path )
2023-01-12 13:44:32 +01:00
package_store . assert_is_package ( )
package = package_store . package
2022-11-01 10:04:58 +01:00
except oscerr . NoWorkingCopy :
2023-01-12 13:44:32 +01:00
if package_is_optional :
package = None
elif not project_store and default_package == " . " :
# project wasn't retrieved from store, let's ask for specifying a package
raise oscerr . OscValueError ( " Please specify a package " ) from None
else :
2022-11-01 10:04:58 +01:00
raise
return project , package
2023-01-12 10:38:38 +01:00
def pop_repository_arch_from_args (
args : List [ str ] ,
repository_is_optional : bool = False ,
default_repository : str = None ,
arch_is_optional : bool = False ,
default_arch : str = None ,
) :
2022-12-15 16:23:11 +01:00
"""
2023-01-12 10:38:38 +01:00
Pop repository and arch from given ` args ` .
They may be either 2 individual entries or a single entry with values separated with " / " .
. . warning : :
The ` args ` list gets modified in this function call !
2022-12-15 16:23:11 +01:00
: param args : List of command - line arguments .
: type args : list ( str )
2023-01-12 10:38:38 +01:00
: param repository_is_optional : Whether to error out when project cannot be retrieved . Implies ` arch_is_optional = False ` .
: type repository_is_optional : bool
: param default_repository : Used if repository is not specified in ` args ` .
: type default_repository : str
: param arch_is_optional : Whether to error out when arch cannot be retrieved .
: type arch_is_optional : bool
: param default_arch : Used if arch is not specified in ` args ` .
: type default_arch : str
: returns : Repository and arch .
2022-12-15 16:23:11 +01:00
: rtype : tuple ( str )
"""
2023-01-12 10:38:38 +01:00
repository , arch = pop_args (
args ,
arg1_name = " repository " ,
arg1_is_optional = repository_is_optional ,
arg1_default = default_repository ,
arg2_name = " arch " ,
arg2_is_optional = arch_is_optional ,
arg2_default = default_arch ,
)
2022-12-15 16:23:11 +01:00
return repository , arch
2023-01-12 10:38:38 +01:00
def pop_project_package_repository_arch_from_args (
args : List [ str ] ,
project_is_optional : bool = False ,
default_project : str = None ,
package_is_optional : bool = False ,
default_package : str = None ,
repository_is_optional : bool = False ,
default_repository : str = None ,
arch_is_optional : bool = False ,
default_arch : str = None ,
) :
2022-12-15 16:23:11 +01:00
"""
2023-01-12 10:38:38 +01:00
Pop project , package , repository and arch from given ` args ` .
. . warning : :
The ` args ` list gets modified in this function call !
2022-12-15 16:23:11 +01:00
: param args : List of command - line arguments .
: type args : list ( str )
2023-01-12 10:38:38 +01:00
: param project_is_optional : Whether to error out when project cannot be retrieved . Implies ` package_is_optional = False ` .
: type project_is_optional : bool
: param default_project : Used if project is not specified in ` args ` .
Resolved from the current working copy if set to ' . ' .
: type default_project : str
: param package_is_optional : Whether to error out when package cannot be retrieved .
: type package_is_optional : bool
: param default_package : Used if package is not specified in ` args ` .
Resolved from the current working copy if set to ' . ' .
: type default_package : str
: param repository_is_optional : Whether to error out when project cannot be retrieved . Implies ` arch_is_optional = False ` .
: type repository_is_optional : bool
: param default_repository : Used if repository is not specified in ` args ` .
: type default_repository : str
: param arch_is_optional : Whether to error out when arch cannot be retrieved .
: type arch_is_optional : bool
: param default_arch : Used if arch is not specified in ` args ` .
: type default_arch : str
: returns : Project , package , repository and arch .
2022-12-15 16:23:11 +01:00
: rtype : tuple ( str )
"""
args_backup = args . copy ( )
2023-01-12 10:38:38 +01:00
if project_is_optional or package_is_optional :
repository_is_optional = True
arch_is_optional = True
try_working_copy = default_project == " . " or default_package == " . "
2022-12-15 16:23:11 +01:00
try :
# try this sequence first: project package repository arch
2023-01-12 10:38:38 +01:00
project , package = pop_project_package_from_args (
args ,
project_is_optional = project_is_optional ,
default_project = default_project ,
package_is_optional = package_is_optional ,
default_package = default_package ,
)
2022-12-15 16:23:11 +01:00
if args :
# we got more than 2 arguments -> we shouldn't try to retrieve project and package from a working copy
try_working_copy = False
2023-01-12 10:38:38 +01:00
repository , arch = pop_repository_arch_from_args (
args ,
repository_is_optional = repository_is_optional ,
default_repository = default_repository ,
arch_is_optional = arch_is_optional ,
default_arch = default_arch ,
)
2022-12-15 16:23:11 +01:00
except oscerr . OscValueError as ex :
if not try_working_copy :
raise ex from None
# then read project and package from working copy and try repository arch
args [ : ] = args_backup . copy ( )
project , package = pop_project_package_from_args (
2023-01-12 10:38:38 +01:00
[ ] , default_project = " . " , default_package = " . "
)
repository , arch = pop_repository_arch_from_args (
args ,
repository_is_optional = repository_is_optional ,
default_repository = default_repository ,
arch_is_optional = arch_is_optional ,
default_arch = default_arch ,
2022-12-15 16:23:11 +01:00
)
return project , package , repository , arch
2023-01-12 10:38:38 +01:00
def pop_project_package_targetproject_targetpackage_from_args (
args : List [ str ] ,
project_is_optional : bool = False ,
default_project : str = None ,
package_is_optional : bool = False ,
default_package : str = None ,
target_project_is_optional : bool = False ,
default_target_project : str = None ,
target_package_is_optional : bool = False ,
default_target_package : str = None ,
) :
2022-12-20 16:53:21 +01:00
"""
2023-01-12 10:38:38 +01:00
Pop project , package , target project and target package from given ` args ` .
. . warning : :
The ` args ` list gets modified in this function call !
2022-12-20 16:53:21 +01:00
: param args : List of command - line arguments .
: type args : list ( str )
2023-01-12 10:38:38 +01:00
: param project_is_optional : Whether to error out when project cannot be retrieved . Implies ` package_is_optional = False ` .
: type project_is_optional : bool
: param default_project : Used if project is not specified in ` args ` .
Resolved from the current working copy if set to ' . ' .
: type default_project : str
: param package_is_optional : Whether to error out when package cannot be retrieved .
: type package_is_optional : bool
: param default_package : Used if package is not specified in ` args ` .
Resolved from the current working copy if set to ' . ' .
: type default_package : str
: param target_project_is_optional : Whether to error out when target project cannot be retrieved . Implies ` target_package_is_optional = False ` .
2023-01-04 20:13:37 +01:00
: type target_project_is_optional : bool
2023-01-12 10:38:38 +01:00
: param default_target_project : Used if target project is not specified in ` args ` .
Resolved from the current working copy if set to ' . ' .
: type default_target_project : str
: param target_package_is_optional : Whether to error out when target package cannot be retrieved .
2022-12-20 16:53:21 +01:00
: type target_package_is_optional : bool
2023-01-12 10:38:38 +01:00
: param default_target_package : Used if target package is not specified in ` args ` .
Resolved from the current working copy if set to ' . ' .
: type default_target_package : str
: returns : Project , package , target project and target package .
2022-12-20 16:53:21 +01:00
: rtype : tuple ( str )
"""
args_backup = args . copy ( )
2023-01-12 10:38:38 +01:00
if project_is_optional or package_is_optional :
target_project_is_optional = True
target_package_is_optional = True
try_working_copy = default_project == " . " or default_package == " . "
2022-12-20 16:53:21 +01:00
try :
# try this sequence first: project package target_project target_package
2023-01-12 10:38:38 +01:00
project , package = pop_project_package_from_args (
args ,
project_is_optional = project_is_optional ,
default_project = default_project ,
package_is_optional = package_is_optional ,
default_package = default_package ,
)
2022-12-20 16:53:21 +01:00
if args :
# we got more than 2 arguments -> we shouldn't try to retrieve project and package from a working copy
try_working_copy = False
target_project , target_package = pop_project_package_from_args (
2023-01-12 10:38:38 +01:00
args ,
project_is_optional = target_project_is_optional ,
default_project = default_target_project ,
package_is_optional = target_package_is_optional ,
default_package = default_target_package ,
2022-12-20 16:53:21 +01:00
)
except oscerr . OscValueError as ex :
if not try_working_copy :
raise ex from None
# then read project and package from working copy and target_project target_package
args [ : ] = args_backup . copy ( )
project , package = pop_project_package_from_args (
2023-01-12 10:38:38 +01:00
[ ] ,
default_project = " . " ,
default_package = " . " ,
package_is_optional = False ,
2022-12-20 16:53:21 +01:00
)
target_project , target_package = pop_project_package_from_args (
2023-01-12 10:38:38 +01:00
args ,
project_is_optional = target_project_is_optional ,
default_project = default_target_project ,
package_is_optional = target_package_is_optional ,
default_package = default_target_package ,
2022-12-20 16:53:21 +01:00
)
return project , package , target_project , target_package
2022-12-15 16:23:11 +01:00
def ensure_no_remaining_args ( args ) :
2023-01-12 10:38:38 +01:00
"""
Error out when ` args ` still contains arguments .
: raises oscerr . WrongArgs : The ` args ` list still contains arguments .
"""
2022-12-15 16:23:11 +01:00
if not args :
return
args_str = " " . join ( args )
raise oscerr . WrongArgs ( f " Unexpected args: { args_str } " )
2022-01-19 15:13:55 +01:00
class Osc ( cmdln . Cmdln ) :
"""
openSUSE commander is a command - line interface to the Open Build Service .
Type ' osc <subcommand> --help ' for help on a specific subcommand .
2006-12-12 03:01:39 +01:00
2009-05-18 16:50:43 +02:00
For additional information , see
2010-07-27 15:20:35 +02:00
* http : / / en . opensuse . org / openSUSE : Build_Service_Tutorial
* http : / / en . opensuse . org / openSUSE : OSC
2008-09-24 14:23:56 +02:00
2015-02-21 08:49:56 +01:00
You can modify osc commands , or roll your own , via the plugin API :
2010-07-27 15:20:35 +02:00
* http : / / en . opensuse . org / openSUSE : OSC_plugins
2007-04-25 01:00:12 +02:00
"""
name = ' osc '
2006-12-12 03:01:39 +01:00
2022-01-19 15:13:55 +01:00
def __init__ ( self ) :
self . options = None
2013-06-13 19:57:34 +02:00
self . _load_plugins ( )
2011-02-11 02:43:10 +01:00
sys . stderr = safewriter . SafeWriter ( sys . stderr )
sys . stdout = safewriter . SafeWriter ( sys . stdout )
2006-05-23 15:48:58 +02:00
2022-08-04 16:08:47 +02:00
def _debug ( self , * args ) :
# if options are not initialized, still allow to use it
if not hasattr ( self , ' options ' ) or self . options . debug :
print ( * args , file = sys . stderr )
2009-05-06 15:20:15 +02:00
def get_version ( self ) :
return get_osc_version ( )
2007-05-16 12:55:05 +02:00
2022-05-10 14:49:21 +02:00
def _process_project_name ( self , project ) :
if isinstance ( project , str ) :
2022-10-18 23:38:28 +02:00
if project == ' . ' :
if is_package_dir ( Path . cwd ( ) ) or is_project_dir ( Path . cwd ( ) ) :
project = store_read_project ( Path . cwd ( ) )
else :
raise oscerr . WrongArgs ( ' No working directory ' )
2022-05-10 14:49:21 +02:00
return project . replace ( conf . config [ ' project_separator ' ] , ' : ' )
return project
2022-08-26 16:23:48 +02:00
def add_global_options ( self , parser , suppress = False ) :
def _add_parser_arguments_from_data ( argument_parser , data ) :
for kwargs in data :
args = kwargs . pop ( " names " )
if suppress :
kwargs [ " help " ] = argparse . SUPPRESS
kwargs [ " default " ] = argparse . SUPPRESS
argument_parser . add_argument ( * args , * * kwargs )
arguments = [ ]
2022-08-26 17:10:24 +02:00
arguments . append ( dict (
names = [ ' -v ' , ' --verbose ' ] ,
action = ' store_true ' ,
help = ' increase verbosity ' ,
) )
arguments . append ( dict (
names = [ ' -q ' , ' --quiet ' ] ,
action = ' store_true ' ,
help = ' be quiet, not verbose ' ,
) )
2022-08-26 16:23:48 +02:00
arguments . append ( dict (
names = [ ' --debugger ' ] ,
action = ' store_true ' ,
help = ' jump into the debugger before executing anything ' ,
) )
arguments . append ( dict (
names = [ ' --post-mortem ' ] ,
action = ' store_true ' ,
help = ' jump into the debugger in case of errors ' ,
) )
arguments . append ( dict (
names = [ ' --traceback ' ] ,
action = ' store_true ' ,
help = ' print call trace in case of errors ' ,
) )
arguments . append ( dict (
names = [ ' -H ' , ' --http-debug ' ] ,
action = ' store_true ' ,
help = ' debug HTTP traffic (filters some headers) ' ,
) )
arguments . append ( dict (
names = [ ' --http-full-debug ' ] ,
action = ' store_true ' ,
help = ' debug HTTP traffic (filters no headers) ' ,
) )
arguments . append ( dict (
names = [ ' --debug ' ] ,
action = ' store_true ' ,
help = ' print info useful for debugging ' ,
) )
arguments . append ( dict (
names = [ ' -A ' , ' --apiurl ' ] ,
metavar = ' URL/alias ' ,
help = ' specify URL to access API server at or an alias ' ,
) )
arguments . append ( dict (
names = [ ' --config ' ] ,
dest = ' conffile ' ,
metavar = ' FILE ' ,
help = ' specify alternate configuration file ' ,
) )
arguments . append ( dict (
names = [ ' --no-keyring ' ] ,
action = ' store_true ' ,
help = ' disable usage of desktop keyring system ' ,
) )
_add_parser_arguments_from_data ( parser , arguments )
2022-01-19 15:13:55 +01:00
def post_argparse ( self ) :
2007-05-16 12:55:05 +02:00
""" merge commandline options into the config """
2022-05-05 11:07:28 +02:00
2022-08-26 17:10:24 +02:00
# handle conflicting options manually because the mutually exclusive group is buggy
# https://github.com/python/cpython/issues/96310
if self . options . quiet and self . options . verbose :
self . argparse_error ( " argument -q/--quiet: not allowed with argument -v/--verbose " )
2022-01-19 15:13:55 +01:00
# avoid loading config that may trigger prompt for username, password etc.
if not self . options . command :
# no command specified
return
if self . alias_to_cmd_name_map . get ( self . options . command , None ) == " help " :
# help command specified
2022-05-05 11:07:28 +02:00
return
Merged revisions 3774-3775,3779,3781-3782,3787,3789-3793,3798,3802,3805,3817-3822,3827,3829-3830,3837-3839,3841-3842,3848-3850 via svnmerge from
https://forgesvn1.novell.com/svn/opensuse/branches/buildservice/osc-exception-handling
........
r3774 | poeml | 2008-04-22 17:39:45 +0200 (Tue, 22 Apr 2008) | 3 lines
A first draft on implement systematic exception handling:
Add errors.py with some exceptions defined, and babysitter.py to handle them
........
r3775 | poeml | 2008-04-22 22:34:12 +0200 (Tue, 22 Apr 2008) | 9 lines
- new global options:
--debugger jump into the debugger before executing anything
--post-mortem jump into the debugger in case of errors
-t, --traceback print call trace in case of errors
- traceback and post_mortem can also be set in .oscrc.
- catch more errors (HTTPError).
- make config accessible from outside of the Osc instance, by making it a class
attribute
........
r3779 | poeml | 2008-04-23 00:55:49 +0200 (Wed, 23 Apr 2008) | 5 lines
- new global option:
-d, --debug print info useful for debugging
- catch some more errors (HTTPError), with OscHTTPError which isn't very
advanced yet.
........
r3781 | Marcus_H | 2008-04-23 01:02:00 +0200 (Wed, 23 Apr 2008) | 2 lines
- added OscConfigError class (just for testing).
- small change in the signature of the OscBaseError constructor (actually we should get rid of the 'args' tuple because it will be deprecated sooner or later
........
r3782 | Marcus_H | 2008-04-23 02:02:13 +0200 (Wed, 23 Apr 2008) | 2 lines
- access the prg.conf.config dict in a save way - this way we avoid AttributeErrors if the prg.conf.config dict doesn't exist
- in case of an configparser error we have to use the prg.options object directly (this was removed in r3781 by accident)
........
r3787 | poeml | 2008-04-23 09:23:56 +0200 (Wed, 23 Apr 2008) | 4 lines
- remove local exception handling from do_req
- for HTTPError, print details (headers and response) when in debug mode
- catch AttributeError
........
r3789 | poeml | 2008-04-23 16:23:14 +0200 (Wed, 23 Apr 2008) | 4 lines
- errors: add two new classes named OscWrongOptionsError and OscWrongArgsError
- commandline: raise instances of the new errors in a number of places
- commandline: add get_cmd_help() to Osc instance which returns the formatted help of a subcommand
........
r3790 | Marcus_H | 2008-04-23 16:48:28 +0200 (Wed, 23 Apr 2008) | 4 lines
- added 2 new exception classes: OscNoConfigfileError and OscIOError
- added new method write_config() to the conf.py module: This method writes osc's configuration file
- minor cleanups in the conf module
........
r3791 | poeml | 2008-04-23 17:11:07 +0200 (Wed, 23 Apr 2008) | 3 lines
small compatibility fix for r3790: try-except-finally isn't supported in
python-2.4.2, thus do the same as try-except inside a try-finally.
........
r3792 | poeml | 2008-04-23 17:37:53 +0200 (Wed, 23 Apr 2008) | 2 lines
fix up the remaining places regarding handling of errors related to commandline parsing
........
r3793 | poeml | 2008-04-23 17:40:34 +0200 (Wed, 23 Apr 2008) | 3 lines
raise a NoWorkingCopyError in osc.core.store_read_project() in case of an
IOError
........
r3798 | Marcus_H | 2008-04-23 23:55:24 +0200 (Wed, 23 Apr 2008) | 1 line
ported -r3797 from trunk
........
r3802 | Marcus_H | 2008-04-24 11:00:55 +0200 (Thu, 24 Apr 2008) | 1 line
ported -r3801 from trunk
........
r3805 | poeml | 2008-04-24 12:52:30 +0200 (Thu, 24 Apr 2008) | 2 lines
raise OscHTTPError in show_pattern_meta(), replacing local error handling
........
r3817 | poeml | 2008-04-24 20:21:32 +0200 (Thu, 24 Apr 2008) | 9 lines
- remove errors.OscHTTPError again.
it seems simpler to use urllib2.HTTPError instead (and just add a specific
error text message where appropriate, and re-raise)
- for 404s, check out _which_ part was not found
it is very ugly, but may be considered Good for pragmatic reasons
- removed local exception handling and workaround for returned 500's from
delete_package() and delete_project(), thereby getting rid of 4 possible exit
points.
........
r3818 | Marcus_H | 2008-04-24 22:36:17 +0200 (Thu, 24 Apr 2008) | 1 line
- this check is superfluous because every HTTPError instance has a code attribute
........
r3819 | poeml | 2008-04-25 00:39:39 +0200 (Fri, 25 Apr 2008) | 1 line
remove a forgotten debug line from core.delete_project()
........
r3820 | poeml | 2008-04-25 10:07:58 +0200 (Fri, 25 Apr 2008) | 2 lines
- ditch local error handling from wipebinaries(), rebuild(), and abortbuild()
........
r3821 | poeml | 2008-04-25 10:56:38 +0200 (Fri, 25 Apr 2008) | 2 lines
It is never needed to import the exception module.
........
r3822 | poeml | 2008-04-25 11:13:39 +0200 (Fri, 25 Apr 2008) | 4 lines
- when going into the debugger with --post-mortem, always print a traceback before
(thus implying -t)
- do not jump into the debugger if not on a TTY, or working in interactive mode
........
r3827 | poeml | 2008-04-25 13:07:46 +0200 (Fri, 25 Apr 2008) | 9 lines
- add errors.OscWorkingCopyOutdated, which takes a tuple with three args:
path to working copy, current rev, expected rev
- add handler for urllib2.URLError errors to the babysitter
- simplify the OscWrongArgsError and OscWrongOptionsError handlers, by removing
the extra line "Sorry, wrong ..." that was printed before the messages given
when the error was raised.
- remove one more errors.OscHTTPError which was still there, and raise
urllib2.HTTPError instead (show_package_meta())
........
r3829 | poeml | 2008-04-25 14:19:10 +0200 (Fri, 25 Apr 2008) | 11 lines
- comment some methods in osc.core which are used by nearly all do_* methods in
osc.commandline
- improve "is not a package/project dir" error messages, by printing the
absolute path tried, instead of '.' for the cwd
- make core.store_read_package() raise a proper NoWorkingCopyError instead of
terminating
- give attribution to things in babysitter.py copied from mercurial
- prefix HTTPError exceptions with 'Server returned an error:'
- remove obsolete local error handling from do_prjresults(), do_importsrcpkg(),
do_repos()
........
r3830 | poeml | 2008-04-25 14:29:35 +0200 (Fri, 25 Apr 2008) | 1 line
catch IOError exceptions in the babysitter
........
r3837 | poeml | 2008-04-25 17:27:36 +0200 (Fri, 25 Apr 2008) | 5 lines
- do_remotebuildlog: raise errors for wrong arguments, remove exits
- raise AttributeError in make_meta_url() instead of exiting
- delete unused method core.delete_server_files()
- replace exit call inside make_meta_url() with an AttributeError
........
r3838 | poeml | 2008-04-25 17:49:18 +0200 (Fri, 25 Apr 2008) | 1 line
simplify the check in do_checkout if a project exists, by using show_project_meta() instead of meta_exists
........
r3839 | poeml | 2008-04-25 18:31:26 +0200 (Fri, 25 Apr 2008) | 6 lines
- commandline do_checkout(): change the order of the two checks, first do the
(cheaper) check for existing directory
- core.core checkout_package(): simplify the check in if the package
exists, by using show_package_meta() instead of meta_exists
Let it throw an exception, instead of using sys.exit().
........
r3841 | Marcus_H | 2008-04-27 15:48:06 +0200 (Sun, 27 Apr 2008) | 5 lines
- added 2 new exception classes: PackageError() and PackageExistsError. The PackageError() class is meant to be the base class for all subsequent package exceptions.
- get rid of 2 sys.exit(1) calls
- make the update() method of the Project() class safer: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- minor fix in delPackage(): use getTransActPath() when printing out the filename
........
r3842 | Marcus_H | 2008-04-27 16:52:55 +0200 (Sun, 27 Apr 2008) | 3 lines
- make the commit() method safe: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- removed another sys.exit(1): raise an exception if a package is missing when doing a commit. For now we use the PackageExistsError() exception but this might change in the future (updated description of PackageExistsError() according to this change)
........
r3848 | poeml | 2008-04-28 12:46:45 +0200 (Mon, 28 Apr 2008) | 3 lines
rename several error classes, dropping the "Osc" prefix, and "Error" suffix in
cases where they don't really make sense.
........
r3849 | poeml | 2008-04-28 12:57:32 +0200 (Mon, 28 Apr 2008) | 3 lines
- rename osc.errors module to osc.oscerr, to make it easier to import it from
other programs and have a crystal clear namespace
........
r3850 | poeml | 2008-04-28 13:26:12 +0200 (Mon, 28 Apr 2008) | 2 lines
split PackageExists exception class into PackageExists and PackageMissing
........
2008-04-28 18:37:44 +02:00
try :
2022-09-12 13:43:10 +02:00
conf . get_config ( override_conffile = self . options . conffile ,
override_apiurl = self . options . apiurl ,
override_debug = self . options . debug ,
override_http_debug = self . options . http_debug ,
override_http_full_debug = self . options . http_full_debug ,
override_traceback = self . options . traceback ,
override_post_mortem = self . options . post_mortem ,
override_no_keyring = self . options . no_keyring ,
override_verbose = self . options . verbose )
2013-04-09 11:27:02 +02:00
except oscerr . NoConfigfile as e :
2013-04-09 12:51:28 +02:00
print ( e . msg , file = sys . stderr )
print ( ' Creating osc configuration file %s ... ' % e . file , file = sys . stderr )
2023-08-22 15:34:45 +02:00
conf . interactive_config_setup ( e . file , self . options . apiurl )
2013-04-09 12:51:28 +02:00
print ( ' done ' , file = sys . stderr )
2022-01-19 15:13:55 +01:00
self . post_argparse ( )
2013-04-09 11:27:02 +02:00
except oscerr . ConfigMissingApiurl as e :
2013-04-09 12:51:28 +02:00
print ( e . msg , file = sys . stderr )
2019-08-26 11:30:41 +02:00
conf . interactive_config_setup ( e . file , e . url , initial = False )
2022-01-19 15:13:55 +01:00
self . post_argparse ( )
2019-08-29 11:35:34 +02:00
except oscerr . ConfigMissingCredentialsError as e :
print ( e . msg )
print ( ' Please enter new credentials. ' )
conf . interactive_config_setup ( e . file , e . url , initial = False )
2022-01-19 15:13:55 +01:00
self . post_argparse ( )
2008-08-07 19:14:26 +02:00
2009-08-20 21:28:05 +02:00
self . options . verbose = conf . config [ ' verbose ' ]
2010-02-09 20:57:10 +01:00
self . download_progress = None
if conf . config . get ( ' show_download_progress ' , False ) :
2019-01-14 12:03:16 +01:00
self . download_progress = create_text_meter ( )
2006-05-23 15:48:58 +02:00
2010-04-30 17:13:21 +02:00
def get_api_url ( self ) :
2011-04-06 15:31:36 +02:00
try :
2022-10-07 17:25:33 +02:00
localdir = Path . cwd ( )
2013-04-09 11:27:02 +02:00
except Exception as e :
2022-09-12 13:43:10 +02:00
# check for Stale NFS file handle: '.'
2013-05-27 13:38:49 +02:00
try :
os . stat ( ' . ' )
2014-08-12 15:01:16 +02:00
except Exception as ee :
2013-05-27 13:38:49 +02:00
e = ee
2022-10-07 17:25:33 +02:00
print ( " Path.cwd() failed: " , e , file = sys . stderr )
2011-04-06 15:31:36 +02:00
sys . exit ( 1 )
2010-04-30 17:13:21 +02:00
if ( is_package_dir ( localdir ) or is_project_dir ( localdir ) ) and not self . options . apiurl :
2022-10-14 14:25:54 +02:00
return osc_store . Store ( Path . cwd ( ) ) . apiurl
2010-04-30 17:13:21 +02:00
else :
2013-05-27 12:16:44 +02:00
return conf . config [ ' apiurl ' ]
2009-08-21 16:55:26 +02:00
2022-08-17 22:21:02 +02:00
def do_version ( self , subcmd , opts ) :
"""
Give version of osc binary
usage :
osc version
"""
print ( get_osc_version ( ) )
2022-09-20 10:02:48 +02:00
@cmdln.option ( ' project ' )
@cmdln.option ( ' package ' , nargs = ' ? ' )
@cmdln.option ( ' scm_url ' , nargs = ' ? ' )
def do_init ( self , subcmd , opts ) :
2022-01-19 15:13:55 +01:00
"""
Initialize a directory as working copy
2006-05-23 15:48:58 +02:00
2008-05-21 18:10:20 +02:00
Initialize an existing directory to be a working copy of an
2009-05-18 16:50:43 +02:00
( already existing ) buildservice project / package .
2008-05-21 18:10:20 +02:00
( This is the same as checking out a package and then copying sources
into the directory . It does NOT create a new package . To create a
package , use ' osc meta pkg ... ... ' )
2006-05-23 15:48:58 +02:00
2008-05-21 18:10:20 +02:00
You wouldn ' t normally use this command.
To get a working copy of a package ( e . g . for building it or working on
it , you would normally use the checkout command . Use " osc help
checkout " to get help for it.
2009-05-18 16:50:43 +02:00
usage :
2008-08-01 15:58:49 +02:00
osc init PRJ
2007-06-21 11:40:47 +02:00
osc init PRJ PAC
2021-11-30 13:13:11 +01:00
osc init PRJ PAC SCM_URL
2007-04-25 01:00:12 +02:00
"""
2009-05-18 16:50:43 +02:00
2022-09-20 10:02:48 +02:00
project = opts . project
package = opts . package
scm_url = opts . scm_url
2010-07-29 17:29:07 +02:00
apiurl = self . get_api_url ( )
2021-11-30 13:13:11 +01:00
if not scm_url :
scm_url = show_scmsync ( apiurl , project , package )
if scm_url :
if package :
2022-10-07 17:25:33 +02:00
Package . init_package ( apiurl , project , package , Path . cwd ( ) , scm_url = scm_url )
print ( ' Initializing %s (Project: %s , Package: %s ) as git repository ' % ( Path . cwd ( ) , project , package ) )
2021-11-30 13:13:11 +01:00
else :
2022-10-07 17:25:33 +02:00
Project . init_project ( apiurl , Path . cwd ( ) , project , conf . config [ ' do_package_tracking ' ] ,
2021-11-30 13:13:11 +01:00
getPackageList = False , scm_url = scm_url )
2022-10-07 17:25:33 +02:00
print ( ' Initializing %s (Project: %s ) as scm repository ' % ( Path . cwd ( ) , project ) )
2021-11-30 13:13:11 +01:00
return
2008-08-08 17:19:54 +02:00
if not package :
2022-10-07 17:25:33 +02:00
Project . init_project ( apiurl , Path . cwd ( ) , project , conf . config [ ' do_package_tracking ' ] ,
2020-11-05 13:08:20 +01:00
getPackageList = False )
2022-10-07 17:25:33 +02:00
print ( ' Initializing %s (Project: %s ) ' % ( Path . cwd ( ) , project ) )
2008-08-01 15:58:49 +02:00
else :
2022-10-07 17:25:33 +02:00
Package . init_package ( apiurl , project , package , Path . cwd ( ) )
store_write_string ( Path . cwd ( ) , ' _files ' , show_files_meta ( apiurl , project , package ) + b ' \n ' )
print ( ' Initializing %s (Project: %s , Package: %s ) ' % ( Path . cwd ( ) , project , package ) )
2007-04-25 01:00:12 +02:00
@cmdln.alias ( ' ls ' )
2009-08-20 21:28:05 +02:00
@cmdln.alias ( ' ll ' )
@cmdln.alias ( ' lL ' )
@cmdln.alias ( ' LL ' )
2007-08-16 20:15:08 +02:00
@cmdln.option ( ' -a ' , ' --arch ' , metavar = ' ARCH ' ,
2010-01-12 13:31:25 +01:00
help = ' specify architecture (only for binaries) ' )
2007-08-16 20:15:08 +02:00
@cmdln.option ( ' -r ' , ' --repo ' , metavar = ' REPO ' ,
2010-01-12 13:31:25 +01:00
help = ' specify repository (only for binaries) ' )
2007-08-16 20:15:08 +02:00
@cmdln.option ( ' -b ' , ' --binaries ' , action = ' store_true ' ,
2010-01-12 13:31:25 +01:00
help = ' list built binaries instead of sources ' )
@cmdln.option ( ' -e ' , ' --expand ' , action = ' store_true ' ,
help = ' expand linked package (only for sources) ' )
2010-03-08 23:52:51 +01:00
@cmdln.option ( ' -u ' , ' --unexpand ' , action = ' store_true ' ,
help = ' always work with unexpanded (source) packages ' )
2022-08-04 10:09:10 +02:00
@cmdln.option ( ' -l ' , ' --long ' , dest = ' verbose ' , action = ' store_true ' ,
2009-08-20 21:28:05 +02:00
help = ' print extra information ' )
2010-05-22 08:22:12 +02:00
@cmdln.option ( ' -D ' , ' --deleted ' , action = ' store_true ' ,
help = ' show only the former deleted projects or packages ' )
2011-06-08 10:25:15 +02:00
@cmdln.option ( ' -M ' , ' --meta ' , action = ' store_true ' ,
help = ' list meta data files ' )
@cmdln.option ( ' -R ' , ' --revision ' , metavar = ' REVISION ' ,
help = ' specify revision (only for sources) ' )
2007-04-25 01:00:12 +02:00
def do_list ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
List sources or binaries on the server
2007-08-16 20:15:08 +02:00
2010-01-12 13:31:25 +01:00
Examples for listing sources :
2010-12-02 23:36:40 +01:00
ls # list all projects (deprecated)
2010-12-02 23:52:38 +01:00
ls / # list all projects
2011-04-11 15:07:56 +02:00
ls . # take PROJECT/PACKAGE from current dir.
2010-01-12 13:31:25 +01:00
ls PROJECT # list packages in a project
ls PROJECT PACKAGE # list source files of package of a project
ls PROJECT PACKAGE < file > # list <file> if this file exists
ls - v PROJECT PACKAGE # verbosely list source files of package
ls - l PROJECT PACKAGE # verbosely list source files of package
ll PROJECT PACKAGE # verbosely list source files of package
LL PROJECT PACKAGE # verbosely list source files of expanded link
2007-06-26 15:17:38 +02:00
With - - verbose , the following fields will be shown for each item :
MD5 hash of file
Revision number of the last commit
Size ( in bytes )
Date and time of the last commit
2007-04-25 01:00:12 +02:00
2010-01-12 13:31:25 +01:00
Examples for listing binaries :
ls - b PROJECT # list all binaries of a project
ls - b PROJECT - a ARCH # list ARCH binaries of a project
ls - b PROJECT - r REPO # list binaries in REPO
ls - b PROJECT PACKAGE REPO ARCH
2022-01-19 15:13:55 +01:00
usage :
ls [ PROJECT [ PACKAGE ] ]
ls - b [ PROJECT [ PACKAGE [ REPO [ ARCH ] ] ] ]
2007-04-25 01:00:12 +02:00
"""
2007-06-26 15:17:38 +02:00
args = slash_split ( args )
2009-08-21 21:39:12 +02:00
if subcmd == ' ll ' :
opts . verbose = True
2022-10-18 23:40:52 +02:00
if subcmd in ( ' lL ' , ' LL ' ) :
2009-08-21 21:39:12 +02:00
opts . verbose = True
opts . expand = True
2007-06-26 15:17:38 +02:00
2009-11-17 14:39:46 +01:00
project = None
package = None
2010-01-12 13:31:25 +01:00
fname = None
2010-12-02 23:52:38 +01:00
if len ( args ) == 0 :
# For consistency with *all* other commands
2011-04-11 15:07:56 +02:00
# this lists what the server has in the current wd.
2010-12-02 23:52:38 +01:00
# CAUTION: 'osc ls -b' already works like this.
pass
2010-01-12 13:31:25 +01:00
if len ( args ) > 0 :
2007-04-25 01:00:12 +02:00
project = args [ 0 ]
2014-08-12 15:01:16 +02:00
if project == ' / ' :
2013-05-27 13:38:49 +02:00
project = None
2011-04-11 15:07:56 +02:00
if project == ' . ' :
2022-10-18 23:38:28 +02:00
project = self . _process_project_name ( project )
2011-04-11 15:07:56 +02:00
cwd = os . getcwd ( )
2022-10-07 17:25:33 +02:00
if is_package_dir ( cwd ) :
2011-04-11 15:07:56 +02:00
package = store_read_package ( cwd )
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( project )
2010-01-12 13:31:25 +01:00
if len ( args ) > 1 :
2007-04-25 01:00:12 +02:00
package = args [ 1 ]
2010-01-12 13:31:25 +01:00
if len ( args ) > 2 :
2010-05-22 08:22:12 +02:00
if opts . deleted :
raise oscerr . WrongArgs ( " Too many arguments when listing deleted packages " )
2010-01-12 13:31:25 +01:00
if opts . binaries :
if opts . repo :
if opts . repo != args [ 2 ] :
2022-04-20 19:22:35 +02:00
raise oscerr . WrongArgs ( " conflicting repos specified ( ' %s ' vs ' %s ' ) " % ( opts . repo , args [ 2 ] ) )
2010-01-12 13:31:25 +01:00
else :
opts . repo = args [ 2 ]
else :
2008-11-20 13:56:16 +01:00
fname = args [ 2 ]
2010-01-12 13:31:25 +01:00
if len ( args ) > 3 :
if not opts . binaries :
raise oscerr . WrongArgs ( ' Too many arguments ' )
if opts . arch :
if opts . arch != args [ 3 ] :
2022-04-20 19:22:35 +02:00
raise oscerr . WrongArgs ( " conflicting archs specified ( ' %s ' vs ' %s ' ) " % ( opts . arch , args [ 3 ] ) )
2010-01-12 13:31:25 +01:00
else :
opts . arch = args [ 3 ]
2009-03-31 00:28:26 +02:00
if opts . binaries and opts . expand :
raise oscerr . WrongOptions ( ' Sorry, --binaries and --expand are mutual exclusive. ' )
2007-08-16 20:15:08 +02:00
2014-08-12 15:01:16 +02:00
apiurl = self . get_api_url ( )
2010-07-29 17:29:07 +02:00
2007-08-16 20:15:08 +02:00
# list binaries
if opts . binaries :
2009-11-17 14:39:46 +01:00
# ls -b toplevel doesn't make sense, so use info from
# current dir if available
if len ( args ) == 0 :
2022-10-07 17:25:33 +02:00
cwd = Path . cwd ( )
2010-08-20 14:34:41 +02:00
if is_project_dir ( cwd ) :
project = store_read_project ( cwd )
elif is_package_dir ( cwd ) :
project = store_read_project ( cwd )
package = store_read_package ( cwd )
2010-04-30 17:13:21 +02:00
2009-11-17 14:39:46 +01:00
if not project :
Merged revisions 3774-3775,3779,3781-3782,3787,3789-3793,3798,3802,3805,3817-3822,3827,3829-3830,3837-3839,3841-3842,3848-3850 via svnmerge from
https://forgesvn1.novell.com/svn/opensuse/branches/buildservice/osc-exception-handling
........
r3774 | poeml | 2008-04-22 17:39:45 +0200 (Tue, 22 Apr 2008) | 3 lines
A first draft on implement systematic exception handling:
Add errors.py with some exceptions defined, and babysitter.py to handle them
........
r3775 | poeml | 2008-04-22 22:34:12 +0200 (Tue, 22 Apr 2008) | 9 lines
- new global options:
--debugger jump into the debugger before executing anything
--post-mortem jump into the debugger in case of errors
-t, --traceback print call trace in case of errors
- traceback and post_mortem can also be set in .oscrc.
- catch more errors (HTTPError).
- make config accessible from outside of the Osc instance, by making it a class
attribute
........
r3779 | poeml | 2008-04-23 00:55:49 +0200 (Wed, 23 Apr 2008) | 5 lines
- new global option:
-d, --debug print info useful for debugging
- catch some more errors (HTTPError), with OscHTTPError which isn't very
advanced yet.
........
r3781 | Marcus_H | 2008-04-23 01:02:00 +0200 (Wed, 23 Apr 2008) | 2 lines
- added OscConfigError class (just for testing).
- small change in the signature of the OscBaseError constructor (actually we should get rid of the 'args' tuple because it will be deprecated sooner or later
........
r3782 | Marcus_H | 2008-04-23 02:02:13 +0200 (Wed, 23 Apr 2008) | 2 lines
- access the prg.conf.config dict in a save way - this way we avoid AttributeErrors if the prg.conf.config dict doesn't exist
- in case of an configparser error we have to use the prg.options object directly (this was removed in r3781 by accident)
........
r3787 | poeml | 2008-04-23 09:23:56 +0200 (Wed, 23 Apr 2008) | 4 lines
- remove local exception handling from do_req
- for HTTPError, print details (headers and response) when in debug mode
- catch AttributeError
........
r3789 | poeml | 2008-04-23 16:23:14 +0200 (Wed, 23 Apr 2008) | 4 lines
- errors: add two new classes named OscWrongOptionsError and OscWrongArgsError
- commandline: raise instances of the new errors in a number of places
- commandline: add get_cmd_help() to Osc instance which returns the formatted help of a subcommand
........
r3790 | Marcus_H | 2008-04-23 16:48:28 +0200 (Wed, 23 Apr 2008) | 4 lines
- added 2 new exception classes: OscNoConfigfileError and OscIOError
- added new method write_config() to the conf.py module: This method writes osc's configuration file
- minor cleanups in the conf module
........
r3791 | poeml | 2008-04-23 17:11:07 +0200 (Wed, 23 Apr 2008) | 3 lines
small compatibility fix for r3790: try-except-finally isn't supported in
python-2.4.2, thus do the same as try-except inside a try-finally.
........
r3792 | poeml | 2008-04-23 17:37:53 +0200 (Wed, 23 Apr 2008) | 2 lines
fix up the remaining places regarding handling of errors related to commandline parsing
........
r3793 | poeml | 2008-04-23 17:40:34 +0200 (Wed, 23 Apr 2008) | 3 lines
raise a NoWorkingCopyError in osc.core.store_read_project() in case of an
IOError
........
r3798 | Marcus_H | 2008-04-23 23:55:24 +0200 (Wed, 23 Apr 2008) | 1 line
ported -r3797 from trunk
........
r3802 | Marcus_H | 2008-04-24 11:00:55 +0200 (Thu, 24 Apr 2008) | 1 line
ported -r3801 from trunk
........
r3805 | poeml | 2008-04-24 12:52:30 +0200 (Thu, 24 Apr 2008) | 2 lines
raise OscHTTPError in show_pattern_meta(), replacing local error handling
........
r3817 | poeml | 2008-04-24 20:21:32 +0200 (Thu, 24 Apr 2008) | 9 lines
- remove errors.OscHTTPError again.
it seems simpler to use urllib2.HTTPError instead (and just add a specific
error text message where appropriate, and re-raise)
- for 404s, check out _which_ part was not found
it is very ugly, but may be considered Good for pragmatic reasons
- removed local exception handling and workaround for returned 500's from
delete_package() and delete_project(), thereby getting rid of 4 possible exit
points.
........
r3818 | Marcus_H | 2008-04-24 22:36:17 +0200 (Thu, 24 Apr 2008) | 1 line
- this check is superfluous because every HTTPError instance has a code attribute
........
r3819 | poeml | 2008-04-25 00:39:39 +0200 (Fri, 25 Apr 2008) | 1 line
remove a forgotten debug line from core.delete_project()
........
r3820 | poeml | 2008-04-25 10:07:58 +0200 (Fri, 25 Apr 2008) | 2 lines
- ditch local error handling from wipebinaries(), rebuild(), and abortbuild()
........
r3821 | poeml | 2008-04-25 10:56:38 +0200 (Fri, 25 Apr 2008) | 2 lines
It is never needed to import the exception module.
........
r3822 | poeml | 2008-04-25 11:13:39 +0200 (Fri, 25 Apr 2008) | 4 lines
- when going into the debugger with --post-mortem, always print a traceback before
(thus implying -t)
- do not jump into the debugger if not on a TTY, or working in interactive mode
........
r3827 | poeml | 2008-04-25 13:07:46 +0200 (Fri, 25 Apr 2008) | 9 lines
- add errors.OscWorkingCopyOutdated, which takes a tuple with three args:
path to working copy, current rev, expected rev
- add handler for urllib2.URLError errors to the babysitter
- simplify the OscWrongArgsError and OscWrongOptionsError handlers, by removing
the extra line "Sorry, wrong ..." that was printed before the messages given
when the error was raised.
- remove one more errors.OscHTTPError which was still there, and raise
urllib2.HTTPError instead (show_package_meta())
........
r3829 | poeml | 2008-04-25 14:19:10 +0200 (Fri, 25 Apr 2008) | 11 lines
- comment some methods in osc.core which are used by nearly all do_* methods in
osc.commandline
- improve "is not a package/project dir" error messages, by printing the
absolute path tried, instead of '.' for the cwd
- make core.store_read_package() raise a proper NoWorkingCopyError instead of
terminating
- give attribution to things in babysitter.py copied from mercurial
- prefix HTTPError exceptions with 'Server returned an error:'
- remove obsolete local error handling from do_prjresults(), do_importsrcpkg(),
do_repos()
........
r3830 | poeml | 2008-04-25 14:29:35 +0200 (Fri, 25 Apr 2008) | 1 line
catch IOError exceptions in the babysitter
........
r3837 | poeml | 2008-04-25 17:27:36 +0200 (Fri, 25 Apr 2008) | 5 lines
- do_remotebuildlog: raise errors for wrong arguments, remove exits
- raise AttributeError in make_meta_url() instead of exiting
- delete unused method core.delete_server_files()
- replace exit call inside make_meta_url() with an AttributeError
........
r3838 | poeml | 2008-04-25 17:49:18 +0200 (Fri, 25 Apr 2008) | 1 line
simplify the check in do_checkout if a project exists, by using show_project_meta() instead of meta_exists
........
r3839 | poeml | 2008-04-25 18:31:26 +0200 (Fri, 25 Apr 2008) | 6 lines
- commandline do_checkout(): change the order of the two checks, first do the
(cheaper) check for existing directory
- core.core checkout_package(): simplify the check in if the package
exists, by using show_package_meta() instead of meta_exists
Let it throw an exception, instead of using sys.exit().
........
r3841 | Marcus_H | 2008-04-27 15:48:06 +0200 (Sun, 27 Apr 2008) | 5 lines
- added 2 new exception classes: PackageError() and PackageExistsError. The PackageError() class is meant to be the base class for all subsequent package exceptions.
- get rid of 2 sys.exit(1) calls
- make the update() method of the Project() class safer: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- minor fix in delPackage(): use getTransActPath() when printing out the filename
........
r3842 | Marcus_H | 2008-04-27 16:52:55 +0200 (Sun, 27 Apr 2008) | 3 lines
- make the commit() method safe: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- removed another sys.exit(1): raise an exception if a package is missing when doing a commit. For now we use the PackageExistsError() exception but this might change in the future (updated description of PackageExistsError() according to this change)
........
r3848 | poeml | 2008-04-28 12:46:45 +0200 (Mon, 28 Apr 2008) | 3 lines
rename several error classes, dropping the "Osc" prefix, and "Error" suffix in
cases where they don't really make sense.
........
r3849 | poeml | 2008-04-28 12:57:32 +0200 (Mon, 28 Apr 2008) | 3 lines
- rename osc.errors module to osc.oscerr, to make it easier to import it from
other programs and have a crystal clear namespace
........
r3850 | poeml | 2008-04-28 13:26:12 +0200 (Mon, 28 Apr 2008) | 2 lines
split PackageExists exception class into PackageExists and PackageMissing
........
2008-04-28 18:37:44 +02:00
raise oscerr . WrongArgs ( ' There are no binaries to list above project level. ' )
2009-04-09 10:21:12 +02:00
if opts . revision :
raise oscerr . WrongOptions ( ' Sorry, the --revision option is not supported for binaries. ' )
2007-08-16 20:15:08 +02:00
2009-11-17 14:39:46 +01:00
repos = [ ]
if opts . repo and opts . arch :
repos . append ( Repo ( opts . repo , opts . arch ) )
elif opts . repo and not opts . arch :
2010-04-09 03:37:04 +02:00
repos = [ repo for repo in get_repos_of_project ( apiurl , project ) if repo . name == opts . repo ]
2009-11-17 14:39:46 +01:00
elif opts . arch and not opts . repo :
2010-04-09 03:37:04 +02:00
repos = [ repo for repo in get_repos_of_project ( apiurl , project ) if repo . arch == opts . arch ]
2009-11-17 14:39:46 +01:00
else :
repos = get_repos_of_project ( apiurl , project )
2009-11-04 15:31:20 +01:00
2009-11-17 14:39:46 +01:00
results = [ ]
for repo in repos :
results . append ( ( repo , get_binarylist ( apiurl , project , repo . name , repo . arch , package = package , verbose = opts . verbose ) ) )
2007-08-16 20:15:08 +02:00
2009-11-17 14:39:46 +01:00
for result in results :
indent = ' '
if len ( results ) > 1 :
2013-04-09 12:51:28 +02:00
print ( ' %s / %s ' % ( result [ 0 ] . name , result [ 0 ] . arch ) )
2009-11-17 14:39:46 +01:00
indent = ' '
2009-11-04 15:31:20 +01:00
2009-11-17 14:39:46 +01:00
if opts . verbose :
for f in result [ 1 ] :
2018-03-13 14:56:33 +01:00
if f . size is None and f . mtime is None :
print ( " %9s %12s %-40s " % ( ' unknown ' , ' unknown ' , f . name ) )
2019-07-11 13:43:22 +02:00
elif f . size is None and f . mtime is not None :
print ( " %9s %s %-40s " % ( ' unknown ' , shorttime ( f . mtime ) , f . name ) )
elif f . size is not None and f . mtime is None :
print ( " %9d %12s %-40s " % ( f . size , ' unknown ' , f . name ) )
2018-03-13 14:56:33 +01:00
else :
print ( " %9d %s %-40s " % ( f . size , shorttime ( f . mtime ) , f . name ) )
2009-11-17 14:39:46 +01:00
else :
for f in result [ 1 ] :
2022-09-12 13:43:10 +02:00
print ( indent + f )
2007-08-16 20:15:08 +02:00
# list sources
elif not opts . binaries :
2023-04-11 09:36:18 +02:00
if not args or not project :
2011-01-05 10:11:55 +01:00
for prj in meta_get_project_list ( apiurl , opts . deleted ) :
2013-04-09 12:51:28 +02:00
print ( prj )
2007-08-16 20:15:08 +02:00
elif len ( args ) == 1 :
2022-09-12 13:43:10 +02:00
for pkg in meta_get_packagelist ( apiurl , project , deleted = opts . deleted , expand = opts . expand ) :
2013-04-09 12:51:28 +02:00
print ( pkg )
2007-08-16 20:15:08 +02:00
2008-11-20 13:56:16 +01:00
elif len ( args ) == 2 or len ( args ) == 3 :
2010-03-08 23:52:51 +01:00
link_seen = False
print_not_found = True
2010-04-09 01:22:26 +02:00
rev = opts . revision
2022-09-12 13:43:10 +02:00
for i in [ 1 , 2 ] :
2010-07-29 17:29:07 +02:00
l = meta_get_filelist ( apiurl ,
2022-09-12 13:43:10 +02:00
project ,
package ,
verbose = opts . verbose ,
expand = opts . expand ,
meta = opts . meta ,
deleted = opts . deleted ,
revision = rev )
2010-04-06 10:57:49 +02:00
link_seen = ' _link ' in l
2010-03-08 23:52:51 +01:00
if opts . verbose :
2022-09-12 13:43:10 +02:00
out = [ ' %s %7s %9d %s %s ' % ( i . md5 , i . rev , i . size , shorttime ( i . mtime ) , i . name )
for i in l if not fname or fname == i . name ]
2010-03-08 23:52:51 +01:00
if len ( out ) > 0 :
print_not_found = False
2013-04-09 12:51:28 +02:00
print ( ' \n ' . join ( out ) )
2010-04-09 03:37:04 +02:00
elif fname :
if fname in l :
2013-04-09 12:51:28 +02:00
print ( fname )
2010-04-09 03:37:04 +02:00
print_not_found = False
2008-11-20 13:56:16 +01:00
else :
2013-04-09 12:51:28 +02:00
print ( ' \n ' . join ( l ) )
2014-08-12 15:01:16 +02:00
if opts . expand or opts . unexpand or not link_seen :
2013-05-27 13:38:49 +02:00
break
2010-07-29 17:29:07 +02:00
m = show_files_meta ( apiurl , project , package )
2010-04-09 01:22:26 +02:00
li = Linkinfo ( )
2018-12-13 15:17:29 +01:00
root = ET . fromstring ( m )
li . read ( root . find ( ' linkinfo ' ) )
2010-04-09 01:22:26 +02:00
if li . haserror ( ) :
raise oscerr . LinkExpandError ( project , package , li . error )
project , package , rev = li . project , li . package , li . rev
2023-10-05 14:15:28 +02:00
if not revision_is_empty ( rev ) :
2013-04-09 12:51:28 +02:00
print ( ' # -> %s %s ( %s ) ' % ( project , package , rev ) )
2010-04-09 01:22:26 +02:00
else :
2013-04-09 12:51:28 +02:00
print ( ' # -> %s %s (latest) ' % ( project , package ) )
2010-03-08 23:52:51 +01:00
opts . expand = True
if fname and print_not_found :
2013-04-09 12:51:28 +02:00
print ( ' file \' %s \' does not exist ' % fname )
2017-02-13 21:45:16 +01:00
return 1
2007-04-25 01:00:12 +02:00
2018-04-27 09:15:48 +02:00
@cmdln.option ( ' --extend-package-names ' , default = False , action = " store_true " ,
help = ' Extend packages names with project name as suffix ' )
def do_addcontainers ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Add maintained containers for a give package
2018-04-27 09:15:48 +02:00
2019-05-24 13:42:47 +02:00
The command adds all containers which are marked as maintained and contain
an rpm originating from the specified source package .
2018-04-27 09:15:48 +02:00
Examples :
osc addcontainers [ PROJECT PACKAGE ]
"""
apiurl = self . get_api_url ( )
2022-11-09 08:57:47 +01:00
args = list ( args )
project , package = pop_project_package_from_args (
args , default_project = " . " , default_package = " . " , package_is_optional = False
)
2018-04-27 09:15:48 +02:00
2022-11-09 08:57:47 +01:00
_private . add_containers (
apiurl , project , package , extend_package_names = opts . extend_package_names , print_to = " stdout "
)
2018-04-27 09:15:48 +02:00
2015-07-14 16:03:35 +02:00
@cmdln.option ( ' -s ' , ' --skip-disabled ' , action = ' store_true ' ,
help = ' Skip disabled channels. Otherwise the source gets added, but not the repositories. ' )
@cmdln.option ( ' -e ' , ' --enable-all ' , action = ' store_true ' ,
help = ' Enable all added channels including the ones disabled by default. ' )
def do_addchannels ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Add channels to project
2015-07-14 16:03:35 +02:00
2016-05-15 17:50:31 +02:00
The command adds all channels which are defined to be used for a given source package .
2015-10-21 17:17:05 +02:00
The source link target is used to lookup the channels . The command can be
used for a certain package or for all in the specified project .
In case no channel is defined the operation is just returning .
2015-07-14 16:03:35 +02:00
Examples :
2015-10-21 17:17:05 +02:00
osc addchannels [ PROJECT [ PACKAGE ] ]
2015-07-14 16:03:35 +02:00
"""
apiurl = self . get_api_url ( )
2015-07-15 20:41:31 +02:00
2022-11-01 14:29:23 +01:00
args = list ( args )
project , package = pop_project_package_from_args (
args , default_project = " . " , default_package = " . " , package_is_optional = True
)
2015-09-04 11:09:40 +02:00
if opts . enable_all and opts . skip_disabled :
2022-11-01 14:29:23 +01:00
self . argparse_error ( " Options ' --enable-all ' and ' --skip-disabled ' are mutually exclusive " )
_private . add_channels (
apiurl , project , package , enable_all = opts . enable_all , skip_disabled = opts . skip_disabled , print_to = " stdout "
)
2015-07-14 16:03:35 +02:00
2015-10-21 17:17:05 +02:00
@cmdln.alias ( ' enablechannel ' )
def do_enablechannels ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Enables channels
2015-10-21 17:17:05 +02:00
Enables existing channel packages in a project . Enabling means adding the
needed repositories for building .
The command can be used to enable a specific one or all channels of a project .
Examples :
2022-11-01 14:50:18 +01:00
osc enablechannels [ PROJECT [ PACKAGE ] ]
2015-10-21 17:17:05 +02:00
"""
apiurl = self . get_api_url ( )
2022-11-01 14:50:18 +01:00
args = list ( args )
project , package = pop_project_package_from_args (
args , default_project = " . " , default_package = " . " , package_is_optional = True
)
2015-10-21 17:17:05 +02:00
2022-11-01 14:50:18 +01:00
_private . enable_channels ( apiurl , project , package , print_to = " stdout " )
2015-10-21 17:17:05 +02:00
2009-11-10 10:56:34 +01:00
@cmdln.option ( ' -f ' , ' --force ' , action = ' store_true ' ,
2011-11-30 10:52:50 +01:00
help = ' force generation of new patchinfo file, do not update existing one. ' )
2009-11-10 10:56:34 +01:00
def do_patchinfo ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Generate and edit a patchinfo file
2009-11-10 10:56:34 +01:00
A patchinfo file describes the packages for an update and the kind of
problem it solves .
2011-11-30 10:52:50 +01:00
This command either creates a new _patchinfo or updates an existing one .
2009-11-10 10:56:34 +01:00
Examples :
osc patchinfo
2012-01-09 11:29:11 +01:00
osc patchinfo [ PROJECT [ PATCH_NAME ] ]
2009-11-10 10:56:34 +01:00
"""
2018-04-27 14:41:08 +02:00
args = slash_split ( args )
2014-08-12 15:01:16 +02:00
apiurl = self . get_api_url ( )
2022-10-07 17:25:33 +02:00
project_dir = localdir = Path . cwd ( )
2012-01-09 11:29:11 +01:00
patchinfo = ' patchinfo '
if len ( args ) == 0 :
if is_project_dir ( localdir ) :
project = store_read_project ( localdir )
apiurl = self . get_api_url ( )
for p in meta_get_packagelist ( apiurl , project ) :
if p . startswith ( " _patchinfo " ) or p . startswith ( " patchinfo " ) :
patchinfo = p
2011-11-30 10:52:50 +01:00
else :
2012-01-09 11:29:11 +01:00
if is_package_dir ( localdir ) :
2013-05-27 12:16:44 +02:00
project = store_read_project ( localdir )
patchinfo = store_read_package ( localdir )
apiurl = self . get_api_url ( )
if not os . path . exists ( ' _patchinfo ' ) :
2012-03-23 09:37:08 +01:00
sys . exit ( ' Current checked out package has no _patchinfo. Either call it from project level or specify patch name. ' )
2012-01-09 11:29:11 +01:00
else :
2013-05-27 12:16:44 +02:00
sys . exit ( ' This command must be called in a checked out project or patchinfo package. ' )
2012-01-09 11:29:11 +01:00
else :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2012-01-09 11:29:11 +01:00
if len ( args ) > 1 :
patchinfo = args [ 1 ]
2010-02-28 02:30:13 +01:00
2011-12-16 15:29:54 +01:00
filelist = None
if patchinfo :
2012-01-09 11:29:11 +01:00
try :
filelist = meta_get_filelist ( apiurl , project , patchinfo )
2013-04-09 14:03:17 +02:00
except HTTPError :
2012-01-09 11:29:11 +01:00
pass
2022-09-12 14:15:34 +02:00
if opts . force or not filelist or ' _patchinfo ' not in filelist :
2013-04-09 12:51:28 +02:00
print ( " Creating new patchinfo... " )
2013-05-27 12:41:50 +02:00
query = ' cmd=createpatchinfo&name= ' + patchinfo
2011-12-16 15:29:54 +01:00
if opts . force :
query + = " &force=1 "
2009-11-10 10:56:34 +01:00
url = makeurl ( apiurl , [ ' source ' , project ] , query = query )
f = http_POST ( url )
2010-02-24 20:02:52 +01:00
for p in meta_get_packagelist ( apiurl , project ) :
2011-03-11 11:07:35 +01:00
if p . startswith ( " _patchinfo " ) or p . startswith ( " patchinfo " ) :
2010-02-24 20:02:52 +01:00
patchinfo = p
2011-11-30 10:52:50 +01:00
else :
2013-04-09 12:51:28 +02:00
print ( " Update existing _patchinfo file... " )
2013-05-27 12:41:50 +02:00
query = ' cmd=updatepatchinfo '
2011-11-30 10:52:50 +01:00
url = makeurl ( apiurl , [ ' source ' , project , patchinfo ] , query = query )
f = http_POST ( url )
2009-11-10 10:56:34 +01:00
2010-12-27 23:03:17 +01:00
# CAUTION:
2014-08-12 15:01:16 +02:00
# Both conf.config['checkout_no_colon'] and conf.config['checkout_rooted']
2010-12-27 23:03:17 +01:00
# fool this test:
2011-11-30 10:52:50 +01:00
if is_package_dir ( localdir ) :
pac = Package ( localdir )
pac . update ( )
filename = " _patchinfo "
else :
2009-11-10 10:56:34 +01:00
checkout_package ( apiurl , project , patchinfo , prj_dir = project_dir )
2023-02-08 11:46:16 +01:00
filename = project_dir / patchinfo / " /_patchinfo "
2009-11-10 10:56:34 +01:00
2010-05-05 09:03:51 +02:00
run_editor ( filename )
2009-11-10 10:56:34 +01:00
2011-03-08 19:23:04 +01:00
@cmdln.alias ( ' bsdevelproject ' )
2013-10-07 13:12:58 +02:00
@cmdln.alias ( ' dp ' )
2011-03-08 19:23:04 +01:00
def do_develproject ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Print the devel project / package of a package
2011-03-08 19:23:04 +01:00
Examples :
2022-11-07 10:36:03 +01:00
osc develproject [ PROJECT PACKAGE ]
2011-03-08 19:23:04 +01:00
"""
apiurl = self . get_api_url ( )
2022-11-07 10:36:03 +01:00
args = list ( args )
2023-01-12 13:44:32 +01:00
project , package = pop_project_package_from_args ( args , default_project = " . " , default_package = " . " )
2011-03-08 19:47:54 +01:00
2022-11-07 10:36:03 +01:00
devel_project , devel_package = show_devel_project ( apiurl , project , package )
if not devel_project :
print ( f " Package { project } / { package } has no devel project " , file = sys . stderr )
sys . exit ( 1 )
print ( f " { devel_project } / { devel_package } " )
2013-10-07 13:12:58 +02:00
2021-11-30 13:13:11 +01:00
@cmdln.alias ( ' ca ' )
def do_cleanassets ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Clean all previous downloaded assets
2021-11-30 13:13:11 +01:00
This is useful to prepare a new git commit .
"""
clean_assets ( " . " )
@cmdln.alias ( ' da ' )
def do_downloadassets ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Download all assets referenced in the build descriptions
2021-11-30 13:13:11 +01:00
"""
download_assets ( " . " )
2013-10-07 13:12:58 +02:00
@cmdln.alias ( ' sdp ' )
2013-10-18 11:50:07 +02:00
@cmdln.option ( ' -u ' , ' --unset ' , action = ' store_true ' ,
help = ' remove devel project ' )
2013-10-07 13:12:58 +02:00
def do_setdevelproject ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
""" Set the devel project / package of a package
2013-10-07 13:12:58 +02:00
Examples :
2022-11-07 10:36:03 +01:00
osc setdevelproject [ PROJECT PACKAGE ] DEVEL_PROJECT [ DEVEL_PACKAGE ]
2013-10-07 13:12:58 +02:00
"""
apiurl = self . get_api_url ( )
2022-11-07 10:36:03 +01:00
args = list ( args )
if opts . unset :
project , package = pop_project_package_from_args (
args , default_project = " . " , default_package = " . " , package_is_optional = False
)
devel_project = None
devel_package = None
2013-10-07 13:12:58 +02:00
else :
2022-11-07 10:36:03 +01:00
args_backup = args . copy ( )
2013-10-07 13:12:58 +02:00
2022-11-07 10:36:03 +01:00
try :
# try this sequence first: project package devel_project [devel_package]
project , package = pop_project_package_from_args ( args , package_is_optional = False )
devel_project , devel_package = pop_project_package_from_args (
args , default_package = package , package_is_optional = True
)
except oscerr . OscValueError :
# then read project and package from working copy and try devel_project [devel_package]
args = args_backup . copy ( )
project , package = pop_project_package_from_args (
[ ] , default_project = " . " , default_package = " . " , package_is_optional = False
)
devel_project , devel_package = pop_project_package_from_args (
args , default_package = package , package_is_optional = True
)
if args :
args_str = " , " . join ( args )
self . argparse_error ( f " Unknown arguments: { args_str } " )
2013-10-07 13:12:58 +02:00
2022-11-07 10:36:03 +01:00
set_devel_project ( apiurl , project , package , devel_project , devel_package , print_to = " stdout " )
2011-03-08 19:23:04 +01:00
2021-02-05 13:17:35 +01:00
def do_showlinked ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Show all packages linking to a given one
2021-02-05 13:17:35 +01:00
Examples :
osc showlinked [ PROJECT PACKAGE ]
"""
apiurl = self . get_api_url ( )
2022-11-09 10:31:20 +01:00
args = list ( args )
project , package = pop_project_package_from_args (
args , default_project = " . " , default_package = " . " , package_is_optional = False
)
linked_packages = _private . get_linked_packages ( apiurl , project , package )
for pkg in linked_packages :
print ( f " { pkg [ ' project ' ] } / { pkg [ ' name ' ] } " )
2021-02-05 13:17:35 +01:00
2013-10-31 09:12:17 +01:00
@cmdln.option ( ' -c ' , ' --create ' , action = ' store_true ' ,
help = ' Create a new token ' )
@cmdln.option ( ' -d ' , ' --delete ' , metavar = ' TOKENID ' ,
2018-10-25 10:16:12 +02:00
help = ' Delete a token ' )
2019-02-12 10:15:01 +01:00
@cmdln.option ( ' -o ' , ' --operation ' , metavar = ' OPERATION ' ,
2021-08-26 10:57:06 +02:00
help = ' Default is " runservice " , but " branch " , " release " , " rebuild " , or " workflow " can also be used ' )
2018-08-12 13:35:53 +02:00
@cmdln.option ( ' -t ' , ' --trigger ' , metavar = ' TOKENSTRING ' ,
2013-11-13 18:23:44 +01:00
help = ' Trigger the action of a token ' )
2022-09-12 13:43:10 +02:00
@cmdln.option ( ' ' , ' --scm-token ' , metavar = ' SCM_TOKEN ' ,
help = ' The scm \' s access token (only in combination with a --operation=workflow option) ' )
2013-10-31 09:12:17 +01:00
def do_token ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Show and manage authentication token
2013-10-31 09:12:17 +01:00
2013-12-09 19:26:15 +01:00
Authentication token can be used to run specific commands without
2013-10-31 09:12:17 +01:00
sending credentials .
2022-01-19 15:13:55 +01:00
usage :
2013-10-31 09:12:17 +01:00
osc token
2019-02-12 10:15:01 +01:00
osc token - - create [ - - operation < OPERATION > ] [ < PROJECT > < PACKAGE > ]
2013-10-31 09:12:17 +01:00
osc token - - delete < TOKENID >
2019-02-12 10:15:01 +01:00
osc token - - trigger < TOKENSTRING > [ - - operation < OPERATION > ] [ < PROJECT > < PACKAGE > ]
2013-10-31 09:12:17 +01:00
"""
args = slash_split ( args )
2021-08-26 10:57:06 +02:00
if opts . scm_token and opts . operation != ' workflow ' :
msg = ' The --scm-token option requires a --operation=workflow option '
raise oscerr . WrongOptions ( msg )
2013-10-31 09:12:17 +01:00
apiurl = self . get_api_url ( )
2021-08-26 10:46:57 +02:00
url_path = [ ' person ' , conf . get_apiurl_usr ( apiurl ) , ' token ' ]
2013-10-31 09:12:17 +01:00
if opts . create :
2021-08-26 10:57:06 +02:00
if opts . operation == ' workflow ' and not opts . scm_token :
msg = ' The --operation=workflow option requires a --scm-token=<token> option '
raise oscerr . WrongOptions ( msg )
2013-10-31 09:12:17 +01:00
print ( " Create a new token " )
2021-08-26 10:46:57 +02:00
query = { ' cmd ' : ' create ' }
2019-02-12 10:15:01 +01:00
if opts . operation :
2021-08-26 10:46:57 +02:00
query [ ' operation ' ] = opts . operation
2021-08-26 10:57:06 +02:00
if opts . scm_token :
query [ ' scm_token ' ] = opts . scm_token
2013-10-31 09:12:17 +01:00
if len ( args ) > 1 :
2021-08-26 10:46:57 +02:00
query [ ' project ' ] = args [ 0 ]
query [ ' package ' ] = args [ 1 ]
2013-10-31 09:12:17 +01:00
2021-08-26 10:46:57 +02:00
url = makeurl ( apiurl , url_path , query )
2013-10-31 09:12:17 +01:00
f = http_POST ( url )
while True :
2023-06-16 08:45:51 +02:00
data = f . read ( 16384 )
if not data :
2013-10-31 09:12:17 +01:00
break
2023-06-16 08:45:51 +02:00
sys . stdout . buffer . write ( data )
2013-10-31 09:12:17 +01:00
elif opts . delete :
print ( " Delete token " )
2021-08-26 10:46:57 +02:00
url_path . append ( opts . delete )
url = makeurl ( apiurl , url_path )
2013-10-31 09:12:17 +01:00
http_DELETE ( url )
2013-11-13 18:23:44 +01:00
elif opts . trigger :
print ( " Trigger token " )
2019-02-12 10:15:01 +01:00
operation = opts . operation or " runservice "
2021-08-26 10:46:57 +02:00
query = { }
2019-02-12 10:15:01 +01:00
if len ( args ) > 1 :
2021-08-26 10:46:57 +02:00
query [ ' project ' ] = args [ 0 ]
query [ ' package ' ] = args [ 1 ]
url = makeurl ( apiurl , [ ' trigger ' , operation ] , query )
2022-07-28 21:01:16 +02:00
headers = {
' Content-Type ' : ' application/octet-stream ' ,
' Authorization ' : " Token " + opts . trigger ,
}
fd = http_POST ( url , headers = headers )
2019-05-23 09:49:21 +02:00
print ( decode_it ( fd . read ( ) ) )
2013-10-31 09:12:17 +01:00
else :
2017-02-27 14:07:42 +01:00
if args and args [ 0 ] in [ ' create ' , ' delete ' , ' trigger ' ] :
raise oscerr . WrongArgs ( " Did you mean -- " + args [ 0 ] + " ? " )
2013-10-31 09:12:17 +01:00
# just list token
2021-08-26 10:46:57 +02:00
url = makeurl ( apiurl , url_path )
2013-10-31 09:12:17 +01:00
for data in streamfile ( url , http_GET ) :
2023-06-16 08:45:51 +02:00
sys . stdout . buffer . write ( data )
2013-10-31 09:12:17 +01:00
2009-10-30 10:40:46 +01:00
@cmdln.option ( ' -a ' , ' --attribute ' , metavar = ' ATTRIBUTE ' ,
help = ' affect only a given attribute ' )
2009-10-30 11:18:44 +01:00
@cmdln.option ( ' --attribute-defaults ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' include defined attribute defaults ' )
2009-10-30 11:18:44 +01:00
@cmdln.option ( ' --attribute-project ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' include project values, if missing in packages ' )
2017-03-21 14:44:19 +01:00
@cmdln.option ( ' --blame ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' show author and time of each line ' )
2011-03-16 10:20:38 +01:00
@cmdln.option ( ' -f ' , ' --force ' , action = ' store_true ' ,
2011-04-28 11:14:38 +02:00
help = ' force the save operation, allows one to ignores some errors like depending repositories. For prj meta only. ' )
2007-07-13 18:01:02 +02:00
@cmdln.option ( ' -F ' , ' --file ' , metavar = ' FILE ' ,
2007-07-16 12:58:11 +02:00
help = ' read metadata from FILE, instead of opening an editor. '
' \' - \' denotes standard input. ' )
2016-06-01 14:00:37 +02:00
@cmdln.option ( ' -r ' , ' --revision ' , metavar = ' REV ' ,
help = ' checkout given revision instead of head revision. For prj and prjconf meta only ' )
@cmdln.option ( ' -m ' , ' --message ' , metavar = ' TEXT ' ,
help = ' specify log message TEXT. For prj and prjconf meta only ' )
2007-07-16 18:20:09 +02:00
@cmdln.option ( ' -e ' , ' --edit ' , action = ' store_true ' ,
help = ' edit metadata ' )
2009-10-30 10:40:46 +01:00
@cmdln.option ( ' -c ' , ' --create ' , action = ' store_true ' ,
help = ' create attribute without values ' )
2012-12-06 14:07:02 +01:00
@cmdln.option ( ' -R ' , ' --remove-linking-repositories ' , action = ' store_true ' ,
help = ' Try to remove also all repositories building against remove ones. ' )
2009-10-30 10:40:46 +01:00
@cmdln.option ( ' -s ' , ' --set ' , metavar = ' ATTRIBUTE_VALUES ' ,
help = ' set attribute values ' )
2023-03-03 14:30:09 +01:00
@cmdln.option ( ' --add ' , metavar = ' ATTRIBUTE_VALUES ' ,
2023-07-18 15:37:43 +02:00
help = ' add to the existing attribute values, skip duplicates ' )
2007-07-19 14:23:42 +02:00
@cmdln.option ( ' --delete ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' delete a pattern or attribute ' )
2007-04-25 01:00:12 +02:00
def do_meta ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Show meta information , or edit it
2006-09-15 12:53:44 +02:00
2007-07-19 12:08:42 +02:00
Show or edit build service metadata of type < prj | pkg | prjconf | user | pattern > .
2007-07-16 12:58:11 +02:00
This command displays metadata on buildservice objects like projects ,
packages , or users . The type of metadata is specified by the word after
" meta " , like e . g . " meta prj " .
2007-07-16 15:40:58 +02:00
prj denotes metadata of a buildservice project .
prjconf denotes the ( build ) configuration of a project .
pkg denotes metadata of a buildservice package .
user denotes the metadata of a user .
2017-08-18 14:57:47 +02:00
group denotes the metadata of a group .
2007-07-19 12:14:10 +02:00
pattern denotes installation patterns defined for a project .
To list patterns , use ' osc meta pattern PRJ ' . An additional argument
will be the pattern file to view or edit .
2007-07-16 15:40:58 +02:00
2007-07-16 12:58:11 +02:00
With the - - edit switch , the metadata can be edited . Per default , osc
opens the program specified by the environmental variable EDITOR with a
temporary file . Alternatively , content to be saved can be supplied via
2007-07-16 18:20:09 +02:00
the - - file switch . If the argument is ' - ' , input is taken from stdin :
2009-03-02 15:03:06 +01:00
osc meta prjconf home : user | sed . . . | osc meta prjconf home : user - F -
2007-07-16 12:58:11 +02:00
2016-06-01 14:00:37 +02:00
For meta prj and prjconf updates optional commit messages can be applied with - - message .
2009-05-27 14:09:50 +02:00
When trying to edit a non - existing resource , it is created implicitly .
2006-09-15 12:53:44 +02:00
2007-08-09 18:15:13 +02:00
Examples :
osc meta prj PRJ
osc meta pkg PRJ PKG
osc meta pkg PRJ PKG - e
2022-01-19 15:13:55 +01:00
usage :
2016-06-01 14:00:37 +02:00
osc meta < prj | prjconf > [ - r | - - revision REV ] ARGS . . .
2017-08-18 14:57:47 +02:00
osc meta < prj | pkg | prjconf | user | group | pattern > ARGS . . .
osc meta < prj | pkg | prjconf | user | group | pattern > [ - m | - - message TEXT ] - e | - - edit ARGS . . .
osc meta < prj | pkg | prjconf | user | group | pattern > [ - m | - - message TEXT ] - F | - - file ARGS . . .
2007-07-19 14:23:42 +02:00
osc meta pattern - - delete PRJ PATTERN
2017-11-08 10:55:38 +01:00
osc meta attribute PRJ [ PKG [ SUBPACKAGE ] ] [ - - attribute ATTRIBUTE ] [ - - create [ - - set < value_list > ] | - - delete | - - set < value_list > ]
2007-04-25 01:00:12 +02:00
"""
2006-05-23 17:27:43 +02:00
2007-07-13 18:01:02 +02:00
args = slash_split ( args )
2006-05-23 17:27:43 +02:00
2007-07-13 18:01:02 +02:00
if not args or args [ 0 ] not in metatypes . keys ( ) :
2022-09-12 13:43:10 +02:00
raise oscerr . WrongArgs ( ' Unknown meta type. Choose one of %s . '
% ' , ' . join ( metatypes ) )
2006-10-12 15:22:56 +02:00
2007-07-13 18:01:02 +02:00
cmd = args [ 0 ]
del args [ 0 ]
2007-06-26 15:17:38 +02:00
2022-10-08 13:24:08 +02:00
if cmd == ' pkg ' :
2010-04-28 10:52:32 +02:00
min_args , max_args = 0 , 2
2022-10-08 13:24:08 +02:00
elif cmd == ' pattern ' :
2007-07-19 12:08:42 +02:00
min_args , max_args = 1 , 2
2022-10-08 13:24:08 +02:00
elif cmd == ' attribute ' :
2009-10-30 10:40:46 +01:00
min_args , max_args = 1 , 3
2022-10-08 13:24:08 +02:00
elif cmd in ( ' prj ' , ' prjconf ' ) :
2010-04-28 10:52:32 +02:00
min_args , max_args = 0 , 1
2007-07-13 18:01:02 +02:00
else :
2007-07-19 12:08:42 +02:00
min_args , max_args = 1 , 1
2010-04-28 10:52:32 +02:00
2007-07-19 12:08:42 +02:00
if len ( args ) < min_args :
Merged revisions 3774-3775,3779,3781-3782,3787,3789-3793,3798,3802,3805,3817-3822,3827,3829-3830,3837-3839,3841-3842,3848-3850 via svnmerge from
https://forgesvn1.novell.com/svn/opensuse/branches/buildservice/osc-exception-handling
........
r3774 | poeml | 2008-04-22 17:39:45 +0200 (Tue, 22 Apr 2008) | 3 lines
A first draft on implement systematic exception handling:
Add errors.py with some exceptions defined, and babysitter.py to handle them
........
r3775 | poeml | 2008-04-22 22:34:12 +0200 (Tue, 22 Apr 2008) | 9 lines
- new global options:
--debugger jump into the debugger before executing anything
--post-mortem jump into the debugger in case of errors
-t, --traceback print call trace in case of errors
- traceback and post_mortem can also be set in .oscrc.
- catch more errors (HTTPError).
- make config accessible from outside of the Osc instance, by making it a class
attribute
........
r3779 | poeml | 2008-04-23 00:55:49 +0200 (Wed, 23 Apr 2008) | 5 lines
- new global option:
-d, --debug print info useful for debugging
- catch some more errors (HTTPError), with OscHTTPError which isn't very
advanced yet.
........
r3781 | Marcus_H | 2008-04-23 01:02:00 +0200 (Wed, 23 Apr 2008) | 2 lines
- added OscConfigError class (just for testing).
- small change in the signature of the OscBaseError constructor (actually we should get rid of the 'args' tuple because it will be deprecated sooner or later
........
r3782 | Marcus_H | 2008-04-23 02:02:13 +0200 (Wed, 23 Apr 2008) | 2 lines
- access the prg.conf.config dict in a save way - this way we avoid AttributeErrors if the prg.conf.config dict doesn't exist
- in case of an configparser error we have to use the prg.options object directly (this was removed in r3781 by accident)
........
r3787 | poeml | 2008-04-23 09:23:56 +0200 (Wed, 23 Apr 2008) | 4 lines
- remove local exception handling from do_req
- for HTTPError, print details (headers and response) when in debug mode
- catch AttributeError
........
r3789 | poeml | 2008-04-23 16:23:14 +0200 (Wed, 23 Apr 2008) | 4 lines
- errors: add two new classes named OscWrongOptionsError and OscWrongArgsError
- commandline: raise instances of the new errors in a number of places
- commandline: add get_cmd_help() to Osc instance which returns the formatted help of a subcommand
........
r3790 | Marcus_H | 2008-04-23 16:48:28 +0200 (Wed, 23 Apr 2008) | 4 lines
- added 2 new exception classes: OscNoConfigfileError and OscIOError
- added new method write_config() to the conf.py module: This method writes osc's configuration file
- minor cleanups in the conf module
........
r3791 | poeml | 2008-04-23 17:11:07 +0200 (Wed, 23 Apr 2008) | 3 lines
small compatibility fix for r3790: try-except-finally isn't supported in
python-2.4.2, thus do the same as try-except inside a try-finally.
........
r3792 | poeml | 2008-04-23 17:37:53 +0200 (Wed, 23 Apr 2008) | 2 lines
fix up the remaining places regarding handling of errors related to commandline parsing
........
r3793 | poeml | 2008-04-23 17:40:34 +0200 (Wed, 23 Apr 2008) | 3 lines
raise a NoWorkingCopyError in osc.core.store_read_project() in case of an
IOError
........
r3798 | Marcus_H | 2008-04-23 23:55:24 +0200 (Wed, 23 Apr 2008) | 1 line
ported -r3797 from trunk
........
r3802 | Marcus_H | 2008-04-24 11:00:55 +0200 (Thu, 24 Apr 2008) | 1 line
ported -r3801 from trunk
........
r3805 | poeml | 2008-04-24 12:52:30 +0200 (Thu, 24 Apr 2008) | 2 lines
raise OscHTTPError in show_pattern_meta(), replacing local error handling
........
r3817 | poeml | 2008-04-24 20:21:32 +0200 (Thu, 24 Apr 2008) | 9 lines
- remove errors.OscHTTPError again.
it seems simpler to use urllib2.HTTPError instead (and just add a specific
error text message where appropriate, and re-raise)
- for 404s, check out _which_ part was not found
it is very ugly, but may be considered Good for pragmatic reasons
- removed local exception handling and workaround for returned 500's from
delete_package() and delete_project(), thereby getting rid of 4 possible exit
points.
........
r3818 | Marcus_H | 2008-04-24 22:36:17 +0200 (Thu, 24 Apr 2008) | 1 line
- this check is superfluous because every HTTPError instance has a code attribute
........
r3819 | poeml | 2008-04-25 00:39:39 +0200 (Fri, 25 Apr 2008) | 1 line
remove a forgotten debug line from core.delete_project()
........
r3820 | poeml | 2008-04-25 10:07:58 +0200 (Fri, 25 Apr 2008) | 2 lines
- ditch local error handling from wipebinaries(), rebuild(), and abortbuild()
........
r3821 | poeml | 2008-04-25 10:56:38 +0200 (Fri, 25 Apr 2008) | 2 lines
It is never needed to import the exception module.
........
r3822 | poeml | 2008-04-25 11:13:39 +0200 (Fri, 25 Apr 2008) | 4 lines
- when going into the debugger with --post-mortem, always print a traceback before
(thus implying -t)
- do not jump into the debugger if not on a TTY, or working in interactive mode
........
r3827 | poeml | 2008-04-25 13:07:46 +0200 (Fri, 25 Apr 2008) | 9 lines
- add errors.OscWorkingCopyOutdated, which takes a tuple with three args:
path to working copy, current rev, expected rev
- add handler for urllib2.URLError errors to the babysitter
- simplify the OscWrongArgsError and OscWrongOptionsError handlers, by removing
the extra line "Sorry, wrong ..." that was printed before the messages given
when the error was raised.
- remove one more errors.OscHTTPError which was still there, and raise
urllib2.HTTPError instead (show_package_meta())
........
r3829 | poeml | 2008-04-25 14:19:10 +0200 (Fri, 25 Apr 2008) | 11 lines
- comment some methods in osc.core which are used by nearly all do_* methods in
osc.commandline
- improve "is not a package/project dir" error messages, by printing the
absolute path tried, instead of '.' for the cwd
- make core.store_read_package() raise a proper NoWorkingCopyError instead of
terminating
- give attribution to things in babysitter.py copied from mercurial
- prefix HTTPError exceptions with 'Server returned an error:'
- remove obsolete local error handling from do_prjresults(), do_importsrcpkg(),
do_repos()
........
r3830 | poeml | 2008-04-25 14:29:35 +0200 (Fri, 25 Apr 2008) | 1 line
catch IOError exceptions in the babysitter
........
r3837 | poeml | 2008-04-25 17:27:36 +0200 (Fri, 25 Apr 2008) | 5 lines
- do_remotebuildlog: raise errors for wrong arguments, remove exits
- raise AttributeError in make_meta_url() instead of exiting
- delete unused method core.delete_server_files()
- replace exit call inside make_meta_url() with an AttributeError
........
r3838 | poeml | 2008-04-25 17:49:18 +0200 (Fri, 25 Apr 2008) | 1 line
simplify the check in do_checkout if a project exists, by using show_project_meta() instead of meta_exists
........
r3839 | poeml | 2008-04-25 18:31:26 +0200 (Fri, 25 Apr 2008) | 6 lines
- commandline do_checkout(): change the order of the two checks, first do the
(cheaper) check for existing directory
- core.core checkout_package(): simplify the check in if the package
exists, by using show_package_meta() instead of meta_exists
Let it throw an exception, instead of using sys.exit().
........
r3841 | Marcus_H | 2008-04-27 15:48:06 +0200 (Sun, 27 Apr 2008) | 5 lines
- added 2 new exception classes: PackageError() and PackageExistsError. The PackageError() class is meant to be the base class for all subsequent package exceptions.
- get rid of 2 sys.exit(1) calls
- make the update() method of the Project() class safer: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- minor fix in delPackage(): use getTransActPath() when printing out the filename
........
r3842 | Marcus_H | 2008-04-27 16:52:55 +0200 (Sun, 27 Apr 2008) | 3 lines
- make the commit() method safe: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- removed another sys.exit(1): raise an exception if a package is missing when doing a commit. For now we use the PackageExistsError() exception but this might change in the future (updated description of PackageExistsError() according to this change)
........
r3848 | poeml | 2008-04-28 12:46:45 +0200 (Mon, 28 Apr 2008) | 3 lines
rename several error classes, dropping the "Osc" prefix, and "Error" suffix in
cases where they don't really make sense.
........
r3849 | poeml | 2008-04-28 12:57:32 +0200 (Mon, 28 Apr 2008) | 3 lines
- rename osc.errors module to osc.oscerr, to make it easier to import it from
other programs and have a crystal clear namespace
........
r3850 | poeml | 2008-04-28 13:26:12 +0200 (Mon, 28 Apr 2008) | 2 lines
split PackageExists exception class into PackageExists and PackageMissing
........
2008-04-28 18:37:44 +02:00
raise oscerr . WrongArgs ( ' Too few arguments. ' )
2007-07-19 12:08:42 +02:00
if len ( args ) > max_args :
Merged revisions 3774-3775,3779,3781-3782,3787,3789-3793,3798,3802,3805,3817-3822,3827,3829-3830,3837-3839,3841-3842,3848-3850 via svnmerge from
https://forgesvn1.novell.com/svn/opensuse/branches/buildservice/osc-exception-handling
........
r3774 | poeml | 2008-04-22 17:39:45 +0200 (Tue, 22 Apr 2008) | 3 lines
A first draft on implement systematic exception handling:
Add errors.py with some exceptions defined, and babysitter.py to handle them
........
r3775 | poeml | 2008-04-22 22:34:12 +0200 (Tue, 22 Apr 2008) | 9 lines
- new global options:
--debugger jump into the debugger before executing anything
--post-mortem jump into the debugger in case of errors
-t, --traceback print call trace in case of errors
- traceback and post_mortem can also be set in .oscrc.
- catch more errors (HTTPError).
- make config accessible from outside of the Osc instance, by making it a class
attribute
........
r3779 | poeml | 2008-04-23 00:55:49 +0200 (Wed, 23 Apr 2008) | 5 lines
- new global option:
-d, --debug print info useful for debugging
- catch some more errors (HTTPError), with OscHTTPError which isn't very
advanced yet.
........
r3781 | Marcus_H | 2008-04-23 01:02:00 +0200 (Wed, 23 Apr 2008) | 2 lines
- added OscConfigError class (just for testing).
- small change in the signature of the OscBaseError constructor (actually we should get rid of the 'args' tuple because it will be deprecated sooner or later
........
r3782 | Marcus_H | 2008-04-23 02:02:13 +0200 (Wed, 23 Apr 2008) | 2 lines
- access the prg.conf.config dict in a save way - this way we avoid AttributeErrors if the prg.conf.config dict doesn't exist
- in case of an configparser error we have to use the prg.options object directly (this was removed in r3781 by accident)
........
r3787 | poeml | 2008-04-23 09:23:56 +0200 (Wed, 23 Apr 2008) | 4 lines
- remove local exception handling from do_req
- for HTTPError, print details (headers and response) when in debug mode
- catch AttributeError
........
r3789 | poeml | 2008-04-23 16:23:14 +0200 (Wed, 23 Apr 2008) | 4 lines
- errors: add two new classes named OscWrongOptionsError and OscWrongArgsError
- commandline: raise instances of the new errors in a number of places
- commandline: add get_cmd_help() to Osc instance which returns the formatted help of a subcommand
........
r3790 | Marcus_H | 2008-04-23 16:48:28 +0200 (Wed, 23 Apr 2008) | 4 lines
- added 2 new exception classes: OscNoConfigfileError and OscIOError
- added new method write_config() to the conf.py module: This method writes osc's configuration file
- minor cleanups in the conf module
........
r3791 | poeml | 2008-04-23 17:11:07 +0200 (Wed, 23 Apr 2008) | 3 lines
small compatibility fix for r3790: try-except-finally isn't supported in
python-2.4.2, thus do the same as try-except inside a try-finally.
........
r3792 | poeml | 2008-04-23 17:37:53 +0200 (Wed, 23 Apr 2008) | 2 lines
fix up the remaining places regarding handling of errors related to commandline parsing
........
r3793 | poeml | 2008-04-23 17:40:34 +0200 (Wed, 23 Apr 2008) | 3 lines
raise a NoWorkingCopyError in osc.core.store_read_project() in case of an
IOError
........
r3798 | Marcus_H | 2008-04-23 23:55:24 +0200 (Wed, 23 Apr 2008) | 1 line
ported -r3797 from trunk
........
r3802 | Marcus_H | 2008-04-24 11:00:55 +0200 (Thu, 24 Apr 2008) | 1 line
ported -r3801 from trunk
........
r3805 | poeml | 2008-04-24 12:52:30 +0200 (Thu, 24 Apr 2008) | 2 lines
raise OscHTTPError in show_pattern_meta(), replacing local error handling
........
r3817 | poeml | 2008-04-24 20:21:32 +0200 (Thu, 24 Apr 2008) | 9 lines
- remove errors.OscHTTPError again.
it seems simpler to use urllib2.HTTPError instead (and just add a specific
error text message where appropriate, and re-raise)
- for 404s, check out _which_ part was not found
it is very ugly, but may be considered Good for pragmatic reasons
- removed local exception handling and workaround for returned 500's from
delete_package() and delete_project(), thereby getting rid of 4 possible exit
points.
........
r3818 | Marcus_H | 2008-04-24 22:36:17 +0200 (Thu, 24 Apr 2008) | 1 line
- this check is superfluous because every HTTPError instance has a code attribute
........
r3819 | poeml | 2008-04-25 00:39:39 +0200 (Fri, 25 Apr 2008) | 1 line
remove a forgotten debug line from core.delete_project()
........
r3820 | poeml | 2008-04-25 10:07:58 +0200 (Fri, 25 Apr 2008) | 2 lines
- ditch local error handling from wipebinaries(), rebuild(), and abortbuild()
........
r3821 | poeml | 2008-04-25 10:56:38 +0200 (Fri, 25 Apr 2008) | 2 lines
It is never needed to import the exception module.
........
r3822 | poeml | 2008-04-25 11:13:39 +0200 (Fri, 25 Apr 2008) | 4 lines
- when going into the debugger with --post-mortem, always print a traceback before
(thus implying -t)
- do not jump into the debugger if not on a TTY, or working in interactive mode
........
r3827 | poeml | 2008-04-25 13:07:46 +0200 (Fri, 25 Apr 2008) | 9 lines
- add errors.OscWorkingCopyOutdated, which takes a tuple with three args:
path to working copy, current rev, expected rev
- add handler for urllib2.URLError errors to the babysitter
- simplify the OscWrongArgsError and OscWrongOptionsError handlers, by removing
the extra line "Sorry, wrong ..." that was printed before the messages given
when the error was raised.
- remove one more errors.OscHTTPError which was still there, and raise
urllib2.HTTPError instead (show_package_meta())
........
r3829 | poeml | 2008-04-25 14:19:10 +0200 (Fri, 25 Apr 2008) | 11 lines
- comment some methods in osc.core which are used by nearly all do_* methods in
osc.commandline
- improve "is not a package/project dir" error messages, by printing the
absolute path tried, instead of '.' for the cwd
- make core.store_read_package() raise a proper NoWorkingCopyError instead of
terminating
- give attribution to things in babysitter.py copied from mercurial
- prefix HTTPError exceptions with 'Server returned an error:'
- remove obsolete local error handling from do_prjresults(), do_importsrcpkg(),
do_repos()
........
r3830 | poeml | 2008-04-25 14:29:35 +0200 (Fri, 25 Apr 2008) | 1 line
catch IOError exceptions in the babysitter
........
r3837 | poeml | 2008-04-25 17:27:36 +0200 (Fri, 25 Apr 2008) | 5 lines
- do_remotebuildlog: raise errors for wrong arguments, remove exits
- raise AttributeError in make_meta_url() instead of exiting
- delete unused method core.delete_server_files()
- replace exit call inside make_meta_url() with an AttributeError
........
r3838 | poeml | 2008-04-25 17:49:18 +0200 (Fri, 25 Apr 2008) | 1 line
simplify the check in do_checkout if a project exists, by using show_project_meta() instead of meta_exists
........
r3839 | poeml | 2008-04-25 18:31:26 +0200 (Fri, 25 Apr 2008) | 6 lines
- commandline do_checkout(): change the order of the two checks, first do the
(cheaper) check for existing directory
- core.core checkout_package(): simplify the check in if the package
exists, by using show_package_meta() instead of meta_exists
Let it throw an exception, instead of using sys.exit().
........
r3841 | Marcus_H | 2008-04-27 15:48:06 +0200 (Sun, 27 Apr 2008) | 5 lines
- added 2 new exception classes: PackageError() and PackageExistsError. The PackageError() class is meant to be the base class for all subsequent package exceptions.
- get rid of 2 sys.exit(1) calls
- make the update() method of the Project() class safer: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- minor fix in delPackage(): use getTransActPath() when printing out the filename
........
r3842 | Marcus_H | 2008-04-27 16:52:55 +0200 (Sun, 27 Apr 2008) | 3 lines
- make the commit() method safe: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- removed another sys.exit(1): raise an exception if a package is missing when doing a commit. For now we use the PackageExistsError() exception but this might change in the future (updated description of PackageExistsError() according to this change)
........
r3848 | poeml | 2008-04-28 12:46:45 +0200 (Mon, 28 Apr 2008) | 3 lines
rename several error classes, dropping the "Osc" prefix, and "Error" suffix in
cases where they don't really make sense.
........
r3849 | poeml | 2008-04-28 12:57:32 +0200 (Mon, 28 Apr 2008) | 3 lines
- rename osc.errors module to osc.oscerr, to make it easier to import it from
other programs and have a crystal clear namespace
........
r3850 | poeml | 2008-04-28 13:26:12 +0200 (Mon, 28 Apr 2008) | 2 lines
split PackageExists exception class into PackageExists and PackageMissing
........
2008-04-28 18:37:44 +02:00
raise oscerr . WrongArgs ( ' Too many arguments. ' )
2006-10-12 15:22:56 +02:00
2023-03-03 14:30:09 +01:00
if opts . add and opts . set :
self . argparse_error ( " Options --add and --set are mutually exclusive " )
2023-07-18 13:13:35 +02:00
if cmd == " attribute " and opts . edit and not opts . attribute :
self . argparse_error ( " Please specify --attribute " )
2012-04-02 13:38:06 +02:00
apiurl = self . get_api_url ( )
2023-07-18 13:13:35 +02:00
project = None
package = None
subpackage = None
user = None
group = None
pattern = None
2012-04-02 13:38:06 +02:00
2014-01-10 13:04:45 +01:00
# Specific arguments
#
# If project or package arguments missing, assume to work
# with project and/or package in current local directory.
2009-10-30 10:40:46 +01:00
attributepath = [ ]
2014-01-10 13:04:45 +01:00
if cmd in [ ' prj ' , ' prjconf ' ] :
if len ( args ) < 1 :
2022-10-14 14:25:54 +02:00
apiurl = osc_store . Store ( Path . cwd ( ) ) . apiurl
2022-10-07 17:25:33 +02:00
project = store_read_project ( Path . cwd ( ) )
2010-05-05 09:03:51 +02:00
else :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2010-05-05 09:03:51 +02:00
2014-01-10 13:04:45 +01:00
elif cmd == ' pkg ' :
if len ( args ) < 2 :
2022-10-14 14:25:54 +02:00
apiurl = osc_store . Store ( Path . cwd ( ) ) . apiurl
2022-10-07 17:25:33 +02:00
project = store_read_project ( Path . cwd ( ) )
2014-01-10 13:04:45 +01:00
if len ( args ) < 1 :
2022-10-07 17:25:33 +02:00
package = store_read_package ( Path . cwd ( ) )
2010-05-05 09:03:51 +02:00
else :
2014-01-10 13:04:45 +01:00
package = args [ 0 ]
else :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2014-01-10 13:04:45 +01:00
package = args [ 1 ]
2010-04-28 10:52:32 +02:00
2009-10-30 10:40:46 +01:00
elif cmd == ' attribute ' :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2009-10-30 10:40:46 +01:00
if len ( args ) > 1 :
2009-12-30 15:10:11 +01:00
package = args [ 1 ]
2009-10-30 10:40:46 +01:00
else :
2009-12-30 15:10:11 +01:00
package = None
if opts . attribute_project :
raise oscerr . WrongOptions ( ' --attribute-project works only when also a package is given ' )
2009-10-30 10:40:46 +01:00
if len ( args ) > 2 :
2009-12-30 15:10:11 +01:00
subpackage = args [ 2 ]
2009-10-30 10:40:46 +01:00
else :
2009-12-30 15:10:11 +01:00
subpackage = None
2009-10-30 10:40:46 +01:00
attributepath . append ( ' source ' )
attributepath . append ( project )
if package :
2009-12-30 15:10:11 +01:00
attributepath . append ( package )
2009-10-30 10:40:46 +01:00
if subpackage :
2009-12-30 15:10:11 +01:00
attributepath . append ( subpackage )
2009-10-30 10:40:46 +01:00
attributepath . append ( ' _attribute ' )
2007-07-13 18:01:02 +02:00
elif cmd == ' user ' :
2007-04-25 01:00:12 +02:00
user = args [ 0 ]
2017-08-18 14:57:47 +02:00
elif cmd == ' group ' :
group = args [ 0 ]
2007-07-19 12:08:42 +02:00
elif cmd == ' pattern ' :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2007-07-19 12:08:42 +02:00
if len ( args ) > 1 :
pattern = args [ 1 ]
else :
pattern = None
2007-07-19 13:54:13 +02:00
# enforce pattern argument if needed
if opts . edit or opts . file :
Merged revisions 3774-3775,3779,3781-3782,3787,3789-3793,3798,3802,3805,3817-3822,3827,3829-3830,3837-3839,3841-3842,3848-3850 via svnmerge from
https://forgesvn1.novell.com/svn/opensuse/branches/buildservice/osc-exception-handling
........
r3774 | poeml | 2008-04-22 17:39:45 +0200 (Tue, 22 Apr 2008) | 3 lines
A first draft on implement systematic exception handling:
Add errors.py with some exceptions defined, and babysitter.py to handle them
........
r3775 | poeml | 2008-04-22 22:34:12 +0200 (Tue, 22 Apr 2008) | 9 lines
- new global options:
--debugger jump into the debugger before executing anything
--post-mortem jump into the debugger in case of errors
-t, --traceback print call trace in case of errors
- traceback and post_mortem can also be set in .oscrc.
- catch more errors (HTTPError).
- make config accessible from outside of the Osc instance, by making it a class
attribute
........
r3779 | poeml | 2008-04-23 00:55:49 +0200 (Wed, 23 Apr 2008) | 5 lines
- new global option:
-d, --debug print info useful for debugging
- catch some more errors (HTTPError), with OscHTTPError which isn't very
advanced yet.
........
r3781 | Marcus_H | 2008-04-23 01:02:00 +0200 (Wed, 23 Apr 2008) | 2 lines
- added OscConfigError class (just for testing).
- small change in the signature of the OscBaseError constructor (actually we should get rid of the 'args' tuple because it will be deprecated sooner or later
........
r3782 | Marcus_H | 2008-04-23 02:02:13 +0200 (Wed, 23 Apr 2008) | 2 lines
- access the prg.conf.config dict in a save way - this way we avoid AttributeErrors if the prg.conf.config dict doesn't exist
- in case of an configparser error we have to use the prg.options object directly (this was removed in r3781 by accident)
........
r3787 | poeml | 2008-04-23 09:23:56 +0200 (Wed, 23 Apr 2008) | 4 lines
- remove local exception handling from do_req
- for HTTPError, print details (headers and response) when in debug mode
- catch AttributeError
........
r3789 | poeml | 2008-04-23 16:23:14 +0200 (Wed, 23 Apr 2008) | 4 lines
- errors: add two new classes named OscWrongOptionsError and OscWrongArgsError
- commandline: raise instances of the new errors in a number of places
- commandline: add get_cmd_help() to Osc instance which returns the formatted help of a subcommand
........
r3790 | Marcus_H | 2008-04-23 16:48:28 +0200 (Wed, 23 Apr 2008) | 4 lines
- added 2 new exception classes: OscNoConfigfileError and OscIOError
- added new method write_config() to the conf.py module: This method writes osc's configuration file
- minor cleanups in the conf module
........
r3791 | poeml | 2008-04-23 17:11:07 +0200 (Wed, 23 Apr 2008) | 3 lines
small compatibility fix for r3790: try-except-finally isn't supported in
python-2.4.2, thus do the same as try-except inside a try-finally.
........
r3792 | poeml | 2008-04-23 17:37:53 +0200 (Wed, 23 Apr 2008) | 2 lines
fix up the remaining places regarding handling of errors related to commandline parsing
........
r3793 | poeml | 2008-04-23 17:40:34 +0200 (Wed, 23 Apr 2008) | 3 lines
raise a NoWorkingCopyError in osc.core.store_read_project() in case of an
IOError
........
r3798 | Marcus_H | 2008-04-23 23:55:24 +0200 (Wed, 23 Apr 2008) | 1 line
ported -r3797 from trunk
........
r3802 | Marcus_H | 2008-04-24 11:00:55 +0200 (Thu, 24 Apr 2008) | 1 line
ported -r3801 from trunk
........
r3805 | poeml | 2008-04-24 12:52:30 +0200 (Thu, 24 Apr 2008) | 2 lines
raise OscHTTPError in show_pattern_meta(), replacing local error handling
........
r3817 | poeml | 2008-04-24 20:21:32 +0200 (Thu, 24 Apr 2008) | 9 lines
- remove errors.OscHTTPError again.
it seems simpler to use urllib2.HTTPError instead (and just add a specific
error text message where appropriate, and re-raise)
- for 404s, check out _which_ part was not found
it is very ugly, but may be considered Good for pragmatic reasons
- removed local exception handling and workaround for returned 500's from
delete_package() and delete_project(), thereby getting rid of 4 possible exit
points.
........
r3818 | Marcus_H | 2008-04-24 22:36:17 +0200 (Thu, 24 Apr 2008) | 1 line
- this check is superfluous because every HTTPError instance has a code attribute
........
r3819 | poeml | 2008-04-25 00:39:39 +0200 (Fri, 25 Apr 2008) | 1 line
remove a forgotten debug line from core.delete_project()
........
r3820 | poeml | 2008-04-25 10:07:58 +0200 (Fri, 25 Apr 2008) | 2 lines
- ditch local error handling from wipebinaries(), rebuild(), and abortbuild()
........
r3821 | poeml | 2008-04-25 10:56:38 +0200 (Fri, 25 Apr 2008) | 2 lines
It is never needed to import the exception module.
........
r3822 | poeml | 2008-04-25 11:13:39 +0200 (Fri, 25 Apr 2008) | 4 lines
- when going into the debugger with --post-mortem, always print a traceback before
(thus implying -t)
- do not jump into the debugger if not on a TTY, or working in interactive mode
........
r3827 | poeml | 2008-04-25 13:07:46 +0200 (Fri, 25 Apr 2008) | 9 lines
- add errors.OscWorkingCopyOutdated, which takes a tuple with three args:
path to working copy, current rev, expected rev
- add handler for urllib2.URLError errors to the babysitter
- simplify the OscWrongArgsError and OscWrongOptionsError handlers, by removing
the extra line "Sorry, wrong ..." that was printed before the messages given
when the error was raised.
- remove one more errors.OscHTTPError which was still there, and raise
urllib2.HTTPError instead (show_package_meta())
........
r3829 | poeml | 2008-04-25 14:19:10 +0200 (Fri, 25 Apr 2008) | 11 lines
- comment some methods in osc.core which are used by nearly all do_* methods in
osc.commandline
- improve "is not a package/project dir" error messages, by printing the
absolute path tried, instead of '.' for the cwd
- make core.store_read_package() raise a proper NoWorkingCopyError instead of
terminating
- give attribution to things in babysitter.py copied from mercurial
- prefix HTTPError exceptions with 'Server returned an error:'
- remove obsolete local error handling from do_prjresults(), do_importsrcpkg(),
do_repos()
........
r3830 | poeml | 2008-04-25 14:29:35 +0200 (Fri, 25 Apr 2008) | 1 line
catch IOError exceptions in the babysitter
........
r3837 | poeml | 2008-04-25 17:27:36 +0200 (Fri, 25 Apr 2008) | 5 lines
- do_remotebuildlog: raise errors for wrong arguments, remove exits
- raise AttributeError in make_meta_url() instead of exiting
- delete unused method core.delete_server_files()
- replace exit call inside make_meta_url() with an AttributeError
........
r3838 | poeml | 2008-04-25 17:49:18 +0200 (Fri, 25 Apr 2008) | 1 line
simplify the check in do_checkout if a project exists, by using show_project_meta() instead of meta_exists
........
r3839 | poeml | 2008-04-25 18:31:26 +0200 (Fri, 25 Apr 2008) | 6 lines
- commandline do_checkout(): change the order of the two checks, first do the
(cheaper) check for existing directory
- core.core checkout_package(): simplify the check in if the package
exists, by using show_package_meta() instead of meta_exists
Let it throw an exception, instead of using sys.exit().
........
r3841 | Marcus_H | 2008-04-27 15:48:06 +0200 (Sun, 27 Apr 2008) | 5 lines
- added 2 new exception classes: PackageError() and PackageExistsError. The PackageError() class is meant to be the base class for all subsequent package exceptions.
- get rid of 2 sys.exit(1) calls
- make the update() method of the Project() class safer: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- minor fix in delPackage(): use getTransActPath() when printing out the filename
........
r3842 | Marcus_H | 2008-04-27 16:52:55 +0200 (Sun, 27 Apr 2008) | 3 lines
- make the commit() method safe: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- removed another sys.exit(1): raise an exception if a package is missing when doing a commit. For now we use the PackageExistsError() exception but this might change in the future (updated description of PackageExistsError() according to this change)
........
r3848 | poeml | 2008-04-28 12:46:45 +0200 (Mon, 28 Apr 2008) | 3 lines
rename several error classes, dropping the "Osc" prefix, and "Error" suffix in
cases where they don't really make sense.
........
r3849 | poeml | 2008-04-28 12:57:32 +0200 (Mon, 28 Apr 2008) | 3 lines
- rename osc.errors module to osc.oscerr, to make it easier to import it from
other programs and have a crystal clear namespace
........
r3850 | poeml | 2008-04-28 13:26:12 +0200 (Mon, 28 Apr 2008) | 2 lines
split PackageExists exception class into PackageExists and PackageMissing
........
2008-04-28 18:37:44 +02:00
raise oscerr . WrongArgs ( ' A pattern file argument is required. ' )
2007-07-16 18:20:09 +02:00
2016-06-01 14:00:37 +02:00
if cmd not in [ ' prj ' , ' prjconf ' ] and ( opts . message or opts . revision ) :
raise oscerr . WrongOptions ( ' options --revision and --message are only supported for the prj or prjconf subcommand ' )
2009-05-18 16:50:43 +02:00
# show
2023-03-03 14:30:09 +01:00
if not opts . edit and not opts . file and not opts . delete and not opts . create and not opts . set and not opts . add :
2007-07-16 18:20:09 +02:00
if cmd == ' prj ' :
2018-12-13 15:17:29 +01:00
sys . stdout . write ( decode_it ( b ' ' . join ( show_project_meta ( apiurl , project , rev = opts . revision , blame = opts . blame ) ) ) )
2007-07-16 18:20:09 +02:00
elif cmd == ' pkg ' :
2018-12-13 15:17:29 +01:00
sys . stdout . write ( decode_it ( b ' ' . join ( show_package_meta ( apiurl , project , package , blame = opts . blame ) ) ) )
2009-10-30 10:40:46 +01:00
elif cmd == ' attribute ' :
2018-12-13 15:17:29 +01:00
sys . stdout . write ( decode_it ( b ' ' . join ( show_attribute_meta ( apiurl , project , package , subpackage ,
2022-09-12 13:43:10 +02:00
opts . attribute , opts . attribute_defaults , opts . attribute_project ) ) ) )
2007-07-16 18:20:09 +02:00
elif cmd == ' prjconf ' :
2018-12-13 15:17:29 +01:00
sys . stdout . write ( decode_it ( b ' ' . join ( show_project_conf ( apiurl , project , rev = opts . revision , blame = opts . blame ) ) ) )
2007-07-16 18:20:09 +02:00
elif cmd == ' user ' :
2010-06-18 16:06:01 +02:00
r = get_user_meta ( apiurl , user )
2007-07-13 18:01:02 +02:00
if r :
2018-12-13 15:17:29 +01:00
sys . stdout . write ( decode_it ( r ) )
2017-08-18 14:57:47 +02:00
elif cmd == ' group ' :
2017-08-21 09:48:50 +02:00
r = get_group_meta ( apiurl , group )
2017-08-18 14:57:47 +02:00
if r :
2018-12-13 15:17:29 +01:00
sys . stdout . write ( decode_it ( r ) )
2007-07-19 12:08:42 +02:00
elif cmd == ' pattern ' :
if pattern :
2010-06-18 16:06:01 +02:00
r = show_pattern_meta ( apiurl , project , pattern )
2007-07-19 12:08:42 +02:00
if r :
sys . stdout . write ( ' ' . join ( r ) )
else :
2010-06-18 16:06:01 +02:00
r = show_pattern_metalist ( apiurl , project )
2007-07-19 12:08:42 +02:00
if r :
sys . stdout . write ( ' \n ' . join ( r ) + ' \n ' )
2007-07-16 18:20:09 +02:00
# edit
if opts . edit and not opts . file :
if cmd == ' prj ' :
2009-05-18 16:50:43 +02:00
edit_meta ( metatype = ' prj ' ,
2007-07-16 18:20:09 +02:00
edit = True ,
2011-03-16 10:20:38 +01:00
force = opts . force ,
2012-12-06 14:07:02 +01:00
remove_linking_repositories = opts . remove_linking_repositories ,
2007-07-16 18:20:09 +02:00
path_args = quote_plus ( project ) ,
2010-06-18 16:06:01 +02:00
apiurl = apiurl ,
2022-09-12 13:43:10 +02:00
msg = opts . message ,
2008-03-07 10:13:30 +01:00
template_args = ( {
2022-09-12 13:43:10 +02:00
' name ' : project ,
' user ' : conf . get_apiurl_usr ( apiurl ) } ) )
2007-07-16 18:20:09 +02:00
elif cmd == ' pkg ' :
2009-05-18 16:50:43 +02:00
edit_meta ( metatype = ' pkg ' ,
2007-07-16 18:20:09 +02:00
edit = True ,
path_args = ( quote_plus ( project ) , quote_plus ( package ) ) ,
2010-06-18 16:06:01 +02:00
apiurl = apiurl ,
2008-03-07 10:13:30 +01:00
template_args = ( {
2022-09-12 13:43:10 +02:00
' name ' : package ,
' user ' : conf . get_apiurl_usr ( apiurl ) } ) )
2007-07-16 18:20:09 +02:00
elif cmd == ' prjconf ' :
2009-05-18 16:50:43 +02:00
edit_meta ( metatype = ' prjconf ' ,
2007-07-16 18:20:09 +02:00
edit = True ,
path_args = quote_plus ( project ) ,
2010-06-18 16:06:01 +02:00
apiurl = apiurl ,
2022-09-12 13:43:10 +02:00
msg = opts . message ,
2007-07-16 18:20:09 +02:00
template_args = None )
elif cmd == ' user ' :
2009-05-18 16:50:43 +02:00
edit_meta ( metatype = ' user ' ,
2007-07-16 18:20:09 +02:00
edit = True ,
path_args = ( quote_plus ( user ) ) ,
2010-06-18 16:06:01 +02:00
apiurl = apiurl ,
2008-03-07 10:13:30 +01:00
template_args = ( { ' user ' : user } ) )
2017-08-18 14:57:47 +02:00
elif cmd == ' group ' :
edit_meta ( metatype = ' group ' ,
edit = True ,
path_args = ( quote_plus ( group ) ) ,
apiurl = apiurl ,
template_args = ( { ' group ' : group } ) )
2007-07-19 12:08:42 +02:00
elif cmd == ' pattern ' :
2009-05-18 16:50:43 +02:00
edit_meta ( metatype = ' pattern ' ,
2007-07-19 12:08:42 +02:00
edit = True ,
path_args = ( project , pattern ) ,
2010-06-18 16:06:01 +02:00
apiurl = apiurl ,
2007-07-19 12:08:42 +02:00
template_args = None )
2023-07-18 13:13:35 +02:00
elif cmd == ' attribute ' :
edit_meta (
metatype = ' attribute ' ,
edit = True ,
path_args = ( quote_plus ( project ) , quote_plus ( opts . attribute ) ) ,
apiurl = apiurl ,
# PUT is not supported
method = " POST " ,
template_args = None ,
)
2007-07-16 18:20:09 +02:00
2009-10-30 10:40:46 +01:00
# create attribute entry
2023-03-03 14:30:09 +01:00
if ( opts . create or opts . set or opts . add ) and cmd == ' attribute ' :
2009-12-30 15:10:11 +01:00
if not opts . attribute :
raise oscerr . WrongOptions ( ' no attribute given to create ' )
2023-03-03 14:30:09 +01:00
aname = opts . attribute . split ( " : " )
if len ( aname ) != 2 :
raise oscerr . WrongOptions ( ' Given attribute is not in " NAMESPACE:NAME " style ' )
2023-07-18 15:37:43 +02:00
values = [ ]
2023-03-03 14:30:09 +01:00
if opts . add :
# read the existing values from server
root = _private . api . get ( apiurl , attributepath )
nodes = _private . api . find_nodes ( root , " attributes " , " attribute " , { " namespace " : aname [ 0 ] , " name " : aname [ 1 ] } , " value " )
for node in nodes :
# append the existing values
2023-07-18 15:37:43 +02:00
values . append ( node . text )
2023-03-03 14:30:09 +01:00
# pretend we're setting values in order to append the values we have specified on the command-line,
# because OBS API doesn't support extending the value list directly
opts . set = opts . add
2009-12-30 15:10:11 +01:00
if opts . set :
for i in opts . set . split ( ' , ' ) :
2023-07-18 15:37:43 +02:00
# append the new values
# we skip duplicates during --add
if opts . add and i in values :
continue
values . append ( i )
values_str = " "
for value in values :
value = _private . api . xml_escape ( value )
values_str + = f " <value> { value } </value> "
2023-03-03 14:30:09 +01:00
2023-07-18 15:37:43 +02:00
ns = _private . api . xml_escape ( aname [ 0 ] )
name = _private . api . xml_escape ( aname [ 1 ] )
d = f " <attributes><attribute namespace= ' { ns } ' name= ' { name } ' > { values_str } </attribute></attributes> "
2010-06-18 16:06:01 +02:00
url = makeurl ( apiurl , attributepath )
2009-12-30 15:10:11 +01:00
for data in streamfile ( url , http_POST , data = d ) :
2023-06-16 08:45:51 +02:00
sys . stdout . buffer . write ( data )
2009-10-30 10:40:46 +01:00
2007-07-16 18:20:09 +02:00
# upload file
if opts . file :
if opts . file == ' - ' :
f = sys . stdin . read ( )
2007-07-13 18:01:02 +02:00
else :
2007-07-16 18:20:09 +02:00
try :
f = open ( opts . file ) . read ( )
except :
sys . exit ( ' could not open file \' %s \' . ' % opts . file )
if cmd == ' prj ' :
2009-05-18 16:50:43 +02:00
edit_meta ( metatype = ' prj ' ,
2007-07-16 18:20:09 +02:00
data = f ,
edit = opts . edit ,
2011-03-16 10:20:38 +01:00
force = opts . force ,
2012-12-06 14:07:02 +01:00
remove_linking_repositories = opts . remove_linking_repositories ,
2010-06-18 16:06:01 +02:00
apiurl = apiurl ,
2022-09-12 13:43:10 +02:00
msg = opts . message ,
2007-07-16 18:20:09 +02:00
path_args = quote_plus ( project ) )
elif cmd == ' pkg ' :
2009-05-18 16:50:43 +02:00
edit_meta ( metatype = ' pkg ' ,
2007-07-16 18:20:09 +02:00
data = f ,
edit = opts . edit ,
2010-06-18 16:06:01 +02:00
apiurl = apiurl ,
2007-07-16 18:20:09 +02:00
path_args = ( quote_plus ( project ) , quote_plus ( package ) ) )
elif cmd == ' prjconf ' :
2009-05-18 16:50:43 +02:00
edit_meta ( metatype = ' prjconf ' ,
2007-07-16 18:20:09 +02:00
data = f ,
edit = opts . edit ,
2010-06-18 16:06:01 +02:00
apiurl = apiurl ,
2022-09-12 13:43:10 +02:00
msg = opts . message ,
2007-07-16 18:20:09 +02:00
path_args = quote_plus ( project ) )
elif cmd == ' user ' :
2009-05-18 16:50:43 +02:00
edit_meta ( metatype = ' user ' ,
2007-07-16 18:20:09 +02:00
data = f ,
edit = opts . edit ,
2010-06-18 16:06:01 +02:00
apiurl = apiurl ,
2007-07-16 18:20:09 +02:00
path_args = ( quote_plus ( user ) ) )
2017-08-18 14:57:47 +02:00
elif cmd == ' group ' :
edit_meta ( metatype = ' group ' ,
data = f ,
edit = opts . edit ,
apiurl = apiurl ,
path_args = ( quote_plus ( group ) ) )
2007-07-19 12:08:42 +02:00
elif cmd == ' pattern ' :
2009-05-18 16:50:43 +02:00
edit_meta ( metatype = ' pattern ' ,
2007-07-19 12:08:42 +02:00
data = f ,
edit = opts . edit ,
2010-06-18 16:06:01 +02:00
apiurl = apiurl ,
2007-07-19 12:08:42 +02:00
path_args = ( project , pattern ) )
2007-07-16 18:20:09 +02:00
2007-07-19 14:23:42 +02:00
# delete
if opts . delete :
path = metatypes [ cmd ] [ ' path ' ]
if cmd == ' pattern ' :
path = path % ( project , pattern )
2010-06-18 16:06:01 +02:00
u = makeurl ( apiurl , [ path ] )
2008-04-10 23:04:17 +02:00
http_DELETE ( u )
2009-10-30 10:40:46 +01:00
elif cmd == ' attribute ' :
if not opts . attribute :
2009-12-30 15:10:11 +01:00
raise oscerr . WrongOptions ( ' no attribute given to create ' )
2009-10-30 10:40:46 +01:00
attributepath . append ( opts . attribute )
2010-06-18 16:06:01 +02:00
u = makeurl ( apiurl , attributepath )
2009-12-30 15:10:11 +01:00
for data in streamfile ( u , http_DELETE ) :
2023-06-16 08:45:51 +02:00
sys . stdout . buffer . write ( data )
2007-07-19 14:23:42 +02:00
else :
2009-12-30 15:10:11 +01:00
raise oscerr . WrongOptions ( ' The --delete switch is only for pattern metadata or attributes. ' )
2007-07-19 14:23:42 +02:00
2010-12-30 03:14:24 +01:00
# TODO: rewrite and consolidate the current submitrequest/createrequest "mess"
2008-03-05 00:41:00 +01:00
@cmdln.option ( ' -m ' , ' --message ' , metavar = ' TEXT ' ,
help = ' specify message TEXT ' )
2022-02-25 12:00:06 +01:00
@cmdln.option ( ' -F ' , ' --file ' , metavar = ' FILE ' ,
help = ' read log message from FILE, \' - \' denotes standard input. ' )
2008-03-13 00:37:35 +01:00
@cmdln.option ( ' -r ' , ' --revision ' , metavar = ' REV ' ,
2010-08-31 18:42:52 +02:00
help = ' specify a certain source revision ID (the md5 sum) for the source package ' )
2017-04-19 15:27:04 +02:00
@cmdln.option ( ' -s ' , ' --supersede ' , metavar = ' REQUEST_ID ' ,
2009-11-17 17:59:17 +01:00
help = ' Superseding another request by this one ' )
2008-06-03 17:01:01 +02:00
@cmdln.option ( ' --nodevelproject ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' do not follow a defined devel project '
2008-06-03 17:01:01 +02:00
' (primary project where a package is developed) ' )
2016-08-16 17:40:34 +02:00
@cmdln.option ( ' --separate-requests ' , action = ' store_true ' ,
help = ' Create multiple requests instead of a single one (when command is used for entire project) ' )
2009-09-05 15:46:55 +02:00
@cmdln.option ( ' --cleanup ' , action = ' store_true ' ,
help = ' remove package if submission gets accepted (default for home:<id>:branch projects) ' )
@cmdln.option ( ' --no-cleanup ' , action = ' store_true ' ,
help = ' never remove source package on accept, but update its content ' )
@cmdln.option ( ' --no-update ' , action = ' store_true ' ,
help = ' never touch source package on accept (will break source links) ' )
2015-03-09 08:44:12 +01:00
@cmdln.option ( ' --update-link ' , action = ' store_true ' ,
help = ' This transfers the source including the _link file. ' )
2009-08-28 09:33:16 +02:00
@cmdln.option ( ' -d ' , ' --diff ' , action = ' store_true ' ,
help = ' show diff only instead of creating the actual request ' )
2009-11-13 09:58:37 +01:00
@cmdln.option ( ' --yes ' , action = ' store_true ' ,
help = ' proceed without asking. ' )
2008-07-09 22:38:49 +02:00
@cmdln.alias ( " sr " )
2009-06-02 16:57:42 +02:00
@cmdln.alias ( " submitreq " )
2009-08-20 21:28:05 +02:00
@cmdln.alias ( " submitpac " )
2009-06-02 16:57:42 +02:00
def do_submitrequest ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Create request to submit source into another Project
2008-03-05 00:41:00 +01:00
2010-07-27 15:20:35 +02:00
[ See http : / / en . opensuse . org / openSUSE : Build_Service_Collaboration for information
2008-06-06 14:04:34 +02:00
on this topic . ]
2019-05-24 13:42:47 +02:00
See the " request " command for showing and modifying existing requests .
2009-06-02 15:14:46 +02:00
2009-06-02 16:57:42 +02:00
usage :
2009-07-13 11:36:19 +02:00
osc submitreq [ OPTIONS ]
osc submitreq [ OPTIONS ] DESTPRJ [ DESTPKG ]
osc submitreq [ OPTIONS ] SOURCEPRJ SOURCEPKG DESTPRJ [ DESTPKG ]
2010-11-26 12:39:09 +01:00
osc submitpac . . . is a shorthand for osc submitreq - - cleanup . . .
2009-06-02 15:14:46 +02:00
"""
2017-01-31 23:35:43 +01:00
def _check_service ( root ) :
serviceinfo = root . find ( ' serviceinfo ' )
if serviceinfo is not None :
# code "running" is ok, because the api will choke when trying
# to create the sr (if it is still running)
if serviceinfo . get ( ' code ' ) not in ( ' running ' , ' succeeded ' ) :
print ( ' A service run for package %s %s : '
% ( root . get ( ' name ' ) , serviceinfo . get ( ' code ' ) ) ,
file = sys . stderr )
error = serviceinfo . find ( ' error ' )
if error is not None :
print ( ' \n ' . join ( error . text . split ( ' \\ n ' ) ) )
sys . exit ( ' \n Please fix this first ' )
2010-11-26 14:53:30 +01:00
if opts . cleanup and opts . no_cleanup :
raise oscerr . WrongOptions ( ' \' --cleanup \' and \' --no-cleanup \' are mutually exclusive ' )
2009-12-19 14:44:51 +01:00
src_update = conf . config [ ' submitrequest_on_accept_action ' ] or None
2009-09-05 15:46:55 +02:00
# we should check here for home:<id>:branch and default to update, but that would require OBS 1.7 server
2010-11-26 12:39:09 +01:00
2010-11-26 14:51:07 +01:00
if subcmd == ' submitpac ' and not opts . no_cleanup :
2013-05-27 12:18:43 +02:00
opts . cleanup = True
2010-11-26 12:39:09 +01:00
2009-09-05 15:46:55 +02:00
if opts . cleanup :
2009-10-20 16:30:15 +02:00
src_update = " cleanup "
2009-09-05 15:46:55 +02:00
elif opts . no_cleanup :
2009-10-20 16:30:15 +02:00
src_update = " update "
2009-09-05 15:46:55 +02:00
elif opts . no_update :
2009-10-20 16:30:15 +02:00
src_update = " noupdate "
2009-09-05 15:46:55 +02:00
2020-06-25 20:46:40 +02:00
if opts . message :
2022-07-07 15:38:14 +02:00
pass
2022-02-25 12:00:06 +01:00
elif opts . file :
if opts . file == ' - ' :
opts . message = sys . stdin . read ( )
else :
try :
opts . message = open ( opts . file ) . read ( )
except :
sys . exit ( ' could not open file \' %s \' . ' % opts . file )
2020-06-25 20:46:40 +02:00
2013-01-31 16:03:16 +01:00
myreqs = [ ]
if opts . supersede :
myreqs = [ opts . supersede ]
2009-06-02 16:57:42 +02:00
args = slash_split ( args )
2009-06-02 15:14:46 +02:00
2009-06-02 16:57:42 +02:00
if len ( args ) > 4 :
2009-06-02 15:14:46 +02:00
raise oscerr . WrongArgs ( ' Too many arguments. ' )
2022-10-07 17:25:33 +02:00
if len ( args ) == 2 and is_project_dir ( Path . cwd ( ) ) :
2013-01-31 16:03:16 +01:00
sys . exit ( ' You can not specify a target package when submitting an entire project \n ' )
2009-11-13 09:58:37 +01:00
2010-04-30 17:13:21 +02:00
apiurl = self . get_api_url ( )
2009-11-16 10:42:58 +01:00
2022-10-07 17:25:33 +02:00
if len ( args ) < 2 and is_project_dir ( Path . cwd ( ) ) :
2013-05-02 22:18:14 +02:00
if opts . diff :
raise oscerr . WrongOptions ( ' \' --diff \' is not supported in a project working copy ' )
2022-10-07 17:25:33 +02:00
project = store_read_project ( Path . cwd ( ) )
2009-11-13 09:58:37 +01:00
sr_ids = [ ]
2019-08-02 13:49:38 +02:00
target_project = None
if len ( args ) == 1 :
2022-05-10 14:49:21 +02:00
target_project = self . _process_project_name ( args [ 0 ] )
2022-08-25 09:57:16 +02:00
if opts . separate_requests :
2019-08-02 13:49:38 +02:00
for p in meta_get_packagelist ( apiurl , project ) :
# get _link info from server, that knows about the local state ...
u = makeurl ( apiurl , [ ' source ' , project , p ] )
f = http_GET ( u )
root = ET . parse ( f ) . getroot ( )
_check_service ( root )
linkinfo = root . find ( ' linkinfo ' )
2022-08-29 12:56:57 +02:00
if linkinfo is None :
2019-08-02 13:49:38 +02:00
if len ( args ) < 1 :
print ( " Package " , p , " is not a source link and no target specified. " )
sys . exit ( " This is currently not supported. " )
else :
if linkinfo . get ( ' error ' ) :
print ( " Package " , p , " is a broken source link. " )
sys . exit ( " Please fix this first " )
t = linkinfo . get ( ' project ' )
if t is None :
2022-04-20 19:22:35 +02:00
print ( " Skipping package " , p , " since it is a source link pointing inside the project. " )
2020-08-27 16:56:36 +02:00
continue
2019-08-02 13:49:38 +02:00
print ( " Submitting package " , p )
try :
result = create_submit_request ( apiurl , project , p , target_project , src_update = src_update )
except HTTPError as e :
if e . hdrs . get ( ' X-Opensuse-Errorcode ' ) == ' missing_action ' :
print ( " Package " , p , " no changes. Skipping... " )
continue
raise
2013-01-31 16:03:16 +01:00
if not result :
sys . exit ( " submit request creation failed " )
sr_ids . append ( result )
2019-08-02 13:49:38 +02:00
else :
actionxml = " "
options_block = " <options> "
if src_update :
options_block + = """ <sourceupdate> %s </sourceupdate> """ % ( src_update )
if opts . update_link :
2022-04-20 19:22:35 +02:00
options_block + """ <updatelink>true</updatelink></options> """
2019-08-02 13:49:38 +02:00
options_block + = " </options> "
target_prj_block = " "
if target_project is not None :
target_prj_block = """ <target project= " %s " /> """ % target_project
2022-04-20 19:22:35 +02:00
s = """ <action type= " submit " > <source project= " %s " /> %s %s </action> """ % \
2022-09-12 13:43:10 +02:00
( project , target_prj_block , options_block )
2019-08-02 13:49:38 +02:00
actionxml + = s
2009-11-13 09:58:37 +01:00
xml = """ <request> %s <state name= " new " /> <description> %s </description> </request> """ % \
2022-09-12 13:43:10 +02:00
( actionxml , _html_escape ( opts . message or " " ) )
2013-02-25 15:22:00 +01:00
u = makeurl ( apiurl , [ ' request ' ] , query = ' cmd=create&addrevision=1 ' )
2009-11-13 09:58:37 +01:00
f = http_POST ( u , data = xml )
2010-02-28 02:30:13 +01:00
2009-11-13 09:58:37 +01:00
root = ET . parse ( f ) . getroot ( )
sr_ids . append ( root . get ( ' id ' ) )
2019-08-02 13:49:38 +02:00
print ( " Request(s) created: " , end = ' ' )
2009-11-13 09:58:37 +01:00
for i in sr_ids :
2013-04-09 12:51:28 +02:00
print ( i , end = ' ' )
2010-08-05 17:00:45 +02:00
2013-01-31 16:03:16 +01:00
# was this project created by clone request ?
u = makeurl ( apiurl , [ ' source ' , project , ' _attribute ' , ' OBS:RequestCloned ' ] )
f = http_GET ( u )
root = ET . parse ( f ) . getroot ( )
value = root . findtext ( ' attribute/value ' )
2013-11-15 11:39:21 +01:00
if value and not opts . yes :
2013-01-31 16:03:16 +01:00
repl = ' '
2022-09-12 13:43:10 +02:00
print ( ' \n \n There are already following submit request: %s . ' %
' , ' . join ( [ str ( i ) for i in myreqs ] ) )
2010-08-05 17:00:45 +02:00
repl = raw_input ( ' \n Supersede the old requests? (y/n) ' )
if repl . lower ( ) == ' y ' :
2022-09-12 13:43:10 +02:00
myreqs + = [ value ]
2013-01-31 16:03:16 +01:00
if len ( myreqs ) > 0 :
for req in myreqs :
2013-05-27 12:16:44 +02:00
change_request_state ( apiurl , str ( req ) , ' superseded ' ,
2022-09-12 13:43:10 +02:00
' superseded by %s ' % sr_ids [ 0 ] , sr_ids [ 0 ] )
2010-08-05 17:00:45 +02:00
2010-06-26 20:54:02 +02:00
sys . exit ( ' Successfully finished ' )
2009-11-13 09:58:37 +01:00
elif len ( args ) < = 2 :
2009-06-02 16:57:42 +02:00
# try using the working copy at hand
2022-10-07 17:25:33 +02:00
p = Package ( Path . cwd ( ) )
2009-06-02 16:57:42 +02:00
src_project = p . prjname
src_package = p . name
2022-10-05 11:55:17 +02:00
if p . apiurl != apiurl :
2018-09-25 13:48:09 +02:00
print ( ' The apiurl for the working copy of this package is %s ' % p . apiurl )
print ( ' You cannot use this command with the -A %s option. ' % self . options . apiurl )
sys . exit ( 1 )
2009-12-15 17:38:09 +01:00
apiurl = p . apiurl
2009-06-02 16:57:42 +02:00
if len ( args ) == 0 and p . islink ( ) :
dst_project = p . linkinfo . project
dst_package = p . linkinfo . package
elif len ( args ) > 0 :
2022-05-10 14:49:21 +02:00
dst_project = self . _process_project_name ( args [ 0 ] )
2009-06-02 16:57:42 +02:00
if len ( args ) == 2 :
dst_package = args [ 1 ]
2009-06-02 15:14:46 +02:00
else :
2012-02-07 11:03:21 +01:00
if p . islink ( ) :
dst_package = p . linkinfo . package
else :
dst_package = src_package
2009-06-02 15:14:46 +02:00
else :
2009-06-02 16:57:42 +02:00
sys . exit ( ' Package \' %s \' is not a source link, so I cannot guess the submit target. \n '
' Please provide it the target via commandline arguments. ' % p . name )
2010-09-21 11:19:27 +02:00
modified = [ i for i in p . filenamelist if not p . status ( i ) in ( ' ' , ' ? ' , ' S ' ) ]
2014-03-12 10:50:46 +01:00
if len ( modified ) > 0 and not opts . yes :
2013-04-09 12:51:28 +02:00
print ( ' Your working copy has local modifications. ' )
2009-06-02 16:57:42 +02:00
repl = raw_input ( ' Proceed without committing the local changes? (y|N) ' )
if repl != ' y ' :
2010-04-20 15:22:03 +02:00
raise oscerr . UserAbort ( )
2009-06-02 16:57:42 +02:00
elif len ( args ) > = 3 :
# get the arguments from the commandline
src_project , src_package , dst_project = args [ 0 : 3 ]
if len ( args ) == 4 :
dst_package = args [ 3 ]
else :
dst_package = src_package
2022-10-18 23:38:28 +02:00
src_project = self . _process_project_name ( src_project )
2022-05-10 14:49:21 +02:00
dst_project = self . _process_project_name ( dst_project )
2009-06-02 16:57:42 +02:00
else :
2022-01-19 15:13:55 +01:00
self . argparse_error ( " Incorrect number of arguments. " )
2009-06-02 16:57:42 +02:00
2017-01-31 23:35:43 +01:00
# check for failed source service
2011-05-02 15:28:44 +02:00
u = makeurl ( apiurl , [ ' source ' , src_project , src_package ] )
f = http_GET ( u )
root = ET . parse ( f ) . getroot ( )
2017-01-31 23:35:43 +01:00
_check_service ( root )
2011-05-02 15:28:44 +02:00
2009-06-02 16:57:42 +02:00
if not opts . nodevelproject :
devloc = None
try :
2013-10-07 13:12:58 +02:00
devloc , _ = show_devel_project ( apiurl , dst_project , dst_package )
2013-04-09 14:03:17 +02:00
except HTTPError :
2013-04-09 12:51:28 +02:00
print ( """ \
2022-09-12 13:43:10 +02:00
Warning : failed to fetch meta data for ' %s ' package ' %s ' ( new package ? ) """
% ( dst_project , dst_package ) , file = sys . stderr )
2009-06-02 15:14:46 +02:00
2009-10-20 16:30:15 +02:00
if devloc and \
dst_project != devloc and \
src_project != devloc :
2013-04-09 12:51:28 +02:00
print ( """ \
2010-02-02 14:38:50 +01:00
A different project , % s , is defined as the place where development
2009-06-02 15:14:46 +02:00
of the package % s primarily takes place .
2022-09-12 13:43:10 +02:00
Please submit there instead , or use - - nodevelproject to force direct submission . """
% ( devloc , dst_package ) )
2010-02-02 14:38:50 +01:00
if not opts . diff :
sys . exit ( 1 )
2010-02-02 14:38:35 +01:00
2013-05-27 12:41:50 +02:00
rev = opts . revision
2011-05-19 17:10:08 +02:00
if not rev :
# get _link info from server, that knows about the local state ...
2012-02-24 11:49:18 +01:00
u = makeurl ( apiurl , [ ' source ' , src_project , src_package ] , query = " expand=1 " )
2011-05-19 17:10:08 +02:00
f = http_GET ( u )
root = ET . parse ( f ) . getroot ( )
linkinfo = root . find ( ' linkinfo ' )
2022-08-29 12:56:57 +02:00
if linkinfo is None :
2013-05-27 12:41:50 +02:00
rev = root . get ( ' rev ' )
2012-02-24 11:49:18 +01:00
else :
2011-05-19 17:10:08 +02:00
if linkinfo . get ( ' project ' ) != dst_project or linkinfo . get ( ' package ' ) != dst_package :
2014-08-12 15:01:16 +02:00
# the submit target is not link target. use merged md5sum references to
2013-05-27 12:16:44 +02:00
# avoid not mergable sources when multiple request from same source get created.
2013-05-27 12:41:50 +02:00
rev = root . get ( ' srcmd5 ' )
2011-05-19 17:10:08 +02:00
2010-02-02 14:38:35 +01:00
rdiff = None
if opts . diff or not opts . message :
try :
2019-07-17 10:34:20 +02:00
rdiff = b ' old: %s / %s \n new: %s / %s rev %s \n ' % ( dst_project . encode ( ) , dst_package . encode ( ) , src_project . encode ( ) , src_package . encode ( ) , str ( rev ) . encode ( ) )
rdiff + = server_diff ( apiurl ,
2022-09-12 13:43:10 +02:00
dst_project , dst_package , None ,
src_project , src_package , rev , True )
2010-02-02 14:38:35 +01:00
except :
2019-07-17 10:34:20 +02:00
rdiff = b ' '
2010-08-05 17:00:45 +02:00
2009-08-28 09:33:16 +02:00
if opts . diff :
2023-07-11 21:02:21 +02:00
run_pager ( highlight_diff ( rdiff ) )
2010-08-13 08:55:18 +02:00
return
2019-07-17 10:34:20 +02:00
if rdiff is not None :
rdiff = decode_it ( rdiff )
2013-03-08 19:06:04 +01:00
supersede_existing = False
reqs = [ ]
2017-10-06 12:32:52 +02:00
if not opts . supersede :
2013-03-08 19:06:04 +01:00
( supersede_existing , reqs ) = check_existing_requests ( apiurl ,
src_project ,
src_package ,
dst_project ,
2017-10-06 12:32:52 +02:00
dst_package ,
not opts . yes )
2015-08-07 10:17:40 +02:00
if not supersede_existing :
2022-08-29 13:39:20 +02:00
( supersede_existing , reqs ) = check_existing_maintenance_requests ( apiurl ,
2022-09-12 13:43:10 +02:00
src_project ,
[ src_package ] ,
dst_project , None ,
not opts . yes )
2010-08-05 17:00:45 +02:00
if not opts . message :
difflines = [ ]
doappend = False
changes_re = re . compile ( r ' ^--- .* \ .changes ' )
for line in rdiff . split ( ' \n ' ) :
if line . startswith ( ' --- ' ) :
if changes_re . match ( line ) :
doappend = True
else :
doappend = False
if doappend :
difflines . append ( line )
opts . message = edit_message ( footer = rdiff , template = ' \n ' . join ( parse_diff_for_commit_message ( ' \n ' . join ( difflines ) ) ) )
result = create_submit_request ( apiurl ,
src_project , src_package ,
dst_project , dst_package ,
2015-03-09 08:44:12 +01:00
opts . message , orev = rev ,
2022-09-12 13:43:10 +02:00
src_update = src_update , dst_updatelink = opts . update_link )
2020-01-23 13:48:20 +01:00
2016-02-15 15:32:26 +01:00
print ( ' created request id ' , result )
2020-01-23 13:48:20 +01:00
if conf . config [ ' print_web_links ' ] :
2023-01-20 13:19:04 +01:00
obs_url = _private . get_configuration_value ( apiurl , " obs_url " )
2023-01-03 16:44:32 +01:00
print ( f " { obs_url } /request/show/ { result } " )
2016-02-15 15:32:26 +01:00
2013-03-08 19:06:04 +01:00
if supersede_existing :
for req in reqs :
2010-12-30 13:28:11 +01:00
change_request_state ( apiurl , req . reqid , ' superseded ' ,
2010-08-05 17:00:45 +02:00
' superseded by %s ' % result , result )
if opts . supersede :
2011-02-08 16:16:18 +01:00
change_request_state ( apiurl , opts . supersede , ' superseded ' ,
2010-08-05 17:00:45 +02:00
opts . message or ' ' , result )
2010-05-24 13:28:44 +02:00
def _submit_request ( self , args , opts , options_block ) :
2013-05-27 12:41:50 +02:00
actionxml = " "
2010-05-24 13:28:44 +02:00
apiurl = self . get_api_url ( )
2022-10-07 17:25:33 +02:00
if len ( args ) == 0 and is_project_dir ( Path . cwd ( ) ) :
2010-05-24 13:28:44 +02:00
# submit requests for multiple packages are currently handled via multiple requests
# They could be also one request with multiple actions, but that avoids to accepts parts of it.
2022-10-07 17:25:33 +02:00
project = store_read_project ( Path . cwd ( ) )
2010-05-24 13:28:44 +02:00
pi = [ ]
pac = [ ]
targetprojects = [ ]
# loop via all packages for checking their state
for p in meta_get_packagelist ( apiurl , project ) :
if p . startswith ( " _patchinfo: " ) :
pi . append ( p )
else :
# get _link info from server, that knows about the local state ...
u = makeurl ( apiurl , [ ' source ' , project , p ] )
f = http_GET ( u )
root = ET . parse ( f ) . getroot ( )
linkinfo = root . find ( ' linkinfo ' )
2022-08-29 12:56:57 +02:00
if linkinfo is None :
2013-04-09 12:51:28 +02:00
print ( " Package " , p , " is not a source link. " )
2010-05-24 13:28:44 +02:00
sys . exit ( " This is currently not supported. " )
if linkinfo . get ( ' error ' ) :
2013-04-09 12:51:28 +02:00
print ( " Package " , p , " is a broken source link. " )
2010-05-24 13:28:44 +02:00
sys . exit ( " Please fix this first " )
t = linkinfo . get ( ' project ' )
if t :
2019-07-17 10:34:20 +02:00
rdiff = b ' '
2010-05-24 13:28:44 +02:00
try :
rdiff = server_diff ( apiurl , t , p , opts . revision , project , p , None , True )
except :
2019-07-17 10:34:20 +02:00
rdiff = b ' '
2010-05-24 13:28:44 +02:00
2019-07-17 10:34:20 +02:00
if rdiff != b ' ' :
2010-05-24 13:28:44 +02:00
targetprojects . append ( t )
pac . append ( p )
else :
2022-09-12 13:43:10 +02:00
print ( " Skipping package " , p , " since it has no difference with the target package. " )
2010-05-24 13:28:44 +02:00
else :
2022-09-12 13:43:10 +02:00
print ( " Skipping package " , p , " since it is a source link pointing inside the project. " )
2010-05-24 13:28:44 +02:00
# loop via all packages to do the action
for p in pac :
2022-09-12 13:43:10 +02:00
s = """ <action type= " submit " > <source project= " %s " package= " %s " rev= " %s " /> <target project= " %s " package= " %s " /> %s </action> """ % \
( project , p , opts . revision or show_upstream_rev ( apiurl , project , p ) , t , p , options_block )
2010-05-24 13:28:44 +02:00
actionxml + = s
# create submit requests for all found patchinfos
for p in pi :
for t in targetprojects :
2022-09-12 13:43:10 +02:00
s = """ <action type= " submit " > <source project= " %s " package= " %s " /> <target project= " %s " package= " %s " /> %s </action> """ % \
( project , p , t , p , options_block )
2010-05-24 13:28:44 +02:00
actionxml + = s
2014-09-23 13:05:10 +02:00
return actionxml , [ ]
2010-05-24 13:28:44 +02:00
elif len ( args ) < = 2 :
# try using the working copy at hand
2022-10-07 17:25:33 +02:00
p = Package ( Path . cwd ( ) )
2010-05-24 13:28:44 +02:00
src_project = p . prjname
src_package = p . name
if len ( args ) == 0 and p . islink ( ) :
dst_project = p . linkinfo . project
dst_package = p . linkinfo . package
elif len ( args ) > 0 :
2022-05-10 14:49:21 +02:00
dst_project = self . _process_project_name ( args [ 0 ] )
2010-05-24 13:28:44 +02:00
if len ( args ) == 2 :
dst_package = args [ 1 ]
else :
dst_package = src_package
else :
sys . exit ( ' Package \' %s \' is not a source link, so I cannot guess the submit target. \n '
' Please provide it the target via commandline arguments. ' % p . name )
modified = [ i for i in p . filenamelist if p . status ( i ) != ' ' and p . status ( i ) != ' ? ' ]
if len ( modified ) > 0 :
2013-04-09 12:51:28 +02:00
print ( ' Your working copy has local modifications. ' )
2010-05-24 13:28:44 +02:00
repl = raw_input ( ' Proceed without committing the local changes? (y|N) ' )
if repl != ' y ' :
sys . exit ( 1 )
elif len ( args ) > = 3 :
# get the arguments from the commandline
src_project , src_package , dst_project = args [ 0 : 3 ]
if len ( args ) == 4 :
dst_package = args [ 3 ]
else :
dst_package = src_package
2022-10-18 23:38:28 +02:00
src_project = self . _process_project_name ( src_project )
2022-05-10 14:49:21 +02:00
dst_project = self . _process_project_name ( dst_project )
2010-05-24 13:28:44 +02:00
else :
2022-01-19 15:13:55 +01:00
self . argparse_error ( " Incorrect number of arguments. " )
2010-05-24 13:28:44 +02:00
if not opts . nodevelproject :
devloc = None
try :
2013-10-07 13:12:58 +02:00
devloc , _ = show_devel_project ( apiurl , dst_project , dst_package )
2013-04-09 14:03:17 +02:00
except HTTPError :
2013-04-09 12:51:28 +02:00
print ( """ \
2022-09-12 13:43:10 +02:00
Warning : failed to fetch meta data for ' %s ' package ' %s ' ( new package ? ) """
% ( dst_project , dst_package ) , file = sys . stderr )
2010-05-24 13:28:44 +02:00
if devloc and \
dst_project != devloc and \
src_project != devloc :
2013-04-09 12:51:28 +02:00
print ( """ \
2010-05-24 13:28:44 +02:00
A different project , % s , is defined as the place where development
of the package % s primarily takes place .
2022-09-12 13:43:10 +02:00
Please submit there instead , or use - - nodevelproject to force direct submission . """
% ( devloc , dst_package ) )
2014-09-23 12:45:44 +02:00
sys . exit ( 1 )
2010-05-24 13:28:44 +02:00
2022-09-15 14:47:38 +02:00
reqs = get_request_collection ( apiurl , project = dst_project , package = dst_package , types = [ ' submit ' ] , states = [ ' new ' , ' review ' ] )
2014-09-23 12:45:44 +02:00
user = conf . get_apiurl_usr ( apiurl )
2022-09-12 13:43:10 +02:00
myreqs = [ i for i in reqs if i . state . who == user and i . reqid != opts . supersede ]
Do not return Request instances in Osc._submit_request
If there are existing requests that should be superseded, the old
code stores the Request instances in the myreqs list, which is
returned to the caller. However, the caller expects only request
ids instead of instances of class Request. Eventually, this results
in a type error - excerpt:
...
File "/usr/lib/python3.8/site-packages/osc/commandline.py", line 1892, in do_createrequest
change_request_state(apiurl, srid, 'superseded',
File "/usr/lib/python3.8/site-packages/osc/core.py", line 4322, in change_request_state
u = makeurl(apiurl,
File "/usr/lib/python3.8/site-packages/osc/core.py", line 3326, in makeurl
return urlunsplit((scheme, netloc, '/'.join([path] + list(l)), query, ''))
TypeError: sequence item 2: expected str instance, Request found
Hence, simply return the request ids instead of the Request instances.
Note: this changes the API of the Osc._submit_request method but
this is OK because it is not part of the public API.
2020-12-09 20:54:52 +01:00
myreq_ids = [ r . reqid for r in myreqs ]
2014-09-23 12:45:44 +02:00
repl = ' y '
if len ( myreqs ) > 0 and not opts . yes :
2022-09-12 13:43:10 +02:00
print ( ' You already created the following submit request: %s . ' %
Do not return Request instances in Osc._submit_request
If there are existing requests that should be superseded, the old
code stores the Request instances in the myreqs list, which is
returned to the caller. However, the caller expects only request
ids instead of instances of class Request. Eventually, this results
in a type error - excerpt:
...
File "/usr/lib/python3.8/site-packages/osc/commandline.py", line 1892, in do_createrequest
change_request_state(apiurl, srid, 'superseded',
File "/usr/lib/python3.8/site-packages/osc/core.py", line 4322, in change_request_state
u = makeurl(apiurl,
File "/usr/lib/python3.8/site-packages/osc/core.py", line 3326, in makeurl
return urlunsplit((scheme, netloc, '/'.join([path] + list(l)), query, ''))
TypeError: sequence item 2: expected str instance, Request found
Hence, simply return the request ids instead of the Request instances.
Note: this changes the API of the Osc._submit_request method but
this is OK because it is not part of the public API.
2020-12-09 20:54:52 +01:00
' , ' . join ( myreq_ids ) )
2014-09-23 12:45:44 +02:00
repl = raw_input ( ' Supersede the old requests? (y/n/c) ' )
if repl . lower ( ) == ' c ' :
print ( ' Aborting ' , file = sys . stderr )
sys . exit ( 1 )
2014-09-23 13:05:10 +02:00
elif repl . lower ( ) != ' y ' :
myreqs = [ ]
2010-05-24 13:28:44 +02:00
2022-09-12 13:43:10 +02:00
actionxml = """ <action type= " submit " > <source project= " %s " package= " %s " rev= " %s " /> <target project= " %s " package= " %s " /> %s </action> """ % \
( src_project , src_package , opts . revision or show_upstream_rev ( apiurl , src_project , src_package ) , dst_project , dst_package , options_block )
2014-09-23 12:45:44 +02:00
if opts . supersede :
Do not return Request instances in Osc._submit_request
If there are existing requests that should be superseded, the old
code stores the Request instances in the myreqs list, which is
returned to the caller. However, the caller expects only request
ids instead of instances of class Request. Eventually, this results
in a type error - excerpt:
...
File "/usr/lib/python3.8/site-packages/osc/commandline.py", line 1892, in do_createrequest
change_request_state(apiurl, srid, 'superseded',
File "/usr/lib/python3.8/site-packages/osc/core.py", line 4322, in change_request_state
u = makeurl(apiurl,
File "/usr/lib/python3.8/site-packages/osc/core.py", line 3326, in makeurl
return urlunsplit((scheme, netloc, '/'.join([path] + list(l)), query, ''))
TypeError: sequence item 2: expected str instance, Request found
Hence, simply return the request ids instead of the Request instances.
Note: this changes the API of the Osc._submit_request method but
this is OK because it is not part of the public API.
2020-12-09 20:54:52 +01:00
myreq_ids . append ( opts . supersede )
2010-05-24 13:28:44 +02:00
2022-09-12 13:43:10 +02:00
# print 'created request id', result
Do not return Request instances in Osc._submit_request
If there are existing requests that should be superseded, the old
code stores the Request instances in the myreqs list, which is
returned to the caller. However, the caller expects only request
ids instead of instances of class Request. Eventually, this results
in a type error - excerpt:
...
File "/usr/lib/python3.8/site-packages/osc/commandline.py", line 1892, in do_createrequest
change_request_state(apiurl, srid, 'superseded',
File "/usr/lib/python3.8/site-packages/osc/core.py", line 4322, in change_request_state
u = makeurl(apiurl,
File "/usr/lib/python3.8/site-packages/osc/core.py", line 3326, in makeurl
return urlunsplit((scheme, netloc, '/'.join([path] + list(l)), query, ''))
TypeError: sequence item 2: expected str instance, Request found
Hence, simply return the request ids instead of the Request instances.
Note: this changes the API of the Osc._submit_request method but
this is OK because it is not part of the public API.
2020-12-09 20:54:52 +01:00
return actionxml , myreq_ids
2010-05-24 13:28:44 +02:00
def _delete_request ( self , args , opts ) :
if len ( args ) < 1 :
raise oscerr . WrongArgs ( ' Please specify at least a project. ' )
if len ( args ) > 2 :
raise oscerr . WrongArgs ( ' Too many arguments. ' )
package = " "
if len ( args ) > 1 :
package = """ package= " %s " """ % ( args [ 1 ] )
actionxml = """ <action type= " delete " > <target project= " %s " %s /> </action> """ % ( args [ 0 ] , package )
return actionxml
def _changedevel_request ( self , args , opts ) :
if len ( args ) > 4 :
raise oscerr . WrongArgs ( ' Too many arguments. ' )
2011-03-09 16:10:48 +01:00
if len ( args ) == 0 and is_package_dir ( ' . ' ) and find_default_project ( ) :
2022-10-07 17:25:33 +02:00
wd = Path . cwd ( )
2010-05-24 13:28:44 +02:00
devel_project = store_read_project ( wd )
devel_package = package = store_read_package ( wd )
2011-03-09 16:10:48 +01:00
project = find_default_project ( self . get_api_url ( ) , package )
2010-05-24 13:28:44 +02:00
else :
if len ( args ) < 3 :
raise oscerr . WrongArgs ( ' Too few arguments. ' )
2022-05-10 14:49:21 +02:00
devel_project = self . _process_project_name ( args [ 2 ] )
project = self . _process_project_name ( args [ 0 ] )
2010-05-24 13:28:44 +02:00
package = args [ 1 ]
devel_package = package
if len ( args ) > 3 :
2022-05-10 14:49:21 +02:00
devel_package = self . _process_project_name ( args [ 3 ] )
2010-05-24 13:28:44 +02:00
actionxml = """ <action type= " change_devel " > <source project= " %s " package= " %s " /> <target project= " %s " package= " %s " /> </action> """ % \
2022-09-12 13:43:10 +02:00
( devel_project , devel_package , project , package )
2010-05-24 13:28:44 +02:00
return actionxml
2011-01-10 13:12:09 +01:00
def _add_me ( self , args , opts ) :
if len ( args ) > 3 :
raise oscerr . WrongArgs ( ' Too many arguments. ' )
if len ( args ) < 2 :
raise oscerr . WrongArgs ( ' Too few arguments. ' )
apiurl = self . get_api_url ( )
user = conf . get_apiurl_usr ( apiurl )
2011-01-12 11:29:46 +01:00
role = args [ 0 ]
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 1 ] )
2011-01-10 13:12:09 +01:00
actionxml = """ <action type= " add_role " > <target project= " %s " /> <person name= " %s " role= " %s " /> </action> """ % \
2022-09-12 13:43:10 +02:00
( project , user , role )
2011-01-10 13:12:09 +01:00
if len ( args ) > 2 :
package = args [ 2 ]
actionxml = """ <action type= " add_role " > <target project= " %s " package= " %s " /> <person name= " %s " role= " %s " /> </action> """ % \
( project , package , user , role )
2022-08-29 12:56:57 +02:00
if get_user_meta ( apiurl , user ) is None :
2019-05-24 13:42:47 +02:00
raise oscerr . WrongArgs ( ' osc: an error occurred. ' )
2011-01-10 13:12:09 +01:00
return actionxml
2011-01-11 20:02:48 +01:00
def _add_user ( self , args , opts ) :
2010-05-24 13:28:44 +02:00
if len ( args ) > 4 :
raise oscerr . WrongArgs ( ' Too many arguments. ' )
if len ( args ) < 3 :
raise oscerr . WrongArgs ( ' Too few arguments. ' )
apiurl = self . get_api_url ( )
user = args [ 0 ]
role = args [ 1 ]
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 2 ] )
2010-09-09 22:07:50 +02:00
actionxml = """ <action type= " add_role " > <target project= " %s " /> <person name= " %s " role= " %s " /> </action> """ % \
2022-09-12 13:43:10 +02:00
( project , user , role )
2010-09-09 22:07:50 +02:00
2010-05-24 13:28:44 +02:00
if len ( args ) > 3 :
package = args [ 3 ]
2010-09-09 22:07:50 +02:00
actionxml = """ <action type= " add_role " > <target project= " %s " package= " %s " /> <person name= " %s " role= " %s " /> </action> """ % \
( project , package , user , role )
2010-05-24 13:28:44 +02:00
2022-08-29 12:56:57 +02:00
if get_user_meta ( apiurl , user ) is None :
2010-05-24 13:28:44 +02:00
raise oscerr . WrongArgs ( ' osc: an error occured. ' )
return actionxml
2011-01-11 20:02:48 +01:00
def _add_group ( self , args , opts ) :
if len ( args ) > 4 :
raise oscerr . WrongArgs ( ' Too many arguments. ' )
if len ( args ) < 3 :
raise oscerr . WrongArgs ( ' Too few arguments. ' )
apiurl = self . get_api_url ( )
group = args [ 0 ]
role = args [ 1 ]
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 2 ] )
2011-01-11 20:02:48 +01:00
actionxml = """ <action type= " add_role " > <target project= " %s " /> <group name= " %s " role= " %s " /> </action> """ % \
2022-09-12 13:43:10 +02:00
( project , group , role )
2011-01-11 20:02:48 +01:00
if len ( args ) > 3 :
package = args [ 3 ]
actionxml = """ <action type= " add_role " > <target project= " %s " package= " %s " /> <group name= " %s " role= " %s " /> </action> """ % \
( project , package , group , role )
2022-08-29 12:56:57 +02:00
if get_group_meta ( apiurl , group ) is None :
2011-01-11 20:02:48 +01:00
raise oscerr . WrongArgs ( ' osc: an error occured. ' )
return actionxml
2010-05-24 13:28:44 +02:00
def _set_bugowner ( self , args , opts ) :
if len ( args ) > 3 :
raise oscerr . WrongArgs ( ' Too many arguments. ' )
if len ( args ) < 2 :
raise oscerr . WrongArgs ( ' Too few arguments. ' )
apiurl = self . get_api_url ( )
user = args [ 0 ]
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 1 ] )
2012-11-23 12:52:05 +01:00
package = " "
2010-05-24 13:28:44 +02:00
if len ( args ) > 2 :
2022-04-20 19:22:35 +02:00
package = """ package= " %s " """ % ( args [ 2 ] )
2010-05-24 13:28:44 +02:00
2014-01-24 17:01:35 +01:00
if user . startswith ( ' group: ' ) :
2014-08-13 11:21:55 +02:00
group = user . replace ( ' group: ' , ' ' )
2014-01-24 17:01:35 +01:00
actionxml = """ <action type= " set_bugowner " > <target project= " %s " %s /> <group name= " %s " /> </action> """ % \
2022-09-12 13:43:10 +02:00
( project , package , group )
2022-08-29 12:56:57 +02:00
if get_group_meta ( apiurl , group ) is None :
2019-05-24 13:42:47 +02:00
raise oscerr . WrongArgs ( ' osc: an error occurred. ' )
2014-01-24 17:01:35 +01:00
else :
actionxml = """ <action type= " set_bugowner " > <target project= " %s " %s /> <person name= " %s " /> </action> """ % \
2022-09-12 13:43:10 +02:00
( project , package , user )
2022-08-29 12:56:57 +02:00
if get_user_meta ( apiurl , user ) is None :
2014-01-24 17:01:35 +01:00
raise oscerr . WrongArgs ( ' osc: an error occured. ' )
2010-05-24 13:28:44 +02:00
return actionxml
2023-04-03 12:03:19 +02:00
@cmdln.option ( ' -a ' , ' --action ' , action = ' append ' , nargs = ' + ' , metavar = ( ' ACTION ' , ' [ARGS] ' ) , dest = ' actions ' , default = [ ] ,
help = ' specify action type of a request, can be : submit/delete/change_devel/add_role/set_bugowner ' )
2010-05-24 13:28:44 +02:00
@cmdln.option ( ' -m ' , ' --message ' , metavar = ' TEXT ' ,
help = ' specify message TEXT ' )
@cmdln.option ( ' -r ' , ' --revision ' , metavar = ' REV ' ,
help = ' for " create " , specify a certain source revision ID (the md5 sum) ' )
2017-04-19 15:27:04 +02:00
@cmdln.option ( ' -s ' , ' --supersede ' , metavar = ' REQUEST_ID ' ,
2010-05-24 13:28:44 +02:00
help = ' Superseding another request by this one ' )
@cmdln.option ( ' --nodevelproject ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' do not follow a defined devel project '
2010-05-24 13:28:44 +02:00
' (primary project where a package is developed) ' )
@cmdln.option ( ' --cleanup ' , action = ' store_true ' ,
help = ' remove package if submission gets accepted (default for home:<id>:branch projects) ' )
@cmdln.option ( ' --no-cleanup ' , action = ' store_true ' ,
help = ' never remove source package on accept, but update its content ' )
@cmdln.option ( ' --no-update ' , action = ' store_true ' ,
help = ' never touch source package on accept (will break source links) ' )
@cmdln.option ( ' --yes ' , action = ' store_true ' ,
help = ' proceed without asking. ' )
@cmdln.alias ( " creq " )
def do_createrequest ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Create multiple requests with a single command
2010-05-24 13:28:44 +02:00
usage :
2014-08-12 15:01:16 +02:00
osc creq [ OPTIONS ] [
- a submit SOURCEPRJ SOURCEPKG DESTPRJ [ DESTPKG ]
- a delete PROJECT [ PACKAGE ]
- a change_devel PROJECT PACKAGE DEVEL_PROJECT [ DEVEL_PACKAGE ]
2011-01-10 13:12:09 +01:00
- a add_me ROLE PROJECT [ PACKAGE ]
2011-01-11 20:02:48 +01:00
- a add_group GROUP ROLE PROJECT [ PACKAGE ]
2010-05-24 13:28:44 +02:00
- a add_role USER ROLE PROJECT [ PACKAGE ]
- a set_bugowner USER PROJECT [ PACKAGE ]
]
Option - m works for all types of request , the rest work only for submit .
2022-01-19 15:13:55 +01:00
Example :
2010-05-24 13:28:44 +02:00
osc creq - a submit - a delete home : someone : branches : openSUSE : Tools - a change_devel openSUSE : Tools osc home : someone : branches : openSUSE : Tools - m ok
This will submit all modified packages under current directory , delete project home : someone : branches : openSUSE : Tools and change the devel project to home : someone : branches : openSUSE : Tools for package osc in project openSUSE : Tools .
"""
src_update = conf . config [ ' submitrequest_on_accept_action ' ] or None
# we should check here for home:<id>:branch and default to update, but that would require OBS 1.7 server
if opts . cleanup :
src_update = " cleanup "
elif opts . no_cleanup :
src_update = " update "
elif opts . no_update :
src_update = " noupdate "
2013-05-27 12:41:50 +02:00
options_block = " "
2010-05-24 13:28:44 +02:00
if src_update :
2013-05-27 12:41:50 +02:00
options_block = """ <options><sourceupdate> %s </sourceupdate></options> """ % ( src_update )
2010-05-24 13:28:44 +02:00
args = slash_split ( args )
apiurl = self . get_api_url ( )
2016-05-15 17:50:31 +02:00
2010-05-24 13:28:44 +02:00
actionsxml = " "
2020-12-09 21:41:37 +01:00
supersede = set ( )
2023-04-03 12:03:19 +02:00
for actiondata in opts . actions :
action = actiondata [ 0 ]
args = actiondata [ 1 : ]
if action == ' submit ' :
2014-09-23 13:05:10 +02:00
actions , to_supersede = self . _submit_request ( args , opts , options_block )
actionsxml + = actions
2020-12-09 21:41:37 +01:00
supersede . update ( to_supersede )
2023-04-03 12:03:19 +02:00
elif action == ' delete ' :
2013-05-27 12:41:50 +02:00
actionsxml + = self . _delete_request ( args , opts )
2023-04-03 12:03:19 +02:00
elif action == ' change_devel ' :
2013-05-27 12:41:50 +02:00
actionsxml + = self . _changedevel_request ( args , opts )
2023-04-03 12:03:19 +02:00
elif action == ' add_me ' :
2013-05-27 12:41:50 +02:00
actionsxml + = self . _add_me ( args , opts )
2023-04-03 12:03:19 +02:00
elif action == ' add_group ' :
2013-05-27 12:41:50 +02:00
actionsxml + = self . _add_group ( args , opts )
2023-04-03 12:03:19 +02:00
elif action == ' add_role ' :
2013-05-27 12:41:50 +02:00
actionsxml + = self . _add_user ( args , opts )
2023-04-03 12:03:19 +02:00
elif action == ' set_bugowner ' :
2013-05-27 12:41:50 +02:00
actionsxml + = self . _set_bugowner ( args , opts )
2010-05-24 13:28:44 +02:00
else :
2023-04-03 12:03:19 +02:00
raise oscerr . WrongArgs ( f " Unsupported action { action } " )
2010-05-24 13:28:44 +02:00
if actionsxml == " " :
sys . exit ( ' No actions need to be taken. ' )
if not opts . message :
opts . message = edit_message ( )
xml = """ <request> %s <state name= " new " /> <description> %s </description> </request> """ % \
2020-03-12 23:00:47 +01:00
( actionsxml , _html_escape ( opts . message or " " ) )
2010-05-24 13:28:44 +02:00
u = makeurl ( apiurl , [ ' request ' ] , query = ' cmd=create ' )
f = http_POST ( u , data = xml )
root = ET . parse ( f ) . getroot ( )
2014-09-23 13:05:10 +02:00
rid = root . get ( ' id ' )
for srid in supersede :
change_request_state ( apiurl , srid , ' superseded ' ,
' superseded by %s ' % rid , rid )
return rid
2010-05-24 13:28:44 +02:00
2010-08-18 11:42:50 +02:00
@cmdln.option ( ' -m ' , ' --message ' , metavar = ' TEXT ' ,
help = ' specify message TEXT ' )
2011-06-01 09:50:30 +02:00
@cmdln.option ( ' -r ' , ' --role ' , metavar = ' role ' ,
2022-09-12 13:43:10 +02:00
help = ' specify user role (default: maintainer) ' )
2011-06-01 09:50:30 +02:00
@cmdln.alias ( " reqbugownership " )
@cmdln.alias ( " requestbugownership " )
2010-11-25 22:23:12 +01:00
@cmdln.alias ( " reqmaintainership " )
@cmdln.alias ( " reqms " )
2011-06-01 09:50:30 +02:00
@cmdln.alias ( " reqbs " )
2010-11-25 22:23:12 +01:00
def do_requestmaintainership ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Requests to add user as maintainer or bugowner
2010-08-18 11:42:50 +02:00
usage :
2014-08-19 14:33:06 +02:00
osc requestmaintainership # for current user in checked out package
osc requestmaintainership USER # for specified user in checked out package
osc requestmaintainership PROJECT # for current user if cwd is not a checked out package
2017-07-02 15:59:45 +02:00
osc requestmaintainership PROJECT group : NAME # request for specified group
2014-08-19 14:33:06 +02:00
osc requestmaintainership PROJECT PACKAGE # for current user
osc requestmaintainership PROJECT PACKAGE USER # request for specified user
osc requestmaintainership PROJECT PACKAGE group : NAME # request for specified group
2016-05-15 17:50:31 +02:00
osc requestbugownership . . . # accepts same parameters but uses bugowner role
2010-08-18 11:42:50 +02:00
"""
args = slash_split ( args )
apiurl = self . get_api_url ( )
2011-01-25 21:06:28 +01:00
if len ( args ) == 2 :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2010-08-18 11:42:50 +02:00
package = args [ 1 ]
2017-07-02 15:59:45 +02:00
if package . startswith ( ' group: ' ) :
user = package
package = None
else :
user = conf . get_apiurl_usr ( apiurl )
2010-08-18 11:42:50 +02:00
elif len ( args ) == 3 :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2010-08-18 11:42:50 +02:00
package = args [ 1 ]
2010-08-18 12:40:43 +02:00
user = args [ 2 ]
2022-10-07 17:25:33 +02:00
elif len ( args ) < 2 and is_package_dir ( Path . cwd ( ) ) :
project = store_read_project ( Path . cwd ( ) )
package = store_read_package ( Path . cwd ( ) )
2011-01-25 21:06:28 +01:00
if len ( args ) == 0 :
user = conf . get_apiurl_usr ( apiurl )
else :
user = args [ 0 ]
2014-03-12 16:41:46 +01:00
elif len ( args ) == 1 :
user = conf . get_apiurl_usr ( apiurl )
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2014-03-12 16:41:46 +01:00
package = None
2010-08-18 11:42:50 +02:00
else :
2010-08-18 11:46:57 +02:00
raise oscerr . WrongArgs ( ' Wrong number of arguments. ' )
2010-08-18 11:42:50 +02:00
2011-06-01 09:50:30 +02:00
role = ' maintainer '
2022-09-12 13:43:10 +02:00
if subcmd in ( ' reqbugownership ' , ' requestbugownership ' , ' reqbs ' ) :
2011-06-01 09:50:30 +02:00
role = ' bugowner '
if opts . role :
role = opts . role
2022-09-12 14:15:34 +02:00
if role not in ( ' maintainer ' , ' bugowner ' ) :
2010-11-25 22:23:12 +01:00
raise oscerr . WrongOptions ( ' invalid \' --role \' : either specify \' maintainer \' or \' bugowner \' ' )
2010-08-18 11:42:50 +02:00
if not opts . message :
opts . message = edit_message ( )
2011-01-25 21:06:28 +01:00
r = Request ( )
2014-08-19 14:33:06 +02:00
if user . startswith ( ' group: ' ) :
2022-04-20 19:22:35 +02:00
group = user . replace ( ' group: ' , ' ' )
if role == ' bugowner ' :
r . add_action ( ' set_bugowner ' , tgt_project = project , tgt_package = package ,
group_name = group )
else :
r . add_action ( ' add_role ' , tgt_project = project , tgt_package = package ,
group_name = group , group_role = role )
2014-08-19 14:33:06 +02:00
elif role == ' bugowner ' :
2013-05-27 12:16:44 +02:00
r . add_action ( ' set_bugowner ' , tgt_project = project , tgt_package = package ,
2022-09-12 13:43:10 +02:00
person_name = user )
2011-06-01 09:50:30 +02:00
else :
2013-05-27 12:16:44 +02:00
r . add_action ( ' add_role ' , tgt_project = project , tgt_package = package ,
2022-09-12 13:43:10 +02:00
person_name = user , person_role = role )
2020-11-28 17:46:44 +01:00
r . description = opts . message
2011-01-25 21:06:28 +01:00
r . create ( apiurl )
2013-04-09 12:51:28 +02:00
print ( r . reqid )
2010-08-18 11:42:50 +02:00
2009-06-02 16:57:42 +02:00
@cmdln.option ( ' -m ' , ' --message ' , metavar = ' TEXT ' ,
help = ' specify message TEXT ' )
2015-04-26 16:53:25 +02:00
@cmdln.option ( ' -r ' , ' --repository ' , metavar = ' REPOSITORY ' ,
help = ' specify repository ' )
2019-02-01 15:44:43 +01:00
@cmdln.option ( ' --all ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' deletes entire project with packages inside ' )
2015-04-26 16:53:25 +02:00
@cmdln.option ( ' --accept-in-hours ' , metavar = ' HOURS ' ,
help = ' specify time when request shall get accepted automatically. Only works with write permissions in target. ' )
2009-06-02 16:57:42 +02:00
@cmdln.alias ( " dr " )
2010-12-14 15:49:27 +01:00
@cmdln.alias ( " dropreq " )
@cmdln.alias ( " droprequest " )
2009-06-02 16:57:42 +02:00
@cmdln.alias ( " deletereq " )
def do_deleterequest ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Request to delete ( or ' drop ' ) a package or project
2009-06-02 15:14:46 +02:00
2009-06-02 16:57:42 +02:00
usage :
2011-01-21 11:04:47 +01:00
osc deletereq [ - m TEXT ] # works in checked out project/package
2019-02-01 15:44:43 +01:00
osc deletereq [ - m TEXT ] PROJECT PACKAGE
osc deletereq [ - m TEXT ] PROJECT [ - - all | - - repository REPOSITORY ]
2009-06-02 16:57:42 +02:00
"""
args = slash_split ( args )
2009-06-02 15:14:46 +02:00
2010-07-06 14:16:24 +02:00
project = None
package = None
2012-11-13 13:20:09 +01:00
repository = None
2010-07-06 14:16:24 +02:00
2011-01-25 20:41:42 +01:00
if len ( args ) > 2 :
raise oscerr . WrongArgs ( ' Too many arguments. ' )
2010-07-06 14:16:24 +02:00
elif len ( args ) == 1 :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2011-01-25 20:41:42 +01:00
elif len ( args ) == 2 :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2010-07-06 14:16:24 +02:00
package = args [ 1 ]
2022-10-07 17:25:33 +02:00
elif is_project_dir ( Path . cwd ( ) ) :
project = store_read_project ( Path . cwd ( ) )
elif is_package_dir ( Path . cwd ( ) ) :
project = store_read_project ( Path . cwd ( ) )
package = store_read_package ( Path . cwd ( ) )
2014-08-12 15:01:16 +02:00
else :
2011-01-25 20:41:42 +01:00
raise oscerr . WrongArgs ( ' Please specify at least a project. ' )
2009-06-23 12:06:31 +02:00
2020-01-16 09:01:43 +01:00
if not opts . all and package is None and not opts . repository :
2019-02-01 15:44:43 +01:00
raise oscerr . WrongOptions ( ' No package name has been provided. Use --all option, if you want to request to delete the entire project. ' )
2012-11-13 13:20:09 +01:00
if opts . repository :
repository = opts . repository
2009-08-19 13:28:16 +02:00
if not opts . message :
2010-07-06 14:16:24 +02:00
if package is not None :
2022-09-12 13:43:10 +02:00
footer = textwrap . TextWrapper ( width = 66 ) . fill (
' please explain why you like to delete package %s of project %s '
% ( package , project ) )
2010-07-06 14:16:24 +02:00
else :
2022-09-12 13:43:10 +02:00
footer = textwrap . TextWrapper ( width = 66 ) . fill (
' please explain why you like to delete project %s ' % project )
2010-07-06 14:16:24 +02:00
opts . message = edit_message ( footer )
2009-08-19 13:28:16 +02:00
2011-01-25 20:41:42 +01:00
r = Request ( )
2012-11-13 13:20:09 +01:00
r . add_action ( ' delete ' , tgt_project = project , tgt_package = package , tgt_repository = repository )
2020-11-28 17:46:44 +01:00
r . description = opts . message
2013-12-05 10:23:53 +01:00
if opts . accept_in_hours :
2022-04-20 19:22:35 +02:00
r . accept_at_in_hours ( int ( opts . accept_in_hours ) )
2011-01-25 20:41:42 +01:00
r . create ( self . get_api_url ( ) )
2013-04-09 12:51:28 +02:00
print ( r . reqid )
2009-06-02 15:14:46 +02:00
2009-06-02 16:57:42 +02:00
@cmdln.option ( ' -m ' , ' --message ' , metavar = ' TEXT ' ,
help = ' specify message TEXT ' )
@cmdln.alias ( " cr " )
@cmdln.alias ( " changedevelreq " )
def do_changedevelrequest ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Create request to change the devel package definition
2009-06-02 15:14:46 +02:00
2014-08-12 15:01:16 +02:00
[ See http : / / en . opensuse . org / openSUSE : Build_Service_Collaboration
2010-07-26 19:45:42 +02:00
for information on this topic . ]
2009-06-02 16:57:42 +02:00
2019-05-24 13:42:47 +02:00
See the " request " command for showing and modifying existing requests .
2009-06-02 16:57:42 +02:00
2022-01-19 15:13:55 +01:00
usage :
osc changedevelrequest PROJECT PACKAGE DEVEL_PROJECT [ DEVEL_PACKAGE ]
2009-06-02 16:57:42 +02:00
"""
2011-03-09 16:10:48 +01:00
if len ( args ) == 0 and is_package_dir ( ' . ' ) and find_default_project ( ) :
2022-10-07 17:25:33 +02:00
wd = Path . cwd ( )
2010-02-24 11:41:59 +01:00
devel_project = store_read_project ( wd )
devel_package = package = store_read_package ( wd )
2011-03-09 16:10:48 +01:00
project = find_default_project ( self . get_api_url ( ) , package )
2011-01-25 20:41:42 +01:00
elif len ( args ) < 3 :
raise oscerr . WrongArgs ( ' Too few arguments. ' )
elif len ( args ) > 4 :
raise oscerr . WrongArgs ( ' Too many arguments. ' )
2010-02-11 11:26:03 +01:00
else :
2022-05-10 14:49:21 +02:00
devel_project = self . _process_project_name ( args [ 2 ] )
project = self . _process_project_name ( args [ 0 ] )
2010-02-11 11:26:03 +01:00
package = args [ 1 ]
devel_package = package
2011-01-25 20:41:42 +01:00
if len ( args ) == 4 :
2010-02-11 11:26:03 +01:00
devel_package = args [ 3 ]
2009-08-19 13:28:16 +02:00
if not opts . message :
2022-09-12 13:43:10 +02:00
footer = textwrap . TextWrapper ( width = 66 ) . fill (
' please explain why you like to change the devel project of %s / %s to %s / %s '
% ( project , package , devel_project , devel_package ) )
2010-02-24 11:41:59 +01:00
opts . message = edit_message ( footer )
2009-08-19 13:28:16 +02:00
2011-01-25 20:41:42 +01:00
r = Request ( )
r . add_action ( ' change_devel ' , src_project = devel_project , src_package = devel_package ,
2022-09-12 13:43:10 +02:00
tgt_project = project , tgt_package = package )
2020-11-28 17:46:44 +01:00
r . description = opts . message
2011-01-25 20:41:42 +01:00
r . create ( self . get_api_url ( ) )
2013-04-09 12:51:28 +02:00
print ( r . reqid )
2009-06-02 15:14:46 +02:00
@cmdln.option ( ' -d ' , ' --diff ' , action = ' store_true ' ,
help = ' generate a diff ' )
2020-02-19 17:07:35 +01:00
@cmdln.option ( ' -S ' , ' --superseded-request ' , metavar = ' SUPERSEDED_REQUEST ' ,
help = ' Create the diff relative to a given former request ' )
2009-06-02 15:14:46 +02:00
@cmdln.option ( ' -u ' , ' --unified ' , action = ' store_true ' ,
help = ' output the diff in the unified diff format ' )
2013-09-25 15:36:54 +02:00
@cmdln.option ( ' --no-devel ' , action = ' store_true ' ,
help = ' Do not attempt to forward to devel project ' )
2009-06-02 15:14:46 +02:00
@cmdln.option ( ' -m ' , ' --message ' , metavar = ' TEXT ' ,
help = ' specify message TEXT ' )
2009-11-20 17:06:05 +01:00
@cmdln.option ( ' -t ' , ' --type ' , metavar = ' TYPE ' ,
2017-08-24 12:14:25 +02:00
help = ' limit to requests which contain a given action type (submit/delete/change_devel/add_role/set_bugowner/maintenance_incident/maintenance_release) ' )
2009-08-19 15:00:22 +02:00
@cmdln.option ( ' -a ' , ' --all ' , action = ' store_true ' ,
2009-08-20 21:28:05 +02:00
help = ' all states. Same as \' -s all \' ' )
2011-02-08 16:16:18 +01:00
@cmdln.option ( ' -f ' , ' --force ' , action = ' store_true ' ,
2023-07-26 15:34:37 +02:00
help = ' enforce state change, can be used to ignore open reviews, devel-package dependencies and more ' )
2022-10-20 10:19:43 +02:00
@cmdln.option ( ' -s ' , ' --state ' ,
2023-02-02 13:50:51 +01:00
help = ' only list requests in one of the comma separated given states (new/review/accepted/revoked/declined) or " all " [default= " new,review,declined " ] ' )
2009-08-21 02:42:51 +02:00
@cmdln.option ( ' -D ' , ' --days ' , metavar = ' DAYS ' ,
2022-01-19 15:13:55 +01:00
help = ' only list requests in state " new " or changed in the last DAYS. ' )
2009-08-20 21:28:05 +02:00
@cmdln.option ( ' -U ' , ' --user ' , metavar = ' USER ' ,
2010-07-29 13:45:44 +02:00
help = ' requests or reviews limited for the specified USER ' )
@cmdln.option ( ' -G ' , ' --group ' , metavar = ' GROUP ' ,
help = ' requests or reviews limited for the specified GROUP ' )
2011-01-23 21:21:32 +01:00
@cmdln.option ( ' -P ' , ' --project ' , metavar = ' PROJECT ' ,
help = ' requests or reviews limited for the specified PROJECT ' )
@cmdln.option ( ' -p ' , ' --package ' , metavar = ' PACKAGE ' ,
help = ' requests or reviews limited for the specified PACKAGE, requires also a PROJECT ' )
2009-06-02 15:14:46 +02:00
@cmdln.option ( ' -b ' , ' --brief ' , action = ' store_true ' , default = False ,
help = ' print output in list view as list subcommand ' )
@cmdln.option ( ' -M ' , ' --mine ' , action = ' store_true ' ,
help = ' only show requests created by yourself ' )
2009-09-28 21:50:57 +02:00
@cmdln.option ( ' -B ' , ' --bugowner ' , action = ' store_true ' ,
help = ' also show requests about packages where I am bugowner ' )
2011-01-30 14:24:21 +01:00
@cmdln.option ( ' -e ' , ' --edit ' , action = ' store_true ' ,
help = ' edit a submit action ' )
2010-02-11 01:47:47 +01:00
@cmdln.option ( ' -i ' , ' --interactive ' , action = ' store_true ' ,
help = ' interactive review of request ' )
2013-05-06 18:44:14 +02:00
@cmdln.option ( ' --or-revoke ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' For automation scripts: accepts (if using with accept argument) a request when it is in new or review state. Or revoke it when it got declined. Otherwise just do nothing. ' )
2010-03-23 16:21:09 +01:00
@cmdln.option ( ' --non-interactive ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' non-interactive review of request ' )
2010-02-25 22:56:21 +01:00
@cmdln.option ( ' --exclude-target-project ' , action = ' append ' ,
2022-09-12 13:43:10 +02:00
help = ' exclude target project from request list ' )
2023-09-28 14:50:20 +02:00
@cmdln.option ( ' --keep-packages-locked ' , action = ' store_true ' ,
help = ' Avoid unlocking of packages in maintenance incident when revoking release requests ' )
2019-10-16 14:07:40 +02:00
@cmdln.option ( ' --incoming ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' Show only requests where the project is target ' )
2010-03-13 21:06:18 +01:00
@cmdln.option ( ' --involved-projects ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' show all requests for project/packages where USER is involved ' )
2017-08-15 14:37:44 +02:00
@cmdln.option ( ' --target-package-filter ' , metavar = ' TARGET_PACKAGE_FILTER ' ,
2022-09-12 13:43:10 +02:00
help = ' only list requests for the packages matching the package filter. A (python) regular expression is expected. ' )
2010-09-14 16:02:21 +02:00
@cmdln.option ( ' --source-buildstatus ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' print the buildstatus of the source package (only works with " show " and the interactive review) ' )
2009-06-02 15:14:46 +02:00
@cmdln.alias ( " rq " )
2009-11-17 17:59:17 +01:00
@cmdln.alias ( " review " )
2010-02-26 09:55:58 +01:00
# FIXME: rewrite this mess and split request and review
2009-06-02 15:14:46 +02:00
def do_request ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Show or modify requests and reviews
2009-06-02 15:14:46 +02:00
2010-07-27 15:20:35 +02:00
[ See http : / / en . opensuse . org / openSUSE : Build_Service_Collaboration
2010-07-26 19:45:42 +02:00
for information on this topic . ]
2009-06-02 15:14:46 +02:00
2010-02-26 09:55:58 +01:00
The ' request ' command has the following sub commands :
2008-03-05 00:41:00 +01:00
2009-08-20 21:28:05 +02:00
" list " lists open requests attached to a project or package or person .
Uses the project / package of the current directory if none of
- M , - U USER , project / package are given .
2008-03-05 00:41:00 +01:00
2008-08-19 16:18:05 +02:00
" log " will show the history of the given ID
2008-03-06 11:25:45 +01:00
" show " will show the request itself , and generate a diff for review , if
2010-01-02 12:25:37 +01:00
used with the - - diff option . The keyword show can be omitted if the ID is numeric .
2008-03-05 00:41:00 +01:00
2010-02-26 09:55:58 +01:00
" decline " will change the request state to " declined "
2008-03-05 00:41:00 +01:00
2010-11-24 14:18:45 +01:00
" reopen " will set the request back to new or review .
2012-01-19 11:43:37 +01:00
" setincident " will direct " maintenance " requests into specific incidents
2011-02-11 16:12:38 +01:00
" supersede " will supersede one request with another existing one .
2008-07-25 11:34:29 +02:00
2010-02-26 09:55:58 +01:00
" revoke " will set the request state to " revoked "
2023-09-29 08:33:55 +02:00
WARNING : Revoking a maitenance release request unlocks packages in the source project .
To avoid unlocking , use the - - keep - packages - locked option .
2008-07-09 17:22:18 +02:00
2008-03-13 00:37:35 +01:00
" accept " will change the request state to " accepted " and will trigger
the actual submit process . That would normally be a server - side copy of
the source package to the target package .
2008-03-05 00:41:00 +01:00
2018-10-17 15:31:23 +02:00
" approve " marks a requests in " review " state as approved . This request will get accepted
automatically when the last review got accepted .
2010-02-26 09:55:58 +01:00
" checkout " will checkout the request ' s source package ( " submit " requests only).
2019-05-24 13:22:30 +02:00
" prioritize " change the priority of a request to either " critical " , " important " , " moderate " or " low "
2014-09-11 11:25:24 +02:00
2010-02-26 09:55:58 +01:00
The ' review ' command has the following sub commands :
" list " lists open requests that need to be reviewed by the
2014-08-12 15:01:16 +02:00
specified user or group
2010-02-26 09:55:58 +01:00
" add " adds a person or group as reviewer to a request
" accept " mark the review positive
" decline " mark the review negative . A negative review will
decline the request .
2008-03-13 00:37:35 +01:00
usage :
2009-09-28 21:50:57 +02:00
osc request list [ - M ] [ - U USER ] [ - s state ] [ - D DAYS ] [ - t type ] [ - B ] [ PRJ [ PKG ] ]
2009-06-02 15:14:46 +02:00
osc request log ID
2009-09-03 19:28:27 +02:00
osc request [ show ] [ - d ] [ - b ] ID
2010-08-10 16:36:29 +02:00
2009-06-02 15:14:46 +02:00
osc request accept [ - m TEXT ] ID
2018-10-17 15:31:23 +02:00
osc request approve [ - m TEXT ] ID
2020-01-08 17:18:54 +01:00
osc request cancelapproval [ - m TEXT ] ID
2009-06-02 15:14:46 +02:00
osc request decline [ - m TEXT ] ID
osc request revoke [ - m TEXT ] ID
2010-08-10 16:36:29 +02:00
osc request reopen [ - m TEXT ] ID
2012-01-19 11:43:37 +01:00
osc request setincident [ - m TEXT ] ID INCIDENT
2011-04-26 17:18:49 +02:00
osc request supersede [ - m TEXT ] ID SUPERSEDING_ID
2010-08-10 16:36:29 +02:00
osc request approvenew [ - m TEXT ] PROJECT
2019-05-24 13:22:30 +02:00
osc request prioritize [ - m TEXT ] ID PRIORITY
2010-08-10 16:36:29 +02:00
2009-09-16 23:39:45 +02:00
osc request checkout / co ID
2010-08-10 16:36:29 +02:00
osc request clone [ - m TEXT ] ID
2012-03-06 13:25:47 +01:00
osc review show [ - d ] [ - b ] ID
2011-04-26 17:18:49 +02:00
osc review list [ - U USER ] [ - G GROUP ] [ - P PROJECT [ - p PACKAGE ] ] [ - s state ]
osc review add [ - m TEXT ] [ - U USER ] [ - G GROUP ] [ - P PROJECT [ - p PACKAGE ] ] ID
osc review accept [ - m TEXT ] [ - U USER ] [ - G GROUP ] [ - P PROJECT [ - p PACKAGE ] ] ID
osc review decline [ - m TEXT ] [ - U USER ] [ - G GROUP ] [ - P PROJECT [ - p PACKAGE ] ] ID
osc review reopen [ - m TEXT ] [ - U USER ] [ - G GROUP ] [ - P PROJECT [ - p PACKAGE ] ] ID
osc review supersede [ - m TEXT ] [ - U USER ] [ - G GROUP ] [ - P PROJECT [ - p PACKAGE ] ] ID SUPERSEDING_ID
2008-03-05 00:41:00 +01:00
"""
args = slash_split ( args )
2009-08-21 23:31:45 +02:00
if opts . all and opts . state :
2022-09-12 13:43:10 +02:00
raise oscerr . WrongOptions ( ' Sorry, the options \' --all \' and \' --state \' '
' are mutually exclusive. ' )
2009-08-21 23:31:45 +02:00
if opts . mine and opts . user :
2022-09-12 13:43:10 +02:00
raise oscerr . WrongOptions ( ' Sorry, the options \' --user \' and \' --mine \' '
' are mutually exclusive. ' )
2010-03-23 16:21:09 +01:00
if opts . interactive and opts . non_interactive :
2022-09-12 13:43:10 +02:00
raise oscerr . WrongOptions ( ' Sorry, the options \' --interactive \' and '
' \' --non-interactive \' are mutually exclusive ' )
2009-08-21 23:31:45 +02:00
2022-10-20 10:19:43 +02:00
if opts . all :
state_list = [ " all " ]
else :
if not opts . state :
2023-02-02 13:50:51 +01:00
opts . state = " new,review,declined "
2022-10-20 10:19:43 +02:00
state_list = opts . state . split ( " , " )
state_list = [ i for i in state_list if i . strip ( ) ]
2009-08-20 21:28:05 +02:00
if not args :
2022-09-12 13:43:10 +02:00
args = [ ' list ' ]
2009-08-20 21:28:05 +02:00
opts . mine = 1
2019-10-16 14:07:40 +02:00
if opts . incoming :
conf . config [ ' include_request_from_project ' ] = False
2018-10-17 15:31:23 +02:00
cmds = [ ' list ' , ' ls ' , ' log ' , ' show ' , ' decline ' , ' reopen ' , ' clone ' , ' accept ' , ' approve ' , ' cancelapproval ' ,
2019-05-24 13:22:30 +02:00
' approvenew ' , ' wipe ' , ' setincident ' , ' supersede ' , ' revoke ' , ' checkout ' , ' co ' , ' priorize ' , ' prioritize ' ]
2010-08-13 09:51:20 +02:00
if subcmd != ' review ' and args [ 0 ] not in cmds :
2022-09-12 13:43:10 +02:00
raise oscerr . WrongArgs ( ' Unknown request action %s . Choose one of %s . '
% ( args [ 0 ] , ' , ' . join ( cmds ) ) )
2012-03-06 13:22:25 +01:00
cmds = [ ' show ' , ' list ' , ' add ' , ' decline ' , ' accept ' , ' reopen ' , ' supersede ' ]
2010-08-13 09:51:20 +02:00
if subcmd == ' review ' and args [ 0 ] not in cmds :
2022-09-12 13:43:10 +02:00
raise oscerr . WrongArgs ( ' Unknown review action %s . Choose one of %s . '
% ( args [ 0 ] , ' , ' . join ( cmds ) ) )
2008-03-05 00:41:00 +01:00
cmd = args [ 0 ]
del args [ 0 ]
2014-09-11 11:25:24 +02:00
if cmd == ' ls ' :
cmd = " list "
2008-03-05 00:41:00 +01:00
2010-10-12 10:59:53 +02:00
apiurl = self . get_api_url ( )
2022-10-08 13:24:08 +02:00
if cmd == ' list ' :
2008-06-24 11:37:49 +02:00
min_args , max_args = 0 , 2
2022-10-08 13:24:08 +02:00
elif cmd in ( ' supersede ' , ' setincident ' , ' prioritize ' , ' priorize ' ) :
2011-02-11 16:12:38 +01:00
min_args , max_args = 2 , 2
2008-03-05 00:41:00 +01:00
else :
min_args , max_args = 1 , 1
if len ( args ) < min_args :
Merged revisions 3774-3775,3779,3781-3782,3787,3789-3793,3798,3802,3805,3817-3822,3827,3829-3830,3837-3839,3841-3842,3848-3850 via svnmerge from
https://forgesvn1.novell.com/svn/opensuse/branches/buildservice/osc-exception-handling
........
r3774 | poeml | 2008-04-22 17:39:45 +0200 (Tue, 22 Apr 2008) | 3 lines
A first draft on implement systematic exception handling:
Add errors.py with some exceptions defined, and babysitter.py to handle them
........
r3775 | poeml | 2008-04-22 22:34:12 +0200 (Tue, 22 Apr 2008) | 9 lines
- new global options:
--debugger jump into the debugger before executing anything
--post-mortem jump into the debugger in case of errors
-t, --traceback print call trace in case of errors
- traceback and post_mortem can also be set in .oscrc.
- catch more errors (HTTPError).
- make config accessible from outside of the Osc instance, by making it a class
attribute
........
r3779 | poeml | 2008-04-23 00:55:49 +0200 (Wed, 23 Apr 2008) | 5 lines
- new global option:
-d, --debug print info useful for debugging
- catch some more errors (HTTPError), with OscHTTPError which isn't very
advanced yet.
........
r3781 | Marcus_H | 2008-04-23 01:02:00 +0200 (Wed, 23 Apr 2008) | 2 lines
- added OscConfigError class (just for testing).
- small change in the signature of the OscBaseError constructor (actually we should get rid of the 'args' tuple because it will be deprecated sooner or later
........
r3782 | Marcus_H | 2008-04-23 02:02:13 +0200 (Wed, 23 Apr 2008) | 2 lines
- access the prg.conf.config dict in a save way - this way we avoid AttributeErrors if the prg.conf.config dict doesn't exist
- in case of an configparser error we have to use the prg.options object directly (this was removed in r3781 by accident)
........
r3787 | poeml | 2008-04-23 09:23:56 +0200 (Wed, 23 Apr 2008) | 4 lines
- remove local exception handling from do_req
- for HTTPError, print details (headers and response) when in debug mode
- catch AttributeError
........
r3789 | poeml | 2008-04-23 16:23:14 +0200 (Wed, 23 Apr 2008) | 4 lines
- errors: add two new classes named OscWrongOptionsError and OscWrongArgsError
- commandline: raise instances of the new errors in a number of places
- commandline: add get_cmd_help() to Osc instance which returns the formatted help of a subcommand
........
r3790 | Marcus_H | 2008-04-23 16:48:28 +0200 (Wed, 23 Apr 2008) | 4 lines
- added 2 new exception classes: OscNoConfigfileError and OscIOError
- added new method write_config() to the conf.py module: This method writes osc's configuration file
- minor cleanups in the conf module
........
r3791 | poeml | 2008-04-23 17:11:07 +0200 (Wed, 23 Apr 2008) | 3 lines
small compatibility fix for r3790: try-except-finally isn't supported in
python-2.4.2, thus do the same as try-except inside a try-finally.
........
r3792 | poeml | 2008-04-23 17:37:53 +0200 (Wed, 23 Apr 2008) | 2 lines
fix up the remaining places regarding handling of errors related to commandline parsing
........
r3793 | poeml | 2008-04-23 17:40:34 +0200 (Wed, 23 Apr 2008) | 3 lines
raise a NoWorkingCopyError in osc.core.store_read_project() in case of an
IOError
........
r3798 | Marcus_H | 2008-04-23 23:55:24 +0200 (Wed, 23 Apr 2008) | 1 line
ported -r3797 from trunk
........
r3802 | Marcus_H | 2008-04-24 11:00:55 +0200 (Thu, 24 Apr 2008) | 1 line
ported -r3801 from trunk
........
r3805 | poeml | 2008-04-24 12:52:30 +0200 (Thu, 24 Apr 2008) | 2 lines
raise OscHTTPError in show_pattern_meta(), replacing local error handling
........
r3817 | poeml | 2008-04-24 20:21:32 +0200 (Thu, 24 Apr 2008) | 9 lines
- remove errors.OscHTTPError again.
it seems simpler to use urllib2.HTTPError instead (and just add a specific
error text message where appropriate, and re-raise)
- for 404s, check out _which_ part was not found
it is very ugly, but may be considered Good for pragmatic reasons
- removed local exception handling and workaround for returned 500's from
delete_package() and delete_project(), thereby getting rid of 4 possible exit
points.
........
r3818 | Marcus_H | 2008-04-24 22:36:17 +0200 (Thu, 24 Apr 2008) | 1 line
- this check is superfluous because every HTTPError instance has a code attribute
........
r3819 | poeml | 2008-04-25 00:39:39 +0200 (Fri, 25 Apr 2008) | 1 line
remove a forgotten debug line from core.delete_project()
........
r3820 | poeml | 2008-04-25 10:07:58 +0200 (Fri, 25 Apr 2008) | 2 lines
- ditch local error handling from wipebinaries(), rebuild(), and abortbuild()
........
r3821 | poeml | 2008-04-25 10:56:38 +0200 (Fri, 25 Apr 2008) | 2 lines
It is never needed to import the exception module.
........
r3822 | poeml | 2008-04-25 11:13:39 +0200 (Fri, 25 Apr 2008) | 4 lines
- when going into the debugger with --post-mortem, always print a traceback before
(thus implying -t)
- do not jump into the debugger if not on a TTY, or working in interactive mode
........
r3827 | poeml | 2008-04-25 13:07:46 +0200 (Fri, 25 Apr 2008) | 9 lines
- add errors.OscWorkingCopyOutdated, which takes a tuple with three args:
path to working copy, current rev, expected rev
- add handler for urllib2.URLError errors to the babysitter
- simplify the OscWrongArgsError and OscWrongOptionsError handlers, by removing
the extra line "Sorry, wrong ..." that was printed before the messages given
when the error was raised.
- remove one more errors.OscHTTPError which was still there, and raise
urllib2.HTTPError instead (show_package_meta())
........
r3829 | poeml | 2008-04-25 14:19:10 +0200 (Fri, 25 Apr 2008) | 11 lines
- comment some methods in osc.core which are used by nearly all do_* methods in
osc.commandline
- improve "is not a package/project dir" error messages, by printing the
absolute path tried, instead of '.' for the cwd
- make core.store_read_package() raise a proper NoWorkingCopyError instead of
terminating
- give attribution to things in babysitter.py copied from mercurial
- prefix HTTPError exceptions with 'Server returned an error:'
- remove obsolete local error handling from do_prjresults(), do_importsrcpkg(),
do_repos()
........
r3830 | poeml | 2008-04-25 14:29:35 +0200 (Fri, 25 Apr 2008) | 1 line
catch IOError exceptions in the babysitter
........
r3837 | poeml | 2008-04-25 17:27:36 +0200 (Fri, 25 Apr 2008) | 5 lines
- do_remotebuildlog: raise errors for wrong arguments, remove exits
- raise AttributeError in make_meta_url() instead of exiting
- delete unused method core.delete_server_files()
- replace exit call inside make_meta_url() with an AttributeError
........
r3838 | poeml | 2008-04-25 17:49:18 +0200 (Fri, 25 Apr 2008) | 1 line
simplify the check in do_checkout if a project exists, by using show_project_meta() instead of meta_exists
........
r3839 | poeml | 2008-04-25 18:31:26 +0200 (Fri, 25 Apr 2008) | 6 lines
- commandline do_checkout(): change the order of the two checks, first do the
(cheaper) check for existing directory
- core.core checkout_package(): simplify the check in if the package
exists, by using show_package_meta() instead of meta_exists
Let it throw an exception, instead of using sys.exit().
........
r3841 | Marcus_H | 2008-04-27 15:48:06 +0200 (Sun, 27 Apr 2008) | 5 lines
- added 2 new exception classes: PackageError() and PackageExistsError. The PackageError() class is meant to be the base class for all subsequent package exceptions.
- get rid of 2 sys.exit(1) calls
- make the update() method of the Project() class safer: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- minor fix in delPackage(): use getTransActPath() when printing out the filename
........
r3842 | Marcus_H | 2008-04-27 16:52:55 +0200 (Sun, 27 Apr 2008) | 3 lines
- make the commit() method safe: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- removed another sys.exit(1): raise an exception if a package is missing when doing a commit. For now we use the PackageExistsError() exception but this might change in the future (updated description of PackageExistsError() according to this change)
........
r3848 | poeml | 2008-04-28 12:46:45 +0200 (Mon, 28 Apr 2008) | 3 lines
rename several error classes, dropping the "Osc" prefix, and "Error" suffix in
cases where they don't really make sense.
........
r3849 | poeml | 2008-04-28 12:57:32 +0200 (Mon, 28 Apr 2008) | 3 lines
- rename osc.errors module to osc.oscerr, to make it easier to import it from
other programs and have a crystal clear namespace
........
r3850 | poeml | 2008-04-28 13:26:12 +0200 (Mon, 28 Apr 2008) | 2 lines
split PackageExists exception class into PackageExists and PackageMissing
........
2008-04-28 18:37:44 +02:00
raise oscerr . WrongArgs ( ' Too few arguments. ' )
2008-03-05 00:41:00 +01:00
if len ( args ) > max_args :
Merged revisions 3774-3775,3779,3781-3782,3787,3789-3793,3798,3802,3805,3817-3822,3827,3829-3830,3837-3839,3841-3842,3848-3850 via svnmerge from
https://forgesvn1.novell.com/svn/opensuse/branches/buildservice/osc-exception-handling
........
r3774 | poeml | 2008-04-22 17:39:45 +0200 (Tue, 22 Apr 2008) | 3 lines
A first draft on implement systematic exception handling:
Add errors.py with some exceptions defined, and babysitter.py to handle them
........
r3775 | poeml | 2008-04-22 22:34:12 +0200 (Tue, 22 Apr 2008) | 9 lines
- new global options:
--debugger jump into the debugger before executing anything
--post-mortem jump into the debugger in case of errors
-t, --traceback print call trace in case of errors
- traceback and post_mortem can also be set in .oscrc.
- catch more errors (HTTPError).
- make config accessible from outside of the Osc instance, by making it a class
attribute
........
r3779 | poeml | 2008-04-23 00:55:49 +0200 (Wed, 23 Apr 2008) | 5 lines
- new global option:
-d, --debug print info useful for debugging
- catch some more errors (HTTPError), with OscHTTPError which isn't very
advanced yet.
........
r3781 | Marcus_H | 2008-04-23 01:02:00 +0200 (Wed, 23 Apr 2008) | 2 lines
- added OscConfigError class (just for testing).
- small change in the signature of the OscBaseError constructor (actually we should get rid of the 'args' tuple because it will be deprecated sooner or later
........
r3782 | Marcus_H | 2008-04-23 02:02:13 +0200 (Wed, 23 Apr 2008) | 2 lines
- access the prg.conf.config dict in a save way - this way we avoid AttributeErrors if the prg.conf.config dict doesn't exist
- in case of an configparser error we have to use the prg.options object directly (this was removed in r3781 by accident)
........
r3787 | poeml | 2008-04-23 09:23:56 +0200 (Wed, 23 Apr 2008) | 4 lines
- remove local exception handling from do_req
- for HTTPError, print details (headers and response) when in debug mode
- catch AttributeError
........
r3789 | poeml | 2008-04-23 16:23:14 +0200 (Wed, 23 Apr 2008) | 4 lines
- errors: add two new classes named OscWrongOptionsError and OscWrongArgsError
- commandline: raise instances of the new errors in a number of places
- commandline: add get_cmd_help() to Osc instance which returns the formatted help of a subcommand
........
r3790 | Marcus_H | 2008-04-23 16:48:28 +0200 (Wed, 23 Apr 2008) | 4 lines
- added 2 new exception classes: OscNoConfigfileError and OscIOError
- added new method write_config() to the conf.py module: This method writes osc's configuration file
- minor cleanups in the conf module
........
r3791 | poeml | 2008-04-23 17:11:07 +0200 (Wed, 23 Apr 2008) | 3 lines
small compatibility fix for r3790: try-except-finally isn't supported in
python-2.4.2, thus do the same as try-except inside a try-finally.
........
r3792 | poeml | 2008-04-23 17:37:53 +0200 (Wed, 23 Apr 2008) | 2 lines
fix up the remaining places regarding handling of errors related to commandline parsing
........
r3793 | poeml | 2008-04-23 17:40:34 +0200 (Wed, 23 Apr 2008) | 3 lines
raise a NoWorkingCopyError in osc.core.store_read_project() in case of an
IOError
........
r3798 | Marcus_H | 2008-04-23 23:55:24 +0200 (Wed, 23 Apr 2008) | 1 line
ported -r3797 from trunk
........
r3802 | Marcus_H | 2008-04-24 11:00:55 +0200 (Thu, 24 Apr 2008) | 1 line
ported -r3801 from trunk
........
r3805 | poeml | 2008-04-24 12:52:30 +0200 (Thu, 24 Apr 2008) | 2 lines
raise OscHTTPError in show_pattern_meta(), replacing local error handling
........
r3817 | poeml | 2008-04-24 20:21:32 +0200 (Thu, 24 Apr 2008) | 9 lines
- remove errors.OscHTTPError again.
it seems simpler to use urllib2.HTTPError instead (and just add a specific
error text message where appropriate, and re-raise)
- for 404s, check out _which_ part was not found
it is very ugly, but may be considered Good for pragmatic reasons
- removed local exception handling and workaround for returned 500's from
delete_package() and delete_project(), thereby getting rid of 4 possible exit
points.
........
r3818 | Marcus_H | 2008-04-24 22:36:17 +0200 (Thu, 24 Apr 2008) | 1 line
- this check is superfluous because every HTTPError instance has a code attribute
........
r3819 | poeml | 2008-04-25 00:39:39 +0200 (Fri, 25 Apr 2008) | 1 line
remove a forgotten debug line from core.delete_project()
........
r3820 | poeml | 2008-04-25 10:07:58 +0200 (Fri, 25 Apr 2008) | 2 lines
- ditch local error handling from wipebinaries(), rebuild(), and abortbuild()
........
r3821 | poeml | 2008-04-25 10:56:38 +0200 (Fri, 25 Apr 2008) | 2 lines
It is never needed to import the exception module.
........
r3822 | poeml | 2008-04-25 11:13:39 +0200 (Fri, 25 Apr 2008) | 4 lines
- when going into the debugger with --post-mortem, always print a traceback before
(thus implying -t)
- do not jump into the debugger if not on a TTY, or working in interactive mode
........
r3827 | poeml | 2008-04-25 13:07:46 +0200 (Fri, 25 Apr 2008) | 9 lines
- add errors.OscWorkingCopyOutdated, which takes a tuple with three args:
path to working copy, current rev, expected rev
- add handler for urllib2.URLError errors to the babysitter
- simplify the OscWrongArgsError and OscWrongOptionsError handlers, by removing
the extra line "Sorry, wrong ..." that was printed before the messages given
when the error was raised.
- remove one more errors.OscHTTPError which was still there, and raise
urllib2.HTTPError instead (show_package_meta())
........
r3829 | poeml | 2008-04-25 14:19:10 +0200 (Fri, 25 Apr 2008) | 11 lines
- comment some methods in osc.core which are used by nearly all do_* methods in
osc.commandline
- improve "is not a package/project dir" error messages, by printing the
absolute path tried, instead of '.' for the cwd
- make core.store_read_package() raise a proper NoWorkingCopyError instead of
terminating
- give attribution to things in babysitter.py copied from mercurial
- prefix HTTPError exceptions with 'Server returned an error:'
- remove obsolete local error handling from do_prjresults(), do_importsrcpkg(),
do_repos()
........
r3830 | poeml | 2008-04-25 14:29:35 +0200 (Fri, 25 Apr 2008) | 1 line
catch IOError exceptions in the babysitter
........
r3837 | poeml | 2008-04-25 17:27:36 +0200 (Fri, 25 Apr 2008) | 5 lines
- do_remotebuildlog: raise errors for wrong arguments, remove exits
- raise AttributeError in make_meta_url() instead of exiting
- delete unused method core.delete_server_files()
- replace exit call inside make_meta_url() with an AttributeError
........
r3838 | poeml | 2008-04-25 17:49:18 +0200 (Fri, 25 Apr 2008) | 1 line
simplify the check in do_checkout if a project exists, by using show_project_meta() instead of meta_exists
........
r3839 | poeml | 2008-04-25 18:31:26 +0200 (Fri, 25 Apr 2008) | 6 lines
- commandline do_checkout(): change the order of the two checks, first do the
(cheaper) check for existing directory
- core.core checkout_package(): simplify the check in if the package
exists, by using show_package_meta() instead of meta_exists
Let it throw an exception, instead of using sys.exit().
........
r3841 | Marcus_H | 2008-04-27 15:48:06 +0200 (Sun, 27 Apr 2008) | 5 lines
- added 2 new exception classes: PackageError() and PackageExistsError. The PackageError() class is meant to be the base class for all subsequent package exceptions.
- get rid of 2 sys.exit(1) calls
- make the update() method of the Project() class safer: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- minor fix in delPackage(): use getTransActPath() when printing out the filename
........
r3842 | Marcus_H | 2008-04-27 16:52:55 +0200 (Sun, 27 Apr 2008) | 3 lines
- make the commit() method safe: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- removed another sys.exit(1): raise an exception if a package is missing when doing a commit. For now we use the PackageExistsError() exception but this might change in the future (updated description of PackageExistsError() according to this change)
........
r3848 | poeml | 2008-04-28 12:46:45 +0200 (Mon, 28 Apr 2008) | 3 lines
rename several error classes, dropping the "Osc" prefix, and "Error" suffix in
cases where they don't really make sense.
........
r3849 | poeml | 2008-04-28 12:57:32 +0200 (Mon, 28 Apr 2008) | 3 lines
- rename osc.errors module to osc.oscerr, to make it easier to import it from
other programs and have a crystal clear namespace
........
r3850 | poeml | 2008-04-28 13:26:12 +0200 (Mon, 28 Apr 2008) | 2 lines
split PackageExists exception class into PackageExists and PackageMissing
........
2008-04-28 18:37:44 +02:00
raise oscerr . WrongArgs ( ' Too many arguments. ' )
2011-04-26 17:18:49 +02:00
if cmd in [ ' add ' ] and not opts . user and not opts . group and not opts . project :
raise oscerr . WrongArgs ( ' No reviewer specified. ' )
2008-06-06 14:04:34 +02:00
2016-02-10 18:27:35 +01:00
source_buildstatus = conf . config [ ' request_show_source_buildstatus ' ] or opts . source_buildstatus
2011-02-11 16:12:38 +01:00
reqid = None
supersedid = None
2010-05-19 12:50:52 +02:00
if cmd == ' list ' or cmd == ' approvenew ' :
2008-06-24 11:37:49 +02:00
package = None
project = None
if len ( args ) > 0 :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2018-04-18 16:04:06 +02:00
elif opts . project :
project = opts . project
if opts . package :
package = opts . package
2017-04-18 09:11:19 +02:00
elif not opts . mine and not opts . user and not opts . group :
2009-05-15 17:32:15 +02:00
try :
2022-10-07 17:25:33 +02:00
project = store_read_project ( Path . cwd ( ) )
package = store_read_package ( Path . cwd ( ) )
2009-05-15 17:32:15 +02:00
except oscerr . NoWorkingCopy :
pass
2008-06-24 11:37:49 +02:00
2008-03-05 00:41:00 +01:00
if len ( args ) > 1 :
package = args [ 1 ]
2011-02-11 16:12:38 +01:00
elif cmd == ' supersede ' :
reqid = args [ 0 ]
supersedid = args [ 1 ]
2012-01-19 11:43:37 +01:00
elif cmd == ' setincident ' :
reqid = args [ 0 ]
incident = args [ 1 ]
2019-05-24 13:22:30 +02:00
elif cmd in [ ' prioritize ' , ' priorize ' ] :
2014-09-11 11:25:24 +02:00
reqid = args [ 0 ]
priority = args [ 1 ]
2018-10-17 15:31:23 +02:00
elif cmd in [ ' log ' , ' add ' , ' show ' , ' decline ' , ' reopen ' , ' clone ' , ' accept ' , ' wipe ' , ' revoke ' , ' checkout ' ,
' co ' , ' approve ' , ' cancelapproval ' ] :
2008-03-05 00:41:00 +01:00
reqid = args [ 0 ]
2010-08-05 15:54:48 +02:00
# clone all packages from a given request
if cmd in [ ' clone ' ] :
2010-10-26 15:34:32 +02:00
# should we force a message?
2013-04-09 12:51:28 +02:00
print ( ' Cloned packages are available in project: %s ' % clone_request ( apiurl , reqid , opts . message ) )
2010-08-05 15:54:48 +02:00
2018-10-17 15:31:23 +02:00
# approve request
elif cmd == ' approve ' or cmd == ' cancelapproval ' :
2022-09-12 13:43:10 +02:00
query = { ' cmd ' : cmd }
2018-10-17 15:31:23 +02:00
url = makeurl ( apiurl , [ ' request ' , reqid ] , query )
r = http_POST ( url , data = opts . message )
print ( ET . parse ( r ) . getroot ( ) . get ( ' code ' ) )
2012-01-19 11:43:37 +01:00
# change incidents
elif cmd == ' setincident ' :
2022-09-12 13:43:10 +02:00
query = { ' cmd ' : ' setincident ' , ' incident ' : incident }
2012-01-19 11:43:37 +01:00
url = makeurl ( apiurl , [ ' request ' , reqid ] , query )
r = http_POST ( url , data = opts . message )
2013-04-09 12:51:28 +02:00
print ( ET . parse ( r ) . getroot ( ) . get ( ' code ' ) )
2012-01-19 11:43:37 +01:00
2014-09-11 11:25:24 +02:00
# change priority
2019-05-24 13:22:30 +02:00
elif cmd in [ ' prioritize ' , ' priorize ' ] :
2022-09-12 13:43:10 +02:00
query = { ' cmd ' : ' setpriority ' , ' priority ' : priority }
2014-09-11 11:25:24 +02:00
url = makeurl ( apiurl , [ ' request ' , reqid ] , query )
r = http_POST ( url , data = opts . message )
print ( ET . parse ( r ) . getroot ( ) . get ( ' code ' ) )
2010-07-30 11:36:17 +02:00
# add new reviewer to existing request
2010-08-05 15:54:48 +02:00
elif cmd in [ ' add ' ] and subcmd == ' review ' :
2022-09-12 13:43:10 +02:00
query = { ' cmd ' : ' addreview ' }
2010-07-30 11:36:17 +02:00
if opts . user :
query [ ' by_user ' ] = opts . user
if opts . group :
query [ ' by_group ' ] = opts . group
2011-01-23 21:21:32 +01:00
if opts . project :
query [ ' by_project ' ] = opts . project
if opts . package :
query [ ' by_package ' ] = opts . package
2010-07-30 11:36:17 +02:00
url = makeurl ( apiurl , [ ' request ' , reqid ] , query )
2010-10-12 11:09:19 +02:00
if not opts . message :
opts . message = edit_message ( )
2010-08-05 10:24:00 +02:00
r = http_POST ( url , data = opts . message )
2013-04-09 12:51:28 +02:00
print ( ET . parse ( r ) . getroot ( ) . get ( ' code ' ) )
2010-07-30 11:36:17 +02:00
2010-05-19 12:50:52 +02:00
# list and approvenew
2010-07-30 11:36:17 +02:00
elif cmd == ' list ' or cmd == ' approvenew ' :
2010-09-07 17:31:07 +02:00
states = ( ' new ' , ' accepted ' , ' revoked ' , ' declined ' , ' review ' , ' superseded ' )
2009-05-17 15:07:55 +02:00
who = ' '
2010-05-19 12:50:52 +02:00
if cmd == ' approvenew ' :
2022-10-20 10:19:43 +02:00
states = ( ' new ' , )
2022-09-15 14:47:38 +02:00
results = get_request_collection ( apiurl , project = project , package = package , states = [ ' new ' ] )
2010-03-13 21:06:18 +01:00
else :
2022-10-20 10:19:43 +02:00
for s in state_list :
if s != ' all ' and s not in states :
raise oscerr . WrongArgs ( ' Unknown state \' %s \' , try one of %s ' % ( s , ' , ' . join ( states ) ) )
2013-05-27 12:16:44 +02:00
if opts . mine :
who = conf . get_apiurl_usr ( apiurl )
if opts . user :
who = opts . user
2022-09-12 13:43:10 +02:00
# FIXME -B not implemented!
2013-05-27 12:16:44 +02:00
if opts . bugowner :
2022-08-04 16:08:47 +02:00
self . _debug ( ' list: option --bugowner ignored: not impl. ' )
2013-05-27 12:16:44 +02:00
if subcmd == ' review ' :
# FIXME: do the review list for the user and for all groups he belong to
2017-08-24 12:01:19 +02:00
results = get_review_list ( apiurl , project , package , who , opts . group , opts . project , opts . package , state_list ,
2023-05-19 21:51:25 +02:00
opts . type , req_states = ( " new " , " review " , " declined " ) )
2013-05-27 12:16:44 +02:00
else :
if opts . involved_projects :
who = who or conf . get_apiurl_usr ( apiurl )
results = get_user_projpkgs_request_list ( apiurl , who , req_state = state_list ,
req_type = opts . type , exclude_projects = opts . exclude_target_project or [ ] )
else :
2022-09-16 09:23:34 +02:00
roles = [ " creator " ] if opts . mine else None
2023-02-07 10:15:09 +01:00
types = [ opts . type ] if opts . type else None
2022-09-15 14:47:38 +02:00
results = get_request_collection (
apiurl , project = project , package = package , user = who ,
2023-02-07 10:15:09 +01:00
states = state_list , types = types , roles = roles )
2010-05-19 12:29:56 +02:00
2011-07-08 15:11:17 +02:00
# Check if project actually exists if result list is empty
if not results :
2013-06-17 16:26:00 +02:00
if project :
2015-08-04 12:51:45 +02:00
msg = ' No results for %(kind)s %(entity)s '
emsg = ' %(kind)s %(entity)s does not exist '
d = { ' entity ' : [ project ] , ' kind ' : ' project ' }
meth = show_project_meta
if package :
d [ ' kind ' ] = ' package '
d [ ' entity ' ] . append ( package )
meth = show_package_meta
2013-06-17 16:26:00 +02:00
try :
2015-08-04 12:51:45 +02:00
entity = d [ ' entity ' ]
d [ ' entity ' ] = ' / ' . join ( entity )
meth ( apiurl , * entity )
print ( msg % d )
2013-06-17 17:37:40 +02:00
except HTTPError :
2015-08-04 12:51:45 +02:00
print ( emsg % d )
2013-06-17 16:26:00 +02:00
else :
print ( ' No results ' )
2011-07-08 15:11:17 +02:00
return
2014-11-11 08:26:08 +01:00
# we must not sort the results here, since the api is doing it already "the right way"
2009-08-21 02:42:51 +02:00
days = opts . days or conf . config [ ' request_list_days ' ]
since = ' '
2009-10-20 16:30:15 +02:00
try :
2014-01-14 11:04:04 +01:00
days = float ( days )
2009-08-21 02:42:51 +02:00
except ValueError :
days = 0
if days > 0 :
2022-09-12 13:43:10 +02:00
since = time . strftime ( ' % Y- % m- %d T % H: % M: % S ' , time . localtime ( time . time ( ) - days * 24 * 3600 ) )
2008-06-27 18:36:36 +02:00
2009-08-20 21:28:05 +02:00
skipped = 0
2022-09-12 13:43:10 +02:00
# bs has received 2009-09-20 a new xquery compare() function
# which allows us to limit the list inside of get_request_list
# That would be much faster for coolo. But counting the remainder
# would not be possible with current xquery implementation.
# Workaround: fetch all, and filter on client side.
2017-08-15 14:37:44 +02:00
2022-09-12 13:43:10 +02:00
# FIXME: date filtering should become implemented on server side
2017-08-15 14:37:44 +02:00
if opts . target_package_filter :
filter_pattern = re . compile ( opts . target_package_filter )
2008-03-05 00:41:00 +01:00
for result in results :
2017-08-15 14:37:44 +02:00
filtered = False
for action in result . actions :
if action . type == ' group ' or not opts . target_package_filter :
continue
2019-07-23 15:51:41 +02:00
if action . tgt_package is not None and not filter_pattern . match ( action . tgt_package ) :
2017-08-15 14:37:44 +02:00
filtered = True
break
if not filtered :
if days == 0 or result . state . when > since or result . state . name == ' new ' :
if ( opts . interactive or conf . config [ ' request_show_interactive ' ] ) and not opts . non_interactive :
ignore_reviews = subcmd != ' review '
request_interactive_review ( apiurl , result , group = opts . group ,
ignore_reviews = ignore_reviews ,
source_buildstatus = source_buildstatus )
else :
print ( result . list_view ( ) , ' \n ' )
2010-09-17 21:03:52 +02:00
else :
2017-08-15 14:37:44 +02:00
skipped + = 1
2009-08-20 21:28:05 +02:00
if skipped :
2013-04-09 12:51:28 +02:00
print ( " There are %d requests older than %s days. \n " % ( skipped , days ) )
2008-03-05 00:41:00 +01:00
2010-05-19 12:50:52 +02:00
if cmd == ' approvenew ' :
2013-04-09 12:51:28 +02:00
print ( " \n *** Approve them all ? [y/n] *** " )
2010-05-19 12:29:56 +02:00
if sys . stdin . read ( 1 ) == " y " :
2016-05-15 17:50:31 +02:00
2010-05-19 12:29:56 +02:00
if not opts . message :
opts . message = edit_message ( )
for result in results :
2013-04-09 12:51:28 +02:00
print ( result . reqid , " : " , end = ' ' )
2010-07-29 17:29:07 +02:00
r = change_request_state ( apiurl ,
2022-09-12 13:43:10 +02:00
result . reqid , ' accepted ' , opts . message or ' ' , force = opts . force )
2013-04-09 12:51:28 +02:00
print ( ' Result of change request state: %s ' % r )
2010-05-19 12:29:56 +02:00
else :
2013-04-09 12:51:28 +02:00
print ( ' Aborted... ' , file = sys . stderr )
2010-05-19 12:29:56 +02:00
raise oscerr . UserAbort ( )
2008-08-19 16:18:05 +02:00
elif cmd == ' log ' :
2010-07-29 17:29:07 +02:00
for l in get_request_log ( apiurl , reqid ) :
2013-04-09 12:51:28 +02:00
print ( l )
2008-08-19 16:18:05 +02:00
2008-03-05 00:41:00 +01:00
# show
elif cmd == ' show ' :
2010-08-03 09:34:33 +02:00
r = get_request ( apiurl , reqid )
2009-04-22 13:02:32 +02:00
if opts . brief :
2013-04-09 12:51:28 +02:00
print ( r . list_view ( ) )
2011-01-30 14:24:21 +01:00
elif opts . edit :
if not r . get_actions ( ' submit ' ) :
2022-09-12 13:43:10 +02:00
raise oscerr . WrongOptions ( ' \' --edit \' not possible '
' (request has no \' submit \' action) ' )
2011-01-30 14:24:21 +01:00
return request_interactive_review ( apiurl , r , ' e ' )
2010-03-23 16:21:09 +01:00
elif ( opts . interactive or conf . config [ ' request_show_interactive ' ] ) and not opts . non_interactive :
2012-10-26 15:19:00 +02:00
ignore_reviews = subcmd != ' review '
2016-02-10 18:19:22 +01:00
return request_interactive_review ( apiurl , r , group = opts . group ,
ignore_reviews = ignore_reviews ,
2016-02-10 18:27:35 +01:00
source_buildstatus = source_buildstatus )
2009-04-22 13:02:32 +02:00
else :
2013-04-09 12:51:28 +02:00
print ( r )
2015-10-19 13:14:53 +02:00
print_comments ( apiurl , ' request ' , reqid )
2016-02-10 18:27:35 +01:00
if source_buildstatus :
2011-01-29 18:47:26 +01:00
sr_actions = r . get_actions ( ' submit ' )
if not sr_actions :
2022-09-12 13:43:10 +02:00
raise oscerr . WrongOptions ( ' \' --source-buildstatus \' not possible '
' (request has no \' submit \' actions) ' )
2011-01-29 18:47:26 +01:00
for action in sr_actions :
2013-04-09 12:51:28 +02:00
print ( ' Buildstatus for \' %s / %s \' : ' % ( action . src_project , action . src_package ) )
print ( ' \n ' . join ( get_results ( apiurl , action . src_project , action . src_package ) ) )
2011-01-29 17:24:45 +01:00
if opts . diff :
2019-09-11 17:05:32 +02:00
diff = b ' '
2008-03-20 21:11:30 +01:00
try :
2010-09-02 10:29:28 +02:00
# works since OBS 2.1
2020-02-19 17:07:35 +01:00
diff = request_diff ( apiurl , reqid , opts . superseded_request )
2013-04-09 14:03:17 +02:00
except HTTPError as e :
2020-02-19 17:07:35 +01:00
if e . code == 404 :
# Any referenced object does not exist, eg. the superseded request
root = ET . fromstring ( e . read ( ) )
summary = root . find ( ' summary ' )
print ( summary . text , file = sys . stderr )
raise oscerr . WrongOptions ( " Object does not exist " )
2010-09-02 10:29:28 +02:00
# for OBS 2.0 and before
2011-01-29 17:47:28 +01:00
sr_actions = r . get_actions ( ' submit ' )
2015-06-11 11:05:08 +02:00
if not r . get_actions ( ' submit ' ) and not r . get_actions ( ' maintenance_incident ' ) and not r . get_actions ( ' maintenance_release ' ) :
raise oscerr . WrongOptions ( ' \' --diff \' not possible (request has no supported actions) ' )
2011-01-29 17:24:45 +01:00
for action in sr_actions :
2019-07-17 10:34:20 +02:00
diff + = b ' old: %s / %s \n new: %s / %s \n ' % ( action . src_project . encode ( ) , action . src_package . encode ( ) ,
2022-09-12 13:43:10 +02:00
action . tgt_project . encode ( ) , action . tgt_package . encode ( ) )
2011-01-29 17:24:45 +01:00
diff + = submit_action_diff ( apiurl , action )
2019-07-17 10:34:20 +02:00
diff + = b ' \n \n '
2023-07-11 21:02:21 +02:00
run_pager ( highlight_diff ( diff ) , tmp_suffix = " " )
2008-03-05 00:41:00 +01:00
2009-09-16 23:39:45 +02:00
# checkout
2022-10-08 13:24:08 +02:00
elif cmd in ( ' checkout ' , ' co ' ) :
2010-07-29 17:29:07 +02:00
r = get_request ( apiurl , reqid )
2012-05-04 17:18:46 +02:00
sr_actions = r . get_actions ( ' submit ' , ' maintenance_release ' )
2011-01-29 18:47:26 +01:00
if not sr_actions :
raise oscerr . WrongArgs ( ' \' checkout \' not possible (request has no \' submit \' actions) ' )
for action in sr_actions :
2022-09-12 13:43:10 +02:00
checkout_package ( apiurl , action . src_project , action . src_package ,
2023-02-08 11:46:16 +01:00
action . src_rev , expand_link = True , prj_dir = Path ( action . src_project ) )
2009-08-19 13:28:16 +02:00
else :
2022-04-20 19:22:35 +02:00
state_map = { ' reopen ' : ' new ' , ' accept ' : ' accepted ' , ' decline ' : ' declined ' , ' wipe ' : ' deleted ' , ' revoke ' : ' revoked ' , ' supersede ' : ' superseded ' }
2009-11-17 17:59:17 +01:00
# Change review state only
if subcmd == ' review ' :
2010-08-18 17:58:42 +02:00
if not opts . message :
2013-05-27 12:16:44 +02:00
opts . message = edit_message ( )
2022-10-08 13:24:08 +02:00
if cmd in ( ' accept ' , ' decline ' , ' reopen ' , ' supersede ' ) :
2011-04-26 17:18:49 +02:00
if opts . user or opts . group or opts . project or opts . package :
2011-08-18 11:40:21 +02:00
r = change_review_state ( apiurl , reqid , state_map [ cmd ] , opts . user , opts . group , opts . project ,
2022-09-12 13:43:10 +02:00
opts . package , opts . message or ' ' , supersed = supersedid )
2013-04-09 12:51:28 +02:00
print ( r )
2011-04-26 17:18:49 +02:00
else :
rq = get_request ( apiurl , reqid )
2022-10-08 13:24:08 +02:00
if rq . state . name in ( ' new ' , ' review ' ) :
2011-08-18 11:40:21 +02:00
for review in rq . reviews : # try all, but do not fail on error
try :
r = change_review_state ( apiurl , reqid , state_map [ cmd ] , review . by_user , review . by_group ,
2022-09-12 13:43:10 +02:00
review . by_project , review . by_package , opts . message or ' ' , supersed = supersedid )
2013-04-09 12:51:28 +02:00
print ( r )
2013-04-09 14:03:17 +02:00
except HTTPError as e :
2014-01-30 11:52:24 +01:00
body = e . read ( )
if e . code in [ 403 ] :
2022-04-20 19:22:35 +02:00
if review . by_user :
print ( ' No permission on review by user %s : ' % review . by_user )
if review . by_group :
print ( ' No permission on review by group %s ' % review . by_group )
if review . by_package :
print ( ' No permission on review by package %s / %s ' % ( review . by_project , review . by_package ) )
elif review . by_project :
print ( ' No permission on review by project %s ' % review . by_project )
2015-07-01 09:47:53 +02:00
print ( e , file = sys . stderr )
2011-08-18 11:40:21 +02:00
else :
2013-04-09 12:51:28 +02:00
print ( ' Request is closed, please reopen the request first before changing any reviews. ' )
2009-11-17 17:59:17 +01:00
# Change state of entire request
2011-02-11 16:12:38 +01:00
elif cmd in [ ' reopen ' , ' accept ' , ' decline ' , ' wipe ' , ' revoke ' , ' supersede ' ] :
2010-08-18 17:58:42 +02:00
rq = get_request ( apiurl , reqid )
2013-05-06 18:44:14 +02:00
if opts . or_revoke :
if rq . state . name == " declined " :
2013-05-27 12:41:50 +02:00
cmd = " revoke "
2013-05-06 18:44:14 +02:00
elif rq . state . name != " new " and rq . state . name != " review " :
2013-02-28 10:28:56 +01:00
return 0
2010-08-18 17:58:42 +02:00
if rq . state . name == state_map [ cmd ] :
2022-09-12 13:43:10 +02:00
repl = raw_input ( " \n *** The state of the request (# %s ) is already ' %s ' . Change state anyway? [y/n] *** " %
2013-05-27 13:03:46 +02:00
( reqid , rq . state . name ) )
2010-08-18 17:58:42 +02:00
if repl . lower ( ) != ' y ' :
2013-04-09 12:51:28 +02:00
print ( ' Aborted... ' , file = sys . stderr )
2010-08-18 17:58:42 +02:00
raise oscerr . UserAbort ( )
2016-05-15 17:50:31 +02:00
2010-08-18 17:58:42 +02:00
if not opts . message :
2010-11-14 18:32:02 +01:00
tmpl = change_request_state_template ( rq , state_map [ cmd ] )
opts . message = edit_message ( template = tmpl )
2013-05-06 18:44:14 +02:00
try :
r = change_request_state ( apiurl ,
2023-09-28 14:50:20 +02:00
reqid , state_map [ cmd ] , opts . message or ' ' , supersed = supersedid , force = opts . force , keep_packages_locked = opts . keep_packages_locked )
2013-05-06 18:44:14 +02:00
print ( ' Result of change request state: %s ' % r )
except HTTPError as e :
2014-01-30 11:52:24 +01:00
print ( e , file = sys . stderr )
2014-06-08 21:33:06 +02:00
details = e . hdrs . get ( ' X-Opensuse-Errorcode ' )
2014-02-04 14:35:30 +01:00
if details :
print ( details , file = sys . stderr )
2014-05-15 18:09:27 +02:00
root = ET . fromstring ( e . read ( ) )
summary = root . find ( ' summary ' )
2022-09-12 14:23:47 +02:00
if summary is not None :
2014-05-15 18:09:27 +02:00
print ( summary . text )
2013-05-06 18:44:14 +02:00
if opts . or_revoke :
2022-09-12 13:43:10 +02:00
if e . code in [ 400 , 403 , 404 , 500 ] :
2013-05-06 18:44:14 +02:00
print ( ' Revoking it ... ' )
r = change_request_state ( apiurl ,
2022-09-12 13:43:10 +02:00
reqid , ' revoked ' , opts . message or ' ' , supersed = supersedid , force = opts . force )
2014-05-21 15:45:07 +02:00
sys . exit ( 1 )
2012-06-26 17:13:33 +02:00
# check for devel instances after accepted requests
if cmd in [ ' accept ' ] :
2022-10-12 15:20:06 +02:00
print ( rq )
if opts . interactive :
_private . forward_request ( apiurl , rq , interactive = True )
2012-06-26 17:13:33 +02:00
sr_actions = rq . get_actions ( ' submit ' )
for action in sr_actions :
u = makeurl ( apiurl , [ ' /search/package ' ] , {
2022-04-20 19:22:35 +02:00
' match ' : " ([devel[@project= ' %s ' and @package= ' %s ' ]]) " % ( action . tgt_project , action . tgt_package )
2022-09-12 13:43:10 +02:00
} )
2012-06-26 17:13:33 +02:00
f = http_GET ( u )
root = ET . parse ( f ) . getroot ( )
2013-09-25 15:36:54 +02:00
if root . findall ( ' package ' ) and not opts . no_devel :
2013-05-27 12:16:44 +02:00
for node in root . findall ( ' package ' ) :
project = node . get ( ' project ' )
package = node . get ( ' name ' )
# skip it when this is anyway a link to me
link_url = makeurl ( apiurl , [ ' source ' , project , package ] )
links_to_project = links_to_package = None
try :
file = http_GET ( link_url )
root = ET . parse ( file ) . getroot ( )
link_node = root . find ( ' linkinfo ' )
2022-08-29 12:56:57 +02:00
if link_node is not None :
2013-05-27 12:16:44 +02:00
links_to_project = link_node . get ( ' project ' ) or project
links_to_package = link_node . get ( ' package ' ) or package
except HTTPError as e :
if e . code != 404 :
print ( ' Cannot get list of files for %s / %s : %s ' % ( project , package , e ) , file = sys . stderr )
except SyntaxError as e :
print ( ' Cannot parse list of files for %s / %s : %s ' % ( project , package , e ) , file = sys . stderr )
2013-05-27 12:41:50 +02:00
if links_to_project == action . tgt_project and links_to_package == action . tgt_package :
2013-05-27 12:16:44 +02:00
# links to my request target anyway, no need to forward submit
continue
print ( project , end = ' ' )
if package != action . tgt_package :
print ( " / " , package , end = ' ' )
repl = raw_input ( ' \n Forward this submit to it? ([y]/n) ' )
if repl . lower ( ) == ' y ' or repl == ' ' :
( supersede , reqs ) = check_existing_requests ( apiurl , action . tgt_project , action . tgt_package ,
project , package )
2017-04-12 12:58:23 +02:00
msg = " %s (forwarded request %s from %s ) " % ( rq . description , reqid , rq . creator )
2013-05-27 12:16:44 +02:00
rid = create_submit_request ( apiurl , action . tgt_project , action . tgt_package ,
2020-11-28 17:46:44 +01:00
project , package , msg )
2013-05-27 12:16:44 +02:00
print ( msg )
print ( " New request # " , rid )
for req in reqs :
change_request_state ( apiurl , req . reqid , ' superseded ' ,
' superseded by %s ' % rid , rid )
2012-06-26 17:13:33 +02:00
2009-04-09 10:21:12 +02:00
@cmdln.option ( ' -r ' , ' --revision ' , metavar = ' rev ' ,
help = ' use the specified revision. ' )
2010-09-07 12:14:13 +02:00
@cmdln.option ( ' -R ' , ' --use-plain-revision ' , action = ' store_true ' ,
2014-03-03 22:44:30 +01:00
help = ' Do not expand revision the specified or latest rev ' )
2009-06-18 11:18:17 +02:00
@cmdln.option ( ' -u ' , ' --unset ' , action = ' store_true ' ,
help = ' remove revision in link, it will point always to latest revision ' )
2009-04-09 10:21:12 +02:00
def do_setlinkrev ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Updates a revision number in a source link
2009-05-18 16:50:43 +02:00
2009-04-09 10:21:12 +02:00
This command adds or updates a specified revision number in a source link .
The current revision of the source is used , if no revision number is specified .
2009-05-18 16:50:43 +02:00
usage :
2009-04-09 10:21:12 +02:00
osc setlinkrev
2009-06-18 11:18:17 +02:00
osc setlinkrev PROJECT [ PACKAGE ]
2009-04-09 10:21:12 +02:00
"""
2010-07-29 17:29:07 +02:00
apiurl = self . get_api_url ( )
2022-11-09 11:54:14 +01:00
2011-02-22 17:43:05 +01:00
rev = parseRevisionOption ( opts . revision ) [ 0 ] or ' '
if opts . unset :
rev = None
2022-11-09 11:54:14 +01:00
args = list ( args )
2022-10-07 17:25:33 +02:00
if not args :
p = Package ( Path . cwd ( ) )
2009-04-09 10:21:12 +02:00
project = p . prjname
package = p . name
2022-11-09 11:54:14 +01:00
assert apiurl == p . apiurl
2009-04-09 13:44:32 +02:00
if not p . islink ( ) :
2009-04-16 10:13:55 +02:00
sys . exit ( ' Local directory is no checked out source link package, aborting ' )
2009-04-09 10:21:12 +02:00
else :
2022-11-09 11:54:14 +01:00
project , package = pop_project_package_from_args (
args , default_project = " . " , default_package = " . " , package_is_optional = True
)
if opts . revision and not package :
# It is highly unlikely that all links for all packages in a project should be set to the same revision.
self . argparse_error ( " The --revision option requires to specify a package " )
2009-04-09 10:21:12 +02:00
2009-06-18 11:18:17 +02:00
if package :
2011-02-22 17:43:05 +01:00
packages = [ package ]
2009-06-18 11:18:17 +02:00
else :
packages = meta_get_packagelist ( apiurl , project )
for p in packages :
2022-11-09 11:54:14 +01:00
try :
rev = set_link_rev ( apiurl , project , p , revision = rev , expand = not opts . use_plain_revision )
except HTTPError as e :
if e . code != 404 :
raise
print ( f " WARNING: Package { project } / { p } has no link " , file = sys . stderr )
continue
2011-11-17 21:33:57 +01:00
if rev is None :
2022-11-09 11:54:14 +01:00
print ( f " Removed link revision from package { project } / { p } " )
2011-11-17 21:33:57 +01:00
else :
2022-11-09 11:54:14 +01:00
print ( f " Set link revision of package { project } / { p } to { rev } " )
2009-04-09 10:21:12 +02:00
2010-01-11 16:36:33 +01:00
def do_linktobranch ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Convert a package containing a classic link with patch to a branch
2010-01-11 16:36:33 +01:00
This command tells the server to convert a _link with or without a project . diff
to a branch . This is a full copy with a _link file pointing to the branched place .
usage :
2023-01-02 14:47:23 +01:00
osc linktobranch # from a package working copy
2010-01-14 12:24:48 +01:00
osc linktobranch PROJECT PACKAGE
2010-01-11 16:36:33 +01:00
"""
2010-04-30 17:13:21 +02:00
apiurl = self . get_api_url ( )
2023-01-02 14:47:23 +01:00
# assume we're in a working copy if no args were specfied
update_working_copy = not args
args = list ( args )
project , package = pop_project_package_from_args (
args , default_project = " . " , default_package = " . " , package_is_optional = False
)
ensure_no_remaining_args ( args )
2010-01-11 16:36:33 +01:00
2010-01-14 12:24:48 +01:00
link_to_branch ( apiurl , project , package )
2023-01-02 14:47:23 +01:00
if update_working_copy :
pac = Package ( Path . cwd ( ) )
2010-02-18 14:14:31 +01:00
pac . update ( rev = pac . latest_rev ( ) )
2010-01-11 16:36:33 +01:00
2011-02-11 17:38:59 +01:00
@cmdln.option ( ' -m ' , ' --message ' , metavar = ' TEXT ' ,
help = ' specify message TEXT ' )
2011-02-11 17:11:44 +01:00
def do_detachbranch ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Replace a link with its expanded sources
2011-02-11 17:11:44 +01:00
If a package is a link it is replaced with its expanded sources . The link
does not exist anymore .
usage :
2023-01-02 14:53:23 +01:00
osc detachbranch # from a package working copy
2011-02-11 17:11:44 +01:00
osc detachbranch PROJECT PACKAGE
"""
apiurl = self . get_api_url ( )
2023-01-02 14:53:23 +01:00
args = list ( args )
project , package = pop_project_package_from_args (
args , default_project = " . " , default_package = " . " , package_is_optional = False
)
ensure_no_remaining_args ( args )
2022-07-07 15:38:14 +02:00
2011-02-11 17:11:44 +01:00
try :
2011-02-11 17:38:59 +01:00
copy_pac ( apiurl , project , package , apiurl , project , package , expand = True , comment = opts . message )
2013-04-09 14:03:17 +02:00
except HTTPError as e :
2011-02-11 17:11:44 +01:00
root = ET . fromstring ( show_files_meta ( apiurl , project , package , ' latest ' , expand = False ) )
li = Linkinfo ( )
li . read ( root . find ( ' linkinfo ' ) )
if li . islink ( ) and li . haserror ( ) :
2021-09-14 14:09:27 +02:00
try :
show_package_meta ( apiurl , li . project , li . package )
except HTTPError as e :
if e . code == 404 :
print ( " Link target got removed, dropping link. WARNING: latest submissions in link target might be lost! " )
delete_files ( apiurl , project , package , [ ' _link ' ] )
else :
raise oscerr . LinkExpandError ( project , package , li . error )
2011-02-11 17:38:59 +01:00
elif not li . islink ( ) :
2013-04-09 12:51:28 +02:00
print ( ' package \' %s / %s \' is no link ' % ( project , package ) , file = sys . stderr )
2011-02-11 17:38:59 +01:00
else :
raise e
2011-02-11 17:11:44 +01:00
2009-05-13 09:59:01 +02:00
@cmdln.option ( ' -C ' , ' --cicount ' , choices = [ ' add ' , ' copy ' , ' local ' ] ,
help = ' cicount attribute in the link, known values are add, copy, and local, default in buildservice is currently add. ' )
2009-06-18 11:18:17 +02:00
@cmdln.option ( ' -c ' , ' --current ' , action = ' store_true ' ,
help = ' link fixed against current revision. ' )
2008-06-26 12:47:58 +02:00
@cmdln.option ( ' -r ' , ' --revision ' , metavar = ' rev ' ,
help = ' link the specified revision. ' )
2009-06-15 17:19:16 +02:00
@cmdln.option ( ' -f ' , ' --force ' , action = ' store_true ' ,
help = ' overwrite an existing link file if it is there. ' )
2022-11-08 15:01:37 +01:00
@cmdln.option ( ' --disable-build ' , action = ' store_true ' ,
help = ' disable building of the linked package ' )
2009-12-21 14:24:33 +01:00
@cmdln.option ( ' -d ' , ' --disable-publish ' , action = ' store_true ' ,
help = ' disable publishing of the linked package ' )
2011-12-15 15:12:13 +01:00
@cmdln.option ( ' -N ' , ' --new-package ' , action = ' store_true ' ,
help = ' create a link to a not yet existing package ' )
2007-04-25 01:00:12 +02:00
def do_linkpac ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
" Link " a package to another package
2009-05-18 16:50:43 +02:00
2007-04-25 01:00:12 +02:00
A linked package is a clone of another package , but plus local
modifications . It can be cross - project .
2006-08-07 12:08:54 +02:00
2022-12-20 16:57:36 +01:00
The TARGET_PACKAGE name is optional ; the source packages ' name will be used if
TARGET_PACKAGE is omitted .
2006-08-07 12:08:54 +02:00
2022-12-20 16:57:36 +01:00
Afterwards , you will want to ' checkout TARGET_PROJECT TARGET_PACKAGE ' .
2006-08-07 12:08:54 +02:00
2007-04-25 01:00:12 +02:00
To add a patch , add the patch as file and add it to the _link file .
You can also specify text which will be inserted at the top of the spec file .
2006-08-07 12:08:54 +02:00
2007-04-25 01:00:12 +02:00
See the examples in the _link file .
2006-08-07 12:08:54 +02:00
2011-12-12 12:57:13 +01:00
NOTE : In case you want to fix or update another package , you should use the ' branch '
command . A branch has correct repositories ( and a link ) setup up by default and
will be cleaned up automatically after it was submitted back .
2010-07-21 09:46:54 +02:00
2009-05-18 16:50:43 +02:00
usage :
2022-12-20 16:57:36 +01:00
osc linkpac PROJECT PACKAGE TARGET_PROJECT [ TARGET_PACKAGE ]
osc linkpac TARGET_PROJECT [ TARGET_PACKAGE ] # from a package checkout
2007-04-25 01:00:12 +02:00
"""
2010-07-29 17:29:07 +02:00
apiurl = self . get_api_url ( )
2007-06-26 15:17:38 +02:00
2022-12-20 16:57:36 +01:00
args = list ( args )
src_project , src_package , tgt_project , tgt_package = pop_project_package_targetproject_targetpackage_from_args (
2023-01-12 10:38:38 +01:00
args ,
default_project = " . " ,
default_package = " . " ,
target_package_is_optional = True ,
2022-12-20 16:57:36 +01:00
)
ensure_no_remaining_args ( args )
if not tgt_package :
tgt_package = src_package
2006-08-07 12:08:54 +02:00
2008-06-26 12:47:58 +02:00
rev , dummy = parseRevisionOption ( opts . revision )
2012-03-02 15:44:15 +01:00
vrev = None
2008-06-26 12:47:58 +02:00
2022-12-20 16:57:36 +01:00
if src_project == tgt_project and not opts . cicount :
2009-11-02 22:02:58 +01:00
# in this case, the user usually wants to build different spec
# files from the same source
opts . cicount = " copy "
2011-12-15 15:12:13 +01:00
if opts . current and not opts . new_package :
2014-03-03 22:44:30 +01:00
rev , vrev = show_upstream_rev_vrev ( apiurl , src_project , src_package , expand = True )
2022-08-29 12:56:57 +02:00
if rev is None or len ( rev ) < 32 :
2012-03-02 15:44:15 +01:00
# vrev is only needed for srcmd5 and OBS instances < 2.1.17 do not support it
vrev = None
2009-04-08 13:48:34 +02:00
2022-11-08 15:01:37 +01:00
link_pac (
2022-12-20 16:57:36 +01:00
src_project , src_package , tgt_project , tgt_package , opts . force , rev , opts . cicount ,
2022-11-08 15:01:37 +01:00
opts . disable_publish , opts . new_package , vrev ,
disable_build = opts . disable_build ,
)
2006-09-21 16:33:24 +02:00
2010-07-20 14:48:27 +02:00
@cmdln.option ( ' --nosources ' , action = ' store_true ' ,
help = ' ignore source packages when copying build results to destination project ' )
2009-07-31 16:31:20 +02:00
@cmdln.option ( ' -m ' , ' --map-repo ' , metavar = ' SRC=TARGET[,SRC=TARGET] ' ,
help = ' Allows repository mapping(s) to be given as SRC=TARGET[,SRC=TARGET] ' )
2009-12-21 14:24:33 +01:00
@cmdln.option ( ' -d ' , ' --disable-publish ' , action = ' store_true ' ,
help = ' disable publishing of the aggregated package ' )
2007-10-30 14:45:54 +01:00
def do_aggregatepac ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
" Aggregate " a package to another package
2009-05-18 16:50:43 +02:00
2008-07-17 19:46:21 +02:00
Aggregation of a package means that the build results ( binaries ) of a
package are basically copied into another project .
This can be used to make packages available from building that are
needed in a project but available only in a different project . Note
2009-05-18 16:50:43 +02:00
that this is done at the expense of disk space . See
2010-12-03 12:39:18 +01:00
http : / / en . opensuse . org / openSUSE : Build_Service_Tips_and_Tricks #link_and_aggregate
2008-07-17 19:46:21 +02:00
for more information .
2007-10-30 14:45:54 +01:00
The DESTPAC name is optional ; the source packages ' name will be used if
DESTPAC is omitted .
2009-05-18 16:50:43 +02:00
usage :
2022-03-02 14:38:21 +01:00
osc aggregatepac SOURCEPRJ SOURCEPAC [ : FLAVOR ] DESTPRJ [ DESTPAC ]
2007-10-30 14:45:54 +01:00
"""
2023-01-02 15:05:35 +01:00
args = list ( args )
src_project , src_package , tgt_project , tgt_package = pop_project_package_targetproject_targetpackage_from_args (
args , target_package_is_optional = True ,
)
ensure_no_remaining_args ( args )
2007-10-30 14:45:54 +01:00
2023-01-02 15:05:35 +01:00
if not tgt_package :
tgt_package = src_package
2009-07-31 16:31:20 +02:00
repo_map = { }
if opts . map_repo :
for pair in opts . map_repo . split ( ' , ' ) :
src_tgt = pair . split ( ' = ' )
if len ( src_tgt ) != 2 :
2010-01-09 14:25:41 +01:00
raise oscerr . WrongOptions ( ' map " %s " must be SRC=TARGET[,SRC=TARGET] ' % opts . map_repo )
2009-07-31 16:31:20 +02:00
repo_map [ src_tgt [ 0 ] ] = src_tgt [ 1 ]
2023-01-02 15:05:35 +01:00
aggregate_pac ( src_project , src_package , tgt_project , tgt_package , repo_map , opts . disable_publish , opts . nosources )
2006-09-21 16:33:24 +02:00
2008-04-02 16:36:23 +02:00
@cmdln.option ( ' -c ' , ' --client-side-copy ' , action = ' store_true ' ,
help = ' do a (slower) client-side copy ' )
2008-04-30 14:28:25 +02:00
@cmdln.option ( ' -k ' , ' --keep-maintainers ' , action = ' store_true ' ,
help = ' keep original maintainers. Default is remove all and replace with the one calling the script. ' )
2011-11-21 12:33:32 +01:00
@cmdln.option ( ' -K ' , ' --keep-link ' , action = ' store_true ' ,
2018-09-07 16:48:44 +02:00
help = ' If the target package is a link, the link is kept, but may be updated. If the source package is a link, its expanded version is considered. ' )
2009-03-11 16:23:23 +01:00
@cmdln.option ( ' -d ' , ' --keep-develproject ' , action = ' store_true ' ,
help = ' keep develproject tag in the package metadata ' )
2009-05-14 13:50:53 +02:00
@cmdln.option ( ' -r ' , ' --revision ' , metavar = ' rev ' ,
2013-06-21 15:11:20 +02:00
help = ' copy the specified revision. ' )
2007-05-04 23:51:54 +02:00
@cmdln.option ( ' -t ' , ' --to-apiurl ' , metavar = ' URL ' ,
help = ' URL of destination api server. Default is the source api server. ' )
2009-05-14 13:50:53 +02:00
@cmdln.option ( ' -m ' , ' --message ' , metavar = ' TEXT ' ,
help = ' specify message TEXT ' )
2009-03-31 00:17:18 +02:00
@cmdln.option ( ' -e ' , ' --expand ' , action = ' store_true ' ,
help = ' if the source package is a link then copy the expanded version of the link ' )
2007-04-25 01:00:12 +02:00
def do_copypac ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Copy a package
2006-09-21 16:33:24 +02:00
2009-05-18 16:50:43 +02:00
A way to copy package to somewhere else .
2008-04-02 16:36:23 +02:00
It can be done across buildservice instances , if the - t option is used .
2010-08-11 22:42:16 +02:00
In that case , a client - side copy and link expansion are implied .
2008-04-02 16:36:23 +02:00
Using - - client - side - copy always involves downloading all files , and
uploading them to the target .
2006-09-21 16:33:24 +02:00
2007-04-25 01:00:12 +02:00
The DESTPAC name is optional ; the source packages ' name will be used if
DESTPAC is omitted .
2006-09-21 16:33:24 +02:00
2022-10-07 17:25:33 +02:00
If SOURCEPRJ or DESTPRJ is ' . ' it will be expanded to the PRJ of the current
directory .
2009-05-18 16:50:43 +02:00
usage :
2007-04-25 01:00:12 +02:00
osc copypac SOURCEPRJ SOURCEPAC DESTPRJ [ DESTPAC ]
"""
2023-01-02 15:21:45 +01:00
args = list ( args )
src_project , src_package , tgt_project , tgt_package = pop_project_package_targetproject_targetpackage_from_args (
args , target_package_is_optional = True ,
)
ensure_no_remaining_args ( args )
2006-09-21 16:33:24 +02:00
2023-01-02 15:21:45 +01:00
if not tgt_package :
tgt_package = src_package
2006-09-21 16:33:24 +02:00
2007-05-04 23:51:54 +02:00
src_apiurl = conf . config [ ' apiurl ' ]
if opts . to_apiurl :
2023-10-23 22:14:32 +02:00
tgt_apiurl = conf . config . apiurl_aliases . get ( opts . to_apiurl , opts . to_apiurl )
2007-05-04 23:51:54 +02:00
else :
2023-01-02 15:21:45 +01:00
tgt_apiurl = src_apiurl
2007-05-04 23:51:54 +02:00
2023-01-02 15:21:45 +01:00
if src_apiurl != tgt_apiurl :
2008-04-02 16:36:23 +02:00
opts . client_side_copy = True
2010-08-11 22:42:16 +02:00
opts . expand = True
2008-03-17 22:46:42 +01:00
2023-01-02 15:21:45 +01:00
rev , _ = parseRevisionOption ( opts . revision )
2009-05-14 13:50:53 +02:00
if opts . message :
2022-07-07 15:38:14 +02:00
comment = opts . message
2009-07-15 20:53:47 +02:00
else :
2023-01-26 11:04:00 +01:00
src_rev = rev or show_upstream_rev ( src_apiurl , src_project , src_package )
comment = ' osc copypac from project: %s package: %s revision: %s ' % ( src_project , src_package , src_rev )
2011-11-25 13:05:41 +01:00
if opts . keep_link :
2013-05-27 12:16:44 +02:00
comment + = " , using keep-link "
2011-11-25 13:05:41 +01:00
if opts . expand :
2013-05-27 12:16:44 +02:00
comment + = " , using expand "
2011-11-25 13:05:41 +01:00
if opts . client_side_copy :
2013-05-27 12:16:44 +02:00
comment + = " , using client side copy "
2009-05-14 13:50:53 +02:00
2009-05-18 16:50:43 +02:00
r = copy_pac ( src_apiurl , src_project , src_package ,
2023-01-02 15:21:45 +01:00
tgt_apiurl , tgt_project , tgt_package ,
2008-04-30 14:28:25 +02:00
client_side_copy = opts . client_side_copy ,
2009-03-11 16:23:23 +01:00
keep_maintainers = opts . keep_maintainers ,
2009-03-31 00:17:18 +02:00
keep_develproject = opts . keep_develproject ,
2009-05-14 13:50:53 +02:00
expand = opts . expand ,
revision = rev ,
2011-11-21 12:33:32 +01:00
comment = comment ,
keep_link = opts . keep_link )
2018-12-13 15:17:29 +01:00
print ( decode_it ( r ) )
2013-07-08 15:58:41 +02:00
@cmdln.option ( ' -r ' , ' --repo ' , metavar = ' REPO ' ,
help = ' Release only binaries from the specified repository ' )
@cmdln.option ( ' --target-project ' , metavar = ' TARGETPROJECT ' ,
help = ' Release only to specified project ' )
@cmdln.option ( ' --target-repository ' , metavar = ' TARGETREPOSITORY ' ,
help = ' Release only to specified repository ' )
2014-03-05 16:03:23 +01:00
@cmdln.option ( ' --set-release ' , metavar = ' RELEASETAG ' ,
help = ' rename binaries during release using this release tag ' )
2018-10-31 03:18:08 +01:00
@cmdln.option ( ' --no-delay ' , action = ' store_true ' ,
help = " Don ' t put the release job in a queue to be run later, but immediately run it. Thus the next call to osc prjresult will reflect it. Otherwise there is no way to know if it is finished or didn ' t start yet. " )
2013-07-08 15:58:41 +02:00
def do_release ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Release sources and binaries
2013-07-08 15:58:41 +02:00
This command is used to transfer sources and binaries without rebuilding them .
2018-10-31 14:22:11 +01:00
It requires defined release targets set to trigger = " manual " .
2013-07-08 15:58:41 +02:00
usage :
2022-11-10 10:29:14 +01:00
osc release [ PROJECT [ PACKAGE ] ]
2013-07-08 15:58:41 +02:00
"""
apiurl = self . get_api_url ( )
2022-11-10 10:29:14 +01:00
args = list ( args )
project , package = pop_project_package_from_args (
args , default_project = " . " , default_package = " . " , package_is_optional = True
)
2013-07-08 15:58:41 +02:00
2022-11-10 10:29:14 +01:00
_private . release (
apiurl ,
project = project ,
package = package ,
repository = opts . repo ,
target_project = opts . target_project ,
target_repository = opts . target_repository ,
set_release_to = opts . set_release ,
delayed = not opts . no_delay ,
print_to = " stdout " ,
)
2006-08-11 12:37:29 +02:00
2011-03-07 19:45:44 +01:00
@cmdln.option ( ' -m ' , ' --message ' , metavar = ' TEXT ' ,
2020-08-05 21:17:30 +02:00
help = ' specify message TEXT ' )
@cmdln.option ( ' -p ' , ' --package ' , metavar = ' PKG ' , action = ' append ' ,
help = ' specify packages to release ' )
2011-03-07 19:45:44 +01:00
def do_releaserequest ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Create a release request
2011-03-07 19:45:44 +01:00
2020-08-05 21:17:30 +02:00
For maintenance incident projects :
2011-03-07 19:45:44 +01:00
2019-05-24 13:42:47 +02:00
This command is used by the maintenance team to start the release process of a maintenance update .
2011-03-07 19:45:44 +01:00
This includes usually testing based on the defined reviewers of the update project .
2020-08-05 21:17:30 +02:00
[ See https : / / openbuildservice . org / help / manuals / obs - user - guide / cha . obs . maintenance_setup . html
for information on this topic . ]
For normal projects :
This command is used to transfer sources and binaries without rebuilding them .
It requires defined release targets set to trigger = " manual " .
[ See https : / / openbuildservice . org / help / manuals / obs - user - guide / cha . obs . request_and_review_system . html
for information on this topic . ]
2011-03-07 19:45:44 +01:00
usage :
2020-08-05 21:17:30 +02:00
osc releaserequest [ - p package ] [ SOURCEPROJECT ]
2011-03-07 19:45:44 +01:00
"""
2016-05-15 17:50:31 +02:00
2011-03-07 19:45:44 +01:00
# FIXME: additional parameters can be a certain repo list to create a partitial release
args = slash_split ( args )
apiurl = self . get_api_url ( )
source_project = None
if len ( args ) > 1 :
raise oscerr . WrongArgs ( ' Too many arguments. ' )
2022-10-07 17:25:33 +02:00
if len ( args ) == 0 and is_project_dir ( Path . cwd ( ) ) :
source_project = store_read_project ( Path . cwd ( ) )
2011-03-07 19:45:44 +01:00
elif len ( args ) == 0 :
raise oscerr . WrongArgs ( ' Too few arguments. ' )
if len ( args ) > 0 :
2022-05-10 14:49:21 +02:00
source_project = self . _process_project_name ( args [ 0 ] )
2011-03-07 19:45:44 +01:00
2020-08-05 21:17:30 +02:00
f = show_project_meta ( apiurl , source_project )
root = ET . fromstring ( b ' ' . join ( f ) )
2011-03-07 19:45:44 +01:00
if not opts . message :
opts . message = edit_message ( )
2020-08-05 21:17:30 +02:00
if ' kind ' in root . attrib and root . attrib [ ' kind ' ] == ' maintenance_incident ' :
r = create_release_request ( apiurl , source_project , opts . message )
else :
r = Request ( )
if opts . package :
for pac in opts . package :
r . add_action ( ' release ' , src_project = source_project , src_package = pac )
else :
r . add_action ( ' release ' , src_project = source_project )
2020-11-28 17:46:44 +01:00
r . description = opts . message
2020-08-05 21:17:30 +02:00
r . create ( apiurl )
2013-04-09 12:51:28 +02:00
print ( r . reqid )
2011-03-07 19:45:44 +01:00
2011-05-02 13:21:28 +02:00
@cmdln.option ( ' -a ' , ' --attribute ' , metavar = ' ATTRIBUTE ' ,
help = ' Use this attribute to find default maintenance project (default is OBS:MaintenanceProject) ' )
2011-05-04 12:11:24 +02:00
@cmdln.option ( ' --noaccess ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' Create a hidden project ' )
2011-05-02 13:21:28 +02:00
@cmdln.option ( ' -m ' , ' --message ' , metavar = ' TEXT ' ,
help = ' specify message TEXT ' )
def do_createincident ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Create a maintenance incident
2011-05-02 13:21:28 +02:00
2022-09-30 12:28:58 +02:00
[ See https : / / openbuildservice . org / help / manuals / obs - user - guide / cha . obs . maintenance_setup . html
2011-05-02 13:21:28 +02:00
for information on this topic . ]
2019-05-24 13:42:47 +02:00
This command is asking to open an empty maintenance incident . This can usually only be done by a responsible
2011-05-02 13:21:28 +02:00
maintenance team .
Please see the " mbranch " command on how to full such a project content and
2011-06-08 12:10:47 +02:00
the " patchinfo " command how add the required maintenance update information .
2011-05-02 13:21:28 +02:00
usage :
osc createincident [ MAINTENANCEPROJECT ]
"""
args = slash_split ( args )
apiurl = self . get_api_url ( )
maintenance_attribute = conf . config [ ' maintenance_attribute ' ]
if opts . attribute :
maintenance_attribute = opts . attribute
source_project = target_project = None
if len ( args ) > 1 :
raise oscerr . WrongArgs ( ' Too many arguments. ' )
if len ( args ) == 1 :
2022-05-10 14:49:21 +02:00
target_project = self . _process_project_name ( args [ 0 ] )
2011-05-02 13:21:28 +02:00
else :
xpath = ' attribute/@name = \' %s \' ' % maintenance_attribute
res = search ( apiurl , project_id = xpath )
root = res [ ' project_id ' ]
project = root . find ( ' project ' )
if project is None :
sys . exit ( ' Unable to find defined OBS:MaintenanceProject project on server. ' )
target_project = project . get ( ' name ' )
2013-04-09 12:51:28 +02:00
print ( ' Using target project \' %s \' ' % target_project )
2011-05-02 13:21:28 +02:00
2022-09-12 13:43:10 +02:00
query = { ' cmd ' : ' createmaintenanceincident ' }
2011-05-04 12:11:24 +02:00
if opts . noaccess :
2013-05-27 12:16:44 +02:00
query [ " noaccess " ] = 1
2011-05-02 13:21:28 +02:00
url = makeurl ( apiurl , [ ' source ' , target_project ] , query = query )
r = http_POST ( url , data = opts . message )
2011-07-19 18:05:07 +02:00
project = None
for i in ET . fromstring ( r . read ( ) ) . findall ( ' data ' ) :
if i . get ( ' name ' ) == ' targetproject ' :
project = i . text . strip ( )
if project :
2013-05-27 12:16:44 +02:00
print ( " Incident project created: " , project )
2011-07-19 18:05:07 +02:00
else :
2013-05-27 12:16:44 +02:00
print ( ET . parse ( r ) . getroot ( ) . get ( ' code ' ) )
print ( ET . parse ( r ) . getroot ( ) . get ( ' error ' ) )
2011-05-02 13:21:28 +02:00
2011-03-07 11:46:51 +01:00
@cmdln.option ( ' -a ' , ' --attribute ' , metavar = ' ATTRIBUTE ' ,
2011-03-11 11:07:35 +01:00
help = ' Use this attribute to find default maintenance project (default is OBS:MaintenanceProject) ' )
2011-03-07 11:46:51 +01:00
@cmdln.option ( ' -m ' , ' --message ' , metavar = ' TEXT ' ,
help = ' specify message TEXT ' )
2014-12-12 13:44:24 +01:00
@cmdln.option ( ' --release-project ' , metavar = ' RELEASEPROJECT ' ,
2022-09-12 13:43:10 +02:00
help = ' Specify the release project ' )
2019-07-22 15:32:19 +02:00
@cmdln.option ( ' --enforce-branching ' , action = ' store_true ' ,
help = ' submit from a fresh branched project ' )
2011-10-31 11:30:26 +01:00
@cmdln.option ( ' --no-cleanup ' , action = ' store_true ' ,
help = ' do not remove source project on accept ' )
2012-10-10 15:54:21 +02:00
@cmdln.option ( ' --cleanup ' , action = ' store_true ' ,
help = ' do remove source project on accept ' )
2012-01-19 11:36:57 +01:00
@cmdln.option ( ' --incident ' , metavar = ' INCIDENT ' ,
2022-09-12 13:43:10 +02:00
help = ' specify incident number to merge in ' )
2012-01-19 11:36:57 +01:00
@cmdln.option ( ' --incident-project ' , metavar = ' INCIDENT_PROJECT ' ,
2022-09-12 13:43:10 +02:00
help = ' specify incident project to merge in ' )
2017-04-19 15:27:04 +02:00
@cmdln.option ( ' -s ' , ' --supersede ' , metavar = ' REQUEST_ID ' ,
2015-08-07 10:17:40 +02:00
help = ' Superseding another request by this one ' )
2012-02-21 18:01:54 +01:00
@cmdln.alias ( " mr " )
2011-03-07 11:46:51 +01:00
def do_maintenancerequest ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Create a request for starting a maintenance incident
2011-03-07 11:46:51 +01:00
2022-09-30 12:28:58 +02:00
[ See https : / / openbuildservice . org / help / manuals / obs - user - guide / cha . obs . maintenance_setup . html
2011-03-07 11:46:51 +01:00
for information on this topic . ]
2019-05-24 13:42:47 +02:00
This command is asking the maintenance team to start a maintenance incident based on a
2011-03-07 11:46:51 +01:00
created maintenance update . Please see the " mbranch " command on how to create such a project and
2011-04-28 11:14:38 +02:00
the " patchinfo " command how add the required maintenance update information .
2011-03-07 11:46:51 +01:00
usage :
2012-02-21 18:01:54 +01:00
osc maintenancerequest [ SOURCEPROJECT [ SOURCEPACKAGES RELEASEPROJECT ] ]
2015-08-25 12:34:13 +02:00
osc maintenancerequest .
2016-05-15 17:50:31 +02:00
The 2 nd line when issued within a package directory provides a short cut to submit a single
2015-08-25 12:34:13 +02:00
package ( the one in the current directory ) from the project of this package to be submitted
to the release project this package links to . This syntax is only valid when specified from
a package subdirectory .
2011-03-07 11:46:51 +01:00
"""
2022-09-12 13:43:10 +02:00
# FIXME: the follow syntax would make more sense and would obsolete the --release-project parameter
2014-12-12 13:44:24 +01:00
# but is incompatible with the current one
# osc maintenancerequest [ SOURCEPROJECT [ RELEASEPROJECT [ SOURCEPACKAGES ] ]
2011-03-07 11:46:51 +01:00
args = slash_split ( args )
apiurl = self . get_api_url ( )
2011-05-02 13:21:28 +02:00
maintenance_attribute = conf . config [ ' maintenance_attribute ' ]
2011-03-07 11:46:51 +01:00
if opts . attribute :
2011-05-02 13:21:28 +02:00
maintenance_attribute = opts . attribute
2011-03-07 11:46:51 +01:00
2015-09-24 18:25:22 +02:00
source_project = target_project = release_project = opt_sourceupdate = None
source_packages = [ ]
2011-03-07 11:46:51 +01:00
2022-10-07 17:25:33 +02:00
if len ( args ) == 0 and ( is_project_dir ( Path . cwd ( ) ) or is_package_dir ( Path . cwd ( ) ) ) :
source_project = store_read_project ( Path . cwd ( ) )
if is_package_dir ( Path . cwd ( ) ) :
source_packages = [ store_read_package ( Path . cwd ( ) ) ]
2011-03-07 13:08:34 +01:00
elif len ( args ) == 0 :
raise oscerr . WrongArgs ( ' Too few arguments. ' )
2011-03-07 11:46:51 +01:00
if len ( args ) > 0 :
2015-08-25 12:34:13 +02:00
if len ( args ) == 1 and args [ 0 ] == ' . ' :
2022-10-07 17:25:33 +02:00
if is_package_dir ( Path . cwd ( ) ) :
source_project = store_read_project ( Path . cwd ( ) )
source_packages = [ store_read_package ( Path . cwd ( ) ) ]
p = Package ( Path . cwd ( ) )
2015-08-25 12:34:13 +02:00
release_project = p . linkinfo . project
else :
raise oscerr . WrongArgs ( ' No package directory ' )
else :
2022-05-10 14:49:21 +02:00
source_project = self . _process_project_name ( args [ 0 ] )
2011-03-07 11:46:51 +01:00
if len ( args ) > 1 :
2012-02-21 18:01:54 +01:00
if len ( args ) == 2 :
sys . exit ( ' Source package defined, but no release project. ' )
2012-01-19 11:36:57 +01:00
source_packages = args [ 1 : ]
2022-05-10 14:49:21 +02:00
release_project = self . _process_project_name ( args [ - 1 ] )
2012-02-21 18:01:54 +01:00
source_packages . remove ( release_project )
2012-10-10 15:54:21 +02:00
if opts . cleanup :
opt_sourceupdate = ' cleanup '
2012-02-15 13:13:44 +01:00
if not opts . no_cleanup :
default_branch = ' home: %s :branches: ' % ( conf . get_apiurl_usr ( apiurl ) )
2012-10-10 15:54:21 +02:00
if source_project . startswith ( default_branch ) :
2012-02-15 13:13:44 +01:00
opt_sourceupdate = ' cleanup '
2012-01-19 11:36:57 +01:00
2014-12-12 13:44:24 +01:00
if opts . release_project :
release_project = opts . release_project
2012-01-19 11:36:57 +01:00
if opts . incident_project :
target_project = opts . incident_project
2011-03-07 11:46:51 +01:00
else :
2011-05-02 13:21:28 +02:00
xpath = ' attribute/@name = \' %s \' ' % maintenance_attribute
2011-03-07 13:08:34 +01:00
res = search ( apiurl , project_id = xpath )
root = res [ ' project_id ' ]
project = root . find ( ' project ' )
if project is None :
2011-03-11 11:07:35 +01:00
sys . exit ( ' Unable to find defined OBS:MaintenanceProject project on server. ' )
2011-03-07 13:08:34 +01:00
target_project = project . get ( ' name ' )
2012-01-19 11:36:57 +01:00
if opts . incident :
target_project + = " : " + opts . incident
2020-01-23 13:28:40 +01:00
release_in = ' '
if release_project is not None :
release_in = ' . (release in \' %s \' ) ' % release_project
print ( ' Using target project \' %s \' %s ' % ( target_project , release_in ) )
2011-03-07 11:46:51 +01:00
if not opts . message :
opts . message = edit_message ( )
2015-08-07 10:17:40 +02:00
supersede_existing = False
reqs = [ ]
if not opts . supersede :
( supersede_existing , reqs ) = check_existing_maintenance_requests ( apiurl ,
2022-09-12 13:43:10 +02:00
source_project ,
source_packages ,
target_project ,
None ) # unspecified release project
2015-08-07 10:17:40 +02:00
2019-07-22 15:32:19 +02:00
r = create_maintenance_request ( apiurl , source_project , source_packages , target_project , release_project , opt_sourceupdate , opts . message , opts . enforce_branching )
2013-04-09 12:51:28 +02:00
print ( r . reqid )
2020-07-07 08:49:36 +02:00
if conf . config [ ' print_web_links ' ] :
2023-01-20 13:19:04 +01:00
obs_url = _private . get_configuration_value ( apiurl , " obs_url " )
2023-01-03 16:44:32 +01:00
print ( f " { obs_url } /request/show/ { r . reqid } " )
2011-03-07 11:46:51 +01:00
2015-08-07 10:17:40 +02:00
if supersede_existing :
for req in reqs :
change_request_state ( apiurl , req . reqid , ' superseded ' ,
' superseded by %s ' % r . reqid , r . reqid )
if opts . supersede :
change_request_state ( apiurl , opts . supersede , ' superseded ' ,
opts . message or ' ' , r . reqid )
2009-11-02 09:32:15 +01:00
@cmdln.option ( ' -c ' , ' --checkout ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' Checkout branched package afterwards '
' ( \' osc bco \' is a shorthand for this option) ' )
2009-11-02 09:32:15 +01:00
@cmdln.option ( ' -a ' , ' --attribute ' , metavar = ' ATTRIBUTE ' ,
help = ' Use this attribute to find affected packages (default is OBS:Maintained) ' )
@cmdln.option ( ' -u ' , ' --update-project-attribute ' , metavar = ' UPDATE_ATTRIBUTE ' ,
help = ' Use this attribute to find update projects (default is OBS:UpdateProject) ' )
2012-01-05 16:15:29 +01:00
@cmdln.option ( ' --dryrun ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' Just simulate the action and report back the result. ' )
2012-01-05 16:15:29 +01:00
@cmdln.option ( ' --noaccess ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' Create a hidden project ' )
2012-01-05 16:15:29 +01:00
@cmdln.option ( ' --nodevelproject ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' do not follow a defined devel project '
' (primary project where a package is developed) ' )
2020-01-23 14:38:22 +01:00
@cmdln.option ( ' --version ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' print version of maintained package ' )
2012-01-05 16:15:29 +01:00
@cmdln.alias ( ' sm ' )
@cmdln.alias ( ' maintained ' )
2009-11-02 09:32:15 +01:00
def do_mbranch ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Search or branch multiple instances of a package
2012-01-05 16:15:29 +01:00
This command is used for searching all relevant instances of packages
and creating links of them in one project .
This is esp . used for maintenance updates . It can also be used to branch
all packages marked before with a given attribute .
2009-11-02 09:32:15 +01:00
2010-07-27 15:20:35 +02:00
[ See http : / / en . opensuse . org / openSUSE : Build_Service_Concept_Maintenance
2010-07-26 19:45:42 +02:00
for information on this topic . ]
2009-11-02 09:32:15 +01:00
The branched package will live in
home : USERNAME : branches : ATTRIBUTE : PACKAGE
if nothing else specified .
2019-10-16 14:41:22 +02:00
If osc maintained or sm is issued only the relevant instances of a
package will be shown . No branch will be created . This is similar
to osc mbranch - - dryrun .
2009-11-02 09:32:15 +01:00
usage :
2012-01-05 16:15:29 +01:00
osc sm [ SOURCEPACKAGE ] [ - a ATTRIBUTE ]
2009-11-02 09:32:15 +01:00
osc mbranch [ SOURCEPACKAGE [ TARGETPROJECT ] ]
"""
args = slash_split ( args )
2010-07-29 17:29:07 +02:00
apiurl = self . get_api_url ( )
2009-11-02 09:32:15 +01:00
tproject = None
maintained_attribute = conf . config [ ' maintained_attribute ' ]
2012-01-05 11:27:22 +01:00
if opts . attribute :
maintained_attribute = opts . attribute
2009-11-02 09:32:15 +01:00
maintained_update_project_attribute = conf . config [ ' maintained_update_project_attribute ' ]
2012-01-05 14:37:09 +01:00
if opts . update_project_attribute :
maintained_update_project_attribute = opts . update_project_attribute
2009-11-02 09:32:15 +01:00
2022-08-29 13:23:29 +02:00
if not args or len ( args ) > 2 :
2009-11-02 09:32:15 +01:00
raise oscerr . WrongArgs ( ' Wrong number of arguments. ' )
if len ( args ) > = 1 :
package = args [ 0 ]
if len ( args ) > = 2 :
2022-05-10 14:49:21 +02:00
tproject = self . _process_project_name ( args [ 1 ] )
2009-11-02 09:32:15 +01:00
2022-10-08 13:24:08 +02:00
if subcmd in ( ' maintained ' , ' sm ' ) :
2012-01-05 16:15:29 +01:00
opts . dryrun = 1
2009-11-02 09:32:15 +01:00
2022-09-12 13:43:10 +02:00
result = attribute_branch_pkg ( apiurl , maintained_attribute , maintained_update_project_attribute ,
package , tproject , noaccess = opts . noaccess , nodevelproject = opts . nodevelproject , dryrun = opts . dryrun )
2012-01-05 16:15:29 +01:00
if result is None :
2013-04-09 12:51:28 +02:00
print ( ' ERROR: Attribute branch call came not back with a project. ' , file = sys . stderr )
2009-11-02 09:32:15 +01:00
sys . exit ( 1 )
2012-01-05 16:15:29 +01:00
if opts . dryrun :
for r in result . findall ( ' package ' ) :
2022-04-20 19:22:35 +02:00
line = " %s / %s " % ( r . get ( ' project ' ) , r . get ( ' package ' ) )
2020-01-23 14:38:22 +01:00
if opts . version :
sr = get_source_rev ( apiurl , r . get ( ' project ' ) , r . get ( ' package ' ) )
version = sr . get ( ' version ' )
if not version or version == ' unknown ' :
version = ' unknown '
line = line + ( ' (version: %s ) ' % version )
2015-05-05 14:01:10 +02:00
for d in r . findall ( ' devel ' ) :
2022-04-20 19:22:35 +02:00
line + = " using sources from %s / %s " % ( d . get ( ' project ' ) , d . get ( ' package ' ) )
2015-05-05 14:01:10 +02:00
print ( line )
2012-01-05 16:15:29 +01:00
return
2016-05-15 17:50:31 +02:00
2013-11-05 15:07:38 +01:00
apiopt = ' '
2023-11-02 13:44:46 +01:00
if conf . get_configParser ( ) . get ( " general " , " apiurl " , fallback = None ) != apiurl :
2013-11-05 15:07:38 +01:00
apiopt = ' -A %s ' % apiurl
2022-09-12 13:43:10 +02:00
print ( ' A working copy of the maintenance branch can be checked out with: \n \n '
' osc %s co %s '
% ( apiopt , result ) )
2009-11-02 09:32:15 +01:00
if opts . checkout :
2012-01-05 16:15:29 +01:00
Project . init_project ( apiurl , result , result , conf . config [ ' do_package_tracking ' ] )
2013-04-09 12:51:28 +02:00
print ( statfrmt ( ' A ' , result ) )
2009-11-02 09:32:15 +01:00
# all packages
2012-01-05 16:15:29 +01:00
for package in meta_get_packagelist ( apiurl , result ) :
2009-11-02 09:32:15 +01:00
try :
2023-02-08 11:46:16 +01:00
checkout_package ( apiurl , result , package , expand_link = True , prj_dir = Path ( result ) )
2009-11-02 09:32:15 +01:00
except :
2013-04-09 12:51:28 +02:00
print ( ' Error while checkout package: \n ' , package , file = sys . stderr )
2009-11-02 09:32:15 +01:00
2023-07-27 09:35:24 +02:00
_private . print_msg ( ' Note: You can use " osc delete " or " osc submitpac " when done. \n ' , print_to = " verbose " )
2009-11-02 09:32:15 +01:00
2009-08-20 21:28:05 +02:00
@cmdln.alias ( ' branchco ' )
@cmdln.alias ( ' bco ' )
@cmdln.alias ( ' getpac ' )
2008-06-03 15:16:55 +02:00
@cmdln.option ( ' --nodevelproject ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' do not follow a defined devel project '
' (primary project where a package is developed) ' )
2009-04-17 14:02:02 +02:00
@cmdln.option ( ' -c ' , ' --checkout ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' Checkout branched package afterwards using " co -e -S " '
' ( \' osc bco \' is a shorthand for this option) ' )
2010-05-17 20:14:49 +02:00
@cmdln.option ( ' -f ' , ' --force ' , default = False , action = " store_true " ,
2010-05-19 10:47:01 +02:00
help = ' force branch, overwrite target ' )
2011-11-25 10:12:16 +01:00
@cmdln.option ( ' --add-repositories ' , default = False , action = " store_true " ,
help = ' Add repositories to target project (happens by default when project is new) ' )
2011-12-01 15:54:50 +01:00
@cmdln.option ( ' --extend-package-names ' , default = False , action = " store_true " ,
help = ' Extend packages names with project name as suffix ' )
2011-05-04 12:11:24 +02:00
@cmdln.option ( ' --noaccess ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' Create a hidden project ' )
2010-03-02 01:34:17 +01:00
@cmdln.option ( ' -m ' , ' --message ' , metavar = ' TEXT ' ,
help = ' specify message TEXT ' )
2012-02-09 10:04:44 +01:00
@cmdln.option ( ' -M ' , ' --maintenance ' , default = False , action = " store_true " ,
help = ' Create project and package in maintenance mode ' )
2011-12-15 15:12:13 +01:00
@cmdln.option ( ' -N ' , ' --new-package ' , action = ' store_true ' ,
help = ' create a branch pointing to a not yet existing package ' )
2010-05-17 20:14:49 +02:00
@cmdln.option ( ' -r ' , ' --revision ' , metavar = ' rev ' ,
help = ' branch against a specific revision ' )
2015-10-23 11:08:30 +02:00
@cmdln.option ( ' --linkrev ' , metavar = ' linkrev ' ,
2022-09-12 13:43:10 +02:00
help = ' specify the used revision in the link target. ' )
2016-03-02 17:12:28 +01:00
@cmdln.option ( ' --add-repositories-block ' , metavar = ' add_repositories_block ' ,
2022-09-12 13:43:10 +02:00
help = ' specify the used block strategy for new repositories ' )
2016-03-02 17:12:28 +01:00
@cmdln.option ( ' --add-repositories-rebuild ' , metavar = ' add_repositories_rebuild ' ,
2022-09-12 13:43:10 +02:00
help = ' specify the used rebuild strategy for new repositories ' )
2022-11-08 15:34:55 +01:00
@cmdln.option ( ' --disable-build ' , action = ' store_true ' ,
help = ' disable building of the branched package ' )
2008-10-16 14:34:41 +02:00
def do_branch ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Branch a package
2008-05-21 17:49:00 +02:00
2010-07-27 15:20:35 +02:00
[ See http : / / en . opensuse . org / openSUSE : Build_Service_Collaboration
2010-07-26 19:45:42 +02:00
for information on this topic . ]
2008-06-06 14:04:34 +02:00
2008-05-21 17:49:00 +02:00
Create a source link from a package of an existing project to a new
subproject of the requesters home project ( home : branches : )
The branched package will live in
home : USERNAME : branches : PROJECT / PACKAGE
2009-04-17 14:02:02 +02:00
if nothing else specified .
2009-05-18 16:50:43 +02:00
2011-03-09 16:10:48 +01:00
With getpac or bco , the branched package will come from one of
2009-09-03 23:32:36 +02:00
% ( getpac_default_project ) s
2011-03-17 18:48:20 +01:00
( list of projects from oscrc : getpac_default_project )
if nothing else is specfied on the command line .
2009-09-03 20:08:43 +02:00
2015-10-23 11:08:30 +02:00
In case of branch errors , where the source has currently merge
conflicts use - - linkrev = base option .
2009-05-18 16:50:43 +02:00
usage :
2010-04-27 12:23:03 +02:00
osc branch
2009-04-17 14:02:02 +02:00
osc branch SOURCEPROJECT SOURCEPACKAGE
2022-10-18 23:38:28 +02:00
osc branch SOURCEPROJECT SOURCEPACKAGE TARGETPROJECT | .
osc branch SOURCEPROJECT SOURCEPACKAGE TARGETPROJECT | . TARGETPACKAGE
2010-08-20 13:23:23 +02:00
osc getpac SOURCEPACKAGE
2009-08-20 21:28:05 +02:00
osc bco . . .
2008-05-21 17:49:00 +02:00
"""
2022-09-30 14:09:37 +02:00
if subcmd in ( ' getpac ' , ' branchco ' , ' bco ' ) :
2013-05-27 13:38:49 +02:00
opts . checkout = True
2008-10-16 14:34:41 +02:00
args = slash_split ( args )
2009-04-17 14:02:02 +02:00
tproject = tpackage = None
2009-08-20 21:28:05 +02:00
2022-09-30 14:09:37 +02:00
if subcmd in ( ' getpac ' , ' bco ' ) and len ( args ) == 1 :
2011-03-09 16:10:48 +01:00
def_p = find_default_project ( self . get_api_url ( ) , args [ 0 ] )
2013-04-09 12:51:28 +02:00
print ( ' defaulting to %s / %s ' % ( def_p , args [ 0 ] ) , file = sys . stderr )
2009-09-03 20:08:43 +02:00
# python has no args.unshift ???
2022-09-12 13:43:10 +02:00
args = [ def_p , args [ 0 ] ]
2016-05-15 17:50:31 +02:00
2010-04-27 12:23:03 +02:00
if len ( args ) == 0 and is_package_dir ( ' . ' ) :
args = ( store_read_project ( ' . ' ) , store_read_package ( ' . ' ) )
2009-09-03 20:08:43 +02:00
2010-02-08 23:31:27 +01:00
if len ( args ) < 2 or len ( args ) > 4 :
2008-10-16 14:34:41 +02:00
raise oscerr . WrongArgs ( ' Wrong number of arguments. ' )
2010-04-27 12:23:03 +02:00
2010-07-29 17:29:07 +02:00
apiurl = self . get_api_url ( )
2010-08-20 13:25:32 +02:00
expected = ' home: %s :branches: %s ' % ( conf . get_apiurl_usr ( apiurl ) , args [ 0 ] )
2009-04-17 14:02:02 +02:00
if len ( args ) > = 3 :
2022-05-10 14:49:21 +02:00
expected = tproject = self . _process_project_name ( args [ 2 ] )
2009-04-17 14:02:02 +02:00
if len ( args ) > = 4 :
tpackage = args [ 3 ]
2008-10-16 14:34:41 +02:00
2015-07-21 13:02:48 +02:00
try :
2022-04-20 19:22:35 +02:00
exists , targetprj , targetpkg , srcprj , srcpkg = \
2022-05-10 14:49:21 +02:00
branch_pkg ( apiurl , self . _process_project_name ( args [ 0 ] ) , args [ 1 ] ,
2009-10-20 16:30:15 +02:00
nodevelproject = opts . nodevelproject , rev = opts . revision ,
2015-10-23 11:08:30 +02:00
linkrev = opts . linkrev ,
2009-10-20 16:30:15 +02:00
target_project = tproject , target_package = tpackage ,
2010-05-17 20:14:49 +02:00
return_existing = opts . checkout , msg = opts . message or ' ' ,
2011-12-01 15:54:50 +01:00
force = opts . force , noaccess = opts . noaccess ,
add_repositories = opts . add_repositories ,
2016-03-02 17:12:28 +01:00
add_repositories_block = opts . add_repositories_block ,
add_repositories_rebuild = opts . add_repositories_rebuild ,
2012-02-09 10:04:44 +01:00
extend_package_names = opts . extend_package_names ,
missingok = opts . new_package ,
2022-11-08 15:34:55 +01:00
maintenance = opts . maintenance ,
disable_build = opts . disable_build )
2015-07-21 13:02:48 +02:00
except oscerr . NotMissing as e :
2022-04-20 19:22:35 +02:00
print ( ' NOTE: Package target exists already via project links, link will point to given project. ' )
print ( ' A submission will initialize a new instance. ' )
exists , targetprj , targetpkg , srcprj , srcpkg = \
2022-05-10 14:49:21 +02:00
branch_pkg ( apiurl , self . _process_project_name ( args [ 0 ] ) , args [ 1 ] ,
2015-07-21 13:02:48 +02:00
nodevelproject = opts . nodevelproject , rev = opts . revision ,
2015-10-23 11:08:30 +02:00
linkrev = opts . linkrev ,
2015-07-21 13:02:48 +02:00
target_project = tproject , target_package = tpackage ,
return_existing = opts . checkout , msg = opts . message or ' ' ,
force = opts . force , noaccess = opts . noaccess ,
add_repositories = opts . add_repositories ,
2016-03-02 17:12:28 +01:00
add_repositories_block = opts . add_repositories_block ,
add_repositories_rebuild = opts . add_repositories_rebuild ,
2015-07-21 13:02:48 +02:00
extend_package_names = opts . extend_package_names ,
missingok = False ,
maintenance = opts . maintenance ,
2022-11-08 15:34:55 +01:00
newinstance = opts . new_package ,
disable_build = opts . disable_build )
2016-05-15 17:50:31 +02:00
2010-02-08 19:58:14 +01:00
if exists :
2013-04-09 12:51:28 +02:00
print ( ' Using existing branch project: %s ' % targetprj , file = sys . stderr )
2009-08-20 21:28:05 +02:00
2009-09-23 01:31:10 +02:00
devloc = None
2022-05-10 14:49:21 +02:00
if not exists and ( srcprj != self . _process_project_name ( args [ 0 ] ) or srcpkg != args [ 1 ] ) :
2011-02-08 16:56:16 +01:00
try :
2018-12-13 15:17:29 +01:00
root = ET . fromstring ( b ' ' . join ( show_attribute_meta ( apiurl , args [ 0 ] , None , None ,
2022-09-12 13:43:10 +02:00
conf . config [ ' maintained_update_project_attribute ' ] , False , False ) ) )
2011-02-08 16:56:16 +01:00
# this might raise an AttributeError
uproject = root . find ( ' attribute ' ) . find ( ' value ' ) . text
2022-09-12 13:43:10 +02:00
print ( ' \n Note: The branch has been created from the configured update project: %s '
% uproject )
2013-04-09 14:03:17 +02:00
except ( AttributeError , HTTPError ) as e :
2011-02-08 16:56:16 +01:00
devloc = srcprj
2022-09-12 13:43:10 +02:00
print ( ' \n Note: The branch has been created of a different project, \n '
' %s , \n '
' which is the primary location of where development for \n '
' that package takes place. \n '
' That \' s also where you would normally make changes against. \n '
' A direct branch of the specified package can be forced \n '
2013-04-09 12:51:28 +02:00
' with the --nodevelproject option. \n ' % devloc )
2009-04-17 14:02:02 +02:00
2012-01-05 17:15:39 +01:00
package = targetpkg or args [ 1 ]
2009-04-17 14:02:02 +02:00
if opts . checkout :
2015-10-03 22:24:58 +02:00
checkout_package ( apiurl , targetprj , package , server_service_files = False ,
2023-02-08 11:46:16 +01:00
expand_link = True , prj_dir = Path ( targetprj ) )
2023-07-27 09:35:24 +02:00
_private . print_msg ( ' Note: You can use " osc delete " or " osc submitpac " when done. \n ' , print_to = " verbose " )
2009-04-17 14:02:02 +02:00
else :
apiopt = ' '
2023-11-02 13:44:46 +01:00
if conf . get_configParser ( ) . get ( " general " , " apiurl " , fallback = None ) != apiurl :
2010-07-29 17:29:07 +02:00
apiopt = ' -A %s ' % apiurl
2022-09-12 13:43:10 +02:00
print ( ' A working copy of the branched package can be checked out with: \n \n '
' osc %s co %s / %s '
% ( apiopt , targetprj , package ) )
2010-07-29 17:29:07 +02:00
print_request_list ( apiurl , args [ 0 ] , args [ 1 ] )
2009-09-23 01:31:10 +02:00
if devloc :
2011-02-08 16:56:16 +01:00
print_request_list ( apiurl , devloc , srcpkg )
2008-05-21 17:49:00 +02:00
2011-05-26 10:21:14 +02:00
@cmdln.option ( ' -m ' , ' --message ' , metavar = ' TEXT ' ,
help = ' specify log message TEXT ' )
2010-05-21 19:02:42 +02:00
def do_undelete ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Restores a deleted project or package on the server
2010-05-21 19:02:42 +02:00
The server restores a package including the sources and meta configuration .
Binaries remain to be lost and will be rebuild .
usage :
osc undelete PROJECT
2023-01-02 15:49:58 +01:00
osc undelete PROJECT PACKAGE
2010-05-21 19:02:42 +02:00
"""
2023-01-02 15:49:58 +01:00
apiurl = self . get_api_url ( )
2010-05-21 19:02:42 +02:00
2023-01-02 15:49:58 +01:00
args = list ( args )
project , package = pop_project_package_from_args (
args , package_is_optional = True
)
ensure_no_remaining_args ( args )
2011-05-26 10:21:14 +02:00
2023-01-02 15:49:58 +01:00
msg = opts . message or edit_message ( )
2010-05-21 19:02:42 +02:00
2023-01-02 15:49:58 +01:00
if package :
undelete_package ( apiurl , project , package , msg )
2010-05-21 19:02:42 +02:00
else :
2023-01-02 15:49:58 +01:00
undelete_project ( apiurl , project , msg )
2010-05-21 19:02:42 +02:00
2011-05-23 20:42:35 +02:00
@cmdln.option ( ' -r ' , ' --recursive ' , action = ' store_true ' ,
help = ' deletes a project with packages inside ' )
2007-10-14 01:15:49 +02:00
@cmdln.option ( ' -f ' , ' --force ' , action = ' store_true ' ,
2011-05-23 20:42:35 +02:00
help = ' deletes a project where other depends on ' )
2011-05-26 10:21:14 +02:00
@cmdln.option ( ' -m ' , ' --message ' , metavar = ' TEXT ' ,
help = ' specify log message TEXT ' )
2009-05-04 21:07:05 +02:00
def do_rdelete ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Delete a project or packages on the server
2006-09-25 17:11:03 +02:00
2007-10-14 01:15:49 +02:00
As a safety measure , project must be empty ( i . e . , you need to delete all
2011-03-05 20:08:47 +01:00
packages first ) . Also , packages must have no requests pending ( i . e . , you need
to accept / revoke such requests first ) .
If you are sure that you want to remove this project and all
2011-05-23 20:42:35 +02:00
its packages use \' --recursive \' switch.
It may still not work because other depends on it . If you want to ignore this as
well use \' --force \' switch.
2006-09-25 17:11:03 +02:00
2009-05-04 21:07:05 +02:00
usage :
2023-01-02 16:25:55 +01:00
osc rdelete [ - r ] [ - f ] PROJECT [ PACKAGE ]
2007-04-25 01:00:12 +02:00
"""
2010-07-29 17:29:07 +02:00
apiurl = self . get_api_url ( )
2009-05-04 21:07:05 +02:00
2023-01-02 16:25:55 +01:00
args = list ( args )
project , package = pop_project_package_from_args (
args , package_is_optional = True
)
ensure_no_remaining_args ( args )
msg = opts . message or edit_message ( )
2011-05-26 10:21:14 +02:00
2010-11-24 14:17:14 +01:00
# empty arguments result in recursive project delete ...
2023-01-02 16:25:55 +01:00
if not project :
2010-11-24 14:17:14 +01:00
raise oscerr . WrongArgs ( ' Project argument is empty ' )
2023-01-02 16:25:55 +01:00
if package :
delete_package ( apiurl , project , package , opts . force , msg )
2007-10-14 01:15:49 +02:00
else :
2023-01-02 16:25:55 +01:00
delete_project ( apiurl , project , opts . force , msg , recursive = opts . recursive )
2009-05-04 21:07:05 +02:00
2016-11-03 08:39:50 +01:00
@cmdln.option ( ' -m ' , ' --message ' , metavar = ' TEXT ' ,
help = ' specify log message TEXT ' )
2023-01-03 14:31:42 +01:00
def do_lock ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Locks a project or package
2015-05-30 16:27:54 +02:00
usage :
osc lock PROJECT [ PACKAGE ]
"""
apiurl = self . get_api_url ( )
2023-01-03 14:31:42 +01:00
args = list ( args )
project , package = pop_project_package_from_args (
args , package_is_optional = True
)
ensure_no_remaining_args ( args )
# TODO: make consistent with unlock and require a message?
lock ( apiurl , project , package , opts . message )
2015-05-30 16:27:54 +02:00
2012-03-15 09:54:56 +01:00
@cmdln.option ( ' -m ' , ' --message ' , metavar = ' TEXT ' ,
help = ' specify log message TEXT ' )
def do_unlock ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Unlocks a project or package
2012-03-15 09:54:56 +01:00
Unlocks a locked project or package . A comment is required .
usage :
osc unlock PROJECT [ PACKAGE ]
"""
apiurl = self . get_api_url ( )
2023-01-03 14:35:14 +01:00
args = list ( args )
project , package = pop_project_package_from_args (
args , package_is_optional = True
)
ensure_no_remaining_args ( args )
2012-03-15 09:54:56 +01:00
2023-01-03 14:35:14 +01:00
msg = opts . message or edit_message ( )
2012-03-15 09:54:56 +01:00
2023-01-03 14:35:14 +01:00
if package :
unlock_package ( apiurl , project , package , msg )
2012-03-15 09:54:56 +01:00
else :
2023-01-03 14:35:14 +01:00
unlock_project ( apiurl , project , msg )
2012-03-15 09:54:56 +01:00
2008-08-08 17:23:03 +02:00
@cmdln.alias ( ' metafromspec ' )
2014-05-22 13:01:44 +02:00
@cmdln.alias ( ' updatepkgmetafromspec ' )
2007-06-30 17:39:47 +02:00
@cmdln.option ( ' ' , ' --specfile ' , metavar = ' FILE ' ,
help = ' Path to specfile. (if you pass more than working copy this option is ignored) ' )
2007-04-25 01:00:12 +02:00
def do_updatepacmetafromspec ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Update package meta information from a specfile
2006-09-25 17:11:03 +02:00
2007-04-25 01:00:12 +02:00
ARG , if specified , is a package working copy .
"""
2006-05-31 14:13:26 +02:00
2007-04-25 01:00:12 +02:00
args = parseargs ( args )
2010-02-09 00:08:21 +01:00
if opts . specfile and len ( args ) == 1 :
2007-06-30 17:39:47 +02:00
specfile = opts . specfile
else :
specfile = None
2022-09-13 16:34:54 +02:00
pacs = Package . from_paths ( args )
2007-04-25 01:00:12 +02:00
for p in pacs :
2007-06-30 17:39:47 +02:00
p . read_meta_from_spec ( specfile )
2007-07-16 15:40:58 +02:00
p . update_package_meta ( )
2006-05-31 14:13:26 +02:00
2010-12-24 22:44:19 +01:00
@cmdln.alias ( ' linkdiff ' )
@cmdln.alias ( ' ldiff ' )
2007-04-25 01:00:12 +02:00
@cmdln.alias ( ' di ' )
2009-05-18 16:50:43 +02:00
@cmdln.option ( ' -c ' , ' --change ' , metavar = ' rev ' ,
help = ' the change made by revision rev (like -r rev-1:rev). '
' If rev is negative this is like -r rev:rev-1. ' )
2007-07-04 14:55:26 +02:00
@cmdln.option ( ' -r ' , ' --revision ' , metavar = ' rev1[:rev2] ' ,
help = ' If rev1 is specified it will compare your working copy against '
' the revision (rev1) on the server. '
2009-01-09 18:09:29 +01:00
' If rev1 and rev2 are specified it will compare rev1 against rev2 '
2009-01-16 15:45:27 +01:00
' (NOTE: changes in your working copy are ignored in this case) ' )
2018-04-11 08:01:45 +02:00
@cmdln.option ( ' -M ' , ' --meta ' , action = ' store_true ' ,
help = ' operate on meta files ' )
2009-09-07 20:49:01 +02:00
@cmdln.option ( ' -p ' , ' --plain ' , action = ' store_true ' ,
help = ' output the diff in plain (not unified) diff format ' )
2010-12-24 22:44:19 +01:00
@cmdln.option ( ' -l ' , ' --link ' , action = ' store_true ' ,
help = ' (osc linkdiff): compare against the base revision of the link ' )
2010-04-10 15:44:15 +02:00
@cmdln.option ( ' --missingok ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' do not fail if the source or target project/package does not exist on the server ' )
2018-04-11 08:01:45 +02:00
@cmdln.option ( ' -u ' , ' --unexpand ' , action = ' store_true ' ,
help = ' Local changes only, ignore changes in linked package sources ' )
2007-04-25 01:00:12 +02:00
def do_diff ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Generates a diff
2006-05-31 14:13:26 +02:00
2007-04-25 01:00:12 +02:00
Generates a diff , comparing local changes against the repository
server .
2009-05-18 16:50:43 +02:00
2022-01-19 15:13:55 +01:00
usage :
2010-12-24 22:44:19 +01:00
ARG , if specified , is a filename to include in the diff .
Default : all files .
osc diff - - link
2014-08-12 15:01:16 +02:00
osc linkdiff
2010-12-24 22:44:19 +01:00
Compare current checkout directory against the link base .
2014-08-12 15:01:16 +02:00
osc diff - - link PROJ PACK
osc linkdiff PROJ PACK
2010-12-24 22:44:19 +01:00
Compare a package against the link base ( ignoring working copy changes ) .
2007-04-25 01:00:12 +02:00
"""
2022-09-30 14:09:37 +02:00
if ( subcmd in ( ' ldiff ' , ' linkdiff ' ) ) :
2010-12-24 22:44:19 +01:00
opts . link = True
2007-04-25 01:00:12 +02:00
args = parseargs ( args )
2016-05-15 17:50:31 +02:00
2010-12-24 22:44:19 +01:00
pacs = None
if not opts . link or not len ( args ) == 2 :
2022-09-13 16:34:54 +02:00
pacs = Package . from_paths ( args )
2010-12-24 22:44:19 +01:00
if opts . link :
2022-09-12 13:43:10 +02:00
query = { ' rev ' : ' latest ' }
2010-12-24 22:44:19 +01:00
if pacs :
u = makeurl ( pacs [ 0 ] . apiurl , [ ' source ' , pacs [ 0 ] . prjname , pacs [ 0 ] . name ] , query = query )
else :
u = makeurl ( self . get_api_url ( ) , [ ' source ' , args [ 0 ] , args [ 1 ] ] , query = query )
f = http_GET ( u )
root = ET . parse ( f ) . getroot ( )
linkinfo = root . find ( ' linkinfo ' )
2022-08-29 12:56:57 +02:00
if linkinfo is None :
2010-12-24 22:44:19 +01:00
raise oscerr . APIError ( ' package is not a source link ' )
baserev = linkinfo . get ( ' baserev ' )
opts . revision = baserev
if pacs :
2019-05-24 13:42:47 +02:00
print ( " diff working copy against last committed version \n " )
2010-12-24 22:44:19 +01:00
else :
2019-05-24 13:42:47 +02:00
print ( " diff committed package against linked revision %s \n " % baserev )
2023-07-11 21:02:21 +02:00
run_pager (
highlight_diff (
server_diff (
self . get_api_url ( ) ,
linkinfo . get ( " project " ) ,
linkinfo . get ( " package " ) ,
baserev ,
args [ 0 ] ,
args [ 1 ] ,
linkinfo . get ( " lsrcmd5 " ) ,
not opts . plain ,
opts . missingok ,
)
)
)
2010-12-24 22:44:19 +01:00
return
2009-05-18 16:50:43 +02:00
if opts . change :
try :
rev = int ( opts . change )
if rev > 0 :
rev1 = rev - 1
rev2 = rev
elif rev < 0 :
rev1 = - rev
rev2 = - rev - 1
else :
return
except :
2013-04-09 12:51:28 +02:00
print ( ' Revision \' %s \' not an integer ' % opts . change , file = sys . stderr )
2009-05-18 16:50:43 +02:00
return
else :
rev1 , rev2 = parseRevisionOption ( opts . revision )
2019-07-17 10:34:20 +02:00
diff = b ' '
2007-11-26 19:13:51 +01:00
for pac in pacs :
2009-01-09 18:09:29 +01:00
if not rev2 :
2010-08-27 16:24:12 +02:00
for i in pac . get_diff ( rev1 ) :
2019-07-17 10:34:20 +02:00
diff + = b ' ' . join ( i )
2009-01-09 18:09:29 +01:00
else :
2023-05-09 21:45:20 +02:00
if args == [ " . " ] :
# parseargs() returns ["."] (list with workdir) if no args are specified
# "." is illegal filename that causes server to return 400
files = None
else :
files = args
2019-07-17 10:34:20 +02:00
diff + = server_diff_noex ( pac . apiurl , pac . prjname , pac . name , rev1 ,
2022-09-12 13:43:10 +02:00
pac . prjname , pac . name , rev2 ,
2023-04-28 14:38:43 +02:00
not opts . plain , opts . missingok , opts . meta , not opts . unexpand , files = files )
2023-07-11 21:02:21 +02:00
run_pager ( highlight_diff ( diff ) )
2007-07-04 14:55:26 +02:00
2017-05-10 16:34:12 +02:00
@cmdln.option ( ' --issues-only ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' show only issues in diff ' )
2011-03-03 10:07:32 +01:00
@cmdln.option ( ' -M ' , ' --meta ' , action = ' store_true ' ,
help = ' diff meta data ' )
2007-11-29 18:22:57 +01:00
@cmdln.option ( ' -r ' , ' --revision ' , metavar = ' N[:M] ' ,
help = ' revision id, where N = old revision and M = new revision ' )
2009-09-07 20:49:01 +02:00
@cmdln.option ( ' -p ' , ' --plain ' , action = ' store_true ' ,
2020-08-07 15:01:45 +02:00
help = ' output the diff in plain (not unified) diff format '
' and show diff of files in archives ' )
2009-09-07 20:49:01 +02:00
@cmdln.option ( ' -c ' , ' --change ' , metavar = ' rev ' ,
2010-01-10 12:12:26 +01:00
help = ' the change made by revision rev (like -r rev-1:rev). '
2009-09-07 20:49:01 +02:00
' If rev is negative this is like -r rev:rev-1. ' )
2010-04-10 15:44:15 +02:00
@cmdln.option ( ' --missingok ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' do not fail if the source or target project/package does not exist on the server ' )
2010-10-19 15:25:25 +02:00
@cmdln.option ( ' -u ' , ' --unexpand ' , action = ' store_true ' ,
help = ' diff unexpanded version if sources are linked ' )
2020-06-15 17:18:52 +02:00
@cmdln.option ( ' --xml ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' show diff as xml (only for issues diff) ' )
2010-01-10 12:12:26 +01:00
def do_rdiff ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Server - side " pretty " diff of two packages
2007-11-29 18:22:57 +01:00
2010-01-10 12:12:26 +01:00
Compares two packages ( three or four arguments ) or shows the
changes of a specified revision of a package ( two arguments )
If no revision is specified the latest revision is used .
2007-11-29 18:32:52 +01:00
2010-01-10 12:12:26 +01:00
usage :
2022-01-19 15:13:55 +01:00
osc rdiff OLDPRJ OLDPAC NEWPRJ [ NEWPAC ]
osc rdiff PROJECT PACKAGE
2023-01-04 20:13:37 +01:00
osc rdiff PROJECT - - meta
2007-11-29 18:22:57 +01:00
"""
2010-07-29 17:29:07 +02:00
apiurl = self . get_api_url ( )
2010-01-10 12:12:26 +01:00
2023-01-04 20:13:37 +01:00
args = list ( args )
old_project , old_package , new_project , new_package = pop_project_package_targetproject_targetpackage_from_args (
args , package_is_optional = True , target_project_is_optional = True , target_package_is_optional = True ,
)
ensure_no_remaining_args ( args )
2009-09-07 20:49:01 +02:00
2023-02-01 10:37:30 +01:00
if not new_project :
new_project = old_project
2023-01-04 20:13:37 +01:00
if not new_package :
new_package = old_package
2010-01-10 12:12:26 +01:00
2023-01-04 20:13:37 +01:00
if not old_package :
2023-10-05 10:34:54 +02:00
new_project = old_project
new_package = " _project "
old_project = None
old_package = None
2010-01-10 12:12:26 +01:00
2011-03-03 10:07:32 +01:00
if opts . meta :
opts . unexpand = True
2010-01-10 12:12:26 +01:00
2023-01-04 20:13:37 +01:00
rev1 = None
rev2 = None
2009-09-07 20:49:01 +02:00
if opts . change :
try :
rev = int ( opts . change )
if rev > 0 :
rev1 = rev - 1
rev2 = rev
elif rev < 0 :
rev1 = - rev
rev2 = - rev - 1
else :
return
except :
2013-04-09 12:51:28 +02:00
print ( ' Revision \' %s \' not an integer ' % opts . change , file = sys . stderr )
2009-09-07 20:49:01 +02:00
return
else :
if opts . revision :
rev1 , rev2 = parseRevisionOption ( opts . revision )
2007-11-29 18:22:57 +01:00
2010-12-23 10:33:31 +01:00
rdiff = server_diff_noex ( apiurl ,
2022-09-12 13:43:10 +02:00
old_project , old_package , rev1 ,
new_project , new_package , rev2 , not opts . plain , opts . missingok ,
meta = opts . meta ,
expand = not opts . unexpand ,
onlyissues = opts . issues_only ,
xml = opts . xml )
2017-05-10 16:34:12 +02:00
if opts . issues_only :
2020-06-15 17:18:52 +02:00
print ( decode_it ( rdiff ) )
2017-05-10 16:34:12 +02:00
else :
2023-07-11 21:02:21 +02:00
run_pager ( highlight_diff ( rdiff ) )
2011-04-28 13:49:48 +02:00
2022-09-12 13:43:10 +02:00
def _pdiff_raise_non_existing_package ( self , project , package , msg = None ) :
2011-04-28 13:49:48 +02:00
raise oscerr . PackageMissing ( project , package , msg or ' %s / %s does not exist. ' % ( project , package ) )
def _pdiff_package_exists ( self , apiurl , project , package ) :
try :
show_package_meta ( apiurl , project , package )
return True
2013-04-09 14:03:17 +02:00
except HTTPError as e :
2011-04-28 13:49:48 +02:00
if e . code != 404 :
2013-04-09 12:51:28 +02:00
print ( ' Cannot check that %s / %s exists: %s ' % ( project , package , e ) , file = sys . stderr )
2011-04-28 13:49:48 +02:00
return False
2022-09-12 13:43:10 +02:00
def _pdiff_guess_parent ( self , apiurl , project , package , check_exists_first = False ) :
2011-04-28 13:49:48 +02:00
# Make sure the parent exists
if check_exists_first and not self . _pdiff_package_exists ( apiurl , project , package ) :
self . _pdiff_raise_non_existing_package ( project , package )
if project . startswith ( ' home: ' ) :
guess = project [ len ( ' home: ' ) : ]
# remove user name
pos = guess . find ( ' : ' )
if pos > 0 :
guess = guess [ guess . find ( ' : ' ) + 1 : ]
if guess . startswith ( ' branches: ' ) :
guess = guess [ len ( ' branches: ' ) : ]
return ( guess , package )
return ( None , None )
def _pdiff_get_parent_from_link ( self , apiurl , project , package ) :
link_url = makeurl ( apiurl , [ ' source ' , project , package , ' _link ' ] )
try :
file = http_GET ( link_url )
root = ET . parse ( file ) . getroot ( )
2013-04-09 14:03:17 +02:00
except HTTPError as e :
2011-04-28 13:49:48 +02:00
return ( None , None )
2013-04-09 11:27:02 +02:00
except SyntaxError as e :
2013-04-09 12:51:28 +02:00
print ( ' Cannot parse %s / %s /_link: %s ' % ( project , package , e ) , file = sys . stderr )
2011-04-28 13:49:48 +02:00
return ( None , None )
parent_project = root . get ( ' project ' )
parent_package = root . get ( ' package ' ) or package
if parent_project is None :
return ( None , None )
return ( parent_project , parent_package )
def _pdiff_get_exists_and_parent ( self , apiurl , project , package ) :
2023-11-22 14:33:06 +01:00
link_url = makeurl ( apiurl , [ ' source ' , project , package ] )
2011-04-28 13:49:48 +02:00
try :
file = http_GET ( link_url )
root = ET . parse ( file ) . getroot ( )
2013-04-09 14:03:17 +02:00
except HTTPError as e :
2011-04-28 13:49:48 +02:00
if e . code != 404 :
2013-04-09 12:51:28 +02:00
print ( ' Cannot get list of files for %s / %s : %s ' % ( project , package , e ) , file = sys . stderr )
2011-04-28 13:49:48 +02:00
return ( None , None , None )
2013-04-09 11:27:02 +02:00
except SyntaxError as e :
2013-04-09 12:51:28 +02:00
print ( ' Cannot parse list of files for %s / %s : %s ' % ( project , package , e ) , file = sys . stderr )
2011-04-28 13:49:48 +02:00
return ( None , None , None )
link_node = root . find ( ' linkinfo ' )
if link_node is None :
return ( True , None , None )
parent_project = link_node . get ( ' project ' )
parent_package = link_node . get ( ' package ' ) or package
if parent_project is None :
raise oscerr . APIError ( ' %s / %s is a link with no parent? ' % ( project , package ) )
return ( True , parent_project , parent_package )
@cmdln.option ( ' -p ' , ' --plain ' , action = ' store_true ' ,
dest = ' plain ' ,
help = ' output the diff in plain (not unified) diff format ' )
@cmdln.option ( ' -n ' , ' --nomissingok ' , action = ' store_true ' ,
dest = ' nomissingok ' ,
help = ' fail if the parent package does not exist on the server ' )
def do_pdiff ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Quick alias to diff the content of a package with its parent
2011-04-28 13:49:48 +02:00
2022-01-19 15:13:55 +01:00
usage :
2011-04-28 13:49:48 +02:00
osc pdiff [ - - plain | - p ] [ - - nomissing - ok | - n ]
osc pdiff [ - - plain | - p ] [ - - nomissing - ok | - n ] PKG
osc pdiff [ - - plain | - p ] [ - - nomissing - ok | - n ] PRJ PKG
"""
apiurl = self . get_api_url ( )
args = slash_split ( args )
unified = not opts . plain
noparentok = not opts . nomissingok
if len ( args ) > 2 :
raise oscerr . WrongArgs ( ' Too many arguments. ' )
if len ( args ) == 0 :
2022-10-07 17:25:33 +02:00
if not is_package_dir ( Path . cwd ( ) ) :
2011-04-28 13:49:48 +02:00
raise oscerr . WrongArgs ( ' Current directory is not a checked out package. Please specify a project and a package. ' )
2022-10-07 17:25:33 +02:00
project = store_read_project ( Path . cwd ( ) )
package = store_read_package ( Path . cwd ( ) )
2011-04-28 13:49:48 +02:00
elif len ( args ) == 1 :
2022-10-07 17:25:33 +02:00
if not is_project_dir ( Path . cwd ( ) ) :
2011-04-28 13:49:48 +02:00
raise oscerr . WrongArgs ( ' Current directory is not a checked out project. Please specify a project and a package. ' )
2022-10-07 17:25:33 +02:00
project = store_read_project ( Path . cwd ( ) )
2011-04-28 13:49:48 +02:00
package = args [ 0 ]
elif len ( args ) == 2 :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2011-04-28 13:49:48 +02:00
package = args [ 1 ]
else :
raise RuntimeError ( ' Internal error: bad check for arguments. ' )
2022-09-12 13:43:10 +02:00
# Find parent package
2011-04-28 13:49:48 +02:00
# Old way, that does one more request to api
#(parent_project, parent_package) = self._pdiff_get_parent_from_link(apiurl, project, package)
2022-09-12 13:43:10 +02:00
# if not parent_project:
2011-04-28 13:49:48 +02:00
# (parent_project, parent_package) = self._pdiff_guess_parent(apiurl, project, package, check_exists_first = True)
# if parent_project and parent_package:
# print 'Guessed that %s/%s is the parent package.' % (parent_project, parent_package)
# New way
2022-04-20 19:22:35 +02:00
( exists , parent_project , parent_package ) = self . _pdiff_get_exists_and_parent ( apiurl , project , package )
2011-04-28 13:49:48 +02:00
if not exists :
self . _pdiff_raise_non_existing_package ( project , package )
if not parent_project :
2022-09-12 13:43:10 +02:00
( parent_project , parent_package ) = self . _pdiff_guess_parent ( apiurl , project , package , check_exists_first = False )
2011-04-28 13:49:48 +02:00
if parent_project and parent_package :
2013-04-09 12:51:28 +02:00
print ( ' Guessed that %s / %s is the parent package. ' % ( parent_project , parent_package ) )
2011-04-28 13:49:48 +02:00
if not parent_project or not parent_package :
2013-04-09 12:51:28 +02:00
print ( ' Cannot find a parent for %s / %s to diff against. ' % ( project , package ) , file = sys . stderr )
2011-04-28 13:49:48 +02:00
return 1
if not noparentok and not self . _pdiff_package_exists ( apiurl , parent_project , parent_package ) :
2014-08-12 15:01:16 +02:00
self . _pdiff_raise_non_existing_package ( parent_project , parent_package ,
2022-09-12 13:43:10 +02:00
msg = ' Parent for %s / %s ( %s / %s ) does not exist. ' %
2013-05-27 13:03:46 +02:00
( project , package , parent_project , parent_package ) )
2011-04-28 13:49:48 +02:00
2013-05-27 13:03:46 +02:00
rdiff = server_diff ( apiurl , parent_project , parent_package , None , project ,
2022-09-12 13:43:10 +02:00
package , None , unified = unified , missingok = noparentok )
2011-04-28 13:49:48 +02:00
2023-07-11 21:02:21 +02:00
run_pager ( highlight_diff ( rdiff ) )
2007-11-29 18:22:57 +01:00
2013-01-18 22:58:53 +01:00
def _get_branch_parent ( self , prj ) :
m = re . match ( ' ^home:[^:]+:branches:(.+) ' , prj )
# OBS_Maintained is a special case
if m and prj . find ( ' :branches:OBS_Maintained: ' ) == - 1 :
return m . group ( 1 )
return None
def _prdiff_skip_package ( self , opts , pkg ) :
if opts . exclude and re . search ( opts . exclude , pkg ) :
return True
if opts . include and not re . search ( opts . include , pkg ) :
return True
return False
def _prdiff_output_diff ( self , opts , rdiff ) :
if opts . diffstat :
2013-04-09 12:51:28 +02:00
print ( )
2022-08-24 08:43:09 +02:00
with subprocess . Popen ( " diffstat " , stdin = subprocess . PIPE , stdout = subprocess . PIPE , close_fds = True ) as p :
p . stdin . write ( rdiff )
p . stdin . close ( )
print ( " " . join ( decode_it ( x ) for x in p . stdout . readlines ( ) ) )
2013-01-18 22:58:53 +01:00
elif opts . unified :
2013-04-09 12:51:28 +02:00
print ( )
2019-07-17 10:34:20 +02:00
if isinstance ( rdiff , str ) :
print ( rdiff )
else :
try :
sys . stdout . buffer . write ( rdiff )
except AttributeError as e :
print ( decode_it ( rdiff ) )
2022-09-12 13:43:10 +02:00
# run_pager(rdiff)
2013-01-18 22:58:53 +01:00
def _prdiff_output_matching_requests ( self , opts , requests ,
srcprj , pkg ) :
"""
Search through the given list of requests and output any
submitrequests which target pkg and originate from srcprj .
"""
for req in requests :
for action in req . get_actions ( ' submit ' ) :
if action . src_project != srcprj :
continue
if action . tgt_package != pkg :
continue
2013-04-09 12:51:28 +02:00
print ( )
print ( req . list_view ( ) )
2013-01-18 22:58:53 +01:00
break
@cmdln.alias ( ' projectdiff ' )
@cmdln.alias ( ' projdiff ' )
@cmdln.option ( ' -r ' , ' --requests ' , action = ' store_true ' ,
help = ' show open requests for any packages with differences ' )
2022-04-20 19:22:35 +02:00
@cmdln.option ( ' -e ' , ' --exclude ' , metavar = ' REGEXP ' , dest = ' exclude ' ,
2013-01-18 22:58:53 +01:00
help = ' skip packages matching REGEXP ' )
2022-04-20 19:22:35 +02:00
@cmdln.option ( ' -i ' , ' --include ' , metavar = ' REGEXP ' , dest = ' include ' ,
2013-01-18 22:58:53 +01:00
help = ' only consider packages matching REGEXP ' )
@cmdln.option ( ' -n ' , ' --show-not-in-old ' , action = ' store_true ' ,
help = ' show packages only in the new project ' )
@cmdln.option ( ' -o ' , ' --show-not-in-new ' , action = ' store_true ' ,
help = ' show packages only in the old project ' )
2022-04-20 19:22:35 +02:00
@cmdln.option ( ' -u ' , ' --unified ' , action = ' store_true ' ,
2013-01-18 22:58:53 +01:00
help = ' show full unified diffs of differences ' )
@cmdln.option ( ' -d ' , ' --diffstat ' , action = ' store_true ' ,
help = ' show diffstat of differences ' )
def do_prdiff ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Server - side diff of two projects
2013-01-18 22:58:53 +01:00
2019-05-24 13:42:47 +02:00
Compares two projects and either summarizes or outputs the
2013-01-18 22:58:53 +01:00
differences in full . In the second form , a project is compared
with one of its branches inside a home : $ USER project ( the branch
is treated as NEWPRJ ) . The home branch is optional if the current
working directory is a checked out copy of it .
2022-01-19 15:13:55 +01:00
usage :
2013-01-18 22:58:53 +01:00
osc prdiff [ OPTIONS ] OLDPRJ NEWPRJ
osc prdiff [ OPTIONS ] [ home : $ USER : branch : $ PRJ ]
"""
if len ( args ) > 2 :
raise oscerr . WrongArgs ( ' Too many arguments. ' )
if len ( args ) == 0 :
2022-10-07 17:25:33 +02:00
if is_project_dir ( Path . cwd ( ) ) :
2013-01-18 22:58:53 +01:00
newprj = Project ( ' . ' , getPackageList = False ) . name
oldprj = self . _get_branch_parent ( newprj )
if oldprj is None :
raise oscerr . WrongArgs ( ' Current directory is not a valid home branch. ' )
else :
raise oscerr . WrongArgs ( ' Current directory is not a project. ' )
elif len ( args ) == 1 :
2022-05-10 14:49:21 +02:00
newprj = self . _process_project_name ( args [ 0 ] )
2013-01-18 22:58:53 +01:00
oldprj = self . _get_branch_parent ( newprj )
if oldprj is None :
raise oscerr . WrongArgs ( ' Single-argument form must be for a home branch. ' )
elif len ( args ) == 2 :
2022-05-10 14:49:21 +02:00
oldprj = self . _process_project_name ( args [ 0 ] )
newprj = self . _process_project_name ( args [ 1 ] )
2013-01-18 22:58:53 +01:00
else :
raise RuntimeError ( ' BUG in argument parsing, please report. \n '
' args: ' + repr ( args ) )
if opts . diffstat and opts . unified :
2013-04-09 12:51:28 +02:00
print ( ' error - cannot specify both --diffstat and --unified ' , file = sys . stderr )
2013-01-18 22:58:53 +01:00
sys . exit ( 1 )
apiurl = self . get_api_url ( )
old_packages = meta_get_packagelist ( apiurl , oldprj )
new_packages = meta_get_packagelist ( apiurl , newprj )
if opts . requests :
2022-09-15 14:47:38 +02:00
requests = get_request_collection ( apiurl , project = oldprj , states = ( ' new ' , ' review ' ) )
2013-01-18 22:58:53 +01:00
for pkg in old_packages :
if self . _prdiff_skip_package ( opts , pkg ) :
continue
if pkg not in new_packages :
if opts . show_not_in_new :
2013-04-09 12:51:28 +02:00
print ( " old only: %s " % pkg )
2013-01-18 22:58:53 +01:00
continue
rdiff = server_diff_noex (
apiurl ,
oldprj , pkg , None ,
newprj , pkg , None ,
unified = True , missingok = False , meta = False , expand = True
2022-09-12 13:43:10 +02:00
)
2013-01-18 22:58:53 +01:00
if rdiff :
2013-04-09 12:51:28 +02:00
print ( " differs: %s " % pkg )
2013-01-18 22:58:53 +01:00
self . _prdiff_output_diff ( opts , rdiff )
if opts . requests :
2022-09-15 14:47:38 +02:00
self . _prdiff_output_matching_requests ( opts , requests , newprj , pkg )
2013-01-18 22:58:53 +01:00
else :
2013-04-09 12:51:28 +02:00
print ( " identical: %s " % pkg )
2013-01-18 22:58:53 +01:00
for pkg in new_packages :
if self . _prdiff_skip_package ( opts , pkg ) :
continue
if pkg not in old_packages :
if opts . show_not_in_old :
2013-04-09 12:51:28 +02:00
print ( " new only: %s " % pkg )
2013-01-18 22:58:53 +01:00
2007-04-25 01:00:12 +02:00
def do_repourls ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Shows URLs of . repo files
2007-04-25 01:00:12 +02:00
2020-09-17 11:30:00 +02:00
Shows URLs on which to access the project repositories .
2006-05-23 15:48:58 +02:00
2009-11-30 10:31:28 +01:00
usage :
osc repourls [ PROJECT ]
2007-04-25 01:00:12 +02:00
"""
2022-04-20 19:22:35 +02:00
def _repo_type ( apiurl , project , repo ) :
2020-09-17 11:30:00 +02:00
if not os . path . exists ( ' /usr/lib/build/queryconfig ' ) :
return None
build_config = get_buildconfig ( apiurl , project , repo )
with tempfile . NamedTemporaryFile ( ) as f :
f . write ( build_config )
f . flush ( )
repo_type = return_external ( ' /usr/lib/build/queryconfig ' , ' --dist ' ,
2022-09-12 13:43:10 +02:00
f . name , ' repotype ' ) . rstrip ( b ' \n ' )
2020-09-17 11:30:00 +02:00
if not repo_type :
return None
return decode_it ( repo_type )
2006-05-23 15:48:58 +02:00
2010-04-30 17:13:21 +02:00
apiurl = self . get_api_url ( )
2007-03-12 16:46:15 +01:00
2009-11-30 10:31:28 +01:00
if len ( args ) == 1 :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2009-11-30 10:31:28 +01:00
elif len ( args ) == 0 :
project = store_read_project ( ' . ' )
else :
raise oscerr . WrongArgs ( ' Wrong number of arguments ' )
2006-05-23 15:48:58 +02:00
2023-01-20 13:19:04 +01:00
download_url = _private . get_configuration_value ( apiurl , " download_url " )
2015-06-29 23:59:59 +02:00
2023-01-03 16:44:32 +01:00
url_deb_tmpl = ' deb ' + download_url + ' / %s / %s / / '
url_arch_tmpl = ' Server= ' + download_url + ' / %s / %s /$arch '
url_tmpl = download_url + ' / %s / %s / %s .repo '
2009-11-30 10:31:28 +01:00
repos = get_repositories_of_project ( apiurl , project )
for repo in repos :
2020-09-17 11:30:00 +02:00
repo_type = _repo_type ( apiurl , project , repo )
if repo_type == ' debian ' :
print ( url_deb_tmpl % ( project . replace ( ' : ' , ' :/ ' ) , repo ) )
elif repo_type == ' arch ' :
print ( url_arch_tmpl % ( project . replace ( ' : ' , ' :/ ' ) , repo ) )
else :
# We assume everything else is rpm-md
print ( url_tmpl % ( project . replace ( ' : ' , ' :/ ' ) , repo , project ) )
2006-05-23 15:48:58 +02:00
2019-09-25 16:12:01 +02:00
def do_browse ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Opens browser
2019-09-25 16:12:01 +02:00
usage :
osc browse [ PROJECT [ PACKAGE ] ]
2023-06-01 11:33:39 +02:00
osc browse [ REQUEST_ID ]
2019-09-25 16:12:01 +02:00
"""
2023-01-03 16:33:38 +01:00
args = list ( args )
2023-06-01 11:33:39 +02:00
apiurl = self . get_api_url ( )
2023-01-03 16:33:38 +01:00
obs_url = _private . get_configuration_value ( apiurl , " obs_url " )
2023-06-01 11:33:39 +02:00
if len ( args ) == 1 and args [ 0 ] . isnumeric ( ) :
reqid = args . pop ( 0 )
url = f " { obs_url } /request/show/ { reqid } "
2023-01-03 16:33:38 +01:00
else :
2023-06-01 11:33:39 +02:00
project , package = pop_project_package_from_args (
args , default_project = " . " , default_package = " . " , package_is_optional = True
)
if package :
url = f " { obs_url } /package/show/ { project } / { package } "
else :
url = f " { obs_url } /project/show/ { project } "
ensure_no_remaining_args ( args )
2019-09-25 16:12:01 +02:00
run_external ( ' xdg-open ' , url )
2007-07-04 14:55:26 +02:00
@cmdln.option ( ' -r ' , ' --revision ' , metavar = ' rev ' ,
2007-07-04 15:48:24 +02:00
help = ' checkout the specified revision. '
' NOTE: if you checkout the complete project '
' this option is ignored! ' )
2008-03-24 21:24:49 +01:00
@cmdln.option ( ' -e ' , ' --expand-link ' , action = ' store_true ' ,
2009-05-18 16:50:43 +02:00
help = ' if a package is a link, check out the expanded '
2008-06-06 14:04:34 +02:00
' sources (no-op, since this became the default) ' )
2018-07-19 13:34:49 +02:00
@cmdln.option ( ' -D ' , ' --deleted ' , action = ' store_true ' ,
help = ' checkout an already deleted package. No meta information ' )
2008-06-06 14:04:34 +02:00
@cmdln.option ( ' -u ' , ' --unexpand-link ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' if a package is a link, check out the _link file '
2008-06-06 14:04:34 +02:00
' instead of the expanded sources ' )
2010-05-25 14:00:50 +02:00
@cmdln.option ( ' -M ' , ' --meta ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' checkout out meta data instead of sources ' )
2009-04-16 19:41:47 +02:00
@cmdln.option ( ' -c ' , ' --current-dir ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' place PACKAGE folder in the current directory '
2009-04-16 19:41:47 +02:00
' instead of a PROJECT/PACKAGE directory ' )
2011-11-02 21:02:26 +01:00
@cmdln.option ( ' -o ' , ' --output-dir ' , metavar = ' outdir ' ,
2022-09-12 13:43:10 +02:00
help = ' place package in the specified directory '
2011-11-02 21:02:26 +01:00
' instead of a PROJECT/PACKAGE directory ' )
2009-08-07 14:18:15 +02:00
@cmdln.option ( ' -s ' , ' --source-service-files ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' Run source services. ' )
2010-06-08 11:24:10 +02:00
@cmdln.option ( ' -S ' , ' --server-side-source-service-files ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' Use server side generated sources instead of local generation. ' )
2010-04-22 15:27:54 +02:00
@cmdln.option ( ' -l ' , ' --limit-size ' , metavar = ' limit_size ' ,
help = ' Skip all files with a given size ' )
2007-04-25 01:00:12 +02:00
@cmdln.alias ( ' co ' )
def do_checkout ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Check out content from the repository
2009-05-18 16:50:43 +02:00
2007-04-25 01:00:12 +02:00
Check out content from the repository server , creating a local working
copy .
2008-03-24 21:24:49 +01:00
When checking out a single package , the option - - revision can be used
2009-05-27 14:09:50 +02:00
to specify a revision of the package to be checked out .
2008-03-24 21:24:49 +01:00
2009-05-18 16:50:43 +02:00
When a package is a source link , then it will be checked out in
expanded form . If - - unexpand - link option is used , the checkout will
2008-06-06 14:04:34 +02:00
instead produce the raw _link file plus patches .
2007-04-25 01:00:12 +02:00
2009-05-18 16:50:43 +02:00
usage :
2007-04-25 01:00:12 +02:00
osc co PROJECT [ PACKAGE ] [ FILE ]
2009-04-17 10:39:04 +02:00
osc co PROJECT # entire project
osc co PROJECT PACKAGE # a package
osc co PROJECT PACKAGE FILE # single file -> to current dir
2009-04-24 01:59:40 +02:00
while inside a project directory :
osc co PACKAGE # check out PACKAGE from project
2016-05-15 17:50:31 +02:00
2011-07-20 17:17:56 +02:00
with the result of rpm - q - - qf ' %% {DISTURL} \\ n ' PACKAGE
2014-08-12 15:01:16 +02:00
osc co obs : / / API / PROJECT / PLATFORM / REVISION - PACKAGE
2007-04-25 01:00:12 +02:00
"""
2008-06-06 14:04:34 +02:00
2009-09-16 23:39:45 +02:00
if opts . unexpand_link :
expand_link = False
else :
expand_link = True
2011-02-01 18:37:17 +01:00
osc co: print help instead of crashing if no arguments are given
This fixes:
~> osc checkout
Traceback (most recent call last):
File "/usr/bin/osc", line 21, in <module>
r = babysitter.run(osccli)
File "/usr/lib/python2.7/site-packages/osc/babysitter.py", line 52, in run
return prg.main()
File "/usr/lib/python2.7/site-packages/osc/cmdln.py", line 310, in main
return self.cmd(args)
File "/usr/lib/python2.7/site-packages/osc/cmdln.py", line 333, in cmd
retval = self.onecmd(argv)
File "/usr/lib/python2.7/site-packages/osc/cmdln.py", line 449, in onecmd
return self._dispatch_cmd(handler, argv)
File "/usr/lib/python2.7/site-packages/osc/cmdln.py", line 1179, in _dispatch_cmd
return handler(argv[0], opts, *args)
File "/usr/lib/python2.7/site-packages/osc/commandline.py", line 3386, in do_checkout
m = re.match(r"obs://([^/]+)/(\S+)/([^/]+)/([A-Fa-f\d]+)\-(\S+)", args[0])
IndexError: tuple index out of range
Signed-off-by: Petr Uzel <petr.uzel@suse.cz>
2011-06-08 13:35:47 +02:00
if not args :
2022-01-19 15:13:55 +01:00
self . argparse_error ( " Incorrect number of arguments. " )
osc co: print help instead of crashing if no arguments are given
This fixes:
~> osc checkout
Traceback (most recent call last):
File "/usr/bin/osc", line 21, in <module>
r = babysitter.run(osccli)
File "/usr/lib/python2.7/site-packages/osc/babysitter.py", line 52, in run
return prg.main()
File "/usr/lib/python2.7/site-packages/osc/cmdln.py", line 310, in main
return self.cmd(args)
File "/usr/lib/python2.7/site-packages/osc/cmdln.py", line 333, in cmd
retval = self.onecmd(argv)
File "/usr/lib/python2.7/site-packages/osc/cmdln.py", line 449, in onecmd
return self._dispatch_cmd(handler, argv)
File "/usr/lib/python2.7/site-packages/osc/cmdln.py", line 1179, in _dispatch_cmd
return handler(argv[0], opts, *args)
File "/usr/lib/python2.7/site-packages/osc/commandline.py", line 3386, in do_checkout
m = re.match(r"obs://([^/]+)/(\S+)/([^/]+)/([A-Fa-f\d]+)\-(\S+)", args[0])
IndexError: tuple index out of range
Signed-off-by: Petr Uzel <petr.uzel@suse.cz>
2011-06-08 13:35:47 +02:00
2018-06-27 10:25:45 +02:00
# A DISTURL can be found in build results to be able to relocate the source used to build
# obs://$OBS_INSTANCE/$PROJECT/$REPOSITORY/$XSRCMD5-$PACKAGE(:$FLAVOR)
2011-01-31 17:49:04 +01:00
# obs://build.opensuse.org/openSUSE:11.3/standard/fc6c25e795a89503e99d59da5dc94a79-screen
2018-06-27 10:25:45 +02:00
m = re . match ( r " obs://([^/]+)/( \ S+)/([^/]+)/([A-Fa-f \ d]+) \ -([^:]*)(: \ S+)? " , args [ 0 ] )
2011-01-31 17:49:04 +01:00
if m and len ( args ) == 1 :
2022-09-12 13:43:10 +02:00
apiurl = " https:// " + m . group ( 1 )
2023-02-08 11:46:16 +01:00
project = m . group ( 2 )
project_dir = Path ( project )
2011-02-01 18:37:17 +01:00
# platform = m.group(3)
2022-09-12 13:43:10 +02:00
opts . revision = m . group ( 4 )
package = m . group ( 5 )
2011-02-01 18:37:17 +01:00
apiurl = apiurl . replace ( ' /build. ' , ' /api. ' )
filename = None
2011-01-31 17:49:04 +01:00
else :
2011-02-01 18:37:17 +01:00
args = slash_split ( args )
project = package = filename = None
apiurl = self . get_api_url ( )
try :
2023-02-08 11:46:16 +01:00
project = self . _process_project_name ( args [ 0 ] )
project_dir = Path ( project )
2011-02-01 18:37:17 +01:00
package = args [ 1 ]
filename = args [ 2 ]
except :
pass
2007-04-25 01:00:12 +02:00
2022-10-07 17:25:33 +02:00
if len ( args ) == 1 and is_project_dir ( Path . cwd ( ) ) :
project = store_read_project ( Path . cwd ( ) )
2023-02-08 11:46:16 +01:00
project_dir = Path . cwd ( )
2009-04-17 10:39:04 +02:00
package = args [ 0 ]
2008-06-06 14:04:34 +02:00
2018-07-19 13:34:49 +02:00
if opts . deleted and package :
if not opts . output_dir :
raise oscerr . WrongOptions ( ' -o | --output-dir is needed to get deleted sources ' )
elif opts . deleted and not package :
raise oscerr . WrongOptions ( ' -D | --deleted can only be used with a package ' )
2007-07-04 14:55:26 +02:00
rev , dummy = parseRevisionOption ( opts . revision )
2023-10-05 14:15:28 +02:00
if revision_is_empty ( rev ) :
2013-05-27 12:41:50 +02:00
rev = " latest "
2007-07-04 14:55:26 +02:00
2023-10-05 14:15:28 +02:00
if not revision_is_empty ( rev ) and rev != " latest " and not checkRevision ( project , package , rev ) :
2013-04-09 12:51:28 +02:00
print ( ' Revision \' %s \' does not exist ' % rev , file = sys . stderr )
2007-07-06 13:54:34 +02:00
sys . exit ( 1 )
2007-04-25 01:00:12 +02:00
if filename :
2011-03-08 18:48:00 +01:00
# Note: same logic as with 'osc cat' (not 'osc ls', which never merges!)
2010-12-30 02:31:28 +01:00
if expand_link :
2011-03-08 18:48:00 +01:00
rev = show_upstream_srcmd5 ( apiurl , project , package , expand = True , revision = rev )
2010-02-09 20:57:10 +01:00
get_source_file ( apiurl , project , package , filename , revision = rev , progress_obj = self . download_progress )
2007-04-25 01:00:12 +02:00
elif package :
2018-07-19 13:34:49 +02:00
if opts . deleted :
checkout_deleted_package ( apiurl , project , package , opts . output_dir )
else :
if opts . current_dir :
project_dir = None
2022-09-12 13:43:10 +02:00
checkout_package ( apiurl , project , package , rev , expand_link = expand_link ,
prj_dir = project_dir , service_files = opts . source_service_files ,
server_service_files = opts . server_side_source_service_files ,
progress_obj = self . download_progress , size_limit = opts . limit_size ,
2018-07-19 13:34:49 +02:00
meta = opts . meta , outdir = opts . output_dir )
2023-07-17 09:01:42 +02:00
if os . isatty ( sys . stdout . fileno ( ) ) :
print_request_list ( apiurl , project , package )
2007-04-25 01:00:12 +02:00
elif project :
2023-02-08 11:46:16 +01:00
sep = ' / ' if not opts . output_dir and conf . config [ ' checkout_no_colon ' ] else conf . config [ ' project_separator ' ]
chosen_output = opts . output_dir if opts . output_dir else project
prj_dir = Path ( chosen_output . replace ( ' : ' , sep ) )
2009-05-15 13:40:50 +02:00
if os . path . exists ( prj_dir ) :
2016-06-15 15:28:10 +02:00
sys . exit ( ' osc: project directory \' %s \' already exists ' % prj_dir )
Merged revisions 3774-3775,3779,3781-3782,3787,3789-3793,3798,3802,3805,3817-3822,3827,3829-3830,3837-3839,3841-3842,3848-3850 via svnmerge from
https://forgesvn1.novell.com/svn/opensuse/branches/buildservice/osc-exception-handling
........
r3774 | poeml | 2008-04-22 17:39:45 +0200 (Tue, 22 Apr 2008) | 3 lines
A first draft on implement systematic exception handling:
Add errors.py with some exceptions defined, and babysitter.py to handle them
........
r3775 | poeml | 2008-04-22 22:34:12 +0200 (Tue, 22 Apr 2008) | 9 lines
- new global options:
--debugger jump into the debugger before executing anything
--post-mortem jump into the debugger in case of errors
-t, --traceback print call trace in case of errors
- traceback and post_mortem can also be set in .oscrc.
- catch more errors (HTTPError).
- make config accessible from outside of the Osc instance, by making it a class
attribute
........
r3779 | poeml | 2008-04-23 00:55:49 +0200 (Wed, 23 Apr 2008) | 5 lines
- new global option:
-d, --debug print info useful for debugging
- catch some more errors (HTTPError), with OscHTTPError which isn't very
advanced yet.
........
r3781 | Marcus_H | 2008-04-23 01:02:00 +0200 (Wed, 23 Apr 2008) | 2 lines
- added OscConfigError class (just for testing).
- small change in the signature of the OscBaseError constructor (actually we should get rid of the 'args' tuple because it will be deprecated sooner or later
........
r3782 | Marcus_H | 2008-04-23 02:02:13 +0200 (Wed, 23 Apr 2008) | 2 lines
- access the prg.conf.config dict in a save way - this way we avoid AttributeErrors if the prg.conf.config dict doesn't exist
- in case of an configparser error we have to use the prg.options object directly (this was removed in r3781 by accident)
........
r3787 | poeml | 2008-04-23 09:23:56 +0200 (Wed, 23 Apr 2008) | 4 lines
- remove local exception handling from do_req
- for HTTPError, print details (headers and response) when in debug mode
- catch AttributeError
........
r3789 | poeml | 2008-04-23 16:23:14 +0200 (Wed, 23 Apr 2008) | 4 lines
- errors: add two new classes named OscWrongOptionsError and OscWrongArgsError
- commandline: raise instances of the new errors in a number of places
- commandline: add get_cmd_help() to Osc instance which returns the formatted help of a subcommand
........
r3790 | Marcus_H | 2008-04-23 16:48:28 +0200 (Wed, 23 Apr 2008) | 4 lines
- added 2 new exception classes: OscNoConfigfileError and OscIOError
- added new method write_config() to the conf.py module: This method writes osc's configuration file
- minor cleanups in the conf module
........
r3791 | poeml | 2008-04-23 17:11:07 +0200 (Wed, 23 Apr 2008) | 3 lines
small compatibility fix for r3790: try-except-finally isn't supported in
python-2.4.2, thus do the same as try-except inside a try-finally.
........
r3792 | poeml | 2008-04-23 17:37:53 +0200 (Wed, 23 Apr 2008) | 2 lines
fix up the remaining places regarding handling of errors related to commandline parsing
........
r3793 | poeml | 2008-04-23 17:40:34 +0200 (Wed, 23 Apr 2008) | 3 lines
raise a NoWorkingCopyError in osc.core.store_read_project() in case of an
IOError
........
r3798 | Marcus_H | 2008-04-23 23:55:24 +0200 (Wed, 23 Apr 2008) | 1 line
ported -r3797 from trunk
........
r3802 | Marcus_H | 2008-04-24 11:00:55 +0200 (Thu, 24 Apr 2008) | 1 line
ported -r3801 from trunk
........
r3805 | poeml | 2008-04-24 12:52:30 +0200 (Thu, 24 Apr 2008) | 2 lines
raise OscHTTPError in show_pattern_meta(), replacing local error handling
........
r3817 | poeml | 2008-04-24 20:21:32 +0200 (Thu, 24 Apr 2008) | 9 lines
- remove errors.OscHTTPError again.
it seems simpler to use urllib2.HTTPError instead (and just add a specific
error text message where appropriate, and re-raise)
- for 404s, check out _which_ part was not found
it is very ugly, but may be considered Good for pragmatic reasons
- removed local exception handling and workaround for returned 500's from
delete_package() and delete_project(), thereby getting rid of 4 possible exit
points.
........
r3818 | Marcus_H | 2008-04-24 22:36:17 +0200 (Thu, 24 Apr 2008) | 1 line
- this check is superfluous because every HTTPError instance has a code attribute
........
r3819 | poeml | 2008-04-25 00:39:39 +0200 (Fri, 25 Apr 2008) | 1 line
remove a forgotten debug line from core.delete_project()
........
r3820 | poeml | 2008-04-25 10:07:58 +0200 (Fri, 25 Apr 2008) | 2 lines
- ditch local error handling from wipebinaries(), rebuild(), and abortbuild()
........
r3821 | poeml | 2008-04-25 10:56:38 +0200 (Fri, 25 Apr 2008) | 2 lines
It is never needed to import the exception module.
........
r3822 | poeml | 2008-04-25 11:13:39 +0200 (Fri, 25 Apr 2008) | 4 lines
- when going into the debugger with --post-mortem, always print a traceback before
(thus implying -t)
- do not jump into the debugger if not on a TTY, or working in interactive mode
........
r3827 | poeml | 2008-04-25 13:07:46 +0200 (Fri, 25 Apr 2008) | 9 lines
- add errors.OscWorkingCopyOutdated, which takes a tuple with three args:
path to working copy, current rev, expected rev
- add handler for urllib2.URLError errors to the babysitter
- simplify the OscWrongArgsError and OscWrongOptionsError handlers, by removing
the extra line "Sorry, wrong ..." that was printed before the messages given
when the error was raised.
- remove one more errors.OscHTTPError which was still there, and raise
urllib2.HTTPError instead (show_package_meta())
........
r3829 | poeml | 2008-04-25 14:19:10 +0200 (Fri, 25 Apr 2008) | 11 lines
- comment some methods in osc.core which are used by nearly all do_* methods in
osc.commandline
- improve "is not a package/project dir" error messages, by printing the
absolute path tried, instead of '.' for the cwd
- make core.store_read_package() raise a proper NoWorkingCopyError instead of
terminating
- give attribution to things in babysitter.py copied from mercurial
- prefix HTTPError exceptions with 'Server returned an error:'
- remove obsolete local error handling from do_prjresults(), do_importsrcpkg(),
do_repos()
........
r3830 | poeml | 2008-04-25 14:29:35 +0200 (Fri, 25 Apr 2008) | 1 line
catch IOError exceptions in the babysitter
........
r3837 | poeml | 2008-04-25 17:27:36 +0200 (Fri, 25 Apr 2008) | 5 lines
- do_remotebuildlog: raise errors for wrong arguments, remove exits
- raise AttributeError in make_meta_url() instead of exiting
- delete unused method core.delete_server_files()
- replace exit call inside make_meta_url() with an AttributeError
........
r3838 | poeml | 2008-04-25 17:49:18 +0200 (Fri, 25 Apr 2008) | 1 line
simplify the check in do_checkout if a project exists, by using show_project_meta() instead of meta_exists
........
r3839 | poeml | 2008-04-25 18:31:26 +0200 (Fri, 25 Apr 2008) | 6 lines
- commandline do_checkout(): change the order of the two checks, first do the
(cheaper) check for existing directory
- core.core checkout_package(): simplify the check in if the package
exists, by using show_package_meta() instead of meta_exists
Let it throw an exception, instead of using sys.exit().
........
r3841 | Marcus_H | 2008-04-27 15:48:06 +0200 (Sun, 27 Apr 2008) | 5 lines
- added 2 new exception classes: PackageError() and PackageExistsError. The PackageError() class is meant to be the base class for all subsequent package exceptions.
- get rid of 2 sys.exit(1) calls
- make the update() method of the Project() class safer: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- minor fix in delPackage(): use getTransActPath() when printing out the filename
........
r3842 | Marcus_H | 2008-04-27 16:52:55 +0200 (Sun, 27 Apr 2008) | 3 lines
- make the commit() method safe: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- removed another sys.exit(1): raise an exception if a package is missing when doing a commit. For now we use the PackageExistsError() exception but this might change in the future (updated description of PackageExistsError() according to this change)
........
r3848 | poeml | 2008-04-28 12:46:45 +0200 (Mon, 28 Apr 2008) | 3 lines
rename several error classes, dropping the "Osc" prefix, and "Error" suffix in
cases where they don't really make sense.
........
r3849 | poeml | 2008-04-28 12:57:32 +0200 (Mon, 28 Apr 2008) | 3 lines
- rename osc.errors module to osc.oscerr, to make it easier to import it from
other programs and have a crystal clear namespace
........
r3850 | poeml | 2008-04-28 13:26:12 +0200 (Mon, 28 Apr 2008) | 2 lines
split PackageExists exception class into PackageExists and PackageMissing
........
2008-04-28 18:37:44 +02:00
# check if the project does exist (show_project_meta will throw an exception)
2009-04-17 10:39:04 +02:00
show_project_meta ( apiurl , project )
Merged revisions 3774-3775,3779,3781-3782,3787,3789-3793,3798,3802,3805,3817-3822,3827,3829-3830,3837-3839,3841-3842,3848-3850 via svnmerge from
https://forgesvn1.novell.com/svn/opensuse/branches/buildservice/osc-exception-handling
........
r3774 | poeml | 2008-04-22 17:39:45 +0200 (Tue, 22 Apr 2008) | 3 lines
A first draft on implement systematic exception handling:
Add errors.py with some exceptions defined, and babysitter.py to handle them
........
r3775 | poeml | 2008-04-22 22:34:12 +0200 (Tue, 22 Apr 2008) | 9 lines
- new global options:
--debugger jump into the debugger before executing anything
--post-mortem jump into the debugger in case of errors
-t, --traceback print call trace in case of errors
- traceback and post_mortem can also be set in .oscrc.
- catch more errors (HTTPError).
- make config accessible from outside of the Osc instance, by making it a class
attribute
........
r3779 | poeml | 2008-04-23 00:55:49 +0200 (Wed, 23 Apr 2008) | 5 lines
- new global option:
-d, --debug print info useful for debugging
- catch some more errors (HTTPError), with OscHTTPError which isn't very
advanced yet.
........
r3781 | Marcus_H | 2008-04-23 01:02:00 +0200 (Wed, 23 Apr 2008) | 2 lines
- added OscConfigError class (just for testing).
- small change in the signature of the OscBaseError constructor (actually we should get rid of the 'args' tuple because it will be deprecated sooner or later
........
r3782 | Marcus_H | 2008-04-23 02:02:13 +0200 (Wed, 23 Apr 2008) | 2 lines
- access the prg.conf.config dict in a save way - this way we avoid AttributeErrors if the prg.conf.config dict doesn't exist
- in case of an configparser error we have to use the prg.options object directly (this was removed in r3781 by accident)
........
r3787 | poeml | 2008-04-23 09:23:56 +0200 (Wed, 23 Apr 2008) | 4 lines
- remove local exception handling from do_req
- for HTTPError, print details (headers and response) when in debug mode
- catch AttributeError
........
r3789 | poeml | 2008-04-23 16:23:14 +0200 (Wed, 23 Apr 2008) | 4 lines
- errors: add two new classes named OscWrongOptionsError and OscWrongArgsError
- commandline: raise instances of the new errors in a number of places
- commandline: add get_cmd_help() to Osc instance which returns the formatted help of a subcommand
........
r3790 | Marcus_H | 2008-04-23 16:48:28 +0200 (Wed, 23 Apr 2008) | 4 lines
- added 2 new exception classes: OscNoConfigfileError and OscIOError
- added new method write_config() to the conf.py module: This method writes osc's configuration file
- minor cleanups in the conf module
........
r3791 | poeml | 2008-04-23 17:11:07 +0200 (Wed, 23 Apr 2008) | 3 lines
small compatibility fix for r3790: try-except-finally isn't supported in
python-2.4.2, thus do the same as try-except inside a try-finally.
........
r3792 | poeml | 2008-04-23 17:37:53 +0200 (Wed, 23 Apr 2008) | 2 lines
fix up the remaining places regarding handling of errors related to commandline parsing
........
r3793 | poeml | 2008-04-23 17:40:34 +0200 (Wed, 23 Apr 2008) | 3 lines
raise a NoWorkingCopyError in osc.core.store_read_project() in case of an
IOError
........
r3798 | Marcus_H | 2008-04-23 23:55:24 +0200 (Wed, 23 Apr 2008) | 1 line
ported -r3797 from trunk
........
r3802 | Marcus_H | 2008-04-24 11:00:55 +0200 (Thu, 24 Apr 2008) | 1 line
ported -r3801 from trunk
........
r3805 | poeml | 2008-04-24 12:52:30 +0200 (Thu, 24 Apr 2008) | 2 lines
raise OscHTTPError in show_pattern_meta(), replacing local error handling
........
r3817 | poeml | 2008-04-24 20:21:32 +0200 (Thu, 24 Apr 2008) | 9 lines
- remove errors.OscHTTPError again.
it seems simpler to use urllib2.HTTPError instead (and just add a specific
error text message where appropriate, and re-raise)
- for 404s, check out _which_ part was not found
it is very ugly, but may be considered Good for pragmatic reasons
- removed local exception handling and workaround for returned 500's from
delete_package() and delete_project(), thereby getting rid of 4 possible exit
points.
........
r3818 | Marcus_H | 2008-04-24 22:36:17 +0200 (Thu, 24 Apr 2008) | 1 line
- this check is superfluous because every HTTPError instance has a code attribute
........
r3819 | poeml | 2008-04-25 00:39:39 +0200 (Fri, 25 Apr 2008) | 1 line
remove a forgotten debug line from core.delete_project()
........
r3820 | poeml | 2008-04-25 10:07:58 +0200 (Fri, 25 Apr 2008) | 2 lines
- ditch local error handling from wipebinaries(), rebuild(), and abortbuild()
........
r3821 | poeml | 2008-04-25 10:56:38 +0200 (Fri, 25 Apr 2008) | 2 lines
It is never needed to import the exception module.
........
r3822 | poeml | 2008-04-25 11:13:39 +0200 (Fri, 25 Apr 2008) | 4 lines
- when going into the debugger with --post-mortem, always print a traceback before
(thus implying -t)
- do not jump into the debugger if not on a TTY, or working in interactive mode
........
r3827 | poeml | 2008-04-25 13:07:46 +0200 (Fri, 25 Apr 2008) | 9 lines
- add errors.OscWorkingCopyOutdated, which takes a tuple with three args:
path to working copy, current rev, expected rev
- add handler for urllib2.URLError errors to the babysitter
- simplify the OscWrongArgsError and OscWrongOptionsError handlers, by removing
the extra line "Sorry, wrong ..." that was printed before the messages given
when the error was raised.
- remove one more errors.OscHTTPError which was still there, and raise
urllib2.HTTPError instead (show_package_meta())
........
r3829 | poeml | 2008-04-25 14:19:10 +0200 (Fri, 25 Apr 2008) | 11 lines
- comment some methods in osc.core which are used by nearly all do_* methods in
osc.commandline
- improve "is not a package/project dir" error messages, by printing the
absolute path tried, instead of '.' for the cwd
- make core.store_read_package() raise a proper NoWorkingCopyError instead of
terminating
- give attribution to things in babysitter.py copied from mercurial
- prefix HTTPError exceptions with 'Server returned an error:'
- remove obsolete local error handling from do_prjresults(), do_importsrcpkg(),
do_repos()
........
r3830 | poeml | 2008-04-25 14:29:35 +0200 (Fri, 25 Apr 2008) | 1 line
catch IOError exceptions in the babysitter
........
r3837 | poeml | 2008-04-25 17:27:36 +0200 (Fri, 25 Apr 2008) | 5 lines
- do_remotebuildlog: raise errors for wrong arguments, remove exits
- raise AttributeError in make_meta_url() instead of exiting
- delete unused method core.delete_server_files()
- replace exit call inside make_meta_url() with an AttributeError
........
r3838 | poeml | 2008-04-25 17:49:18 +0200 (Fri, 25 Apr 2008) | 1 line
simplify the check in do_checkout if a project exists, by using show_project_meta() instead of meta_exists
........
r3839 | poeml | 2008-04-25 18:31:26 +0200 (Fri, 25 Apr 2008) | 6 lines
- commandline do_checkout(): change the order of the two checks, first do the
(cheaper) check for existing directory
- core.core checkout_package(): simplify the check in if the package
exists, by using show_package_meta() instead of meta_exists
Let it throw an exception, instead of using sys.exit().
........
r3841 | Marcus_H | 2008-04-27 15:48:06 +0200 (Sun, 27 Apr 2008) | 5 lines
- added 2 new exception classes: PackageError() and PackageExistsError. The PackageError() class is meant to be the base class for all subsequent package exceptions.
- get rid of 2 sys.exit(1) calls
- make the update() method of the Project() class safer: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- minor fix in delPackage(): use getTransActPath() when printing out the filename
........
r3842 | Marcus_H | 2008-04-27 16:52:55 +0200 (Sun, 27 Apr 2008) | 3 lines
- make the commit() method safe: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- removed another sys.exit(1): raise an exception if a package is missing when doing a commit. For now we use the PackageExistsError() exception but this might change in the future (updated description of PackageExistsError() according to this change)
........
r3848 | poeml | 2008-04-28 12:46:45 +0200 (Mon, 28 Apr 2008) | 3 lines
rename several error classes, dropping the "Osc" prefix, and "Error" suffix in
cases where they don't really make sense.
........
r3849 | poeml | 2008-04-28 12:57:32 +0200 (Mon, 28 Apr 2008) | 3 lines
- rename osc.errors module to osc.oscerr, to make it easier to import it from
other programs and have a crystal clear namespace
........
r3850 | poeml | 2008-04-28 13:26:12 +0200 (Mon, 28 Apr 2008) | 2 lines
split PackageExists exception class into PackageExists and PackageMissing
........
2008-04-28 18:37:44 +02:00
2021-11-30 13:13:11 +01:00
scm_url = show_scmsync ( apiurl , project )
2022-08-29 12:56:57 +02:00
if scm_url is not None :
2021-11-30 13:13:11 +01:00
if not os . path . isfile ( ' /usr/lib/obs/service/obs_scm_bridge ' ) :
raise oscerr . OscIOError ( None , ' Install the obs-scm-bridge package to work on packages managed in scm (git)! ' )
os . putenv ( " OSC_VERSION " , get_osc_version ( ) )
2023-02-08 11:46:16 +01:00
run_external ( [ ' /usr/lib/obs/service/obs_scm_bridge ' , ' --outdir ' , str ( prj_dir ) , ' --url ' , scm_url ] )
2021-11-30 13:13:11 +01:00
Project . init_project ( apiurl , prj_dir , project , conf . config [ ' do_package_tracking ' ] , scm_url = scm_url )
2013-04-09 12:51:28 +02:00
print ( statfrmt ( ' A ' , prj_dir ) )
Merged revisions 3774-3775,3779,3781-3782,3787,3789-3793,3798,3802,3805,3817-3822,3827,3829-3830,3837-3839,3841-3842,3848-3850 via svnmerge from
https://forgesvn1.novell.com/svn/opensuse/branches/buildservice/osc-exception-handling
........
r3774 | poeml | 2008-04-22 17:39:45 +0200 (Tue, 22 Apr 2008) | 3 lines
A first draft on implement systematic exception handling:
Add errors.py with some exceptions defined, and babysitter.py to handle them
........
r3775 | poeml | 2008-04-22 22:34:12 +0200 (Tue, 22 Apr 2008) | 9 lines
- new global options:
--debugger jump into the debugger before executing anything
--post-mortem jump into the debugger in case of errors
-t, --traceback print call trace in case of errors
- traceback and post_mortem can also be set in .oscrc.
- catch more errors (HTTPError).
- make config accessible from outside of the Osc instance, by making it a class
attribute
........
r3779 | poeml | 2008-04-23 00:55:49 +0200 (Wed, 23 Apr 2008) | 5 lines
- new global option:
-d, --debug print info useful for debugging
- catch some more errors (HTTPError), with OscHTTPError which isn't very
advanced yet.
........
r3781 | Marcus_H | 2008-04-23 01:02:00 +0200 (Wed, 23 Apr 2008) | 2 lines
- added OscConfigError class (just for testing).
- small change in the signature of the OscBaseError constructor (actually we should get rid of the 'args' tuple because it will be deprecated sooner or later
........
r3782 | Marcus_H | 2008-04-23 02:02:13 +0200 (Wed, 23 Apr 2008) | 2 lines
- access the prg.conf.config dict in a save way - this way we avoid AttributeErrors if the prg.conf.config dict doesn't exist
- in case of an configparser error we have to use the prg.options object directly (this was removed in r3781 by accident)
........
r3787 | poeml | 2008-04-23 09:23:56 +0200 (Wed, 23 Apr 2008) | 4 lines
- remove local exception handling from do_req
- for HTTPError, print details (headers and response) when in debug mode
- catch AttributeError
........
r3789 | poeml | 2008-04-23 16:23:14 +0200 (Wed, 23 Apr 2008) | 4 lines
- errors: add two new classes named OscWrongOptionsError and OscWrongArgsError
- commandline: raise instances of the new errors in a number of places
- commandline: add get_cmd_help() to Osc instance which returns the formatted help of a subcommand
........
r3790 | Marcus_H | 2008-04-23 16:48:28 +0200 (Wed, 23 Apr 2008) | 4 lines
- added 2 new exception classes: OscNoConfigfileError and OscIOError
- added new method write_config() to the conf.py module: This method writes osc's configuration file
- minor cleanups in the conf module
........
r3791 | poeml | 2008-04-23 17:11:07 +0200 (Wed, 23 Apr 2008) | 3 lines
small compatibility fix for r3790: try-except-finally isn't supported in
python-2.4.2, thus do the same as try-except inside a try-finally.
........
r3792 | poeml | 2008-04-23 17:37:53 +0200 (Wed, 23 Apr 2008) | 2 lines
fix up the remaining places regarding handling of errors related to commandline parsing
........
r3793 | poeml | 2008-04-23 17:40:34 +0200 (Wed, 23 Apr 2008) | 3 lines
raise a NoWorkingCopyError in osc.core.store_read_project() in case of an
IOError
........
r3798 | Marcus_H | 2008-04-23 23:55:24 +0200 (Wed, 23 Apr 2008) | 1 line
ported -r3797 from trunk
........
r3802 | Marcus_H | 2008-04-24 11:00:55 +0200 (Thu, 24 Apr 2008) | 1 line
ported -r3801 from trunk
........
r3805 | poeml | 2008-04-24 12:52:30 +0200 (Thu, 24 Apr 2008) | 2 lines
raise OscHTTPError in show_pattern_meta(), replacing local error handling
........
r3817 | poeml | 2008-04-24 20:21:32 +0200 (Thu, 24 Apr 2008) | 9 lines
- remove errors.OscHTTPError again.
it seems simpler to use urllib2.HTTPError instead (and just add a specific
error text message where appropriate, and re-raise)
- for 404s, check out _which_ part was not found
it is very ugly, but may be considered Good for pragmatic reasons
- removed local exception handling and workaround for returned 500's from
delete_package() and delete_project(), thereby getting rid of 4 possible exit
points.
........
r3818 | Marcus_H | 2008-04-24 22:36:17 +0200 (Thu, 24 Apr 2008) | 1 line
- this check is superfluous because every HTTPError instance has a code attribute
........
r3819 | poeml | 2008-04-25 00:39:39 +0200 (Fri, 25 Apr 2008) | 1 line
remove a forgotten debug line from core.delete_project()
........
r3820 | poeml | 2008-04-25 10:07:58 +0200 (Fri, 25 Apr 2008) | 2 lines
- ditch local error handling from wipebinaries(), rebuild(), and abortbuild()
........
r3821 | poeml | 2008-04-25 10:56:38 +0200 (Fri, 25 Apr 2008) | 2 lines
It is never needed to import the exception module.
........
r3822 | poeml | 2008-04-25 11:13:39 +0200 (Fri, 25 Apr 2008) | 4 lines
- when going into the debugger with --post-mortem, always print a traceback before
(thus implying -t)
- do not jump into the debugger if not on a TTY, or working in interactive mode
........
r3827 | poeml | 2008-04-25 13:07:46 +0200 (Fri, 25 Apr 2008) | 9 lines
- add errors.OscWorkingCopyOutdated, which takes a tuple with three args:
path to working copy, current rev, expected rev
- add handler for urllib2.URLError errors to the babysitter
- simplify the OscWrongArgsError and OscWrongOptionsError handlers, by removing
the extra line "Sorry, wrong ..." that was printed before the messages given
when the error was raised.
- remove one more errors.OscHTTPError which was still there, and raise
urllib2.HTTPError instead (show_package_meta())
........
r3829 | poeml | 2008-04-25 14:19:10 +0200 (Fri, 25 Apr 2008) | 11 lines
- comment some methods in osc.core which are used by nearly all do_* methods in
osc.commandline
- improve "is not a package/project dir" error messages, by printing the
absolute path tried, instead of '.' for the cwd
- make core.store_read_package() raise a proper NoWorkingCopyError instead of
terminating
- give attribution to things in babysitter.py copied from mercurial
- prefix HTTPError exceptions with 'Server returned an error:'
- remove obsolete local error handling from do_prjresults(), do_importsrcpkg(),
do_repos()
........
r3830 | poeml | 2008-04-25 14:29:35 +0200 (Fri, 25 Apr 2008) | 1 line
catch IOError exceptions in the babysitter
........
r3837 | poeml | 2008-04-25 17:27:36 +0200 (Fri, 25 Apr 2008) | 5 lines
- do_remotebuildlog: raise errors for wrong arguments, remove exits
- raise AttributeError in make_meta_url() instead of exiting
- delete unused method core.delete_server_files()
- replace exit call inside make_meta_url() with an AttributeError
........
r3838 | poeml | 2008-04-25 17:49:18 +0200 (Fri, 25 Apr 2008) | 1 line
simplify the check in do_checkout if a project exists, by using show_project_meta() instead of meta_exists
........
r3839 | poeml | 2008-04-25 18:31:26 +0200 (Fri, 25 Apr 2008) | 6 lines
- commandline do_checkout(): change the order of the two checks, first do the
(cheaper) check for existing directory
- core.core checkout_package(): simplify the check in if the package
exists, by using show_package_meta() instead of meta_exists
Let it throw an exception, instead of using sys.exit().
........
r3841 | Marcus_H | 2008-04-27 15:48:06 +0200 (Sun, 27 Apr 2008) | 5 lines
- added 2 new exception classes: PackageError() and PackageExistsError. The PackageError() class is meant to be the base class for all subsequent package exceptions.
- get rid of 2 sys.exit(1) calls
- make the update() method of the Project() class safer: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- minor fix in delPackage(): use getTransActPath() when printing out the filename
........
r3842 | Marcus_H | 2008-04-27 16:52:55 +0200 (Sun, 27 Apr 2008) | 3 lines
- make the commit() method safe: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- removed another sys.exit(1): raise an exception if a package is missing when doing a commit. For now we use the PackageExistsError() exception but this might change in the future (updated description of PackageExistsError() according to this change)
........
r3848 | poeml | 2008-04-28 12:46:45 +0200 (Mon, 28 Apr 2008) | 3 lines
rename several error classes, dropping the "Osc" prefix, and "Error" suffix in
cases where they don't really make sense.
........
r3849 | poeml | 2008-04-28 12:57:32 +0200 (Mon, 28 Apr 2008) | 3 lines
- rename osc.errors module to osc.oscerr, to make it easier to import it from
other programs and have a crystal clear namespace
........
r3850 | poeml | 2008-04-28 13:26:12 +0200 (Mon, 28 Apr 2008) | 2 lines
split PackageExists exception class into PackageExists and PackageMissing
........
2008-04-28 18:37:44 +02:00
2022-08-29 12:56:57 +02:00
if scm_url is not None :
2021-11-30 13:13:11 +01:00
return
2007-04-25 01:00:12 +02:00
# all packages
2009-04-17 10:39:04 +02:00
for package in meta_get_packagelist ( apiurl , project ) :
2015-09-25 17:02:35 +02:00
if opts . output_dir is not None :
outputdir = os . path . join ( opts . output_dir , package )
if not os . path . exists ( opts . output_dir ) :
os . mkdir ( os . path . join ( opts . output_dir ) )
else :
2022-04-20 19:22:35 +02:00
outputdir = None
2015-09-25 17:02:35 +02:00
2011-07-20 17:27:05 +02:00
# don't check out local links by default
try :
m = show_files_meta ( apiurl , project , package )
li = Linkinfo ( )
li . read ( ET . fromstring ( ' ' . join ( m ) ) . find ( ' linkinfo ' ) )
if not li . haserror ( ) :
2013-05-27 12:16:44 +02:00
if li . project == project :
print ( statfrmt ( ' S ' , package + " link to package " + li . package ) )
continue
2011-07-20 17:27:05 +02:00
except :
pass
2008-10-02 17:46:52 +02:00
try :
2022-09-12 13:43:10 +02:00
checkout_package ( apiurl , project , package , expand_link = expand_link ,
prj_dir = prj_dir , service_files = opts . source_service_files ,
server_service_files = opts . server_side_source_service_files ,
progress_obj = self . download_progress , size_limit = opts . limit_size ,
2016-06-15 15:28:10 +02:00
meta = opts . meta )
2013-04-09 11:27:02 +02:00
except oscerr . LinkExpandError as e :
2013-04-09 12:51:28 +02:00
print ( ' Link cannot be expanded: \n ' , e , file = sys . stderr )
print ( ' Use " osc repairlink " for fixing merge conflicts: \n ' , file = sys . stderr )
2008-10-02 17:46:52 +02:00
# check out in unexpanded form at least
2022-09-12 13:43:10 +02:00
checkout_package ( apiurl , project , package , expand_link = False ,
prj_dir = prj_dir , service_files = opts . source_service_files ,
server_service_files = opts . server_side_source_service_files ,
progress_obj = self . download_progress , size_limit = opts . limit_size ,
2013-05-27 13:03:46 +02:00
meta = opts . meta )
2023-07-17 09:01:42 +02:00
if os . isatty ( sys . stdout . fileno ( ) ) :
print_request_list ( apiurl , project )
2008-10-02 17:46:52 +02:00
2007-04-25 01:00:12 +02:00
else :
2022-01-19 15:13:55 +01:00
self . argparse_error ( " Incorrect number of arguments. " )
2007-04-25 01:00:12 +02:00
2010-08-11 18:05:12 +02:00
@cmdln.option ( ' -e ' , ' --show-excluded ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' also show files which are excluded by the '
2010-08-11 18:05:12 +02:00
' " exclude_glob " config option ' )
2007-04-25 01:00:12 +02:00
@cmdln.alias ( ' st ' )
def do_status ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Show status of files in working copy
2007-04-25 01:00:12 +02:00
Show the status of files in a local working copy , indicating whether
files have been changed locally , deleted , added , . . .
The first column in the output specifies the status and is one of the
following characters :
' ' no modifications
' A ' Added
' C ' Conflicted
' D ' Deleted
' M ' Modified
2017-10-03 22:05:41 +02:00
' R ' Replaced ( file was deleted and added again afterwards )
2007-04-25 01:00:12 +02:00
' ? ' item is not under version control
2009-07-15 23:16:34 +02:00
' ! ' item is missing ( removed by non - osc command ) or incomplete
2015-01-21 03:01:29 +01:00
' S ' item is skipped ( item exceeds a file size limit or is _service : * file )
2014-11-21 16:12:26 +01:00
' F ' Frozen ( use " osc pull " to merge conflicts ) ( package - only state )
2007-04-25 01:00:12 +02:00
examples :
osc st
osc st < directory >
osc st file1 file2 . . .
2009-05-18 16:50:43 +02:00
usage :
2007-04-25 01:00:12 +02:00
osc status [ OPTS ] [ PATH . . . ]
"""
2010-12-22 23:17:11 +01:00
args = parseargs ( args )
lines = [ ]
excl_states = ( ' ' , )
if opts . quiet :
excl_states + = ( ' ? ' , )
elif opts . verbose :
excl_states = ( )
2007-04-25 01:00:12 +02:00
for arg in args :
if is_project_dir ( arg ) :
2008-03-10 19:04:23 +01:00
prj = Project ( arg , False )
2010-12-22 23:17:11 +01:00
# don't exclude packages with state ' ' because the packages
# might have modified etc. files
prj_excl = [ st for st in excl_states if st != ' ' ]
2018-12-13 15:17:29 +01:00
for st , pac in sorted ( prj . get_status ( * prj_excl ) , key = cmp_to_key ( compare ) ) :
2010-12-22 23:17:11 +01:00
p = prj . get_pacobj ( pac )
if p is None :
# state is != ' '
lines . append ( statfrmt ( st , os . path . normpath ( os . path . join ( prj . dir , pac ) ) ) )
continue
2014-11-21 16:12:26 +01:00
if p . isfrozen ( ) :
lines . append ( statfrmt ( ' F ' , os . path . normpath ( os . path . join ( prj . dir , pac ) ) ) )
elif st == ' ' and opts . verbose or st != ' ' :
2010-12-22 23:17:11 +01:00
lines . append ( statfrmt ( st , os . path . normpath ( os . path . join ( prj . dir , pac ) ) ) )
states = p . get_status ( opts . show_excluded , * excl_states )
2018-12-13 15:17:29 +01:00
for st , filename in sorted ( states , key = cmp_to_key ( compare ) ) :
2010-12-22 23:17:11 +01:00
lines . append ( statfrmt ( st , os . path . normpath ( os . path . join ( p . dir , filename ) ) ) )
2007-04-25 01:00:12 +02:00
else :
2022-09-13 16:34:54 +02:00
p = Package ( arg )
2018-12-13 15:17:29 +01:00
for st , filename in sorted ( p . get_status ( opts . show_excluded , * excl_states ) , key = cmp_to_key ( compare ) ) :
2010-12-22 23:17:11 +01:00
lines . append ( statfrmt ( st , os . path . normpath ( os . path . join ( p . dir , filename ) ) ) )
2010-12-25 20:57:26 +01:00
if lines :
2013-04-09 12:51:28 +02:00
print ( ' \n ' . join ( lines ) )
2006-06-02 16:00:58 +02:00
2022-10-18 23:40:52 +02:00
2021-03-11 17:52:05 +01:00
@cmdln.option ( ' -f ' , ' --force ' , action = ' store_true ' ,
help = ' add files even if they are excluded by the exclude_glob config option ' )
2007-04-25 01:00:12 +02:00
def do_add ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Mark files to be added upon the next commit
2006-05-23 15:48:58 +02:00
2010-05-14 16:59:45 +02:00
In case a URL is given the file will get downloaded and registered to be downloaded
by the server as well via the download_url source service .
This is recommended for release tar balls to track their source and to help
others to review your changes esp . on version upgrades .
2009-05-18 16:50:43 +02:00
usage :
2010-05-14 16:59:45 +02:00
osc add URL [ URL . . . ]
2007-04-25 01:00:12 +02:00
osc add FILE [ FILE . . . ]
"""
if not args :
2022-01-19 15:13:55 +01:00
self . argparse_error ( " Incorrect number of arguments. " )
2006-05-23 15:48:58 +02:00
2010-05-14 16:59:45 +02:00
# Do some magic here, when adding a url. We want that the server to download the tar ball and to verify it
2010-05-14 16:44:42 +02:00
for arg in parseargs ( args ) :
2022-04-11 08:48:30 +02:00
if arg . endswith ( ' .git ' ) or arg . startswith ( ' git:// ' ) or \
2022-12-12 18:15:40 +01:00
arg . startswith ( ' git@ ' ) or ( arg . startswith ( ' https://github.com ' ) and ' /releases/ ' not in arg and ' /archive/ ' not in arg ) or \
2022-04-11 08:48:30 +02:00
arg . startswith ( ' https://gitlab.com ' ) :
2020-05-05 10:35:56 +02:00
addGitSource ( arg )
elif arg . startswith ( ' http:// ' ) or arg . startswith ( ' https:// ' ) or arg . startswith ( ' ftp:// ' ) :
addDownloadUrlService ( arg )
2016-08-26 17:12:09 +02:00
else :
2021-03-11 17:52:05 +01:00
addFiles ( [ arg ] , force = opts . force )
2006-05-23 15:48:58 +02:00
2022-10-18 23:40:52 +02:00
2008-03-10 19:04:23 +01:00
def do_mkpac ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Create a new package under version control
2006-09-29 15:15:41 +02:00
2008-03-10 19:04:23 +01:00
usage :
osc mkpac new_package
"""
2008-03-18 00:43:32 +01:00
if not conf . config [ ' do_package_tracking ' ] :
2022-09-12 13:43:10 +02:00
print ( " to use this feature you have to enable \' do_package_tracking \' "
" in the [general] section in the configuration file " , file = sys . stderr )
2008-03-18 00:43:32 +01:00
sys . exit ( 1 )
2008-03-10 19:04:23 +01:00
if len ( args ) != 1 :
Merged revisions 3774-3775,3779,3781-3782,3787,3789-3793,3798,3802,3805,3817-3822,3827,3829-3830,3837-3839,3841-3842,3848-3850 via svnmerge from
https://forgesvn1.novell.com/svn/opensuse/branches/buildservice/osc-exception-handling
........
r3774 | poeml | 2008-04-22 17:39:45 +0200 (Tue, 22 Apr 2008) | 3 lines
A first draft on implement systematic exception handling:
Add errors.py with some exceptions defined, and babysitter.py to handle them
........
r3775 | poeml | 2008-04-22 22:34:12 +0200 (Tue, 22 Apr 2008) | 9 lines
- new global options:
--debugger jump into the debugger before executing anything
--post-mortem jump into the debugger in case of errors
-t, --traceback print call trace in case of errors
- traceback and post_mortem can also be set in .oscrc.
- catch more errors (HTTPError).
- make config accessible from outside of the Osc instance, by making it a class
attribute
........
r3779 | poeml | 2008-04-23 00:55:49 +0200 (Wed, 23 Apr 2008) | 5 lines
- new global option:
-d, --debug print info useful for debugging
- catch some more errors (HTTPError), with OscHTTPError which isn't very
advanced yet.
........
r3781 | Marcus_H | 2008-04-23 01:02:00 +0200 (Wed, 23 Apr 2008) | 2 lines
- added OscConfigError class (just for testing).
- small change in the signature of the OscBaseError constructor (actually we should get rid of the 'args' tuple because it will be deprecated sooner or later
........
r3782 | Marcus_H | 2008-04-23 02:02:13 +0200 (Wed, 23 Apr 2008) | 2 lines
- access the prg.conf.config dict in a save way - this way we avoid AttributeErrors if the prg.conf.config dict doesn't exist
- in case of an configparser error we have to use the prg.options object directly (this was removed in r3781 by accident)
........
r3787 | poeml | 2008-04-23 09:23:56 +0200 (Wed, 23 Apr 2008) | 4 lines
- remove local exception handling from do_req
- for HTTPError, print details (headers and response) when in debug mode
- catch AttributeError
........
r3789 | poeml | 2008-04-23 16:23:14 +0200 (Wed, 23 Apr 2008) | 4 lines
- errors: add two new classes named OscWrongOptionsError and OscWrongArgsError
- commandline: raise instances of the new errors in a number of places
- commandline: add get_cmd_help() to Osc instance which returns the formatted help of a subcommand
........
r3790 | Marcus_H | 2008-04-23 16:48:28 +0200 (Wed, 23 Apr 2008) | 4 lines
- added 2 new exception classes: OscNoConfigfileError and OscIOError
- added new method write_config() to the conf.py module: This method writes osc's configuration file
- minor cleanups in the conf module
........
r3791 | poeml | 2008-04-23 17:11:07 +0200 (Wed, 23 Apr 2008) | 3 lines
small compatibility fix for r3790: try-except-finally isn't supported in
python-2.4.2, thus do the same as try-except inside a try-finally.
........
r3792 | poeml | 2008-04-23 17:37:53 +0200 (Wed, 23 Apr 2008) | 2 lines
fix up the remaining places regarding handling of errors related to commandline parsing
........
r3793 | poeml | 2008-04-23 17:40:34 +0200 (Wed, 23 Apr 2008) | 3 lines
raise a NoWorkingCopyError in osc.core.store_read_project() in case of an
IOError
........
r3798 | Marcus_H | 2008-04-23 23:55:24 +0200 (Wed, 23 Apr 2008) | 1 line
ported -r3797 from trunk
........
r3802 | Marcus_H | 2008-04-24 11:00:55 +0200 (Thu, 24 Apr 2008) | 1 line
ported -r3801 from trunk
........
r3805 | poeml | 2008-04-24 12:52:30 +0200 (Thu, 24 Apr 2008) | 2 lines
raise OscHTTPError in show_pattern_meta(), replacing local error handling
........
r3817 | poeml | 2008-04-24 20:21:32 +0200 (Thu, 24 Apr 2008) | 9 lines
- remove errors.OscHTTPError again.
it seems simpler to use urllib2.HTTPError instead (and just add a specific
error text message where appropriate, and re-raise)
- for 404s, check out _which_ part was not found
it is very ugly, but may be considered Good for pragmatic reasons
- removed local exception handling and workaround for returned 500's from
delete_package() and delete_project(), thereby getting rid of 4 possible exit
points.
........
r3818 | Marcus_H | 2008-04-24 22:36:17 +0200 (Thu, 24 Apr 2008) | 1 line
- this check is superfluous because every HTTPError instance has a code attribute
........
r3819 | poeml | 2008-04-25 00:39:39 +0200 (Fri, 25 Apr 2008) | 1 line
remove a forgotten debug line from core.delete_project()
........
r3820 | poeml | 2008-04-25 10:07:58 +0200 (Fri, 25 Apr 2008) | 2 lines
- ditch local error handling from wipebinaries(), rebuild(), and abortbuild()
........
r3821 | poeml | 2008-04-25 10:56:38 +0200 (Fri, 25 Apr 2008) | 2 lines
It is never needed to import the exception module.
........
r3822 | poeml | 2008-04-25 11:13:39 +0200 (Fri, 25 Apr 2008) | 4 lines
- when going into the debugger with --post-mortem, always print a traceback before
(thus implying -t)
- do not jump into the debugger if not on a TTY, or working in interactive mode
........
r3827 | poeml | 2008-04-25 13:07:46 +0200 (Fri, 25 Apr 2008) | 9 lines
- add errors.OscWorkingCopyOutdated, which takes a tuple with three args:
path to working copy, current rev, expected rev
- add handler for urllib2.URLError errors to the babysitter
- simplify the OscWrongArgsError and OscWrongOptionsError handlers, by removing
the extra line "Sorry, wrong ..." that was printed before the messages given
when the error was raised.
- remove one more errors.OscHTTPError which was still there, and raise
urllib2.HTTPError instead (show_package_meta())
........
r3829 | poeml | 2008-04-25 14:19:10 +0200 (Fri, 25 Apr 2008) | 11 lines
- comment some methods in osc.core which are used by nearly all do_* methods in
osc.commandline
- improve "is not a package/project dir" error messages, by printing the
absolute path tried, instead of '.' for the cwd
- make core.store_read_package() raise a proper NoWorkingCopyError instead of
terminating
- give attribution to things in babysitter.py copied from mercurial
- prefix HTTPError exceptions with 'Server returned an error:'
- remove obsolete local error handling from do_prjresults(), do_importsrcpkg(),
do_repos()
........
r3830 | poeml | 2008-04-25 14:29:35 +0200 (Fri, 25 Apr 2008) | 1 line
catch IOError exceptions in the babysitter
........
r3837 | poeml | 2008-04-25 17:27:36 +0200 (Fri, 25 Apr 2008) | 5 lines
- do_remotebuildlog: raise errors for wrong arguments, remove exits
- raise AttributeError in make_meta_url() instead of exiting
- delete unused method core.delete_server_files()
- replace exit call inside make_meta_url() with an AttributeError
........
r3838 | poeml | 2008-04-25 17:49:18 +0200 (Fri, 25 Apr 2008) | 1 line
simplify the check in do_checkout if a project exists, by using show_project_meta() instead of meta_exists
........
r3839 | poeml | 2008-04-25 18:31:26 +0200 (Fri, 25 Apr 2008) | 6 lines
- commandline do_checkout(): change the order of the two checks, first do the
(cheaper) check for existing directory
- core.core checkout_package(): simplify the check in if the package
exists, by using show_package_meta() instead of meta_exists
Let it throw an exception, instead of using sys.exit().
........
r3841 | Marcus_H | 2008-04-27 15:48:06 +0200 (Sun, 27 Apr 2008) | 5 lines
- added 2 new exception classes: PackageError() and PackageExistsError. The PackageError() class is meant to be the base class for all subsequent package exceptions.
- get rid of 2 sys.exit(1) calls
- make the update() method of the Project() class safer: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- minor fix in delPackage(): use getTransActPath() when printing out the filename
........
r3842 | Marcus_H | 2008-04-27 16:52:55 +0200 (Sun, 27 Apr 2008) | 3 lines
- make the commit() method safe: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- removed another sys.exit(1): raise an exception if a package is missing when doing a commit. For now we use the PackageExistsError() exception but this might change in the future (updated description of PackageExistsError() according to this change)
........
r3848 | poeml | 2008-04-28 12:46:45 +0200 (Mon, 28 Apr 2008) | 3 lines
rename several error classes, dropping the "Osc" prefix, and "Error" suffix in
cases where they don't really make sense.
........
r3849 | poeml | 2008-04-28 12:57:32 +0200 (Mon, 28 Apr 2008) | 3 lines
- rename osc.errors module to osc.oscerr, to make it easier to import it from
other programs and have a crystal clear namespace
........
r3850 | poeml | 2008-04-28 13:26:12 +0200 (Mon, 28 Apr 2008) | 2 lines
split PackageExists exception class into PackageExists and PackageMissing
........
2008-04-28 18:37:44 +02:00
raise oscerr . WrongArgs ( ' Wrong number of arguments. ' )
2008-03-15 23:51:37 +01:00
createPackageDir ( args [ 0 ] )
2006-05-23 15:48:58 +02:00
2022-10-18 23:40:52 +02:00
2008-08-20 21:24:55 +02:00
@cmdln.option ( ' -r ' , ' --recursive ' , action = ' store_true ' ,
help = ' If CWD is a project dir then scan all package dirs as well ' )
2009-05-11 15:21:33 +02:00
@cmdln.alias ( ' ar ' )
2007-04-25 01:00:12 +02:00
def do_addremove ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Adds new files , removes disappeared files
2006-04-20 16:26:50 +02:00
2007-04-25 01:00:12 +02:00
Adds all files new in the local copy , and removes all disappeared files .
2006-04-20 16:26:50 +02:00
2007-04-25 01:00:12 +02:00
ARG , if specified , is a package working copy .
"""
2006-05-11 09:27:50 +02:00
2007-04-25 01:00:12 +02:00
args = parseargs ( args )
2008-08-20 21:24:55 +02:00
arg_list = args [ : ]
for arg in arg_list :
2009-03-16 22:29:42 +01:00
if is_project_dir ( arg ) and conf . config [ ' do_package_tracking ' ] :
2008-08-20 21:24:55 +02:00
prj = Project ( arg , False )
for pac in prj . pacs_unvers :
pac_dir = getTransActPath ( os . path . join ( prj . dir , pac ) )
if os . path . isdir ( pac_dir ) :
addFiles ( [ pac_dir ] , prj )
for pac in prj . pacs_broken :
if prj . get_state ( pac ) != ' D ' :
prj . set_state ( pac , ' D ' )
2013-04-09 12:51:28 +02:00
print ( statfrmt ( ' D ' , getTransActPath ( os . path . join ( prj . dir , pac ) ) ) )
2008-08-20 21:24:55 +02:00
if opts . recursive :
for pac in prj . pacs_have :
state = prj . get_state ( pac )
2022-08-29 12:56:57 +02:00
if state is not None and state != ' D ' :
2008-08-20 21:24:55 +02:00
pac_dir = getTransActPath ( os . path . join ( prj . dir , pac ) )
args . append ( pac_dir )
args . remove ( arg )
prj . write_packages ( )
2009-03-16 22:29:42 +01:00
elif is_project_dir ( arg ) :
2022-09-12 13:43:10 +02:00
print ( ' osc: addremove is not supported in a project dir unless '
' \' do_package_tracking \' is enabled in the configuration file ' , file = sys . stderr )
2009-03-16 22:29:42 +01:00
sys . exit ( 1 )
2008-08-20 21:24:55 +02:00
2022-09-13 16:34:54 +02:00
pacs = Package . from_paths ( args )
2007-04-25 01:00:12 +02:00
for p in pacs :
2014-10-21 22:15:54 +02:00
todo = list ( set ( p . filenamelist + p . filenamelist_unvers + p . to_be_added ) )
for filename in todo :
2014-10-21 22:23:28 +02:00
abs_filename = os . path . join ( p . absdir , filename )
if os . path . isdir ( abs_filename ) :
2007-04-25 01:00:12 +02:00
continue
2007-07-06 13:20:30 +02:00
# ignore foo.rXX, foo.mine for files which are in 'C' state
if os . path . splitext ( filename ) [ 0 ] in p . in_conflict :
2009-10-20 16:30:15 +02:00
continue
2007-04-25 01:00:12 +02:00
state = p . status ( filename )
if state == ' ? ' :
2009-08-20 21:28:05 +02:00
# TODO: should ignore typical backup files suffix ~ or .orig
2007-04-25 01:00:12 +02:00
p . addfile ( filename )
2014-10-21 22:31:30 +02:00
elif state == ' D ' and os . path . isfile ( abs_filename ) :
# if the "deleted" file exists in the wc, track it again
p . addfile ( filename )
2007-04-25 01:00:12 +02:00
elif state == ' ! ' :
2010-09-06 15:28:23 +02:00
p . delete_file ( filename )
2013-04-09 12:51:28 +02:00
print ( statfrmt ( ' D ' , getTransActPath ( os . path . join ( p . dir , filename ) ) ) )
2007-04-25 01:00:12 +02:00
@cmdln.alias ( ' ci ' )
@cmdln.alias ( ' checkin ' )
2007-07-12 01:24:26 +02:00
@cmdln.option ( ' -m ' , ' --message ' , metavar = ' TEXT ' ,
help = ' specify log message TEXT ' )
2014-02-12 14:50:18 +01:00
@cmdln.option ( ' -n ' , ' --no-message ' , default = False , action = ' store_true ' ,
help = ' do not specify a log message ' )
2007-07-13 12:02:35 +02:00
@cmdln.option ( ' -F ' , ' --file ' , metavar = ' FILE ' ,
2011-03-30 23:33:30 +02:00
help = ' read log message from FILE, \' - \' denotes standard input. ' )
2009-08-03 15:03:24 +02:00
@cmdln.option ( ' -f ' , ' --force ' , default = False , action = " store_true " ,
2023-03-09 15:27:01 +01:00
help = ' Allow empty commit with no changes. When commiting a project, allow removing packages even if other packages depend on them. ' )
2023-05-04 14:39:17 +02:00
@cmdln.option ( " --skip-local-service-run " , " --noservice " , " --no-service " , default = False , action = " store_true " ,
help = " Skip run of local source services as specified in _service file. " )
2007-04-25 01:00:12 +02:00
def do_commit ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Upload content to the repository server
2007-04-25 01:00:12 +02:00
Upload content which is changed in your working copy , to the repository
server .
2009-05-18 16:50:43 +02:00
examples :
2007-04-25 01:00:12 +02:00
osc ci # current dir
osc ci < dir >
osc ci file1 file2 . . .
"""
2016-09-09 13:20:15 +02:00
try :
self . _commit ( subcmd , opts , args )
except oscerr . ExtRuntimeError as e :
2019-10-23 14:12:03 +02:00
pattern = re . compile ( " No such file " )
if " No such file " in e . msg :
editor = os . getenv ( ' EDITOR ' , default = get_default_editor ( ) )
print ( " Editor %s not found " % editor )
return 1
2016-09-09 13:20:15 +02:00
print ( " ERROR: service run failed " , e , file = sys . stderr )
return 1
except oscerr . PackageNotInstalled as e :
2016-09-09 13:23:55 +02:00
print ( " ERROR: please install %s " % e . args , end = ' ' )
2016-09-09 13:20:15 +02:00
print ( " or use the --noservice option " )
return 1
2008-05-21 15:44:49 +02:00
2016-09-09 13:20:15 +02:00
def _commit ( self , subcmd , opts , args ) :
args = parseargs ( args )
2011-09-10 22:56:26 +02:00
2010-05-22 08:51:04 +02:00
msg = ' '
2008-03-10 19:04:23 +01:00
if opts . message :
2022-07-07 15:38:14 +02:00
msg = opts . message
2008-03-10 19:04:23 +01:00
elif opts . file :
2011-03-30 23:33:30 +02:00
if opts . file == ' - ' :
msg = sys . stdin . read ( )
else :
try :
msg = open ( opts . file ) . read ( )
except :
sys . exit ( ' could not open file \' %s \' . ' % opts . file )
2023-05-04 14:39:17 +02:00
2011-09-07 15:19:54 +02:00
skip_local_service_run = False
if not conf . config [ ' local_service_run ' ] or opts . skip_local_service_run :
skip_local_service_run = True
2022-06-07 16:45:45 +02:00
for arg in args . copy ( ) :
2008-03-10 19:04:23 +01:00
if conf . config [ ' do_package_tracking ' ] and is_project_dir ( arg ) :
2016-09-09 13:20:15 +02:00
prj = Project ( arg )
2022-06-07 16:45:45 +02:00
if prj . scm_url :
2022-07-28 19:11:29 +02:00
print ( f " WARNING: Skipping project ' { prj . name } ' because it is managed in scm (git): { prj . scm_url } " )
2022-06-07 16:45:45 +02:00
args . remove ( arg )
continue
2016-09-09 13:20:15 +02:00
if not msg and not opts . no_message :
msg = edit_message ( )
# check any of the packages is a link, if so, as for branching
pacs = ( Package ( os . path . join ( prj . dir , pac ) )
for pac in prj . pacs_have if prj . get_state ( pac ) == ' ' )
can_branch = False
if any ( pac . is_link_to_different_project ( ) for pac in pacs ) :
2022-09-12 13:43:10 +02:00
repl = raw_input ( ' Some of the packages are links to a different project! \n '
2016-09-09 13:20:15 +02:00
' Create a local branch before commit? (y|N) ' )
2022-04-20 19:22:35 +02:00
if repl in ( ' y ' , ' Y ' ) :
2016-09-09 13:20:15 +02:00
can_branch = True
prj . commit ( msg = msg , skip_local_service_run = skip_local_service_run , verbose = opts . verbose , can_branch = can_branch )
2008-03-10 19:04:23 +01:00
args . remove ( arg )
2007-04-25 01:00:12 +02:00
2022-09-13 16:34:54 +02:00
pacs , no_pacs = Package . from_paths_nofail ( args )
2008-05-21 15:44:49 +02:00
2022-06-07 16:45:45 +02:00
for pac in pacs . copy ( ) :
if pac . scm_url :
2022-07-28 19:11:29 +02:00
print ( f " WARNING: Skipping package ' { pac . name } ' because it is managed in scm (git): { pac . scm_url } " )
2022-06-07 16:45:45 +02:00
pacs . remove ( pac )
continue
2017-08-04 14:06:24 +02:00
if conf . config [ ' do_package_tracking ' ] and ( pacs or no_pacs ) :
2008-03-10 19:04:23 +01:00
prj_paths = { }
single_paths = [ ]
files = { }
2010-09-09 12:30:49 +02:00
# XXX: this is really ugly
pac_objs = { }
2008-03-10 19:04:23 +01:00
# it is possible to commit packages from different projects at the same
# time: iterate over all pacs and put each pac to the right project in the dict
for pac in pacs :
path = os . path . normpath ( os . path . join ( pac . dir , os . pardir ) )
if is_project_dir ( path ) :
2017-08-04 14:48:01 +02:00
# use this path construction for computing "pac_name",
# because it is possible that pac.name != pac_name (e.g.
# for an external package wc)
pac_name = os . path . basename ( os . path . normpath ( pac . absdir ) )
prj_paths . setdefault ( path , [ ] ) . append ( pac_name )
2010-09-09 12:30:49 +02:00
pac_objs . setdefault ( path , [ ] ) . append ( pac )
2017-08-04 14:48:01 +02:00
files . setdefault ( path , { } ) [ pac_name ] = pac . todo
2008-03-10 19:04:23 +01:00
else :
single_paths . append ( pac . dir )
2011-05-26 16:39:12 +02:00
if not pac . todo :
pac . todo = pac . filenamelist + pac . filenamelist_unvers
pac . todo . sort ( )
2017-08-04 14:06:24 +02:00
for pac in no_pacs :
if os . path . exists ( pac ) :
# fail with an appropriate error message
2022-10-14 14:25:54 +02:00
Package ( pac )
2017-08-04 14:06:24 +02:00
path = os . path . normpath ( os . path . join ( pac , os . pardir ) )
if is_project_dir ( path ) :
2017-08-04 14:48:01 +02:00
pac_name = os . path . basename ( os . path . normpath ( os . path . abspath ( pac ) ) )
2017-08-04 14:06:24 +02:00
prj_paths . setdefault ( path , [ ] ) . append ( pac_name )
pac_objs . setdefault ( path , [ ] )
# wrt. the current implementation of Project.commit, this
# actually not needed
2017-08-04 14:48:01 +02:00
files . setdefault ( path , { } ) [ pac_name ] = [ ]
2017-08-04 14:06:24 +02:00
else :
# fail with an appropriate error message
2022-10-14 14:25:54 +02:00
Package ( pac )
2013-04-09 11:25:19 +02:00
for prj_path , packages in prj_paths . items ( ) :
2010-09-09 12:30:49 +02:00
prj = Project ( prj_path )
2014-02-12 14:50:18 +01:00
if not msg and not opts . no_message :
2010-12-26 13:33:14 +01:00
msg = get_commit_msg ( prj . absdir , pac_objs [ prj_path ] )
2014-02-25 16:51:39 +01:00
# check any of the packages is a link, if so, as for branching
can_branch = False
if any ( pac . is_link_to_different_project ( ) for pac in pacs ) :
2022-09-12 13:43:10 +02:00
repl = raw_input ( ' Some of the packages are links to a different project! \n '
2014-02-25 16:51:39 +01:00
' Create a local branch before commit? (y|N) ' )
2022-04-20 19:22:35 +02:00
if repl in ( ' y ' , ' Y ' ) :
2014-02-25 16:51:39 +01:00
can_branch = True
2017-08-04 14:48:01 +02:00
prj_files = files [ prj_path ]
prj . commit ( packages , msg = msg , files = prj_files , skip_local_service_run = skip_local_service_run , verbose = opts . verbose , can_branch = can_branch , force = opts . force )
2010-12-26 13:33:14 +01:00
store_unlink_file ( prj . absdir , ' _commit_msg ' )
2008-03-10 19:04:23 +01:00
for pac in single_paths :
2010-09-09 12:30:49 +02:00
p = Package ( pac )
2014-02-12 14:50:18 +01:00
if not msg and not opts . no_message :
2010-12-26 13:33:14 +01:00
msg = get_commit_msg ( p . absdir , [ p ] )
2015-04-29 13:43:23 +02:00
p . commit ( msg , skip_local_service_run = skip_local_service_run , verbose = opts . verbose , force = opts . force )
2010-12-26 13:33:14 +01:00
store_unlink_file ( p . absdir , ' _commit_msg ' )
2017-08-04 14:06:24 +02:00
elif no_pacs :
# fail with an appropriate error message
2022-10-14 14:25:54 +02:00
Package . from_paths ( no_pacs )
2008-03-10 19:04:23 +01:00
else :
for p in pacs :
2011-05-26 16:39:12 +02:00
if not p . todo :
p . todo = p . filenamelist + p . filenamelist_unvers
p . todo . sort ( )
2014-02-12 14:50:18 +01:00
if not msg and not opts . no_message :
2010-12-26 13:33:14 +01:00
msg = get_commit_msg ( p . absdir , [ p ] )
2015-04-29 13:43:23 +02:00
p . commit ( msg , skip_local_service_run = skip_local_service_run , verbose = opts . verbose , force = opts . force )
2010-12-26 13:33:14 +01:00
store_unlink_file ( p . absdir , ' _commit_msg ' )
2006-04-20 16:26:50 +02:00
2008-03-24 21:24:49 +01:00
@cmdln.option ( ' -r ' , ' --revision ' , metavar = ' REV ' ,
2007-07-04 14:55:26 +02:00
help = ' update to specified revision (this option will be ignored '
' if you are going to update the complete project or more than '
' one package) ' )
2017-12-03 16:45:36 +01:00
@cmdln.option ( ' ' , ' --linkrev ' , metavar = ' REV ' ,
2022-09-12 13:43:10 +02:00
help = ' revision of the link target that is used during link expansion ' )
2008-03-24 21:24:49 +01:00
@cmdln.option ( ' -u ' , ' --unexpand-link ' , action = ' store_true ' ,
help = ' if a package is an expanded link, update to the raw _link file ' )
@cmdln.option ( ' -e ' , ' --expand-link ' , action = ' store_true ' ,
help = ' if a package is a link, update to the expanded sources ' )
2009-09-03 16:56:48 +02:00
@cmdln.option ( ' -s ' , ' --source-service-files ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' Run local source services after update. ' )
2010-06-08 11:24:10 +02:00
@cmdln.option ( ' -S ' , ' --server-side-source-service-files ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' Use server side generated sources instead of local generation. ' )
2010-04-22 15:27:54 +02:00
@cmdln.option ( ' -l ' , ' --limit-size ' , metavar = ' limit_size ' ,
help = ' Skip all files with a given size ' )
2007-04-25 01:00:12 +02:00
@cmdln.alias ( ' up ' )
def do_update ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Update a working copy
2006-04-20 16:26:50 +02:00
2009-05-18 16:50:43 +02:00
examples :
2006-04-20 16:26:50 +02:00
2007-04-25 01:00:12 +02:00
1. osc up
If the current working directory is a package , update it .
If the directory is a project directory , update all contained
packages , AND check out newly added packages .
2006-05-23 15:48:58 +02:00
2007-04-25 01:00:12 +02:00
To update only checked out packages , without checking out new
ones , you might want to use " osc up * " from within the project
dir .
2006-05-23 15:48:58 +02:00
2007-04-25 01:00:12 +02:00
2. osc up PAC
Update the packages specified by the path argument ( s )
2006-04-20 16:26:50 +02:00
2008-03-24 21:24:49 +01:00
When - - expand - link is used with source link packages , the expanded
sources will be checked out . Without this option , the _link file and
patches will be checked out . The option - - unexpand - link can be used to
switch back to the " raw " source with a _link file plus patch ( es ) .
2007-04-25 01:00:12 +02:00
"""
2006-04-20 16:26:50 +02:00
2017-12-03 16:45:36 +01:00
if opts . expand_link and opts . unexpand_link :
raise oscerr . WrongOptions ( ' Sorry, the options --expand-link and '
' --unexpand-link and are mutually '
' exclusive. ' )
2009-08-12 01:01:03 +02:00
2007-04-25 01:00:12 +02:00
args = parseargs ( args )
2008-08-20 21:24:55 +02:00
arg_list = args [ : ]
2006-04-24 14:04:20 +02:00
2008-08-20 21:24:55 +02:00
for arg in arg_list :
2007-04-25 01:00:12 +02:00
if is_project_dir ( arg ) :
2010-02-09 20:57:10 +01:00
prj = Project ( arg , progress_obj = self . download_progress )
2022-06-23 07:56:30 +02:00
if prj . scm_url :
print ( " Please use git to update project " , prj . name )
continue
2006-04-20 16:26:50 +02:00
2008-03-10 19:04:23 +01:00
if conf . config [ ' do_package_tracking ' ] :
2009-05-18 16:50:43 +02:00
prj . update ( expand_link = opts . expand_link ,
2008-03-24 21:24:49 +01:00
unexpand_link = opts . unexpand_link )
2008-03-10 19:04:23 +01:00
args . remove ( arg )
2009-05-18 16:50:43 +02:00
else :
# if not tracking package, and 'update' is run inside a project dir,
2008-03-10 19:04:23 +01:00
# it should do the following:
# (a) update all packages
args + = prj . pacs_have
# (b) fetch new packages
2016-10-06 11:15:30 +02:00
prj . checkout_missing_pacs ( opts . expand_link , opts . unexpand_link )
2008-03-10 19:04:23 +01:00
args . remove ( arg )
2009-09-18 03:10:41 +02:00
print_request_list ( prj . apiurl , prj . name )
2006-06-06 12:50:40 +02:00
2009-06-09 11:34:25 +02:00
args . sort ( )
2022-09-13 16:34:54 +02:00
pacs = Package . from_paths ( args , progress_obj = self . download_progress )
2006-04-20 16:26:50 +02:00
2010-02-09 00:08:21 +01:00
if opts . revision and len ( args ) == 1 :
2007-07-04 14:55:26 +02:00
rev , dummy = parseRevisionOption ( opts . revision )
2008-02-18 14:44:20 +01:00
if not checkRevision ( pacs [ 0 ] . prjname , pacs [ 0 ] . name , rev , pacs [ 0 ] . apiurl ) :
2013-04-09 12:51:28 +02:00
print ( ' Revision \' %s \' does not exist ' % rev , file = sys . stderr )
2007-07-06 13:54:34 +02:00
sys . exit ( 1 )
2017-12-03 16:45:36 +01:00
if opts . expand_link or opts . unexpand_link :
meta = show_files_meta ( pacs [ 0 ] . apiurl , pacs [ 0 ] . prjname ,
pacs [ 0 ] . name , revision = rev ,
linkrev = opts . linkrev ,
expand = opts . server_side_source_service_files )
directory = ET . fromstring ( meta )
li_node = directory . find ( ' linkinfo ' )
if li_node is None :
print ( ' Revision \' %s \' is no link ' % rev , file = sys . stderr )
sys . exit ( 1 )
li = Linkinfo ( )
li . read ( li_node )
if li . haserror ( ) and opts . expand_link :
raise oscerr . LinkExpandError ( pacs [ 0 ] . prjname , pacs [ 0 ] . name ,
li . error )
rev = li . lsrcmd5
if opts . expand_link :
rev = li . xsrcmd5
if rev is None :
# 2 cases: a) unexpand and passed rev has linkerror
# b) expand and passed rev is already expanded
rev = directory . get ( ' srcmd5 ' )
2007-07-04 14:55:26 +02:00
else :
rev = None
2007-04-25 01:00:12 +02:00
for p in pacs :
if len ( pacs ) > 1 :
2013-04-09 12:51:28 +02:00
print ( ' Updating %s ' % p . name )
2008-03-24 21:24:49 +01:00
2010-08-25 11:55:56 +02:00
# this shouldn't be needed anymore with the new update mechanism
# an expand/unexpand update is treated like a normal update (there's nothing special)
2010-01-20 17:55:44 +01:00
# FIXME: ugly workaround for #399247
2010-08-25 11:55:56 +02:00
# if opts.expand_link or opts.unexpand_link:
# if [ i for i in p.filenamelist+p.filenamelist_unvers if p.status(i) != ' ' and p.status(i) != '?']:
# print >>sys.stderr, 'osc: cannot expand/unexpand because your working ' \
# 'copy has local modifications.\nPlease revert/commit them ' \
# 'and try again.'
# sys.exit(1)
2022-06-23 07:56:30 +02:00
if p . scm_url :
print ( " Please use git to update package " , p . name )
continue
2009-04-06 22:08:14 +02:00
2008-11-19 13:13:18 +01:00
if not rev :
2016-02-08 17:24:35 +01:00
if opts . expand_link :
2012-03-28 23:14:28 +02:00
rev = p . latest_rev ( expand = True )
2016-02-08 17:24:35 +01:00
if p . islink ( ) and not p . isexpanded ( ) :
print ( ' Expanding to rev ' , rev )
2008-11-19 13:13:18 +01:00
elif opts . unexpand_link and p . islink ( ) and p . isexpanded ( ) :
2012-03-28 23:14:28 +02:00
rev = show_upstream_rev ( p . apiurl , p . prjname , p . name , meta = p . meta )
2013-04-09 12:51:28 +02:00
print ( ' Unexpanding to rev ' , rev )
2011-06-09 17:20:51 +02:00
elif ( p . islink ( ) and p . isexpanded ( ) ) or opts . server_side_source_service_files :
2011-05-23 15:26:13 +02:00
rev = p . latest_rev ( include_service_files = opts . server_side_source_service_files )
2008-03-24 21:24:49 +01:00
2010-06-08 11:24:10 +02:00
p . update ( rev , opts . server_side_source_service_files , opts . limit_size )
if opts . source_service_files :
2013-04-09 12:51:28 +02:00
print ( ' Running local source services ' )
2010-06-08 11:24:10 +02:00
p . run_source_services ( )
2010-01-20 17:55:44 +01:00
if opts . unexpand_link :
p . unmark_frozen ( )
2008-06-11 10:29:27 +02:00
rev = None
2009-09-18 03:10:41 +02:00
print_request_list ( p . apiurl , p . prjname , p . name )
2009-05-18 16:50:43 +02:00
2008-03-10 19:04:23 +01:00
@cmdln.option ( ' -f ' , ' --force ' , action = ' store_true ' ,
2009-05-04 21:07:05 +02:00
help = ' forces removal of entire package and its files ' )
2007-04-25 01:00:12 +02:00
@cmdln.alias ( ' rm ' )
@cmdln.alias ( ' del ' )
@cmdln.alias ( ' remove ' )
def do_delete ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Mark files or package directories to be deleted upon the next ' checkin '
2006-05-22 12:50:37 +02:00
2009-05-18 16:50:43 +02:00
usage :
2009-10-08 16:21:43 +02:00
cd . . . / PROJECT / PACKAGE
osc delete FILE [ . . . ]
cd . . . / PROJECT
osc delete PACKAGE [ . . . ]
2009-05-04 21:07:05 +02:00
This command works on check out copies . Use " rdelete " for working on server
side only . This is needed for removing the entire project .
2009-10-08 16:21:43 +02:00
As a safety measure , projects must be empty ( i . e . , you need to delete all
2009-10-20 16:30:15 +02:00
packages first ) .
2009-10-08 16:21:43 +02:00
If you are sure that you want to remove a package and all
its files use \' --force \' switch. Sometimes this also works without --force.
2007-04-25 01:00:12 +02:00
"""
2006-05-22 12:50:37 +02:00
2007-04-25 01:00:12 +02:00
if not args :
2022-01-19 15:13:55 +01:00
self . argparse_error ( " Incorrect number of arguments. " )
2006-06-26 17:11:22 +02:00
2007-04-25 01:00:12 +02:00
args = parseargs ( args )
2008-03-10 19:04:23 +01:00
# check if args contains a package which was removed by
# a non-osc command and mark it with the 'D'-state
2008-08-20 21:24:55 +02:00
arg_list = args [ : ]
for i in arg_list :
2008-03-10 19:04:23 +01:00
if not os . path . exists ( i ) :
prj_dir , pac_dir = getPrjPacPaths ( i )
if is_project_dir ( prj_dir ) :
prj = Project ( prj_dir , False )
if i in prj . pacs_broken :
if prj . get_state ( i ) != ' A ' :
prj . set_state ( pac_dir , ' D ' )
else :
prj . del_package_node ( i )
2013-04-09 12:51:28 +02:00
print ( statfrmt ( ' D ' , getTransActPath ( i ) ) )
2008-03-10 19:04:23 +01:00
args . remove ( i )
prj . write_packages ( )
2022-09-13 16:34:54 +02:00
pacs = Package . from_paths ( args )
2006-04-20 16:26:50 +02:00
2007-04-25 01:00:12 +02:00
for p in pacs :
2008-03-10 19:04:23 +01:00
if not p . todo :
prj_dir , pac_dir = getPrjPacPaths ( p . absdir )
2009-05-04 21:07:05 +02:00
if is_project_dir ( prj_dir ) :
2009-10-20 16:30:15 +02:00
if conf . config [ ' do_package_tracking ' ] :
prj = Project ( prj_dir , False )
prj . delPackage ( p , opts . force )
else :
2013-04-09 12:51:28 +02:00
print ( " WARNING: package tracking is disabled, operation skipped ! " , file = sys . stderr )
2008-03-10 19:04:23 +01:00
else :
pathn = getTransActPath ( p . dir )
for filename in p . todo :
2010-07-28 12:13:46 +02:00
p . clear_from_conflictlist ( filename )
2009-07-15 23:10:38 +02:00
ret , state = p . delete_file ( filename , opts . force )
if ret :
2013-04-09 12:51:28 +02:00
print ( statfrmt ( ' D ' , os . path . join ( pathn , filename ) ) )
2009-07-15 23:10:38 +02:00
continue
if state == ' ? ' :
2008-03-10 19:04:23 +01:00
sys . exit ( ' \' %s \' is not under version control ' % filename )
2022-09-30 14:09:37 +02:00
elif state in ( ' A ' , ' M ' ) and not opts . force :
2009-07-15 23:10:38 +02:00
sys . exit ( ' \' %s \' has local modifications (use --force to remove this file) ' % filename )
2011-01-18 19:38:33 +01:00
elif state == ' S ' :
sys . exit ( ' \' %s \' is marked as skipped and no local file with this name exists ' % filename )
2006-05-23 15:48:58 +02:00
2007-04-25 01:00:12 +02:00
def do_resolved ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Remove ' conflicted ' state on working copy files
2009-05-18 16:50:43 +02:00
2007-04-25 01:00:12 +02:00
If an upstream change can ' t be merged automatically, a file is put into
in ' conflicted ' ( ' C ' ) state . Within the file , conflicts are marked with
special << << << < as well as == == == == and >> >> >> > lines .
2009-05-18 16:50:43 +02:00
2007-04-25 01:00:12 +02:00
After manually resolving all conflicting parts , use this command to
remove the ' conflicted ' state .
Note : this subcommand does not semantically resolve conflicts or
remove conflict markers ; it merely removes the conflict - related
artifact files and allows PATH to be committed again .
2006-05-23 15:48:58 +02:00
2009-05-18 16:50:43 +02:00
usage :
2007-04-25 01:00:12 +02:00
osc resolved FILE [ FILE . . . ]
"""
2006-05-23 15:48:58 +02:00
2007-04-25 01:00:12 +02:00
if not args :
2022-01-19 15:13:55 +01:00
self . argparse_error ( " Incorrect number of arguments. " )
2006-04-20 16:26:50 +02:00
2007-04-25 01:00:12 +02:00
args = parseargs ( args )
2022-09-13 16:34:54 +02:00
pacs = Package . from_paths ( args )
2006-04-28 17:37:25 +02:00
2007-04-25 01:00:12 +02:00
for p in pacs :
for filename in p . todo :
2013-04-09 12:51:28 +02:00
print ( ' Resolved conflicted state of " %s " ' % filename )
2007-04-25 01:00:12 +02:00
p . clear_from_conflictlist ( filename )
2006-04-20 16:26:50 +02:00
2010-07-28 16:04:27 +02:00
@cmdln.alias ( ' dists ' )
def do_distributions ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Shows all available distributions
2010-07-28 16:04:27 +02:00
2010-08-13 00:30:05 +02:00
This command shows the available distributions . For active distributions
2014-08-12 15:01:16 +02:00
it shows the name , project and name of the repository and a suggested default repository name .
2010-07-28 16:04:27 +02:00
usage :
2014-08-12 15:01:16 +02:00
osc distributions
2010-07-28 16:04:27 +02:00
"""
apiurl = self . get_api_url ( )
2022-07-29 22:00:41 +02:00
dists = get_distributions ( apiurl )
if dists :
headers = dists [ 0 ] . keys ( )
rows = [ ]
for dist in dists :
rows . append ( [ dist [ h ] for h in headers ] )
2022-07-29 22:06:22 +02:00
print ( format_table ( rows , headers ) . rstrip ( ) )
2022-07-29 22:00:41 +02:00
2009-07-07 16:30:15 +02:00
@cmdln.option ( ' -f ' , ' --force ' , action = ' store_true ' , default = False ,
help = " Don ' t ask and delete files " )
2022-09-20 10:03:13 +02:00
@cmdln.option ( ' project ' )
@cmdln.option ( ' package ' )
@cmdln.option ( ' files ' , metavar = " file " , nargs = ' + ' )
def do_rremove ( self , subcmd , opts ) :
2022-01-19 15:13:55 +01:00
"""
Remove source files from selected package
2009-07-07 16:30:15 +02:00
"""
2022-09-20 10:03:13 +02:00
project = opts . project
package = opts . package
files = opts . files
2010-08-13 00:30:05 +02:00
apiurl = self . get_api_url ( )
2009-07-07 16:30:15 +02:00
if len ( files ) == 0 :
2022-09-12 14:15:34 +02:00
if ' / ' not in project :
2009-07-07 16:30:15 +02:00
raise oscerr . WrongArgs ( " Missing operand, type osc help rremove for help " )
else :
files = ( package , )
project , package = project . split ( ' / ' )
2010-08-20 14:34:41 +02:00
for filename in files :
2009-07-07 16:30:15 +02:00
if not opts . force :
2010-08-20 14:34:41 +02:00
resp = raw_input ( " rm: remove source file ` %s ' from ` %s / %s ' ? (yY|nN) " % ( filename , project , package ) )
2009-07-07 16:30:15 +02:00
if resp not in ( ' y ' , ' Y ' ) :
continue
try :
2010-08-20 14:34:41 +02:00
delete_files ( apiurl , project , package , ( filename , ) )
2013-04-09 14:03:17 +02:00
except HTTPError as e :
2009-07-07 16:30:15 +02:00
if opts . force :
2013-04-09 12:51:28 +02:00
print ( e , file = sys . stderr )
2009-07-07 16:30:15 +02:00
body = e . read ( )
2022-10-08 13:24:08 +02:00
if e . code in ( 400 , 403 , 404 , 500 ) :
2009-07-07 16:30:15 +02:00
if ' <summary> ' in body :
msg = body . split ( ' <summary> ' ) [ 1 ]
msg = msg . split ( ' </summary> ' ) [ 0 ]
2013-04-09 12:51:28 +02:00
print ( msg , file = sys . stderr )
2009-07-07 16:30:15 +02:00
else :
raise e
2008-06-17 08:12:48 +02:00
@cmdln.alias ( ' r ' )
2009-02-23 13:25:56 +01:00
@cmdln.option ( ' -l ' , ' --last-build ' , action = ' store_true ' ,
help = ' show last build results (succeeded/failed/unknown) ' )
2022-09-12 13:43:10 +02:00
@cmdln.option ( ' -r ' , ' --repo ' , action = ' append ' , default = [ ] ,
2009-05-15 09:16:26 +02:00
help = ' Show results only for specified repo(s) ' )
2022-09-12 13:43:10 +02:00
@cmdln.option ( ' -a ' , ' --arch ' , action = ' append ' , default = [ ] ,
2009-05-15 09:16:26 +02:00
help = ' Show results only for specified architecture(s) ' )
2020-06-19 08:32:00 +02:00
@cmdln.option ( ' -b ' , ' --brief ' , action = ' store_true ' ,
help = ' show the result in " pkgname repo arch result " . Default for -f ' )
2017-01-17 16:45:06 +01:00
@cmdln.option ( ' --no-multibuild ' , action = ' store_true ' , default = False ,
2022-09-12 13:43:10 +02:00
help = ' Disable results for all direct affect packages inside of the project ' )
2022-05-10 10:19:09 +02:00
@cmdln.option ( ' -M ' , ' --multibuild-package ' , metavar = ' FLAVOR ' , action = ' append ' , default = [ ] ,
help = HELP_MULTIBUILD_MANY )
2020-01-30 14:39:27 +01:00
@cmdln.option ( ' -V ' , ' --vertical ' , action = ' store_true ' ,
help = ' list packages vertically instead horizontally for entire project ' )
2018-11-05 22:57:14 +01:00
@cmdln.option ( ' -w ' , ' --watch ' , action = ' store_true ' ,
2012-01-24 09:59:23 +01:00
help = ' watch the results until all finished building ' )
2020-06-19 08:32:00 +02:00
@cmdln.option ( ' -s ' , ' --status-filter ' ,
help = ' only show packages with the given build status ' )
@cmdln.option ( ' -f ' , ' --failed ' , action = ' store_true ' ,
help = ' show only failed results ' )
2010-04-20 15:38:52 +02:00
@cmdln.option ( ' ' , ' --xml ' , action = ' store_true ' , default = False ,
2022-09-12 13:43:10 +02:00
help = ' generate output in XML (former results_meta) ' )
2010-04-20 15:38:52 +02:00
@cmdln.option ( ' ' , ' --csv ' , action = ' store_true ' , default = False ,
2022-09-12 13:43:10 +02:00
help = ' generate output in CSV format ' )
2010-04-20 15:38:52 +02:00
@cmdln.option ( ' ' , ' --format ' , default = ' %(repository)s | %(arch)s | %(state)s | %(dirty)s | %(code)s | %(details)s ' ,
2022-09-12 13:43:10 +02:00
help = ' format string for csv output ' )
2017-04-07 10:01:20 +02:00
@cmdln.option ( ' --show-excluded ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' show repos that are excluded for this package ' )
2007-04-25 01:00:12 +02:00
def do_results ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Shows the build results of a package or project
2006-04-20 16:26:50 +02:00
2022-01-19 15:13:55 +01:00
usage :
2010-12-02 23:36:40 +01:00
osc results # (inside working copy of PRJ or PKG)
2022-05-10 10:19:09 +02:00
osc results PROJECT [ PACKAGE [ : FLAVOR ] ]
2008-05-16 14:25:50 +02:00
"""
2009-05-25 13:33:04 +02:00
2009-05-10 22:29:34 +02:00
args = slash_split ( args )
2009-08-20 21:28:05 +02:00
2010-04-30 17:13:21 +02:00
apiurl = self . get_api_url ( )
2012-04-04 10:28:27 +02:00
if len ( args ) > 2 :
2010-12-02 23:36:40 +01:00
raise oscerr . WrongArgs ( ' Too many arguments (required none, one, or two) ' )
2012-04-04 10:28:27 +02:00
project = package = None
2022-10-07 17:25:33 +02:00
wd = Path . cwd ( )
2012-04-04 10:28:27 +02:00
if is_project_dir ( wd ) :
project = store_read_project ( wd )
elif is_package_dir ( wd ) :
project = store_read_project ( wd )
package = store_read_package ( wd )
if len ( args ) > 0 :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2012-04-04 10:28:27 +02:00
if len ( args ) > 1 :
2009-05-25 13:33:04 +02:00
package = args [ 1 ]
2009-05-18 16:50:43 +02:00
2022-08-29 12:56:57 +02:00
if project is None :
2012-04-04 10:28:27 +02:00
raise oscerr . WrongOptions ( " No project given " )
2020-06-19 08:32:00 +02:00
if opts . failed and opts . status_filter :
raise oscerr . WrongArgs ( ' -s and -f cannot be used together ' )
if opts . failed :
opts . status_filter = ' failed '
opts . brief = True
2022-08-29 12:56:57 +02:00
if package is None :
2012-04-04 10:28:27 +02:00
opts . hide_legend = None
opts . name_filter = None
opts . show_non_building = None
opts . show_excluded = None
2019-02-04 13:07:59 +01:00
return self . do_prjresults ( ' prjresults ' , opts , * args )
2012-04-04 10:28:27 +02:00
2010-04-20 15:38:52 +02:00
if opts . xml and opts . csv :
raise oscerr . WrongOptions ( " --xml and --csv are mutual exclusive " )
2016-02-07 00:55:23 +01:00
kwargs = { ' apiurl ' : apiurl , ' project ' : project , ' package ' : package ,
' lastbuild ' : opts . last_build , ' repository ' : opts . repo ,
2020-06-19 08:32:00 +02:00
' arch ' : opts . arch , ' wait ' : opts . watch , ' showexcl ' : opts . show_excluded ,
' code ' : opts . status_filter }
2016-11-23 15:35:09 +01:00
if opts . multibuild_package :
2017-01-17 16:45:06 +01:00
opts . no_multibuild = False
2022-05-10 10:19:09 +02:00
resolver = MultibuildFlavorResolver ( apiurl , project , package , use_local = False )
kwargs [ ' multibuild_packages ' ] = resolver . resolve ( opts . multibuild_package )
2017-01-17 16:45:06 +01:00
if not opts . no_multibuild :
kwargs [ ' multibuild ' ] = kwargs [ ' locallink ' ] = True
2016-02-07 00:55:23 +01:00
if opts . xml or opts . csv :
2017-05-17 23:33:27 +02:00
# hmm should we filter excluded repos here as well?
# for now, ignore --show-excluded
del kwargs [ ' showexcl ' ]
2016-02-07 00:55:23 +01:00
for xml in get_package_results ( * * kwargs ) :
if opts . xml :
2018-12-13 15:17:29 +01:00
print ( decode_it ( xml ) , end = ' ' )
2016-02-07 00:55:23 +01:00
else :
# csv formatting
2017-01-12 15:33:26 +01:00
results = [ r for r , _ in result_xml_to_dicts ( xml ) ]
2016-02-07 00:55:23 +01:00
print ( ' \n ' . join ( format_results ( results , opts . format ) ) )
2010-04-20 15:38:52 +02:00
else :
2016-02-07 00:55:23 +01:00
kwargs [ ' verbose ' ] = opts . verbose
kwargs [ ' wait ' ] = opts . watch
kwargs [ ' printJoin ' ] = ' \n '
get_results ( * * kwargs )
2010-01-14 15:20:00 +01:00
# WARNING: this function is also called by do_results. You need to set a default there
# as well when adding a new option!
2022-09-12 13:43:10 +02:00
2020-06-19 08:32:00 +02:00
@cmdln.option ( ' -b ' , ' --brief ' , action = ' store_true ' ,
help = ' show the result in " pkgname repo arch result " ' )
2018-11-05 22:57:14 +01:00
@cmdln.option ( ' -w ' , ' --watch ' , action = ' store_true ' ,
help = ' watch the results until all finished building, only supported with --xml ' )
2008-03-13 12:13:22 +01:00
@cmdln.option ( ' -c ' , ' --csv ' , action = ' store_true ' ,
2008-02-12 13:45:06 +01:00
help = ' csv output ' )
2013-01-18 16:56:13 +01:00
@cmdln.option ( ' ' , ' --xml ' , action = ' store_true ' , default = False ,
2022-09-12 13:43:10 +02:00
help = ' generate output in XML ' )
2008-05-15 20:09:24 +02:00
@cmdln.option ( ' -s ' , ' --status-filter ' , metavar = ' STATUS ' ,
help = ' show only packages with buildstatus STATUS (see legend) ' )
@cmdln.option ( ' -n ' , ' --name-filter ' , metavar = ' EXPR ' ,
2008-08-19 21:37:08 +02:00
help = ' show only packages whose names match EXPR ' )
2017-09-28 15:23:02 +02:00
@cmdln.option ( ' -a ' , ' --arch ' , metavar = ' ARCH ' , action = ' append ' ,
2009-10-15 16:24:12 +02:00
help = ' show results only for specified architecture(s) ' )
2017-09-28 15:23:02 +02:00
@cmdln.option ( ' -r ' , ' --repo ' , metavar = ' REPO ' , action = ' append ' ,
2009-10-15 16:24:12 +02:00
help = ' show results only for specified repo(s) ' )
2010-01-11 16:36:21 +01:00
@cmdln.option ( ' -V ' , ' --vertical ' , action = ' store_true ' ,
help = ' list packages vertically instead horizontally ' )
2010-08-04 17:16:59 +02:00
@cmdln.option ( ' --show-excluded ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' show packages that are excluded in all repos, also hide repos that have only excluded packages ' )
2008-06-17 08:12:48 +02:00
@cmdln.alias ( ' pr ' )
2007-04-25 01:00:12 +02:00
def do_prjresults ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Shows project - wide build results
2009-05-18 16:50:43 +02:00
2022-01-19 15:13:55 +01:00
usage :
2009-05-25 13:33:04 +02:00
osc prjresults ( inside working copy )
2010-01-11 16:36:21 +01:00
osc prjresults PROJECT
2007-04-25 01:00:12 +02:00
"""
2010-04-30 17:13:21 +02:00
apiurl = self . get_api_url ( )
2006-04-29 22:44:09 +02:00
2009-05-25 13:33:04 +02:00
if args :
if len ( args ) == 1 :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2008-08-19 21:37:08 +02:00
else :
2010-01-11 16:36:21 +01:00
raise oscerr . WrongArgs ( ' Wrong number of arguments. ' )
2009-05-25 13:33:04 +02:00
else :
2022-10-07 17:25:33 +02:00
wd = Path . cwd ( )
2008-08-19 21:37:08 +02:00
project = store_read_project ( wd )
2006-05-23 15:48:58 +02:00
2013-01-18 16:56:13 +01:00
if opts . xml :
2018-11-05 22:57:14 +01:00
kwargs = { }
if opts . repo :
kwargs [ ' repository ' ] = opts . repo
if opts . arch :
kwargs [ ' arch ' ] = opts . arch
kwargs [ ' wait ' ] = opts . watch
for results in get_package_results ( apiurl , project , * * kwargs ) :
2018-12-13 15:17:29 +01:00
print ( decode_it ( results ) )
2013-01-18 16:56:13 +01:00
return
2018-11-05 22:57:14 +01:00
if opts . watch :
print ( ' Please implement support for osc prjresults --watch without --xml. ' )
return 2
2022-09-12 13:43:10 +02:00
print ( ' \n ' . join ( get_prj_results ( apiurl , project , hide_legend = opts . quiet ,
csv = opts . csv , status_filter = opts . status_filter ,
name_filter = opts . name_filter , repo = opts . repo ,
arch = opts . arch , vertical = opts . vertical ,
2020-06-19 08:32:00 +02:00
show_excluded = opts . show_excluded , brief = opts . brief ) ) )
2008-05-16 14:25:50 +02:00
2017-08-30 17:08:12 +02:00
@cmdln.alias ( ' rpmlint ' )
@cmdln.alias ( ' lint ' )
def do_rpmlintlog ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Shows the rpmlint logfile
2017-08-30 17:08:12 +02:00
Shows the rpmlint logfile to analyse if there are any problems
with the spec file and the built binaries .
usage :
osc rpmlintlog project package repository arch
"""
apiurl = self . get_api_url ( )
2017-09-01 10:51:28 +02:00
args = slash_split ( args )
2017-08-30 17:08:12 +02:00
if len ( args ) == 4 :
project , package , repository , arch = args
else :
raise oscerr . WrongArgs ( ' please provide project package repository arch. ' )
2018-12-13 15:17:29 +01:00
print ( decode_it ( get_rpmlint_log ( apiurl , project , package , repository , arch ) ) )
2017-08-30 17:08:12 +02:00
2007-07-12 01:24:26 +02:00
@cmdln.alias ( ' bl ' )
2011-01-07 23:05:44 +01:00
@cmdln.alias ( ' blt ' )
@cmdln.alias ( ' buildlogtail ' )
2013-08-13 10:38:43 +02:00
@cmdln.option ( ' -l ' , ' --last ' , action = ' store_true ' ,
help = ' Show the last finished log file ' )
2021-01-15 11:21:40 +01:00
@cmdln.option ( ' --lastsucceeded ' , ' --last-succeeded ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' Show the last succeeded log file ' )
2022-05-10 10:44:33 +02:00
@cmdln.option ( ' -M ' , ' --multibuild-package ' , metavar = ' FLAVOR ' ,
help = HELP_MULTIBUILD_ONE )
2011-01-07 23:05:44 +01:00
@cmdln.option ( ' -o ' , ' --offset ' , metavar = ' OFFSET ' ,
2022-09-12 13:43:10 +02:00
help = ' get log start or end from the offset ' )
2012-12-15 01:50:24 +01:00
@cmdln.option ( ' -s ' , ' --strip-time ' , action = ' store_true ' ,
help = ' strip leading build time from the log ' )
2009-11-23 11:13:19 +01:00
def do_buildlog ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Shows the build log of a package
2007-04-25 01:00:12 +02:00
Shows the log file of the build of a package . Can be used to follow the
log while it is being written .
Needs to be called from within a package directory .
2006-05-23 15:48:58 +02:00
2011-01-07 23:05:44 +01:00
When called as buildlogtail ( or blt ) it just shows the end of the logfile .
2011-04-28 11:14:38 +02:00
This is useful to see just a build failure reasons .
2011-01-07 23:05:44 +01:00
2009-09-08 10:14:27 +02:00
The arguments REPOSITORY and ARCH are the first two columns in the ' osc
2010-02-16 13:49:14 +01:00
results ' output. If the buildlog url is used buildlog command has the
same behavior as remotebuildlog .
2007-04-25 01:00:12 +02:00
2022-01-19 15:13:55 +01:00
buildlog [ REPOSITORY ARCH | BUILDLOGURL ]
2007-04-25 01:00:12 +02:00
"""
2016-02-05 16:10:43 +01:00
project = package = repository = arch = None
2010-02-16 13:49:14 +01:00
2010-04-30 17:13:21 +02:00
apiurl = self . get_api_url ( )
2010-02-16 13:49:14 +01:00
if len ( args ) == 1 and args [ 0 ] . startswith ( ' http ' ) :
apiurl , project , package , repository , arch = parse_buildlogurl ( args [ 0 ] )
else :
2022-10-07 17:25:33 +02:00
project = store_read_project ( Path . cwd ( ) )
package = store_read_package ( Path . cwd ( ) )
2016-02-05 16:10:43 +01:00
if len ( args ) == 1 :
repository , arch = self . _find_last_repo_arch ( args [ 0 ] , fatal = False )
if repository is None :
# no local build with this repo was done
print ( ' failed to guess arch, using hostarch ' )
repository = args [ 0 ]
2022-09-09 11:46:28 +02:00
arch = osc_build . hostarch
2016-02-05 16:10:43 +01:00
elif len ( args ) < 2 :
self . print_repos ( )
elif len ( args ) > 2 :
raise oscerr . WrongArgs ( ' Too many arguments. ' )
else :
repository = args [ 0 ]
arch = args [ 1 ]
2007-03-13 00:21:34 +01:00
2017-02-14 17:09:16 +01:00
if opts . multibuild_package :
package = package + " : " + opts . multibuild_package
2013-05-27 12:41:50 +02:00
offset = 0
2022-09-30 14:09:37 +02:00
if subcmd in ( " blt " , " buildlogtail " ) :
2022-09-12 13:43:10 +02:00
query = { ' view ' : ' entry ' }
2013-08-13 10:38:43 +02:00
if opts . last :
query [ ' last ' ] = 1
2021-01-15 11:21:40 +01:00
if opts . lastsucceeded :
query [ ' lastsucceeded ' ] = 1
2020-04-28 14:00:00 +02:00
u = makeurl ( self . get_api_url ( ) , [ ' build ' , quote_plus ( project ) , quote_plus ( repository ) , quote_plus ( arch ) , quote_plus ( package ) , ' _log ' ] , query = query )
2011-01-07 23:05:44 +01:00
f = http_GET ( u )
root = ET . parse ( f ) . getroot ( )
offset = int ( root . find ( ' entry ' ) . get ( ' size ' ) )
if opts . offset :
offset = offset - int ( opts . offset )
else :
2022-09-12 13:43:10 +02:00
offset = offset - ( 8 * 1024 )
2011-01-07 23:05:44 +01:00
if offset < 0 :
2013-05-27 12:41:50 +02:00
offset = 0
2011-01-07 23:05:44 +01:00
elif opts . offset :
offset = int ( opts . offset )
2012-12-15 01:50:24 +01:00
strip_time = opts . strip_time or conf . config [ ' buildlog_strip_time ' ]
2021-01-15 11:21:40 +01:00
print_buildlog ( apiurl , quote_plus ( project ) , quote_plus ( package ) , quote_plus ( repository ) , quote_plus ( arch ) , offset , strip_time , opts . last , opts . lastsucceeded )
2008-01-03 23:10:16 +01:00
2019-08-30 10:32:02 +02:00
def print_repos ( self , repos_only = False , exc_class = oscerr . WrongArgs , exc_msg = ' Missing arguments ' , project = None ) :
2022-10-07 17:25:33 +02:00
wd = Path . cwd ( )
2010-02-27 20:11:15 +01:00
doprint = False
if is_package_dir ( wd ) :
2019-08-30 10:32:02 +02:00
msg = ' Valid arguments for this package are: '
2010-02-27 20:11:15 +01:00
doprint = True
elif is_project_dir ( wd ) :
2019-08-30 10:32:02 +02:00
msg = ' Valid arguments for this project are: '
2010-02-27 20:11:15 +01:00
doprint = True
2019-08-30 10:32:02 +02:00
args = [ ]
if project is not None :
args . append ( project )
msg = ' Valid arguments are: '
2022-04-20 19:22:35 +02:00
doprint = True
2019-08-30 10:32:02 +02:00
2010-02-27 20:11:15 +01:00
if doprint :
2019-08-30 10:32:02 +02:00
print ( msg )
2013-04-09 12:51:28 +02:00
print ( )
2010-07-30 16:17:41 +02:00
if repos_only :
2019-08-30 10:32:02 +02:00
self . do_repositories ( " repos_only " , None , * args )
2010-07-30 16:17:41 +02:00
else :
2019-08-30 10:32:02 +02:00
self . do_repositories ( None , None , * args )
2011-03-02 14:38:24 +01:00
raise exc_class ( exc_msg )
2009-11-23 11:13:19 +01:00
2008-01-03 23:10:16 +01:00
@cmdln.alias ( ' rbl ' )
2009-05-21 14:05:39 +02:00
@cmdln.alias ( ' rbuildlog ' )
2011-01-07 23:05:44 +01:00
@cmdln.alias ( ' rblt ' )
@cmdln.alias ( ' rbuildlogtail ' )
@cmdln.alias ( ' remotebuildlogtail ' )
2013-08-13 10:38:43 +02:00
@cmdln.option ( ' -l ' , ' --last ' , action = ' store_true ' ,
help = ' Show the last finished log file ' )
2021-01-15 11:21:40 +01:00
@cmdln.option ( ' --lastsucceeded ' , ' --last-succeeded ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' Show the last succeeded log file ' )
2022-05-10 10:45:29 +02:00
@cmdln.option ( ' -M ' , ' --multibuild-package ' , metavar = ' FLAVOR ' ,
help = HELP_MULTIBUILD_ONE )
2011-01-07 23:05:44 +01:00
@cmdln.option ( ' -o ' , ' --offset ' , metavar = ' OFFSET ' ,
2022-09-12 13:43:10 +02:00
help = ' get log starting or ending from the offset ' )
2012-12-15 01:50:24 +01:00
@cmdln.option ( ' -s ' , ' --strip-time ' , action = ' store_true ' ,
help = ' strip leading build time from the log ' )
2008-01-03 23:10:16 +01:00
def do_remotebuildlog ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Shows the build log of a package
2008-01-03 23:10:16 +01:00
Shows the log file of the build of a package . Can be used to follow the
log while it is being written .
2011-01-07 23:05:44 +01:00
remotebuildlogtail shows just the tail of the log file .
2008-01-03 23:10:16 +01:00
usage :
2022-05-10 10:45:29 +02:00
osc remotebuildlog project package [ : flavor ] repository arch
2008-01-03 23:10:16 +01:00
or
2022-05-10 10:45:29 +02:00
osc remotebuildlog project / package [ : flavor ] / repository / arch
2010-02-16 12:23:25 +01:00
or
osc remotebuildlog buildlogurl
2008-01-03 23:10:16 +01:00
"""
2010-01-28 20:00:34 +01:00
if len ( args ) == 1 and args [ 0 ] . startswith ( ' http ' ) :
2010-01-28 13:20:11 +01:00
apiurl , project , package , repository , arch = parse_buildlogurl ( args [ 0 ] )
else :
args = slash_split ( args )
2010-07-29 17:29:07 +02:00
apiurl = self . get_api_url ( )
2010-01-28 13:20:11 +01:00
if len ( args ) < 4 :
raise oscerr . WrongArgs ( ' Too few arguments. ' )
elif len ( args ) > 4 :
raise oscerr . WrongArgs ( ' Too many arguments. ' )
else :
project , package , repository , arch = args
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( project )
2010-02-28 02:30:13 +01:00
2017-02-14 17:09:16 +01:00
if opts . multibuild_package :
package = package + " : " + opts . multibuild_package
2013-05-27 12:41:50 +02:00
offset = 0
2022-09-30 14:09:37 +02:00
if subcmd in ( " rblt " , " rbuildlogtail " , " remotebuildlogtail " ) :
2022-09-12 13:43:10 +02:00
query = { ' view ' : ' entry ' }
2013-08-13 10:38:43 +02:00
if opts . last :
query [ ' last ' ] = 1
2021-01-15 11:21:40 +01:00
if opts . lastsucceeded :
query [ ' lastsucceeded ' ] = 1
2020-04-28 14:00:00 +02:00
u = makeurl ( self . get_api_url ( ) , [ ' build ' , quote_plus ( project ) , quote_plus ( repository ) , quote_plus ( arch ) , quote_plus ( package ) , ' _log ' ] , query = query )
2011-01-07 23:05:44 +01:00
f = http_GET ( u )
root = ET . parse ( f ) . getroot ( )
offset = int ( root . find ( ' entry ' ) . get ( ' size ' ) )
if opts . offset :
offset = offset - int ( opts . offset )
else :
2022-09-12 13:43:10 +02:00
offset = offset - ( 8 * 1024 )
2011-01-07 23:05:44 +01:00
if offset < 0 :
2013-05-27 12:41:50 +02:00
offset = 0
2011-01-07 23:05:44 +01:00
elif opts . offset :
offset = int ( opts . offset )
2012-12-15 01:50:24 +01:00
strip_time = opts . strip_time or conf . config [ ' buildlog_strip_time ' ]
2020-04-28 14:00:00 +02:00
print_buildlog ( apiurl , quote_plus ( project ) , quote_plus ( package ) , quote_plus ( repository ) , quote_plus ( arch ) , offset , strip_time , opts . last , opts . lastsucceeded )
2006-05-23 15:48:58 +02:00
2016-02-05 16:10:43 +01:00
def _find_last_repo_arch ( self , repo = None , fatal = True ) :
2022-10-07 17:25:33 +02:00
files = glob . glob ( os . path . join ( Path . cwd ( ) , store , " _buildinfo-* " ) )
2016-02-05 16:10:43 +01:00
if repo is not None :
files = [ f for f in files
if os . path . basename ( f ) . replace ( ' _buildinfo- ' , ' ' ) . startswith ( repo + ' - ' ) ]
if not files :
if not fatal :
return None , None
self . print_repos ( )
cfg = files [ 0 ]
# find newest file
for f in files [ 1 : ] :
2016-02-05 16:11:11 +01:00
if os . stat ( f ) . st_atime > os . stat ( cfg ) . st_atime :
2016-02-05 16:10:43 +01:00
cfg = f
root = ET . parse ( cfg ) . getroot ( )
repo = root . get ( " repository " )
arch = root . find ( " arch " ) . text
return repo , arch
2010-02-12 15:54:33 +01:00
@cmdln.alias ( ' lbl ' )
2011-01-07 23:05:44 +01:00
@cmdln.option ( ' -o ' , ' --offset ' , metavar = ' OFFSET ' ,
2010-02-12 15:54:33 +01:00
help = ' get log starting from offset ' )
2012-12-15 01:50:24 +01:00
@cmdln.option ( ' -s ' , ' --strip-time ' , action = ' store_true ' ,
help = ' strip leading build time from the log ' )
2010-02-23 13:41:10 +01:00
def do_localbuildlog ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Shows the build log of a local buildchroot
2010-02-18 14:20:40 +01:00
2010-02-23 13:41:10 +01:00
usage :
2013-03-25 20:28:27 +01:00
osc lbl [ REPOSITORY [ ARCH ] ]
2010-02-23 13:41:10 +01:00
osc lbl # show log of newest last local build
2010-02-18 14:20:40 +01:00
"""
2010-02-12 15:54:33 +01:00
if conf . config [ ' build-type ' ] :
2010-02-23 13:41:10 +01:00
# FIXME: raise Exception instead
2013-04-09 12:51:28 +02:00
print ( ' Not implemented for VMs ' , file = sys . stderr )
2010-02-12 15:54:33 +01:00
sys . exit ( 1 )
2010-02-23 13:41:10 +01:00
2013-03-25 20:28:27 +01:00
if len ( args ) == 0 or len ( args ) == 1 :
2016-02-05 16:10:43 +01:00
project = store_read_project ( ' . ' )
2010-02-23 13:41:10 +01:00
package = store_read_package ( ' . ' )
2016-02-05 16:10:43 +01:00
repo = None
2013-03-25 20:28:27 +01:00
if args :
2016-02-05 16:10:43 +01:00
repo = args [ 0 ]
repo , arch = self . _find_last_repo_arch ( repo )
2010-02-23 13:41:10 +01:00
elif len ( args ) == 2 :
project = store_read_project ( ' . ' )
package = store_read_package ( ' . ' )
repo = args [ 0 ]
arch = args [ 1 ]
else :
2022-10-07 17:25:33 +02:00
if is_package_dir ( Path . cwd ( ) ) :
2010-02-23 13:41:10 +01:00
self . print_repos ( )
raise oscerr . WrongArgs ( ' Wrong number of arguments. ' )
2014-08-04 11:14:48 +02:00
# TODO: refactor/unify buildroot calculation and move it to core.py
apihost = urlsplit ( self . get_api_url ( ) ) [ 1 ]
2023-09-25 14:24:57 +02:00
buildroot = osc_build . calculate_build_root ( apihost , project , package , repo , arch )
2010-02-12 15:54:33 +01:00
offset = 0
2011-01-28 15:52:10 +01:00
if opts . offset :
offset = int ( opts . offset )
2010-02-12 15:54:33 +01:00
logfile = os . path . join ( buildroot , ' .build.log ' )
if not os . path . isfile ( logfile ) :
raise oscerr . OscIOError ( None , ' logfile \' %s \' does not exist ' % logfile )
2019-06-21 10:13:31 +02:00
f = open ( logfile , ' rb ' )
2010-02-12 15:54:33 +01:00
f . seek ( offset )
data = f . read ( BUFSIZE )
while len ( data ) :
2012-12-15 01:50:24 +01:00
if opts . strip_time or conf . config [ ' buildlog_strip_time ' ] :
2023-06-16 08:45:51 +02:00
# FIXME: this is not working when the time is split between 2 chunks
2012-12-15 01:50:24 +01:00
data = buildlog_strip_time ( data )
2023-06-16 08:45:51 +02:00
sys . stdout . buffer . write ( data )
2010-02-12 15:54:33 +01:00
data = f . read ( BUFSIZE )
f . close ( )
2006-09-25 17:11:03 +02:00
2022-05-10 10:46:28 +02:00
@cmdln.option ( ' -M ' , ' --multibuild-package ' , metavar = ' FLAVOR ' , help = HELP_MULTIBUILD_ONE )
2009-12-09 07:53:33 +01:00
@cmdln.alias ( ' tr ' )
def do_triggerreason ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Show reason why a package got triggered to build
2009-12-09 07:53:33 +01:00
The server decides when a package needs to get rebuild , this command
shows the detailed reason for a package . A brief reason is also stored
in the jobhistory , which can be accessed via " osc jobhistory " .
Trigger reasons might be :
- new build ( never build yet or rebuild manually forced )
2019-05-24 13:42:47 +02:00
- source change ( e . g . on updating sources )
2009-12-09 07:53:33 +01:00
- meta change ( packages which are used for building have changed )
- rebuild count sync ( In case that it is configured to sync release numbers )
usage in package or project directory :
2017-08-15 16:39:32 +02:00
osc triggerreason REPOSITORY ARCH
2022-05-10 10:46:28 +02:00
osc triggerreason PROJECT PACKAGE [ : FLAVOR ] REPOSITORY ARCH
2009-12-09 07:53:33 +01:00
"""
2022-10-07 17:25:33 +02:00
wd = Path . cwd ( )
2009-12-09 07:53:33 +01:00
args = slash_split ( args )
project = package = repository = arch = None
2010-02-28 02:30:13 +01:00
2010-02-09 00:08:21 +01:00
if len ( args ) < 2 :
2009-12-09 07:53:33 +01:00
self . print_repos ( )
2016-05-15 17:50:31 +02:00
2010-04-30 17:13:21 +02:00
apiurl = self . get_api_url ( )
2009-12-09 07:53:33 +01:00
2022-09-12 13:43:10 +02:00
if len ( args ) == 2 : # 2
2009-12-09 07:53:33 +01:00
if is_package_dir ( ' . ' ) :
2010-02-27 20:11:15 +01:00
package = store_read_package ( wd )
2009-12-09 07:53:33 +01:00
else :
2010-02-27 20:11:15 +01:00
raise oscerr . WrongArgs ( ' package is not specified. ' )
2009-12-09 07:53:33 +01:00
project = store_read_project ( wd )
repository = args [ 0 ]
arch = args [ 1 ]
elif len ( args ) == 4 :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2009-12-09 07:53:33 +01:00
package = args [ 1 ]
repository = args [ 2 ]
arch = args [ 3 ]
else :
raise oscerr . WrongArgs ( ' Too many arguments. ' )
2017-08-15 15:18:41 +02:00
if opts . multibuild_package :
package = package + " : " + opts . multibuild_package
2013-04-09 12:51:28 +02:00
print ( apiurl , project , package , repository , arch )
2009-12-09 07:53:33 +01:00
xml = show_package_trigger_reason ( apiurl , project , package , repository , arch )
2009-12-26 14:22:34 +01:00
root = ET . fromstring ( xml )
2019-05-14 10:50:24 +02:00
if root . find ( ' explain ' ) is None :
reason = " No triggerreason found "
print ( reason )
else :
reason = root . find ( ' explain ' ) . text
triggertime = time . strftime ( ' % Y- % m- %d % H: % M: % S ' , time . gmtime ( int ( root . find ( ' time ' ) . text ) ) )
print ( " %s (at %s ) " % ( reason , triggertime ) )
2009-12-09 07:53:33 +01:00
if reason == " meta change " :
2013-04-09 12:51:28 +02:00
print ( " changed keys: " )
2010-02-27 20:11:15 +01:00
for package in root . findall ( ' packagechange ' ) :
2013-04-09 12:51:28 +02:00
print ( " " , package . get ( ' change ' ) , package . get ( ' key ' ) )
2009-12-09 07:53:33 +01:00
2009-12-04 16:20:17 +01:00
# FIXME: the new osc syntax should allow to specify multiple packages
# FIXME: the command should optionally use buildinfo data to show all dependencies
2022-09-12 13:43:10 +02:00
2009-12-04 16:20:17 +01:00
def do_dependson ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Dependson shows the build dependencies inside of a project , valid for a given repository and architecture
2020-04-21 20:02:18 +02:00
The command can be used to find build dependencies ( wrt . a given repository and arch )
that reside in the same project . To see all build dependencies use the buildinfo command .
2009-12-04 16:20:17 +01:00
This is no guarantee , since the new build might have changed dependencies .
2010-02-28 02:30:13 +01:00
NOTE : to see all binary packages , which can trigger a build you need to
2009-12-04 16:20:17 +01:00
refer the buildinfo , since this command shows only the dependencies
inside of a project .
The arguments REPOSITORY and ARCH can be taken from the first two columns
of the ' osc repos ' output .
usage in package or project directory :
osc dependson REPOSITORY ARCH
usage :
osc dependson PROJECT [ PACKAGE ] REPOSITORY ARCH
2020-04-21 20:02:18 +02:00
"""
self . _dependson ( False , * args )
def do_whatdependson ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Show the packages that require the specified package during the build
2020-04-21 20:02:18 +02:00
The command whatdependson can be used to find out what will be triggered when
a certain package changes .
This is no guarantee , since the new build might have changed dependencies .
2023-04-28 09:30:38 +02:00
The packages marked with the [ i ] flag are inherited to the project .
2020-04-21 20:02:18 +02:00
The arguments REPOSITORY and ARCH can be taken from the first two columns
of the ' osc repos ' output .
usage in package or project directory :
osc whatdependson REPOSITORY ARCH
usage :
2009-12-04 16:20:17 +01:00
osc whatdependson PROJECT [ PACKAGE ] REPOSITORY ARCH
"""
2020-04-21 20:02:18 +02:00
self . _dependson ( True , * args )
def _dependson ( self , reverse , * args ) :
2022-10-07 17:25:33 +02:00
wd = Path . cwd ( )
2009-12-04 16:20:17 +01:00
args = slash_split ( args )
2020-04-21 20:02:18 +02:00
project = packages = repository = arch = None
2010-02-28 02:30:13 +01:00
2010-02-09 00:08:21 +01:00
if len ( args ) < 2 and ( is_package_dir ( ' . ' ) or is_project_dir ( ' . ' ) ) :
2009-12-04 16:20:17 +01:00
self . print_repos ( )
2012-04-04 14:34:47 +02:00
if len ( args ) > 4 :
2009-12-04 16:20:17 +01:00
raise oscerr . WrongArgs ( ' Too many arguments. ' )
2010-04-30 17:13:21 +02:00
apiurl = self . get_api_url ( )
2022-09-12 13:43:10 +02:00
if len ( args ) < 3 : # 2
2009-12-04 16:20:17 +01:00
if is_package_dir ( ' . ' ) :
2010-02-27 20:11:15 +01:00
packages = [ store_read_package ( wd ) ]
2009-12-04 16:20:17 +01:00
elif not is_project_dir ( ' . ' ) :
2010-02-27 20:11:15 +01:00
raise oscerr . WrongArgs ( ' Project and package is not specified. ' )
2009-12-04 16:20:17 +01:00
project = store_read_project ( wd )
repository = args [ 0 ]
arch = args [ 1 ]
if len ( args ) == 3 :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2009-12-04 16:20:17 +01:00
repository = args [ 1 ]
arch = args [ 2 ]
if len ( args ) == 4 :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2009-12-04 16:20:17 +01:00
packages = [ args [ 1 ] ]
repository = args [ 2 ]
arch = args [ 3 ]
2023-04-28 09:30:38 +02:00
project_packages = meta_get_packagelist ( apiurl , project , deleted = False , expand = False )
2009-12-04 16:20:17 +01:00
xml = get_dependson ( apiurl , project , repository , arch , packages , reverse )
2009-12-26 14:22:34 +01:00
root = ET . fromstring ( xml )
for package in root . findall ( ' package ' ) :
2013-04-09 12:51:28 +02:00
print ( package . get ( ' name ' ) , " : " )
2009-12-04 16:20:17 +01:00
for dep in package . findall ( ' pkgdep ' ) :
2023-04-28 09:30:38 +02:00
inherited = " " if dep . text in project_packages else " [i] "
print ( f " { inherited } { dep . text } " )
2009-12-04 16:20:17 +01:00
2018-10-23 20:27:43 +02:00
@cmdln.option ( ' --alternative-project ' , metavar = ' PROJECT ' ,
help = ' specify the build target project ' )
2022-09-30 09:43:41 +02:00
@cmdln.option ( ' -d ' , ' --debug ' , action = ' store_true ' , dest = " debug_dependencies " ,
help = ' verbose output of build dependencies ' )
2022-05-10 10:47:31 +02:00
@cmdln.option ( ' -M ' , ' --multibuild-package ' , metavar = ' FLAVOR ' ,
help = HELP_MULTIBUILD_ONE )
2007-05-09 11:36:55 +02:00
@cmdln.option ( ' -x ' , ' --extra-pkgs ' , metavar = ' PAC ' , action = ' append ' ,
help = ' Add this package when computing the buildinfo ' )
2010-07-26 15:41:02 +02:00
@cmdln.option ( ' -p ' , ' --prefer-pkgs ' , metavar = ' DIR ' , action = ' append ' ,
help = ' Prefer packages from this directory when installing the build-root ' )
2007-04-25 01:00:12 +02:00
def do_buildinfo ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Shows the build info
2007-04-25 01:00:12 +02:00
Shows the build " info " which is used in building a package .
This command is mostly used internally by the ' build ' subcommand .
It needs to be called from within a package directory .
The BUILD_DESCR argument is optional . BUILD_DESCR is a local RPM specfile
or Debian " dsc " file . If specified , it is sent to the server , and the
buildinfo will be based on it . If the argument is not supplied , the
buildinfo is derived from the specfile which is currently on the source
repository server .
The returned data is XML and contains a list of the packages used in
building , their source , and the expanded BuildRequires .
2010-09-10 15:17:45 +02:00
The arguments REPOSITORY and ARCH are optional . They can be taken from
the first two columns of the ' osc repos ' output . If not specified ,
2019-05-24 13:42:47 +02:00
REPOSITORY defaults to the ' build_repository ' config entry in your ' oscrc '
2010-09-10 15:17:45 +02:00
and ARCH defaults to your host architecture .
2007-04-25 01:00:12 +02:00
2009-05-18 16:50:43 +02:00
usage :
2010-10-04 15:57:52 +02:00
in a package working copy :
osc buildinfo [ OPTS ] REPOSITORY ARCH BUILD_DESCR
osc buildinfo [ OPTS ] REPOSITORY ( ARCH = hostarch , BUILD_DESCR is detected automatically )
osc buildinfo [ OPTS ] ARCH ( REPOSITORY = build_repository ( config option ) , BUILD_DESCR is detected automatically )
osc buildinfo [ OPTS ] BUILD_DESCR ( REPOSITORY = build_repository ( config option ) , ARCH = hostarch )
osc buildinfo [ OPTS ] ( REPOSITORY = build_repository ( config option ) , ARCH = hostarch , BUILD_DESCR is detected automatically )
Note : if BUILD_DESCR does not exist locally the remote BUILD_DESCR is used
2022-05-10 10:47:31 +02:00
osc buildinfo [ OPTS ] PROJECT PACKAGE [ : FLAVOR ] REPOSITORY ARCH [ BUILD_DESCR ]
2007-04-25 01:00:12 +02:00
"""
2022-10-07 17:25:33 +02:00
wd = Path . cwd ( )
2009-11-06 20:52:28 +01:00
args = slash_split ( args )
2010-02-28 02:30:13 +01:00
2010-10-04 15:57:52 +02:00
project = package = repository = arch = build_descr = None
if len ( args ) < = 3 :
if not is_package_dir ( ' . ' ) :
raise oscerr . WrongArgs ( ' Incorrect number of arguments (Note: \' . \' is no package wc) ' )
2018-10-23 20:27:43 +02:00
if opts . alternative_project :
project = opts . alternative_project
2019-10-21 13:29:37 +02:00
package = ' _repository '
2018-10-23 20:27:43 +02:00
else :
project = store_read_project ( ' . ' )
2019-10-21 13:29:37 +02:00
package = store_read_package ( ' . ' )
2018-10-23 20:27:43 +02:00
repository , arch , build_descr = self . parse_repoarchdescr ( args , alternative_project = opts . alternative_project , ignore_descr = True , multibuild_package = opts . multibuild_package )
2010-09-10 15:17:45 +02:00
elif len ( args ) == 4 or len ( args ) == 5 :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2009-11-06 20:52:28 +01:00
package = args [ 1 ]
repository = args [ 2 ]
arch = args [ 3 ]
2010-10-04 15:57:52 +02:00
if len ( args ) == 5 :
build_descr = args [ 4 ]
2010-09-10 15:17:45 +02:00
else :
raise oscerr . WrongArgs ( ' Too many arguments. ' )
apiurl = self . get_api_url ( )
2007-04-25 01:00:12 +02:00
2010-07-26 15:41:02 +02:00
build_descr_data = None
2022-09-12 14:23:47 +02:00
if build_descr is not None :
2018-12-13 15:17:29 +01:00
build_descr_data = open ( build_descr , ' rb ' ) . read ( )
2010-07-26 15:41:02 +02:00
if opts . prefer_pkgs and build_descr_data is None :
raise oscerr . WrongArgs ( ' error: a build description is needed if \' --prefer-pkgs \' is used ' )
elif opts . prefer_pkgs :
2013-04-09 12:51:28 +02:00
print ( ' Scanning the following dirs for local packages: %s ' % ' , ' . join ( opts . prefer_pkgs ) )
2016-04-14 16:25:48 +02:00
cpiodata = cpio . CpioWrite ( )
2022-09-09 11:46:28 +02:00
prefer_pkgs = osc_build . get_prefer_pkgs ( opts . prefer_pkgs , arch ,
2022-09-12 13:43:10 +02:00
os . path . splitext ( build_descr ) [ 1 ] ,
cpiodata )
2018-12-13 15:17:29 +01:00
cpiodata . add ( os . path . basename ( build_descr . encode ( ) ) , build_descr_data )
2016-04-14 16:25:48 +02:00
build_descr_data = cpiodata . get ( )
2007-04-25 01:00:12 +02:00
2017-02-14 17:09:16 +01:00
if opts . multibuild_package :
package = package + " : " + opts . multibuild_package
2018-12-13 15:17:29 +01:00
print ( decode_it ( get_buildinfo ( apiurl ,
2022-09-12 13:43:10 +02:00
project , package , repository , arch ,
specfile = build_descr_data ,
2022-09-30 09:43:41 +02:00
debug = opts . debug_dependencies ,
2022-09-12 13:43:10 +02:00
addlist = opts . extra_pkgs ) ) )
2006-09-25 17:11:03 +02:00
2009-11-06 20:52:28 +01:00
def do_buildconfig ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Shows the build config
2007-04-25 01:00:12 +02:00
Shows the build configuration which is used in building a package .
This command is mostly used internally by the ' build ' command .
The returned data is the project - wide build configuration in a format
which is directly readable by the build script . It contains RPM macros
and BuildRequires expansions , for example .
2014-08-12 15:01:16 +02:00
The argument REPOSITORY an be taken from the first column of the
2010-07-27 13:58:52 +02:00
' osc repos ' output .
2007-04-25 01:00:12 +02:00
2009-11-06 20:52:28 +01:00
usage :
2010-07-27 13:58:52 +02:00
osc buildconfig REPOSITORY ( in pkg or prj dir )
osc buildconfig PROJECT REPOSITORY
2007-04-25 01:00:12 +02:00
"""
2022-10-07 17:25:33 +02:00
wd = Path . cwd ( )
2009-11-06 20:52:28 +01:00
args = slash_split ( args )
2010-02-28 02:30:13 +01:00
2010-07-27 13:58:52 +02:00
if len ( args ) < 1 and ( is_package_dir ( ' . ' ) or is_project_dir ( ' . ' ) ) :
2010-07-30 16:17:41 +02:00
self . print_repos ( True )
2009-11-06 20:52:28 +01:00
2010-07-27 13:58:52 +02:00
if len ( args ) > 2 :
2009-11-06 20:52:28 +01:00
raise oscerr . WrongArgs ( ' Too many arguments. ' )
2010-04-30 17:13:21 +02:00
apiurl = self . get_api_url ( )
2010-07-27 13:58:52 +02:00
if len ( args ) == 1 :
2022-09-12 13:43:10 +02:00
# FIXME: check if args[0] is really a repo and not a project, need a is_project() function for this
2009-11-06 20:52:28 +01:00
project = store_read_project ( wd )
repository = args [ 0 ]
2010-07-27 13:58:52 +02:00
elif len ( args ) == 2 :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2010-07-27 13:58:52 +02:00
repository = args [ 1 ]
2009-11-06 20:52:28 +01:00
else :
raise oscerr . WrongArgs ( ' Wrong number of arguments. ' )
2006-09-25 17:11:03 +02:00
2018-12-13 15:17:29 +01:00
print ( decode_it ( get_buildconfig ( apiurl , project , repository ) ) )
2006-09-25 17:11:03 +02:00
2022-09-20 10:03:21 +02:00
@cmdln.option ( ' worker ' , metavar = ' <hostarch>:<workerid> ' )
def do_workerinfo ( self , subcmd , opts ) :
2022-01-19 15:13:55 +01:00
"""
Gets the information to a worker from the server
2016-12-29 12:46:07 +01:00
Examples :
2020-08-18 14:52:38 +02:00
osc workerinfo x86_64 : goat : 1
2022-01-19 15:13:55 +01:00
usage :
2020-08-18 14:52:38 +02:00
osc workerinfo < hostarch > : < workerid >
2016-12-29 12:46:07 +01:00
"""
2022-09-20 10:03:21 +02:00
worker = opts . worker
2016-12-29 12:46:07 +01:00
apiurl = self . get_api_url ( )
print ( ' ' . join ( get_worker_info ( apiurl , worker ) ) )
@cmdln.option ( ' ' , ' --ignore-file ' , action = ' store_true ' ,
help = ' ignore _constraints file and only check project constraints ' )
2023-08-29 17:23:43 +02:00
@cmdln.option ( ' -M ' , ' --multibuild-package ' , metavar = ' FLAVOR ' ,
help = HELP_MULTIBUILD_ONE )
2016-12-29 12:46:07 +01:00
def do_checkconstraints ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Check the constraints and view compliant workers
2016-12-29 12:46:07 +01:00
Checks the constraints for compliant workers .
usage :
2018-09-28 10:47:53 +02:00
remote request :
2023-08-28 13:44:31 +02:00
osc checkconstraints [ OPTS ] PROJECT PACKAGE REPOSITORY ARCH [ CONSTRAINTSFILE ]
2018-09-28 10:47:53 +02:00
2016-12-29 12:46:07 +01:00
in a package working copy :
2023-08-28 13:44:31 +02:00
osc checkconstraints [ OPTS ] REPOSITORY ARCH [ CONSTRAINTSFILE ]
2016-12-29 12:46:07 +01:00
osc checkconstraints [ OPTS ] CONSTRAINTSFILE
osc checkconstraints [ OPTS ]
"""
repository = arch = constraintsfile = None
2018-09-28 10:47:53 +02:00
args = slash_split ( args )
2023-08-28 13:44:31 +02:00
if len ( args ) > 5 :
raise oscerr . WrongArgs ( ' Too many arguments ' )
if len ( args ) == 4 or len ( args ) == 5 :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2018-09-28 10:47:53 +02:00
package = args [ 1 ]
repository = args [ 2 ]
arch = args [ 3 ]
opts . ignore_file = True
2023-08-28 13:44:31 +02:00
if len ( args ) == 5 :
constraintsfile = args [ 4 ] ;
2018-09-28 10:47:53 +02:00
else :
project = store_read_project ( ' . ' )
package = store_read_package ( ' . ' )
2023-08-29 17:23:43 +02:00
if opts . multibuild_package :
package = package + " : " + opts . multibuild_package
2016-12-29 12:46:07 +01:00
if len ( args ) == 1 :
constraintsfile = args [ 0 ]
elif len ( args ) == 2 or len ( args ) == 3 :
repository = args [ 0 ]
arch = args [ 1 ]
if len ( args ) == 3 :
constraintsfile = args [ 2 ]
constraintsfile_data = None
if constraintsfile is not None :
2022-07-28 19:11:29 +02:00
constraintsfile_data = open ( constraintsfile ) . read ( )
2016-12-29 12:46:07 +01:00
elif not opts . ignore_file :
if os . path . isfile ( " _constraints " ) :
2022-07-28 19:11:29 +02:00
constraintsfile_data = open ( " _constraints " ) . read ( )
2016-12-29 12:46:07 +01:00
else :
print ( " No local _constraints file. Using just the project constraints " )
apiurl = self . get_api_url ( )
r = [ ]
if not arch and not repository :
result_line_templ = ' %(name)-25s %(arch)-25s %(comp_workers)s '
for repo in get_repos_of_project ( apiurl , project ) :
rmap = { }
rmap [ ' name ' ] = repo . name
rmap [ ' arch ' ] = repo . arch
workers = check_constraints ( apiurl , project , repo . name , repo . arch , package , constraintsfile_data )
rmap [ ' comp_workers ' ] = len ( workers )
r . append ( result_line_templ % rmap )
r . insert ( 0 , ' Repository Arch Worker ' )
r . insert ( 1 , ' ---------- ---- ------ ' )
else :
r = check_constraints ( apiurl , project , repository , arch , package , constraintsfile_data )
r . insert ( 0 , ' Worker ' )
r . insert ( 1 , ' ------ ' )
print ( ' \n ' . join ( r ) )
2010-07-29 16:59:54 +02:00
@cmdln.alias ( ' repos ' )
@cmdln.alias ( ' platforms ' )
def do_repositories ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Shows repositories configured for a project
It skips repositories by default which are disabled for a given package .
2006-06-22 13:26:01 +02:00
2009-11-30 10:57:39 +01:00
usage :
osc repos
2010-07-12 14:56:08 +02:00
osc repos [ PROJECT ] [ PACKAGE ]
2007-04-25 01:00:12 +02:00
"""
2006-09-15 13:47:34 +02:00
2010-04-30 17:13:21 +02:00
apiurl = self . get_api_url ( )
2010-07-29 16:59:54 +02:00
project = None
2010-07-12 14:56:08 +02:00
package = None
disabled = None
2006-09-15 13:47:34 +02:00
2009-11-30 10:57:39 +01:00
if len ( args ) == 1 :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2010-07-29 16:59:54 +02:00
elif len ( args ) == 2 :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2010-07-12 14:56:08 +02:00
package = args [ 1 ]
2009-11-30 10:57:39 +01:00
elif len ( args ) == 0 :
2010-07-12 14:56:08 +02:00
if is_package_dir ( ' . ' ) :
package = store_read_package ( ' . ' )
project = store_read_project ( ' . ' )
elif is_project_dir ( ' . ' ) :
project = store_read_project ( ' . ' )
2009-11-30 10:57:39 +01:00
else :
raise oscerr . WrongArgs ( ' Wrong number of arguments ' )
2006-07-05 12:25:31 +02:00
2010-07-29 16:59:54 +02:00
if project is None :
raise oscerr . WrongArgs ( ' No project specified ' )
2010-07-12 14:56:08 +02:00
if package is not None :
disabled = show_package_disabled_repos ( apiurl , project , package )
2010-07-30 16:17:41 +02:00
if subcmd == ' repos_only ' :
2014-08-12 15:01:16 +02:00
for repo in get_repositories_of_project ( apiurl , project ) :
2017-11-08 10:39:42 +01:00
if ( disabled is None ) or ( ( disabled is not None ) and ( repo not in [ d [ ' repo ' ] for d in disabled ] ) ) :
2013-04-09 12:51:28 +02:00
print ( repo )
2010-07-30 16:17:41 +02:00
else :
data = [ ]
for repo in get_repos_of_project ( apiurl , project ) :
2017-11-08 10:39:42 +01:00
if disabled is not None :
if ( { ' repo ' : repo . name , ' arch ' : repo . arch } in disabled
or repo . name in [ d [ ' repo ' ] for d in disabled if d [ ' arch ' ] is None ]
2022-09-12 13:43:10 +02:00
or repo . arch in [ d [ ' arch ' ] for d in disabled if d [ ' repo ' ] is None ] ) :
continue
2017-11-08 10:39:42 +01:00
data + = [ repo . name , repo . arch ]
2016-05-15 17:50:31 +02:00
2010-07-30 16:17:41 +02:00
for row in build_table ( 2 , data , width = 2 ) :
2013-04-09 12:51:28 +02:00
print ( row )
2006-07-05 12:25:31 +02:00
2022-09-12 13:43:10 +02:00
def parse_repoarchdescr ( self , args , noinit = False , alternative_project = None , ignore_descr = False , vm_type = None , multibuild_package = None ) :
2010-01-30 16:18:30 +01:00
""" helper to parse the repo, arch and build description from args """
arg_arch = arg_repository = arg_descr = None
if len ( args ) < 3 :
2013-04-16 15:42:37 +02:00
# some magic, works only sometimes, but people seem to like it :/
all_archs = [ ]
2022-09-09 11:46:28 +02:00
for mainarch in osc_build . can_also_build :
2013-05-27 12:16:44 +02:00
all_archs . append ( mainarch )
2022-09-09 11:46:28 +02:00
for subarch in osc_build . can_also_build . get ( mainarch ) :
2013-05-27 12:16:44 +02:00
all_archs . append ( subarch )
2010-01-30 16:18:30 +01:00
for arg in args :
2022-04-20 17:28:01 +02:00
if ( arg . endswith ( ' .spec ' ) or arg . endswith ( ' .dsc ' ) or
arg . endswith ( ' .kiwi ' ) or arg . endswith ( ' .livebuild ' ) or
arg . endswith ( ' flatpak.yaml ' ) or arg . endswith ( ' flatpak.yml ' ) or
arg . endswith ( ' flatpak.json ' ) or
arg in ( ' PKGBUILD ' , ' build.collax ' , ' Chart.yaml ' , ' Dockerfile ' ,
' fissile.yml ' , ' appimage.yml ' , ' _preinstallimage ' ) ) :
2010-01-30 16:18:30 +01:00
arg_descr = arg
else :
2022-09-09 11:46:28 +02:00
if ( arg == osc_build . hostarch or arg in all_archs ) and arg_arch is None :
2013-04-16 15:42:37 +02:00
# it seems to be an architecture in general
2010-01-30 16:18:30 +01:00
arg_arch = arg
2022-09-09 11:46:28 +02:00
if not ( arg == osc_build . hostarch or arg in osc_build . can_also_build . get ( osc_build . hostarch , [ ] ) ) :
2022-09-30 14:09:37 +02:00
if vm_type not in ( ' qemu ' , ' emulator ' ) :
2022-04-20 19:22:35 +02:00
print ( " WARNING: native compile is not possible, a emulator via binfmt misc handler must be configured! " )
2010-01-30 16:18:30 +01:00
elif not arg_repository :
arg_repository = arg
else :
2022-04-20 19:22:35 +02:00
# raise oscerr.WrongArgs('\'%s\' is neither a build description nor a supported arch' % arg)
2014-07-02 23:56:34 +02:00
# take it as arch (even though this is no supported arch) - hopefully, this invalid
# arch will be detected below
arg_arch = arg
2010-01-30 16:18:30 +01:00
else :
arg_repository , arg_arch , arg_descr = args
2022-09-09 11:46:28 +02:00
arg_arch = arg_arch or osc_build . hostarch
self . _debug ( " hostarch: " , osc_build . hostarch )
2022-08-04 16:08:47 +02:00
self . _debug ( " arg_arch: " , arg_arch )
self . _debug ( " arg_repository: " , arg_repository )
self . _debug ( " arg_descr: " , arg_descr )
2010-01-30 16:18:30 +01:00
2010-04-29 14:25:38 +02:00
repositories = [ ]
# store list of repos for potential offline use
2022-10-07 17:25:33 +02:00
repolistfile = os . path . join ( Path . cwd ( ) , store , " _build_repositories " )
2010-04-29 14:25:38 +02:00
if noinit :
2014-07-02 22:07:01 +02:00
repositories = Repo . fromfile ( repolistfile )
2010-04-29 14:25:38 +02:00
else :
2010-01-30 16:18:30 +01:00
project = alternative_project or store_read_project ( ' . ' )
2010-06-30 13:37:26 +02:00
apiurl = self . get_api_url ( )
2014-07-02 22:07:01 +02:00
repositories = list ( get_repos_of_project ( apiurl , project ) )
2022-08-29 13:23:29 +02:00
if not repositories :
2010-01-30 16:18:30 +01:00
raise oscerr . WrongArgs ( ' no repositories defined for project \' %s \' ' % project )
2014-07-02 22:07:01 +02:00
if alternative_project is None :
# only persist our own repos
Repo . tofile ( repolistfile , repositories )
2010-04-29 14:25:38 +02:00
2017-01-23 15:32:58 +01:00
no_repo = False
2022-07-28 19:11:29 +02:00
repo_names = sorted ( { r . name for r in repositories } )
2014-07-02 22:07:01 +02:00
if not arg_repository and repositories :
2014-11-17 10:12:35 +01:00
# XXX: we should avoid hardcoding repository names
2010-04-29 14:25:38 +02:00
# Use a default value from config, but just even if it's available
2014-11-17 10:12:35 +01:00
# unless try standard, or openSUSE_Factory, or openSUSE_Tumbleweed
2017-01-23 15:32:58 +01:00
no_repo = True
2014-07-02 22:07:01 +02:00
arg_repository = repositories [ - 1 ] . name
2014-11-17 10:12:35 +01:00
for repository in ( conf . config [ ' build_repository ' ] , ' standard ' , ' openSUSE_Factory ' , ' openSUSE_Tumbleweed ' ) :
2014-07-02 22:07:01 +02:00
if repository in repo_names :
2010-04-29 14:25:38 +02:00
arg_repository = repository
2017-01-23 15:32:58 +01:00
no_repo = False
2010-04-29 14:25:38 +02:00
break
if not arg_repository :
2010-01-30 16:18:30 +01:00
raise oscerr . WrongArgs ( ' please specify a repository ' )
2014-07-02 22:07:01 +02:00
if not noinit :
2022-09-12 14:15:34 +02:00
if arg_repository not in repo_names :
2014-07-02 22:07:01 +02:00
raise oscerr . WrongArgs ( ' %s is not a valid repository, use one of: %s ' % ( arg_repository , ' , ' . join ( repo_names ) ) )
arches = [ r . arch for r in repositories if r . name == arg_repository and r . arch ]
2022-09-12 14:15:34 +02:00
if arches and arg_arch not in arches :
2014-07-02 22:07:01 +02:00
raise oscerr . WrongArgs ( ' %s is not a valid arch for the repository %s , use one of: %s ' % ( arg_arch , arg_repository , ' , ' . join ( arches ) ) )
2010-01-30 16:18:30 +01:00
2010-04-27 18:18:34 +02:00
# can be implemented using
2010-04-30 15:19:35 +02:00
# reduce(lambda x, y: x + y, (glob.glob(x) for x in ('*.spec', '*.dsc', '*.kiwi')))
2010-04-27 18:18:34 +02:00
# but be a bit more readable :)
2022-04-20 17:28:01 +02:00
descr = glob . glob ( ' *.spec ' ) + glob . glob ( ' *.dsc ' ) + glob . glob ( ' *.kiwi ' ) + glob . glob ( ' *.livebuild ' ) + \
glob . glob ( ' PKGBUILD ' ) + glob . glob ( ' build.collax ' ) + glob . glob ( ' Dockerfile ' ) + \
glob . glob ( ' fissile.yml ' ) + glob . glob ( ' appimage.yml ' ) + glob . glob ( ' Chart.yaml ' ) + \
2023-11-24 11:19:55 +01:00
glob . glob ( ' *flatpak.yaml ' ) + glob . glob ( ' *flatpak.yml ' ) + glob . glob ( ' *flatpak.json ' ) + \
glob . glob ( ' *.productcompose ' )
2016-05-15 17:50:31 +02:00
2010-01-30 16:18:30 +01:00
# FIXME:
# * request repos from server and select by build type.
if not arg_descr and len ( descr ) == 1 :
arg_descr = descr [ 0 ]
2010-04-30 15:25:24 +02:00
elif not arg_descr :
2010-05-12 11:41:43 +02:00
msg = None
2010-04-27 18:23:03 +02:00
if len ( descr ) > 1 :
2017-01-23 15:32:58 +01:00
if no_repo :
raise oscerr . WrongArgs ( " Repository is missing. Cannot guess build description without repository " )
apiurl = self . get_api_url ( )
2023-07-27 12:50:05 +02:00
project = alternative_project or store_read_project ( ' . ' )
2019-05-21 14:28:55 +02:00
# some distros like Debian rename and move build to obs-build
if not os . path . isfile ( ' /usr/lib/build/queryconfig ' ) and os . path . isfile ( ' /usr/lib/obs-build/queryconfig ' ) :
queryconfig = ' /usr/lib/obs-build/queryconfig '
else :
queryconfig = ' /usr/lib/build/queryconfig '
if noinit :
bc_filename = ' _buildconfig- %s - %s ' % ( arg_repository , arg_arch )
if is_package_dir ( ' . ' ) :
2022-10-07 17:25:33 +02:00
bc_filename = os . path . join ( Path . cwd ( ) , store , bc_filename )
2017-07-07 18:47:43 +02:00
else :
2019-05-21 14:28:55 +02:00
bc_filename = os . path . abspath ( bc_filename )
if not os . path . isfile ( bc_filename ) :
raise oscerr . WrongOptions ( ' --offline is not possible, no local buildconfig file ' )
recipe = return_external ( queryconfig , ' --dist ' , bc_filename , ' type ' )
else :
bc = get_buildconfig ( apiurl , project , arg_repository )
with tempfile . NamedTemporaryFile ( ) as f :
f . write ( bc )
f . flush ( )
recipe = return_external ( queryconfig , ' --dist ' , f . name , ' type ' )
2017-01-23 15:32:58 +01:00
recipe = recipe . strip ( )
if recipe == ' arch ' :
recipe = ' PKGBUILD '
2018-12-13 15:17:29 +01:00
recipe = decode_it ( recipe )
2022-10-07 17:25:33 +02:00
pac = os . path . basename ( Path . cwd ( ) )
if is_package_dir ( Path . cwd ( ) ) :
pac = store_read_package ( Path . cwd ( ) )
2017-02-14 17:09:16 +01:00
if multibuild_package :
pac = multibuild_package
2017-01-23 15:32:58 +01:00
if recipe == ' PKGBUILD ' :
cands = [ d for d in descr if d . startswith ( recipe ) ]
else :
cands = [ d for d in descr if d . endswith ( ' . ' + recipe ) ]
if len ( cands ) > 1 :
repo_cands = [ d for d in cands if d == ' %s - %s . %s ' % ( pac , arg_repository , recipe ) ]
if repo_cands :
cands = repo_cands
else :
pac_cands = [ d for d in cands if d == ' %s . %s ' % ( pac , recipe ) ]
if pac_cands :
cands = pac_cands
2011-01-30 16:38:11 +01:00
if len ( cands ) == 1 :
arg_descr = cands [ 0 ]
2010-08-08 23:15:25 +02:00
if not arg_descr :
2017-01-23 15:32:58 +01:00
msg = ' Multiple build description files found: %s ' % ' , ' . join ( cands )
2010-10-04 15:57:52 +02:00
elif not ignore_descr :
2019-10-17 08:06:14 +02:00
msg = ' Missing argument: build description (for example a spec, dsc or kiwi file) '
2010-04-27 18:23:03 +02:00
try :
p = Package ( ' . ' )
if p . islink ( ) and not p . isexpanded ( ) :
msg + = ' (this package is not expanded - you might want to try osc up --expand) '
except :
pass
2010-05-12 11:41:43 +02:00
if msg :
raise oscerr . WrongArgs ( msg )
2010-04-27 18:23:03 +02:00
2010-01-30 16:18:30 +01:00
return arg_repository , arg_arch , arg_descr
2007-04-25 01:00:12 +02:00
@cmdln.option ( ' --clean ' , action = ' store_true ' ,
help = ' Delete old build root before initializing it ' )
2010-04-17 10:53:53 +02:00
@cmdln.option ( ' -o ' , ' --offline ' , action = ' store_true ' ,
help = ' Start with cached prjconf and packages without contacting the api server ' )
@cmdln.option ( ' -l ' , ' --preload ' , action = ' store_true ' ,
2012-02-02 11:49:17 +01:00
help = ' Preload all files into the cache for offline operation ' )
2007-09-03 12:25:18 +02:00
@cmdln.option ( ' --no-changelog ' , action = ' store_true ' ,
help = ' don \' t update the package changelog from a changes file ' )
2009-10-20 16:30:15 +02:00
@cmdln.option ( ' --rsync-src ' , metavar = ' RSYNCSRCPATH ' , dest = ' rsyncsrc ' ,
2009-08-18 23:28:33 +02:00
help = ' Copy folder to buildroot after installing all RPMs. Use together with --rsync-dest. This is the path on the HOST filesystem e.g. /tmp/linux-kernel-tree. It defines RSYNCDONE 1 . ' )
2009-10-20 16:30:15 +02:00
@cmdln.option ( ' --rsync-dest ' , metavar = ' RSYNCDESTPATH ' , dest = ' rsyncdest ' ,
2009-08-18 23:28:33 +02:00
help = ' Copy folder to buildroot after installing all RPMs. Use together with --rsync-src. This is the path on the TARGET filesystem e.g. /usr/src/packages/BUILD/linux-2.6 . ' )
@cmdln.option ( ' --overlay ' , metavar = ' OVERLAY ' ,
help = ' Copy overlay filesystem to buildroot after installing all RPMs . ' )
2007-04-25 01:00:12 +02:00
@cmdln.option ( ' --noinit ' , ' --no-init ' , action = ' store_true ' ,
help = ' Skip initialization of build root and start with build immediately. ' )
2008-07-23 22:05:09 +02:00
@cmdln.option ( ' --nochecks ' , ' --no-checks ' , action = ' store_true ' ,
2014-03-03 11:59:45 +01:00
help = ' Do not run build checks on the resulting packages. ' )
2014-02-12 12:26:59 +01:00
@cmdln.option ( ' --no-verify ' , ' --noverify ' , action = ' store_true ' ,
2017-10-27 11:29:00 +02:00
help = ' Skip signature verification (via pgp keys) of packages used for build. (Global config in oscrc: no_verify) ' )
2019-12-03 15:05:48 +01:00
@cmdln.option ( ' --nodebugpackages ' , ' --no-debug-packages ' , action = ' store_true ' ,
help = ' Skip installation of additional debug packages for CLI builds ' )
2023-05-04 14:39:17 +02:00
@cmdln.option ( " --skip-local-service-run " , " --noservice " , " --no-service " , default = False , action = " store_true " ,
help = " Skip run of local source services as specified in _service file. " )
2007-05-03 17:54:40 +02:00
@cmdln.option ( ' -p ' , ' --prefer-pkgs ' , metavar = ' DIR ' , action = ' append ' ,
2007-05-02 15:49:57 +02:00
help = ' Prefer packages from this directory when installing the build-root ' )
2009-05-18 16:50:43 +02:00
@cmdln.option ( ' -k ' , ' --keep-pkgs ' , metavar = ' DIR ' ,
2007-05-03 17:54:40 +02:00
help = ' Save built packages into this directory ' )
2022-05-10 10:49:10 +02:00
@cmdln.option ( ' -M ' , ' --multibuild-package ' , metavar = ' FLAVOR ' ,
help = HELP_MULTIBUILD_ONE )
2007-05-09 11:36:55 +02:00
@cmdln.option ( ' -x ' , ' --extra-pkgs ' , metavar = ' PAC ' , action = ' append ' ,
help = ' Add this package when installing the build-root ' )
2022-10-13 00:51:20 +02:00
@cmdln.option ( ' -X ' , ' --extra-pkgs-from ' , metavar = ' FILE ' , action = ' append ' ,
help = ' Add packages listed in this file when installing the build-root ' )
2009-11-23 14:53:59 +01:00
@cmdln.option ( ' --root ' , metavar = ' ROOT ' ,
help = ' Build in specified directory ' )
2008-04-24 11:00:23 +02:00
@cmdln.option ( ' -j ' , ' --jobs ' , metavar = ' N ' ,
help = ' Compile with N jobs ' )
2015-03-10 11:58:08 +01:00
@cmdln.option ( ' -t ' , ' --threads ' , metavar = ' N ' ,
help = ' Compile with N threads ' )
2008-12-11 12:36:07 +01:00
@cmdln.option ( ' --icecream ' , metavar = ' N ' ,
help = ' use N parallel build jobs with icecream ' )
@cmdln.option ( ' --ccache ' , action = ' store_true ' ,
help = ' use ccache to speed up rebuilds ' )
2020-05-19 14:47:03 +02:00
@cmdln.option ( ' --pkg-ccache ' , metavar = ' /path/to/_ccache.tar ' ,
help = ' path to an existing uncompressed archive ccache. Using this option implies --ccache ' )
2021-04-08 12:09:33 +02:00
@cmdln.option ( ' --sccache ' , action = ' store_true ' ,
help = ' use sccache to speed up rebuilds. Conflicts with --cache ' )
@cmdln.option ( ' --sccache-uri ' , metavar = ' redis://127.0.0.1:6389 ' ,
help = ' Optional remote URI for sccache storage. Implies --sccache. ' )
2009-11-24 10:49:26 +01:00
@cmdln.option ( ' --with ' , metavar = ' X ' , dest = ' _with ' , action = ' append ' ,
2008-12-11 12:36:07 +01:00
help = ' enable feature X for build ' )
2009-11-24 10:49:26 +01:00
@cmdln.option ( ' --without ' , metavar = ' X ' , action = ' append ' ,
2008-12-11 12:36:07 +01:00
help = ' disable feature X for build ' )
2010-12-07 16:07:20 +01:00
@cmdln.option ( ' --define ' , metavar = ' \' X Y \' ' , action = ' append ' ,
help = ' define macro X with value Y ' )
2017-04-19 15:33:08 +02:00
@cmdln.option ( ' --build-opt ' , metavar = ' OPT ' , action = ' append ' ,
help = ' pass option OPT to the build command ' )
2023-04-26 09:03:14 +02:00
@cmdln.option ( ' --buildtool-opt ' , metavar = ' OPT ' , action = ' append ' ,
help = ' pass option OPT to the build tool command (rpmbuild) ' )
2019-12-02 14:01:18 +01:00
@cmdln.option ( ' --userootforbuild ' , ' --login-as-root ' , action = ' store_true ' ,
2019-01-09 15:17:06 +01:00
help = ' Run build or shell as root. The default is to build as '
2007-05-14 10:29:50 +02:00
' unprivileged user. Note that a line " # norootforbuild " '
' in the spec file will invalidate this option. ' )
2010-02-12 22:54:39 +01:00
@cmdln.option ( ' --build-uid ' , metavar = ' uid:gid| " caller " ' ,
help = ' specify the numeric uid:gid pair to assign to the '
' unprivileged " abuild " user or use " caller " to use the current user uid:gid ' )
2009-03-31 13:45:30 +02:00
@cmdln.option ( ' --local-package ' , action = ' store_true ' ,
2008-01-07 15:54:31 +01:00
help = ' build a package which does not exist on the server ' )
2021-02-18 08:56:22 +01:00
@cmdln.option ( ' --stage ' , metavar = ' STAGE ' ,
help = ' runs a specific stage, default is " a " for all. Append a trailing " = " '
' to only run the specified stage. Append a trailing " + " to run '
' the specified stage and all stages coming after it. With no '
' suffix, stages up to and included the specified stage are run. ' )
2009-12-09 06:53:27 +01:00
@cmdln.option ( ' --linksources ' , action = ' store_true ' ,
help = ' use hard links instead of a deep copied source ' )
2017-04-19 15:27:04 +02:00
@cmdln.option ( ' --vm-memory ' , metavar = ' MEMORY ' ,
2019-12-03 15:08:41 +01:00
help = ' amount of memory for VM defined in MB ' )
@cmdln.option ( ' --vm-disk-size ' , metavar = ' DISKSIZE ' ,
help = ' size for newly created disk image in MB ' )
2010-04-29 14:27:29 +02:00
@cmdln.option ( ' --vm-type ' , metavar = ' TYPE ' ,
help = ' use VM type TYPE (e.g. kvm) ' )
2015-11-25 14:20:55 +01:00
@cmdln.option ( ' --vm-telnet ' , metavar = ' TELNET ' ,
help = ' Launch a telnet server inside of VM build ' )
2013-02-06 17:12:52 +01:00
@cmdln.option ( ' --target ' , metavar = ' TARGET ' ,
2013-05-07 09:29:59 +02:00
help = ' define target platform ' )
2009-03-31 13:45:30 +02:00
@cmdln.option ( ' --alternative-project ' , metavar = ' PROJECT ' ,
2008-01-07 15:54:31 +01:00
help = ' specify the build target project ' )
2008-03-11 16:18:02 +01:00
@cmdln.option ( ' -d ' , ' --debuginfo ' , action = ' store_true ' ,
help = ' also build debuginfo sub-packages ' )
2009-03-31 13:45:30 +02:00
@cmdln.option ( ' --disable-debuginfo ' , action = ' store_true ' ,
help = ' disable build of debuginfo packages ' )
2008-05-08 14:21:57 +02:00
@cmdln.option ( ' -b ' , ' --baselibs ' , action = ' store_true ' ,
help = ' Create -32bit/-64bit/-x86 rpms for other architectures ' )
2009-12-01 14:36:11 +01:00
@cmdln.option ( ' --release ' , metavar = ' N ' ,
help = ' set release number of the package to N ' )
2010-09-07 16:08:05 +02:00
@cmdln.option ( ' --disable-cpio-bulk-download ' , action = ' store_true ' ,
2010-09-15 15:28:47 +02:00
help = ' disable downloading packages as cpio archive from api ' )
@cmdln.option ( ' --cpio-bulk-download ' , action = ' store_false ' ,
2022-09-30 10:27:10 +02:00
dest = ' disable_cpio_bulk_download ' , help = argparse . SUPPRESS )
2010-01-20 09:15:17 +01:00
@cmdln.option ( ' --download-api-only ' , action = ' store_true ' ,
2014-05-15 17:46:10 +02:00
help = ' only fetch packages from the api ' )
2010-06-24 10:51:38 +02:00
@cmdln.option ( ' --oldpackages ' , metavar = ' DIR ' ,
2022-09-12 13:43:10 +02:00
help = ' take previous build from DIR (special values: _self, _link) ' )
2022-09-30 09:20:14 +02:00
@cmdln.option ( ' --verbose-mode ' , metavar = ' MODE ' ,
help = ' set verbose mode of the " build " program, arguments can be " all " or " vm " ' )
2019-01-09 15:17:06 +01:00
@cmdln.option ( ' --wipe ' , action = ' store_true ' ,
2022-09-30 10:27:10 +02:00
help = argparse . SUPPRESS )
2010-06-24 10:51:55 +02:00
@cmdln.option ( ' --shell ' , action = ' store_true ' ,
2022-09-30 10:27:10 +02:00
help = argparse . SUPPRESS )
2021-02-11 10:58:40 +01:00
@cmdln.option ( ' --shell-after-fail ' , action = ' store_true ' ,
help = " run a shell if the build tool fails " )
2019-01-09 15:17:06 +01:00
@cmdln.option ( ' --shell-cmd ' , metavar = ' COMMAND ' ,
help = ' run specified command instead of bash ' )
2019-12-11 14:20:54 +01:00
@cmdln.option ( ' -f ' , ' --force ' , action = ' store_true ' ,
help = ' Do not ask for confirmation to wipe ' )
2013-02-11 14:27:18 +01:00
@cmdln.option ( ' --host ' , metavar = ' HOST ' ,
2022-09-12 13:43:10 +02:00
help = ' perform the build on a remote server - user@server:~/remote/directory ' )
2015-05-05 23:39:58 +02:00
@cmdln.option ( ' --trust-all-projects ' , action = ' store_true ' ,
help = ' trust packages from all projects ' )
2016-06-09 16:24:30 +02:00
@cmdln.option ( ' --nopreinstallimage ' , ' --no-preinstallimage ' , action = ' store_true ' ,
help = ' Do not use preinstall images for creating the build root. ' )
2023-09-04 11:48:11 +02:00
@cmdln.option ( " --just-print-buildroot " , action = " store_true " ,
help = " Print build root path and exit. " )
2019-01-09 15:17:06 +01:00
@cmdln.alias ( ' chroot ' )
@cmdln.alias ( ' shell ' )
@cmdln.alias ( ' wipe ' )
2007-04-25 01:00:12 +02:00
def do_build ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Build a package on your local machine
2006-09-15 13:47:34 +02:00
2022-08-03 07:16:37 +02:00
The command works from a package checkout ( local changes are fine ) .
2006-07-05 12:25:31 +02:00
2022-08-03 07:16:37 +02:00
You can use ` osc repos ` to look up REPOSITORY and ARCH arguments . If
2022-08-03 12:36:31 +02:00
they are not set , ` osc ` choses from configured repos in this priority :
1. ` build_repository ` mentioned in config file
2. " standard "
3. " openSUSE_Factory "
4. " openSUSE_Tumbleweed "
5. last repo from the sorted list
BUILD_DESCR is either a RPM spec file , or a Debian dsc file .
2006-07-05 12:25:31 +02:00
2019-05-24 13:42:47 +02:00
The command honors packagecachedir , build - root and build - uid
2017-10-27 11:29:00 +02:00
settings in oscrc , if present . You may want to set su - wrapper = ' sudo '
in oscrc , and configure sudo with option NOPASSWD for / usr / bin / build .
2006-07-05 12:25:31 +02:00
2007-05-02 15:49:57 +02:00
If neither - - clean nor - - noinit is given , build will reuse an existing
build - root again , removing unneeded packages and add missing ones . This
is usually the fastest option .
2006-07-05 12:25:31 +02:00
2008-01-07 15:54:31 +01:00
If the package doesn ' t exist on the server please use the --local-package
2022-08-03 07:16:37 +02:00
option . If the project of the package doesn ' t exist on the server use the
- - alternative - project < alternative - project > option . Example :
2008-01-07 15:54:31 +01:00
osc build [ OPTS ] - - alternative - project openSUSE : 10.3 standard i586 BUILD_DESCR
2009-05-18 16:50:43 +02:00
usage :
2019-01-09 15:17:06 +01:00
osc build [ OPTS ] # will try to guess a build environement
2009-09-08 10:14:27 +02:00
osc build [ OPTS ] REPOSITORY ARCH BUILD_DESCR
2011-09-30 14:26:58 +02:00
osc build [ OPTS ] REPOSITORY ARCH
2009-09-08 10:14:27 +02:00
osc build [ OPTS ] REPOSITORY ( ARCH = hostarch , BUILD_DESCR is detected automatically )
osc build [ OPTS ] ARCH ( REPOSITORY = build_repository ( config option ) , BUILD_DESCR is detected automatically )
osc build [ OPTS ] BUILD_DESCR ( REPOSITORY = build_repository ( config option ) , ARCH = hostarch )
osc build [ OPTS ] ( REPOSITORY = build_repository ( config option ) , ARCH = hostarch , BUILD_DESCR is detected automatically )
2008-04-09 20:45:59 +02:00
2022-08-03 07:16:37 +02:00
For debugging after a build you can jump into the build environment :
2019-01-09 15:17:06 +01:00
osc shell [ OPTS ] REPOSITORY ARCH
2020-05-12 09:19:01 +02:00
Run a single command inside of the build environment :
osc shell - - shell - cmd = COMMAND [ OPTS ] REPOSITORY ARCH
2022-08-03 07:16:37 +02:00
Useful ` shell ` OPTS
2019-11-28 10:21:05 +01:00
- - noinit # for faster run
- - shell - cmd = COMMAND
2021-02-11 10:58:40 +01:00
- - shell - after - fail
2020-05-12 09:19:01 +02:00
- - extra - pkgs = PACKAGE # install additional packages
2019-01-09 15:17:06 +01:00
To clean up the build environment run
osc wipe [ OPTS ]
osc wipe [ OPTS ] REPOSITORY ARCH
2022-08-03 07:16:37 +02:00
If you ' ve set the used VM type in oscrc, it can be also overridden here
2019-11-28 10:21:05 +01:00
- - vm - type = chroot # for faster, but uncleaner and unsecure build
- - vm - type = kvm # for clean and secure build
- - vm - type = qemu # for slow cross architecture build using system emulator
2009-05-18 16:50:43 +02:00
# Note:
# Configuration can be overridden by envvars, e.g.
# OSC_SU_WRAPPER overrides the setting of su-wrapper.
2008-04-09 20:45:59 +02:00
# OSC_BUILD_ROOT overrides the setting of build-root.
# OSC_PACKAGECACHEDIR overrides the setting of packagecachedir.
"""
2014-10-01 14:45:48 +02:00
if which ( conf . config [ ' build-cmd ' ] ) is None :
print ( ' Error: build ( \' %s \' ) command not found ' % conf . config [ ' build-cmd ' ] , file = sys . stderr )
print ( ' Install the build package from http://download.opensuse.org/repositories/openSUSE:/Tools/ ' , file = sys . stderr )
2007-04-25 01:00:12 +02:00
return 1
2006-07-17 15:15:42 +02:00
2009-03-31 13:45:30 +02:00
if opts . debuginfo and opts . disable_debuginfo :
raise oscerr . WrongOptions ( ' osc: --debuginfo and --disable-debuginfo are mutual exclusive ' )
2019-01-09 15:17:06 +01:00
if subcmd == ' wipe ' :
opts . wipe = True
2008-07-30 18:45:00 +02:00
if len ( args ) > 3 :
raise oscerr . WrongArgs ( ' Too many arguments ' )
2009-05-18 16:50:43 +02:00
2023-07-27 13:29:38 +02:00
store = osc_store . get_store ( Path . cwd ( ) , print_warnings = True )
2023-07-25 15:58:21 +02:00
store . assert_is_package ( )
2023-08-23 12:02:25 +02:00
try :
if opts . alternative_project and opts . alternative_project == store . project :
opts . alternative_project = None
except RuntimeError :
# ignore the following exception: Couldn't map git branch '<BRANCH>' to a project
pass
2018-02-07 14:35:35 +01:00
2023-07-27 13:29:38 +02:00
# HACK: avoid calling some underlying store_*() functions from parse_repoarchdescr() method
# We'll fix parse_repoarchdescr() later because it requires a larger change
if not opts . alternative_project and isinstance ( store , git_scm . GitStore ) :
opts . alternative_project = store . project
2023-07-25 15:58:21 +02:00
if len ( args ) == 0 and store . is_package and store . last_buildroot :
2019-12-04 09:45:17 +01:00
# build env not specified, just read from last build attempt
2023-07-25 15:58:21 +02:00
args = [ store . last_buildroot [ 0 ] , store . last_buildroot [ 1 ] ]
if not opts . vm_type :
opts . vm_type = store . last_buildroot [ 2 ]
2009-11-26 10:52:26 +01:00
2023-09-04 11:48:11 +02:00
if opts . just_print_buildroot :
if opts . root :
build_root = opts . root
else :
args = self . parse_repoarchdescr ( args , opts . noinit or opts . offline , opts . alternative_project , False , opts . vm_type , opts . multibuild_package )
repo , arch , build_descr = args
prj , pac = osc_build . calculate_prj_pac ( store , opts , build_descr )
apihost = urlsplit ( self . get_api_url ( ) ) [ 1 ]
2023-09-25 14:56:50 +02:00
user = osc_build . calculate_build_root_user ( opts . vm_type )
build_root = osc_build . calculate_build_root ( apihost , prj , pac , repo , arch , user )
2023-09-04 11:48:11 +02:00
print ( build_root )
return
2019-12-11 14:20:54 +01:00
vm_chroot = opts . vm_type or conf . config [ ' build-type ' ]
if ( subcmd in ( ' shell ' , ' chroot ' ) or opts . shell or opts . wipe ) and not vm_chroot :
if opts . root :
build_root = opts . root
else :
args = self . parse_repoarchdescr ( args , opts . noinit or opts . offline , opts . alternative_project , False , opts . vm_type , opts . multibuild_package )
repo , arch , build_descr = args
2023-07-25 15:58:21 +02:00
prj , pac = osc_build . calculate_prj_pac ( store , opts , build_descr )
2019-12-11 14:20:54 +01:00
apihost = urlsplit ( self . get_api_url ( ) ) [ 1 ]
2023-09-25 14:56:50 +02:00
user = osc_build . calculate_build_root_user ( opts . vm_type )
build_root = osc_build . calculate_build_root ( apihost , prj , pac , repo , arch , user )
2019-12-11 14:20:54 +01:00
if opts . wipe and not opts . force :
2022-08-29 13:39:20 +02:00
# Confirm delete
2023-09-26 13:34:02 +02:00
print ( " Really wipe ' %s ' ? [y/N]: " % build_root , end = " " )
2022-08-29 13:39:20 +02:00
choice = raw_input ( ) . lower ( )
if choice != ' y ' :
print ( ' Aborting ' )
sys . exit ( 0 )
2019-12-11 14:20:54 +01:00
build_args = [ ' --root= ' + build_root , ' --noinit ' , ' --shell ' ]
if opts . wipe :
build_args . append ( ' --wipe ' )
2022-09-09 11:46:28 +02:00
sys . exit ( osc_build . run_build ( opts , * build_args ) )
2019-12-11 14:20:54 +01:00
elif subcmd in ( ' shell ' , ' chroot ' ) or opts . shell :
print ( ' --shell in combination with build-type %s is experimental. ' % vm_chroot )
print ( ' The semantics may change at any time! ' )
opts . shell = True
2017-02-14 17:09:16 +01:00
args = self . parse_repoarchdescr ( args , opts . noinit or opts . offline , opts . alternative_project , False , opts . vm_type , opts . multibuild_package )
2016-05-15 17:50:31 +02:00
2017-03-31 15:48:14 +02:00
if not opts . local_package :
try :
prj = Project ( os . pardir , getPackageList = False , wc_check = False )
2023-07-25 15:58:21 +02:00
if prj . status ( store . package ) == " A " :
2017-03-31 15:48:14 +02:00
# a package with state 'A' most likely does not exist on
# the server - hence, treat it as a local package
opts . local_package = True
2023-07-25 15:58:21 +02:00
print ( " INFO: Building the package as a local package. " , file = sys . stderr )
2017-03-31 15:48:14 +02:00
except oscerr . NoWorkingCopy :
pass
2010-08-12 23:13:51 +02:00
if conf . config [ ' no_verify ' ] :
2010-08-12 21:34:08 +02:00
opts . no_verify = True
2010-08-26 18:50:20 +02:00
if opts . keep_pkgs and not os . path . isdir ( opts . keep_pkgs ) :
if os . path . exists ( opts . keep_pkgs ) :
raise oscerr . WrongOptions ( ' Preferred save location \' %s \' is not a directory ' % opts . keep_pkgs )
else :
os . makedirs ( opts . keep_pkgs )
2007-05-03 17:54:40 +02:00
if opts . prefer_pkgs :
for d in opts . prefer_pkgs :
2007-05-02 15:49:57 +02:00
if not os . path . isdir ( d ) :
2010-01-09 14:25:41 +01:00
raise oscerr . WrongOptions ( ' Preferred package location \' %s \' is not a directory ' % d )
2007-05-02 15:49:57 +02:00
2010-04-17 10:53:53 +02:00
if opts . offline and opts . preload :
raise oscerr . WrongOptions ( ' --offline and --preload are mutually exclusive ' )
2023-05-04 14:39:17 +02:00
if not opts . skip_local_service_run :
# if the option is not set by the user read the default from config
if not conf . config [ ' local_service_run ' ] :
opts . skip_local_service_run = True
2019-12-02 14:32:36 +01:00
if opts . shell or opts . wipe :
2023-05-04 14:39:17 +02:00
opts . skip_local_service_run = True
2019-12-02 14:32:36 +01:00
2016-06-09 16:24:30 +02:00
if opts . preload :
opts . nopreinstallimage = True
2019-02-04 13:07:59 +01:00
2013-04-09 12:51:28 +02:00
print ( ' Building %s for %s / %s ' % ( args [ 2 ] , args [ 0 ] , args [ 1 ] ) )
2013-02-11 14:27:18 +01:00
if not opts . host :
2023-07-25 15:58:21 +02:00
return osc_build . main ( self . get_api_url ( ) , store , opts , args )
2013-02-11 14:27:18 +01:00
else :
return self . _do_rbuild ( subcmd , opts , * args )
def _do_rbuild ( self , subcmd , opts , * args ) :
# drop the --argument, value tuple from the list
def drop_arg2 ( lst , name ) :
2014-08-12 15:01:16 +02:00
if not name :
2013-05-27 13:38:49 +02:00
return lst
2013-02-11 14:27:18 +01:00
while name in lst :
i = lst . index ( name )
2022-09-12 13:43:10 +02:00
lst . pop ( i + 1 )
2013-02-11 14:27:18 +01:00
lst . pop ( i )
return lst
# change the local directory to more suitable remote one in hostargs
# and perform the rsync to such location as well
def rsync_dirs_2host ( hostargs , short_name , long_name , dirs ) :
drop_arg2 ( hostargs , short_name )
drop_arg2 ( hostargs , long_name )
for pdir in dirs :
# drop the last '/' from pdir name - this is because
# rsync foo remote:/bar create /bar/foo on remote machine
# rsync foo/ remote:/bar copy the content of foo in the /bar
if pdir [ - 1 : ] == os . path . sep :
pdir = pdir [ : - 1 ]
hostprefer = os . path . join (
2022-09-12 13:43:10 +02:00
hostpath ,
basename ,
" %s __ " % ( long_name . replace ( ' - ' , ' _ ' ) ) ,
os . path . basename ( os . path . abspath ( pdir ) ) )
2013-02-11 14:27:18 +01:00
hostargs . append ( long_name )
hostargs . append ( hostprefer )
2014-01-08 15:18:02 +01:00
rsync_prefer_cmd = [ ' rsync ' , ' -az ' , ' --delete ' , ' -e ' , ' ssh ' ,
2022-09-12 13:43:10 +02:00
pdir ,
" %s : %s " % ( hostname , os . path . dirname ( hostprefer ) ) ]
2013-04-09 12:51:28 +02:00
print ( ' Run: %s ' % " " . join ( rsync_prefer_cmd ) )
2013-03-08 00:56:57 +01:00
ret = run_external ( rsync_prefer_cmd [ 0 ] , * rsync_prefer_cmd [ 1 : ] )
2013-02-11 14:27:18 +01:00
if ret != 0 :
return ret
return 0
2016-05-15 17:50:31 +02:00
2022-10-07 17:25:33 +02:00
cwd = Path . cwd ( )
2013-02-11 14:27:18 +01:00
basename = os . path . basename ( cwd )
2022-09-12 14:15:34 +02:00
if ' : ' not in opts . host :
2013-02-11 14:27:18 +01:00
hostname = opts . host
hostpath = " ~/ "
else :
hostname , hostpath = opts . host . split ( ' : ' , 1 )
# arguments for build: use all arguments behind build and drop --host 'HOST'
2022-09-12 13:43:10 +02:00
hostargs = sys . argv [ sys . argv . index ( subcmd ) + 1 : ]
2013-02-11 14:27:18 +01:00
drop_arg2 ( hostargs , ' --host ' )
# global arguments: use first '-' up to subcmd
gi = 0
for i , a in enumerate ( sys . argv ) :
if a == subcmd :
break
if a [ 0 ] == ' - ' :
gi = i
break
if gi :
2022-04-20 19:22:35 +02:00
hostglobalargs = sys . argv [ gi : sys . argv . index ( subcmd ) + 1 ]
2013-02-11 14:27:18 +01:00
else :
hostglobalargs = ( subcmd , )
# keep-pkgs
hostkeep = None
if opts . keep_pkgs :
drop_arg2 ( hostargs , ' -k ' )
drop_arg2 ( hostargs , ' --keep-pkgs ' )
hostkeep = os . path . join (
2022-09-12 13:43:10 +02:00
hostpath ,
basename ,
" __keep_pkgs__ " ,
" " ) # <--- this adds last '/', thus triggers correct rsync behavior
2013-02-11 14:27:18 +01:00
hostargs . append ( ' --keep-pkgs ' )
hostargs . append ( hostkeep )
### run all commands ###
# 1.) rsync sources
2014-01-08 15:18:02 +01:00
rsync_source_cmd = [ ' rsync ' , ' -az ' , ' --delete ' , ' -e ' , ' ssh ' , cwd , " %s : %s " % ( hostname , hostpath ) ]
2013-04-09 12:51:28 +02:00
print ( ' Run: %s ' % " " . join ( rsync_source_cmd ) )
2013-03-08 00:56:57 +01:00
ret = run_external ( rsync_source_cmd [ 0 ] , * rsync_source_cmd [ 1 : ] )
2013-02-11 14:27:18 +01:00
if ret != 0 :
return ret
# 2.) rsync prefer-pkgs dirs, overlay and rsyns-src
if opts . prefer_pkgs :
ret = rsync_dirs_2host ( hostargs , ' -p ' , ' --prefer-pkgs ' , opts . prefer_pkgs )
if ret != 0 :
return ret
for arg , long_name in ( ( opts . rsyncsrc , ' --rsync-src ' ) , ( opts . overlay , ' --overlay ' ) ) :
2014-08-12 15:01:16 +02:00
if not arg :
2013-05-27 13:38:49 +02:00
continue
2013-02-11 14:27:18 +01:00
ret = rsync_dirs_2host ( hostargs , None , long_name , ( arg , ) )
if ret != 0 :
return ret
# 3.) call osc build
osc_cmd = " osc "
for var in ( ' OSC_SU_WRAPPER ' , ' OSC_BUILD_ROOT ' , ' OSC_PACKAGECACHEDIR ' ) :
if os . getenv ( var ) :
osc_cmd = " %s = %s %s " % ( var , os . getenv ( var ) , osc_cmd )
ssh_cmd = \
[ ' ssh ' , ' -t ' , hostname ,
2022-09-12 13:43:10 +02:00
" cd %(remote_dir)s ; %(osc_cmd)s %(global_args)s %(local_args)s " % dict (
remote_dir = os . path . join ( hostpath , basename ) ,
osc_cmd = osc_cmd ,
global_args = " " . join ( hostglobalargs ) ,
local_args = " " . join ( hostargs ) )
]
2013-04-09 12:51:28 +02:00
print ( ' Run: %s ' % " " . join ( ssh_cmd ) )
2013-03-08 00:56:57 +01:00
build_ret = run_external ( ssh_cmd [ 0 ] , * ssh_cmd [ 1 : ] )
2013-02-11 14:27:18 +01:00
if build_ret != 0 :
return build_ret
# 4.) get keep-pkgs back
if opts . keep_pkgs :
ret = rsync_keep_cmd = [ ' rsync ' , ' -az ' , ' -e ' , ' ssh ' , " %s : %s " % ( hostname , hostkeep ) , opts . keep_pkgs ]
2013-04-09 12:51:28 +02:00
print ( ' Run: %s ' % " " . join ( rsync_keep_cmd ) )
2013-03-08 00:56:57 +01:00
ret = run_external ( rsync_keep_cmd [ 0 ] , * rsync_keep_cmd [ 1 : ] )
2013-02-11 14:27:18 +01:00
if ret != 0 :
return ret
return build_ret
2006-07-14 19:39:46 +02:00
2009-05-13 11:04:27 +02:00
@cmdln.option ( ' ' , ' --csv ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' generate output in CSV (separated by |) ' )
2023-04-17 15:31:46 +02:00
@cmdln.option ( ' -l ' , ' --limit ' , metavar = ' limit ' , type = int , default = 0 ,
2015-12-07 10:05:08 +01:00
help = ' for setting the number of results ' )
2022-05-10 10:49:57 +02:00
@cmdln.option ( ' -M ' , ' --multibuild-package ' , metavar = ' FLAVOR ' ,
help = HELP_MULTIBUILD_ONE )
2007-04-25 01:00:12 +02:00
@cmdln.alias ( ' buildhist ' )
2009-09-08 10:14:27 +02:00
def do_buildhistory ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Shows the build history of a package
2006-05-19 22:13:29 +02:00
2009-09-08 10:14:27 +02:00
The arguments REPOSITORY and ARCH can be taken from the first two columns
2007-04-25 01:00:12 +02:00
of the ' osc repos ' output .
2009-09-08 10:14:27 +02:00
usage :
osc buildhist REPOSITORY ARCHITECTURE
2022-05-10 10:49:57 +02:00
osc buildhist PROJECT PACKAGE [ : FLAVOR ] REPOSITORY ARCHITECTURE
2007-04-25 01:00:12 +02:00
"""
2010-04-30 17:13:21 +02:00
apiurl = self . get_api_url ( )
2022-12-15 10:05:18 +01:00
args = list ( args )
2023-01-26 15:49:21 +01:00
args_backup = args . copy ( )
try :
args = [ " . " , " . " ] + args_backup . copy ( )
project , package , repository , arch = pop_project_package_repository_arch_from_args ( args )
ensure_no_remaining_args ( args )
except ( oscerr . NoWorkingCopy , oscerr . WrongArgs ) :
args [ : ] = args_backup . copy ( )
project , package , repository , arch = pop_project_package_repository_arch_from_args ( args )
ensure_no_remaining_args ( args )
2006-09-29 12:37:53 +02:00
2017-02-14 17:09:16 +01:00
if opts . multibuild_package :
package = package + " : " + opts . multibuild_package
2022-12-15 10:05:18 +01:00
history = _private . BuildHistory ( apiurl , project , package , repository , arch , limit = opts . limit )
2009-05-13 11:04:27 +02:00
if opts . csv :
2022-12-15 10:05:18 +01:00
print ( history . to_csv ( ) , end = " " )
else :
print ( history . to_text_table ( ) )
2006-06-08 12:30:29 +02:00
2009-05-13 11:04:27 +02:00
@cmdln.option ( ' ' , ' --csv ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' generate output in CSV (separated by |) ' )
2009-11-13 14:31:10 +01:00
@cmdln.option ( ' -l ' , ' --limit ' , metavar = ' limit ' ,
help = ' for setting the number of results ' )
2022-05-10 10:51:18 +02:00
@cmdln.option ( ' -M ' , ' --multibuild-package ' , metavar = ' FLAVOR ' ,
help = HELP_MULTIBUILD_ONE )
2009-02-20 12:04:45 +01:00
@cmdln.alias ( ' jobhist ' )
2009-11-06 19:47:54 +01:00
def do_jobhistory ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Shows the job history of a project
2009-02-20 12:04:45 +01:00
2009-09-08 10:14:27 +02:00
The arguments REPOSITORY and ARCH can be taken from the first two columns
2009-02-20 12:04:45 +01:00
of the ' osc repos ' output .
2009-11-06 19:47:54 +01:00
usage :
osc jobhist REPOSITORY ARCHITECTURE ( in project dir )
2022-05-10 10:51:18 +02:00
osc jobhist PROJECT [ PACKAGE [ : FLAVOR ] ] REPOSITORY ARCHITECTURE
2009-02-20 12:04:45 +01:00
"""
2022-10-07 17:25:33 +02:00
wd = Path . cwd ( )
2009-11-06 19:47:54 +01:00
args = slash_split ( args )
2010-02-09 02:27:29 +01:00
if len ( args ) < 2 and ( is_project_dir ( ' . ' ) or is_package_dir ( ' . ' ) ) :
2009-11-23 11:13:19 +01:00
self . print_repos ( )
2010-04-30 17:13:21 +02:00
apiurl = self . get_api_url ( )
2009-11-06 19:47:54 +01:00
if len ( args ) == 4 :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2009-11-06 19:47:54 +01:00
package = args [ 1 ]
repository = args [ 2 ]
arch = args [ 3 ]
elif len ( args ) == 3 :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2009-11-06 19:47:54 +01:00
package = None # skipped = prj
repository = args [ 1 ]
arch = args [ 2 ]
elif len ( args ) == 2 :
package = None
try :
package = store_read_package ( wd )
except :
pass
project = store_read_project ( wd )
repository = args [ 0 ]
arch = args [ 1 ]
else :
raise oscerr . WrongArgs ( ' Wrong number of arguments ' )
2009-02-20 12:04:45 +01:00
2022-05-10 10:51:18 +02:00
if opts . multibuild_package and package :
2017-02-14 17:09:16 +01:00
package = package + " : " + opts . multibuild_package
2009-05-13 11:04:27 +02:00
format = ' text '
if opts . csv :
format = ' csv '
2009-11-23 11:13:12 +01:00
print_jobhistory ( apiurl , project , package , repository , arch , format , opts . limit )
2009-02-20 12:04:45 +01:00
2007-07-12 02:48:52 +02:00
@cmdln.option ( ' -r ' , ' --revision ' , metavar = ' rev ' ,
help = ' show log of the specified revision ' )
2009-05-13 10:53:32 +02:00
@cmdln.option ( ' ' , ' --csv ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' generate output in CSV (separated by |) ' )
2009-05-13 10:53:32 +02:00
@cmdln.option ( ' ' , ' --xml ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' generate output in XML ' )
2011-01-19 20:26:38 +01:00
@cmdln.option ( ' -D ' , ' --deleted ' , action = ' store_true ' ,
help = ' work on deleted package ' )
2010-05-25 14:00:50 +02:00
@cmdln.option ( ' -M ' , ' --meta ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' checkout out meta data instead of sources ' )
2009-05-25 13:33:04 +02:00
def do_log ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Shows the commit log of a package
2007-07-12 01:24:26 +02:00
2022-01-19 15:13:55 +01:00
usage :
2009-05-25 13:33:04 +02:00
osc log ( inside working copy )
2010-05-27 07:17:27 +02:00
osc log remote_project [ remote_package ]
2008-09-23 15:39:54 +02:00
"""
2010-04-30 17:13:21 +02:00
apiurl = self . get_api_url ( )
2022-11-09 10:56:56 +01:00
args = list ( args )
project , package = pop_project_package_from_args (
args , default_project = " . " , default_package = " . " , package_is_optional = True
)
2009-05-25 12:41:16 +02:00
2022-06-02 10:02:32 +02:00
rev , rev_upper = parseRevisionOption ( opts . revision )
2023-10-05 14:15:28 +02:00
if not revision_is_empty ( rev ) and not checkRevision ( project , package , rev , apiurl , opts . meta ) :
2013-04-09 12:51:28 +02:00
print ( ' Revision \' %s \' does not exist ' % rev , file = sys . stderr )
2008-09-23 15:39:54 +02:00
sys . exit ( 1 )
2009-05-13 10:53:32 +02:00
format = ' text '
if opts . csv :
format = ' csv '
if opts . xml :
format = ' xml '
2011-11-22 20:12:28 +01:00
log = ' \n ' . join ( get_commitlog ( apiurl , project , package , rev , format , opts . meta , opts . deleted , rev_upper ) )
2010-05-03 10:05:36 +02:00
run_pager ( log )
2008-09-23 15:39:54 +02:00
2023-01-10 08:48:09 +01:00
@cmdln.option ( ' -v ' , ' --verbose ' , action = ' store_true ' ,
help = ' verbose run of local services for debugging purposes ' )
2010-09-01 12:44:47 +02:00
def do_service ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Handle source services
2010-09-01 12:44:47 +02:00
Source services can be used to modify sources like downloading files ,
verify files , generating files or modify existing files .
usage :
osc service COMMAND ( inside working copy )
2011-02-15 09:41:03 +01:00
osc service run [ SOURCE_SERVICE ]
2017-03-31 10:34:52 +02:00
osc service runall
Fix single service disabled run
Without this patch, running an individual service that has parameters
defined in the _service file fails:
$ osc service run obs_scm
Please specify valid --scm=... options
Aborting: service call failed: /usr/lib/obs/service/obs_scm --outdir [snipped]
This is because although the service is defined in the _service file and
the "scm" parameter is set in it, the service wasn't being found in the
data structure and so the service executable wasn't being called with
the parameters supplied in the _service file. This patch corrects the
issue with the services data structure so that the service data isn't
overridden if it is defined in the _service file.
A side effect of this correction for services defined in the _service
file is that instead of overriding the service mode with '', the mode is
taken from the _service file. When using the "run" command, this would
mean that the call mode of None may not be in agreement with the service
mode defined in the file, e.g. "manual", and so the "run" command would
no longer cause it to run when it would before. We can take this
opportunity to define this as the correct behavior - the "run" command
now only runs services with "trylocal", "localonly", or no mode set -
and also ensure that other call mode commands result in sensible
behavior when called with a service name, for instance "osc service
manualrun download_files" will run only services with mode="manual" and
name="download"files" instead of all services with mode="manual".
Additionally, services that aren't defined in the _service file can be
called with a call mode command and will use that call mode rather than
None.
2020-03-16 22:13:15 +01:00
osc service manualrun [ SOURCE_SERVICE ]
2011-02-15 09:41:03 +01:00
osc service remoterun [ PROJECT PACKAGE ]
2016-03-03 11:05:48 +01:00
osc service merge [ PROJECT PACKAGE ]
osc service wait [ PROJECT PACKAGE ]
2010-09-01 12:44:47 +02:00
COMMAND can be :
2021-04-28 12:11:56 +02:00
run r run defined services with modes " trylocal " , " localonly " , or no mode set locally ,
may take an optional parameter to run only a specified source service . In case
parameters exist for this one in _service file they are used .
2017-03-31 10:34:52 +02:00
runall ra run all services independent of the used mode
Fix single service disabled run
Without this patch, running an individual service that has parameters
defined in the _service file fails:
$ osc service run obs_scm
Please specify valid --scm=... options
Aborting: service call failed: /usr/lib/obs/service/obs_scm --outdir [snipped]
This is because although the service is defined in the _service file and
the "scm" parameter is set in it, the service wasn't being found in the
data structure and so the service executable wasn't being called with
the parameters supplied in the _service file. This patch corrects the
issue with the services data structure so that the service data isn't
overridden if it is defined in the _service file.
A side effect of this correction for services defined in the _service
file is that instead of overriding the service mode with '', the mode is
taken from the _service file. When using the "run" command, this would
mean that the call mode of None may not be in agreement with the service
mode defined in the file, e.g. "manual", and so the "run" command would
no longer cause it to run when it would before. We can take this
opportunity to define this as the correct behavior - the "run" command
now only runs services with "trylocal", "localonly", or no mode set -
and also ensure that other call mode commands result in sensible
behavior when called with a service name, for instance "osc service
manualrun download_files" will run only services with mode="manual" and
name="download"files" instead of all services with mode="manual".
Additionally, services that aren't defined in the _service file can be
called with a call mode command and will use that call mode rather than
None.
2020-03-16 22:13:15 +01:00
manualrun mr run all services with mode " manual " , may take an optional parameter to run only a
specified source service
2011-01-26 16:30:57 +01:00
remoterun rr trigger a re - run on the server side
2016-03-03 11:05:48 +01:00
merge commits all server side generated files and drops the _service definition
wait waits until the service finishes and returns with an error if it failed
2010-09-01 12:44:47 +02:00
2020-07-24 23:17:12 +02:00
Not for common usage anymore :
localrun lr the same as " run " but services with mode " serveronly " are also executed
disabledrun dr run all services with mode " disabled "
2010-09-01 12:44:47 +02:00
"""
2016-06-01 17:01:34 +02:00
# disabledrun and localrun exists as well, but are considered to be obsolete
2010-09-01 12:44:47 +02:00
2023-07-28 13:22:12 +02:00
args = list ( args )
2010-09-01 12:44:47 +02:00
apiurl = self . get_api_url ( )
2023-07-28 13:22:12 +02:00
project = None
package = None
singleservice = None
mode = None
remote_commands = ( " remoterun " , " rr " , " merge " , " wait " )
2010-09-01 12:44:47 +02:00
2011-03-22 10:21:25 +01:00
if len ( args ) < 1 :
2023-07-28 13:22:12 +02:00
self . argparse_error ( " Please specify a command " )
2010-09-01 12:44:47 +02:00
2023-07-28 13:22:12 +02:00
command = args . pop ( 0 )
2023-09-19 16:32:13 +02:00
if command not in ( " runall " , " ra " , " run " , " localrun " , " manualrun " , " disabledrun " , " remoterun " , " lr " , " dr " , " mr " , " r " , " rr " , " merge " , " wait " ) :
2023-07-28 13:22:12 +02:00
self . argparse_error ( f " Invalid command: { command } " )
2010-09-01 12:44:47 +02:00
2023-08-10 13:42:52 +02:00
if command in ( " localrun " , " lr " ) :
print ( f " WARNING: Command ' { command } ' is obsolete, please use ' run ' instead. " , file = sys . stderr )
if command in ( " disabledrun " , " dr " ) :
print ( f " WARNING: Command ' { command } ' is obsolete, \n "
" please convert your _service to use ' manual ' and then ' manualrun/mr ' instead. " , file = sys . stderr )
2023-07-28 13:22:12 +02:00
if len ( args ) == 1 :
singleservice = args . pop ( 0 )
elif len ( args ) in ( 0 , 2 ) and command in remote_commands :
project , package = pop_project_package_from_args (
args , default_project = " . " , default_package = " . " , package_is_optional = False
)
ensure_no_remaining_args ( args )
2011-03-22 10:21:25 +01:00
2022-09-30 14:09:37 +02:00
if command in ( ' remoterun ' , ' rr ' ) :
2013-04-09 12:51:28 +02:00
print ( runservice ( apiurl , project , package ) )
2011-02-15 09:41:03 +01:00
return
2010-09-01 12:44:47 +02:00
2016-03-03 11:05:48 +01:00
if command == " wait " :
print ( waitservice ( apiurl , project , package ) )
return
if command == " merge " :
print ( mergeservice ( apiurl , project , package ) )
return
2023-07-28 13:22:12 +02:00
store = osc_store . get_store ( Path . cwd ( ) , print_warnings = True )
store . assert_is_package ( )
2020-07-24 23:17:12 +02:00
if command in ( ' runall ' , ' ra ' , ' run ' , ' localrun ' , ' manualrun ' , ' disabledrun ' , ' lr ' , ' mr ' , ' dr ' , ' r ' ) :
2010-09-01 12:44:47 +02:00
p = Package ( " . " )
2022-09-30 14:09:37 +02:00
if command in ( " localrun " , " lr " ) :
2011-02-15 09:41:03 +01:00
mode = " local "
2022-09-30 14:09:37 +02:00
elif command in ( " manualrun " , " mr " ) :
2020-07-24 23:17:12 +02:00
mode = " manual "
2022-09-30 14:09:37 +02:00
elif command in ( " disabledrun " , " dr " ) :
2011-02-15 09:41:03 +01:00
mode = " disabled "
2022-09-30 14:09:37 +02:00
elif command in ( " runall " , " ra " ) :
2016-06-01 17:01:34 +02:00
mode = " all "
2011-02-15 09:41:03 +01:00
2023-01-10 08:48:09 +01:00
return p . run_source_services ( mode , singleservice , opts . verbose )
2010-09-01 12:44:47 +02:00
2010-11-08 16:20:01 +01:00
@cmdln.option ( ' -a ' , ' --arch ' , metavar = ' ARCH ' ,
help = ' trigger rebuilds for a specific architecture ' )
@cmdln.option ( ' -r ' , ' --repo ' , metavar = ' REPO ' ,
help = ' trigger rebuilds for a specific repository ' )
2007-04-25 01:00:12 +02:00
@cmdln.option ( ' -f ' , ' --failed ' , action = ' store_true ' ,
help = ' rebuild all failed packages ' )
2022-05-10 10:16:55 +02:00
@cmdln.option ( ' -M ' , ' --multibuild-package ' , metavar = " FLAVOR " , action = ' append ' ,
help = HELP_MULTIBUILD_MANY )
2011-02-22 22:44:04 +01:00
@cmdln.option ( ' --all ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' Rebuild all packages of entire project ' )
2009-06-15 17:38:39 +02:00
@cmdln.alias ( ' rebuildpac ' )
def do_rebuild ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Trigger package rebuilds
2006-06-08 12:30:29 +02:00
2007-04-25 01:00:12 +02:00
Note that it is normally NOT needed to kick off rebuilds like this , because
they principally happen in a fully automatic way , triggered by source
check - ins . In particular , the order in which packages are built is handled
by the build service .
2006-09-25 17:11:03 +02:00
2009-09-08 10:14:27 +02:00
The arguments REPOSITORY and ARCH can be taken from the first two columns
2009-06-23 12:06:31 +02:00
of the ' osc repos ' output .
2006-06-08 12:30:29 +02:00
2009-05-18 16:50:43 +02:00
usage :
2022-05-10 10:16:55 +02:00
osc rebuild [ PROJECT [ PACKAGE [ : FLAVOR ] [ REPOSITORY [ ARCH ] ] ] ]
2007-04-25 01:00:12 +02:00
"""
2010-07-29 17:29:07 +02:00
apiurl = self . get_api_url ( )
2010-04-23 12:01:24 +02:00
2023-01-12 10:46:01 +01:00
args = list ( args )
project , package , repo , arch = pop_project_package_repository_arch_from_args (
args ,
package_is_optional = True ,
repository_is_optional = True ,
arch_is_optional = True ,
2023-01-29 12:22:56 +01:00
default_project = ' . ' ,
default_package = ' . ' ,
2023-01-12 10:46:01 +01:00
)
ensure_no_remaining_args ( args )
2010-11-08 16:20:01 +01:00
if opts . repo :
repo = opts . repo
if opts . arch :
arch = opts . arch
2023-01-12 10:46:01 +01:00
code = None
2007-04-25 01:00:12 +02:00
if opts . failed :
code = ' failed '
2011-02-22 22:44:04 +01:00
if not ( opts . all or package or repo or arch or code ) :
raise oscerr . WrongOptions ( ' No option has been provided. If you want to rebuild all packages of the entire project, use --all option. ' )
2023-08-28 10:28:06 +02:00
if opts . all :
# ignore the package name which can come from a working copy
packages = [ None ]
elif opts . multibuild_package :
2022-05-10 10:16:55 +02:00
resolver = MultibuildFlavorResolver ( apiurl , project , package , use_local = False )
packages = resolver . resolve_as_packages ( opts . multibuild_package )
2017-02-14 17:09:16 +01:00
else :
2022-05-10 10:16:55 +02:00
packages = [ package ]
2017-02-14 17:09:16 +01:00
for package in packages :
print ( rebuild ( apiurl , project , package , repo , arch , code ) )
2006-05-23 15:48:58 +02:00
2007-05-04 23:51:54 +02:00
def do_info ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Print information about a working copy
2007-05-04 23:51:54 +02:00
Print information about each ARG ( default : ' . ' )
ARG is a working - copy path .
"""
args = parseargs ( args )
2022-09-13 16:34:54 +02:00
pacs = Package . from_paths ( args )
2007-05-04 23:51:54 +02:00
for p in pacs :
2013-04-09 12:51:28 +02:00
print ( p . info ( ) )
2007-05-04 23:51:54 +02:00
2022-05-10 10:34:24 +02:00
@cmdln.option ( ' -M ' , ' --multibuild-package ' , metavar = ' FLAVOR ' , action = ' append ' ,
help = HELP_MULTIBUILD_MANY )
2018-02-09 08:47:52 +01:00
def do_sendsysrq ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Trigger a sysrq in a running build
2018-02-09 08:47:52 +01:00
This is only going to work when the build is running in a supported VM .
Also only a subset of sysrq are supported . Typical use case for debugging
are 9 , t and w in this sequence .
usage :
2018-02-09 10:08:13 +01:00
osc sendsysrq REPOSITORY ARCH SYSRQ
2022-05-10 10:34:24 +02:00
osc sendsysrq PROJECT PACKAGE [ : FLAVOR ] REPOSITORY ARCH SYSRQ
2018-02-09 08:47:52 +01:00
"""
args = slash_split ( args )
project = package = repo = arch = sysrq = None
apiurl = self . get_api_url ( )
if len ( args ) < 4 :
2022-10-07 17:25:33 +02:00
if is_package_dir ( Path . cwd ( ) ) :
project = store_read_project ( Path . cwd ( ) )
package = store_read_package ( Path . cwd ( ) )
2022-10-14 14:25:54 +02:00
apiurl = osc_store . Store ( Path . cwd ( ) ) . apiurl
2018-02-09 08:47:52 +01:00
repo = args [ 0 ]
arch = args [ 1 ]
sysrq = args [ 2 ]
else :
raise oscerr . WrongArgs ( ' Too few arguments. ' )
elif len ( args ) != 5 :
raise oscerr . WrongArgs ( ' Wrong number of arguments. ' )
else :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2018-02-09 08:47:52 +01:00
package = args [ 1 ]
repo = args [ 2 ]
arch = args [ 3 ]
sysrq = args [ 4 ]
if opts . multibuild_package :
2022-05-10 10:34:24 +02:00
resolver = MultibuildFlavorResolver ( apiurl , project , package , use_local = False )
packages = resolver . resolve_as_packages ( opts . multibuild_package )
else :
packages = [ package ]
2018-02-09 15:35:52 +01:00
for package in packages :
print ( cmdbuild ( apiurl , ' sendsysrq ' , project , package , arch , repo , None , sysrq ) )
2018-02-09 08:47:52 +01:00
2007-06-14 16:30:36 +02:00
@cmdln.option ( ' -a ' , ' --arch ' , metavar = ' ARCH ' ,
2013-10-28 18:29:56 +01:00
help = ' Restart builds for a specific architecture ' )
2022-05-10 10:36:36 +02:00
@cmdln.option ( ' -M ' , ' --multibuild-package ' , metavar = " FLAVOR " , action = ' append ' ,
help = HELP_MULTIBUILD_MANY )
2007-06-14 16:30:36 +02:00
@cmdln.option ( ' -r ' , ' --repo ' , metavar = ' REPO ' ,
2013-10-28 18:29:56 +01:00
help = ' Restart builds for a specific repository ' )
2011-02-22 22:44:04 +01:00
@cmdln.option ( ' --all ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' Restart all running builds of entire project ' )
2013-10-28 18:29:56 +01:00
@cmdln.alias ( ' abortbuild ' )
def do_restartbuild ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Restart the build of a certain project or package
2009-05-18 16:50:43 +02:00
usage :
2022-05-10 10:36:36 +02:00
osc restartbuild [ PROJECT [ PACKAGE [ : FLAVOR ] [ REPOSITORY [ ARCH ] ] ] ]
2007-06-14 16:30:36 +02:00
"""
2011-04-20 14:05:00 +02:00
args = slash_split ( args )
package = repo = arch = code = None
2010-07-29 17:29:07 +02:00
apiurl = self . get_api_url ( )
2007-06-14 16:30:36 +02:00
2011-04-20 14:05:00 +02:00
if opts . repo :
repo = opts . repo
2007-06-14 16:30:36 +02:00
2011-04-20 14:05:00 +02:00
if opts . arch :
arch = opts . arch
if len ( args ) < 1 :
2022-10-07 17:25:33 +02:00
if is_package_dir ( Path . cwd ( ) ) :
project = store_read_project ( Path . cwd ( ) )
package = store_read_package ( Path . cwd ( ) )
2022-10-14 14:25:54 +02:00
apiurl = osc_store . Store ( Path . cwd ( ) ) . apiurl
2022-10-07 17:25:33 +02:00
elif is_project_dir ( Path . cwd ( ) ) :
project = store_read_project ( Path . cwd ( ) )
2022-10-14 14:25:54 +02:00
apiurl = osc_store . Store ( Path . cwd ( ) ) . apiurl
2011-04-20 14:05:00 +02:00
else :
raise oscerr . WrongArgs ( ' Too few arguments. ' )
2007-06-14 16:30:36 +02:00
else :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2011-04-20 14:05:00 +02:00
if len ( args ) > 1 :
package = args [ 1 ]
if len ( args ) > 2 :
repo = args [ 2 ]
if len ( args ) > 3 :
arch = args [ 3 ]
2007-06-14 16:30:36 +02:00
2011-02-22 22:44:04 +01:00
if not ( opts . all or package or repo or arch ) :
2013-10-28 18:29:56 +01:00
raise oscerr . WrongOptions ( ' No option has been provided. If you want to restart all packages of the entire project, use --all option. ' )
2011-02-22 22:44:04 +01:00
2017-02-14 17:09:16 +01:00
if opts . multibuild_package :
2022-05-10 10:36:36 +02:00
resolver = MultibuildFlavorResolver ( apiurl , project , package , use_local = False )
packages = resolver . resolve_as_packages ( opts . multibuild_package )
2017-02-14 17:09:16 +01:00
else :
2022-05-10 10:36:36 +02:00
packages = [ package ]
2017-02-14 17:09:16 +01:00
for package in packages :
print ( cmdbuild ( apiurl , subcmd , project , package , arch , repo ) )
2007-06-14 16:30:36 +02:00
@cmdln.option ( ' -a ' , ' --arch ' , metavar = ' ARCH ' ,
2007-07-04 16:57:19 +02:00
help = ' Delete all binary packages for a specific architecture ' )
2022-05-10 10:54:25 +02:00
@cmdln.option ( ' -M ' , ' --multibuild-package ' , metavar = " FLAVOR " , action = ' append ' ,
help = HELP_MULTIBUILD_MANY )
2007-06-14 16:30:36 +02:00
@cmdln.option ( ' -r ' , ' --repo ' , metavar = ' REPO ' ,
help = ' Delete all binary packages for a specific repository ' )
2007-07-04 16:57:19 +02:00
@cmdln.option ( ' --build-disabled ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' Delete all binaries of packages for which the build is disabled ' )
2007-10-27 21:13:24 +02:00
@cmdln.option ( ' --build-failed ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' Delete all binaries of packages for which the build failed ' )
2007-10-27 21:13:24 +02:00
@cmdln.option ( ' --broken ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' Delete all binaries of packages for which the package source is bad ' )
2010-04-23 14:38:00 +02:00
@cmdln.option ( ' --unresolvable ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' Delete all binaries of packages which have dependency errors ' )
2009-05-31 13:00:03 +02:00
@cmdln.option ( ' --all ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' Delete all binaries regardless of the package status (previously default) ' )
2017-01-16 11:58:02 +01:00
@cmdln.alias ( " unpublish " )
2007-06-14 16:30:36 +02:00
def do_wipebinaries ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Delete all binary packages of a certain project / package
2007-06-14 16:30:36 +02:00
2007-07-15 15:49:13 +02:00
With the optional argument < package > you can specify a certain package
2007-06-14 16:30:36 +02:00
otherwise all binary packages in the project will be deleted .
2009-05-18 16:50:43 +02:00
usage :
2011-01-21 11:04:47 +01:00
osc wipebinaries OPTS # works in checked out project dir
2022-05-10 10:54:25 +02:00
osc wipebinaries OPTS PROJECT [ PACKAGE [ : FLAVOR ] ]
2017-01-16 11:58:02 +01:00
osc unpublish OPTS # works in checked out project dir
2022-05-10 10:54:25 +02:00
osc unpublish OPTS PROJECT [ PACKAGE [ : FLAVOR ] ]
2007-06-14 16:30:36 +02:00
"""
2009-05-18 16:50:43 +02:00
2007-06-26 15:17:38 +02:00
args = slash_split ( args )
2010-06-29 15:32:53 +02:00
package = project = None
apiurl = self . get_api_url ( )
2010-06-27 19:07:46 +02:00
# try to get project and package from checked out dirs
2007-06-14 16:30:36 +02:00
if len ( args ) < 1 :
2022-10-07 17:25:33 +02:00
if is_project_dir ( Path . cwd ( ) ) :
project = store_read_project ( Path . cwd ( ) )
if is_package_dir ( Path . cwd ( ) ) :
project = store_read_project ( Path . cwd ( ) )
package = store_read_package ( Path . cwd ( ) )
2022-04-20 19:22:35 +02:00
if project is None :
2010-06-27 19:07:46 +02:00
raise oscerr . WrongArgs ( ' Missing <project> argument. ' )
2008-06-11 10:01:10 +02:00
if len ( args ) > 2 :
raise oscerr . WrongArgs ( ' Wrong number of arguments. ' )
2010-06-27 19:07:46 +02:00
# respect given project and package
if len ( args ) > = 1 :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2010-06-27 19:07:46 +02:00
2007-06-14 16:30:36 +02:00
if len ( args ) == 2 :
2013-05-27 12:16:44 +02:00
package = args [ 1 ]
2007-10-27 21:13:24 +02:00
codes = [ ]
if opts . build_disabled :
codes . append ( ' disabled ' )
if opts . build_failed :
codes . append ( ' failed ' )
if opts . broken :
codes . append ( ' broken ' )
2010-04-23 14:38:00 +02:00
if opts . unresolvable :
codes . append ( ' unresolvable ' )
2017-04-24 16:35:15 +02:00
if len ( codes ) == 0 :
# don't do a second wipe if a filter got specified
if opts . all or opts . repo or opts . arch :
codes . append ( None )
2007-10-27 21:13:24 +02:00
if len ( codes ) == 0 :
2010-01-09 14:25:41 +01:00
raise oscerr . WrongOptions ( ' No option has been provided. If you want to delete all binaries, use --all option. ' )
2007-10-27 21:13:24 +02:00
2017-02-14 17:09:16 +01:00
if opts . multibuild_package :
2022-05-10 10:54:25 +02:00
resolver = MultibuildFlavorResolver ( apiurl , project , package , use_local = False )
packages = resolver . resolve_as_packages ( opts . multibuild_package )
2017-02-14 17:09:16 +01:00
else :
2022-05-10 10:54:25 +02:00
packages = [ package ]
2017-02-14 17:09:16 +01:00
# make a new request for each code= parameter and for each package in packages
for package in packages :
for code in codes :
if subcmd == ' unpublish ' :
print ( unpublish ( apiurl , project , package , opts . arch , opts . repo , code ) )
else :
print ( wipebinaries ( apiurl , project , package , opts . arch , opts . repo , code ) )
2007-06-14 16:30:36 +02:00
2011-01-21 10:35:47 +01:00
@cmdln.option ( ' -d ' , ' --destdir ' , default = ' ./binaries ' , metavar = ' DIR ' ,
2008-09-30 16:54:08 +02:00
help = ' destination directory ' )
2022-02-28 13:11:49 +01:00
@cmdln.option ( ' -M ' , ' --multibuild-package ' , metavar = " FLAVOR " , action = ' append ' ,
help = ' Get binaries from the specified flavor of a multibuild package. '
' It is meant for use from a package checkout when it is not possible to specify package:flavor. ' )
2009-01-16 11:31:38 +01:00
@cmdln.option ( ' --sources ' , action = " store_true " ,
help = ' also fetch source packages ' )
2022-08-04 10:09:10 +02:00
@cmdln.option ( ' --debuginfo ' , action = " store_true " ,
2010-09-27 17:43:44 +02:00
help = ' also fetch debug packages ' )
2020-05-05 09:58:16 +02:00
@cmdln.option ( ' --ccache ' , action = " store_true " ,
help = ' allow fetching ccache archive ' )
2009-04-21 11:46:32 +02:00
def do_getbinaries ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Download binaries to a local directory
2008-09-30 16:54:08 +02:00
2009-05-18 16:50:43 +02:00
This command downloads packages directly from the api server .
2009-02-20 16:01:16 +01:00
Thus , it directly accesses the packages that are used for building
others even when they are not " published " yet .
2008-09-30 16:54:08 +02:00
2009-04-21 11:46:32 +02:00
usage :
2010-07-01 15:32:21 +02:00
osc getbinaries REPOSITORY # works in checked out project/package (check out all archs in subdirs)
osc getbinaries REPOSITORY ARCHITECTURE # works in checked out project/package
2019-05-24 13:42:47 +02:00
osc getbinaries PROJECT REPOSITORY ARCHITECTURE
2009-04-21 11:46:32 +02:00
osc getbinaries PROJECT PACKAGE REPOSITORY ARCHITECTURE
2012-11-19 10:21:24 +01:00
osc getbinaries PROJECT PACKAGE REPOSITORY ARCHITECTURE FILE
2008-09-30 16:54:08 +02:00
"""
2009-04-21 11:46:32 +02:00
args = slash_split ( args )
2010-04-30 17:13:21 +02:00
apiurl = self . get_api_url ( )
2010-07-12 14:56:08 +02:00
project = None
2012-11-19 10:21:24 +01:00
package = None
binary = None
2009-04-21 11:46:32 +02:00
2022-10-07 17:25:33 +02:00
if opts . multibuild_package and ( ( len ( args ) > 2 ) or ( len ( args ) < = 2 and is_project_dir ( Path . cwd ( ) ) ) ) :
2022-01-19 15:13:55 +01:00
self . argparse_error ( " The -M/--multibuild-package option can be only used from a package checkout. " )
2022-02-28 13:11:49 +01:00
2010-04-21 15:20:40 +02:00
if len ( args ) < 1 and is_package_dir ( ' . ' ) :
2009-11-23 11:13:19 +01:00
self . print_repos ( )
2010-05-22 18:27:11 +02:00
architecture = None
2012-11-19 10:21:24 +01:00
if len ( args ) == 4 or len ( args ) == 5 :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2009-04-21 11:46:32 +02:00
package = args [ 1 ]
2022-04-20 19:22:35 +02:00
repository = args [ 2 ]
2009-04-21 11:46:32 +02:00
architecture = args [ 3 ]
2012-11-19 10:21:24 +01:00
if len ( args ) == 5 :
binary = args [ 4 ]
2016-10-07 14:13:46 +02:00
elif len ( args ) == 3 :
project , repository , architecture = args
2011-11-18 21:51:03 +01:00
elif len ( args ) > = 1 and len ( args ) < = 2 :
2022-10-07 17:25:33 +02:00
if is_package_dir ( Path . cwd ( ) ) :
project = store_read_project ( Path . cwd ( ) )
package = store_read_package ( Path . cwd ( ) )
elif is_project_dir ( Path . cwd ( ) ) :
project = store_read_project ( Path . cwd ( ) )
2010-07-01 15:32:21 +02:00
else :
2022-09-12 13:43:10 +02:00
raise oscerr . WrongArgs ( ' Missing arguments: either specify <project> and '
2010-07-01 15:32:21 +02:00
' <package> or move to a project or package working copy ' )
2022-04-20 19:22:35 +02:00
repository = args [ 0 ]
2010-05-22 18:27:11 +02:00
if len ( args ) == 2 :
2009-10-20 16:30:15 +02:00
architecture = args [ 1 ]
2009-04-21 11:46:32 +02:00
else :
2016-11-15 14:06:33 +01:00
raise oscerr . WrongArgs ( ' Need either 1, 2, 3 or 4 arguments ' )
2009-04-21 11:46:32 +02:00
2011-03-02 14:25:22 +01:00
repos = list ( get_repos_of_project ( apiurl , project ) )
if not [ i for i in repos if repository == i . name ] :
2019-08-30 10:32:02 +02:00
self . print_repos ( exc_msg = ' Invalid repository \' %s \' ' % repository , project = project )
2011-03-02 14:25:22 +01:00
2010-05-22 18:27:11 +02:00
arches = [ architecture ]
if architecture is None :
2011-03-02 14:25:22 +01:00
arches = [ i . arch for i in repos if repository == i . name ]
2010-07-01 15:32:21 +02:00
2010-08-13 00:30:05 +02:00
if package is None :
2022-03-21 17:19:23 +01:00
package_specified = False
2022-02-23 14:53:59 +01:00
package = meta_get_packagelist ( apiurl , project , deleted = 0 )
2014-08-12 15:01:16 +02:00
else :
2022-03-21 17:19:23 +01:00
package_specified = True
2017-02-14 17:09:16 +01:00
if opts . multibuild_package :
packages = [ ]
for subpackage in opts . multibuild_package :
packages . append ( package + " : " + subpackage )
package = packages
else :
package = [ package ]
2010-07-01 15:32:21 +02:00
2011-01-21 10:35:47 +01:00
# Set binary target directory and create if not existing
target_dir = os . path . normpath ( opts . destdir )
if not os . path . isdir ( target_dir ) :
2018-03-13 15:00:46 +01:00
print ( ' Creating directory " %s " ' % target_dir )
2013-04-09 12:45:16 +02:00
os . makedirs ( target_dir , 0o755 )
2011-01-21 10:35:47 +01:00
2010-05-22 18:27:11 +02:00
for arch in arches :
2010-07-01 15:32:21 +02:00
for pac in package :
2010-08-13 00:30:05 +02:00
binaries = get_binarylist ( apiurl , project , repository , arch ,
2020-05-05 09:58:16 +02:00
package = pac , verbose = True , withccache = opts . ccache )
2010-08-13 00:30:05 +02:00
if not binaries :
2022-04-21 12:16:31 +02:00
print ( ' no binaries found: Either the package %s '
' does not exist or no binaries have been built. ' % pac , file = sys . stderr )
2010-08-13 00:30:05 +02:00
continue
for i in binaries :
2022-08-29 12:56:57 +02:00
if binary is not None and binary != i . name :
2012-11-19 10:21:24 +01:00
continue
2010-08-13 00:30:05 +02:00
# skip source rpms
2022-04-21 12:16:31 +02:00
if not opts . sources and ( i . name . endswith ( ' .src.rpm ' ) or i . name . endswith ( ' .sdeb ' ) ) :
continue
# skip debuginfo rpms
2022-08-04 10:09:10 +02:00
if not opts . debuginfo and ( ' -debuginfo- ' in i . name or ' -debugsource- ' in i . name ) :
2011-11-18 21:52:30 +01:00
continue
2022-03-21 17:19:23 +01:00
if package_specified :
# if package is specified, download everything into the target dir
fname = ' %s / %s ' % ( target_dir , i . name )
elif i . name . startswith ( " _ " ) or i . name . endswith ( " .log " ) :
# download logs and metadata into subdirs
# to avoid overwriting them with files with indentical names
fname = ' %s / %s / %s ' % ( target_dir , pac , i . name )
else :
# always download packages into the target dir
fname = ' %s / %s ' % ( target_dir , i . name )
2010-08-13 00:30:05 +02:00
if os . path . exists ( fname ) :
st = os . stat ( fname )
if st . st_mtime == i . mtime and st . st_size == i . size :
continue
get_binary_file ( apiurl ,
project ,
repository , arch ,
i . name ,
2022-09-12 13:43:10 +02:00
package = pac ,
target_filename = fname ,
target_mtime = i . mtime ,
progress_meter = not opts . quiet )
2008-09-30 16:54:08 +02:00
2010-01-12 15:10:32 +01:00
@cmdln.option ( ' -b ' , ' --bugowner ' , action = ' store_true ' ,
help = ' restrict listing to items where the user is bugowner ' )
@cmdln.option ( ' -m ' , ' --maintainer ' , action = ' store_true ' ,
help = ' restrict listing to items where the user is maintainer ' )
2009-08-21 03:26:37 +02:00
@cmdln.option ( ' -a ' , ' --all ' , action = ' store_true ' ,
2010-01-12 15:10:32 +01:00
help = ' all involvements ' )
@cmdln.option ( ' -U ' , ' --user ' , metavar = ' USER ' ,
help = ' search for USER instead of yourself ' )
2010-03-13 14:06:48 +01:00
@cmdln.option ( ' --exclude-project ' , action = ' append ' ,
2022-09-12 13:43:10 +02:00
help = ' exclude requests for specified project ' )
2010-07-07 16:25:09 +02:00
@cmdln.option ( ' --maintained ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' limit search results to packages with maintained attribute set. ' )
2012-01-26 12:04:55 +01:00
def do_my ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Show waiting work , packages , projects or requests involving yourself
2010-01-12 15:10:32 +01:00
2022-01-19 15:13:55 +01:00
Examples :
# list all open tasks for me
osc my [ work ]
# list packages where I am bugowner
osc my pkg - b
# list projects where I am maintainer
osc my prj - m
# list request for all my projects and packages
osc my rq
# list requests, excluding project 'foo' and 'bar'
osc my rq - - exclude - project foo , bar
# list requests I made
osc my sr
2010-01-12 15:10:32 +01:00
2022-01-19 15:13:55 +01:00
usage :
osc my < TYPE >
2010-01-12 15:10:32 +01:00
2022-01-19 15:13:55 +01:00
where TYPE is one of requests , submitrequests ,
projects or packages ( rq , sr , prj or pkg )
2009-09-03 20:08:43 +02:00
"""
2009-08-21 03:26:37 +02:00
2011-03-03 16:31:33 +01:00
# TODO: please clarify the difference between sr and rq.
2014-08-12 15:01:16 +02:00
# My first implementeation was to make no difference between requests FROM one
2011-03-03 16:31:33 +01:00
# of my projects and TO one of my projects. The current implementation appears to make this difference.
# The usage above indicates, that sr would be a subset of rq, which is no the case with my tests.
# jw.
2012-01-26 12:04:55 +01:00
args_rq = ( ' requests ' , ' request ' , ' req ' , ' rq ' , ' work ' )
2010-01-12 15:10:32 +01:00
args_sr = ( ' submitrequests ' , ' submitrequest ' , ' submitreq ' , ' submit ' , ' sr ' )
args_prj = ( ' projects ' , ' project ' , ' projs ' , ' proj ' , ' prj ' )
args_pkg = ( ' packages ' , ' package ' , ' pack ' , ' pkgs ' , ' pkg ' )
2012-01-26 12:04:55 +01:00
args_patchinfos = ( ' patchinfos ' , ' work ' )
2010-01-12 15:10:32 +01:00
2010-03-13 14:06:48 +01:00
if opts . bugowner and opts . maintainer :
raise oscerr . WrongOptions ( ' Sorry, \' --bugowner \' and \' maintainer \' are mutually exclusive ' )
elif opts . all and ( opts . bugowner or opts . maintainer ) :
raise oscerr . WrongOptions ( ' Sorry, \' --all \' and \' --bugowner \' or \' --maintainer \' are mutually exclusive ' )
2009-08-21 03:26:37 +02:00
2010-04-30 17:13:21 +02:00
apiurl = self . get_api_url ( )
2010-04-21 15:58:57 +02:00
2010-03-13 14:06:48 +01:00
exclude_projects = [ ]
for i in opts . exclude_project or [ ] :
prj = i . split ( ' , ' )
if len ( prj ) == 1 :
exclude_projects . append ( i )
else :
exclude_projects . extend ( prj )
2010-01-12 15:10:32 +01:00
if not opts . user :
2010-04-21 15:58:57 +02:00
user = conf . get_apiurl_usr ( apiurl )
2010-01-12 15:10:32 +01:00
else :
user = opts . user
2010-03-13 14:06:48 +01:00
what = { ' project ' : ' ' , ' package ' : ' ' }
2013-05-27 12:41:50 +02:00
type = " work "
2012-01-26 12:04:55 +01:00
if len ( args ) > 0 :
2013-05-27 12:41:50 +02:00
type = args [ 0 ]
2012-01-26 12:04:55 +01:00
list_patchinfos = list_requests = False
if type in args_patchinfos :
list_patchinfos = True
2010-01-12 15:10:32 +01:00
if type in args_rq :
list_requests = True
elif type in args_prj :
2010-03-13 14:06:48 +01:00
what = { ' project ' : ' ' }
elif type in args_sr :
2022-09-15 14:47:38 +02:00
requests = get_request_collection ( apiurl , roles = [ ' creator ' ] , user = user )
2018-12-13 15:17:29 +01:00
for r in sorted ( requests , key = lambda x : x . reqid ) :
2013-04-09 12:51:28 +02:00
print ( r . list_view ( ) , ' \n ' )
2010-03-13 14:06:48 +01:00
return
2022-09-12 14:15:34 +02:00
elif type not in args_pkg :
2010-01-12 15:10:32 +01:00
raise oscerr . WrongArgs ( " invalid type %s " % type )
2010-03-13 14:06:48 +01:00
role_filter = ' '
if opts . maintainer :
2010-01-12 15:10:32 +01:00
role_filter = ' maintainer '
elif opts . bugowner :
role_filter = ' bugowner '
2010-03-13 14:06:48 +01:00
elif list_requests :
role_filter = ' maintainer '
if opts . all :
role_filter = ' '
2012-01-26 12:04:55 +01:00
if list_patchinfos :
2013-05-27 12:16:44 +02:00
u = makeurl ( apiurl , [ ' /search/package ' ] , {
2022-09-12 13:43:10 +02:00
' match ' : " ([kind= ' patchinfo ' and issue[@state= ' OPEN ' and owner/@login= ' %s ' ]]) " % user
} )
2013-05-27 12:16:44 +02:00
f = http_GET ( u )
root = ET . parse ( f ) . getroot ( )
if root . findall ( ' package ' ) :
print ( " Patchinfos with open bugs assigned to you: \n " )
for node in root . findall ( ' package ' ) :
project = node . get ( ' project ' )
package = node . get ( ' name ' )
print ( project , " / " , package , ' \n ' )
2022-09-12 13:43:10 +02:00
p = makeurl ( apiurl , [ ' source ' , project , package ] , { ' view ' : ' issues ' } )
2013-05-27 12:16:44 +02:00
fp = http_GET ( p )
issues = ET . parse ( fp ) . findall ( ' issue ' )
for issue in issues :
2022-08-29 12:56:57 +02:00
if issue . find ( ' state ' ) is None or issue . find ( ' state ' ) . text != " OPEN " :
2013-05-27 12:16:44 +02:00
continue
2022-08-29 12:56:57 +02:00
if issue . find ( ' owner ' ) is None or issue . find ( ' owner ' ) . find ( ' login ' ) . text != user :
2013-05-27 12:16:44 +02:00
continue
print ( " # " , issue . find ( ' label ' ) . text , ' : ' , end = ' ' )
desc = issue . find ( ' summary ' )
2022-08-29 12:56:57 +02:00
if desc is not None :
2013-05-27 12:16:44 +02:00
print ( desc . text )
else :
print ( " \n " )
print ( " " )
2012-01-26 12:04:55 +01:00
2011-01-23 21:21:32 +01:00
if list_requests :
# try api side search as supported since OBS 2.2
try :
2011-04-20 16:53:42 +02:00
requests = [ ]
2011-12-16 09:44:57 +01:00
# open reviews
2011-12-15 15:35:11 +01:00
u = makeurl ( apiurl , [ ' request ' ] , {
2014-08-13 11:21:55 +02:00
' view ' : ' collection ' ,
2011-12-16 09:44:57 +01:00
' states ' : ' review ' ,
' reviewstates ' : ' new ' ,
' roles ' : ' reviewer ' ,
2014-08-13 11:21:55 +02:00
' user ' : user ,
2022-09-12 13:43:10 +02:00
} )
2011-12-15 15:35:11 +01:00
f = http_GET ( u )
root = ET . parse ( f ) . getroot ( )
if root . findall ( ' request ' ) :
2013-05-27 12:16:44 +02:00
print ( " Requests which request a review by you: \n " )
for node in root . findall ( ' request ' ) :
r = Request ( )
r . read ( node )
print ( r . list_view ( ) , ' \n ' )
print ( " " )
2011-12-16 09:44:57 +01:00
# open requests
2011-02-04 10:29:13 +01:00
u = makeurl ( apiurl , [ ' request ' ] , {
2014-08-13 11:21:55 +02:00
' view ' : ' collection ' ,
2011-12-16 09:44:57 +01:00
' states ' : ' new ' ,
' roles ' : ' maintainer ' ,
2014-08-13 11:21:55 +02:00
' user ' : user ,
2022-09-12 13:43:10 +02:00
} )
2011-04-20 16:53:42 +02:00
f = http_GET ( u )
root = ET . parse ( f ) . getroot ( )
2011-12-15 15:35:11 +01:00
if root . findall ( ' request ' ) :
2013-05-27 12:16:44 +02:00
print ( " Requests for your packages: \n " )
for node in root . findall ( ' request ' ) :
r = Request ( )
r . read ( node )
print ( r . list_view ( ) , ' \n ' )
print ( " " )
2011-12-16 09:44:57 +01:00
# declined requests submitted by me
2011-04-20 16:53:42 +02:00
u = makeurl ( apiurl , [ ' request ' ] , {
2014-08-13 11:21:55 +02:00
' view ' : ' collection ' ,
2011-12-16 09:44:57 +01:00
' states ' : ' declined ' ,
' roles ' : ' creator ' ,
2014-08-13 11:21:55 +02:00
' user ' : user ,
2022-09-12 13:43:10 +02:00
} )
2011-02-04 10:29:13 +01:00
f = http_GET ( u )
root = ET . parse ( f ) . getroot ( )
2011-12-15 15:35:11 +01:00
if root . findall ( ' request ' ) :
2013-05-27 12:16:44 +02:00
print ( " Declined requests created by you (revoke, reopen or supersede): \n " )
for node in root . findall ( ' request ' ) :
r = Request ( )
r . read ( node )
print ( r . list_view ( ) , ' \n ' )
print ( " " )
2011-02-04 10:14:04 +01:00
return
2013-04-09 14:03:17 +02:00
except HTTPError as e :
2016-09-13 12:34:48 +02:00
if e . code != 400 :
raise e
# skip it ... try again with old style below
2011-01-23 21:21:32 +01:00
2010-09-29 19:57:00 +02:00
res = get_user_projpkgs ( apiurl , user , role_filter , exclude_projects ,
2013-04-09 11:33:25 +02:00
' project ' in what , ' package ' in what ,
2010-09-29 19:57:00 +02:00
opts . maintained , opts . verbose )
2010-12-22 08:45:36 +01:00
# map of project =>[list of packages]
# if list of packages is empty user is maintainer of the whole project
2010-03-13 14:06:48 +01:00
request_todo = { }
2010-12-22 08:45:36 +01:00
2016-09-13 12:39:24 +02:00
dummy_elm = ET . Element ( ' dummy ' )
2010-03-13 14:06:48 +01:00
roles = { }
if len ( what . keys ( ) ) == 2 :
2016-09-13 12:39:24 +02:00
for i in res . get ( ' project_id ' , res . get ( ' project ' , dummy_elm ) ) . findall ( ' project ' ) :
2010-03-13 14:06:48 +01:00
request_todo [ i . get ( ' name ' ) ] = [ ]
roles [ i . get ( ' name ' ) ] = [ p . get ( ' role ' ) for p in i . findall ( ' person ' ) if p . get ( ' userid ' ) == user ]
2016-09-13 12:39:24 +02:00
for i in res . get ( ' package_id ' , res . get ( ' package ' , dummy_elm ) ) . findall ( ' package ' ) :
2010-12-22 08:45:36 +01:00
prj = i . get ( ' project ' )
roles [ ' / ' . join ( [ prj , i . get ( ' name ' ) ] ) ] = [ p . get ( ' role ' ) for p in i . findall ( ' person ' ) if p . get ( ' userid ' ) == user ]
2022-09-12 14:15:34 +02:00
if prj not in request_todo or request_todo [ prj ] != [ ] :
2010-12-22 08:45:36 +01:00
request_todo . setdefault ( prj , [ ] ) . append ( i . get ( ' name ' ) )
2010-03-13 14:06:48 +01:00
else :
2016-09-13 12:39:24 +02:00
for i in res . get ( ' project_id ' , res . get ( ' project ' , dummy_elm ) ) . findall ( ' project ' ) :
2010-03-13 14:06:48 +01:00
roles [ i . get ( ' name ' ) ] = [ p . get ( ' role ' ) for p in i . findall ( ' person ' ) if p . get ( ' userid ' ) == user ]
2010-01-12 15:10:32 +01:00
if list_requests :
2011-01-23 21:21:32 +01:00
# old style, only for OBS 2.1 and before. Should not be used, since it is slow and incomplete
2010-04-21 15:58:57 +02:00
requests = get_user_projpkgs_request_list ( apiurl , user , projpkgs = request_todo )
2018-12-13 15:17:29 +01:00
for r in sorted ( requests , key = lambda x : x . reqid ) :
2013-04-09 12:51:28 +02:00
print ( r . list_view ( ) , ' \n ' )
2022-08-29 13:23:29 +02:00
if not requests :
2013-04-09 12:51:28 +02:00
print ( " -> try also ' osc my sr ' to see more. " )
2010-01-12 15:10:32 +01:00
else :
2010-03-13 14:06:48 +01:00
for i in sorted ( roles . keys ( ) ) :
out = ' %s ' % i
prjpac = i . split ( ' / ' )
if type in args_pkg and len ( prjpac ) == 1 and not opts . verbose :
continue
2010-01-12 15:10:32 +01:00
if opts . verbose :
2010-03-13 14:06:48 +01:00
out = ' %s ( %s ) ' % ( i , ' , ' . join ( sorted ( roles [ i ] ) ) )
if len ( prjpac ) == 2 :
out = ' %s ( %s ) ' % ( prjpac [ 1 ] , ' , ' . join ( sorted ( roles [ i ] ) ) )
2013-04-09 12:51:28 +02:00
print ( out )
2009-08-21 03:26:37 +02:00
2007-08-09 13:35:08 +02:00
@cmdln.option ( ' --repos-baseurl ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' show base URLs of download repositories ' )
2009-04-07 20:45:42 +02:00
@cmdln.option ( ' -e ' , ' --exact ' , action = ' store_true ' ,
2009-11-23 17:13:57 +01:00
help = ' show only exact matches, this is default now ' )
@cmdln.option ( ' -s ' , ' --substring ' , action = ' store_true ' ,
help = ' Show also results where the search term is a sub string, slower search ' )
2007-07-15 15:49:13 +02:00
@cmdln.option ( ' --package ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' search for a package ' )
2007-07-15 15:49:13 +02:00
@cmdln.option ( ' --project ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' search for a project ' )
2007-07-15 15:49:13 +02:00
@cmdln.option ( ' --title ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' search for matches in the \' title \' element ' )
2007-07-15 15:49:13 +02:00
@cmdln.option ( ' --description ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' search for matches in the \' description \' element ' )
2009-10-22 12:10:15 +02:00
@cmdln.option ( ' -a ' , ' --limit-to-attribute ' , metavar = ' ATTRIBUTE ' ,
help = ' match only when given attribute exists in meta data ' )
2014-08-12 15:01:16 +02:00
@cmdln.option ( ' -V ' , ' --version ' , action = ' store_true ' ,
2010-12-26 21:14:40 +01:00
help = ' show package version, revision, and srcmd5. CAUTION: This is slow and unreliable ' )
2008-06-24 17:07:44 +02:00
@cmdln.option ( ' -i ' , ' --involved ' , action = ' store_true ' ,
2015-04-22 12:22:44 +02:00
help = ' show projects/packages where given person (or myself) is involved as bugowner or maintainer [[ { group|person}/]<name>] default: person ' )
2009-08-21 03:26:37 +02:00
@cmdln.option ( ' -b ' , ' --bugowner ' , action = ' store_true ' ,
help = ' as -i, but only bugowner ' )
@cmdln.option ( ' -m ' , ' --maintainer ' , action = ' store_true ' ,
help = ' as -i, but only maintainer ' )
@cmdln.option ( ' -M ' , ' --mine ' , action = ' store_true ' ,
help = ' shorthand for --bugowner --package ' )
2009-05-15 10:33:25 +02:00
@cmdln.option ( ' --csv ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' generate output in CSV (separated by |) ' )
2010-03-15 16:08:00 +01:00
@cmdln.option ( ' --binary ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' search binary packages ' )
2010-03-15 16:08:00 +01:00
@cmdln.option ( ' -B ' , ' --baseproject ' , metavar = ' PROJECT ' ,
help = ' search packages built for PROJECT (implies --binary) ' )
2012-01-13 15:18:33 +01:00
@cmdln.option ( ' --binaryversion ' , metavar = ' VERSION ' ,
2022-09-12 13:43:10 +02:00
help = ' search for binary with specified version (implies --binary) ' )
2009-08-21 03:26:37 +02:00
@cmdln.alias ( ' se ' )
2010-03-20 12:27:27 +01:00
@cmdln.alias ( ' bse ' )
2011-01-17 19:28:50 +01:00
def do_search ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Search for a project and / or package
2007-07-15 15:49:13 +02:00
If no option is specified osc will search for projects and
packages which contains the \' search term \' in their name,
title or description .
usage :
osc search \' search term \' <options>
2010-03-20 12:27:27 +01:00
osc bse . . . ( ' osc search --binary ' )
2018-02-18 21:27:22 +01:00
osc se ' perl(Foo::Bar) ' ( ' osc search --package perl-Foo-Bar ' )
2007-07-15 15:49:13 +02:00
"""
2022-09-12 13:43:10 +02:00
def build_xpath ( attr , what , substr = False ) :
2010-03-10 23:36:09 +01:00
if substr :
return ' contains( %s , \' %s \' ) ' % ( attr , what )
else :
return ' %s = \' %s \' ' % ( attr , what )
2009-09-03 20:08:43 +02:00
2011-01-17 19:33:02 +01:00
search_term = ' '
2011-01-17 19:28:50 +01:00
if len ( args ) > 1 :
raise oscerr . WrongArgs ( ' Too many arguments ' )
elif len ( args ) == 0 :
if opts . involved or opts . bugowner or opts . maintainer or opts . mine :
search_term = conf . get_apiurl_usr ( conf . config [ ' apiurl ' ] )
else :
raise oscerr . WrongArgs ( ' Too few arguments ' )
2011-01-17 19:33:02 +01:00
else :
search_term = args [ 0 ]
2011-01-17 19:28:50 +01:00
2011-01-30 21:37:45 +01:00
# XXX: is it a good idea to make this the default?
# support perl symbols:
2022-07-28 19:11:29 +02:00
if re . match ( r ' ^perl \ ( \ w+(:: \ w+)* \ )$ ' , search_term ) :
search_term = re . sub ( r ' \ ) ' , ' ' , re . sub ( r ' (::| \ () ' , ' - ' , search_term ) )
2010-11-12 23:55:11 +01:00
opts . package = True
2009-09-03 20:08:43 +02:00
if opts . mine :
opts . bugowner = True
opts . package = True
2009-10-20 16:30:15 +02:00
2010-03-10 23:36:09 +01:00
if ( opts . title or opts . description ) and ( opts . involved or opts . bugowner or opts . maintainer ) :
2022-09-12 13:43:10 +02:00
raise oscerr . WrongOptions ( ' Sorry, the options \' --title \' and/or \' --description \' '
2010-03-10 23:36:09 +01:00
' are mutually exclusive with \' -i \' / \' -b \' / \' -m \' / \' -M \' ' )
if opts . substring and opts . exact :
raise oscerr . WrongOptions ( ' Sorry, the options \' --substring \' and \' --exact \' are mutually exclusive ' )
2007-07-15 15:49:13 +02:00
2009-11-23 17:13:57 +01:00
if not opts . substring :
opts . exact = True
2012-01-13 17:43:32 +01:00
if subcmd == ' bse ' or opts . baseproject or opts . binaryversion :
2010-03-15 16:08:00 +01:00
opts . binary = True
if opts . binary and ( opts . title or opts . description or opts . involved or opts . bugowner or opts . maintainer
or opts . project or opts . package ) :
2022-09-12 13:43:10 +02:00
raise oscerr . WrongOptions ( ' Sorry, \' --binary \' and \' --title \' or \' --description \' or \' --involved '
' or \' --bugowner \' or \' --maintainer \' or \' --limit-to-attribute <attr> \\ '
2010-03-15 16:08:00 +01:00
' or \' --project \' or \' --package \' are mutually exclusive ' )
2010-02-28 02:30:13 +01:00
2010-07-29 17:29:07 +02:00
apiurl = self . get_api_url ( )
2010-03-10 23:36:09 +01:00
xpath = ' '
if opts . title :
xpath = xpath_join ( xpath , build_xpath ( ' title ' , search_term , opts . substring ) , inner = True )
if opts . description :
xpath = xpath_join ( xpath , build_xpath ( ' description ' , search_term , opts . substring ) , inner = True )
2010-03-15 16:08:00 +01:00
if opts . project or opts . package or opts . binary :
2010-03-10 23:36:09 +01:00
xpath = xpath_join ( xpath , build_xpath ( ' @name ' , search_term , opts . substring ) , inner = True )
# role filter
role_filter = ' '
if opts . bugowner or opts . maintainer or opts . involved :
2015-04-24 09:47:12 +02:00
tmp = search_term . split ( ' : ' )
2015-04-22 12:22:44 +02:00
if len ( tmp ) > 1 :
search_type , search_term = [ tmp [ 0 ] , tmp [ 1 ] ]
else :
search_type = ' person '
2022-09-12 13:43:10 +02:00
search_dict = { ' person ' : ' userid ' ,
' group ' : ' groupid ' }
2015-04-22 12:22:44 +02:00
try :
2022-09-12 13:43:10 +02:00
search_id = search_dict [ search_type ]
2015-04-22 12:22:44 +02:00
except KeyError :
2022-09-12 13:43:10 +02:00
search_type , search_id = [ ' person ' , ' userid ' ]
2015-04-22 12:22:44 +02:00
xpath = xpath_join ( xpath , ' %s /@ %s = \' %s \' ' % ( search_type , search_id , search_term ) , inner = True )
role_filter = ' %s ( %s ) ' % ( search_term , search_type )
2010-03-12 15:22:11 +01:00
role_filter_xpath = xpath
2010-03-10 23:36:09 +01:00
if opts . bugowner and not opts . maintainer :
2015-04-22 14:59:36 +02:00
xpath = xpath_join ( xpath , ' %s /@role= \' bugowner \' ' % search_type , op = ' and ' )
2010-03-12 15:22:11 +01:00
role_filter = ' bugowner '
2010-03-10 23:36:09 +01:00
elif not opts . bugowner and opts . maintainer :
2015-04-22 14:59:36 +02:00
xpath = xpath_join ( xpath , ' %s /@role= \' maintainer \' ' % search_type , op = ' and ' )
2010-03-12 15:22:11 +01:00
role_filter = ' maintainer '
2010-03-10 23:36:09 +01:00
if opts . limit_to_attribute :
xpath = xpath_join ( xpath , ' attribute/@name= \' %s \' ' % opts . limit_to_attribute , op = ' and ' )
2010-03-15 16:08:00 +01:00
if opts . baseproject :
2023-09-04 11:48:59 +02:00
xpath = xpath_join ( xpath , ' path/@project= \' %s \' ' % self . _process_project_name ( opts . baseproject ) , op = ' and ' )
2012-01-13 15:18:33 +01:00
if opts . binaryversion :
m = re . match ( r ' (.+)-(.*?)$ ' , opts . binaryversion )
if m :
if m . group ( 2 ) != ' ' :
xpath = xpath_join ( xpath , ' @versrel= \' %s \' ' % opts . binaryversion , op = ' and ' )
else :
xpath = xpath_join ( xpath , ' @version= \' %s \' ' % m . group ( 1 ) , op = ' and ' )
else :
xpath = xpath_join ( xpath , ' @version= \' %s \' ' % opts . binaryversion , op = ' and ' )
2009-08-21 03:26:37 +02:00
2010-03-10 23:36:09 +01:00
if not xpath :
xpath = xpath_join ( xpath , build_xpath ( ' @name ' , search_term , opts . substring ) , inner = True )
xpath = xpath_join ( xpath , build_xpath ( ' title ' , search_term , opts . substring ) , inner = True )
xpath = xpath_join ( xpath , build_xpath ( ' description ' , search_term , opts . substring ) , inner = True )
what = { ' project ' : xpath , ' package ' : xpath }
2012-01-05 16:15:29 +01:00
if opts . project and not opts . package :
2010-03-10 23:36:09 +01:00
what = { ' project ' : xpath }
elif not opts . project and opts . package :
what = { ' package ' : xpath }
2010-03-18 17:57:25 +01:00
elif opts . binary :
2010-03-15 16:08:00 +01:00
what = { ' published/binary/id ' : xpath }
2010-03-12 15:22:11 +01:00
try :
2010-07-29 17:29:07 +02:00
res = search ( apiurl , * * what )
2013-04-09 14:03:17 +02:00
except HTTPError as e :
2010-03-12 15:22:11 +01:00
if e . code != 400 or not role_filter :
raise e
# backward compatibility: local role filtering
if opts . limit_to_attribute :
role_filter_xpath = xpath_join ( role_filter_xpath , ' attribute/@name= \' %s \' ' % opts . limit_to_attribute , op = ' and ' )
2022-07-28 19:11:29 +02:00
what = { kind : role_filter_xpath for kind in what . keys ( ) }
2010-07-29 17:29:07 +02:00
res = search ( apiurl , * * what )
2010-03-13 14:06:48 +01:00
filter_role ( res , search_term , role_filter )
2010-03-12 15:22:11 +01:00
if role_filter :
role_filter = ' %s ( %s ) ' % ( search_term , role_filter )
2010-03-15 16:08:00 +01:00
kind_map = { ' published/binary/id ' : ' binary ' }
2013-04-09 11:25:19 +02:00
for kind , root in res . items ( ) :
2010-03-10 23:36:09 +01:00
results = [ ]
2010-03-15 16:08:00 +01:00
for node in root . findall ( kind_map . get ( kind , kind ) ) :
2010-03-10 23:36:09 +01:00
result = [ ]
project = node . get ( ' project ' )
package = None
if project is None :
project = node . get ( ' name ' )
else :
2012-07-03 14:16:15 +02:00
if kind == ' published/binary/id ' :
package = node . get ( ' package ' )
else :
package = node . get ( ' name ' )
2010-03-10 23:36:09 +01:00
result . append ( project )
2022-09-12 14:23:47 +02:00
if package is not None :
2010-03-10 23:36:09 +01:00
result . append ( package )
2010-12-26 21:14:40 +01:00
2022-08-29 12:56:57 +02:00
if opts . version and package is not None :
2013-05-27 12:41:50 +02:00
sr = get_source_rev ( apiurl , project , package )
2011-02-21 13:41:02 +01:00
v = sr . get ( ' version ' )
r = sr . get ( ' rev ' )
s = sr . get ( ' srcmd5 ' )
2013-05-27 13:38:49 +02:00
if not v or v == ' unknown ' :
v = ' - '
if not r :
r = ' - '
if not s :
s = ' - '
2010-12-26 21:14:40 +01:00
result . append ( v )
result . append ( r )
result . append ( s )
2010-03-10 23:36:09 +01:00
if opts . verbose :
2021-07-30 21:05:05 +02:00
if opts . binary :
result . append ( node . get ( ' repository ' ) or ' - ' )
result . append ( node . get ( ' arch ' ) or ' - ' )
result . append ( node . get ( ' version ' ) or ' - ' )
result . append ( node . get ( ' release ' ) or ' - ' )
else :
title = node . findtext ( ' title ' ) . strip ( )
if len ( title ) > 60 :
title = title [ : 61 ] + ' ... '
result . append ( title )
2010-12-26 21:14:40 +01:00
2010-03-10 23:36:09 +01:00
if opts . repos_baseurl :
# FIXME: no hardcoded URL of instance
result . append ( ' http://download.opensuse.org/repositories/ %s / ' % project . replace ( ' : ' , ' :/ ' ) )
2010-03-15 16:08:00 +01:00
if kind == ' published/binary/id ' :
result . append ( node . get ( ' filepath ' ) )
2010-03-10 23:36:09 +01:00
results . append ( result )
2022-08-29 13:23:29 +02:00
if not results :
2013-04-09 12:51:28 +02:00
print ( ' No matches found for \' %s \' in %s s ' % ( role_filter or search_term , kind ) )
2009-06-09 19:07:02 +02:00
continue
2010-03-10 23:36:09 +01:00
# construct a sorted, flat list
2010-08-12 20:21:04 +02:00
# Sort by first column, follwed by second column if we have two columns, else sort by first.
2019-04-16 15:18:04 +02:00
if len ( results [ 0 ] ) > 1 :
2022-04-20 19:22:35 +02:00
sorted_results = sorted ( results , key = itemgetter ( 0 , 1 ) )
2019-04-16 15:18:04 +02:00
else :
sorted_results = sorted ( results , key = itemgetter ( 0 ) )
2010-03-10 23:36:09 +01:00
new = [ ]
2019-04-16 15:18:04 +02:00
for i in sorted_results :
2010-03-10 23:36:09 +01:00
new . extend ( i )
results = new
headline = [ ]
2022-09-30 14:09:37 +02:00
if kind in ( ' package ' , ' published/binary/id ' ) :
2022-09-12 13:43:10 +02:00
headline = [ ' # Project ' , ' # Package ' ]
2007-07-15 15:49:13 +02:00
else :
2022-09-12 13:43:10 +02:00
headline = [ ' # Project ' ]
2011-02-11 15:11:50 +01:00
if opts . version and kind == ' package ' :
2010-12-26 21:14:40 +01:00
headline . append ( ' # Ver ' )
headline . append ( ' Rev ' )
headline . append ( ' Srcmd5 ' )
2009-06-09 19:07:02 +02:00
if opts . verbose :
2021-07-30 21:05:05 +02:00
if opts . binary :
headline . extend ( [ ' # Repository ' , ' # Arch ' , ' # Version ' ,
' # Release ' ] )
else :
headline . append ( ' # Title ' )
2009-06-09 19:07:02 +02:00
if opts . repos_baseurl :
headline . append ( ' # URL ' )
2010-03-15 16:08:00 +01:00
if opts . binary :
headline . append ( ' # filepath ' )
2009-06-09 19:07:02 +02:00
if not opts . csv :
2010-03-10 23:36:09 +01:00
if len ( what . keys ( ) ) > 1 :
2013-04-09 12:51:28 +02:00
print ( ' # ' * 68 )
print ( ' matches for \' %s \' in %s s: \n ' % ( role_filter or search_term , kind ) )
2022-09-12 13:43:10 +02:00
for row in build_table ( len ( headline ) , results , headline , 2 , csv = opts . csv ) :
2013-04-09 12:51:28 +02:00
print ( row )
2007-06-29 20:26:30 +02:00
2007-07-23 18:03:30 +02:00
@cmdln.option ( ' -p ' , ' --project ' , metavar = ' project ' ,
2009-12-25 18:16:35 +01:00
help = ' specify the path to a project ' )
2007-07-23 18:03:30 +02:00
@cmdln.option ( ' -n ' , ' --name ' , metavar = ' name ' ,
help = ' specify a package name ' )
@cmdln.option ( ' -t ' , ' --title ' , metavar = ' title ' ,
help = ' set a title ' )
@cmdln.option ( ' -d ' , ' --description ' , metavar = ' description ' ,
help = ' set the description of the package ' )
2022-09-12 13:43:10 +02:00
@cmdln.option ( ' ' , ' --delete-old-files ' , action = ' store_true ' ,
help = ' delete existing files from the server ' )
@cmdln.option ( ' -c ' , ' --commit ' , action = ' store_true ' ,
help = ' commit the new files ' )
2022-09-20 10:03:32 +02:00
@cmdln.option ( ' srpm ' )
def do_importsrcpkg ( self , subcmd , opts ) :
2022-01-19 15:13:55 +01:00
"""
Import a new package from a src . rpm
2007-07-23 18:03:30 +02:00
A new package dir will be created inside the project dir
( if no project is specified and the current working dir is a
project dir the package will be created in this project ) . If
the package does not exist on the server it will be created
too otherwise the meta data of the existing package will be
updated ( < title / > and < description / > ) .
2008-11-29 14:32:25 +01:00
The src . rpm will be extracted into the package dir . The files
won ' t be committed unless you explicitly pass the --commit switch.
2007-07-23 18:03:30 +02:00
2007-07-25 14:21:46 +02:00
SRPM is the path of the src . rpm in the local filesystem ,
or an URL .
2007-07-23 18:03:30 +02:00
"""
2022-09-20 10:03:32 +02:00
srpm = opts . srpm
2008-03-10 19:04:23 +01:00
if opts . delete_old_files and conf . config [ ' do_package_tracking ' ] :
# IMHO the --delete-old-files option doesn't really fit into our
# package tracking strategy
2013-04-09 12:51:28 +02:00
print ( ' --delete-old-files is not supported anymore ' , file = sys . stderr )
print ( ' when do_package_tracking is enabled ' , file = sys . stderr )
2008-03-10 19:04:23 +01:00
sys . exit ( 1 )
2007-07-25 14:21:46 +02:00
if ' :// ' in srpm :
2018-02-02 15:47:17 +01:00
if srpm . endswith ( ' / ' ) :
print ( ' %s is not a valid link. It must not end with / ' % srpm )
sys . exit ( 1 )
2013-04-09 12:51:28 +02:00
print ( ' trying to fetch ' , srpm )
2018-02-02 15:47:17 +01:00
OscFileGrabber ( ) . urlgrab ( srpm )
2007-07-25 14:21:46 +02:00
srpm = os . path . basename ( srpm )
2007-07-25 14:14:32 +02:00
srpm = os . path . abspath ( srpm )
2008-03-15 23:51:37 +01:00
if not os . path . isfile ( srpm ) :
2013-04-09 12:51:28 +02:00
print ( ' file \' %s \' does not exist ' % srpm , file = sys . stderr )
2008-03-15 23:51:37 +01:00
sys . exit ( 1 )
2007-07-23 18:03:30 +02:00
if opts . project :
project_dir = opts . project
else :
2022-10-18 23:38:28 +02:00
project_dir = str ( Path . cwd ( ) )
2007-07-23 18:03:30 +02:00
2017-06-29 14:09:37 +02:00
if not is_project_dir ( project_dir ) :
raise oscerr . WrongArgs ( " ' %s ' is no project working copy " % project_dir )
Merged revisions 3774-3775,3779,3781-3782,3787,3789-3793,3798,3802,3805,3817-3822,3827,3829-3830,3837-3839,3841-3842,3848-3850 via svnmerge from
https://forgesvn1.novell.com/svn/opensuse/branches/buildservice/osc-exception-handling
........
r3774 | poeml | 2008-04-22 17:39:45 +0200 (Tue, 22 Apr 2008) | 3 lines
A first draft on implement systematic exception handling:
Add errors.py with some exceptions defined, and babysitter.py to handle them
........
r3775 | poeml | 2008-04-22 22:34:12 +0200 (Tue, 22 Apr 2008) | 9 lines
- new global options:
--debugger jump into the debugger before executing anything
--post-mortem jump into the debugger in case of errors
-t, --traceback print call trace in case of errors
- traceback and post_mortem can also be set in .oscrc.
- catch more errors (HTTPError).
- make config accessible from outside of the Osc instance, by making it a class
attribute
........
r3779 | poeml | 2008-04-23 00:55:49 +0200 (Wed, 23 Apr 2008) | 5 lines
- new global option:
-d, --debug print info useful for debugging
- catch some more errors (HTTPError), with OscHTTPError which isn't very
advanced yet.
........
r3781 | Marcus_H | 2008-04-23 01:02:00 +0200 (Wed, 23 Apr 2008) | 2 lines
- added OscConfigError class (just for testing).
- small change in the signature of the OscBaseError constructor (actually we should get rid of the 'args' tuple because it will be deprecated sooner or later
........
r3782 | Marcus_H | 2008-04-23 02:02:13 +0200 (Wed, 23 Apr 2008) | 2 lines
- access the prg.conf.config dict in a save way - this way we avoid AttributeErrors if the prg.conf.config dict doesn't exist
- in case of an configparser error we have to use the prg.options object directly (this was removed in r3781 by accident)
........
r3787 | poeml | 2008-04-23 09:23:56 +0200 (Wed, 23 Apr 2008) | 4 lines
- remove local exception handling from do_req
- for HTTPError, print details (headers and response) when in debug mode
- catch AttributeError
........
r3789 | poeml | 2008-04-23 16:23:14 +0200 (Wed, 23 Apr 2008) | 4 lines
- errors: add two new classes named OscWrongOptionsError and OscWrongArgsError
- commandline: raise instances of the new errors in a number of places
- commandline: add get_cmd_help() to Osc instance which returns the formatted help of a subcommand
........
r3790 | Marcus_H | 2008-04-23 16:48:28 +0200 (Wed, 23 Apr 2008) | 4 lines
- added 2 new exception classes: OscNoConfigfileError and OscIOError
- added new method write_config() to the conf.py module: This method writes osc's configuration file
- minor cleanups in the conf module
........
r3791 | poeml | 2008-04-23 17:11:07 +0200 (Wed, 23 Apr 2008) | 3 lines
small compatibility fix for r3790: try-except-finally isn't supported in
python-2.4.2, thus do the same as try-except inside a try-finally.
........
r3792 | poeml | 2008-04-23 17:37:53 +0200 (Wed, 23 Apr 2008) | 2 lines
fix up the remaining places regarding handling of errors related to commandline parsing
........
r3793 | poeml | 2008-04-23 17:40:34 +0200 (Wed, 23 Apr 2008) | 3 lines
raise a NoWorkingCopyError in osc.core.store_read_project() in case of an
IOError
........
r3798 | Marcus_H | 2008-04-23 23:55:24 +0200 (Wed, 23 Apr 2008) | 1 line
ported -r3797 from trunk
........
r3802 | Marcus_H | 2008-04-24 11:00:55 +0200 (Thu, 24 Apr 2008) | 1 line
ported -r3801 from trunk
........
r3805 | poeml | 2008-04-24 12:52:30 +0200 (Thu, 24 Apr 2008) | 2 lines
raise OscHTTPError in show_pattern_meta(), replacing local error handling
........
r3817 | poeml | 2008-04-24 20:21:32 +0200 (Thu, 24 Apr 2008) | 9 lines
- remove errors.OscHTTPError again.
it seems simpler to use urllib2.HTTPError instead (and just add a specific
error text message where appropriate, and re-raise)
- for 404s, check out _which_ part was not found
it is very ugly, but may be considered Good for pragmatic reasons
- removed local exception handling and workaround for returned 500's from
delete_package() and delete_project(), thereby getting rid of 4 possible exit
points.
........
r3818 | Marcus_H | 2008-04-24 22:36:17 +0200 (Thu, 24 Apr 2008) | 1 line
- this check is superfluous because every HTTPError instance has a code attribute
........
r3819 | poeml | 2008-04-25 00:39:39 +0200 (Fri, 25 Apr 2008) | 1 line
remove a forgotten debug line from core.delete_project()
........
r3820 | poeml | 2008-04-25 10:07:58 +0200 (Fri, 25 Apr 2008) | 2 lines
- ditch local error handling from wipebinaries(), rebuild(), and abortbuild()
........
r3821 | poeml | 2008-04-25 10:56:38 +0200 (Fri, 25 Apr 2008) | 2 lines
It is never needed to import the exception module.
........
r3822 | poeml | 2008-04-25 11:13:39 +0200 (Fri, 25 Apr 2008) | 4 lines
- when going into the debugger with --post-mortem, always print a traceback before
(thus implying -t)
- do not jump into the debugger if not on a TTY, or working in interactive mode
........
r3827 | poeml | 2008-04-25 13:07:46 +0200 (Fri, 25 Apr 2008) | 9 lines
- add errors.OscWorkingCopyOutdated, which takes a tuple with three args:
path to working copy, current rev, expected rev
- add handler for urllib2.URLError errors to the babysitter
- simplify the OscWrongArgsError and OscWrongOptionsError handlers, by removing
the extra line "Sorry, wrong ..." that was printed before the messages given
when the error was raised.
- remove one more errors.OscHTTPError which was still there, and raise
urllib2.HTTPError instead (show_package_meta())
........
r3829 | poeml | 2008-04-25 14:19:10 +0200 (Fri, 25 Apr 2008) | 11 lines
- comment some methods in osc.core which are used by nearly all do_* methods in
osc.commandline
- improve "is not a package/project dir" error messages, by printing the
absolute path tried, instead of '.' for the cwd
- make core.store_read_package() raise a proper NoWorkingCopyError instead of
terminating
- give attribution to things in babysitter.py copied from mercurial
- prefix HTTPError exceptions with 'Server returned an error:'
- remove obsolete local error handling from do_prjresults(), do_importsrcpkg(),
do_repos()
........
r3830 | poeml | 2008-04-25 14:29:35 +0200 (Fri, 25 Apr 2008) | 1 line
catch IOError exceptions in the babysitter
........
r3837 | poeml | 2008-04-25 17:27:36 +0200 (Fri, 25 Apr 2008) | 5 lines
- do_remotebuildlog: raise errors for wrong arguments, remove exits
- raise AttributeError in make_meta_url() instead of exiting
- delete unused method core.delete_server_files()
- replace exit call inside make_meta_url() with an AttributeError
........
r3838 | poeml | 2008-04-25 17:49:18 +0200 (Fri, 25 Apr 2008) | 1 line
simplify the check in do_checkout if a project exists, by using show_project_meta() instead of meta_exists
........
r3839 | poeml | 2008-04-25 18:31:26 +0200 (Fri, 25 Apr 2008) | 6 lines
- commandline do_checkout(): change the order of the two checks, first do the
(cheaper) check for existing directory
- core.core checkout_package(): simplify the check in if the package
exists, by using show_package_meta() instead of meta_exists
Let it throw an exception, instead of using sys.exit().
........
r3841 | Marcus_H | 2008-04-27 15:48:06 +0200 (Sun, 27 Apr 2008) | 5 lines
- added 2 new exception classes: PackageError() and PackageExistsError. The PackageError() class is meant to be the base class for all subsequent package exceptions.
- get rid of 2 sys.exit(1) calls
- make the update() method of the Project() class safer: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- minor fix in delPackage(): use getTransActPath() when printing out the filename
........
r3842 | Marcus_H | 2008-04-27 16:52:55 +0200 (Sun, 27 Apr 2008) | 3 lines
- make the commit() method safe: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- removed another sys.exit(1): raise an exception if a package is missing when doing a commit. For now we use the PackageExistsError() exception but this might change in the future (updated description of PackageExistsError() according to this change)
........
r3848 | poeml | 2008-04-28 12:46:45 +0200 (Mon, 28 Apr 2008) | 3 lines
rename several error classes, dropping the "Osc" prefix, and "Error" suffix in
cases where they don't really make sense.
........
r3849 | poeml | 2008-04-28 12:57:32 +0200 (Mon, 28 Apr 2008) | 3 lines
- rename osc.errors module to osc.oscerr, to make it easier to import it from
other programs and have a crystal clear namespace
........
r3850 | poeml | 2008-04-28 13:26:12 +0200 (Mon, 28 Apr 2008) | 2 lines
split PackageExists exception class into PackageExists and PackageMissing
........
2008-04-28 18:37:44 +02:00
if conf . config [ ' do_package_tracking ' ] :
project = Project ( project_dir )
2007-07-23 18:03:30 +02:00
else :
Merged revisions 3774-3775,3779,3781-3782,3787,3789-3793,3798,3802,3805,3817-3822,3827,3829-3830,3837-3839,3841-3842,3848-3850 via svnmerge from
https://forgesvn1.novell.com/svn/opensuse/branches/buildservice/osc-exception-handling
........
r3774 | poeml | 2008-04-22 17:39:45 +0200 (Tue, 22 Apr 2008) | 3 lines
A first draft on implement systematic exception handling:
Add errors.py with some exceptions defined, and babysitter.py to handle them
........
r3775 | poeml | 2008-04-22 22:34:12 +0200 (Tue, 22 Apr 2008) | 9 lines
- new global options:
--debugger jump into the debugger before executing anything
--post-mortem jump into the debugger in case of errors
-t, --traceback print call trace in case of errors
- traceback and post_mortem can also be set in .oscrc.
- catch more errors (HTTPError).
- make config accessible from outside of the Osc instance, by making it a class
attribute
........
r3779 | poeml | 2008-04-23 00:55:49 +0200 (Wed, 23 Apr 2008) | 5 lines
- new global option:
-d, --debug print info useful for debugging
- catch some more errors (HTTPError), with OscHTTPError which isn't very
advanced yet.
........
r3781 | Marcus_H | 2008-04-23 01:02:00 +0200 (Wed, 23 Apr 2008) | 2 lines
- added OscConfigError class (just for testing).
- small change in the signature of the OscBaseError constructor (actually we should get rid of the 'args' tuple because it will be deprecated sooner or later
........
r3782 | Marcus_H | 2008-04-23 02:02:13 +0200 (Wed, 23 Apr 2008) | 2 lines
- access the prg.conf.config dict in a save way - this way we avoid AttributeErrors if the prg.conf.config dict doesn't exist
- in case of an configparser error we have to use the prg.options object directly (this was removed in r3781 by accident)
........
r3787 | poeml | 2008-04-23 09:23:56 +0200 (Wed, 23 Apr 2008) | 4 lines
- remove local exception handling from do_req
- for HTTPError, print details (headers and response) when in debug mode
- catch AttributeError
........
r3789 | poeml | 2008-04-23 16:23:14 +0200 (Wed, 23 Apr 2008) | 4 lines
- errors: add two new classes named OscWrongOptionsError and OscWrongArgsError
- commandline: raise instances of the new errors in a number of places
- commandline: add get_cmd_help() to Osc instance which returns the formatted help of a subcommand
........
r3790 | Marcus_H | 2008-04-23 16:48:28 +0200 (Wed, 23 Apr 2008) | 4 lines
- added 2 new exception classes: OscNoConfigfileError and OscIOError
- added new method write_config() to the conf.py module: This method writes osc's configuration file
- minor cleanups in the conf module
........
r3791 | poeml | 2008-04-23 17:11:07 +0200 (Wed, 23 Apr 2008) | 3 lines
small compatibility fix for r3790: try-except-finally isn't supported in
python-2.4.2, thus do the same as try-except inside a try-finally.
........
r3792 | poeml | 2008-04-23 17:37:53 +0200 (Wed, 23 Apr 2008) | 2 lines
fix up the remaining places regarding handling of errors related to commandline parsing
........
r3793 | poeml | 2008-04-23 17:40:34 +0200 (Wed, 23 Apr 2008) | 3 lines
raise a NoWorkingCopyError in osc.core.store_read_project() in case of an
IOError
........
r3798 | Marcus_H | 2008-04-23 23:55:24 +0200 (Wed, 23 Apr 2008) | 1 line
ported -r3797 from trunk
........
r3802 | Marcus_H | 2008-04-24 11:00:55 +0200 (Thu, 24 Apr 2008) | 1 line
ported -r3801 from trunk
........
r3805 | poeml | 2008-04-24 12:52:30 +0200 (Thu, 24 Apr 2008) | 2 lines
raise OscHTTPError in show_pattern_meta(), replacing local error handling
........
r3817 | poeml | 2008-04-24 20:21:32 +0200 (Thu, 24 Apr 2008) | 9 lines
- remove errors.OscHTTPError again.
it seems simpler to use urllib2.HTTPError instead (and just add a specific
error text message where appropriate, and re-raise)
- for 404s, check out _which_ part was not found
it is very ugly, but may be considered Good for pragmatic reasons
- removed local exception handling and workaround for returned 500's from
delete_package() and delete_project(), thereby getting rid of 4 possible exit
points.
........
r3818 | Marcus_H | 2008-04-24 22:36:17 +0200 (Thu, 24 Apr 2008) | 1 line
- this check is superfluous because every HTTPError instance has a code attribute
........
r3819 | poeml | 2008-04-25 00:39:39 +0200 (Fri, 25 Apr 2008) | 1 line
remove a forgotten debug line from core.delete_project()
........
r3820 | poeml | 2008-04-25 10:07:58 +0200 (Fri, 25 Apr 2008) | 2 lines
- ditch local error handling from wipebinaries(), rebuild(), and abortbuild()
........
r3821 | poeml | 2008-04-25 10:56:38 +0200 (Fri, 25 Apr 2008) | 2 lines
It is never needed to import the exception module.
........
r3822 | poeml | 2008-04-25 11:13:39 +0200 (Fri, 25 Apr 2008) | 4 lines
- when going into the debugger with --post-mortem, always print a traceback before
(thus implying -t)
- do not jump into the debugger if not on a TTY, or working in interactive mode
........
r3827 | poeml | 2008-04-25 13:07:46 +0200 (Fri, 25 Apr 2008) | 9 lines
- add errors.OscWorkingCopyOutdated, which takes a tuple with three args:
path to working copy, current rev, expected rev
- add handler for urllib2.URLError errors to the babysitter
- simplify the OscWrongArgsError and OscWrongOptionsError handlers, by removing
the extra line "Sorry, wrong ..." that was printed before the messages given
when the error was raised.
- remove one more errors.OscHTTPError which was still there, and raise
urllib2.HTTPError instead (show_package_meta())
........
r3829 | poeml | 2008-04-25 14:19:10 +0200 (Fri, 25 Apr 2008) | 11 lines
- comment some methods in osc.core which are used by nearly all do_* methods in
osc.commandline
- improve "is not a package/project dir" error messages, by printing the
absolute path tried, instead of '.' for the cwd
- make core.store_read_package() raise a proper NoWorkingCopyError instead of
terminating
- give attribution to things in babysitter.py copied from mercurial
- prefix HTTPError exceptions with 'Server returned an error:'
- remove obsolete local error handling from do_prjresults(), do_importsrcpkg(),
do_repos()
........
r3830 | poeml | 2008-04-25 14:29:35 +0200 (Fri, 25 Apr 2008) | 1 line
catch IOError exceptions in the babysitter
........
r3837 | poeml | 2008-04-25 17:27:36 +0200 (Fri, 25 Apr 2008) | 5 lines
- do_remotebuildlog: raise errors for wrong arguments, remove exits
- raise AttributeError in make_meta_url() instead of exiting
- delete unused method core.delete_server_files()
- replace exit call inside make_meta_url() with an AttributeError
........
r3838 | poeml | 2008-04-25 17:49:18 +0200 (Fri, 25 Apr 2008) | 1 line
simplify the check in do_checkout if a project exists, by using show_project_meta() instead of meta_exists
........
r3839 | poeml | 2008-04-25 18:31:26 +0200 (Fri, 25 Apr 2008) | 6 lines
- commandline do_checkout(): change the order of the two checks, first do the
(cheaper) check for existing directory
- core.core checkout_package(): simplify the check in if the package
exists, by using show_package_meta() instead of meta_exists
Let it throw an exception, instead of using sys.exit().
........
r3841 | Marcus_H | 2008-04-27 15:48:06 +0200 (Sun, 27 Apr 2008) | 5 lines
- added 2 new exception classes: PackageError() and PackageExistsError. The PackageError() class is meant to be the base class for all subsequent package exceptions.
- get rid of 2 sys.exit(1) calls
- make the update() method of the Project() class safer: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- minor fix in delPackage(): use getTransActPath() when printing out the filename
........
r3842 | Marcus_H | 2008-04-27 16:52:55 +0200 (Sun, 27 Apr 2008) | 3 lines
- make the commit() method safe: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- removed another sys.exit(1): raise an exception if a package is missing when doing a commit. For now we use the PackageExistsError() exception but this might change in the future (updated description of PackageExistsError() according to this change)
........
r3848 | poeml | 2008-04-28 12:46:45 +0200 (Mon, 28 Apr 2008) | 3 lines
rename several error classes, dropping the "Osc" prefix, and "Error" suffix in
cases where they don't really make sense.
........
r3849 | poeml | 2008-04-28 12:57:32 +0200 (Mon, 28 Apr 2008) | 3 lines
- rename osc.errors module to osc.oscerr, to make it easier to import it from
other programs and have a crystal clear namespace
........
r3850 | poeml | 2008-04-28 13:26:12 +0200 (Mon, 28 Apr 2008) | 2 lines
split PackageExists exception class into PackageExists and PackageMissing
........
2008-04-28 18:37:44 +02:00
project = store_read_project ( project_dir )
2007-07-23 18:03:30 +02:00
2009-09-09 17:28:21 +02:00
rpmq = rpmquery . RpmQuery . query ( srpm )
title , pac , descr , url = rpmq . summary ( ) , rpmq . name ( ) , rpmq . description ( ) , rpmq . url ( )
if url is None :
url = ' '
2007-07-23 18:03:30 +02:00
if opts . title :
title = opts . title
if opts . name :
pac = opts . name
2020-02-22 02:08:37 +01:00
elif pac is not None :
pac = pac . decode ( )
2007-07-23 18:03:30 +02:00
if opts . description :
descr = opts . description
2009-05-18 16:50:43 +02:00
2007-07-29 17:27:27 +02:00
# title and description can be empty
if not pac :
2022-09-12 13:43:10 +02:00
print ( ' please specify a package name with the \' --name \' option. '
' The automatic detection failed ' , file = sys . stderr )
2007-07-29 17:27:27 +02:00
sys . exit ( 1 )
2008-03-15 23:51:37 +01:00
if conf . config [ ' do_package_tracking ' ] :
2009-12-25 00:08:29 +01:00
createPackageDir ( os . path . join ( project . dir , pac ) , project )
2008-03-15 23:51:37 +01:00
else :
if not os . path . exists ( os . path . join ( project_dir , pac ) ) :
2022-10-14 14:25:54 +02:00
apiurl = osc_store . Store ( project_dir ) . apiurl
2008-03-15 23:51:37 +01:00
user = conf . get_apiurl_usr ( apiurl )
2008-03-10 19:04:23 +01:00
data = meta_exists ( metatype = ' pkg ' ,
path_args = ( quote_plus ( project ) , quote_plus ( pac ) ) ,
template_args = ( {
' name ' : pac ,
2008-03-15 23:51:37 +01:00
' user ' : user } ) , apiurl = apiurl )
2008-03-10 19:04:23 +01:00
if data :
2019-11-18 09:36:09 +01:00
data = ET . fromstring ( parse_meta_to_string ( data ) )
2010-08-30 14:05:06 +02:00
data . find ( ' title ' ) . text = ' ' . join ( title )
2008-03-10 19:04:23 +01:00
data . find ( ' description ' ) . text = ' ' . join ( descr )
2009-01-21 22:55:53 +01:00
data . find ( ' url ' ) . text = url
2022-07-28 12:28:33 +02:00
data = ET . tostring ( data , encoding = " unicode " )
2008-03-10 19:04:23 +01:00
else :
2013-04-09 12:51:28 +02:00
print ( ' error - cannot get meta data ' , file = sys . stderr )
2008-03-10 19:04:23 +01:00
sys . exit ( 1 )
edit_meta ( metatype = ' pkg ' ,
path_args = ( quote_plus ( project ) , quote_plus ( pac ) ) ,
2022-09-12 13:43:10 +02:00
data = data , apiurl = apiurl )
2010-08-30 14:05:06 +02:00
Package . init_package ( apiurl , project , pac , os . path . join ( project_dir , pac ) )
2007-07-30 13:12:42 +02:00
else :
2013-04-09 12:51:28 +02:00
print ( ' error - local package already exists ' , file = sys . stderr )
2007-07-30 13:12:42 +02:00
sys . exit ( 1 )
2008-03-15 23:51:37 +01:00
2010-08-30 14:05:06 +02:00
unpack_srcrpm ( srpm , os . path . join ( project_dir , pac ) )
p = Package ( os . path . join ( project_dir , pac ) )
2008-03-15 23:51:37 +01:00
if len ( p . filenamelist ) == 0 and opts . commit :
2013-04-09 12:51:28 +02:00
print ( ' Adding files to working copy... ' )
2011-01-20 20:38:36 +01:00
addFiles ( glob . glob ( ' %s /* ' % os . path . join ( project_dir , pac ) ) )
2008-03-15 23:51:37 +01:00
if conf . config [ ' do_package_tracking ' ] :
project . commit ( ( pac , ) )
else :
p . update_datastructs ( )
p . commit ( )
elif opts . commit and opts . delete_old_files :
2010-08-20 14:34:41 +02:00
for filename in p . filenamelist :
p . delete_remote_source_file ( filename )
2008-03-15 23:51:37 +01:00
p . update_local_filesmeta ( )
2013-04-09 12:51:28 +02:00
print ( ' Adding files to working copy... ' )
2008-03-15 23:51:37 +01:00
addFiles ( glob . glob ( ' * ' ) )
p . update_datastructs ( )
p . commit ( )
2007-07-23 18:03:30 +02:00
else :
2022-09-12 13:43:10 +02:00
print ( ' No files were committed to the server. Please '
2013-04-09 12:51:28 +02:00
' commit them manually. ' )
print ( ' Package \' %s \' only imported locally ' % pac )
2007-07-23 18:03:30 +02:00
sys . exit ( 1 )
2013-04-09 12:51:28 +02:00
print ( ' Package \' %s \' imported successfully ' % pac )
2007-07-25 12:56:04 +02:00
2010-07-29 11:43:56 +02:00
@cmdln.option ( ' -X ' , ' -m ' , ' --method ' , default = ' GET ' , metavar = ' HTTP_METHOD ' ,
2023-12-07 16:59:19 +01:00
choices = ( ' HEAD ' , ' GET ' , ' PUT ' , ' POST ' , ' DELETE ' ) ,
help = ' specify HTTP method to use (HEAD|GET|PUT|DELETE|POST) ' )
2014-10-31 09:22:25 +01:00
@cmdln.option ( ' -e ' , ' --edit ' , default = None , action = ' store_true ' ,
help = ' GET, edit and PUT the location ' )
2007-07-25 12:56:04 +02:00
@cmdln.option ( ' -d ' , ' --data ' , default = None , metavar = ' STRING ' ,
help = ' specify string data for e.g. POST ' )
2010-07-29 11:43:56 +02:00
@cmdln.option ( ' -T ' , ' -f ' , ' --file ' , default = None , metavar = ' FILE ' ,
2011-09-23 12:11:14 +02:00
help = ' specify filename to upload, uses PUT mode by default ' )
2009-05-18 16:50:43 +02:00
@cmdln.option ( ' -a ' , ' --add-header ' , default = None , metavar = ' NAME STRING ' ,
2008-03-16 21:46:16 +01:00
nargs = 2 , action = ' append ' , dest = ' headers ' ,
help = ' add the specified header to the request ' )
2022-09-20 10:01:28 +02:00
@cmdln.option ( ' url ' ,
help = " either URL ' /path ' or full URL with ' scheme://hostname/path ' " )
def do_api ( self , subcmd , opts ) :
2022-01-19 15:13:55 +01:00
"""
Issue an arbitrary request to the API
2007-07-25 12:56:04 +02:00
Useful for testing .
URL can be specified either partially ( only the path component ) , or fully
with URL scheme and hostname ( ' http://... ' ) .
Note the global - A and - H options ( see osc help ) .
Examples :
2009-06-04 16:14:01 +02:00
osc api / source / home : user
2010-07-29 11:43:56 +02:00
osc api - X PUT - T / etc / fstab source / home : user / test5 / myfstab
2014-10-31 14:14:06 +01:00
osc api - e / configuration
2007-07-25 12:56:04 +02:00
"""
2022-09-20 10:01:28 +02:00
url = opts . url
2010-07-29 17:29:07 +02:00
apiurl = self . get_api_url ( )
2007-07-25 12:56:04 +02:00
2011-09-23 12:11:14 +02:00
# default is PUT when uploading files
if opts . file and opts . method == ' GET ' :
opts . method = ' PUT '
2007-07-25 12:56:04 +02:00
if not url . startswith ( ' http ' ) :
if not url . startswith ( ' / ' ) :
url = ' / ' + url
2010-07-29 17:29:07 +02:00
url = apiurl + url
2007-07-25 12:56:04 +02:00
2008-03-16 21:46:16 +01:00
if opts . headers :
opts . headers = dict ( opts . headers )
2009-05-18 16:50:43 +02:00
r = http_request ( opts . method ,
url ,
data = opts . data ,
Merged revisions 3774-3775,3779,3781-3782,3787,3789-3793,3798,3802,3805,3817-3822,3827,3829-3830,3837-3839,3841-3842,3848-3850 via svnmerge from
https://forgesvn1.novell.com/svn/opensuse/branches/buildservice/osc-exception-handling
........
r3774 | poeml | 2008-04-22 17:39:45 +0200 (Tue, 22 Apr 2008) | 3 lines
A first draft on implement systematic exception handling:
Add errors.py with some exceptions defined, and babysitter.py to handle them
........
r3775 | poeml | 2008-04-22 22:34:12 +0200 (Tue, 22 Apr 2008) | 9 lines
- new global options:
--debugger jump into the debugger before executing anything
--post-mortem jump into the debugger in case of errors
-t, --traceback print call trace in case of errors
- traceback and post_mortem can also be set in .oscrc.
- catch more errors (HTTPError).
- make config accessible from outside of the Osc instance, by making it a class
attribute
........
r3779 | poeml | 2008-04-23 00:55:49 +0200 (Wed, 23 Apr 2008) | 5 lines
- new global option:
-d, --debug print info useful for debugging
- catch some more errors (HTTPError), with OscHTTPError which isn't very
advanced yet.
........
r3781 | Marcus_H | 2008-04-23 01:02:00 +0200 (Wed, 23 Apr 2008) | 2 lines
- added OscConfigError class (just for testing).
- small change in the signature of the OscBaseError constructor (actually we should get rid of the 'args' tuple because it will be deprecated sooner or later
........
r3782 | Marcus_H | 2008-04-23 02:02:13 +0200 (Wed, 23 Apr 2008) | 2 lines
- access the prg.conf.config dict in a save way - this way we avoid AttributeErrors if the prg.conf.config dict doesn't exist
- in case of an configparser error we have to use the prg.options object directly (this was removed in r3781 by accident)
........
r3787 | poeml | 2008-04-23 09:23:56 +0200 (Wed, 23 Apr 2008) | 4 lines
- remove local exception handling from do_req
- for HTTPError, print details (headers and response) when in debug mode
- catch AttributeError
........
r3789 | poeml | 2008-04-23 16:23:14 +0200 (Wed, 23 Apr 2008) | 4 lines
- errors: add two new classes named OscWrongOptionsError and OscWrongArgsError
- commandline: raise instances of the new errors in a number of places
- commandline: add get_cmd_help() to Osc instance which returns the formatted help of a subcommand
........
r3790 | Marcus_H | 2008-04-23 16:48:28 +0200 (Wed, 23 Apr 2008) | 4 lines
- added 2 new exception classes: OscNoConfigfileError and OscIOError
- added new method write_config() to the conf.py module: This method writes osc's configuration file
- minor cleanups in the conf module
........
r3791 | poeml | 2008-04-23 17:11:07 +0200 (Wed, 23 Apr 2008) | 3 lines
small compatibility fix for r3790: try-except-finally isn't supported in
python-2.4.2, thus do the same as try-except inside a try-finally.
........
r3792 | poeml | 2008-04-23 17:37:53 +0200 (Wed, 23 Apr 2008) | 2 lines
fix up the remaining places regarding handling of errors related to commandline parsing
........
r3793 | poeml | 2008-04-23 17:40:34 +0200 (Wed, 23 Apr 2008) | 3 lines
raise a NoWorkingCopyError in osc.core.store_read_project() in case of an
IOError
........
r3798 | Marcus_H | 2008-04-23 23:55:24 +0200 (Wed, 23 Apr 2008) | 1 line
ported -r3797 from trunk
........
r3802 | Marcus_H | 2008-04-24 11:00:55 +0200 (Thu, 24 Apr 2008) | 1 line
ported -r3801 from trunk
........
r3805 | poeml | 2008-04-24 12:52:30 +0200 (Thu, 24 Apr 2008) | 2 lines
raise OscHTTPError in show_pattern_meta(), replacing local error handling
........
r3817 | poeml | 2008-04-24 20:21:32 +0200 (Thu, 24 Apr 2008) | 9 lines
- remove errors.OscHTTPError again.
it seems simpler to use urllib2.HTTPError instead (and just add a specific
error text message where appropriate, and re-raise)
- for 404s, check out _which_ part was not found
it is very ugly, but may be considered Good for pragmatic reasons
- removed local exception handling and workaround for returned 500's from
delete_package() and delete_project(), thereby getting rid of 4 possible exit
points.
........
r3818 | Marcus_H | 2008-04-24 22:36:17 +0200 (Thu, 24 Apr 2008) | 1 line
- this check is superfluous because every HTTPError instance has a code attribute
........
r3819 | poeml | 2008-04-25 00:39:39 +0200 (Fri, 25 Apr 2008) | 1 line
remove a forgotten debug line from core.delete_project()
........
r3820 | poeml | 2008-04-25 10:07:58 +0200 (Fri, 25 Apr 2008) | 2 lines
- ditch local error handling from wipebinaries(), rebuild(), and abortbuild()
........
r3821 | poeml | 2008-04-25 10:56:38 +0200 (Fri, 25 Apr 2008) | 2 lines
It is never needed to import the exception module.
........
r3822 | poeml | 2008-04-25 11:13:39 +0200 (Fri, 25 Apr 2008) | 4 lines
- when going into the debugger with --post-mortem, always print a traceback before
(thus implying -t)
- do not jump into the debugger if not on a TTY, or working in interactive mode
........
r3827 | poeml | 2008-04-25 13:07:46 +0200 (Fri, 25 Apr 2008) | 9 lines
- add errors.OscWorkingCopyOutdated, which takes a tuple with three args:
path to working copy, current rev, expected rev
- add handler for urllib2.URLError errors to the babysitter
- simplify the OscWrongArgsError and OscWrongOptionsError handlers, by removing
the extra line "Sorry, wrong ..." that was printed before the messages given
when the error was raised.
- remove one more errors.OscHTTPError which was still there, and raise
urllib2.HTTPError instead (show_package_meta())
........
r3829 | poeml | 2008-04-25 14:19:10 +0200 (Fri, 25 Apr 2008) | 11 lines
- comment some methods in osc.core which are used by nearly all do_* methods in
osc.commandline
- improve "is not a package/project dir" error messages, by printing the
absolute path tried, instead of '.' for the cwd
- make core.store_read_package() raise a proper NoWorkingCopyError instead of
terminating
- give attribution to things in babysitter.py copied from mercurial
- prefix HTTPError exceptions with 'Server returned an error:'
- remove obsolete local error handling from do_prjresults(), do_importsrcpkg(),
do_repos()
........
r3830 | poeml | 2008-04-25 14:29:35 +0200 (Fri, 25 Apr 2008) | 1 line
catch IOError exceptions in the babysitter
........
r3837 | poeml | 2008-04-25 17:27:36 +0200 (Fri, 25 Apr 2008) | 5 lines
- do_remotebuildlog: raise errors for wrong arguments, remove exits
- raise AttributeError in make_meta_url() instead of exiting
- delete unused method core.delete_server_files()
- replace exit call inside make_meta_url() with an AttributeError
........
r3838 | poeml | 2008-04-25 17:49:18 +0200 (Fri, 25 Apr 2008) | 1 line
simplify the check in do_checkout if a project exists, by using show_project_meta() instead of meta_exists
........
r3839 | poeml | 2008-04-25 18:31:26 +0200 (Fri, 25 Apr 2008) | 6 lines
- commandline do_checkout(): change the order of the two checks, first do the
(cheaper) check for existing directory
- core.core checkout_package(): simplify the check in if the package
exists, by using show_package_meta() instead of meta_exists
Let it throw an exception, instead of using sys.exit().
........
r3841 | Marcus_H | 2008-04-27 15:48:06 +0200 (Sun, 27 Apr 2008) | 5 lines
- added 2 new exception classes: PackageError() and PackageExistsError. The PackageError() class is meant to be the base class for all subsequent package exceptions.
- get rid of 2 sys.exit(1) calls
- make the update() method of the Project() class safer: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- minor fix in delPackage(): use getTransActPath() when printing out the filename
........
r3842 | Marcus_H | 2008-04-27 16:52:55 +0200 (Sun, 27 Apr 2008) | 3 lines
- make the commit() method safe: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- removed another sys.exit(1): raise an exception if a package is missing when doing a commit. For now we use the PackageExistsError() exception but this might change in the future (updated description of PackageExistsError() according to this change)
........
r3848 | poeml | 2008-04-28 12:46:45 +0200 (Mon, 28 Apr 2008) | 3 lines
rename several error classes, dropping the "Osc" prefix, and "Error" suffix in
cases where they don't really make sense.
........
r3849 | poeml | 2008-04-28 12:57:32 +0200 (Mon, 28 Apr 2008) | 3 lines
- rename osc.errors module to osc.oscerr, to make it easier to import it from
other programs and have a crystal clear namespace
........
r3850 | poeml | 2008-04-28 13:26:12 +0200 (Mon, 28 Apr 2008) | 2 lines
split PackageExists exception class into PackageExists and PackageMissing
........
2008-04-28 18:37:44 +02:00
file = opts . file ,
2009-05-18 16:50:43 +02:00
headers = opts . headers )
2007-07-25 12:56:04 +02:00
2014-10-31 09:22:25 +01:00
if opts . edit :
2023-06-06 13:40:41 +02:00
# to edit the output, we need to read all of it
# it's going to run ouf of memory if the data is too big
out = r . read ( )
2014-10-31 09:22:25 +01:00
text = edit_text ( out )
r = http_request ( " PUT " ,
2022-09-12 13:43:10 +02:00
url ,
data = text ,
headers = opts . headers )
2014-10-31 09:22:25 +01:00
2023-06-06 13:40:41 +02:00
while True :
data = r . read ( 8192 )
if not data :
break
sys . stdout . buffer . write ( data )
2009-10-22 11:43:58 +02:00
2009-12-25 17:19:44 +01:00
@cmdln.option ( ' -b ' , ' --bugowner-only ' , action = ' store_true ' ,
2009-06-18 18:20:49 +02:00
help = ' Show only the bugowner ' )
2009-10-22 11:43:58 +02:00
@cmdln.option ( ' -B ' , ' --bugowner ' , action = ' store_true ' ,
help = ' Show only the bugowner if defined, or maintainer otherwise ' )
2007-09-03 12:17:26 +02:00
@cmdln.option ( ' -e ' , ' --email ' , action = ' store_true ' ,
help = ' show email addresses instead of user names ' )
2009-06-18 18:20:49 +02:00
@cmdln.option ( ' --nodevelproject ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' do not follow a defined devel project '
2009-06-18 18:20:49 +02:00
' (primary project where a package is developed) ' )
2008-05-20 10:29:54 +02:00
@cmdln.option ( ' -D ' , ' --devel-project ' , metavar = ' devel_project ' ,
help = ' define the project where this package is primarily developed ' )
2007-09-12 20:01:13 +02:00
@cmdln.option ( ' -a ' , ' --add ' , metavar = ' user ' ,
2012-11-23 12:52:05 +01:00
help = ' add a new person for given role ( " maintainer " by default) ' )
2023-03-13 15:24:00 +01:00
@cmdln.option ( ' -A ' , ' --all ' , action = ' store_true ' ,
2012-11-23 12:52:05 +01:00
help = ' list all found entries not just the first one ' )
@cmdln.option ( ' -s ' , ' --set-bugowner ' , metavar = ' user ' ,
2014-01-24 17:01:35 +01:00
help = ' Set the bugowner to specified person (or group via group: prefix) ' )
2012-11-23 12:52:05 +01:00
@cmdln.option ( ' -S ' , ' --set-bugowner-request ' , metavar = ' user ' ,
2014-01-24 17:01:35 +01:00
help = ' Set the bugowner to specified person via a request (or group via group: prefix) ' )
2013-02-20 11:41:17 +01:00
@cmdln.option ( ' -U ' , ' --user ' , metavar = ' USER ' ,
help = ' All official maintained instances for the specified USER ' )
@cmdln.option ( ' -G ' , ' --group ' , metavar = ' GROUP ' ,
help = ' All official maintained instances for the specified GROUP ' )
2007-09-12 20:01:13 +02:00
@cmdln.option ( ' -d ' , ' --delete ' , metavar = ' user ' ,
2009-12-30 21:54:57 +01:00
help = ' delete a maintainer/bugowner (can be specified via --role) ' )
2009-12-25 17:31:13 +01:00
@cmdln.option ( ' -r ' , ' --role ' , metavar = ' role ' , action = ' append ' , default = [ ] ,
2009-06-19 15:57:27 +02:00
help = ' Specify user role ' )
2013-05-02 11:38:53 +02:00
@cmdln.option ( ' -m ' , ' --message ' ,
help = ' Define message as commit entry or request description ' )
2012-11-23 12:52:05 +01:00
@cmdln.alias ( ' bugowner ' )
2007-09-03 12:17:26 +02:00
def do_maintainer ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Show maintainers according to server side configuration
2009-05-18 16:50:43 +02:00
2022-01-19 15:13:55 +01:00
# Search for official maintained sources in OBS instance
osc maintainer BINARY_OR_PACKAGE_NAME < options >
osc maintainer - U < user > < options >
osc maintainer - G < group > < options >
2013-02-20 11:41:17 +01:00
2022-01-19 15:13:55 +01:00
# Lookup via containers
osc maintainer < options >
osc maintainer PRJ < options >
osc maintainer PRJ PKG < options >
2016-05-15 17:50:31 +02:00
2012-11-22 11:37:32 +01:00
The tool looks up the default responsible person for a certain project or package .
When using with an OBS 2.4 ( or later ) server it is doing the lookup for
a given binary according to the server side configuration of default owners .
2013-03-06 11:49:22 +01:00
The tool is also looking into devel packages and supports to fallback to the project
in case a package has no defined maintainer .
Please use " osc meta pkg " in case you need to know the definition in a specific container .
2010-09-10 14:20:42 +02:00
PRJ and PKG default to current working - copy path .
2007-09-03 12:17:26 +02:00
"""
2014-02-11 11:56:44 +01:00
def get_maintainer_data ( apiurl , maintainer , verbose = False ) :
tags = ( ' email ' , )
if maintainer . startswith ( ' group: ' ) :
group = maintainer . replace ( ' group: ' , ' ' )
if verbose :
return [ maintainer ] + get_group_data ( apiurl , group , ' title ' , * tags )
return get_group_data ( apiurl , group , ' email ' )
if verbose :
tags = ( ' login ' , ' realname ' , ' email ' )
return get_user_data ( apiurl , maintainer , * tags )
2022-09-12 13:43:10 +02:00
2014-05-08 16:07:42 +02:00
def setBugownerHelper ( apiurl , project , package , bugowner ) :
try :
setBugowner ( apiurl , project , package , bugowner )
except HTTPError as e :
if e . code != 403 :
raise
print ( " No write permission in " , project , end = ' ' )
if package :
print ( " / " , package , end = ' ' )
print ( )
repl = raw_input ( ' \n Creating a request instead? (y/n) ' )
if repl . lower ( ) == ' y ' :
opts . set_bugowner_request = bugowner
opts . set_bugowner = None
2009-05-18 16:50:43 +02:00
2020-08-12 09:14:16 +02:00
search_term = None
2010-09-10 14:20:42 +02:00
prj = None
2012-11-22 11:37:32 +01:00
pac = None
metaroot = None
searchresult = None
2022-09-12 13:43:10 +02:00
roles = [ ' bugowner ' , ' maintainer ' ]
2009-12-25 17:31:13 +01:00
if len ( opts . role ) :
roles = opts . role
2014-07-10 09:50:52 +02:00
elif opts . bugowner_only or opts . bugowner or subcmd == ' bugowner ' :
2022-09-12 13:43:10 +02:00
roles = [ ' bugowner ' ]
2009-06-18 18:20:49 +02:00
2013-01-08 22:32:27 +01:00
args = slash_split ( args )
2013-02-20 11:41:17 +01:00
if opts . user or opts . group :
if len ( args ) != 0 :
raise oscerr . WrongArgs ( ' Either search for user or for packages. ' )
elif len ( args ) == 0 :
2010-09-10 14:20:42 +02:00
try :
pac = store_read_package ( ' . ' )
except oscerr . NoWorkingCopy :
pass
prj = store_read_project ( ' . ' )
elif len ( args ) == 1 :
2020-08-12 09:14:16 +02:00
# it is unclear if one argument is a search_term or a project, try search_term first for new OBS 2.4
2022-05-10 14:49:21 +02:00
search_term = prj = self . _process_project_name ( args [ 0 ] )
2007-09-03 12:17:26 +02:00
elif len ( args ) == 2 :
2022-05-10 14:49:21 +02:00
prj = self . _process_project_name ( args [ 0 ] )
2007-09-12 20:01:13 +02:00
pac = args [ 1 ]
2007-09-03 12:17:26 +02:00
else :
2010-02-02 16:14:00 +01:00
raise oscerr . WrongArgs ( ' Wrong number of arguments. ' )
2009-05-18 16:50:43 +02:00
2010-07-29 17:29:07 +02:00
apiurl = self . get_api_url ( )
2014-08-12 15:01:16 +02:00
# Try the OBS 2.4 way first.
2020-08-12 09:14:16 +02:00
if search_term or opts . user or opts . group :
2013-05-27 12:41:50 +02:00
limit = None
2013-05-27 12:16:44 +02:00
if opts . all :
2013-05-27 12:41:50 +02:00
limit = 0
filterroles = roles
2022-09-12 13:43:10 +02:00
if filterroles == [ ' bugowner ' , ' maintainer ' ] :
2013-05-27 12:16:44 +02:00
# use server side configured default
2013-05-27 12:41:50 +02:00
filterroles = None
2020-08-12 09:14:16 +02:00
if search_term :
# try the package name first, it is faster and may catch cases where no
# binary with that name exists for the given package name
searchresult = owner ( apiurl , search_term , " package " , usefilter = filterroles , devel = None , limit = limit )
2022-08-29 12:56:57 +02:00
if searchresult is None or len ( searchresult ) == 0 :
2020-08-12 09:14:16 +02:00
searchresult = owner ( apiurl , search_term , " binary " , usefilter = filterroles , devel = None , limit = limit )
2022-08-29 12:56:57 +02:00
if searchresult is not None and len ( searchresult ) == 0 :
2014-07-10 09:50:52 +02:00
# We talk to an OBS 2.4 or later understanding the call
if opts . set_bugowner or opts . set_bugowner_request :
# filtered search did not succeed, but maybe we want to set an owner initially?
2020-08-12 09:14:16 +02:00
searchresult = owner ( apiurl , search_term , " binary " , usefilter = " " , devel = None , limit = - 1 )
2014-07-10 09:50:52 +02:00
if searchresult :
print ( " WARNING: the binary exists, but has no matching maintainership roles defined. " )
print ( " Do you want to set it in the container where the binary appeared first? " )
result = searchresult . find ( ' owner ' )
print ( " This is: " + result . get ( ' project ' ) , end = ' ' )
if result . get ( ' package ' ) :
2022-04-20 19:22:35 +02:00
print ( " / " + result . get ( ' package ' ) )
2014-07-10 09:50:52 +02:00
repl = raw_input ( ' \n Use this container? (y/n) ' )
if repl . lower ( ) != ' y ' :
searchresult = None
2013-05-27 12:16:44 +02:00
elif opts . user :
searchresult = owner ( apiurl , opts . user , " user " , usefilter = filterroles , devel = None )
elif opts . group :
searchresult = owner ( apiurl , opts . group , " group " , usefilter = filterroles , devel = None )
else :
raise oscerr . WrongArgs ( ' osc bug, no valid search criteria ' )
2012-11-23 12:52:05 +01:00
2009-06-18 18:20:49 +02:00
if opts . add :
2012-11-23 12:52:05 +01:00
if searchresult :
for result in searchresult . findall ( ' owner ' ) :
for role in roles :
addPerson ( apiurl , result . get ( ' project ' ) , result . get ( ' package ' ) , opts . add , role )
else :
for role in roles :
addPerson ( apiurl , prj , pac , opts . add , role )
elif opts . set_bugowner or opts . set_bugowner_request :
bugowner = opts . set_bugowner or opts . set_bugowner_request
requestactionsxml = " "
if searchresult :
for result in searchresult . findall ( ' owner ' ) :
if opts . set_bugowner :
2014-05-08 16:07:42 +02:00
setBugownerHelper ( apiurl , result . get ( ' project ' ) , result . get ( ' package ' ) , opts . set_bugowner )
2012-11-23 12:52:05 +01:00
if opts . set_bugowner_request :
2014-05-08 16:07:42 +02:00
args = [ bugowner , result . get ( ' project ' ) ]
if result . get ( ' package ' ) :
args = args + [ result . get ( ' package ' ) ]
requestactionsxml + = self . _set_bugowner ( args , opts )
2012-11-23 12:52:05 +01:00
else :
2013-05-02 11:08:27 +02:00
if opts . set_bugowner :
2014-05-08 16:07:42 +02:00
setBugownerHelper ( apiurl , prj , pac , opts . set_bugowner )
2013-05-02 11:08:27 +02:00
if opts . set_bugowner_request :
2014-05-08 15:41:15 +02:00
args = [ bugowner , prj ]
if pac :
args = args + [ pac ]
requestactionsxml + = self . _set_bugowner ( args , opts )
2012-11-23 12:52:05 +01:00
if requestactionsxml != " " :
2013-05-02 11:38:53 +02:00
if opts . message :
2022-07-07 15:38:14 +02:00
message = opts . message
2013-05-02 11:38:53 +02:00
else :
message = edit_message ( )
2012-11-23 12:52:05 +01:00
xml = """ <request> %s <state name= " new " /> <description> %s </description> </request> """ % \
2020-03-12 23:00:47 +01:00
( requestactionsxml , _html_escape ( message or " " ) )
2012-11-23 12:52:05 +01:00
u = makeurl ( apiurl , [ ' request ' ] , query = ' cmd=create ' )
f = http_POST ( u , data = xml )
root = ET . parse ( f ) . getroot ( )
2013-04-09 12:51:28 +02:00
print ( " Request ID: " , root . get ( ' id ' ) )
2012-11-23 12:52:05 +01:00
2007-09-12 20:01:13 +02:00
elif opts . delete :
2012-11-23 12:52:05 +01:00
if searchresult :
for result in searchresult . findall ( ' owner ' ) :
for role in roles :
2014-05-08 15:26:29 +02:00
delPerson ( apiurl , result . get ( ' project ' ) , result . get ( ' package ' ) , opts . delete , role )
2012-11-23 12:52:05 +01:00
else :
for role in roles :
delPerson ( apiurl , prj , pac , opts . delete , role )
2008-05-20 10:29:54 +02:00
elif opts . devel_project :
2009-12-25 17:19:44 +01:00
# XXX: does it really belong to this command?
2010-07-29 17:29:07 +02:00
setDevelProject ( apiurl , prj , pac , opts . devel_project )
2009-06-23 12:06:31 +02:00
else :
2010-02-02 16:14:00 +01:00
if pac :
2010-07-29 17:29:07 +02:00
m = show_package_meta ( apiurl , prj , pac )
2018-12-13 15:17:29 +01:00
metaroot = ET . fromstring ( b ' ' . join ( m ) )
2010-02-02 16:14:00 +01:00
if not opts . nodevelproject :
2012-11-22 11:37:32 +01:00
while metaroot . findall ( ' devel ' ) :
d = metaroot . find ( ' devel ' )
2010-02-02 16:14:00 +01:00
prj = d . get ( ' project ' , prj )
pac = d . get ( ' package ' , pac )
if opts . verbose :
2013-04-09 12:51:28 +02:00
print ( " Following to the development space: %s / %s " % ( prj , pac ) )
2010-07-29 17:29:07 +02:00
m = show_package_meta ( apiurl , prj , pac )
2018-12-13 15:17:29 +01:00
metaroot = ET . fromstring ( b ' ' . join ( m ) )
2014-01-24 17:01:35 +01:00
if not metaroot . findall ( ' person ' ) and not metaroot . findall ( ' group ' ) :
2010-02-02 16:14:00 +01:00
if opts . verbose :
2013-04-09 12:51:28 +02:00
print ( " No dedicated persons in package defined, showing the project persons. " )
2010-02-02 16:14:00 +01:00
pac = None
2010-07-29 17:29:07 +02:00
m = show_project_meta ( apiurl , prj )
2018-12-13 15:17:29 +01:00
metaroot = ET . fromstring ( b ' ' . join ( m ) )
2010-02-02 16:14:00 +01:00
else :
2012-11-22 11:37:32 +01:00
# fallback to project lookup for old servers
2013-02-20 11:41:17 +01:00
if prj and not searchresult :
2013-05-27 12:16:44 +02:00
m = show_project_meta ( apiurl , prj )
2018-12-13 15:17:29 +01:00
metaroot = ET . fromstring ( b ' ' . join ( m ) )
2012-11-22 11:37:32 +01:00
# extract the maintainers
projects = [ ]
# from owner search
if searchresult :
for result in searchresult . findall ( ' owner ' ) :
maintainers = { }
maintainers . setdefault ( " project " , result . get ( ' project ' ) )
maintainers . setdefault ( " package " , result . get ( ' package ' ) )
for person in result . findall ( ' person ' ) :
maintainers . setdefault ( person . get ( ' role ' ) , [ ] ) . append ( person . get ( ' name ' ) )
2013-04-22 17:09:33 +02:00
for group in result . findall ( ' group ' ) :
2022-09-12 13:43:10 +02:00
maintainers . setdefault ( group . get ( ' role ' ) , [ ] ) . append ( " group: " + group . get ( ' name ' ) )
2012-11-22 11:37:32 +01:00
projects = projects + [ maintainers ]
# from meta data
if metaroot :
# we have just one result
maintainers = { }
for person in metaroot . findall ( ' person ' ) :
maintainers . setdefault ( person . get ( ' role ' ) , [ ] ) . append ( person . get ( ' userid ' ) )
2013-04-22 17:09:33 +02:00
for group in metaroot . findall ( ' group ' ) :
2022-09-12 13:43:10 +02:00
maintainers . setdefault ( group . get ( ' role ' ) , [ ] ) . append ( " group: " + group . get ( ' groupid ' ) )
2012-11-22 11:37:32 +01:00
projects = [ maintainers ]
2010-02-02 16:14:00 +01:00
2009-06-18 18:20:49 +02:00
# showing the maintainers
2012-11-22 11:37:32 +01:00
for maintainers in projects :
2013-05-27 12:41:50 +02:00
indent = " "
2013-05-27 13:38:49 +02:00
definingproject = maintainers . get ( " project " )
2013-05-27 12:16:44 +02:00
if definingproject :
2013-05-27 13:38:49 +02:00
definingpackage = maintainers . get ( " package " )
2013-05-27 12:41:50 +02:00
indent = " "
2013-05-27 12:16:44 +02:00
if definingpackage :
2013-05-27 13:38:49 +02:00
print ( " Defined in package: %s / %s " % ( definingproject , definingpackage ) )
2013-05-27 12:16:44 +02:00
else :
print ( " Defined in project: " , definingproject )
2014-08-12 15:01:16 +02:00
if prj :
2013-05-27 12:16:44 +02:00
# not for user/group search
for role in roles :
2022-08-29 13:23:29 +02:00
if opts . bugowner and not maintainers . get ( role , [ ] ) :
2013-05-27 12:16:44 +02:00
role = ' maintainer '
if pac :
2022-04-20 19:22:35 +02:00
print ( " %s %s of %s / %s : " % ( indent , role , prj , pac ) )
2013-05-27 12:16:44 +02:00
else :
2022-04-20 19:22:35 +02:00
print ( " %s %s of %s : " % ( indent , role , prj ) )
2013-05-27 12:16:44 +02:00
if opts . email :
emails = [ ]
for maintainer in maintainers . get ( role , [ ] ) :
2014-02-11 11:56:44 +01:00
user = get_maintainer_data ( apiurl , maintainer , verbose = False )
2022-08-29 13:23:29 +02:00
if user :
2013-05-27 12:16:44 +02:00
emails . append ( ' ' . join ( user ) )
print ( indent , end = ' ' )
print ( ' , ' . join ( emails ) or ' - ' )
elif opts . verbose :
userdata = [ ]
for maintainer in maintainers . get ( role , [ ] ) :
2014-02-11 11:56:44 +01:00
user = get_maintainer_data ( apiurl , maintainer , verbose = True )
2013-05-27 12:16:44 +02:00
userdata . append ( user [ 0 ] )
2022-04-20 19:22:35 +02:00
if user [ 1 ] != ' - ' :
userdata . append ( " %s < %s > " % ( user [ 1 ] , user [ 2 ] ) )
2013-05-27 12:16:44 +02:00
else :
userdata . append ( user [ 2 ] )
for row in build_table ( 2 , userdata , None , 3 ) :
print ( indent , end = ' ' )
print ( row )
else :
print ( indent , end = ' ' )
print ( ' , ' . join ( maintainers . get ( role , [ ] ) ) or ' - ' )
print ( )
2007-09-03 12:17:26 +02:00
2011-04-11 20:48:59 +02:00
@cmdln.alias ( ' who ' )
@cmdln.alias ( ' user ' )
2022-09-20 10:03:42 +02:00
@cmdln.option ( ' user ' , nargs = ' * ' )
def do_whois ( self , subcmd , opts ) :
2022-01-19 15:13:55 +01:00
"""
Show fullname and email of a buildservice user
2011-04-11 20:48:59 +02:00
"""
apiurl = self . get_api_url ( )
2023-10-13 19:16:36 +02:00
usernames = opts . user
if not usernames :
usernames = [ conf . config [ " api_host_options " ] [ apiurl ] [ " user " ] ]
2011-09-20 15:24:46 +02:00
for name in usernames :
user = get_user_data ( apiurl , name , ' login ' , ' realname ' , ' email ' )
if len ( user ) == 3 :
2022-04-20 19:22:35 +02:00
print ( " %s : \" %s \" < %s > " % ( user [ 0 ] , user [ 1 ] , user [ 2 ] ) )
2011-04-11 20:48:59 +02:00
2022-09-29 16:46:41 +02:00
@cmdln.name ( " create-pbuild-config " )
@cmdln.alias ( ' cpc ' )
@cmdln.option ( " repository " )
@cmdln.option ( " arch " )
def do_create_pbuild_config ( self , subcmd , opts ) :
"""
This command is creating the necessary files to build using pbuild tool .
It basically creates _config and _pbuild file in the project directory .
Changes from there can not get submitted back , except the project is managed
in git .
Examples :
osc cpc REPOSITORY ARCH
"""
apiurl = self . get_api_url ( )
project = None
2022-10-18 23:38:28 +02:00
project_dir = str ( Path . cwd ( ) )
2022-09-29 16:46:41 +02:00
if is_project_dir ( project_dir ) :
project = store_read_project ( project_dir )
elif is_package_dir ( project_dir ) :
2022-10-30 19:52:06 +01:00
project_dir = str ( Path . cwd ( ) . parent )
2022-09-29 16:46:41 +02:00
project = store_read_project ( project_dir )
else :
raise oscerr . WrongArgs ( ' Creating pbuild only works in a checked out project or package ' )
create_pbuild_config ( apiurl , project , opts . repository , opts . arch , project_dir )
2008-01-15 19:58:58 +01:00
@cmdln.option ( ' -r ' , ' --revision ' , metavar = ' rev ' ,
help = ' print out the specified revision ' )
2009-08-20 21:28:05 +02:00
@cmdln.option ( ' -e ' , ' --expand ' , action = ' store_true ' ,
2017-03-09 12:01:50 +01:00
help = ' (default) force expansion of linked packages. ' )
2010-03-08 10:56:29 +01:00
@cmdln.option ( ' -u ' , ' --unexpand ' , action = ' store_true ' ,
help = ' always work with unexpanded packages. ' )
2017-06-24 14:25:05 +02:00
@cmdln.option ( ' -D ' , ' --deleted ' , action = ' store_true ' ,
help = ' access file in a deleted package ' )
2011-06-08 10:25:15 +02:00
@cmdln.option ( ' -M ' , ' --meta ' , action = ' store_true ' ,
help = ' list meta data files ' )
2017-03-02 16:05:48 +01:00
@cmdln.alias ( ' blame ' )
2011-01-12 17:04:22 +01:00
@cmdln.alias ( ' less ' )
2007-11-02 19:18:30 +01:00
def do_cat ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Output the content of a file to standard output
2007-07-25 12:56:04 +02:00
2007-11-02 19:18:30 +01:00
Examples :
2017-03-07 15:07:44 +01:00
osc cat file
2007-11-02 19:18:30 +01:00
osc cat project package file
osc cat project / package / file
2009-09-03 19:28:27 +02:00
osc cat http : / / api . opensuse . org / build / . . . / _log
osc cat http : / / api . opensuse . org / source / . . / _link
2007-11-02 19:18:30 +01:00
2017-03-07 15:07:44 +01:00
osc less file
osc less project package file
osc blame file
osc blame project package file
2007-11-02 19:18:30 +01:00
"""
2009-09-03 19:28:27 +02:00
if len ( args ) == 1 and ( args [ 0 ] . startswith ( ' http:// ' ) or
args [ 0 ] . startswith ( ' https:// ' ) ) :
2009-10-20 16:30:15 +02:00
opts . method = ' GET '
opts . headers = None
opts . data = None
opts . file = None
return self . do_api ( ' list ' , opts , * args )
2007-11-02 19:18:30 +01:00
args = slash_split ( args )
2017-03-07 15:07:44 +01:00
project = package = filename = None
if len ( args ) == 3 :
2022-05-10 14:49:21 +02:00
project = self . _process_project_name ( args [ 0 ] )
2017-03-07 15:07:44 +01:00
package = args [ 1 ]
filename = args [ 2 ]
2022-10-07 17:25:33 +02:00
elif len ( args ) == 1 and is_package_dir ( Path . cwd ( ) ) :
project = store_read_project ( Path . cwd ( ) )
package = store_read_package ( Path . cwd ( ) )
2017-03-07 15:07:44 +01:00
filename = args [ 0 ]
else :
Merged revisions 3774-3775,3779,3781-3782,3787,3789-3793,3798,3802,3805,3817-3822,3827,3829-3830,3837-3839,3841-3842,3848-3850 via svnmerge from
https://forgesvn1.novell.com/svn/opensuse/branches/buildservice/osc-exception-handling
........
r3774 | poeml | 2008-04-22 17:39:45 +0200 (Tue, 22 Apr 2008) | 3 lines
A first draft on implement systematic exception handling:
Add errors.py with some exceptions defined, and babysitter.py to handle them
........
r3775 | poeml | 2008-04-22 22:34:12 +0200 (Tue, 22 Apr 2008) | 9 lines
- new global options:
--debugger jump into the debugger before executing anything
--post-mortem jump into the debugger in case of errors
-t, --traceback print call trace in case of errors
- traceback and post_mortem can also be set in .oscrc.
- catch more errors (HTTPError).
- make config accessible from outside of the Osc instance, by making it a class
attribute
........
r3779 | poeml | 2008-04-23 00:55:49 +0200 (Wed, 23 Apr 2008) | 5 lines
- new global option:
-d, --debug print info useful for debugging
- catch some more errors (HTTPError), with OscHTTPError which isn't very
advanced yet.
........
r3781 | Marcus_H | 2008-04-23 01:02:00 +0200 (Wed, 23 Apr 2008) | 2 lines
- added OscConfigError class (just for testing).
- small change in the signature of the OscBaseError constructor (actually we should get rid of the 'args' tuple because it will be deprecated sooner or later
........
r3782 | Marcus_H | 2008-04-23 02:02:13 +0200 (Wed, 23 Apr 2008) | 2 lines
- access the prg.conf.config dict in a save way - this way we avoid AttributeErrors if the prg.conf.config dict doesn't exist
- in case of an configparser error we have to use the prg.options object directly (this was removed in r3781 by accident)
........
r3787 | poeml | 2008-04-23 09:23:56 +0200 (Wed, 23 Apr 2008) | 4 lines
- remove local exception handling from do_req
- for HTTPError, print details (headers and response) when in debug mode
- catch AttributeError
........
r3789 | poeml | 2008-04-23 16:23:14 +0200 (Wed, 23 Apr 2008) | 4 lines
- errors: add two new classes named OscWrongOptionsError and OscWrongArgsError
- commandline: raise instances of the new errors in a number of places
- commandline: add get_cmd_help() to Osc instance which returns the formatted help of a subcommand
........
r3790 | Marcus_H | 2008-04-23 16:48:28 +0200 (Wed, 23 Apr 2008) | 4 lines
- added 2 new exception classes: OscNoConfigfileError and OscIOError
- added new method write_config() to the conf.py module: This method writes osc's configuration file
- minor cleanups in the conf module
........
r3791 | poeml | 2008-04-23 17:11:07 +0200 (Wed, 23 Apr 2008) | 3 lines
small compatibility fix for r3790: try-except-finally isn't supported in
python-2.4.2, thus do the same as try-except inside a try-finally.
........
r3792 | poeml | 2008-04-23 17:37:53 +0200 (Wed, 23 Apr 2008) | 2 lines
fix up the remaining places regarding handling of errors related to commandline parsing
........
r3793 | poeml | 2008-04-23 17:40:34 +0200 (Wed, 23 Apr 2008) | 3 lines
raise a NoWorkingCopyError in osc.core.store_read_project() in case of an
IOError
........
r3798 | Marcus_H | 2008-04-23 23:55:24 +0200 (Wed, 23 Apr 2008) | 1 line
ported -r3797 from trunk
........
r3802 | Marcus_H | 2008-04-24 11:00:55 +0200 (Thu, 24 Apr 2008) | 1 line
ported -r3801 from trunk
........
r3805 | poeml | 2008-04-24 12:52:30 +0200 (Thu, 24 Apr 2008) | 2 lines
raise OscHTTPError in show_pattern_meta(), replacing local error handling
........
r3817 | poeml | 2008-04-24 20:21:32 +0200 (Thu, 24 Apr 2008) | 9 lines
- remove errors.OscHTTPError again.
it seems simpler to use urllib2.HTTPError instead (and just add a specific
error text message where appropriate, and re-raise)
- for 404s, check out _which_ part was not found
it is very ugly, but may be considered Good for pragmatic reasons
- removed local exception handling and workaround for returned 500's from
delete_package() and delete_project(), thereby getting rid of 4 possible exit
points.
........
r3818 | Marcus_H | 2008-04-24 22:36:17 +0200 (Thu, 24 Apr 2008) | 1 line
- this check is superfluous because every HTTPError instance has a code attribute
........
r3819 | poeml | 2008-04-25 00:39:39 +0200 (Fri, 25 Apr 2008) | 1 line
remove a forgotten debug line from core.delete_project()
........
r3820 | poeml | 2008-04-25 10:07:58 +0200 (Fri, 25 Apr 2008) | 2 lines
- ditch local error handling from wipebinaries(), rebuild(), and abortbuild()
........
r3821 | poeml | 2008-04-25 10:56:38 +0200 (Fri, 25 Apr 2008) | 2 lines
It is never needed to import the exception module.
........
r3822 | poeml | 2008-04-25 11:13:39 +0200 (Fri, 25 Apr 2008) | 4 lines
- when going into the debugger with --post-mortem, always print a traceback before
(thus implying -t)
- do not jump into the debugger if not on a TTY, or working in interactive mode
........
r3827 | poeml | 2008-04-25 13:07:46 +0200 (Fri, 25 Apr 2008) | 9 lines
- add errors.OscWorkingCopyOutdated, which takes a tuple with three args:
path to working copy, current rev, expected rev
- add handler for urllib2.URLError errors to the babysitter
- simplify the OscWrongArgsError and OscWrongOptionsError handlers, by removing
the extra line "Sorry, wrong ..." that was printed before the messages given
when the error was raised.
- remove one more errors.OscHTTPError which was still there, and raise
urllib2.HTTPError instead (show_package_meta())
........
r3829 | poeml | 2008-04-25 14:19:10 +0200 (Fri, 25 Apr 2008) | 11 lines
- comment some methods in osc.core which are used by nearly all do_* methods in
osc.commandline
- improve "is not a package/project dir" error messages, by printing the
absolute path tried, instead of '.' for the cwd
- make core.store_read_package() raise a proper NoWorkingCopyError instead of
terminating
- give attribution to things in babysitter.py copied from mercurial
- prefix HTTPError exceptions with 'Server returned an error:'
- remove obsolete local error handling from do_prjresults(), do_importsrcpkg(),
do_repos()
........
r3830 | poeml | 2008-04-25 14:29:35 +0200 (Fri, 25 Apr 2008) | 1 line
catch IOError exceptions in the babysitter
........
r3837 | poeml | 2008-04-25 17:27:36 +0200 (Fri, 25 Apr 2008) | 5 lines
- do_remotebuildlog: raise errors for wrong arguments, remove exits
- raise AttributeError in make_meta_url() instead of exiting
- delete unused method core.delete_server_files()
- replace exit call inside make_meta_url() with an AttributeError
........
r3838 | poeml | 2008-04-25 17:49:18 +0200 (Fri, 25 Apr 2008) | 1 line
simplify the check in do_checkout if a project exists, by using show_project_meta() instead of meta_exists
........
r3839 | poeml | 2008-04-25 18:31:26 +0200 (Fri, 25 Apr 2008) | 6 lines
- commandline do_checkout(): change the order of the two checks, first do the
(cheaper) check for existing directory
- core.core checkout_package(): simplify the check in if the package
exists, by using show_package_meta() instead of meta_exists
Let it throw an exception, instead of using sys.exit().
........
r3841 | Marcus_H | 2008-04-27 15:48:06 +0200 (Sun, 27 Apr 2008) | 5 lines
- added 2 new exception classes: PackageError() and PackageExistsError. The PackageError() class is meant to be the base class for all subsequent package exceptions.
- get rid of 2 sys.exit(1) calls
- make the update() method of the Project() class safer: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- minor fix in delPackage(): use getTransActPath() when printing out the filename
........
r3842 | Marcus_H | 2008-04-27 16:52:55 +0200 (Sun, 27 Apr 2008) | 3 lines
- make the commit() method safe: in any case we have to write the _packages file otherwise the package tracking will be screwed up.
- removed another sys.exit(1): raise an exception if a package is missing when doing a commit. For now we use the PackageExistsError() exception but this might change in the future (updated description of PackageExistsError() according to this change)
........
r3848 | poeml | 2008-04-28 12:46:45 +0200 (Mon, 28 Apr 2008) | 3 lines
rename several error classes, dropping the "Osc" prefix, and "Error" suffix in
cases where they don't really make sense.
........
r3849 | poeml | 2008-04-28 12:57:32 +0200 (Mon, 28 Apr 2008) | 3 lines
- rename osc.errors module to osc.oscerr, to make it easier to import it from
other programs and have a crystal clear namespace
........
r3850 | poeml | 2008-04-28 13:26:12 +0200 (Mon, 28 Apr 2008) | 2 lines
split PackageExists exception class into PackageExists and PackageMissing
........
2008-04-28 18:37:44 +02:00
raise oscerr . WrongArgs ( ' Wrong number of arguments. ' )
2017-03-07 15:07:44 +01:00
2008-01-15 19:58:58 +01:00
rev , dummy = parseRevisionOption ( opts . revision )
2010-07-29 17:29:07 +02:00
apiurl = self . get_api_url ( )
2007-12-10 15:23:58 +01:00
2022-09-12 13:43:10 +02:00
query = { }
2017-03-02 16:05:48 +01:00
if subcmd == ' blame ' :
query [ ' view ' ] = " blame "
2011-06-08 10:25:15 +02:00
if opts . meta :
query [ ' meta ' ] = 1
2017-06-24 14:25:05 +02:00
if opts . deleted :
query [ ' deleted ' ] = 1
2009-04-09 17:52:59 +02:00
if opts . revision :
2009-08-20 21:28:05 +02:00
query [ ' rev ' ] = opts . revision
2017-03-09 12:01:50 +01:00
if not opts . unexpand :
2017-06-24 14:25:05 +02:00
query [ ' rev ' ] = show_upstream_srcmd5 ( apiurl , project , package , expand = True , revision = opts . revision , meta = opts . meta , deleted = opts . deleted )
2022-09-12 13:43:10 +02:00
query [ ' expand ' ] = 1 # important for blame case to follow links in old revisions
2017-03-07 15:07:44 +01:00
u = makeurl ( apiurl , [ ' source ' , project , package , filename ] , query = query )
2017-03-09 12:01:50 +01:00
if subcmd == ' less ' :
f = http_GET ( u )
2018-12-13 15:17:29 +01:00
run_pager ( b ' ' . join ( f . readlines ( ) ) )
2017-03-09 12:01:50 +01:00
else :
for data in streamfile ( u ) :
2018-12-13 15:17:29 +01:00
if isinstance ( data , str ) :
sys . stdout . write ( data )
else :
2019-09-18 10:49:39 +02:00
sys . stdout . buffer . write ( data )
2007-12-10 15:23:58 +01:00
2009-04-21 18:52:26 +02:00
# helper function to download a file from a specific revision
2022-09-12 13:43:10 +02:00
2009-04-21 18:52:26 +02:00
def download ( self , name , md5 , dir , destfile ) :
2009-05-22 17:00:31 +02:00
o = open ( destfile , ' wb ' )
2009-04-22 11:06:13 +02:00
if md5 != ' ' :
query = { ' rev ' : dir [ ' srcmd5 ' ] }
u = makeurl ( dir [ ' apiurl ' ] , [ ' source ' , dir [ ' project ' ] , dir [ ' package ' ] , pathname2url ( name ) ] , query = query )
for buf in streamfile ( u , http_GET , BUFSIZE ) :
o . write ( buf )
2010-05-03 16:06:33 +02:00
o . close ( )
2009-04-21 18:52:26 +02:00
@cmdln.option ( ' -d ' , ' --destdir ' , default = ' repairlink ' , metavar = ' DIR ' ,
2022-09-12 13:43:10 +02:00
help = ' destination directory ' )
2009-04-23 10:58:21 +02:00
def do_repairlink ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Repair a broken source link
2009-04-22 11:06:13 +02:00
2009-04-23 10:58:21 +02:00
This command checks out a package with merged source changes . It uses
a 3 - way merge to resolve file conflicts . After reviewing / repairing
2009-10-20 16:30:15 +02:00
the merge , use ' osc resolved ... ' and ' osc ci ' to re - create a
2009-08-20 21:28:05 +02:00
working source link .
2009-04-23 10:58:21 +02:00
2009-05-18 16:50:43 +02:00
usage :
2009-05-04 11:13:35 +02:00
* For merging conflicting changes of a checkout package :
2009-04-23 10:58:21 +02:00
osc repairlink
2009-05-04 11:13:35 +02:00
* Check out a package and merge changes :
2009-04-23 10:58:21 +02:00
osc repairlink PROJECT PACKAGE
2009-05-04 11:13:35 +02:00
* Pull conflicting changes from one project into another one :
osc repairlink PROJECT PACKAGE INTO_PROJECT [ INTO_PACKAGE ]
2009-04-22 11:06:13 +02:00
"""
2010-04-30 17:13:21 +02:00
apiurl = self . get_api_url ( )
2012-11-01 20:02:14 +01:00
args = slash_split ( args )
2009-05-07 20:43:04 +02:00
if len ( args ) > = 3 and len ( args ) < = 4 :
2022-05-10 14:49:21 +02:00
prj = self . _process_project_name ( args [ 0 ] )
2009-05-04 11:13:35 +02:00
package = target_package = args [ 1 ]
2022-05-10 14:49:21 +02:00
target_prj = self . _process_project_name ( args [ 2 ] )
2009-05-04 11:13:35 +02:00
if len ( args ) == 4 :
2009-10-20 16:30:15 +02:00
target_package = args [ 3 ]
2009-05-07 20:43:04 +02:00
elif len ( args ) == 2 :
2022-05-10 14:49:21 +02:00
target_prj = prj = self . _process_project_name ( args [ 0 ] )
2009-05-04 11:13:35 +02:00
target_package = package = args [ 1 ]
2022-10-07 17:25:33 +02:00
elif is_package_dir ( Path . cwd ( ) ) :
target_prj = prj = store_read_project ( Path . cwd ( ) )
target_package = package = store_read_package ( Path . cwd ( ) )
2009-04-23 10:58:21 +02:00
else :
2009-05-07 20:43:04 +02:00
raise oscerr . WrongArgs ( ' Please specify project and package ' )
2009-04-22 11:06:13 +02:00
2009-04-27 12:09:38 +02:00
# first try stored reference, then lastworking
2022-09-12 13:43:10 +02:00
query = { ' rev ' : ' latest ' }
2009-04-22 11:06:13 +02:00
u = makeurl ( apiurl , [ ' source ' , prj , package ] , query = query )
f = http_GET ( u )
root = ET . parse ( f ) . getroot ( )
linkinfo = root . find ( ' linkinfo ' )
2022-08-29 12:56:57 +02:00
if linkinfo is None :
2009-04-22 11:06:13 +02:00
raise oscerr . APIError ( ' package is not a source link ' )
2022-08-29 12:56:57 +02:00
if linkinfo . get ( ' error ' ) is None :
2009-04-22 11:06:13 +02:00
raise oscerr . APIError ( ' source link is not broken ' )
2009-04-27 12:09:38 +02:00
workingrev = None
2015-10-23 11:08:30 +02:00
if linkinfo . get ( ' baserev ' ) :
2022-09-12 13:43:10 +02:00
query = { ' rev ' : ' latest ' , ' linkrev ' : ' base ' }
2009-04-27 12:09:38 +02:00
u = makeurl ( apiurl , [ ' source ' , prj , package ] , query = query )
f = http_GET ( u )
root = ET . parse ( f ) . getroot ( )
linkinfo = root . find ( ' linkinfo ' )
2022-08-29 12:56:57 +02:00
if linkinfo . get ( ' error ' ) is None :
2009-04-27 12:09:38 +02:00
workingrev = linkinfo . get ( ' xsrcmd5 ' )
2022-08-29 12:56:57 +02:00
if workingrev is None :
2022-09-12 13:43:10 +02:00
query = { ' lastworking ' : 1 }
2009-04-27 12:09:38 +02:00
u = makeurl ( apiurl , [ ' source ' , prj , package ] , query = query )
f = http_GET ( u )
root = ET . parse ( f ) . getroot ( )
linkinfo = root . find ( ' linkinfo ' )
2022-08-29 12:56:57 +02:00
if linkinfo is None :
2009-04-27 12:09:38 +02:00
raise oscerr . APIError ( ' package is not a source link ' )
2022-08-29 12:56:57 +02:00
if linkinfo . get ( ' error ' ) is None :
2009-04-27 12:09:38 +02:00
raise oscerr . APIError ( ' source link is not broken ' )
workingrev = linkinfo . get ( ' lastworking ' )
2022-08-29 12:56:57 +02:00
if workingrev is None :
2009-04-27 12:09:38 +02:00
raise oscerr . APIError ( ' source link never worked ' )
2013-04-09 12:51:28 +02:00
print ( " using last working link target " )
2009-04-27 12:09:38 +02:00
else :
2013-04-09 12:51:28 +02:00
print ( " using link target of last commit " )
2009-04-22 11:06:13 +02:00
2022-09-12 13:43:10 +02:00
query = { ' expand ' : 1 , ' emptylink ' : 1 }
2009-04-22 11:06:13 +02:00
u = makeurl ( apiurl , [ ' source ' , prj , package ] , query = query )
f = http_GET ( u )
meta = f . readlines ( )
2018-12-13 15:17:29 +01:00
root_new = ET . fromstring ( b ' ' . join ( meta ) )
2022-09-12 13:43:10 +02:00
dir_new = { ' apiurl ' : apiurl , ' project ' : prj , ' package ' : package }
2009-04-22 11:06:13 +02:00
dir_new [ ' srcmd5 ' ] = root_new . get ( ' srcmd5 ' )
2009-05-07 21:13:50 +02:00
dir_new [ ' entries ' ] = [ [ n . get ( ' name ' ) , n . get ( ' md5 ' ) ] for n in root_new . findall ( ' entry ' ) ]
2009-04-22 11:06:13 +02:00
2022-09-12 13:43:10 +02:00
query = { ' rev ' : workingrev }
2009-04-22 11:06:13 +02:00
u = makeurl ( apiurl , [ ' source ' , prj , package ] , query = query )
f = http_GET ( u )
root_oldpatched = ET . parse ( f ) . getroot ( )
linkinfo_oldpatched = root_oldpatched . find ( ' linkinfo ' )
2022-08-29 12:56:57 +02:00
if linkinfo_oldpatched is None :
2009-04-27 12:09:38 +02:00
raise oscerr . APIError ( ' working rev is not a source link? ' )
2022-08-29 12:56:57 +02:00
if linkinfo_oldpatched . get ( ' error ' ) is not None :
2009-04-27 12:09:38 +02:00
raise oscerr . APIError ( ' working rev is not working? ' )
2022-09-12 13:43:10 +02:00
dir_oldpatched = { ' apiurl ' : apiurl , ' project ' : prj , ' package ' : package }
2009-04-22 11:06:13 +02:00
dir_oldpatched [ ' srcmd5 ' ] = root_oldpatched . get ( ' srcmd5 ' )
2009-05-07 21:13:50 +02:00
dir_oldpatched [ ' entries ' ] = [ [ n . get ( ' name ' ) , n . get ( ' md5 ' ) ] for n in root_oldpatched . findall ( ' entry ' ) ]
2009-04-22 11:06:13 +02:00
query = { }
query [ ' rev ' ] = linkinfo_oldpatched . get ( ' srcmd5 ' )
u = makeurl ( apiurl , [ ' source ' , linkinfo_oldpatched . get ( ' project ' ) , linkinfo_oldpatched . get ( ' package ' ) ] , query = query )
f = http_GET ( u )
root_old = ET . parse ( f ) . getroot ( )
2022-09-12 13:43:10 +02:00
dir_old = { ' apiurl ' : apiurl }
2009-04-22 11:06:13 +02:00
dir_old [ ' project ' ] = linkinfo_oldpatched . get ( ' project ' )
dir_old [ ' package ' ] = linkinfo_oldpatched . get ( ' package ' )
2009-04-22 15:14:17 +02:00
dir_old [ ' srcmd5 ' ] = root_old . get ( ' srcmd5 ' )
2009-05-07 21:13:50 +02:00
dir_old [ ' entries ' ] = [ [ n . get ( ' name ' ) , n . get ( ' md5 ' ) ] for n in root_old . findall ( ' entry ' ) ]
2009-04-22 11:06:13 +02:00
entries_old = dict ( dir_old [ ' entries ' ] )
entries_oldpatched = dict ( dir_oldpatched [ ' entries ' ] )
entries_new = dict ( dir_new [ ' entries ' ] )
entries = { }
entries . update ( entries_old )
entries . update ( entries_oldpatched )
entries . update ( entries_new )
destdir = opts . destdir
if os . path . isdir ( destdir ) :
shutil . rmtree ( destdir )
os . mkdir ( destdir )
2010-08-30 13:46:49 +02:00
Package . init_package ( apiurl , target_prj , target_package , destdir )
2018-12-13 15:17:29 +01:00
store_write_string ( destdir , ' _files ' , b ' ' . join ( meta ) + b ' \n ' )
2009-10-20 16:30:15 +02:00
store_write_string ( destdir , ' _linkrepair ' , ' ' )
2009-04-22 11:06:13 +02:00
pac = Package ( destdir )
storedir = os . path . join ( destdir , store )
for name in sorted ( entries . keys ( ) ) :
md5_old = entries_old . get ( name , ' ' )
md5_new = entries_new . get ( name , ' ' )
md5_oldpatched = entries_oldpatched . get ( name , ' ' )
if md5_new != ' ' :
self . download ( name , md5_new , dir_new , os . path . join ( storedir , name ) )
if md5_old == md5_new :
if md5_oldpatched == ' ' :
pac . put_on_deletelist ( name )
continue
2013-04-09 12:51:28 +02:00
print ( statfrmt ( ' ' , name ) )
2009-04-22 11:06:13 +02:00
self . download ( name , md5_oldpatched , dir_oldpatched , os . path . join ( destdir , name ) )
continue
if md5_old == md5_oldpatched :
if md5_new == ' ' :
continue
2013-04-09 12:51:28 +02:00
print ( statfrmt ( ' U ' , name ) )
2009-04-22 11:06:13 +02:00
shutil . copy2 ( os . path . join ( storedir , name ) , os . path . join ( destdir , name ) )
continue
if md5_new == md5_oldpatched :
if md5_new == ' ' :
continue
2013-04-09 12:51:28 +02:00
print ( statfrmt ( ' G ' , name ) )
2009-04-22 11:06:13 +02:00
shutil . copy2 ( os . path . join ( storedir , name ) , os . path . join ( destdir , name ) )
continue
self . download ( name , md5_oldpatched , dir_oldpatched , os . path . join ( destdir , name + ' .mine ' ) )
if md5_new != ' ' :
shutil . copy2 ( os . path . join ( storedir , name ) , os . path . join ( destdir , name + ' .new ' ) )
else :
self . download ( name , md5_new , dir_new , os . path . join ( destdir , name + ' .new ' ) )
self . download ( name , md5_old , dir_old , os . path . join ( destdir , name + ' .old ' ) )
2009-04-23 11:03:59 +02:00
if binary_file ( os . path . join ( destdir , name + ' .mine ' ) ) or \
binary_file ( os . path . join ( destdir , name + ' .old ' ) ) or \
binary_file ( os . path . join ( destdir , name + ' .new ' ) ) :
shutil . copy2 ( os . path . join ( destdir , name + ' .new ' ) , os . path . join ( destdir , name ) )
2013-04-09 12:51:28 +02:00
print ( statfrmt ( ' C ' , name ) )
2009-04-23 11:03:59 +02:00
pac . put_on_conflictlist ( name )
continue
2022-04-20 19:22:35 +02:00
o = open ( os . path . join ( destdir , name ) , ' wb ' )
2022-09-12 13:43:10 +02:00
code = run_external (
' diff3 ' ,
' -m ' , ' -E ' ,
' -L ' , ' .mine ' , os . path . join ( destdir , name + ' .mine ' ) ,
' -L ' , ' .old ' , os . path . join ( destdir , name + ' .old ' ) ,
' -L ' , ' .new ' , os . path . join ( destdir , name + ' .new ' ) ,
stdout = o
)
2009-04-22 11:06:13 +02:00
if code == 0 :
2013-04-09 12:51:28 +02:00
print ( statfrmt ( ' G ' , name ) )
2009-04-27 12:09:38 +02:00
os . unlink ( os . path . join ( destdir , name + ' .mine ' ) )
os . unlink ( os . path . join ( destdir , name + ' .old ' ) )
os . unlink ( os . path . join ( destdir , name + ' .new ' ) )
2009-04-22 11:06:13 +02:00
elif code == 1 :
2013-04-09 12:51:28 +02:00
print ( statfrmt ( ' C ' , name ) )
2009-04-22 11:06:13 +02:00
pac . put_on_conflictlist ( name )
else :
2013-04-09 12:51:28 +02:00
print ( statfrmt ( ' ? ' , name ) )
2009-04-22 11:06:13 +02:00
pac . put_on_conflictlist ( name )
pac . write_deletelist ( )
pac . write_conflictlist ( )
2013-04-09 12:51:28 +02:00
print ( )
print ( ' Please change into the \' %s \' directory, ' % destdir )
print ( ' fix the conflicts (files marked with \' C \' above), ' )
print ( ' run \' osc resolved ... \' , and commit the changes. ' )
2009-04-21 18:52:26 +02:00
2009-12-17 17:16:56 +01:00
def do_pull ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Merge the changes of the link target into your working copy
2009-12-17 17:16:56 +01:00
"""
2009-12-17 20:20:35 +01:00
p = Package ( ' . ' )
2009-12-17 17:16:56 +01:00
# check if everything is committed
2009-12-17 20:20:35 +01:00
for filename in p . filenamelist :
2010-07-28 12:08:40 +02:00
state = p . status ( filename )
if state != ' ' and state != ' S ' :
2009-12-17 20:20:35 +01:00
raise oscerr . WrongArgs ( ' Please commit your local changes first! ' )
2009-12-17 17:16:56 +01:00
# check if we need to update
upstream_rev = p . latest_rev ( )
2011-02-14 12:26:51 +01:00
if not ( p . isfrozen ( ) or p . ispulled ( ) ) :
raise oscerr . WrongArgs ( ' osc pull makes only sense with a detached head, did you mean osc up? ' )
2009-12-17 17:16:56 +01:00
if p . rev != upstream_rev :
2009-12-17 20:20:35 +01:00
raise oscerr . WorkingCopyOutdated ( ( p . absdir , p . rev , upstream_rev ) )
elif not p . islink ( ) :
raise oscerr . WrongArgs ( ' osc pull only works on linked packages. ' )
elif not p . isexpanded ( ) :
raise oscerr . WrongArgs ( ' osc pull only works on expanded links. ' )
2010-01-11 17:00:24 +01:00
linkinfo = p . linkinfo
baserev = linkinfo . baserev
2022-08-29 12:56:57 +02:00
if baserev is None :
2010-01-11 17:00:24 +01:00
raise oscerr . WrongArgs ( ' osc pull only works on links containing a base revision. ' )
2009-12-17 20:20:35 +01:00
2010-01-11 17:00:24 +01:00
# get revisions we need
2022-09-12 13:43:10 +02:00
query = { ' expand ' : 1 , ' emptylink ' : 1 }
2010-01-11 17:00:24 +01:00
u = makeurl ( p . apiurl , [ ' source ' , p . prjname , p . name ] , query = query )
f = http_GET ( u )
meta = f . readlines ( )
2018-12-13 15:17:29 +01:00
root_new = ET . fromstring ( b ' ' . join ( meta ) )
2010-01-11 17:00:24 +01:00
linkinfo_new = root_new . find ( ' linkinfo ' )
2022-08-29 12:56:57 +02:00
if linkinfo_new is None :
2010-01-11 17:00:24 +01:00
raise oscerr . APIError ( ' link is not a really a link? ' )
2022-08-29 12:56:57 +02:00
if linkinfo_new . get ( ' error ' ) is not None :
2010-01-11 17:00:24 +01:00
raise oscerr . APIError ( ' link target is broken ' )
2010-01-14 20:16:10 +01:00
if linkinfo_new . get ( ' srcmd5 ' ) == baserev :
2013-04-09 12:51:28 +02:00
print ( " Already up-to-date. " )
2010-01-20 17:55:44 +01:00
p . unmark_frozen ( )
2010-01-11 17:00:24 +01:00
return
2022-09-12 13:43:10 +02:00
dir_new = { ' apiurl ' : p . apiurl , ' project ' : p . prjname , ' package ' : p . name }
2010-01-11 17:00:24 +01:00
dir_new [ ' srcmd5 ' ] = root_new . get ( ' srcmd5 ' )
dir_new [ ' entries ' ] = [ [ n . get ( ' name ' ) , n . get ( ' md5 ' ) ] for n in root_new . findall ( ' entry ' ) ]
2009-12-17 17:16:56 +01:00
2022-09-12 13:43:10 +02:00
dir_oldpatched = { ' apiurl ' : p . apiurl , ' project ' : p . prjname , ' package ' : p . name , ' srcmd5 ' : p . srcmd5 }
2010-01-14 20:16:10 +01:00
dir_oldpatched [ ' entries ' ] = [ [ f . name , f . md5 ] for f in p . filelist ]
2010-02-28 02:30:13 +01:00
2022-09-12 13:43:10 +02:00
query = { ' rev ' : linkinfo . srcmd5 }
2010-01-11 17:00:24 +01:00
u = makeurl ( p . apiurl , [ ' source ' , linkinfo . project , linkinfo . package ] , query = query )
f = http_GET ( u )
root_old = ET . parse ( f ) . getroot ( )
2022-09-12 13:43:10 +02:00
dir_old = { ' apiurl ' : p . apiurl , ' project ' : linkinfo . project , ' package ' : linkinfo . package , ' srcmd5 ' : linkinfo . srcmd5 }
2010-01-11 17:00:24 +01:00
dir_old [ ' entries ' ] = [ [ n . get ( ' name ' ) , n . get ( ' md5 ' ) ] for n in root_old . findall ( ' entry ' ) ]
# now do 3-way merge
entries_old = dict ( dir_old [ ' entries ' ] )
entries_oldpatched = dict ( dir_oldpatched [ ' entries ' ] )
entries_new = dict ( dir_new [ ' entries ' ] )
entries = { }
entries . update ( entries_old )
entries . update ( entries_oldpatched )
entries . update ( entries_new )
for name in sorted ( entries . keys ( ) ) :
2011-03-17 15:35:22 +01:00
if name . startswith ( ' _service: ' ) or name . startswith ( ' _service_ ' ) :
2013-04-09 14:22:45 +02:00
continue
2010-01-11 17:00:24 +01:00
md5_old = entries_old . get ( name , ' ' )
md5_new = entries_new . get ( name , ' ' )
md5_oldpatched = entries_oldpatched . get ( name , ' ' )
if md5_old == md5_new or md5_oldpatched == md5_new :
2010-01-14 20:16:10 +01:00
continue
2010-01-11 17:00:24 +01:00
if md5_old == md5_oldpatched :
if md5_new == ' ' :
2013-04-09 12:51:28 +02:00
print ( statfrmt ( ' D ' , name ) )
2010-01-11 17:00:24 +01:00
p . put_on_deletelist ( name )
2010-01-14 20:16:10 +01:00
os . unlink ( name )
2010-10-29 17:41:39 +02:00
elif md5_old == ' ' :
2013-04-09 12:51:28 +02:00
print ( statfrmt ( ' A ' , name ) )
2010-10-29 17:41:39 +02:00
self . download ( name , md5_new , dir_new , name )
p . put_on_addlist ( name )
2010-01-11 17:00:24 +01:00
else :
2013-04-09 12:51:28 +02:00
print ( statfrmt ( ' U ' , name ) )
2010-01-11 17:00:24 +01:00
self . download ( name , md5_new , dir_new , name )
2010-01-14 20:16:10 +01:00
continue
# need diff3 to resolve issue
if md5_oldpatched == ' ' :
open ( name , ' w ' ) . write ( ' ' )
os . rename ( name , name + ' .mine ' )
self . download ( name , md5_new , dir_new , name + ' .new ' )
2010-01-11 17:00:24 +01:00
self . download ( name , md5_old , dir_old , name + ' .old ' )
if binary_file ( name + ' .mine ' ) or binary_file ( name + ' .old ' ) or binary_file ( name + ' .new ' ) :
shutil . copy2 ( name + ' .new ' , name )
2013-04-09 12:51:28 +02:00
print ( statfrmt ( ' C ' , name ) )
2010-01-11 17:00:24 +01:00
p . put_on_conflictlist ( name )
continue
o = open ( name , ' wb ' )
2022-09-12 13:43:10 +02:00
code = run_external (
' diff3 ' , ' -m ' , ' -E ' ,
' -L ' , ' .mine ' , name + ' .mine ' ,
' -L ' , ' .old ' , name + ' .old ' ,
' -L ' , ' .new ' , name + ' .new ' ,
stdout = o
)
2010-01-11 17:00:24 +01:00
if code == 0 :
2013-04-09 12:51:28 +02:00
print ( statfrmt ( ' G ' , name ) )
2010-01-11 17:00:24 +01:00
os . unlink ( name + ' .mine ' )
os . unlink ( name + ' .old ' )
os . unlink ( name + ' .new ' )
elif code == 1 :
2013-04-09 12:51:28 +02:00
print ( statfrmt ( ' C ' , name ) )
2010-01-11 17:00:24 +01:00
p . put_on_conflictlist ( name )
else :
2013-04-09 12:51:28 +02:00
print ( statfrmt ( ' ? ' , name ) )
2010-01-11 17:00:24 +01:00
p . put_on_conflictlist ( name )
p . write_deletelist ( )
2010-10-29 17:41:39 +02:00
p . write_addlist ( )
2010-01-11 17:00:24 +01:00
p . write_conflictlist ( )
# store new linkrev
2010-08-30 14:20:12 +02:00
store_write_string ( p . absdir , ' _pulled ' , linkinfo_new . get ( ' srcmd5 ' ) + ' \n ' )
2010-01-20 17:55:44 +01:00
p . unmark_frozen ( )
2013-04-09 12:51:28 +02:00
print ( )
2022-08-29 13:23:29 +02:00
if p . in_conflict :
2013-04-09 12:51:28 +02:00
print ( ' Please fix the conflicts (files marked with \' C \' above), ' )
print ( ' run \' osc resolved ... \' , and commit the changes ' )
print ( ' to update the link information. ' )
2010-01-14 20:16:10 +01:00
else :
2013-04-09 12:51:28 +02:00
print ( ' Please commit the changes to update the link information. ' )
2009-12-17 17:16:56 +01:00
2009-10-16 16:12:55 +02:00
@cmdln.option ( ' --create ' , action = ' store_true ' , default = False ,
help = ' create new gpg signing key for this project ' )
2010-07-13 13:53:47 +02:00
@cmdln.option ( ' --extend ' , action = ' store_true ' , default = False ,
help = ' extend expiration date of the gpg public key for this project ' )
2009-10-16 16:12:55 +02:00
@cmdln.option ( ' --delete ' , action = ' store_true ' , default = False ,
help = ' delete the gpg signing key in this project ' )
2009-11-26 11:56:28 +01:00
@cmdln.option ( ' --notraverse ' , action = ' store_true ' , default = False ,
2019-11-11 22:09:47 +01:00
help = ' don \' t traverse projects upwards to find key ' )
2013-08-30 09:41:13 +02:00
@cmdln.option ( ' --sslcert ' , action = ' store_true ' , default = False ,
help = ' fetch SSL certificate instead of GPG key ' )
2009-10-16 16:12:55 +02:00
def do_signkey ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Manage Project Signing Key
2009-10-16 16:12:55 +02:00
2010-07-13 13:53:47 +02:00
osc signkey [ - - create | - - delete | - - extend ] < PROJECT >
2009-11-26 11:56:28 +01:00
osc signkey [ - - notraverse ] < PROJECT >
2009-10-16 16:12:55 +02:00
This command is for managing gpg keys . It shows the public key
2009-10-20 16:30:15 +02:00
by default . There is no way to download or upload the private
2009-10-16 16:12:55 +02:00
part of a key by design .
However you can create a new own key . You may want to consider
to sign the public key with your own existing key .
If a project has no key , the key from upper level project will
2019-05-24 13:42:47 +02:00
be used ( e . g . when dropping " KDE:KDE4:Community " key , the one from
2009-10-16 16:12:55 +02:00
" KDE:KDE4 " will be used ) .
2019-05-24 13:42:47 +02:00
WARNING : THE OLD KEY CANNOT BE RESTORED AFTER USING DELETE OR CREATE
2009-10-16 16:12:55 +02:00
"""
2010-04-30 17:13:21 +02:00
apiurl = self . get_api_url ( )
2009-10-16 16:12:55 +02:00
f = None
2009-11-26 11:56:28 +01:00
prj = None
if len ( args ) == 0 :
2022-10-07 17:25:33 +02:00
cwd = Path . cwd ( )
2010-08-20 14:34:41 +02:00
if is_project_dir ( cwd ) or is_package_dir ( cwd ) :
prj = store_read_project ( cwd )
2009-10-16 16:12:55 +02:00
if len ( args ) == 1 :
2022-05-10 14:49:21 +02:00
prj = self . _process_project_name ( args [ 0 ] )
2009-11-26 11:56:28 +01:00
if not prj :
2009-10-16 16:12:55 +02:00
raise oscerr . WrongArgs ( ' Please specify just the project ' )
if opts . create :
2009-10-20 16:30:15 +02:00
url = makeurl ( apiurl , [ ' source ' , prj ] , query = ' cmd=createkey ' )
f = http_POST ( url )
2010-07-13 13:53:47 +02:00
elif opts . extend :
2010-07-13 14:53:25 +02:00
url = makeurl ( apiurl , [ ' source ' , prj ] , query = ' cmd=extendkey ' )
2010-07-13 13:53:47 +02:00
f = http_POST ( url )
2009-10-16 16:12:55 +02:00
elif opts . delete :
2009-10-20 16:30:15 +02:00
url = makeurl ( apiurl , [ ' source ' , prj , " _pubkey " ] )
f = http_DELETE ( url )
2009-10-16 16:12:55 +02:00
else :
2021-04-28 13:42:06 +02:00
try :
# use current api, supporting fallback to higher project and server side scripts
query = { }
if opts . sslcert :
query [ ' withsslcert ' ] = 1
url = makeurl ( apiurl , [ ' source ' , prj , ' _keyinfo ' ] , query )
f = http_GET ( url )
except HTTPError as e :
# old way to do it
while True :
try :
url = makeurl ( apiurl , [ ' source ' , prj , ' _pubkey ' ] )
if opts . sslcert :
url = makeurl ( apiurl , [ ' source ' , prj , ' _project ' , ' _sslcert ' ] , ' meta=1 ' )
f = http_GET ( url )
break
except HTTPError as e :
l = prj . rsplit ( ' : ' , 1 )
# try key from parent project
if not opts . notraverse and len ( l ) > 1 and l [ 0 ] and l [ 1 ] and e . code == 404 :
print ( ' %s has no key, trying %s ' % ( prj , l [ 0 ] ) )
prj = l [ 0 ]
else :
raise
2009-10-16 16:12:55 +02:00
2010-03-17 15:28:10 +01:00
while True :
2023-06-16 08:45:51 +02:00
data = f . read ( 16384 )
if not data :
2010-03-17 15:28:10 +01:00
break
2023-06-16 08:45:51 +02:00
sys . stdout . buffer . write ( data )
2009-10-16 16:12:55 +02:00
2009-04-20 15:40:33 +02:00
@cmdln.option ( ' -m ' , ' --message ' ,
2014-02-05 17:50:31 +01:00
help = ' add MESSAGE to changes (do not open an editor) ' )
@cmdln.option ( ' -F ' , ' --file ' , metavar = ' FILE ' ,
help = ' read changes message from FILE (do not open an editor) ' )
2009-04-22 16:44:17 +02:00
@cmdln.option ( ' -e ' , ' --just-edit ' , action = ' store_true ' , default = False ,
2009-04-27 12:09:38 +02:00
help = ' just open changes (cannot be used with -m) ' )
2009-04-20 15:40:33 +02:00
def do_vc ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Edit the changes file
2009-04-20 15:40:33 +02:00
2009-04-22 16:44:17 +02:00
osc vc [ - m MESSAGE | - e ] [ filename [ . changes ] | path [ file_with_comment ] ]
2009-04-20 15:40:33 +02:00
If no < filename > is given , exactly one * . changes or * . spec file has to
be in the cwd or in path .
2010-01-02 12:25:37 +01:00
The email address used in . changes file is read from BuildService
2017-10-27 11:29:00 +02:00
instance , or should be defined in oscrc
2009-04-20 15:40:33 +02:00
[ https : / / api . opensuse . org / ]
user = login
pass = password
email = user @defined.email
or can be specified via mailaddr environment variable .
2022-09-16 02:55:29 +02:00
By default , osc vc opens the program specified by the EDITOR
environment variable ( and it uses Vim if that variable is not set ) with
a temporary file that should replace the * . changes file when saved by
the editor , or discarded otherwise .
2009-04-20 15:40:33 +02:00
"""
2014-02-05 17:50:31 +01:00
if opts . message and opts . file :
raise oscerr . WrongOptions ( ' \' --message \' and \' --file \' are mutually exclusive ' )
elif opts . message and opts . just_edit :
raise oscerr . WrongOptions ( ' \' --message \' and \' --just-edit \' are mutually exclusive ' )
elif opts . file and opts . just_edit :
raise oscerr . WrongOptions ( ' \' --file \' and \' --just-edit \' are mutually exclusive ' )
2010-08-20 13:00:57 +02:00
meego_style = False
if not args :
try :
fn_changelog = glob . glob ( ' *.changes ' ) [ 0 ]
2018-12-13 15:17:29 +01:00
fp = open ( fn_changelog )
2010-08-20 13:00:57 +02:00
titleline = fp . readline ( )
fp . close ( )
2022-07-28 19:11:29 +02:00
if re . match ( r ' ^ \ * \ W+(.+ \ W+ \ d { 1,2} \ W+20 \ d {2} ) \ W+(.+) \ W+<(.+)> \ W+(.+)$ ' , titleline ) :
2010-08-20 13:00:57 +02:00
meego_style = True
except IndexError :
pass
2009-04-20 15:40:33 +02:00
2014-10-01 14:45:48 +02:00
cmd_list = [ conf . config [ ' vc-cmd ' ] ]
2010-08-20 13:00:57 +02:00
if meego_style :
if not os . path . exists ( ' /usr/bin/vc ' ) :
2013-04-09 12:51:28 +02:00
print ( ' Error: you need meego-packaging-tools for /usr/bin/vc command ' , file = sys . stderr )
2010-08-20 13:00:57 +02:00
return 1
2010-08-23 10:08:09 +02:00
cmd_list = [ ' /usr/bin/vc ' ]
2014-10-01 14:45:48 +02:00
elif which ( cmd_list [ 0 ] ) is None :
print ( ' Error: vc ( \' %s \' ) command not found ' % cmd_list [ 0 ] , file = sys . stderr )
print ( ' Install the build package from http://download.opensuse.org/repositories/openSUSE:/Tools/ ' , file = sys . stderr )
return 1
2009-04-20 15:40:33 +02:00
2016-09-23 16:37:23 +02:00
if args and is_package_dir ( args [ 0 ] ) :
2022-10-14 14:25:54 +02:00
apiurl = osc_store . Store ( args [ 0 ] ) . apiurl
2016-09-23 16:37:23 +02:00
else :
apiurl = self . get_api_url ( )
2009-04-20 15:40:33 +02:00
2010-08-20 13:00:57 +02:00
if meego_style :
if opts . message or opts . just_edit :
2013-04-09 12:51:28 +02:00
print ( ' Warning: to edit MeeGo style changelog, opts will be ignored. ' , file = sys . stderr )
2010-08-20 13:00:57 +02:00
else :
if opts . message :
cmd_list . append ( " -m " )
cmd_list . append ( opts . message )
2014-02-05 17:50:31 +01:00
if opts . file :
2019-09-20 10:40:25 +02:00
if len ( args ) > 1 :
raise oscerr . WrongOptions ( ' --file and file_with_comment are mutually exclusive ' )
elif not os . path . isfile ( opts . file ) :
2014-02-05 17:50:31 +01:00
raise oscerr . WrongOptions ( ' \' %s \' : is no file ' % opts . file )
2019-09-20 10:40:25 +02:00
args = list ( args )
if not args :
2019-11-11 13:05:34 +01:00
args . append ( ' ' )
args . append ( opts . file )
2009-04-20 15:40:33 +02:00
2010-08-20 13:00:57 +02:00
if opts . just_edit :
cmd_list . append ( " -e " )
2009-04-22 16:44:17 +02:00
2010-08-23 10:08:09 +02:00
cmd_list . extend ( args )
2009-04-20 15:40:33 +02:00
2019-01-29 14:20:12 +01:00
vc_export_env ( apiurl )
2022-09-09 11:46:28 +02:00
vc = subprocess . Popen ( cmd_list )
2009-04-20 15:40:33 +02:00
vc . wait ( )
sys . exit ( vc . returncode )
2009-11-24 17:25:48 +01:00
@cmdln.option ( ' -f ' , ' --force ' , action = ' store_true ' ,
help = ' forces removal of entire package and its files ' )
2022-09-20 10:03:52 +02:00
@cmdln.option ( ' source ' )
@cmdln.option ( ' dest ' )
def do_mv ( self , subcmd , opts ) :
2022-01-19 15:13:55 +01:00
"""
Move SOURCE file to DEST and keep it under version control
2009-11-24 17:25:48 +01:00
"""
2022-09-20 10:03:52 +02:00
source = opts . source
dest = opts . dest
2009-11-24 17:25:48 +01:00
if not os . path . isfile ( source ) :
2015-09-10 11:25:14 +02:00
raise oscerr . WrongArgs ( " Source file ' %s ' does not exist or is not a file " % source )
2009-11-24 17:25:48 +01:00
if not opts . force and os . path . isfile ( dest ) :
2013-02-28 00:30:05 +01:00
raise oscerr . WrongArgs ( " Dest file ' %s ' already exists " % dest )
if os . path . isdir ( dest ) :
dest = os . path . join ( dest , os . path . basename ( source ) )
2022-09-13 16:34:54 +02:00
src_pkg = Package ( source )
tgt_pkg = Package ( dest )
2012-09-20 01:18:38 +02:00
if not src_pkg :
raise oscerr . NoWorkingCopy ( " Error: \" %s \" is not located in an osc working copy. " % os . path . abspath ( source ) )
if not tgt_pkg :
raise oscerr . NoWorkingCopy ( " Error: \" %s \" does not point to an osc working copy. " % os . path . abspath ( dest ) )
2009-11-24 17:25:48 +01:00
os . rename ( source , dest )
2012-09-20 01:18:38 +02:00
try :
2023-01-26 10:11:54 +01:00
tgt_pkg . addfile ( os . path . basename ( dest ) )
2012-09-20 01:18:38 +02:00
except oscerr . PackageFileConflict :
# file is already tracked
pass
2023-01-26 10:11:54 +01:00
src_pkg . delete_file ( os . path . basename ( source ) , force = opts . force )
2009-11-24 17:25:48 +01:00
2010-03-07 22:50:11 +01:00
@cmdln.option ( ' -d ' , ' --delete ' , action = ' store_true ' ,
help = ' delete option from config or reset option to the default) ' )
2010-10-16 12:24:21 +02:00
@cmdln.option ( ' -s ' , ' --stdin ' , action = ' store_true ' ,
help = ' indicates that the config value should be read from stdin ' )
@cmdln.option ( ' -p ' , ' --prompt ' , action = ' store_true ' ,
help = ' prompt for a value ' )
2019-08-29 11:35:34 +02:00
@cmdln.option ( ' --change-password ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' Change password ' )
2019-08-29 11:35:34 +02:00
@cmdln.option ( ' --select-password-store ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' Change the password store ' )
2010-10-16 12:24:21 +02:00
@cmdln.option ( ' --no-echo ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' prompt for a value but do not echo entered characters ' )
2010-12-18 17:16:43 +01:00
@cmdln.option ( ' --dump ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' dump the complete configuration (without \' pass \' and \' passx \' options) ' )
2010-12-18 17:16:43 +01:00
@cmdln.option ( ' --dump-full ' , action = ' store_true ' ,
2022-09-12 13:43:10 +02:00
help = ' dump the complete configuration (including \' pass \' and \' passx \' options) ' )
2010-12-18 17:16:43 +01:00
def do_config ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Get / set a config option
2010-03-07 22:50:11 +01:00
Examples :
osc config section option ( get current value )
osc config section option value ( set to value )
osc config section option - - delete ( delete option / reset to the default )
2019-08-29 16:42:09 +02:00
osc config section - - change - password ( changes the password in section " section " )
2010-10-16 12:24:21 +02:00
( section is either an apiurl or an alias or ' general ' )
2010-12-18 17:16:43 +01:00
osc config - - dump ( dump the complete configuration )
2010-03-07 22:50:11 +01:00
"""
2019-08-29 11:35:34 +02:00
prompt_value = ' Value: '
if opts . change_password :
opts . no_echo = True
opts . prompt = True
opts . select_password_store = True
2022-06-23 07:56:30 +02:00
prompt_value = ' Password : '
2019-08-29 11:35:34 +02:00
if len ( args ) != 1 :
raise oscerr . WrongArgs ( ' --change-password only needs the apiurl ' )
args = [ args [ 0 ] , ' pass ' ]
2021-07-14 11:19:08 +02:00
elif opts . select_password_store :
if len ( args ) != 1 :
raise oscerr . WrongArgs ( ' --select-password-store only needs the apiurl ' )
args = [ args [ 0 ] , ' pass ' ]
2010-12-18 17:16:43 +01:00
if len ( args ) < 2 and not ( opts . dump or opts . dump_full ) :
raise oscerr . WrongArgs ( ' Too few arguments ' )
elif opts . dump or opts . dump_full :
cp = conf . get_configParser ( conf . config [ ' conffile ' ] )
for sect in cp . sections ( ) :
2013-04-09 12:51:28 +02:00
print ( ' [ %s ] ' % sect )
2010-12-18 17:16:43 +01:00
for opt in sorted ( cp . options ( sect ) ) :
if sect == ' general ' and opt in conf . api_host_options or \
2022-09-12 14:15:34 +02:00
sect != ' general ' and opt not in conf . api_host_options :
2010-12-18 17:16:43 +01:00
continue
if opt in ( ' pass ' , ' passx ' ) and not opts . dump_full :
continue
val = str ( cp . get ( sect , opt , raw = True ) )
# special handling for continuation lines
val = ' \n ' . join ( val . split ( ' \n ' ) )
2013-04-09 12:51:28 +02:00
print ( ' %s = %s ' % ( opt , val ) )
print ( )
2010-12-18 17:16:43 +01:00
return
section , opt , val = args [ 0 ] , args [ 1 ] , args [ 2 : ]
2022-08-29 13:23:29 +02:00
if val and ( opts . delete or opts . stdin or opts . prompt or opts . no_echo ) :
2022-09-12 13:43:10 +02:00
raise oscerr . WrongOptions ( ' Sorry, \' --delete \' or \' --stdin \' or \' --prompt \' or \' --no-echo \' '
' and the specification of a value argument are mutually exclusive ' )
2010-10-16 12:24:21 +02:00
elif ( opts . prompt or opts . no_echo ) and opts . stdin :
raise oscerr . WrongOptions ( ' Sorry, \' --prompt \' or \' --no-echo \' and \' --stdin \' are mutually exclusive ' )
elif opts . stdin :
# strip lines
val = [ i . strip ( ) for i in sys . stdin . readlines ( ) if i . strip ( ) ]
2022-08-29 13:23:29 +02:00
if not val :
2010-10-16 12:24:21 +02:00
raise oscerr . WrongArgs ( ' error: read empty value from stdin ' )
elif opts . no_echo or opts . prompt :
if opts . no_echo :
2019-08-29 11:35:34 +02:00
inp = getpass . getpass ( prompt_value ) . strip ( )
2010-10-16 12:24:21 +02:00
else :
2019-08-29 11:35:34 +02:00
inp = raw_input ( prompt_value ) . strip ( )
2010-10-16 12:24:21 +02:00
if not inp :
raise oscerr . WrongArgs ( ' error: no value was entered ' )
val = [ inp ]
2019-08-29 11:35:34 +02:00
creds_mgr_descr = None
if opt == ' pass ' and opts . select_password_store :
creds_mgr_descr = conf . select_credentials_manager_descr ( )
orig_opt = opt
opt , newval = conf . config_set_option ( section , opt , ' ' . join ( val ) , delete = opts . delete , update = True , creds_mgr_descr = creds_mgr_descr )
2010-03-07 22:50:11 +01:00
if newval is None and opts . delete :
2013-04-09 12:51:28 +02:00
print ( ' \' %s \' : \' %s \' got removed ' % ( section , opt ) )
2010-03-07 22:50:11 +01:00
elif newval is None :
2013-04-09 12:51:28 +02:00
print ( ' \' %s \' : \' %s \' is not set ' % ( section , opt ) )
2010-03-07 22:50:11 +01:00
else :
2019-08-29 11:35:34 +02:00
if orig_opt == ' pass ' :
print ( ' Password has been changed. ' )
elif opts . no_echo :
2010-10-16 12:32:21 +02:00
# supress value
2013-04-09 12:51:28 +02:00
print ( ' \' %s \' : set \' %s \' ' % ( section , opt ) )
2010-10-16 12:32:21 +02:00
else :
2013-04-09 12:51:28 +02:00
print ( ' \' %s \' : \' %s \' is set to \' %s \' ' % ( section , opt , newval ) )
2009-11-24 17:25:48 +01:00
2022-09-20 10:04:04 +02:00
@cmdln.option ( ' file ' , nargs = ' + ' )
def do_revert ( self , subcmd , opts ) :
2022-01-19 15:13:55 +01:00
"""
Restore changed files or the entire working copy
2010-08-23 16:15:05 +02:00
Examples :
osc revert < modified file ( s ) >
2018-05-03 16:16:38 +02:00
osc revert .
2011-09-09 19:55:19 +02:00
Note : this only works for package working copies
2010-08-23 16:15:05 +02:00
"""
2022-09-20 10:04:04 +02:00
files = opts . file
2022-09-13 16:34:54 +02:00
pacs = Package . from_paths ( files )
2010-08-23 16:15:05 +02:00
for p in pacs :
2022-08-29 13:23:29 +02:00
if not p . todo :
2011-09-09 17:30:50 +02:00
p . todo = p . filenamelist + p . to_be_added
2010-08-23 16:15:05 +02:00
for f in p . todo :
p . revert ( f )
2010-09-08 18:56:15 +02:00
2010-12-07 20:35:12 +01:00
@cmdln.option ( ' --force-apiurl ' , action = ' store_true ' ,
help = ' ask once for an apiurl and force this apiurl for all inconsistent projects/packages ' )
2010-09-08 18:56:15 +02:00
def do_repairwc ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Try to repair an inconsistent working copy
2010-09-08 18:56:15 +02:00
Examples :
osc repairwc < path >
2022-01-19 15:13:55 +01:00
Note : if < path > is omitted it defaults to ' . ' ( < path > can be a project or package working copy )
2010-09-08 18:56:15 +02:00
Warning : This command might delete some files in the storedir
( . osc ) . Please check the state of the wc afterwards ( via ' osc status ' ) .
"""
2010-10-10 21:40:31 +02:00
def get_apiurl ( apiurls ) :
2022-09-12 13:43:10 +02:00
print ( ' No apiurl is defined for this working copy. \n '
' Please choose one from the following list (enter the number): ' )
2010-10-10 21:40:31 +02:00
for i in range ( len ( apiurls ) ) :
2013-04-09 12:51:28 +02:00
print ( ' %d ) %s ' % ( i , apiurls [ i ] ) )
2010-10-10 21:40:31 +02:00
num = raw_input ( ' > ' )
try :
num = int ( num )
except ValueError :
raise oscerr . WrongArgs ( ' \' %s \' is not a number. Aborting ' % num )
if num < 0 or num > = len ( apiurls ) :
raise oscerr . WrongArgs ( ' number \' %s \' out of range. Aborting ' % num )
return apiurls [ num ]
2010-09-08 18:56:15 +02:00
args = parseargs ( args )
2010-09-14 14:40:18 +02:00
pacs = [ ]
2013-04-09 11:25:19 +02:00
apiurls = list ( conf . config [ ' api_host_options ' ] . keys ( ) )
2010-12-07 20:35:12 +01:00
apiurl = ' '
2010-09-14 14:40:18 +02:00
for i in args :
if is_project_dir ( i ) :
2010-10-10 21:40:31 +02:00
try :
prj = Project ( i , getPackageList = False )
2013-04-09 11:27:02 +02:00
except oscerr . WorkingCopyInconsistent as e :
2010-12-07 20:35:12 +01:00
if ' _apiurl ' in e . dirty_files and ( not apiurl or not opts . force_apiurl ) :
2010-10-10 21:40:31 +02:00
apiurl = get_apiurl ( apiurls )
prj = Project ( i , getPackageList = False , wc_check = False )
prj . wc_repair ( apiurl )
2010-09-14 14:40:18 +02:00
for p in prj . pacs_have :
if p in prj . pacs_broken :
continue
try :
Package ( os . path . join ( i , p ) )
except oscerr . WorkingCopyInconsistent :
pacs . append ( os . path . join ( i , p ) )
elif is_package_dir ( i ) :
pacs . append ( i )
else :
2022-09-12 13:43:10 +02:00
print ( ' \' %s \' is neither a project working copy '
' nor a package working copy ' % i , file = sys . stderr )
2010-09-28 23:07:33 +02:00
for pdir in pacs :
2010-09-14 14:40:18 +02:00
try :
2010-09-28 23:07:33 +02:00
p = Package ( pdir )
2013-04-09 11:27:02 +02:00
except oscerr . WorkingCopyInconsistent as e :
2010-12-07 20:35:12 +01:00
if ' _apiurl ' in e . dirty_files and ( not apiurl or not opts . force_apiurl ) :
2010-10-10 21:40:31 +02:00
apiurl = get_apiurl ( apiurls )
2010-09-28 23:07:33 +02:00
p = Package ( pdir , wc_check = False )
p . wc_repair ( apiurl )
2013-04-09 12:51:28 +02:00
print ( ' done. Please check the state of the wc (via \' osc status %s \' ). ' % i )
2010-09-14 14:40:18 +02:00
else :
2013-04-09 12:51:28 +02:00
print ( ' osc: working copy \' %s \' is not inconsistent ' % i , file = sys . stderr )
2009-05-18 16:50:43 +02:00
2013-09-12 16:13:18 +02:00
@cmdln.option ( ' -n ' , ' --dry-run ' , action = ' store_true ' ,
help = ' print the results without actually removing a file ' )
def do_clean ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
Removes all untracked files from the package working copy
2013-09-12 16:13:18 +02:00
Examples :
osc clean < path >
2022-01-19 15:13:55 +01:00
Note : if < path > is omitted it defaults to ' . ' ( < path > has to be a package working copy )
2013-09-12 16:13:18 +02:00
Warning : This command removes all files with status ' ? ' .
"""
pacs = parseargs ( args )
# do a sanity check first
for pac in pacs :
if not is_package_dir ( pac ) :
raise oscerr . WrongArgs ( ' \' %s \' is no package working copy ' % pac )
for pdir in pacs :
p = Package ( pdir )
pdir = getTransActPath ( pdir )
2017-08-03 17:21:20 +02:00
todo = [ fname for st , fname in p . get_status ( ) if st == ' ? ' ]
for fname in p . excluded :
# there might be some rare cases, where an excluded file has
# not state '?'
if os . path . isfile ( fname ) and p . status ( fname ) == ' ? ' :
todo . append ( fname )
for filename in todo :
2013-09-12 16:13:18 +02:00
print ( ' Removing: %s ' % os . path . join ( pdir , filename ) )
if not opts . dry_run :
os . unlink ( os . path . join ( p . absdir , filename ) )
2017-03-02 11:03:39 +01:00
@cmdln.option ( ' -c ' , ' --comment ' ,
2022-09-12 13:43:10 +02:00
help = ' comment text ' , metavar = ' COMMENT ' )
2017-03-02 11:03:39 +01:00
@cmdln.option ( ' -p ' , ' --parent ' ,
2022-09-12 13:43:10 +02:00
help = ' reply to comment with parent id ' , metavar = ' PARENT ' )
2017-03-02 11:03:39 +01:00
def do_comment ( self , subcmd , opts , * args ) :
2022-01-19 15:13:55 +01:00
"""
List / create / delete comments
2017-03-02 11:03:39 +01:00
On create :
If - p is given a reply to the ID is created . Otherwise
a toplevel comment is created .
If - c is not given the default editor will be opened and
you can type your comment
usage :
osc comment list package PROJECT PACKAGE
osc comment list project PROJECT
osc comment list request REQUEST_ID
osc comment create [ - p PARENT_ID ] [ - c COMMENT ] package PROJECT PACKAGE
osc comment create [ - p PARENT_ID ] [ - c COMMENT ] project PROJECT
osc comment create [ - p PARENT_ID ] [ - c COMMENT ] request REQUEST_ID
osc comment delete ID
"""
comment = None
args = slash_split ( args )
apiurl = self . get_api_url ( )
if len ( args ) < 2 :
2022-01-19 15:13:55 +01:00
self . argparse_error ( " Incorrect number of arguments. " )
2017-03-02 11:03:39 +01:00
cmds = [ ' list ' , ' create ' , ' delete ' ]
if args [ 0 ] not in cmds :
2022-09-12 13:43:10 +02:00
raise oscerr . WrongArgs ( ' Unknown comment action %s . Choose one of %s . '
% ( args [ 0 ] , ' , ' . join ( cmds ) ) )
2017-03-02 11:03:39 +01:00
comment_targets = [ ' package ' , ' project ' , ' request ' ]
if args [ 0 ] != ' delete ' and args [ 1 ] not in comment_targets :
2022-09-12 13:43:10 +02:00
raise oscerr . WrongArgs ( ' Unknown comment target %s . Choose one of %s . '
% ( args [ 1 ] , ' , ' . join ( comment_targets ) ) )
2017-03-02 11:03:39 +01:00
if args [ 1 ] == ' package ' and len ( args ) != 4 :
raise oscerr . WrongArgs ( ' Please use PROJECT PACKAGE ' )
elif args [ 1 ] == ' project ' and len ( args ) != 3 :
raise oscerr . WrongArgs ( ' Please use PROJECT ' )
elif args [ 1 ] == ' request ' and len ( args ) != 3 :
raise oscerr . WrongArgs ( ' Please use REQUEST ' )
elif args [ 0 ] == ' delete ' and len ( args ) != 2 :
raise oscerr . WrongArgs ( ' Please use COMMENT_ID ' )
if not opts . comment and args [ 0 ] == ' create ' :
comment = edit_text ( )
else :
comment = opts . comment
if args [ 0 ] == ' list ' :
print_comments ( apiurl , args [ 1 ] , * args [ 2 : ] )
elif args [ 0 ] == ' create ' :
result = create_comment ( apiurl , args [ 1 ] , comment ,
* args [ 2 : ] , parent = opts . parent )
print ( result )
elif args [ 0 ] == ' delete ' :
result = delete_comment ( apiurl , args [ 1 ] )
print ( result )
2013-06-13 19:57:34 +02:00
def _load_plugins ( self ) :
2023-10-13 13:46:44 +02:00
if IN_VENV :
_private . print_msg ( " Running in virtual environment, skipping loading legacy plugins. " , print_to = " stderr " )
return
2013-06-13 19:57:34 +02:00
plugin_dirs = [
' /usr/lib/osc-plugins ' ,
' /usr/local/lib/osc-plugins ' ,
2022-03-18 18:21:16 +01:00
os . path . expanduser ( ' ~/.local/lib/osc-plugins ' ) ,
2013-06-13 19:57:34 +02:00
os . path . expanduser ( ' ~/.osc-plugins ' ) ]
for plugin_dir in plugin_dirs :
if not os . path . isdir ( plugin_dir ) :
continue
2017-03-14 13:39:04 +01:00
sys . path . append ( plugin_dir )
2007-06-29 20:26:30 +02:00
for extfile in os . listdir ( plugin_dir ) :
if not extfile . endswith ( ' .py ' ) :
continue
2011-03-21 18:53:05 +01:00
try :
2022-08-22 15:45:25 +02:00
modname = " osc.plugins. " + os . path . splitext ( extfile ) [ 0 ]
spec = importlib . util . spec_from_file_location ( modname , os . path . join ( plugin_dir , extfile ) )
mod = importlib . util . module_from_spec ( spec )
sys . modules [ modname ] = mod
spec . loader . exec_module ( mod )
2013-06-13 19:57:34 +02:00
# restore the old exec semantic
mod . __dict__ . update ( globals ( ) )
for name in dir ( mod ) :
2013-08-15 17:26:07 +02:00
data = getattr ( mod , name )
# Add all functions (which are defined in the imported module)
2013-07-23 12:10:31 +02:00
# to the class (filtering only methods which start with "do_"
2013-08-15 17:26:07 +02:00
# breaks the old behavior).
# Also add imported modules (needed for backward compatibility).
# New plugins should not use "self.<imported modname>.<something>"
# to refer to the imported module. Instead use
# "<imported modname>.<something>".
if ( inspect . isfunction ( data ) and inspect . getmodule ( data ) == mod
2022-09-12 13:43:10 +02:00
or inspect . ismodule ( data ) ) :
2013-08-15 17:26:07 +02:00
setattr ( self . __class__ , name , data )
2014-05-06 18:51:12 +02:00
except ( SyntaxError , NameError , ImportError ) as e :
2022-08-31 12:05:33 +02:00
if os . environ . get ( ' OSC_PLUGIN_FAIL_IGNORE ' ) :
2013-06-06 11:55:50 +02:00
print ( " %s : %s \n " % ( os . path . join ( plugin_dir , extfile ) , e ) , file = sys . stderr )
2011-03-21 18:53:05 +01:00
else :
traceback . print_exc ( file = sys . stderr )
2013-06-06 11:55:50 +02:00
print ( ' \n %s : %s ' % ( os . path . join ( plugin_dir , extfile ) , e ) , file = sys . stderr )
2013-04-09 12:51:28 +02:00
print ( " \n Try ' env OSC_PLUGIN_FAIL_IGNORE=1 osc ... ' " , file = sys . stderr )
2011-03-21 18:53:05 +01:00
sys . exit ( 1 )
2013-06-13 19:57:34 +02:00
# fini!
###############################################################################
2007-06-29 20:26:30 +02:00
2010-02-25 09:52:47 +01:00
# vim: sw=4 et