Subject: [PATCH staging] Add python-robotframework et al.
From: Maxim Cournoyer <[email-masked]>
To: guix-patches <[email-masked]>
Date: Wed, 03 Apr 2019 00:15:45 -0400
List-Id: <debbugs-submit.debbugs.gnu.org>

Hello!

Here's a series adding a few new Python packages to support Robot
Framework, as well as the Emacs mode to accompany it.

python-pygithub will not build reproducibly until a fix is applied to
the Python build system (to be submitted in another change).

Thanks!

Maxim

From 37c922139857952a96cf81efe4d6c8aa60893f65 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <[email-masked]>
Date: Mon, 1 Apr 2019 22:39:41 -0400
Subject: [PATCH 1/8] gnu: Add python-bumpversion.

* gnu/packages/python-xyz.scm (python-bumpversion): New variable.
---
 gnu/packages/python-xyz.scm | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/gnu/packages/python-xyz.scm b/gnu/packages/python-xyz.scm
index 366f8a0af2..85d802a3b1 100644
--- a/gnu/packages/python-xyz.scm
+++ b/gnu/packages/python-xyz.scm
@@ -2631,6 +2631,24 @@ and several other projects.")
 (define-public python2-guzzle-sphinx-theme
   (package-with-python2 python-guzzle-sphinx-theme))
 
+(define-public python-bumpversion
+  (package
+    (name "python-bumpversion")
+    (version "0.5.3")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "bumpversion" version))
+       (sha256
+        (base32
+         "0zn7694yfipxg35ikkfh7kvgl2fissha3dnqad2c5bvsvmrwhi37"))))
+    (build-system python-build-system)
+    (home-page "https://github.com/peritus/bumpversion")
+    (synopsis "Tool to bump software version")
+    (description "This tool provides a command-line interface (CLI) to bump a
+software version simply.")
+    (license license:expat)))
+
 (define-public python-rst.linker
   (package
     (name "python-rst.linker")
-- 
2.20.1

From ddd1cfe29399403bb946dd96a79741f2bd0735dd Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <[email-masked]>
Date: Mon, 1 Apr 2019 22:39:42 -0400
Subject: [PATCH 2/8] gnu: Add python-scp.

* gnu/packages/python-xyz.scm (python-scp): New variable.
---
 gnu/packages/python-xyz.scm | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/gnu/packages/python-xyz.scm b/gnu/packages/python-xyz.scm
index 85d802a3b1..bd5550b90f 100644
--- a/gnu/packages/python-xyz.scm
+++ b/gnu/packages/python-xyz.scm
@@ -2649,6 +2649,29 @@ and several other projects.")
 software version simply.")
     (license license:expat)))
 
