Change-Id: If433b9b73e12f1547ff21e1d4968fac29143f272
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
Stephen Finucane
2025-06-27 09:34:57 +01:00
parent f42dccb0a0
commit 2f112eac23
17 changed files with 379 additions and 201 deletions

28
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,28 @@
---
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
- id: mixed-line-ending
args: ['--fix', 'lf']
exclude: '.*\.(svg)$'
- id: check-byte-order-marker
- id: check-executables-have-shebangs
- id: check-merge-conflict
- id: debug-statements
- id: check-yaml
files: .*\.(yaml|yml)$
exclude: '^zuul.d/.*$'
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.12.1
hooks:
- id: ruff-check
args: ['--fix', '--unsafe-fixes']
- id: ruff-format
- repo: https://opendev.org/openstack/hacking
rev: 7.0.0
hooks:
- id: hacking
exclude: '^(doc|releasenotes|tools)/.*$'
additional_dependencies: []

28
doc/source/conf.py Executable file → Normal file
View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# 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
@@ -16,6 +15,7 @@ import os
import sys
sys.path.insert(0, os.path.abspath('../..'))
# -- General configuration ----------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
@@ -23,13 +23,8 @@ sys.path.insert(0, os.path.abspath('../..'))
extensions = [
'sphinx.ext.autodoc',
'openstackdocstheme',
#'sphinx.ext.intersphinx',
]
# autodoc generation is a bit aggressive and a nuisance when doing heavy
# text edit cycles.
# execute "export SPHINX_DEBUG=1" in your terminal to disable
# The suffix of source filenames.
source_suffix = '.rst'
@@ -37,8 +32,8 @@ source_suffix = '.rst'
master_doc = 'index'
# General information about the project.
project = u'os-service-types'
copyright = u'2017, OpenStack Developers'
project = 'os-service-types'
copyright = '2017-, OpenStack Developers'
# openstackdocstheme options
openstackdocs_repo_name = 'openstack/os-service-types'
@@ -64,18 +59,15 @@ pygments_style = 'native'
# html_static_path = ['static']
html_theme = 'openstackdocs'
# Output file base name for HTML help builder.
htmlhelp_basename = '%sdoc' % project
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass
# [howto/manual]).
latex_documents = [
('index',
'%s.tex' % project,
u'%s Documentation' % project,
u'OpenStack Foundation', 'manual'),
(
'index',
f'{project}.tex',
f'{project} Documentation',
'OpenStack Foundation',
'manual',
),
]
# Example configuration for intersphinx: refer to the Python standard library.
#intersphinx_mapping = {'http://docs.python.org/': None}

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
# 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

View File

@@ -22,10 +22,8 @@ DATA_DIR = os.path.dirname(__file__)
def read_data(filename):
"""Return data that is shipped inside the Python package.
"""
"""Return data that is shipped inside the Python package."""
filepath = os.path.join(DATA_DIR, filename)
with open(filepath, 'r') as fd:
with open(filepath) as fd:
return json.load(fd)

View File

