core

This is the osc core module.

basic structures

class osc.core.AbstractState(tag)

Base class which represents state-like objects (<review />, <state />).

get_node_attrs()
Returns:

attributes for the tag/element

get_node_name()
Returns:

tag/element name

get_comment()
Returns:

data from <comment /> tag

get_description()
Returns:

data from <description /> tag

to_xml()
Returns:

object serialized to XML

to_str()
Returns:

object serialized to pretty-printed XML

class osc.core.ReviewState(review_node)

Represents the review state in a request

get_node_attrs()
Returns:

attributes for the tag/element

get_comment()
Returns:

data from <comment /> tag

get_description()
Returns:

data from <description /> tag

class osc.core.RequestHistory(history_node)

Represents a history element of a request

get_node_attrs()
Returns:

attributes for the tag/element

get_description()
Returns:

data from <description /> tag

get_comment()
Returns:

data from <comment /> tag

class osc.core.RequestState(state_node)

Represents the state of a request

get_node_attrs()
Returns:

attributes for the tag/element

get_comment()
Returns:

data from <comment /> tag

get_description()
Returns:

data from <description /> tag

class osc.core.Action(type, **kwargs)

Represents an <action /> element of a Request. This class is quite common so that it can be used for all different action types.

Note

Instances only provide attributes for their specific type.

Examples:

r = Action('set_bugowner', tgt_project='foo', person_name='buguser')
# available attributes: r.type (== 'set_bugowner'), r.tgt_project (== 'foo'), r.tgt_package (is None)
r.to_str() ->
<action type="set_bugowner">
  <target project="foo" />
  <person name="buguser" />
</action>

r = Action('delete', tgt_project='foo', tgt_package='bar')
# available attributes: r.type (== 'delete'), r.tgt_project (== 'foo'), r.tgt_package (=='bar')
r.to_str() ->
<action type="delete">
  <target package="bar" project="foo" />
</action>
to_xml()

Serialize object to XML. The xml tag names and attributes are constructed from the instance’s attributes.

Returns:

object serialized to XML

Example:

self.group_name  -> tag name is "group", attribute name is "name"
self.src_project -> tag name is "source" (translated via prefix_to_elm dict),
                    attribute name is "project"

Attributes prefixed with opt_ need a special handling, the resulting xml should look like this: opt_updatelink -> <options><updatelink>value</updatelink></options>. Attributes which are None will be skipped.

to_str()
Returns:

object serialized to pretty-printed XML

static from_xml(action_node, apiurl=None)

create action from XML

class osc.core.Request

Represents a request (<request />)

read(root, apiurl=None)

read in a request

add_action(type, **kwargs)

add a new action to the request

get_actions(*types) List[Action]

get all actions with a specific type (if types is empty return all actions)

Return type:

List[Action]

to_xml()
Returns:

object serialized to XML

to_str()
Returns:

object serialized to pretty-printed XML

accept_at_in_hours(hours)

set auto accept_at time

static format_review(review, show_srcupdate=False)

format a review depending on the reviewer’s type. A dict which contains the formatted str’s is returned.

format_action(action: Action, show_srcupdate=False)

format an action depending on the action’s type. A dict which contains the formatted str’s is returned.

Parameters:

action (Action)

list_view()

return “list view” format

create(apiurl: str, addrevision=False, enforce_branching=False)

create a new request

Parameters:

apiurl (str)

osc.core.shorttime(t)

format time as Apr 02 18:19 or Apr 02 2005 depending on whether it is in the current year

osc.core.parse_disturl(disturl: str)

Parse a disturl, returns tuple (apiurl, project, source, repository, revision), else raises an oscerr.WrongArgs exception

Parameters:

disturl (str)

osc.core.parse_buildlogurl(buildlogurl: str)

Parse a build log url, returns a tuple (apiurl, project, package, repository, arch), else raises oscerr.WrongArgs exception

Parameters:

buildlogurl (str)

osc.core.slash_split(args)

Split command line arguments like ‘foo/bar’ into ‘foo’ ‘bar’. This is handy to allow copy/paste a project/package combination in this form.

Leading and trailing slashes are removed before the split, because the split could otherwise give additional empty strings.

osc.core.expand_proj_pack(args, idx=0, howmany=0)

