Skip to content

Commit

Permalink
Universum 0.19.7
Browse files Browse the repository at this point in the history
  • Loading branch information
k-dovgan committed May 19, 2021
2 parents 4462a0f + 42aca15 commit d21e4a3
Show file tree
Hide file tree
Showing 19 changed files with 346 additions and 322 deletions.
24 changes: 24 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
Change log
==========

0.19.7 (2021-05-19)
-------------------

BREAKING CHANGES
~~~~~~~~~~~~~~~~

* **submit:** ``--reconcile-list`` option can no longer be passed several times. Please use comma-separated
single string instead (e.g. ``python -m universum submit -rl 'target1, target2'``)
* **analyzers:** ``universum.analyzers.svace`` support is deprecated until further notice

New features
~~~~~~~~~~~~

* **submit:** ``--commit-message`` and ``--reconcile-list`` now support passing required values via local file.
To use this feature, pass an absolute or relative file path starting with '@' as a corresponding argument.
See :ref:`argument description <additional_commands#submit>` for details

Bug fixes
~~~~~~~~~

* **analyzers:** ``'Namespace' object has no attribute 'file_names'`` error message
from :ref:`Uncrustify <code_report#uncrustify>` module fixed


0.19.6 (2021-05-12)
-------------------

Expand Down
42 changes: 2 additions & 40 deletions doc/code_report.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ The following analysing modules (analysers) are currently added to Universum:

* `pylint`_
* `mypy`_
* `svace`_
* `uncrustify`_

Analysers are separate scripts, fully compatible with Universum. It is possible to use them
Expand Down Expand Up @@ -102,43 +101,6 @@ This file will get us the following list of configurations:
[{'name': 'mypy', 'code_report': True, 'command': '{python} -m universum.analyzers.mypy --python-version 3 --result-file ${CODE_REPORT_FILE} --files *.py examples/'}]

.. _code_report#svace:

Svace
-----

.. argparse::
:ref: universum.analyzers.svace.form_arguments_for_documentation
:prog: {python} -m universum.analyzers.svace

Config example for ``universum.analyzers.svace``:

.. testcode::

from universum.configuration_support import Configuration, Step

configs = Configuration([Step(name="svace", code_report=True, command=[
"{python}", "-m", "universum.analyzers.svace", "--build-cmd", "make", "--lang", "CXX",
"--result-file", "${CODE_REPORT_FILE}"
])])

if __name__ == '__main__':
print(configs.dump())

will produce this list of configurations:

.. testcode::
:hide:

print("$ ./.universum.py")
print(configs.dump())

.. testoutput::

$ ./.universum.py
[{'name': 'svace', 'code_report': True, 'command': '{python} -m universum.analyzers.svace --build-cmd make --lang CXX --result-file ${CODE_REPORT_FILE}'}]


.. _code_report#uncrustify:

Uncrustify
Expand All @@ -156,7 +118,7 @@ Config example for ``universum.analyzers.uncrustify``:
from universum.configuration_support import Configuration, Step

configs = Configuration([Step(name="uncrustify", code_report=True, command=[
"{python}", "-m", "universum.analyzers.uncrustify", "--files", "project_root_directory",
"{python}", "-m", "universum.analyzers.uncrustify", "--files", "/home/user/workspace/temp",
"--cfg-file", "file_name.cfg", "--filter-regex", ".*//.(?:c|cpp)",
"--result-file", "${CODE_REPORT_FILE}", "--output-directory", "uncrustify"
])])
Expand All @@ -175,4 +137,4 @@ will produce this list of configurations:
.. testoutput::

$ ./.universum.py
[{'name': 'uncrustify', 'code_report': True, 'command': '{python} -m universum.analyzers.uncrustify --files project_root_directory --cfg-file file_name.cfg --filter-regex .*//.(?:c|cpp) --result-file ${CODE_REPORT_FILE} --output-directory uncrustify'}]
[{'name': 'uncrustify', 'code_report': True, 'command': '{python} -m universum.analyzers.uncrustify --files /home/user/workspace/temp --cfg-file file_name.cfg --filter-regex .*//.(?:c|cpp) --result-file ${CODE_REPORT_FILE} --output-directory uncrustify'}]
4 changes: 2 additions & 2 deletions tests/docker/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
UNIVERSUM_ENVIRONMENT=$(filter-out Makefile perforce, $(wildcard *))
UNIVERSUM_ENVIRONMENT= universum_test_env universum_test_env_no_p4 universum_test_env_no_vcs
DOCKER_ARGS :=
PYTHON ?= $(shell python -c 'import sys; print("python%d.%d"% sys.version_info[0:2])' )
ifeq ($(PYTHON),)
Expand All @@ -10,7 +10,7 @@ endif
all: $(UNIVERSUM_ENVIRONMENT) perforce