+(define-public python-scp
+  (package
+    (name "python-scp")
+    (version "0.13.2")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "scp" version))
+       (sha256
+        (base32
+         "1crlpw9lnn58fs1c1rmh7s7s9y5gkgpgjsqlvg9qa51kq1knx7gg"))))
+    (build-system python-build-system)
+    (arguments
+     '(#:tests? #f))                     ;tests require an SSH server
+    (propagated-inputs
+     `(("python-paramiko" ,python-paramiko)))
+    (home-page "https://github.com/jbardin/scp.py")
+    (synopsis "SCP protocol module for Python and Paramiko")
+    (description "The scp module extends the Paramiko library to send and
+receive files via the SCP1 protocol, as implemented by the OpenSSH
+@command{scp} program.")
+    (license license:gpl2+)))
+
 (define-public python-rst.linker
   (package
     (name "python-rst.linker")
-- 
2.20.1

From 8cd1fb65718dd0f30dd1a3278b38f476b055dd4d Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <[email-masked]>
Date: Mon, 1 Apr 2019 22:39:43 -0400
Subject: [PATCH 3/8] gnu: Add python-deprecated.

* gnu/packages/python-xyz.scm (python-deprecated): New variable.
---
 gnu/packages/python-xyz.scm | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/gnu/packages/python-xyz.scm b/gnu/packages/python-xyz.scm
index bd5550b90f..115cfa84ab 100644
--- a/gnu/packages/python-xyz.scm
+++ b/gnu/packages/python-xyz.scm
@@ -2649,6 +2649,40 @@ and several other projects.")
 software version simply.")
     (license license:expat)))
 
+(define-public python-deprecated
+  (package
+    (name "python-deprecated")
+    (version "1.2.5")
+    (source
+     (origin
+       (method git-fetch)
+       (uri (git-reference
+             (url "https://github.com/tantale/deprecated.git")
+             (commit (string-append "v" version))))
+       (file-name (git-file-name name version))
+       (sha256
+        (base32
+         "14909glxxwwc4b9qpz2b9jdriwzi5n65ichw85xqppap5f79wcwz"))))
+    (build-system python-build-system)
+    (arguments
+     `(#:phases (modify-phases %standard-phases
+                  (replace 'check
+                    (lambda _
+                      (invoke "pytest"))))))
+    (propagated-inputs
+     `(("python-wrapt" ,python-wrapt)))
+    (native-inputs
+     `(("python-bumpversion" ,python-bumpversion)
+       ("python-pytest" ,python-pytest)
+       ("python-pytest-cov" ,python-pytest-cov)
+       ("python-sphinx" ,python-sphinx)
+       ("python-tox" ,python-tox)))
+    (home-page "https://github.com/tantale/deprecated")
+    (synopsis "Python decorator to deprecate classes, functions or methods")
+    (description "The @code{deprecated} decorator provides a convenient way to deprecate
+to deprecate classes, functions or methods.")
+    (license license:expat)))
+
 (define-public python-scp
   (package
     (name "python-scp")
-- 
2.20.1

From ab380b196e1461c0bc834c4db7f18d22560ccf59 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <[email-masked]>
Date: Mon, 1 Apr 2019 22:39:43 -0400
Subject: [PATCH 4/8] gnu: Add python-pygithub.

* gnu/packages/python-xyz.scm (python-pygithub): New variable.
---
 gnu/packages/python-xyz.scm | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/gnu/packages/python-xyz.scm b/gnu/packages/python-xyz.scm
index 115cfa84ab..d447e5c1d9 100644
--- a/gnu/packages/python-xyz.scm
+++ b/gnu/packages/python-xyz.scm
@@ -2683,6 +2683,37 @@ software version simply.")
 to deprecate classes, functions or methods.")
     (license license:expat)))
 
+(define-public python-pygithub
+  (package
+    (name "python-pygithub")
+    (version "1.43.5")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "PyGithub" version))
+       (sha256
+        (base32
+         "0wj8hs14jsds6y8jrbpfiavv603svc4k2cf100wr9ql37as04c96"))))
+    (build-system python-build-system)
+    (arguments
+     `(#:phases (modify-phases %standard-phases
+                  ;; Some tests rely on the network.
+                  (add-after 'unpack 'disable-failing-tests
+                    (lambda _
+                      (substitute* "github/tests/Issue142.py"
+                        (("testDecodeJson") "disabled_testDecodeJson"))
+                      #t)))))
+    (propagated-inputs
+     `(("python-deprecated" ,python-deprecated)
+       ("python-pyjwt" ,python-pyjwt)
+       ("python-requests" ,python-requests)))
+    (home-page "https://pygithub.readthedocs.io/en/latest/")
+    (synopsis "Python library for the GitHub API")
+    (description "This library allows managing GitHub resources such as
+repositories, user profiles, and organizations in your Python applications,
+using version 3 of the GitHub application programming interface (API).")
+    (license license:lgpl3+)))
+
 (define-public python-scp
   (package
     (name "python-scp")
-- 
2.20.1

From b066f4d300934a30d8d744912a22d581133bc402 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <[email-masked]>
Date: Mon, 1 Apr 2019 22:39:44 -0400
Subject: [PATCH 5/8] gnu: Add python-rellu.

* gnu/packages/python-xyz.scm (python-rellu): New variable.
---
 gnu/packages/python-xyz.scm | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/gnu/packages/python-xyz.scm b/gnu/packages/python-xyz.scm
index d447e5c1d9..21fa4261bb 100644
--- a/gnu/packages/python-xyz.scm
+++ b/gnu/packages/python-xyz.scm
@@ -2714,6 +2714,29 @@ repositories, user profiles, and organizations in your Python applications,
 using version 3 of the GitHub application programming interface (API).")
     (license license:lgpl3+)))
 