looks for occurance of ‘.’ at the position idx. If howmany is 2, both proj and pack are expanded together using the current directory, or none of them if not possible. If howmany is 0, proj is expanded if possible, then, if there is no idx+1 element in args (or args[idx+1] == ‘.’), pack is also expanded, if possible. If howmany is 1, only proj is expanded if possible.

If args[idx] does not exist, an implicit ‘.’ is assumed. If not enough elements up to idx exist, an error is raised.

See also parseargs(args), slash_split(args), Package.from_paths(args) All these need unification, somehow.

osc.core.findpacs(files, progress_obj=None, fatal=True)

collect Package objects belonging to the given files and make sure each Package is returned only once

osc.core.parseargs(list_of_args)

Convenience method osc’s commandline argument parsing.

If called with an empty tuple (or list), return a list containing the current directory. Otherwise, return a list of the arguments.

osc.core.pathjoin(a, *p)

Join two or more pathname components, inserting ‘/’ as needed. Cut leading ./

class osc.core.UrlQueryArray(iterable=(), /)

Passing values wrapped in this object causes makeurl() to encode the list in Ruby on Rails compatible way (adding square brackets to the parameter names): {“file”: UrlQueryArray([“foo”, “bar”])} -> &file[]=foo&file[]=bar

osc.core.makeurl(apiurl: str, path: List[str], query: dict | None = None)

Construct an URL based on the given arguments.

Parameters:
  • apiurl (str) – URL to the API server.

  • path (List[str]) – List of URL path components.

  • query (dict | None) – Optional dictionary with URL query data. Values can be: str, int, bool, [str], [int]. Items with value equal to None will be skipped.

osc.core.meta_get_filelist(apiurl: str, prj: str, package: str, verbose=False, expand=False, revision=None, meta=False, deleted=False)

return a list of file names, or a list File() instances if verbose=True

Parameters:
  • apiurl (str)

  • prj (str)

  • package (str)

class osc.core.metafile(url, input, change_is_required=False, file_ext='.xml', method=None)

metafile that can be manipulated and is stored back after manipulation.

osc.core.parse_meta_to_string(data: bytes | list | Iterable) str

Converts the output of meta_exists into a string value

Parameters:

data (bytes | list | Iterable)

Return type:

str

osc.core.read_meta_from_spec(specfile, *args)

Read tags and sections from spec file. To read out a tag the passed argument mustn’t end with a colon. To read out a section the passed argument must start with a ‘%’. This method returns a dictionary which contains the requested data.

osc.core.get_user_projpkgs_request_list(apiurl: str, user, req_state=('new', 'review', 'declined'), req_type=None, exclude_projects=None, projpkgs=None)

OBSOLETE: user involved request search is supported by OBS 2.2 server side in a better way Return all running requests for all projects/packages where is user is involved

Parameters:

apiurl (str)

osc.core.get_user_data(apiurl: str, user: str, *tags)

get specified tags from the user meta

Parameters:
  • apiurl (str)

  • user (str)

osc.core.binary(s)

return True if a string is binary data using diff’s heuristic

osc.core.binary_file(fn)

read 4096 bytes from a file named fn, and call binary() on the data

osc.core.get_source_file_diff(dir, filename, rev, oldfilename=None, olddir=None, origfilename=None)

This methods diffs oldfilename against filename (so filename will be shown as the new file). The variable origfilename is used if filename and oldfilename differ in their names (for instance if a tempfile is used for filename etc.)

osc.core.get_request_issues(apiurl: str, reqid)

gets a request xml with the issues for the request inside and creates a list ‘issue_list’ with a dict of the relevant information for the issues. This only works with bugtrackers we can access, like buzilla.o.o

Parameters:

apiurl (str)

osc.core.submit_action_diff(apiurl: str, action: Action)

diff a single submit action

Parameters:
  • apiurl (str)

  • action (Action)

osc.core.make_dir(apiurl: str, project: str, package: str, pathname=None, prj_dir=None, package_tracking=True, pkg_path=None)

creates the plain directory structure for a package dir. The ‘apiurl’ parameter is needed for the project dir initialization. The ‘project’ and ‘package’ parameters specify the name of the project and the package. The optional ‘pathname’ parameter is used for printing out the message that a new dir was created (default: ‘prj_dir/package’). The optional ‘prj_dir’ parameter specifies the path to the project dir (default: ‘project’). If pkg_path is not None store the package’s content in pkg_path (no project structure is created)

