Source code for renku.core.models.refs
# -*- coding: utf-8 -*-
#
# Copyright 2018-2020- Swiss Data Science Center (SDSC)
# A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and
# Eidgenössische Technische Hochschule Zürich (ETHZ).
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Manage names of Renku objects."""
import os
import subprocess
from pathlib import Path
import attr
from renku.core import errors
[docs]@attr.s(slots=True)
class LinkReference:
"""Manage linked object names."""
client = attr.ib()
name = attr.ib()
REFS = "refs"
"""Define a name of the folder with references in the Renku folder."""
[docs] @name.validator
def name_validator(self, attribute, value):
"""Validate reference name."""
if not self.check_ref_format(value):
raise errors.ParameterError('The reference name "{0}" is not valid.'.format(value))
@property
def path(self):
"""Return full reference path."""
return self.client.renku_path / self.REFS / self.name
@property
def reference(self):
"""Return the path we point to relative to the client."""
return self.path.resolve()
[docs] def delete(self):
"""Delete the reference at the given path."""
return self.path.unlink()
[docs] def set_reference(self, reference):
"""Set ourselves to the given reference path."""
reference_path = Path(reference).resolve().absolute()
reference_path.relative_to(self.client.path)
self.path.parent.mkdir(parents=True, exist_ok=True)
os.symlink(os.path.relpath(str(reference_path), start=str(self.path.parent)), str(self.path))
[docs] @classmethod
def iter_items(cls, client, common_path=None):
"""Find all references in the repository."""
refs_path = path = client.renku_path / cls.REFS
if common_path:
path = path / common_path
for name in path.rglob("*"):
if name.is_dir():
continue
yield cls(client=client, name=str(name.relative_to(refs_path)))
[docs] @classmethod
def create(cls, client, name, force=False):
"""Create symlink to object in reference path."""
ref = cls(client=client, name=name)
path = ref.path
if os.path.lexists(path):
if not force:
raise OSError(str(path))
else:
ref.delete()
return ref
[docs] def rename(self, new_name, force=False):
"""Rename self to a new name."""
new_ref = self.create(client=self.client, name=new_name, force=force)
new_ref.set_reference(self.reference)
self.delete()
return new_ref