+(define-public python-rellu
+  (package
+    (name "python-rellu")
+    (version "0.7")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "rellu" version))
+       (sha256
+        (base32
+         "1w0arpj1sm7vh29nrbnca4pnp8sx42l07r17inwqcjjf9bhng66x"))))
+    (build-system python-build-system)
+    (propagated-inputs
+     `(("python-invoke" ,python-invoke)
+       ("python-pygithub" ,python-pygithub)))
+    (home-page "https://github.com/robotframework/rellu")
+    (synopsis "Utilities to create PyPI releases")
+    (description "This collection of utilities contains tooling and templates
+to assist in creating releases on GitHub and publishing them on PyPI.  It is
+designed to be used by Robot Framework and tools and libraries in its
+ecosystem, but can naturally be used also by other projects.")
+    (license license:asl2.0)))
+
 (define-public python-scp
   (package
     (name "python-scp")
-- 
2.20.1

From 9c0479a389ed6c849b589347bd8cce36773c0e2e Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <[email-masked]>
Date: Mon, 1 Apr 2019 22:39:45 -0400
Subject: [PATCH 6/8] gnu: Add python-robotframework.

* gnu/packages/python-xyz.scm (python-robotframework): New variable.
* gnu/packages/patches/python-robotframework-honor-source-date-epoch.patch:
Add patch.
* gnu/local.mk (dist_patch_DATA): Register it.
---
 gnu/local.mk                                  |  1 +
 ...botframework-honor-source-date-epoch.patch | 62 +++++++++++++++++++
 gnu/packages/python-xyz.scm                   | 45 ++++++++++++++
 3 files changed, 108 insertions(+)
 create mode 100644 gnu/packages/patches/python-robotframework-honor-source-date-epoch.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 1332efdcff..37a501aa71 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1191,6 +1191,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/python-pycrypto-CVE-2013-7459.patch	\
   %D%/packages/patches/python2-pygobject-2-gi-info-type-error-domain.patch \
   %D%/packages/patches/python-pygpgme-fix-pinentry-tests.patch	\
+  %D%/packages/patches/python-robotframework-honor-source-date-epoch.patch \
   %D%/packages/patches/python2-subprocess32-disable-input-test.patch	\
   %D%/packages/patches/python-unittest2-python3-compat.patch	\
   %D%/packages/patches/python-unittest2-remove-argparse.patch	\
diff --git a/gnu/packages/patches/python-robotframework-honor-source-date-epoch.patch b/gnu/packages/patches/python-robotframework-honor-source-date-epoch.patch
new file mode 100644
index 0000000000..ccd87911d8
--- /dev/null
+++ b/gnu/packages/patches/python-robotframework-honor-source-date-epoch.patch
@@ -0,0 +1,62 @@
+From 3cc41c05fad5601c0dd1832f64a6e9efca017727 Mon Sep 17 00:00:00 2001
+From: Maxim Cournoyer <[email-masked]>
+Date: Mon, 1 Apr 2019 11:36:04 -0400
+Subject: [PATCH] robottime: Honor the SOURCE_DATE_EPOCH environment variable.
+
+Honoring the SOURCE_DATE_EPOCH environment variable allows building
+the documentation using libdoc reproducibly, by setting the generated
+timestamp to a fixed value.
+
+For more background on reproducible builds and the SOURCE_DATE_EPOCH
+environment variable, see:
+https://reproducible-builds.org/specs/source-date-epoch/.
+
+* src/robot/utils/robottime.py: import `os'.
+(TimestampCache._get_epoch): Retrieve date from SOURCE_DATE_EPOCH if
+it is defined, otherwise from time.time().
+* utest/output/test_logger.py (TestLogger.test_write_to_one_logger):
+Check for the existance of a timestamp attribute instead of checking
+for its content as the later is easy to break when using the
+SOURCE_DATE_EPOCH environment variable.
+---
+ src/robot/utils/robottime.py | 3 +++
+ utest/output/test_logger.py  | 2 +-
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/src/robot/utils/robottime.py b/src/robot/utils/robottime.py
+index 06432a4a6..91526f826 100644
+--- a/src/robot/utils/robottime.py
++++ b/src/robot/utils/robottime.py
+@@ -14,6 +14,7 @@
+ #  limitations under the License.
+ 
+ import datetime
++import os
+ import time
+ import re
+ 
+@@ -395,6 +396,8 @@ class TimestampCache(object):
+ 
+     # Seam for mocking
+     def _get_epoch(self):
++        if os.getenv('SOURCE_DATE_EPOCH'):
++            return float(os.getenv('SOURCE_DATE_EPOCH'))
+         return time.time()
+ 
+     def _use_cache(self, secs, *separators):
+diff --git a/utest/output/test_logger.py b/utest/output/test_logger.py
+index 92fe6d77d..e980227aa 100644
+--- a/utest/output/test_logger.py
++++ b/utest/output/test_logger.py
+@@ -46,7 +46,7 @@ class TestLogger(unittest.TestCase):
+         logger = LoggerMock(('Hello, world!', 'INFO'))
+         self.logger.register_logger(logger)
+         self.logger.write('Hello, world!', 'INFO')
+-        assert_true(logger.msg.timestamp.startswith('20'))
++        assert_true(hasattr(logger.msg, 'timestamp'))
+ 
+     def test_write_to_one_logger_with_trace_level(self):
+         logger = LoggerMock(('expected message', 'TRACE'))
+-- 
+2.20.1
+
diff --git a/gnu/packages/python-xyz.scm b/gnu/packages/python-xyz.scm
index 21fa4261bb..5213eea4f6 100644
--- a/gnu/packages/python-xyz.scm
+++ b/gnu/packages/python-xyz.scm
@@ -2737,6 +2737,51 @@ designed to be used by Robot Framework and tools and libraries in its
 ecosystem, but can naturally be used also by other projects.")
     (license license:asl2.0)))
 