@@ -29,7 +29,7 @@ def _normalize_type(service_type):
return service_type.replace('_', '-')
class ServiceTypes(object):
class ServiceTypes:
"""Encapsulation of the OpenStack Service Types Authority data.
The Service Types Authority data will be either pulled from its remote
@@ -57,7 +57,8 @@ class ServiceTypes(object):
def __init__(self, session=None, only_remote=False, warn=False):
if not session and only_remote:
raise ValueError(
"only_remote was requested but no Session was provided.")
"only_remote was requested but no Session was provided."
)
self._service_types_data = BUILTIN_DATA
self._warn = warn
if session:
@@ -65,7 +66,7 @@ class ServiceTypes(object):
response = session.get(SERVICE_TYPES_URL)
response.raise_for_status()
self._service_types_data = response.json()
except IOError:
except OSError:
# If we can't fetch, fall backto BUILTIN
if only_remote:
raise
@@ -106,19 +107,22 @@ class ServiceTypes(object):
def all_types_by_service_type(self):
"Mapping of official service type to official type and aliases."
return copy.deepcopy(
self._service_types_data['all_types_by_service_type'])
self._service_types_data['all_types_by_service_type']
)
@property
def primary_service_by_project(self):
"Mapping of project name to the primary associated service."
return copy.deepcopy(
self._service_types_data['primary_service_by_project'])
self._service_types_data['primary_service_by_project']
)
@property
def service_types_by_project(self):
"Mapping of project name to a list of all associated service-types."
return copy.deepcopy(
self._service_types_data['service_types_by_project'])
self._service_types_data['service_types_by_project']
)
def get_official_service_data(self, service_type):
"""Get the service data for an official service_type.
@@ -224,13 +228,12 @@ class ServiceTypes(object):
official = self._service_types_data['reverse'].get(service_type)
if permissive and official is None:
if self._warn:
exc.warn(
exc.UnofficialUsageWarning,
given=service_type)
exc.warn(exc.UnofficialUsageWarning, given=service_type)
return service_type
if self._warn:
exc.warn(
exc.AliasUsageWarning, given=service_type, official=official)
exc.AliasUsageWarning, given=service_type, official=official
)
return official
def get_all_types(self, service_type):
@@ -243,7 +246,8 @@ class ServiceTypes(object):
if not self.is_known(service_type):
return [service_type]
return self.all_types_by_service_type[
self.get_service_type(service_type)]
self.get_service_type(service_type)
]
def get_project_name(self, service_type):
"""Return the OpenStack project name for a given service_type.
@@ -280,6 +284,7 @@ class ServiceTypes(object):
"""
data = []
for service_type in self.service_types_by_project.get(
project_name, []):
project_name, []
):
data.append(self.get_service_data(service_type))
return data

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2010-2011 OpenStack Foundation
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
#
@@ -29,7 +27,7 @@ class TestCase(base.BaseTestCase):
"""Base test case class before singleton protection is added."""
def setUp(self):
super(TestCase, self).setUp()
super().setUp()
self.builtin_content = os_service_types.service_types.BUILTIN_DATA
self.builtin_version = self.builtin_content['version']
@@ -41,111 +39,214 @@ class TestCase(base.BaseTestCase):
self.remote_content['version'] = self.remote_version
class ServiceDataMixin(object):
class ServiceDataMixin:
scenarios = [
('compute', dict(
service_type='compute', official='compute', aliases=[],
all_types=['compute'],
api_reference='compute', api_reference_project=None,
is_secondary=False, all_services=['compute'],
is_known=True, is_alias=False, is_official=True, project='nova')),
('volumev2', dict(
service_type='volumev2', official='block-storage', aliases=[],
all_types=['block-storage', 'volumev3', 'volumev2', 'volume',
'block-store'],
api_reference='block-storage', api_reference_project=None,
is_known=True, is_alias=True, is_official=False,
is_secondary=False, all_services=['block-storage'],
project='cinder')),
('volumev3', dict(
service_type='volumev3', official='block-storage', aliases=[],
all_types=['block-storage', 'volumev3', 'volumev2', 'volume',
'block-store'],
api_reference='block-storage', api_reference_project=None,
is_known=True, is_alias=True, is_official=False,
is_secondary=False, all_services=['block-storage'],
project='cinder')),
('block-storage', dict(
service_type='block-storage', official='block-storage',
all_types=['block-storage', 'volumev3', 'volumev2', 'volume',
'block-store'],
api_reference='block-storage', api_reference_project=None,
aliases=['volumev3', 'volumev2', 'volume', 'block-store'],
is_known=True, is_alias=False, is_official=True,
is_secondary=False, all_services=['block-storage'],
project='cinder')),
('block_storage', dict(
service_type='block_storage', official='block-storage',
all_types=['block-storage', 'volumev3', 'volumev2', 'volume',
'block-store'],
api_reference='block-storage', api_reference_project=None,
aliases=['volumev3', 'volumev2', 'volume', 'block-store'],
is_known=True, is_alias=False, is_official=True,
is_secondary=False, all_services=['block-storage'],
project='cinder')),
('network', dict(
service_type='network', official='network', aliases=[],
all_types=['network'],
api_reference='network', api_reference_project='neutron-lib',
is_known=True, is_alias=False, is_official=True,
is_secondary=False, all_services=['network'],
project='neutron')),
('placement', dict(
service_type='placement', official='placement', aliases=[],
all_types=['placement'], all_services=['placement'],
api_reference='placement', api_reference_project=None,
is_known=True, is_alias=False, is_official=True,
is_secondary=False, project='placement')),
('missing', dict(
service_type='missing', official=None,
aliases=[], all_services=[],
all_types=['missing'],
api_reference=None, api_reference_project=None,
is_known=False, is_alias=False, is_official=False,
is_secondary=False,
project=None)),
(
'compute',
dict(
service_type='compute',
official='compute',
aliases=[],
all_types=['compute'],
api_reference='compute',
api_reference_project=None,
is_secondary=False,
all_services=['compute'],
is_known=True,
is_alias=False,
is_official=True,
project='nova',
),
),
(
'volumev2',
dict(
service_type='volumev2',
official='block-storage',
aliases=[],
all_types=[
'block-storage',
'volumev3',
'volumev2',
'volume',
'block-store',
],
api_reference='block-storage',
api_reference_project=None,
is_known=True,
is_alias=True,
is_official=False,
is_secondary=False,
all_services=['block-storage'],
project='cinder',
),
),
(
'volumev3',
dict(
service_type='volumev3',
official='block-storage',
aliases=[],
all_types=[
'block-storage',
'volumev3',
'volumev2',
'volume',
'block-store',
],
api_reference='block-storage',
api_reference_project=None,
is_known=True,
is_alias=True,
is_official=False,
is_secondary=False,
all_services=['block-storage'],
project='cinder',
),
),
(
'block-storage',
dict(
service_type='block-storage',
official='block-storage',
all_types=[
'block-storage',
'volumev3',
'volumev2',
'volume',
'block-store',
],
api_reference='block-storage',
api_reference_project=None,
aliases=['volumev3', 'volumev2', 'volume', 'block-store'],
is_known=True,
is_alias=False,
is_official=True,
is_secondary=False,
all_services=['block-storage'],
project='cinder',
),
),
(
'block_storage',
dict(
service_type='block_storage',
official='block-storage',
all_types=[
'block-storage',
'volumev3',
'volumev2',
'volume',
'block-store',
],
api_reference='block-storage',
api_reference_project=None,
aliases=['volumev3', 'volumev2', 'volume', 'block-store'],
is_known=True,
is_alias=False,
is_official=True,
is_secondary=False,
all_services=['block-storage'],
project='cinder',
),
),
(
'network',
dict(
service_type='network',
official='network',
aliases=[],
all_types=['network'],
api_reference='network',
api_reference_project='neutron-lib',
is_known=True,
is_alias=False,
is_official=True,
is_secondary=False,
all_services=['network'],
project='neutron',
),
),
(
'placement',
dict(
service_type='placement',
official='placement',
aliases=[],
all_types=['placement'],
all_services=['placement'],
api_reference='placement',
api_reference_project=None,
is_known=True,
is_alias=False,
is_official=True,
is_secondary=False,
project='placement',
),
),
(
'missing',
dict(
service_type='missing',
official=None,
aliases=[],
all_services=[],
all_types=['missing'],
api_reference=None,
api_reference_project=None,
is_known=False,
is_alias=False,
is_official=False,
is_secondary=False,
project=None,
),
),
]
def test_get_service_type(self):
if self.official:
self.assertEqual(
self.official,
self.service_types.get_service_type(self.service_type))
self.service_types.get_service_type(self.service_type),
)
else:
self.assertIsNone(
self.service_types.get_service_type(self.service_type))
self.service_types.get_service_type(self.service_type)
)
def test_get_service_type_permissive(self):
self.assertEqual(
self.official or self.service_type,
self.service_types.get_service_type(
self.service_type, permissive=True))
self.service_type, permissive=True
),
)
def test_get_aliases(self):
self.assertEqual(
self.aliases,
self.service_types.get_aliases(self.service_type))
self.aliases, self.service_types.get_aliases(self.service_type)
)
def test_is_known(self):
self.assertEqual(
self.is_known,
self.service_types.is_known(self.service_type))
self.is_known, self.service_types.is_known(self.service_type)
)
def test_is_alias(self):
self.assertEqual(
self.is_alias,
self.service_types.is_alias(self.service_type))
self.is_alias, self.service_types.is_alias(self.service_type)
)
def test_is_official(self):
self.assertEqual(
self.is_official,
self.service_types.is_official(self.service_type))
self.is_official, self.service_types.is_official(self.service_type)
)
def test_get_project_name(self):
self.assertEqual(
self.project,
self.service_types.get_project_name(self.service_type))
self.service_types.get_project_name(self.service_type),
)
def test_get_service_data(self):
service_data = self.service_types.get_service_data(self.service_type)
@@ -163,11 +264,13 @@ class ServiceDataMixin(object):
self.assertEqual(self.official, service_data['service_type'])
self.assertEqual(
api_url.format(api_reference=self.api_reference),
service_data['api_reference'])
service_data['api_reference'],
)
def test_get_official_service_data(self):
service_data = self.service_types.get_official_service_data(
self.service_type)
self.service_type
)
# TODO(mordred) Once all the docs have been aligned, remove
# self.api_reference and replace with self.service_type
api_url = 'https://docs.openstack.org/api-ref/{api_reference}/'
@@ -182,14 +285,16 @@ class ServiceDataMixin(object):
self.assertEqual(self.official, service_data['service_type'])
self.assertEqual(
api_url.format(api_reference=self.api_reference),
service_data['api_reference'])
service_data['api_reference'],
)
def test_empty_project_error(self):
if not self.project:
self.assertRaises(
ValueError,
self.service_types.get_service_data_for_project,
self.project)
self.project,
)
def test_get_service_data_for_project(self):
if self.is_secondary:
@@ -200,7 +305,8 @@ class ServiceDataMixin(object):
return
service_data = self.service_types.get_service_data_for_project(
self.project)
self.project
)
# TODO(mordred) Once all the docs have been aligned, remove
# self.api_reference and replace with self.service_type
api_url = 'https://docs.openstack.org/api-ref/{api_reference}/'
@@ -209,18 +315,20 @@ class ServiceDataMixin(object):
if self.api_reference_project:
self.assertEqual(
self.api_reference_project,
service_data['api_reference_project'])
service_data['api_reference_project'],
)
else:
self.assertEqual(self.project, service_data['project'])
self.assertEqual(self.official, service_data['service_type'])
self.assertEqual(
api_url.format(api_reference=self.api_reference),
service_data['api_reference'])
service_data['api_reference'],
)
def test_get_all_types(self):
self.assertEqual(
self.all_types,
self.service_types.get_all_types(self.service_type))
self.all_types, self.service_types.get_all_types(self.service_type)
)
def test_all_get_service_data_for_project(self):
if not self.project:
@@ -228,19 +336,28 @@ class ServiceDataMixin(object):
return
all_data = self.service_types.get_all_service_data_for_project(
self.project)
for (index, data) in enumerate(all_data):
self.project
)
for index, data in enumerate(all_data):
self.assertEqual(
data,
self.service_types.get_service_data(self.all_services[index]))
self.service_types.get_service_data(self.all_services[index]),
)
class TemporaryFileMixin(base.BaseTestCase):
def create_temp_file(self, mode='w', suffix='', prefix='tmp', dir=None,
text=False, delete=True):
fd, name = tempfile.mkstemp(suffix=suffix, prefix=prefix, dir=dir,
text=text)
def create_temp_file(
self,
mode='w',
suffix='',
prefix='tmp',
dir=None,
text=False,
delete=True,
):
fd, name = tempfile.mkstemp(
suffix=suffix, prefix=prefix, dir=dir, text=text
)
fd = os.fdopen(fd, mode)
if delete:
self.addCleanup(self._delete_temp, fd, name)

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
# 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
@@ -21,6 +19,7 @@ Tests for `ServiceTypes` class builtin data.
oslotest sets up a TempHomeDir for us, so there should be no ~/.cache files
available in these tests.
"""
from testscenarios import load_tests_apply_scenarios as load_tests # noqa
import os_service_types
@@ -28,9 +27,8 @@ from os_service_types.tests import base
class TestBuiltin(base.TestCase, base.ServiceDataMixin):
def setUp(self):
super(TestBuiltin, self).setUp()
super().setUp()
# Make an object with no network access
self.service_types = os_service_types.ServiceTypes()

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
# 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
@@ -27,9 +25,8 @@ from os_service_types.tests import base
class TestData(base.TestCase, base.TemporaryFileMixin):
def setUp(self):
super(TestData, self).setUp()
super().setUp()
def test_load(self):
json_data = {'some_key': 'some_value'}
@@ -39,13 +36,18 @@ class TestData(base.TestCase, base.TemporaryFileMixin):
def test_load_service_types(self):
json_data = data.read_data('service-types.json')
for key in ["all_types_by_service_type", "forward",
"primary_service_by_project", "reverse"]:
for key in [
"all_types_by_service_type",
"forward",
"primary_service_by_project",
"reverse",
]:
self.assertIn(key, json_data)
def test_load_non_existing(self):
self.assertRaises(FileNotFoundError, data.read_data,
'/non-existing-file')
self.assertRaises(
FileNotFoundError, data.read_data, '/non-existing-file'
)
def create_json(self, json_data):
fd, name = self.create_temp_file(suffix='.json')

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
# 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
@@ -21,6 +19,7 @@ Tests for is_match logic
oslotest sets up a TempHomeDir for us, so there should be no ~/.cache files
available in these tests.
"""
from testscenarios import load_tests_apply_scenarios as load_tests # noqa
import os_service_types
@@ -28,32 +27,48 @@ from os_service_types.tests import base
class TestMatch(base.TestCase):
scenarios = [
('match-official', dict(
requested='compute', found='compute', is_match=True)),
('direct-match-unknown', dict(
requested='unknown', found='unknown', is_match=True)),
('volumev2-finds-block', dict(
requested='volumev2', found='block-storage', is_match=True)),
('volumev3-finds-block', dict(
requested='volumev3', found='block-storage', is_match=True)),
('block-finds-volumev2', dict(
requested='block-storage', found='volumev2', is_match=True)),
('block-finds-volumev3', dict(
requested='block-storage', found='volumev3', is_match=True)),
('volumev2-not-volumev3', dict(
requested='volumev2', found='volumev3', is_match=False)),
('non-match', dict(
requested='unknown', found='compute', is_match=False)),
(
'match-official',
dict(requested='compute', found='compute', is_match=True),
),
(
'direct-match-unknown',
dict(requested='unknown', found='unknown', is_match=True),
),
(
'volumev2-finds-block',
dict(requested='volumev2', found='block-storage', is_match=True),
),
(
'volumev3-finds-block',
dict(requested='volumev3', found='block-storage', is_match=True),
),
(
'block-finds-volumev2',
dict(requested='block-storage', found='volumev2', is_match=True),
),
(
'block-finds-volumev3',
dict(requested='block-storage', found='volumev3', is_match=True),
),
(
'volumev2-not-volumev3',
dict(requested='volumev2', found='volumev3', is_match=False),
),
(
'non-match',
dict(requested='unknown', found='compute', is_match=False),
),
]
def setUp(self):
super(TestMatch, self).setUp()
super().setUp()
# Make an object with no network access
self.service_types = os_service_types.ServiceTypes()
def test_is_match(self):
self.assertEqual(
self.is_match,
self.service_types.is_match(self.requested, self.found))
self.service_types.is_match(self.requested, self.found),
)

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
# 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
@@ -24,7 +22,6 @@ from os_service_types.tests import base
class TestMisc(base.TestCase):
def test_normalize(self):
self.assertEqual('foo-bar', service_types._normalize_type('foo_bar'))

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
# 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
@@ -21,6 +19,7 @@ Tests for `ServiceTypes` class remote data.
oslotest sets up a TempHomeDir for us, so there should be no ~/.cache files
available in these tests.
"""
from requests_mock.contrib import fixture as rm_fixture
from testscenarios import load_tests_apply_scenarios as load_tests # noqa
@@ -32,20 +31,22 @@ from os_service_types.tests import base
class TestRemote(base.TestCase, base.ServiceDataMixin):
def setUp(self):
super(TestRemote, self).setUp()
super().setUp()
# Set up a requests_mock fixture for all HTTP traffic
adapter = self.useFixture(rm_fixture.Fixture())
adapter.register_uri(
'GET', os_service_types.service_types.SERVICE_TYPES_URL,
'GET',
os_service_types.service_types.SERVICE_TYPES_URL,
json=self.remote_content,
headers={'etag': self.getUniqueString('etag')})
headers={'etag': self.getUniqueString('etag')},
)
# use keystoneauth1 to get a Sessiom with no auth information
self.session = keystoneauth1.session.Session()
# Make an object that fetches from the network
self.service_types = os_service_types.ServiceTypes(
session=self.session)
session=self.session
)
self.assertEqual(1, len(adapter.request_history))
def test_remote_version(self):

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
# 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
@@ -18,14 +16,14 @@ test_singleton
Tests for `get_service_types` singleton factory function.
"""
import os_service_types
from os_service_types.tests import base
class TestSingleton(base.TestCase):
def setUp(self):
super(TestSingleton, self).setUp()
super().setUp()
# Make an object with no network access
self.service_types = os_service_types.get_service_types()

