Skip to content

Commit

Permalink
Merge branch '1.0.x' into 'master'
Browse files Browse the repository at this point in the history
  • Loading branch information
remram44 committed May 15, 2018
2 parents 0302a38 + 1672954 commit df0b716
Show file tree
Hide file tree
Showing 60 changed files with 1,227 additions and 779 deletions.
4 changes: 2 additions & 2 deletions .travis/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ in
sudo apt-get install -qq libc6-dev-i386 gcc-multilib
if [ $TEST_MODE = "coverage" ]; then
pip install coverage codecov
pip install -e ./reprozip -e ./reprounzip -e ./reprounzip-docker -e ./reprounzip-vagrant -e ./reprounzip-vistrails -e ./reprounzip-qt
pip install -e ./reprozip -e ./reprounzip -e ./reprounzip-docker -e ./reprounzip-vagrant -e ./reprounzip-vistrails -e ./reprounzip-qt -e ./reprozip-jupyter
else
pip install ./reprozip ./reprounzip ./reprounzip-docker ./reprounzip-vagrant ./reprounzip-vistrails ./reprounzip-qt
pip install ./reprozip ./reprounzip ./reprounzip-docker ./reprounzip-vagrant ./reprounzip-vistrails ./reprounzip-qt -e ./reprozip-jupyter
fi
;;
checks)
Expand Down
5 changes: 3 additions & 2 deletions .travis/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@ in
python tests --run-docker
;;
checks)
flake8 --ignore=E731 reprozip/reprozip reprounzip/reprounzip reprounzip-*/reprounzip reprounzip-qt/reprounzip_qt tests/*.py
flake8 --ignore=E731 reprozip/reprozip reprounzip/reprounzip reprounzip-*/reprounzip reprounzip-qt/reprounzip_qt reprozip-jupyter/reprozip_jupyter tests/*.py
diff -q reprozip/reprozip/common.py reprounzip/reprounzip/common.py
diff -q reprozip/reprozip/utils.py reprounzip/reprounzip/utils.py
find reprozip reprounzip reprounzip-* .travis -name '*.py' -or -name '*.sh' -or -name '*.h' -or -name '*.c' | (set +x; while read i; do
find reprozip reprounzip reprozip-* reprounzip-* .travis -name '*.py' -or -name '*.sh' -or -name '*.h' -or -name '*.c' | (set +x; while read i; do
T=$(file -b --mime "$i")
if ! ( echo "$T" | grep -q ascii || echo "$T" | grep -q empty ) ; then
echo "$i is not ASCII"
exit 1
fi
done)
find reprozip reprounzip reprozip-* reprounzip-* -name '*.py' -exec sh -c "grep 'logging\\.\\(debug\\|warning\\|critical\\|error\\|info\\)' \"\$@\" && exit 1; exit 0" {} +
;;
esac
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,20 @@ Features:
* Configuration file contains the walltime taken by each run
* It is now possible to upload or download any file via its full path

1.0.13 (2018-05-15)
-------------------

Bugfixes:
* Fix uninitialized return value making some xxx_at() calls abort the trace
* Fix some other warnings via static analysis

Enhancements:
* Show a warning when executing a file that has the set-uid or set-gid bit set, since Linux will not give it its privileges, making it confusing for users why their run failed
* Make reprounzip-docker run even without a TTY
* Correctly handle experiment returning non-0 in Docker
* The C extension now logs through Python's logging facilities ('reprozip' logger)
* Collect usage information from reprounzip-qt as well

1.0.12 (2018-03-30)
-------------------

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[![Build Status](https://travis-ci.org/ViDA-NYU/reprozip.svg?branch=master)](https://travis-ci.org/ViDA-NYU/reprozip)
[![Coverage Status](https://codecov.io/github/ViDA-NYU/reprozip/coverage.svg?branch=master)](https://codecov.io/github/ViDA-NYU/reprozip?branch=master)
[![Code Health](https://landscape.io/github/ViDA-NYU/reprozip/master/landscape.png)](https://landscape.io/github/ViDA-NYU/reprozip/master)
[![Documentation Status](https://readthedocs.org/projects/reprozip/badge/?version=latest)](https://docs.reprozip.org/en/latest/)
[![Matrix](https://img.shields.io/badge/chat-matrix.org-blue.svg)](https://riot.im/app/#/room/#reprozip:matrix.org)
[![Say Thanks!](https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg)](https://saythanks.io/to/remram44)
[![status](https://img.shields.io/badge/JOSS-10.21105%2Fjoss.00107-green.svg)](http://joss.theoj.org/papers/b578b171263c73f64dfb9d040ca80fe0)
[![DOI](https://img.shields.io/badge/DOI-10.5281%2Fzenodo.1210301-green.svg)](https://doi.org/10.5281/zenodo.1210301)

Expand Down
145 changes: 75 additions & 70 deletions reprounzip-docker/reprounzip/unpackers/docker.py

Large diffs are not rendered by default.

12 changes: 10 additions & 2 deletions reprounzip-docker/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
with io.open('README.rst', encoding='utf-8') as fp:
description = fp.read()
setup(name='reprounzip-docker',
version='1.0.10',
version='1.0.13',
packages=['reprounzip', 'reprounzip.unpackers'],
entry_points={
'reprounzip.unpackers': [
Expand All @@ -25,7 +25,15 @@
author_email='reprozip-users@vgc.poly.edu',
maintainer="Remi Rampin",
maintainer_email='remirampin@gmail.com',
url='http://vida-nyu.github.io/reprozip/',
url='https://www.reprozip.org/',
project_urls={
'Homepage': 'https://github.com/ViDA-NYU/reprozip',
'Documentation': 'https://docs.reprozip.org/',
'Examples': 'https://examples.reprozip.org/',
'Say Thanks': 'https://saythanks.io/to/remram44',
'Source': 'https://github.com/ViDA-NYU/reprozip',
'Tracker': 'https://github.com/ViDA-NYU/reprozip/issues',
},
long_description=description,
license='BSD-3-Clause',
keywords=['reprozip', 'reprounzip', 'reproducibility', 'provenance',
Expand Down
2 changes: 1 addition & 1 deletion reprounzip-qt/reprounzip_qt/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '1.0.12'
__version__ = '1.0.13'
42 changes: 41 additions & 1 deletion reprounzip-qt/reprounzip_qt/gui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from __future__ import division, print_function, unicode_literals

import logging
import os
import platform
from PyQt4 import QtCore, QtGui
Expand All @@ -12,11 +13,16 @@
import sys
import tempfile
import traceback
import usagestats

import reprounzip_qt
from reprounzip_qt.gui.common import error_msg
from reprounzip_qt.gui.unpack import UnpackTab
from reprounzip_qt.gui.run import RunTab
from reprounzip_qt.usage import record_usage, _usage_report as usage_report


logger = logging.getLogger('reprounzip_qt')


class Application(QtGui.QApplication):
Expand All @@ -29,6 +35,7 @@ def linux_try_register_default(self, window):
rcpath = os.path.expanduser('~/.reprozip')
rcname = 'rpuzqt-nodefault'
if os.path.exists(os.path.join(rcpath, rcname)):
logger.info("Registering application disabled")
return
try:
proc = subprocess.Popen(['xdg-mime', 'query', 'default',
Expand All @@ -38,7 +45,8 @@ def linux_try_register_default(self, window):
out, err = proc.communicate()
registered = bool(out.strip())
except OSError:
pass
record_usage(appregister='fail xdg-mime')
logger.info("xdg-mime call failed, not registering application")
else:
if not registered:
r = QtGui.QMessageBox.question(
Expand All @@ -49,18 +57,22 @@ def linux_try_register_default(self, window):
if r == QtGui.QMessageBox.Yes:
self.linux_register_default(window)
elif r == QtGui.QMessageBox.No:
record_usage(appregister='no')
if not os.path.exists(rcpath):
os.mkdir(rcpath)
with open(os.path.join(rcpath, rcname), 'w') as fp:
fp.write('1\n')

def linux_register_default(self, window):
record_usage(appregister='yes')
command = os.path.abspath(sys.argv[0])
if not os.path.isfile(command):
logger.error("Couldn't find argv[0] location!")
return
dirname = tempfile.mkdtemp(prefix='reprozip_mime_')
try:
# Install x-reprozip mimetype
logger.info("Installing application/x-reprozip mimetype for .rpz")
filename = os.path.join(dirname, 'nyuvida-reprozip.xml')
with open(filename, 'w') as fp:
fp.write('''\
Expand All @@ -78,6 +90,7 @@ def linux_register_default(self, window):
'.local/share/mime')])

# Install icon
logger.info("Copying icon")
icon_dest_root = os.path.join(os.environ['HOME'],
'.local/share/icons/hicolor')
icon_dest_subdir = os.path.join(icon_dest_root, '48x48/mimetypes')
Expand All @@ -91,6 +104,7 @@ def linux_register_default(self, window):
subprocess.check_call(['update-icon-caches', icon_dest_root])

# Install desktop file
logger.info("Installing reprounzip.desktop file")
app_dir = os.path.join(os.environ['HOME'],
'.local/share/applications')
if not os.path.exists(app_dir):
Expand All @@ -105,14 +119,38 @@ def linux_register_default(self, window):
Icon={1}
'''.format(command, icon_dest_file))
subprocess.check_call(['update-desktop-database', app_dir])

logger.info("Application registered!")
except (OSError, subprocess.CalledProcessError):
error_msg(window, "Error setting default application",
'error', traceback.format_exc())
finally:
shutil.rmtree(dirname)

def ask_enable_usage_report(self):
dialog = QtGui.QDialog()
dialog.setWindowTitle("Anonymous usage statistics")
layout = QtGui.QVBoxLayout()
layout.addWidget(QtGui.QLabel("Send anonymous usage reports to the "
"developers?"))
dont_ask = QtGui.QCheckBox("Don't ask again")
layout.addWidget(dont_ask)
buttons = QtGui.QDialogButtonBox(
QtGui.QDialogButtonBox.Yes | QtGui.QDialogButtonBox.No)
layout.addWidget(buttons)
buttons.accepted.connect(dialog.accept)
buttons.rejected.connect(dialog.reject)
dialog.setLayout(layout)

res = dialog.exec_()
if res == QtGui.QDialog.Accepted:
usage_report.enable_reporting()
elif dont_ask.isChecked():
usage_report.disable_reporting()

def event(self, event):
if event.type() == QtCore.QEvent.FileOpen:
record_usage(fileopenevent=True)
# Create new window for this RPZ
window = ReprounzipUi(unpack=dict(package=event.file()))
window.setVisible(True)
Expand All @@ -130,6 +168,8 @@ def set_first_window(self, window):
self.windows.add(window)
if platform.system().lower() == 'linux':
self.linux_try_register_default(window)
if usage_report.status is usagestats.Stats.UNSET:
self.ask_enable_usage_report()


class ReprounzipUi(QtGui.QMainWindow):
Expand Down
3 changes: 1 addition & 2 deletions reprounzip-qt/reprounzip_qt/gui/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@

from __future__ import division, print_function, unicode_literals

import re

from PyQt4 import QtCore, QtGui
import re


def error_msg(parent, message, severity, details=None):
Expand Down
23 changes: 20 additions & 3 deletions reprounzip-qt/reprounzip_qt/gui/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@

from __future__ import division, print_function, unicode_literals

import yaml

from PyQt4 import QtCore, QtGui
import yaml

import reprounzip_qt.reprounzip_interface as reprounzip
from reprounzip_qt.gui.common import ROOT, ResizableStack, handle_error, \
error_msg, parse_ports
from reprounzip_qt.usage import record_usage


class RunOptions(QtGui.QWidget):
Expand Down Expand Up @@ -87,14 +87,20 @@ def options(self):

if self.tunneled_x11.isChecked():
options['args'].append('--tunneled-x11')
record_usage(docker_tunneled_x11=True)

if self.detach.isChecked():
options['args'].append('--detach')
record_usage(docker_detach=True)

nb_raw = 0
for opt in self.raw_options.text().split():
opt = opt.strip()
if opt:
nb_raw += 1
options['args'].append('--docker-option=%s' % opt)
if nb_raw:
record_usage(docker_raw_options=nb_raw)

ports = parse_ports(self.ports.text(), self)
if ports is None:
Expand All @@ -103,6 +109,7 @@ def options(self):
options['args'].extend(
['--docker-option=-p',
'--docker-option=%s:%s/%s' % (host, container, proto)])
record_usage(docker_run_port_fwd=bool(ports))

return options

Expand All @@ -126,6 +133,7 @@ def options(self):
for host, container, proto in parse_ports(self.ports.text(), self):
options['args'].append('--expose-port=%s:%s/%s' %
(host, container, proto))
record_usage(vagrant_run_port_fwd=bool(ports))

return options

Expand Down Expand Up @@ -176,6 +184,7 @@ def __init__(self, directory, unpacker=None, root=None, **kwargs):
("O" if file_status.is_output else ''),
file_status.name)
self.files_widget.addItem(text)
record_usage(iofiles=self.files_widget.count())

def _file_changed(self):
selected = [i.row() for i in self.files_widget.selectedIndexes()]
Expand Down Expand Up @@ -212,6 +221,7 @@ def _upload(self):
self, "Pick file to upload",
QtCore.QDir.currentPath())
if picked:
record_usage(file_upload=True)
handle_error(self, reprounzip.upload(
self.directory, file_status.name, picked,
unpacker=self.unpacker, root=self.root))
Expand All @@ -224,6 +234,7 @@ def _download(self):
self, "Pick destination",
QtCore.QDir.currentPath() + '/' + file_status.name)
if picked:
record_usage(file_download=True)
handle_error(self, reprounzip.download(
self.directory, file_status.name, picked,
unpacker=self.unpacker, root=self.root))
Expand All @@ -232,6 +243,7 @@ def _download(self):
def _reset(self):
selected = self.files_widget.selectedIndexes()[0].row()
file_status = self.files_status[selected]
record_usage(file_reset=True)
handle_error(self, reprounzip.upload(
self.directory, file_status.name, None,
unpacker=self.unpacker, root=self.root))
Expand Down Expand Up @@ -335,6 +347,7 @@ def _browse(self):
self, "Pick directory",
QtCore.QDir.currentPath())
if picked:
record_usage(browse_unpacked=True)
self.directory_widget.setText(picked)
self._directory_changed()

Expand Down Expand Up @@ -386,6 +399,7 @@ def _run(self):
if not runs:
error_msg(self, "No run selected", 'warning')
return
record_usage(run='%d/%d' % (len(runs), self.runs_widget.count()))
handle_error(self, reprounzip.run(
self.directory, runs=runs,
unpacker=self.unpacker,
Expand Down Expand Up @@ -419,7 +433,10 @@ def should_exit(self):
"The experiment is still unpacked with '%s'. Are you sure you "
"want to exit without removing it?" % self.unpacker,
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
return r == QtGui.QMessageBox.Yes
if r == QtGui.QMessageBox.Yes:
record_usage(leave_unpacked=True)
else:
return False
else:
return True

Expand Down

0 comments on commit df0b716

Please sign in to comment.