$(UNIVERSUM_ENVIRONMENT):
docker build --build-arg PYTHON=$(PYTHON) $(DOCKER_ARGS) $@ -t $@_$(PYTHON)
docker build --target $@ --build-arg PYTHON=$(PYTHON) $(DOCKER_ARGS) universum_test_env -t $@_$(PYTHON)

perforce:
docker build $(DOCKER_ARGS) $@ -t $@
Expand Down
8 changes: 5 additions & 3 deletions tests/docker/perforce/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
FROM ubuntu:bionic

ENV DEBIAN_FRONTEND noninteractive
# Please note: apt-get install will produce the following message in stderr:
# 'debconf: delaying package configuration, since apt-utils is not installed`
# In scope of non-interactive configuration there's no need to fix it

# Update package list and install wget
RUN apt-get update && apt-get install -y wget gnupg2

# Get perforce packages
RUN wget -q http://package.perforce.com/perforce.pubkey -O - | apt-key add - && \
RUN wget -q http://package.perforce.com/perforce.pubkey -O - | APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1 apt-key add - && \
echo "deb http://package.perforce.com/apt/ubuntu bionic release" > /etc/apt/sources.list.d/perforce.list && \
apt update
apt-get update

RUN apt-get install -y helix-p4d curl

Expand Down
36 changes: 27 additions & 9 deletions tests/docker/universum_test_env/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,23 +1,41 @@
FROM ubuntu:bionic
FROM ubuntu:bionic AS universum_test_env_no_vcs
ARG PYTHON=python3.7

# Please note: apt-get install will produce the following message in stderr:
# 'debconf: delaying package configuration, since apt-utils is not installed`
# In scope of non-interactive configuration there's no need to fix it

# Update package list and install wget
RUN apt update && apt install -y wget software-properties-common
RUN apt-get update && apt-get install -y wget software-properties-common

# Install latest python & pip
RUN add-apt-repository ppa:deadsnakes/ppa && apt update
RUN DEBIAN_FRONTEND=noninteractive apt install -y ${PYTHON}-dev ${PYTHON}-distutils gnupg2 libssl-dev build-essential
RUN wget --no-check-certificate -O get-pip.py 'https://bootstrap.pypa.io/get-pip.py'
RUN add-apt-repository ppa:deadsnakes/ppa && apt-get update
RUN apt-get install -y ${PYTHON}-dev ${PYTHON}-distutils gnupg2 libssl-dev build-essential

# Please note: wget is writing logs to stderr, these logs are not any kind of warning
RUN wget --no-verbose --no-check-certificate -O get-pip.py 'https://bootstrap.pypa.io/get-pip.py'
RUN ${PYTHON} get-pip.py

FROM universum_test_env_no_vcs AS universum_test_env_no_p4
ARG PYTHON=python3.7

# Install Git & gitpython
RUN apt install -y git
RUN apt-get install -y git

# Please note, that using Pip as a root user is, indeed, a bad practice
# But in case of 'gitpython' and 'p4python' installing packages into system once per image instead of repeatedly
# installing them into every newly created container as user
# a) is not that dangerous as we use disposable docker containers anyway
# b) saves a lot of times and adds more stability to tests
RUN ${PYTHON} -m pip install gitpython

FROM universum_test_env_no_p4 AS universum_test_env
ARG PYTHON=python3.7

# Install Perforce and p4python
RUN wget -q http://package.perforce.com/perforce.pubkey -O - | apt-key add - && \
RUN wget -q http://package.perforce.com/perforce.pubkey -O - | APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1 apt-key add - && \
echo "deb http://package.perforce.com/apt/ubuntu bionic release" > /etc/apt/sources.list.d/perforce.list && \
apt update
apt-get update

RUN apt install -y helix-cli
RUN apt-get install -y helix-cli
RUN ${PYTHON} -m pip install p4python
15 changes: 0 additions & 15 deletions tests/docker/universum_test_env_no_p4/Dockerfile

This file was deleted.