+(define-public python-robotframework
+  (package
+    (name "python-robotframework")
+    (version "3.1.1")
+    ;; There are no tests in the PyPI archive.
+    (source
+     (origin
+       (method git-fetch)
+       (uri (git-reference
+             (url "https://github.com/robotframework/robotframework.git")
+             (commit (string-append "v" version))))
+       (file-name (git-file-name name version))
+       (sha256
+        (base32
+         "1aaiamc9l35m5sf7xl2qc5q9308v7sz3p1qgzcslsjxzddphyn4v"))
+       (patches (search-patches
+                 "python-robotframework-honor-source-date-epoch.patch"))))
+    (build-system python-build-system)
+    (arguments
+     `(#:phases (modify-phases %standard-phases
+                  (add-before 'build 'build-and-install-doc
+                    (lambda* (#:key outputs #:allow-other-keys)
+                      (let* ((doc-output (assoc-ref outputs "doc"))
+                             (doc (string-append doc-output "/share/"
+                                                 ,name "-" ,version "/")))
+                        (invoke "invoke" "library-docs" "all")
+                        (mkdir-p doc)
+                        (copy-recursively "doc/libraries"
+                                          (string-append doc "/libraries"))
+                        #t)))
+                  (replace 'check
+                    (lambda _
+                      (invoke "python" "utest/run.py"))))))
+    (native-inputs
+     `(("python-invoke" ,python-invoke)
+       ("python-rellu" ,python-rellu)
+       ("python:tk" ,python "tk")))     ;used when building the HTML doc
+    (outputs '("out" "doc"))
+    (home-page "https://robotframework.org")
+    (synopsis "Generic automation framework")
+    (description "Robot Framework is a generic automation framework for
+acceptance testing, acceptance test driven development (ATDD), and robotic
+process automation (RPA).")
+    (license license:asl2.0)))
+
 (define-public python-scp
   (package
     (name "python-scp")
-- 
2.20.1

From 07321e51e5cbeae1dee8920cbb653a03ae7a1789 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <[email-masked]>
Date: Mon, 1 Apr 2019 22:39:45 -0400
Subject: [PATCH 7/8] gnu: Add python-robotframework-sshlibrary.

* gnu/packages/python-xyz.scm (python-robotframework-sshlibrary): New variable.
---
 gnu/packages/python-xyz.scm | 61 +++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/gnu/packages/python-xyz.scm b/gnu/packages/python-xyz.scm
index 5213eea4f6..6c23dad1bf 100644
--- a/gnu/packages/python-xyz.scm
+++ b/gnu/packages/python-xyz.scm
@@ -2782,6 +2782,67 @@ acceptance testing, acceptance test driven development (ATDD), and robotic
 process automation (RPA).")
     (license license:asl2.0)))
 
+(define-public python-robotframework-sshlibrary
+  (package
+    (name "python-robotframework-sshlibrary")
+    (version "3.3.0")
+    ;; There are no tests in the PyPI archive.
+    (source
+     (origin
+       (method git-fetch)
+       (uri (git-reference
+             (url "https://github.com/robotframework/SSHLibrary.git")
+             (commit (string-append "v" version))))
+       (file-name (git-file-name name version))
+       (sha256
+        (base32
+         "1mk6dz2jqqndbx4yji09012q6rmadnqdywi7czvj62b0s07dr3r2"))))
+    (build-system python-build-system)
+    (arguments
+     `(#:phases
+       (modify-phases %standard-phases
+         (add-before 'build 'build-and-install-doc
+           (lambda* (#:key outputs #:allow-other-keys)
+             (let* ((doc-output (assoc-ref outputs "doc"))
+                    (doc (string-append doc-output "/share/"
+                                        ,name "-" ,version "/")))
+               (invoke "chmod" "-R" "+w" "docs")
+               (invoke "invoke" "kw-docs" "project-docs")
+               (mkdir-p doc)
+               (for-each delete-file (find-files "docs" "\\.rst"))
+               (copy-recursively "docs" doc)
+               #t)))
+         (replace 'check
+           (lambda _
+             ;; Some tests require an SSH server; we remove them.
+             (delete-file "utest/test_client_api.py")
+             (delete-file "utest/test_scp.py")
+             (invoke "python" "utest/run.py"))))))
+    (propagated-inputs
+     `(("python-robotframework" ,python-robotframework)
+       ("python-paramiko" ,python-paramiko)
+       ("python-scp" ,python-scp)))
+    (native-inputs
+     `(("openssh" ,openssh)
+       ("which" ,which)
+       ;; To generate the documentation
+       ("python-docutils" ,python-docutils)
+       ("python-invoke" ,python-invoke)
+       ("python-pygments" ,python-pygments)
+       ("python-rellu" ,python-rellu)))
+    (outputs '("out" "doc"))
+    (home-page "https://github.com/robotframework/SSHLibrary")
+    (synopsis "Robot Framework library for SSH and SFTP")
+    (description "SSHLibrary is a Robot Framework library providing support
+for SSH and SFTP.  It has the following main usages:
+@itemize @bullet
+@item Executing commands on the remote machine, either blocking or non-blocking.
+@item Writing and reading in an interactive shell.
+@item Transferring files and directories over SFTP.
+@item Ensuring that files and directories exist on the remote machine.
+@end itemize")
+    (license license:asl2.0)))
+
 (define-public python-scp
   (package
     (name "python-scp")
-- 
2.20.1

From 8c843de4a97752aba5563912236ce5e22ee3f9d1 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <[email-masked]>
Date: Mon, 1 Apr 2019 22:39:46 -0400
Subject: [PATCH 8/8] gnu: Add emacs-robot-mode.

* gnu/packages/emacs-xyz.scm (emacs-robot-mode): New variable.
---
 gnu/packages/emacs-xyz.scm | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/gnu/packages/emacs-xyz.scm b/gnu/packages/emacs-xyz.scm
index 1e8d703ce3..aa1dad2a8e 100644
--- a/gnu/packages/emacs-xyz.scm
+++ b/gnu/packages/emacs-xyz.scm
@@ -2548,6 +2548,31 @@ definitions, modules and classes, display method documentation and provide
 method and constant name completion.")
     (license license:gpl3+)))
 
+(define-public emacs-robot-mode
+  (let ((commit "32846e7e80ae3471b7c07f9709dcaa4f9b9ed4a0")
+        (revision "1"))
+    (package
+      (name "emacs-robot-mode")
+      (version (git-version "0.0.0" revision commit))
+      (source (origin
+                (method git-fetch)
+                (uri (git-reference
+                      ;; A better maintained fork of robot-mode.
+                      (url "https://github.com/jvalkeejarvi/robot-mode.git")
+                      (commit commit)))
+                (file-name (git-file-name name version))
+                (sha256
+                 (base32
+                  "1i8wf7m0gml8zvvmlgppjzv78b432686p1qdbzgclc7qfcvzag0d"))))
+      (build-system emacs-build-system)
+      (propagated-inputs `(("emacs-s" ,emacs-s)))
+      (home-page "https://github.com/jvalkeejarvi/robot-mode")
+      (synopsis "Emacs mode for Robot Framework")
+      (description "This major mode facilitates editing Robot Framework source
+files with features such as syntax highlighting, comments, finding keywords,
+completing keywords and smart indentation.")
+      (license license:gpl3+))))
+
 (define-public emacs-rspec
   (package
     (name "emacs-rspec")
-- 
2.20.1