Parameters:
  • apiurl (str)

  • project (str)

  • package (str)

osc.core.replace_pkg_meta(pkgmeta, new_name: str, new_prj: str, keep_maintainers=False, dst_userid=None, keep_develproject=False, keep_lock: bool = False)

update pkgmeta with new new_name and new_prj and set calling user as the only maintainer (unless keep_maintainers is set). Additionally remove the develproject entry (<devel />) unless keep_develproject is true.

Parameters:
  • new_name (str)

  • new_prj (str)

  • keep_lock (bool)

convert a package with a _link + project.diff to a branch

Parameters:
  • apiurl (str)

  • project (str)

  • package (str)

create a linked package
  • “src” is the original package

  • “dst” is the “link” package that we are creating here

Parameters:
  • src_project (str)

  • src_package (str)

  • dst_project (str)

  • dst_package (str)

  • force (bool)

osc.core.aggregate_pac(src_project: str, src_package: str, dst_project: str, dst_package: str, repo_map: dict | None = None, disable_publish=False, nosources=False, repo_check=True)
aggregate package
  • “src” is the original package

  • “dst” is the “aggregate” package that we are creating here

  • “map” is a dictionary SRC => TARGET repository mappings

  • “repo_check” determines if presence of repos in the source and destination repos is checked

Parameters:
  • src_project (str)

  • src_package (str)

  • dst_project (str)

  • dst_package (str)

  • repo_map (dict | None)

osc.core.attribute_branch_pkg(apiurl: str, attribute: str, maintained_update_project_attribute, package: str, targetproject: str, return_existing=False, force=False, noaccess=False, add_repositories=False, dryrun=False, nodevelproject=False, maintenance=False)

Branch packages defined via attributes (via API call)

Parameters:
  • apiurl (str)

  • attribute (str)

  • package (str)

  • targetproject (str)

osc.core.branch_pkg(apiurl: str, src_project: str, src_package: str, nodevelproject=False, rev=None, linkrev=None, target_project: str | None = None, target_package=None, return_existing=False, msg='', force=False, noaccess=False, add_repositories=False, add_repositories_block=None, add_repositories_rebuild=None, extend_package_names=False, missingok=False, maintenance=False, newinstance=False, disable_build=False)

Branch a package (via API call)

Parameters:
  • apiurl (str)

  • src_project (str)

  • src_package (str)

  • target_project (str | None)

osc.core.copy_pac(src_apiurl: str, src_project: str, src_package: str, dst_apiurl: str, dst_project: str, dst_package: str, client_side_copy=False, keep_maintainers=False, keep_develproject=False, expand=False, revision=None, comment=None, force_meta_update=None, keep_link=None)

Create a copy of a package.

Copying can be done by downloading the files from one package and commit them into the other by uploading them (client-side copy) – or by the server, in a single api call.

Parameters:
  • src_apiurl (str)

  • src_project (str)

  • src_package (str)

  • dst_apiurl (str)

  • dst_project (str)

  • dst_package (str)

osc.core.get_distributions(apiurl: str)

Returns list of dicts with headers ‘distribution’, ‘project’, ‘repository’, ‘reponame’

Parameters:

apiurl (str)

osc.core.format_results(results, format)

apply selected format on each dict in results and return it as a list of strings

osc.core.get_results(apiurl: str, project: str, package: str, verbose=False, printJoin='', *args, **kwargs)

returns list of/or prints a human readable status for the specified package

Parameters:
  • apiurl (str)

  • project (str)

  • package (str)

osc.core.get_package_results(apiurl: str, project: str, package: str | None = None, wait=False, *args, **kwargs)

generator that returns a the package results as an xml structure

Parameters:
  • apiurl (str)

  • project (str)

  • package (str | None)

osc.core.streamfile(url: str, http_meth=<function http_GET>, bufsize=8192, data=None, progress_obj=None, text=None)

performs http_meth on url and read bufsize bytes from the response until EOF is reached. After each read bufsize bytes are yielded to the caller. A spezial usage is bufsize=”line” to read line by line (text).

