patchutils.scm 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2014, 2018 Eric Bavier <bavier@member.fsf.org>
  3. ;;; Copyright © 2015, 2018 Leo Famulari <leo@famulari.name>
  4. ;;; Copyright © 2018–2021 Tobias Geerinckx-Rice <me@tobias.gr>
  5. ;;; Copyright © 2019 Christopher Baines <mail@cbaines.net>
  6. ;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
  7. ;;;
  8. ;;; This file is part of GNU Guix.
  9. ;;;
  10. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  11. ;;; under the terms of the GNU General Public License as published by
  12. ;;; the Free Software Foundation; either version 3 of the License, or (at
  13. ;;; your option) any later version.
  14. ;;;
  15. ;;; GNU Guix is distributed in the hope that it will be useful, but
  16. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. ;;; GNU General Public License for more details.
  19. ;;;
  20. ;;; You should have received a copy of the GNU General Public License
  21. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  22. (define-module (gnu packages patchutils)
  23. #:use-module (guix utils)
  24. #:use-module (guix packages)
  25. #:use-module (guix licenses)
  26. #:use-module (guix download)
  27. #:use-module (guix git-download)
  28. #:use-module (guix build-system gnu)
  29. #:use-module (guix build-system python)
  30. #:use-module (gnu packages)
  31. #:use-module (gnu packages ed)
  32. #:use-module (gnu packages base)
  33. #:use-module (gnu packages bash)
  34. #:use-module (gnu packages check)
  35. #:use-module (gnu packages databases)
  36. #:use-module (gnu packages django)
  37. #:use-module (gnu packages file)
  38. #:use-module (gnu packages gawk)
  39. #:use-module (gnu packages gettext)
  40. #:use-module (gnu packages glib)
  41. #:use-module (gnu packages gnome)
  42. #:use-module (gnu packages gtk)
  43. #:use-module (gnu packages less)
  44. #:use-module (gnu packages mail)
  45. #:use-module (gnu packages ncurses)
  46. #:use-module (gnu packages perl)
  47. #:use-module (gnu packages python)
  48. #:use-module (gnu packages python-xyz)
  49. #:use-module (gnu packages version-control)
  50. #:use-module (gnu packages xml))
  51. (define-public patchutils
  52. (package
  53. (name "patchutils")
  54. (version "0.4.2")
  55. (source
  56. (origin
  57. (method url-fetch)
  58. (uri (string-append "http://cyberelk.net/tim/data/patchutils/stable/"
  59. name "-" version ".tar.xz"))
  60. (sha256
  61. (base32
  62. "1va5pzmxbzpi87vdnbjm9qdf9bvzps9xfv0gi4mycgg3bybb0xc8"))))
  63. (build-system gnu-build-system)
  64. (inputs
  65. `(("perl" ,perl)
  66. ("python" ,python)))
  67. (arguments
  68. '(#:parallel-tests? #f
  69. #:phases
  70. (modify-phases %standard-phases
  71. (add-before 'check 'patch-test-scripts
  72. (lambda _
  73. (substitute* (find-files "tests" "^run-test$")
  74. (("/bin/echo") (which "echo")))))
  75. (add-after 'install 'wrap-program
  76. ;; Point installed scripts to the utilities they need.
  77. (lambda* (#:key inputs outputs #:allow-other-keys)
  78. (let* ((out (assoc-ref outputs "out"))
  79. (diffutils (assoc-ref inputs "diffutils"))
  80. (sed (assoc-ref inputs "sed"))
  81. (gawk (assoc-ref inputs "gawk")))
  82. (for-each
  83. (lambda (prog)
  84. (wrap-program (string-append out "/bin/" prog)
  85. `("PATH" ":" prefix
  86. ,(map (lambda (dir)
  87. (string-append dir "/bin"))
  88. (list diffutils sed gawk)))))
  89. '("dehtmldiff" "editdiff" "espdiff"))))))))
  90. (home-page "http://cyberelk.net/tim/software/patchutils")
  91. (synopsis "Collection of tools for manipulating patch files")
  92. (description
  93. "Patchutils is a collection of programs that can manipulate patch files
  94. in useful ways such as interpolating between two pre-patches, combining two
  95. incremental patches, fixing line numbers in hand-edited patches, and simply
  96. listing the files modified by a patch.")
  97. (license gpl2+)))
  98. (define-public quilt
  99. (package
  100. (name "quilt")
  101. (version "0.66")
  102. (source
  103. (origin
  104. (method url-fetch)
  105. (uri (string-append "mirror://savannah/quilt/"
  106. "quilt-" version ".tar.gz"))
  107. (sha256
  108. (base32 "01vfvk4pqigahx82fhaaffg921ivd3k7rylz1yfvy4zbdyd32jri"))))
  109. (build-system gnu-build-system)
  110. (native-inputs
  111. `(("gettext" ,gettext-minimal)))
  112. (inputs `(("perl" ,perl)
  113. ("less" ,less)
  114. ("file" ,file)
  115. ("ed" ,ed)
  116. ("diffstat" ,diffstat)))
  117. (arguments
  118. '(#:parallel-tests? #f
  119. #:phases
  120. (modify-phases %standard-phases
  121. (add-before 'check 'patch-tests
  122. (lambda _
  123. (substitute*
  124. '("test/run"
  125. "test/edit.test")
  126. (("/bin/sh") (which "sh")))
  127. #t))
  128. (add-after 'install 'wrap-program
  129. ;; quilt's configure checks for the absolute path to the utilities it
  130. ;; needs, but uses only the name when invoking them, so we need to
  131. ;; make sure the quilt script can find those utilities when run.
  132. (lambda* (#:key inputs outputs #:allow-other-keys)
  133. (let* ((out (assoc-ref outputs "out"))
  134. (coreutils (assoc-ref inputs "coreutils"))
  135. (diffutils (assoc-ref inputs "diffutils"))
  136. (findutils (assoc-ref inputs "findutils"))
  137. (diffstat (assoc-ref inputs "diffstat"))
  138. (less (assoc-ref inputs "less"))
  139. (file (assoc-ref inputs "file"))
  140. (ed (assoc-ref inputs "ed"))
  141. (sed (assoc-ref inputs "sed"))
  142. (bash (assoc-ref inputs "bash"))
  143. (grep (assoc-ref inputs "grep")))
  144. (wrap-program (string-append out "/bin/quilt")
  145. `("PATH" ":" prefix
  146. ,(map (lambda (dir)
  147. (string-append dir "/bin"))
  148. (list coreutils diffutils findutils
  149. less file ed sed bash grep
  150. diffstat)))))
  151. #t)))))
  152. (home-page "https://savannah.nongnu.org/projects/quilt/")
  153. (synopsis "Script for managing patches to software")
  154. (description
  155. "Quilt allows you to easily manage large numbers of patches by keeping
  156. track of the changes each patch makes. Patches can be applied, un-applied,
  157. refreshed, and more.")
  158. (license gpl2)))
  159. (define-public colordiff
  160. (package
  161. (name "colordiff")
  162. (version "1.0.19")
  163. (source
  164. (origin
  165. (method url-fetch)
  166. (uri (list (string-append "https://www.colordiff.org/colordiff-"
  167. version ".tar.gz")
  168. (string-append "http://www.colordiff.org/archive/colordiff-"
  169. version ".tar.gz")))
  170. (sha256
  171. (base32 "069vzzgs7b44bmfh3ks2psrdb26s1w19gp9w4xxbgi7nhx6w3s26"))))
  172. (build-system gnu-build-system)
  173. (arguments
  174. `(#:tests? #f ; no tests
  175. #:make-flags (list (string-append "DESTDIR=" (assoc-ref %outputs "out"))
  176. "INSTALL_DIR=/bin" "MAN_DIR=/share/man/man1")
  177. #:phases
  178. (modify-phases %standard-phases
  179. (delete 'configure) ; no configure script
  180. (delete 'build)))) ; nothing to build
  181. (inputs
  182. `(("perl" ,perl)
  183. ("xmlto" ,xmlto)))
  184. (home-page "https://www.colordiff.org")
  185. (synopsis "Display diff output with colors")
  186. (description
  187. "Colordiff is Perl script wrapper on top of diff command which provides
  188. 'syntax highlighting' for various patch formats.")
  189. (license gpl2+)))
  190. (define-public patches
  191. (let ((commit "ef1b8a7d954b82ed4af3a08fd63d2085d19090ef"))
  192. (package
  193. (name "patches")
  194. (home-page "https://github.com/stefanha/patches")
  195. (version (string-append "0.0-1." (string-take commit 7)))
  196. (source (origin
  197. (method git-fetch)
  198. (uri (git-reference
  199. (url home-page)
  200. (commit commit)))
  201. (sha256
  202. (base32
  203. "11rdmhv0l1s8nqb20ywmw2zqizczch2p62qf9apyx5wqgxlnjshk"))
  204. (file-name (string-append name "-"version "-checkout"))))
  205. (build-system python-build-system)
  206. (inputs `(("python-notmuch" ,python2-notmuch)))
  207. (arguments
  208. `(#:tests? #f ;no "test" target
  209. #:python ,python-2)) ;not compatible with Python 3
  210. (synopsis "Patch tracking tool")
  211. (description
  212. "@code{Patches} is a patch-tracking tool initially written for the QEMU
  213. project. It provides commands that build a database of patches from a mailing
  214. list, and commands that can search that database. It allows users to track
  215. the status of a patch, apply patches, and search for patches---all that from
  216. the command-line or from Emacs via its Notmuch integration.")
  217. (license gpl2+))))
  218. (define-public vbindiff
  219. (package
  220. (name "vbindiff")
  221. (version "3.0_beta5")
  222. (source (origin
  223. (method url-fetch)
  224. (uri (string-append "https://www.cjmweb.net/vbindiff/vbindiff-"
  225. version ".tar.gz"))
  226. (sha256
  227. (base32
  228. "1f1kj4jki08bnrwpzi663mjfkrx4wnfpzdfwd2qgijlkx5ysjkgh"))))
  229. (build-system gnu-build-system)
  230. (inputs
  231. `(("ncurses" ,ncurses)))
  232. (home-page "https://www.cjmweb.net/vbindiff/")
  233. (synopsis "Console-based tool for comparing binary data")
  234. (description "Visual Binary Diff (@command{vbindiff}) displays files in
  235. hexadecimal and ASCII (or EBCDIC). It can also display two files at once, and
  236. highlight the differences between them. It works well with large files (up to 4
  237. GiB).")
  238. (license gpl2+)))
  239. (define-public meld
  240. (package
  241. (name "meld")
  242. (version "3.20.4")
  243. (source
  244. (origin
  245. (method url-fetch)
  246. (uri (string-append "mirror://gnome/sources/meld/"
  247. (version-major+minor version)
  248. "/meld-" version ".tar.xz"))
  249. (sha256
  250. (base32 "04vx2mdbcdin0g3w8x910czfch5vyrl8drv1f2l8gxh6qvp113pl"))))
  251. (build-system python-build-system)
  252. (native-inputs
  253. `(("intltool" ,intltool)
  254. ("xmllint" ,libxml2)
  255. ("glib-compile-schemas" ,glib "bin")
  256. ("python-pytest" ,python-pytest)))
  257. (inputs
  258. `(("python-cairo" ,python-pycairo)
  259. ("python-gobject" ,python-pygobject)
  260. ("gsettings-desktop-schemas" ,gsettings-desktop-schemas)
  261. ("gtksourceview" ,gtksourceview-3)))
  262. (propagated-inputs
  263. `(("dconf" ,dconf)))
  264. (arguments
  265. `(#:imported-modules ((guix build glib-or-gtk-build-system)
  266. ,@%python-build-system-modules)
  267. #:modules ((guix build python-build-system)
  268. ((guix build glib-or-gtk-build-system) #:prefix glib-or-gtk:)
  269. (guix build utils))
  270. #:phases
  271. (modify-phases %standard-phases
  272. ;; This setup.py script does not support one of the Python build
  273. ;; system's default flags, "--single-version-externally-managed".
  274. (replace 'install
  275. (lambda* (#:key outputs #:allow-other-keys)
  276. (invoke "python" "setup.py"
  277. ;; This setup.py runs gtk-update-icon-cache which we don't want.
  278. "--no-update-icon-cache"
  279. ;; "--no-compile-schemas"
  280. "install"
  281. (string-append "--prefix=" (assoc-ref outputs "out"))
  282. "--root=/")))
  283. ;; The tests need to be run after installation.
  284. (delete 'check)
  285. (add-after 'install 'check
  286. (lambda* (#:key inputs outputs #:allow-other-keys)
  287. ;; Tests look for installed package
  288. (add-installed-pythonpath inputs outputs)
  289. ;; The tests fail when HOME=/homeless-shelter.
  290. (setenv "HOME" "/tmp")
  291. (invoke "py.test" "-v" "-k"
  292. ;; TODO: Those tests fail, why?
  293. "not test_classify_change_actions")))
  294. (add-after 'install 'copy-styles
  295. (lambda* (#:key inputs outputs #:allow-other-keys)
  296. (let ((styles "/share/gtksourceview-3.0/styles"))
  297. (copy-recursively
  298. (string-append (assoc-ref inputs "gtksourceview") styles)
  299. (string-append (assoc-ref outputs "out") styles))
  300. #t)))
  301. (add-after 'wrap 'glib-or-gtk-wrap
  302. (assoc-ref glib-or-gtk:%standard-phases 'glib-or-gtk-wrap))
  303. (add-after 'wrap 'wrap-typelib
  304. (lambda* (#:key inputs outputs #:allow-other-keys)
  305. (let ((out (assoc-ref outputs "out")))
  306. (wrap-program (string-append out "/bin/meld")
  307. `("GI_TYPELIB_PATH" prefix
  308. ,(search-path-as-string->list (getenv "GI_TYPELIB_PATH"))))
  309. #t))))))
  310. (home-page "https://meldmerge.org/")
  311. (synopsis "Compare files, directories and working copies")
  312. (description "Meld is a visual diff and merge tool targeted at
  313. developers. Meld helps you compare files, directories, and version controlled
  314. projects. It provides two- and three-way comparison of both files and
  315. directories, and has support for many popular version control systems.
  316. Meld helps you review code changes and understand patches. It might even help
  317. you to figure out what is going on in that merge you keep avoiding.")
  318. (license gpl2)))
  319. (define-public patchwork
  320. (package
  321. (name "patchwork")
  322. (version "3.0.1")
  323. (source (origin
  324. (method git-fetch)
  325. (uri (git-reference
  326. (url "https://github.com/getpatchwork/patchwork")
  327. (commit (string-append "v" version))))
  328. (file-name (git-file-name name version))
  329. (sha256
  330. (base32
  331. "049ih1fbbbmj11v5m9ilahifl8x7gi6wyba58552y9n9djzs8csc"))))
  332. (build-system python-build-system)
  333. (arguments
  334. `(;; TODO: Tests require a running database
  335. #:tests? #f
  336. #:phases
  337. (modify-phases %standard-phases
  338. (delete 'configure)
  339. (delete 'build)
  340. (add-after 'unpack 'replace-wsgi.py
  341. (lambda* (#:key inputs outputs #:allow-other-keys)
  342. (delete-file "patchwork/wsgi.py")
  343. (call-with-output-file "patchwork/wsgi.py"
  344. (lambda (port)
  345. ;; Embed the PYTHONPATH containing the dependencies, as well
  346. ;; as the python modules in this package in the wsgi.py file,
  347. ;; as this will ensure they are available at runtime.
  348. (define pythonpath
  349. (string-append (getenv "GUIX_PYTHONPATH")
  350. ":"
  351. (site-packages inputs outputs)))
  352. (display
  353. (string-append "
  354. import os, sys
  355. sys.path.extend('" pythonpath "'.split(':'))
  356. from django.core.wsgi import get_wsgi_application
  357. # By default, assume that patchwork is running as a Guix service, which
  358. # provides the settings as the 'guix.patchwork.settings' Python module.
  359. #
  360. # When using httpd, it's hard to set environment variables, so rely on the
  361. # default set here.
  362. os.environ['DJANGO_SETTINGS_MODULE'] = os.getenv(
  363. 'DJANGO_SETTINGS_MODULE',
  364. 'guix.patchwork.settings' # default
  365. )
  366. application = get_wsgi_application()\n") port)))))
  367. (replace 'check
  368. (lambda* (#:key tests? #:allow-other-keys)
  369. (when tests?
  370. (setenv "DJANGO_SETTINGS_MODULE" "patchwork.settings.dev")
  371. (invoke "python" "-Wonce" "./manage.py" "test" "--noinput"))
  372. #t))
  373. (replace 'install
  374. (lambda* (#:key inputs outputs #:allow-other-keys)
  375. (let ((out (assoc-ref outputs "out"))
  376. (out-site-packages (site-packages inputs outputs)))
  377. (for-each (lambda (directory)
  378. (copy-recursively
  379. directory
  380. (string-append out-site-packages directory)))
  381. '(;; Contains the python code
  382. "patchwork"
  383. ;; Contains the templates for the generated HTML
  384. "templates"))
  385. (delete-file-recursively
  386. (string-append out-site-packages "patchwork/tests"))
  387. ;; Install patchwork related tools
  388. (for-each (lambda (file)
  389. (install-file file (string-append out "/bin")))
  390. (list
  391. (string-append out-site-packages
  392. "patchwork/bin/parsemail.sh")
  393. (string-append out-site-packages
  394. "patchwork/bin/parsemail-batch.sh")))
  395. ;; Collect the static assets, this includes JavaScript, CSS and
  396. ;; fonts. This is a standard Django process when running a
  397. ;; Django application for regular use, and includes assets for
  398. ;; dependencies like the admin site from Django.
  399. ;;
  400. ;; The intent here is that you can serve files from this
  401. ;; directory through a webserver, which is recommended when
  402. ;; running Django applications.
  403. (let ((static-root
  404. (string-append out "/share/patchwork/htdocs")))
  405. (mkdir-p static-root)
  406. (copy-file "patchwork/settings/production.example.py"
  407. "patchwork/settings/assets.py")
  408. (setenv "DJANGO_SECRET_KEY" "dummyvalue")
  409. (setenv "DJANGO_SETTINGS_MODULE" "patchwork.settings.assets")
  410. (setenv "STATIC_ROOT" static-root)
  411. (invoke "./manage.py" "collectstatic" "--no-input"))
  412. ;; The lib directory includes example configuration files that
  413. ;; may be useful when deploying patchwork.
  414. (copy-recursively "lib"
  415. (string-append
  416. out "/share/doc/" ,name "-" ,version)))
  417. #t))
  418. ;; The hasher script is used from the post-receive.hook
  419. (add-after 'install 'install-hasher
  420. (lambda* (#:key inputs outputs #:allow-other-keys)
  421. (let* ((out (assoc-ref outputs "out"))
  422. (out-site-packages (site-packages inputs outputs))
  423. (out-hasher.py (string-append out-site-packages
  424. "/patchwork/hasher.py")))
  425. (chmod out-hasher.py #o555)
  426. (symlink out-hasher.py (string-append out "/bin/hasher")))
  427. #t))
  428. ;; Create a patchwork specific version of Django's command line admin
  429. ;; utility.
  430. (add-after 'install 'install-patchwork-admin
  431. (lambda* (#:key inputs outputs #:allow-other-keys)
  432. (let* ((out (assoc-ref outputs "out")))
  433. (mkdir-p (string-append out "/bin"))
  434. (call-with-output-file (string-append out "/bin/patchwork-admin")
  435. (lambda (port)
  436. (simple-format port "#!~A
  437. import os, sys
  438. if __name__ == \"__main__\":
  439. from django.core.management import execute_from_command_line
  440. execute_from_command_line(sys.argv)" (which "python"))))
  441. (chmod (string-append out "/bin/patchwork-admin") #o555))
  442. #t)))))
  443. (inputs
  444. `(("python-wrapper" ,python-wrapper)))
  445. (propagated-inputs
  446. `(("python-django" ,python-django-2.2)
  447. ;; TODO: Make this configurable
  448. ("python-psycopg2" ,python-psycopg2)
  449. ("python-mysqlclient" ,python-mysqlclient)
  450. ("python-django-filter" ,python-django-filter)
  451. ("python-djangorestframework" ,python-djangorestframework)
  452. ("python-django-debug-toolbar" ,python-django-debug-toolbar)))
  453. (synopsis "Web based patch tracking system")
  454. (description
  455. "Patchwork is a patch tracking system. It takes in emails containing
  456. patches, and displays the patches along with comments and state information.
  457. Users can login allowing them to change the state of patches.")
  458. (home-page "http://jk.ozlabs.org/projects/patchwork/")
  459. (license gpl2+)))
  460. (define-public pwclient
  461. (package
  462. (name "pwclient")
  463. (version "1.3.0")
  464. (source (origin
  465. (method git-fetch)
  466. (uri (git-reference
  467. (url "https://github.com/getpatchwork/pwclient")
  468. (commit version)))
  469. (file-name (git-file-name name version))
  470. (sha256
  471. (base32
  472. "1xckwvcqklzpyh3xs4k2zm40ifp0q5fdkj2vmgb8vhfvl1ivs6jv"))))
  473. (build-system python-build-system)
  474. (arguments
  475. `(#:phases
  476. (modify-phases %standard-phases
  477. (add-after 'unpack 'patch-requirements
  478. (lambda _
  479. (substitute* "test-requirements.txt"
  480. ;; The pytest requirement is unnecessarily strict
  481. (("pytest>=3.0,<5.0;")
  482. "pytest>=3.0,<6.0;"))
  483. #t))
  484. (add-before 'build 'set-PBR_VERSION
  485. (lambda _
  486. (setenv "PBR_VERSION"
  487. ,version)
  488. #t))
  489. (replace 'check
  490. (lambda* (#:key tests? #:allow-other-keys)
  491. (when tests?
  492. (invoke "pytest"))
  493. #t))
  494. (add-after 'install 'install-man-page
  495. (lambda* (#:key outputs #:allow-other-keys)
  496. (install-file "man/pwclient.1"
  497. (string-append
  498. (assoc-ref outputs "out")
  499. "/share/man/man1"))
  500. #t)))))
  501. (native-inputs
  502. `(("python-pbr" ,python-pbr)
  503. ("python-pytest" ,python-pytest)
  504. ("python-pytest-cov" ,python-pytest-cov)
  505. ("python-mock" ,python-mock)))
  506. (home-page
  507. "https://github.com/getpatchwork/pwclient")
  508. (synopsis "Command-line client for the Patchwork patch tracking tool")
  509. (description
  510. "pwclient is a VCS-agnostic tool for interacting with Patchwork, the
  511. web-based patch tracking system.")
  512. (license gpl2+)))