11 changes: 0 additions & 11 deletions tests/docker/universum_test_env_no_vcs/Dockerfile

This file was deleted.

59 changes: 57 additions & 2 deletions tests/test_code_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
def fixture_runner_with_analyzers(docker_main):
docker_main.environment.install_python_module("pylint")
docker_main.environment.install_python_module("mypy")
docker_main.environment.assert_successful_execution("apt install uncrustify")
yield docker_main


Expand All @@ -22,10 +23,11 @@ def __init__(self):
self.text = "from universum.configuration_support import Configuration, Step\n"
self.text += "configs = Configuration()\n"

def add_analyzer(self, analyzer: str, arguments: List[str]) -> 'ConfigData':
def add_analyzer(self, analyzer: str, arguments: List[str], extra_cfg: str = '') -> 'ConfigData':
args = [f", '{arg}'" for arg in arguments]
cmd = f"['{python()}', '-m', 'universum.analyzers.{analyzer}'{''.join(args)}]"
self.text += f"configs += Configuration([Step(name='Run {analyzer}', code_report=True, command={cmd})])\n"
self.text +=\
f"configs += Configuration([Step(name='Run {analyzer}', {extra_cfg} code_report=True, command={cmd})])\n"
return self

def finalize(self) -> str:
Expand All @@ -39,18 +41,37 @@ def finalize(self) -> str:
print(f"Hello {s}.")
"""

source_code_c = """
int main() {
\treturn 0;
}
"""

cfg_uncrustify = """
code_width = 120
input_tab_size = 2
"""

log_fail = r'Found [0-9]+ issues'
log_success = r'Issues not found'


@pytest.mark.parametrize('analyzers, extra_args, tested_content, expected_success', [
[['uncrustify'], [], source_code_c, True],
[['uncrustify'], [], source_code_c.replace('\t', ' '), False],
[['pylint', 'mypy'], ["--python-version", python_version()], source_code_python, True],
[['pylint'], ["--python-version", python_version()], source_code_python + '\n', False],
[['mypy'], ["--python-version", python_version()], source_code_python.replace(': str', ': int'), False],
[['pylint', 'mypy'], ["--python-version", python_version()], source_code_python.replace(': str', ': int') + '\n', False],
# TODO: add test with rcfile
# TODO: parametrize test for different versions of python
], ids=[
'uncrustify_no_issues',
'uncrustify_found_issues',
'pylint_and_mypy_both_no_issues',
'pylint_found_issues',
'mypy_found_issues',
'pylint_and_mypy_found_issues_independently',
])
def test_code_report_log(runner_with_analyzers, analyzers, extra_args, tested_content, expected_success):
common_args = [
Expand All @@ -61,6 +82,9 @@ def test_code_report_log(runner_with_analyzers, analyzers, extra_args, tested_co
config = ConfigData()
for analyzer in analyzers:
args = common_args + extra_args
if analyzer == 'uncrustify':
args += ["--cfg-file", "cfg"]
runner_with_analyzers.local.root_directory.join("cfg").write(cfg_uncrustify)
config.add_analyzer(analyzer, args)

log = runner_with_analyzers.run(config.finalize())
Expand Down Expand Up @@ -101,6 +125,8 @@ def test_pylint_analyzer_wrong_common_params(runner_with_analyzers, analyzer, co
['pylint', ["--python-version", python_version(), "--files", "source_file",
"--result-file", "${CODE_REPORT_FILE}", '--rcfile'],
"rcfile: expected one argument"],
['uncrustify', ["--files", "source_file", "--result-file", "${CODE_REPORT_FILE}"],
"Please specify the '--cfg_file' parameter or set an env. variable 'UNCRUSTIFY_CONFIG'"],
])
def test_pylint_analyzer_wrong_specific_params(runner_with_analyzers, analyzer, arg_set, expected_log):
source_file = runner_with_analyzers.local.root_directory.join("source_file")
Expand All @@ -111,6 +137,35 @@ def test_pylint_analyzer_wrong_specific_params(runner_with_analyzers, analyzer,
assert expected_log in log


@pytest.mark.parametrize('extra_args, tested_content, expected_success, expected_artifact', [
[[], source_code_c, True, False],
[["--report-html"], source_code_c.replace('\t', ' '), False, True],
[[], source_code_c.replace('\t', ' '), False, False],
], ids=[
"uncrustify_html_file_not_needed",
"uncrustify_html_file_saved",
"uncrustify_html_file_disabled",
])
def test_uncrustify_file_diff(runner_with_analyzers, extra_args, tested_content, expected_success, expected_artifact):
root = runner_with_analyzers.local.root_directory
source_file = root.join("source_file")
source_file.write(tested_content)
root.join("cfg").write(cfg_uncrustify)
common_args = [
"--result-file", "${CODE_REPORT_FILE}",
"--files", "source_file",
"--cfg-file", "cfg",
]

args = common_args + extra_args
extra_cfg = "artifacts='./uncrustify/source_file.html',"
log = runner_with_analyzers.run(ConfigData().add_analyzer('uncrustify', args, extra_cfg).finalize())

assert re.findall(log_success if expected_success else log_fail, log)
assert re.findall(r"Collecting 'source_file.html' - [^\n]*Success" if expected_artifact
else r"Collecting 'source_file.html' - [^\n]*Failed", log)


def test_code_report_extended_arg_search(tmpdir, stdout_checker):
env = utils.TestEnvironment(tmpdir, "main")
env.settings.Vcs.type = "none"
Expand Down
21 changes: 0 additions & 21 deletions tests/test_multiline_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,24 +51,3 @@ def test_multiline_variable_files(tmp_path):
error = module.global_error_state.get_errors()[0]
assert "argument" in str(error)
assert "this-is-not-a-file" in str(error)


def test_multiline_variable_stdin(tmp_path):
script_file = tmp_path / "script.py"
script_file.write_text(script)
script_path = str(script_file)

env = dict(os.environ)
env['PYTHONPATH'] = os.getcwd()
common_args = {"capture_output": True, "text": True, "env": env}

result = subprocess.run([python(), script_path, "-a", "-"], **common_args, input=text, check=True)
assert result.stdout[:-1] == text

env['ARGUMENT'] = '-'
result = subprocess.run([python(), script_path], **common_args, input=text, check=True)
assert result.stdout[:-1] == text
del env['ARGUMENT']

result = subprocess.run([python(), script_path, "-a", "-"], **common_args, input="", check=False)
assert error_message in result.stdout
8 changes: 4 additions & 4 deletions tests/test_submit.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def test_p4_error_forbidden_branch(p4_submit_environment, branch):
file_to_add.write(text + "\n")

settings = copy.deepcopy(p4_submit_environment.settings)
setattr(settings.Submit, "reconcile_list", [str(file_to_add)])
setattr(settings.Submit, "reconcile_list", str(file_to_add))

assert __main__.run(settings)

Expand All @@ -59,7 +59,7 @@ def test_p4_success_files_in_default(p4_submit_environment):
new_file.write("This is a new file" + "\n")

settings = copy.deepcopy(p4_submit_environment.settings)
setattr(settings.Submit, "reconcile_list", [str(new_file)])
setattr(settings.Submit, "reconcile_list", str(new_file))

assert not __main__.run(settings)
assert text in p4_file.read()
Expand All @@ -80,7 +80,7 @@ def test_p4_error_files_in_default_and_reverted(p4_submit_environment):
new_file.write(text_new + "\n")

settings = copy.deepcopy(p4_submit_environment.settings)
setattr(settings.Submit, "reconcile_list", [str(new_file)])
setattr(settings.Submit, "reconcile_list", str(new_file))

assert __main__.run(settings)
assert text_default in p4_file.read()
Expand All @@ -95,7 +95,7 @@ def __init__(self, stdout_checker, environment):

def submit_path_list(self, path_list, **kwargs):
settings = copy.deepcopy(self.submit_settings)
setattr(settings.Submit, "reconcile_list", path_list)
setattr(settings.Submit, "reconcile_list", ",".join(path_list))

if kwargs:
for key in kwargs:
Expand Down
2 changes: 1 addition & 1 deletion tests/test_unicode.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def test_unicode(vcs, test_type, perforce_workspace, git_client, unicode_dir):
if test_type == "submit":
temp_file = env.vcs_cooking_dir.join(utils.randomize_name("new_file") + ".txt")
temp_file.write("This is a new file" + "\n")
env.settings.Submit.reconcile_list = [str(temp_file)]
env.settings.Submit.reconcile_list = str(temp_file)

res = __main__.run(env.settings)
assert res == 0
Expand Down
Loading

0 comments on commit d21e4a3

Please sign in to comment.