Parameters:

url (str)

osc.core.buildlog_strip_time(data)

Strips the leading build time from the log

osc.core.print_buildlog(apiurl: str, prj: str, package: str, repository: str, arch: str, offset=0, strip_time=False, last=False, lastsucceeded=False, output_buffer=None)

prints out the buildlog on stdout

Parameters:
  • apiurl (str)

  • prj (str)

  • package (str)

  • repository (str)

  • arch (str)

osc.core.create_pbuild_config(apiurl: str, project: str, repository: str, arch: str, project_dir)

This is always replacing a possible exiting config for now we could extend the _pbuild file easily, but what should we do with multiple instances of the _config?

Parameters:
  • apiurl (str)

  • project (str)

  • repository (str)

  • arch (str)

osc.core.parseRevisionOption(string, allow_md5=True)

returns a tuple which contains the revisions

osc.core.checkRevision(prj: str, pac: str, revision, apiurl: str | None = None, meta=False)

check if revision is valid revision, i.e. it is not larger than the upstream revision id

Parameters:
  • prj (str)

  • pac (str)

  • apiurl (str | None)

osc.core.build_table(col_num, data=None, headline=None, width=1, csv=False)

This method builds a simple table.

Example:

build_table(2, ['foo', 'bar', 'suse', 'osc'], ['col1', 'col2'], 2)

col1  col2
foo   bar
suse  osc
osc.core.xpath_join(expr, new_expr, op='or', inner=False, nexpr_parentheses=False)

Join two xpath expressions. If inner is False expr will be surrounded with parentheses (unless it’s not already surrounded). If nexpr_parentheses is True new_expr will be surrounded with parentheses.

osc.core.search(apiurl: str, queries=None, **kwargs)

Perform a search request. The requests are constructed as follows: kwargs = {‘kind1’ => xpath1, ‘kind2’ => xpath2, …, ‘kindN’ => xpathN} GET /search/kind1?match=xpath1 … GET /search/kindN?match=xpathN

queries is a dict of optional http query parameters, which are passed to the makeurl call, of the form {kindI1: dict_or_list, …, kindIL: dict_or_list}, where kind_i1 to kind_iL are keys of kwargs.

Parameters:

apiurl (str)

osc.core.owner(apiurl: str, search_term=None, mode='binary', attribute=None, project=None, usefilter=None, devel=None, limit=None, binary=None)

Perform a binary package owner search. This is supported since OBS 2.4.

Parameters:

apiurl (str)

osc.core.unpack_srcrpm(srpm, dir, *files)

This method unpacks the passed srpm into the passed dir. If arguments are passed to the ‘files’ tuple only this files will be unpacked.

osc.core.is_rpm(f)

check if the named file is an RPM package

osc.core.is_srcrpm(f)

check if the named file is a source RPM

osc.core.addPerson(apiurl: str, prj: str, pac: str, user: str, role='maintainer')

add a new person to a package or project

Parameters:
  • apiurl (str)

  • prj (str)

  • pac (str)

  • user (str)

osc.core.delPerson(apiurl: str, prj: str, pac: str, user: str, role='maintainer')

delete a person from a package or project

Parameters:
  • apiurl (str)

  • prj (str)

  • pac (str)

  • user (str)

osc.core.setBugowner(apiurl: str, prj: str, pac: str, user=None, group=None)

delete all bugowners (user and group entries) and set one new one in a package or project

Parameters:
  • apiurl (str)

  • prj (str)

  • pac (str)

osc.core.createPackageDir(pathname, prj_obj=None)

create and initialize a new package dir in the given project. prj_obj can be a Project() instance.

osc.core.getPrjPacPaths(path)

returns the path for a project and a package from path. This is needed if you try to add or delete packages:

Examples:

osc add pac1/: prj_dir = CWD;
               pac_dir = pac1
osc add /path/to/pac1:
               prj_dir = path/to;
               pac_dir = pac1
osc add /path/to/pac1/file
               => this would be an invalid path
                  the caller has to validate the returned
                  path!
osc.core.getTransActPath(pac_dir)

returns the path for the commit and update operations/transactions. Normally the “dir” attribute of a Package() object will be passed to this method.

osc.core.get_commit_message_template(pac)

Read the difference in .changes file(s) and put them as a template to commit message.