View File

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
# 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
@@ -18,6 +16,7 @@ test_warn
Tests for warnings
"""
import warnings
import os_service_types
@@ -26,9 +25,8 @@ from os_service_types.tests import base
class TestWarnOn(base.TestCase):
def setUp(self):
super(TestWarnOn, self).setUp()
super().setUp()
# Cause all warnings to always be triggered.
warnings.simplefilter("always")
self.service_types = os_service_types.ServiceTypes(warn=True)
@@ -46,9 +44,8 @@ class TestWarnOn(base.TestCase):
class TestWarnOff(base.TestCase):
def setUp(self):
super(TestWarnOff, self).setUp()
super().setUp()
# Cause all warnings to always be triggered.
warnings.simplefilter("always")
self.service_types = os_service_types.ServiceTypes()

17
pyproject.toml Normal file
View File

@@ -0,0 +1,17 @@
[tool.ruff]
line-length = 79
target-version = "py310"
[tool.ruff.format]
quote-style = "preserve"
docstring-code-format = true
[tool.ruff.lint]
select = ["E4", "E7", "E9", "F", "S", "U"]
ignore = [
# we only use asserts for type narrowing
"S101",
]
[tool.ruff.lint.per-file-ignores]
"os_service_types/tests/*" = ["S"]

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# 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
@@ -52,7 +51,7 @@ source_suffix = '.rst'
master_doc = 'index'
# General information about the project.
copyright = u'2017, OpenStack Developers'
copyright = '2017, OpenStack Developers'
# openstackdocstheme options
openstackdocs_repo_name = 'openstack/os-service-types'
@@ -199,9 +198,13 @@ htmlhelp_basename = 'os_service_typesReleaseNotesdoc'
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
('index', 'os_service_typesReleaseNotes.tex',
u'os_service_types Release Notes Documentation',
u'OpenStack Foundation', 'manual'),
(
'index',
'os_service_typesReleaseNotes.tex',
'os_service_types Release Notes Documentation',
'OpenStack Foundation',
'manual',
),
]
# The name of an image file (relative to this directory) to place at the top of
@@ -230,9 +233,13 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'os_service_typesrereleasenotes',
u'os_service_types Release Notes Documentation',
[u'OpenStack Developers'], 1)
(
'index',
'os_service_typesrereleasenotes',
'os_service_types Release Notes Documentation',
['OpenStack Developers'],
1,
)
]
# If true, show URL addresses after external links.
@@ -245,11 +252,15 @@ man_pages = [
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', 'os_service_types ReleaseNotes',
u'os_service_types Release Notes Documentation',
u'OpenStack Developers', 'os_service_typesReleaseNotes',
'One line description of project.',
'Miscellaneous'),
(
'index',
'os_service_types ReleaseNotes',
'os_service_types Release Notes Documentation',
'OpenStack Developers',
'os_service_typesReleaseNotes',
'One line description of project.',
'Miscellaneous',
),
]
# Documents to append as an appendix to all manuals.

View File

@@ -16,6 +16,4 @@
# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT
import setuptools
setuptools.setup(
setup_requires=['pbr>=2.0.0'],
pbr=True)
setuptools.setup(setup_requires=['pbr>=2.0.0'], pbr=True)

View File

@@ -13,7 +13,13 @@ commands =
stestr run --slowest {posargs}
[testenv:pep8]
commands = flake8 {posargs}
description =
Run style checks.
skip_install = true
deps =
pre-commit
commands =
pre-commit run --all-files --show-diff-on-failure
[testenv:venv]
commands = {posargs}