forked from github.com/pypiserver
Standalone conf, Dockerfile updates, pub interface
* Fixed config for standalone package to handle the expected error in `pkg_resources.resource_file()` * Ensured the `pypiserver` user in the Dockerfile is part of the `pypiserver` group * Ensured `__updated__` is available in the public interface by moving it back into `__init__.py` * Added `const.py` for defining, you guessed it, constants
This commit is contained in:
parent
38d51dfbce
commit
0763077124
@ -4,8 +4,8 @@ FROM python:3.6-alpine
|
||||
COPY . /code
|
||||
WORKDIR /code
|
||||
|
||||
RUN adduser -S -u 9898 pypiserver && \
|
||||
addgroup -S -g 9898 pypiserver && \
|
||||
RUN addgroup -S -g 9898 pypiserver && \
|
||||
adduser -S -u 9898 -G pypiserver pypiserver && \
|
||||
python setup.py install && \
|
||||
pip install passlib && \
|
||||
cd / && \
|
||||
|
@ -4,6 +4,7 @@
|
||||
__title__ = "pypiserver"
|
||||
__summary__ = "A minimal PyPI server for use with pip/easy_install."
|
||||
__uri__ = "https://github.com/pypiserver/pypiserver"
|
||||
__updated__ = "2018-06-12 20:15:10"
|
||||
|
||||
# Interface
|
||||
from ._app import app # noqa
|
||||
|
@ -4,4 +4,3 @@ import re
|
||||
|
||||
__version__ = version = "1.2.2"
|
||||
__version_info__ = tuple(re.split('[.-]', __version__))
|
||||
__updated__ = "2018-06-12 20:15:10"
|
||||
|
@ -11,6 +11,7 @@ import pkg_resources
|
||||
|
||||
from . import __version__
|
||||
from .bottle import server_names
|
||||
from .const import STANDALONE_WELCOME
|
||||
|
||||
|
||||
_AUTH_RE = re.compile(r'[, ]+')
|
||||
@ -23,6 +24,14 @@ def str2bool(string):
|
||||
return string.lower() not in _FALSES
|
||||
|
||||
|
||||
def _get_welcome_file():
|
||||
"""Get the welcome file or set a constant for the standalone package."""
|
||||
try:
|
||||
return pkg_resources.resource_filename('pypiserver', 'welcome.html')
|
||||
except NotImplementedError: # raised in standalone zipfile.
|
||||
return STANDALONE_WELCOME
|
||||
|
||||
|
||||
class _Defaults(object):
|
||||
"""Define default constants."""
|
||||
|
||||
@ -348,7 +357,7 @@ class PypiserverParserFactory(object):
|
||||
'--welcome',
|
||||
default=environ.get(
|
||||
'PYPISERVER_WELCOME',
|
||||
pkg_resources.resource_filename('pypiserver', 'welcome.html'),
|
||||
_get_welcome_file()
|
||||
),
|
||||
dest='welcome_file',
|
||||
metavar='HTML_FILE',
|
||||
|
3
pypiserver/const.py
Normal file
3
pypiserver/const.py
Normal file
@ -0,0 +1,3 @@
|
||||
"""Constant values for pypiserver."""
|
||||
|
||||
STANDALONE_WELCOME = 'standalone'
|
@ -10,12 +10,16 @@ import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
if sys.version_info < (3,):
|
||||
from io import open
|
||||
|
||||
import pkg_resources
|
||||
|
||||
from .const import STANDALONE_WELCOME
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
_archive_suffix_rx = re.compile(
|
||||
r"(\.zip|\.tar\.gz|\.tgz|\.tar\.bz2|-py[23]\.\d-.*|"
|
||||
"\.win-amd64-py[23]\.\d\..*|\.win32-py[23]\.\d\..*|\.egg)$",
|
||||
@ -62,8 +66,15 @@ def configure(config):
|
||||
config.auther = functools.partial(auth_by_htpasswd_file, htPsswdFile)
|
||||
|
||||
try:
|
||||
with open(config.welcome_file, 'r', encoding='utf-8') as fd:
|
||||
config.welcome_msg = fd.read()
|
||||
# pkg_resources.resource_filename() is not supported for zipfiles,
|
||||
# so we rely on resource_string() instead.
|
||||
if config.welcome_file == STANDALONE_WELCOME:
|
||||
config.welcome_msg = pkg_resources.resource_string(
|
||||
__name__, 'welcome.html'
|
||||
).decode('utf-8')
|
||||
else:
|
||||
with open(config.welcome_file, 'r', encoding='utf-8') as fd:
|
||||
config.welcome_msg = fd.read()
|
||||
except Exception:
|
||||
log.warning(
|
||||
"Could not load welcome file(%s)!",
|
||||
|
@ -4,9 +4,15 @@ import logging
|
||||
from os import getcwd
|
||||
from os.path import exists, expanduser
|
||||
|
||||
try:
|
||||
from unittest.mock import Mock
|
||||
except ImportError: # py2
|
||||
from mock import Mock
|
||||
|
||||
import pytest
|
||||
|
||||
from pypiserver import config
|
||||
from pypiserver import const
|
||||
|
||||
|
||||
class StubAction:
|
||||
@ -217,6 +223,17 @@ class TestDeprecatedParser:
|
||||
else:
|
||||
assert parser.parse_args(args).welcome_file == exp
|
||||
|
||||
def test_standalone_welcome(self, monkeypatch):
|
||||
"""Test that the error raised in the standalone package is handled."""
|
||||
monkeypatch.setattr(
|
||||
config.pkg_resources,
|
||||
'resource_filename',
|
||||
Mock(side_effect=NotImplementedError)
|
||||
)
|
||||
assert config.PypiserverParserFactory(
|
||||
parser_type='pypi-server'
|
||||
).get_parser().parse_args([]).welcome_file == const.STANDALONE_WELCOME
|
||||
|
||||
@pytest.mark.parametrize('args, exp', (
|
||||
([], None),
|
||||
(['--cache-control', '12'], 12),
|
||||
@ -486,6 +503,17 @@ class TestParser:
|
||||
else:
|
||||
assert parser.parse_args(args).welcome_file == exp
|
||||
|
||||
def test_standalone_welcome(self, monkeypatch):
|
||||
"""Test that the error raised in the standalone package is handled."""
|
||||
monkeypatch.setattr(
|
||||
config.pkg_resources,
|
||||
'resource_filename',
|
||||
Mock(side_effect=NotImplementedError)
|
||||
)
|
||||
assert config.PypiserverParserFactory().get_parser().parse_args(
|
||||
['run']
|
||||
).welcome_file == const.STANDALONE_WELCOME
|
||||
|
||||
@pytest.mark.parametrize('args, exp', (
|
||||
([], None),
|
||||
(['--cache-control', '12'], 12),
|
||||
|
@ -1,6 +1,7 @@
|
||||
#! /usr/bin/env py.test
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# TODO: write more tests for core!
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
@ -9,8 +10,7 @@ import pytest
|
||||
from pypiserver import __main__, core
|
||||
|
||||
|
||||
## Enable logging to detect any problems with it
|
||||
##
|
||||
# Enable logging to detect any problems with it
|
||||
__main__.init_logging(level=logging.NOTSET)
|
||||
|
||||
|
||||
@ -57,18 +57,21 @@ files = [
|
||||
("package-name-0.0.1.alpha.1.win-amd64-py3.2.exe", "package-name", "0.0.1.alpha.1"),
|
||||
]
|
||||
|
||||
|
||||
def _capitalize_ext(fpath):
|
||||
f, e = os.path.splitext(fpath)
|
||||
if e != '.whl':
|
||||
e = e.upper()
|
||||
return f + e
|
||||
|
||||
|
||||
@pytest.mark.parametrize(("filename", "pkgname", "version"), files)
|
||||
def test_guess_pkgname_and_version(filename, pkgname, version):
|
||||
exp = (pkgname, version)
|
||||
assert core.guess_pkgname_and_version(filename) == exp
|
||||
assert core.guess_pkgname_and_version(_capitalize_ext(filename)) == exp
|
||||
|
||||
|
||||
@pytest.mark.parametrize(("filename", "pkgname", "version"), files)
|
||||
def test_guess_pkgname_and_version_asc(filename, pkgname, version):
|
||||
exp = (pkgname, version)
|
||||
@ -81,10 +84,13 @@ def test_listdir_bad_name(tmpdir):
|
||||
res = list(core.listdir(tmpdir.strpath))
|
||||
assert res == []
|
||||
|
||||
|
||||
hashes = [
|
||||
('sha256', 'e3b0c44298fc1c149afbf4c8996fb924'), # empty-sha256
|
||||
('md5', 'd41d8cd98f00b204e9800998ecf8427e'), # empty-md5
|
||||
('sha256', 'e3b0c44298fc1c149afbf4c8996fb924'), # empty-sha256
|
||||
('md5', 'd41d8cd98f00b204e9800998ecf8427e'), # empty-md5
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(("algo", "digest"), hashes)
|
||||
def test_hashfile(tmpdir, algo, digest):
|
||||
f = tmpdir.join("empty")
|
||||
|
Loading…
Reference in New Issue
Block a user