osc.core.print_request_list(apiurl, project, package=None, states=('new', 'review'), force=False)

prints list of pending requests for the specified project/package if “check_for_request_on_action” is enabled in the config or if “force” is set to True

osc.core.request_interactive_review(apiurl, request, initial_cmd='', group=None, ignore_reviews=False, source_buildstatus=False)

review the request interactively

osc.core.edit_submitrequest(apiurl, project, orequest, new_request=None)

edit a submit action from orequest/new_request

osc.core.get_user_projpkgs(apiurl, user, role=None, exclude_projects=None, proj=True, pkg=True, maintained=False, metadata=False)

Return all project/packages where user is involved.

osc.core.run_external(filename, *args, **kwargs)

Executes the program filename via subprocess.call.

*args are additional arguments which are passed to the program filename. **kwargs specify additional arguments for the subprocess.call function. if no args are specified the plain filename is passed to subprocess.call (this can be used to execute a shell command). Otherwise [filename] + list(args) is passed to the subprocess.call function.

osc.core.return_external(filename, *args, **kwargs)

Executes the program filename via subprocess.check_output.

*args are additional arguments which are passed to the program filename. **kwargs specify additional arguments for the subprocess.check_output function. if no args are specified the plain filename is passed to subprocess.check_output (this can be used to execute a shell command). Otherwise [filename] + list(args) is passed to the subprocess.check_output function.

Returns the output of the command.

osc.core.filter_role(meta, user, role)

remove all project/package nodes if no person node exists where @userid=user and @role=role

osc.core.find_default_project(apiurl: str | None = None, package: str | None = None)

look though the list of conf.config[‘getpac_default_project’] and find the first project where the given package exists in the build service.

Parameters:
  • apiurl (str | None)

  • package (str | None)

osc.core.utime(filename, arg, ignore_einval=True)

wrapper around os.utime which ignore errno EINVAL by default

osc.core.which(name: str)

Searches “name” in PATH.

Parameters:

name (str)

class osc.core.File(name, md5, size, mtime, skipped=False)

represent a file, including its metadata

class osc.core.Serviceinfo

Source service content

read(serviceinfo_node, append=False)

read in the source services <services> element passed as elementtree node.

class osc.core.Linkinfo

linkinfo metadata (which is part of the xml representing a directory)

read(linkinfo_node)

read in the linkinfo metadata from the <linkinfo> element passed as elementtree node. If the passed element is None, the method does nothing.

Returns:

True if the linkinfo is not empty, otherwise False

isexpanded()
Returns:

True if the package is an expanded link

haserror()
Returns:

True if the link is in error state (could not be applied)

class osc.core.Project(dir, getPackageList=True, progress_obj=None, wc_check=True)

Represent a checked out project directory, holding packages.

Attributes:
dir

The directory path containing the project.

name

The name of the project.

apiurl

The endpoint URL of the API server.

pacs_available

List of names of packages available server-side. This is only populated if getPackageList is set to True in the constructor.

pacs_have

List of names of packages which exist server-side and exist in the local project working copy (if ‘do_package_tracking’ is disabled). If ‘do_package_tracking’ is enabled it represents the list names of packages which are tracked in the project working copy (that is it might contain packages which exist on the server as well as packages which do not exist on the server (for instance if the local package was added or if the package was removed on the server-side)).

pacs_excluded

List of names of packages in the local project directory which are excluded by the exclude_glob configuration variable. Only set if do_package_tracking is enabled.

pacs_unvers

List of names of packages in the local project directory which are not tracked. Only set if do_package_tracking is enabled.

pacs_broken

List of names of packages which are tracked but do not exist in the local project working copy. Only set if do_package_tracking is enabled.

pacs_missing

List of names of packages which exist server-side but are not expected to exist in the local project directory.

read_packages()

Returns an xml.etree.ElementTree object representing the parsed contents of the project’s .osc/_packages XML file.

commitNewPackage(pac, msg='', files=None, verbose=False, skip_local_service_run=False)

creates and commits a new package if it does not exist on the server

commitDelPackage(pac, force=False)

deletes a package on the server and in the working copy

commitExtPackage(pac, msg, files=None, verbose=False, skip_local_service_run=False)

commits a package from an external project