~singpolyma/cheogram-smtp

c4cb10c489af64504e6b963857d6433dd4449d3b — Stephen Paul Weber 1 year, 2 months ago 7aa9b1a
Guixify
7 files changed, 1144 insertions(+), 8 deletions(-)

A .builds/guix.yml
A Makefile
M cheogram-smtp.cabal
M gateway.hs
A guix.scm
M incoming-email.hs
A manifest.scm
A .builds/guix.yml => .builds/guix.yml +34 -0
@@ 0,0 1,34 @@
image: guix
packages:
- plzip
sources:
- https://git.singpolyma.net/cheogram-smtp
secrets:
- 9ded4157-4cf9-42ae-b7d0-55eb6e52ea37
- fd52c9ce-04e8-4684-af6c-1ab78d2e124a
artifacts:
- cheogram-smtp.scm
- cheogram-smtp.nar.lz
tasks:
- bake: |
    printf "(define-module (cheogram-smtp))\n" >> cheogram-smtp.scm
    sed '/^;;;;$/q' cheogram-smtp/guix.scm >> cheogram-smtp.scm
    printf "(define-public cheogram-smtp\n\t" >> cheogram-smtp.scm
    cd cheogram-smtp
    printf '(load "%s/guix.scm")\n(write (bake cheogram-smtp-template))\n' "$(pwd)" | guix repl /dev/stdin >> ../cheogram-smtp.scm
    cd -
    printf ")\n" >> cheogram-smtp.scm
    rm -f cheogram-smtp/guix.scm
    [ "$BUILD_REASON" = patchset ] || rm -rf cheogram-smtp
- build: |
    if [ "$BUILD_REASON" = patchset ]; then with_source="--with-source=$PWD/cheogram-smtp"; fi
    guix build $with_source --no-grafts -r out -L. cheogram-smtp
- archive: |
    if [ -e signing-key.sec ]; then
      sudo mv signing-key.pub /etc/guix/
      sudo mv signing-key.sec /etc/guix/
      sudo chown root:root /etc/guix/signing-key.sec
      sudo chmod 0400 /etc/guix/signing-key.sec
    fi
    guix archive --export -r --no-grafts $(readlink -f out-*) > cheogram-smtp.nar
    plzip cheogram-smtp.nar

A Makefile => Makefile +25 -0
@@ 0,0 1,25 @@
GHCFLAGS=-Wall -Wno-tabs -Wno-orphans -Wno-name-shadowing -XHaskell2010 -O -threaded
HLINTFLAGS=-XHaskell2010 -XCPP -i 'Use camelCase' -i 'Use String' -i 'Use head' -i 'Use string literal' -i 'Use list comprehension'

.PHONY: all shell clean

all: report.html gateway incoming-email incoming-mms

gateway: Email.hs IQManager.hs Router.hs Util.hs VCard.hs gateway.hs
	ghc -dynamic -o gateway $(GHCFLAGS) gateway.hs

incoming-email: Email.hs IQManager.hs Util.hs VCard.hs incoming-email.hs
	ghc -dynamic -o incoming-email $(GHCFLAGS) incoming-email.hs

incoming-mms: Email.hs IQManager.hs Util.hs MMS.hs incoming-mms.hs
	ghc -dynamic -o incoming-mms $(GHCFLAGS) incoming-mms.hs

report.html: Email.hs IQManager.hs Router.hs Util.hs VCard.hs MMS.hs gateway.hs incoming-email.hs incoming-mms.hs
	-hlint $(HLINTFLAGS) --report $^

shell:
	ghci $(GHCFLAGS)

clean:
	find -name '*.o' -o -name '*.hi' | xargs $(RM)
	$(RM) gateway incoming-email incoming-mms report.html

M cheogram-smtp.cabal => cheogram-smtp.cabal +4 -4
@@ 12,7 12,7 @@ build-type:          Simple
common defs
  default-language:    Haskell2010
  ghc-options:         -Wall -Wno-tabs -Wno-orphans -Werror
  build-depends:       base                  >=4.11 && <4.14,
  build-depends:       base                  >=4.11 && <4.15,
                       aeson                 >= 1.4,
                       attoparsec            >=0.13 && <0.14,
                       basic-prelude         >=0.7 && <0.8,


@@ 24,15 24,15 @@ common defs
                       focus                 >= 1.0.1 && < 1.1,
                       http-streams          >= 0.8.0.0 && < 0.9.0.0,
                       ipld-cid              >= 0.1 && < 0.2,
                       lens                  >=4.16 && <4.19,
                       mime-mail             >=0.4 && < 0.5,
                       lens                  >=4.16 && <4.20,
                       mime-mail             >=0.4 && < 0.6,
                       mime-types            >=0.1 && < 0.2,
                       network               >= 2.6.3 && < 2.7,
                       network-protocol-xmpp >=0.4 && <0.5,
                       network-uri           >=2.6 && <2.7,
                       purebred-email        >=0.5 && <0.6,
                       stm                   >=2.4 && <2.6,
                       stm-containers        >= 1.1.0 && < 1.2,
                       stm-containers        >= 1.1.0 && < 1.3,
                       stm-delay             >=0.1 && <0.2,
                       text                  >=1.2 && <1.3,
                       time                  >=1.5 && <2.0,

M gateway.hs => gateway.hs +1 -2
@@ 8,7 8,6 @@ import Control.Concurrent              (threadDelay)
import Control.Concurrent.STM          (STM)
import Control.Error                   (exceptT, ExceptT(..), headZ, throwE)
import Control.Lens                    (over, set, at, _Right, traverseOf)
import Network                         (PortID (PortNumber))
import Data.Time.Clock                 (getCurrentTime)
import qualified Focus
import qualified StmContainers.Map     as STMMap


@@ 226,7 225,7 @@ main = do
		(s"boop@" ++ encodeUtf8 componentJidTxt)
	let Just componentJid = XMPP.parseJID componentJidTxt
	let Just trustedJids = mapM XMPP.parseJID trustedTxt
	let port = PortNumber $ read portTxt
	let port = read portTxt
	let server = XMPP.Server componentJid (textToString host) port
	let sendmail = textToString sendmailTxt


A guix.scm => guix.scm +1072 -0
@@ 0,0 1,1072 @@
(use-modules
  ((guix licenses) #:prefix license:)
  (guix packages)
  (guix download)
  (guix git-download)
  (guix build-system gnu)
  (guix build-system haskell)
  (gnu packages pkg-config)
  (gnu packages compression)
  (gnu packages tls)
  (gnu packages gsasl)
  (gnu packages gnupg)
  (gnu packages kerberos)
  (gnu packages libidn)
  (gnu packages xml)
  (gnu packages dhall)
  (gnu packages haskell)
  (gnu packages haskell-check)
  (gnu packages haskell-crypto)
  (gnu packages haskell-web)
  (gnu packages haskell-xyz)
  (gnu packages icu4c)
  (gnu packages pkg-config)
  (ice-9 rdelim)
  (ice-9 popen)
)

(define-public ghc-network
  (package
    (name "ghc-network")
    (version "2.6.3.6")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "network" version))
              (sha256
               (base32
                "198mam7ahny48p9fajznbqq16a8ya2gw0xm3gnm1si1rmc4hdplv"))))
    (build-system haskell-build-system)
    (arguments '(#:tests? #f))
    (native-inputs (list ghc-hunit ghc-temporary ghc-hspec ghc-quickcheck
                         ghc-doctest))
    (home-page "https://github.com/haskell/network")
    (synopsis "Low-level networking interface")
    (description
     "This package provides a low-level networking interface. . === High-Level
Packages Other packages provide higher level interfaces: . * connection * hookup
* network-simple . === Extended Packages @@network@@ seeks to provide a
cross-platform core for networking.  As such some APIs live in extended
libraries.  Packages in the @@network@@ ecosystem are often prefixed with
@@network-@@. . ==== @@network-bsd@@ In @@network-3.0.0.0@@ the @@Network.BSD@@
module was split off into its own package, @@network-bsd-3.0.0.0@@. . ====
@@network-uri@@ In @@network-2.6@@ the @@Network.URI@@ module was split off into
its own package, @@network-uri-2.6@@.  If you're using the @@Network.URI@@
module you can automatically get it from the right package by adding this to
your @@.cabal@@ file: . > library > build-depends: network-uri-flag")
    (license license:bsd-3)))

(define-public ghc-multihash-cryptonite
  (package
    (name "ghc-multihash-cryptonite")
    (version "0.1.0.0")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "multihash-cryptonite" version))
              (sha256
               (base32
                "0gl13kjqz14lnwz7x162fad3j99qs1xa3zabpr30q53pkzk8adsi"))))
    (build-system haskell-build-system)
    (inputs (list ghc-binary-varint ghc-cryptonite ghc-hashable ghc-memory))
    (native-inputs (list ghc-hedgehog ghc-doctest ghc-cabal-doctest))
    (home-page "https://github.com/oscoin/ipfs")
    (synopsis
     "Self-identifying hashes, implementation of <https://github.com/multiformats/multihash>")
    (description "")
    (license license:bsd-3)))

(define-public ghc-formatting
  (package
    (name "ghc-formatting")
    (version "7.2.0")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "formatting" version))
              (sha256
               (base32
                "0vbaf1p2grz8irh92d4v44f1np5kywjdjvrfygjyf57ng8bihyy0"))))
    (build-system haskell-build-system)
    (inputs (list ghc-clock ghc-old-locale ghc-scientific
                  ghc-double-conversion))
    (native-inputs (list ghc-hspec))
    (home-page "https://github.com/AJChapman/formatting#readme")
    (synopsis
     "Combinator-based type-safe formatting (like printf() or FORMAT)")
    (description
     "Combinator-based type-safe formatting (like printf() or FORMAT), modelled from
the HoleyMonoids package. .  See the README at
<https://github.com/AJChapman/formatting#readme> for more info.")
    (license license:bsd-3)))

(define-public ghc-base58-bytestring
  (package
    (name "ghc-base58-bytestring")
    (version "0.1.0")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "base58-bytestring" version))
              (sha256
               (base32
                "1ls05nzswjr6aw0wwk3q7cpv1hf0lw7vk16a5khm6l21yfcgbny2"))))
    (build-system haskell-build-system)
    (native-inputs (list ghc-quickcheck-assertions ghc-quickcheck-instances
                         ghc-tasty ghc-tasty-quickcheck))
    (home-page "https://bitbucket.org/s9gf4ult/base58-bytestring")
    (synopsis "Implementation of BASE58 transcoding for ByteStrings")
    (description
     "Implementation of BASE58 transcoding copy-pasted from haskoin package")
    (license license:public-domain)))

(define-public ghc-generic-arbitrary
  (package
    (name "ghc-generic-arbitrary")
    (version "1.0.1")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "generic-arbitrary" version))
              (sha256
               (base32
                "1ir95k98w3i7aisw3gjflzaxzgq3qamxw1bssvdbww43sgckw0cj"))))
    (build-system haskell-build-system)
    (arguments '(#:tests? #f))
    (inputs (list ghc-quickcheck))
    (home-page "https://hackage.haskell.org/package/generic-arbitrary")
    (synopsis "")
    (description
     "")
    (license license:expat)))

(define-public ghc-tasty-discover
  (package
    (name "ghc-tasty-discover")
    (version "5.0.0")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "tasty-discover" version))
              (sha256
               (base32
                "0a3h3m6hjwr9dgnr1m2zwifn1c40rhbyh55ihlrh9m98z6jpvcpf"))))
    (build-system haskell-build-system)
    (arguments '(#:tests? #f))
    (inputs (list ghc-tasty ghc-glob))
    (home-page "https://hackage.haskell.org/package/tasty-discover")
    (synopsis "")
    (description
     "")
    (license license:expat)))

(define-public ghc-tasty-tap
  (package
    (name "ghc-tasty-tap")
    (version "0.1.0")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "tasty-tap" version))
              (sha256
               (base32
                "16i7pd0xis1fyqgmsy4mq04y87ny61dh2lddnjijcf1s9jz9b6x8"))))
    (build-system haskell-build-system)
    (inputs (list ghc-tasty))
    (native-inputs (list ghc-tasty-hunit ghc-tasty-golden))
    (home-page "https://github.com/michaelxavier/tasty-tap")
    (synopsis "TAP (Test Anything Protocol) Version 13 formatter for tasty")
    (description
     "This package provides a tasty ingredient to output test results in TAP 13
format.")
    (license license:expat)))

(define-public ghc-tasty-fail-fast
  (package
    (name "ghc-tasty-fail-fast")
    (version "0.0.3")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "tasty-fail-fast" version))
              (sha256
               (base32
                "1pkqa3b1jglmy6g2sx9pyw2f6dlsg2crmgvy039xiyldl985g9w4"))))
    (build-system haskell-build-system)
    (arguments '(#:tests? #f))
    (inputs (list ghc-tasty ghc-tagged))
    (native-inputs (list ghc-tasty-hunit ghc-tasty-golden ghc-tasty-tap))
    (home-page "http://github.com/MichaelXavier/tasty-fail-fast#readme")
    (synopsis
     "Adds the ability to fail a tasty test suite on first test failure")
    (description
     "tasty-fail-fast wraps any ingredient to fail as soon as the first test fails.
For example: . @@ defaultMainWithIngredients (map failFast defaultIngredients)
tests @@ .  Your test suite will now get a @@--fail-fast@@ flag.")
    (license license:bsd-3)))

(define-public ghc-cpu
  (package
    (name "ghc-cpu")
    (version "0.1.2")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "cpu" version))
              (sha256
               (base32
                "0x19mlanmkg96h6h1i04w2i631z84y4rbk22ki4zhgsajysgw9sn"))))
    (build-system haskell-build-system)
    (home-page "http://github.com/vincenthz/hs-cpu")
    (synopsis "Cpu information and properties helpers.")
    (description
     "Lowlevel cpu routines to get basic properties of the cpu platform, like
endianness and architecture.")
    (license license:bsd-3)))

(define-public ghc-base32-z-bytestring
  (package
    (name "ghc-base32-z-bytestring")
    (version "1.0.0.0")
    (source
      (origin
        (method url-fetch)
        (uri (hackage-uri "base32-z-bytestring" version))
        (sha256
          (base32 "1r0235a2qqnavsm7jl807m555yd2k2vi2kfacw878v83zdr5qyix"))))
    (build-system haskell-build-system)
    (arguments
     `(#:phases
       (modify-phases %standard-phases
         (add-after 'unpack 'fix-internal-reference
           (lambda _
             (substitute* "base32-z-bytestring.cabal"
               (("z-base32-bytestring") "base32-z-bytestring"))
             #t)))))
    (inputs (list ghc-cpu))
    (native-inputs
      (list ghc-hedgehog
            ghc-tasty
            ghc-tasty-fail-fast
            ghc-tasty-hedgehog
            ghc-tasty-hspec))
    (home-page "https://github.com/oscoin/z-base32-bytestring")
    (synopsis "Fast z-base32 and z-base32hex codec for ByteStrings")
    (description
      "base32 and base32hex codec according to RFC4648 <http://tools.ietf.org/html/rfc4648>, extended to support z-base32 encoding according to <https://gist.github.com/maaku/8996338#file-bip-ecc32-mediawiki> . The package API is similar to base64-bytestring.")
    (license license:bsd-3)))

(define-public ghc-gnuidn
  (package
    (name "ghc-gnuidn")
    (version "0.2.2")
    (source
      (origin
        (method url-fetch)
        (uri (string-append
               "https://hackage.haskell.org/package/gnuidn/gnuidn-"
               version
               ".tar.gz"))
        (sha256
          (base32 "0vxrcp9xz5gsvx60k12991zn5c9nk3fgg0yw7dixbsjcfqgnnd31"))))
    (build-system haskell-build-system)
    (arguments
     `(#:phases
       (modify-phases %standard-phases
         (add-after 'unpack 'less-strict-dependencies
           (lambda _
             (substitute* "gnuidn.cabal"
               (("chell >= 0.4 && < 0.5") "chell <0.6"))
             #t)))))
    (inputs `(("libidn" ,libidn)))
    (native-inputs
      `(("ghc-chell" ,ghc-chell)
        ("ghc-c2hs" ,ghc-c2hs)
        ("ghc-chell-quickcheck" ,ghc-chell-quickcheck)
        ("ghc-quickcheck" ,ghc-quickcheck)
        ("pkg-config" ,pkg-config)))
    (home-page "https://john-millikin.com/software/haskell-gnuidn/")
    (synopsis "Bindings for GNU IDN")
    (description "")
    (license license:gpl3)))

(define-public ghc-gnutls
  (package
    (name "ghc-gnutls")
    (version "0.2")
    (source
      (origin
        (method url-fetch)
        (uri (string-append
               "https://hackage.haskell.org/package/gnutls/gnutls-"
               version
               ".tar.gz"))
        (sha256
          (base32 "1c5pm0d80wpgh2bkcgbvmc72agf89h8ghfnrn1m1x3fljbgzvrn0"))))
    (build-system haskell-build-system)
    (inputs
      `(("ghc-monads-tf" ,ghc-monads-tf)
        ("gnutls" ,gnutls)))
    (native-inputs `(("pkg-config" ,pkg-config)))
    (home-page "https://john-millikin.com/software/haskell-gnutls/")
    (synopsis "Bindings for GNU libgnutls")
    (description
      "You almost certainly don't want to depend on this release. . This is a pre-alpha, almost useless release; its only purpose is to enable TLS support in some of my other libraries. More complete bindings for GNU TLS will be released at a later date.")
    (license license:gpl3)))

(define-public gsasl-1
  (package
   (name "gsasl")
   (version "1.10.0")
   (source (origin
            (method url-fetch)
            (uri (string-append "mirror://gnu/gsasl/gsasl-" version
                                ".tar.gz"))
            (sha256
             (base32
              "1lv8fp01aq4jjia9g4vkx90zacl8rgmjhfi6f1wdwnh9ws7bvg45"))))
   (build-system gnu-build-system)
   (arguments
    `(#:configure-flags '("--with-gssapi-impl=mit"
                          "--disable-static")))
   (inputs
    (list libgcrypt libidn libntlm mit-krb5 zlib))
   (native-inputs
    (list ;; Needed for cross compiling.
          libgcrypt))
   (propagated-inputs
    ;; Propagate GnuTLS because libgnutls.la reads `-lnettle', and Nettle is a
    ;; propagated input of GnuTLS.
    (list gnutls))
   (synopsis "Simple Authentication and Security Layer library")
   (description
    "GNU SASL is an implementation of the Simple Authentication and
Security Layer framework.  On network servers such as IMAP or SMTP servers,
SASL is used to handle client/server authentication.  This package contains
both a library and a command-line tool to access the library.")
   (license license:gpl3+)
   (home-page "https://www.gnu.org/software/gsasl/")))

(define-public ghc-gsasl
  (package
    (name "ghc-gsasl")
    (version "0.3.7")
    (source
      (origin
        (method url-fetch)
        (uri (string-append
               "https://hackage.haskell.org/package/gsasl/gsasl-"
               version
               ".tar.gz"))
        (sha256
          (base32 "11i12r9s30jrq8hkgqagf2fd129r6ya607s9ibw549ablsxgr507"))))
    (build-system haskell-build-system)
    (arguments
      `(#:cabal-revision
        ("1" "1c806a82qd1hkxxfh1mwk0i062bz6fkaap5ys3n4x9n6wjv7ilin")))
    (inputs
      `(("ghc-monad-loops" ,ghc-monad-loops)
        ("gsasl" ,gsasl-1)))
    (native-inputs `(("pkg-config" ,pkg-config)))
    (home-page "https://git.singpolyma.net/gsasl-haskell")
    (synopsis "Bindings for GNU libgsasl")
    (description "")
    (license license:gpl3)))

(define-public ghc-libxml-sax
  (package
    (name "ghc-libxml-sax")
    (version "0.7.5")
    (source
      (origin
        (method url-fetch)
        (uri (string-append
               "https://hackage.haskell.org/package/libxml-sax/libxml-sax-"
               version
               ".tar.gz"))
        (sha256
          (base32 "0lbdq6lmiyrnzk6gkx09vvp928wj8qnqnqfzy14mfv0drj21f54r"))))
    (build-system haskell-build-system)
    (inputs
      `(("ghc-xml-types" ,ghc-xml-types)
        ("libxml2" ,libxml2)))
    (native-inputs `(("pkg-config" ,pkg-config)))
    (home-page "https://john-millikin.com/software/haskell-libxml/")
    (synopsis "Bindings for the libXML2 SAX interface")
    (description "")
    (license license:expat)))

(define-public ghc-network-simple
  (package
    (name "ghc-network-simple")
    (version "0.4.5")
    (source
      (origin
        (method url-fetch)
        (uri (hackage-uri "network-simple" version))
        (sha256
          (base32 "17hpgcwrsx2h8lrb2wwzy0anp33mn80dnwcgnqmb8prajwjvz807"))))
    (build-system haskell-build-system)
    (inputs (list ghc-network ghc-network-bsd ghc-safe-exceptions ghc-socks))
    (home-page "https://github.com/k0001/network-simple")
    (synopsis "Simple network sockets usage patterns.")
    (description
      "This module exports functions that abstract simple network socket usage patterns. . See the @changelog.md@ file in the source distribution to learn about any important changes between versions.")
    (license license:bsd-3)))

(define-public ghc-multibase
  (package
    (name "ghc-multibase")
    (version "0.1.2")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "multibase" version))
              (sha256
               (base32
                "036caj0dzhzp065dhy05flz2j5qml5pirs1y95np4hf2xv9jk32h"))))
    (build-system haskell-build-system)
    (inputs (list ghc-aeson
                  ghc-base16-bytestring
                  ghc-base32-z-bytestring
                  ghc-base58-bytestring
                  ghc-base64-bytestring
                  ghc-formatting
                  ghc-hashable
                  ghc-sandi
                  ghc-serialise
                  ghc-tagged))
    (native-inputs (list ghc-doctest ghc-quickcheck ghc-cabal-doctest))
    (home-page "https://github.com/oscoin/ipfs")
    (synopsis
     "Self-identifying base encodings, implementation of <https://github.com/multiformats/multihash>")
    (description "")
    (license license:bsd-3)))

(define-public ghc-binary-varint
  (package
    (name "ghc-binary-varint")
    (version "0.1.0.0")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "binary-varint" version))
              (sha256
               (base32
                "1i183ab4bbq3yarijnb2pwgbi9k1w1nc0fs6ph8d8xnysj6ws8l8"))))
    (build-system haskell-build-system)
    (home-page "https://github.com/oscoin/ipfs")
    (synopsis "VarInt encoding/decoding via Data.Binary")
    (description "")
    (license license:bsd-3)))

(define-public ghc-ipld-cid
  (package
    (name "ghc-ipld-cid")
    (version "0.1.0.0")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "ipld-cid" version))
              (sha256
               (base32
                "1y08j0ibcrpfcm0zv1h17zdgbl3hm3sjvm0w9bk1lzdipd6p6cwj"))))
    (build-system haskell-build-system)
    (inputs (list ghc-binary-varint ghc-cryptonite ghc-hashable ghc-multibase
                  ghc-multihash-cryptonite))
    (native-inputs (list ghc-hedgehog))
    (home-page "https://github.com/oscoin/ipfs")
    (synopsis "IPLD Content-IDentifiers <https://github.com/ipld/cid>")
    (description "")
    (license license:bsd-3)))

(define-public ghc-focus
  (package
    (name "ghc-focus")
    (version "1.0.3")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "focus" version))
              (sha256
               (base32
                "03h6gq0k5z9a7nar29qijfnd4gwxd8h16dfsig74bsdzazj50c1m"))))
    (build-system haskell-build-system)
    (native-inputs (list ghc-quickcheck
                         ghc-quickcheck-instances
                         ghc-rerebase
                         ghc-tasty
                         ghc-tasty-hunit
                         ghc-tasty-quickcheck))
    (home-page "https://github.com/nikita-volkov/focus")
    (synopsis
     "A general abstraction for manipulating elements of container data structures")
    (description
     "An API for construction of free-form strategies of access and manipulation of
elements of arbitrary data structures.  It allows to implement efficient
composite patterns, e.g., a simultaneous update and lookup of an element, and
even more complex things. .  Strategies are meant to be interpreted by the host
data structure libraries.  Thus they allow to implement all access and
modification patterns of a data structure with just a single function, which
interprets strategies. .  This library provides pure and monadic interfaces, so
it supports both immutable and mutable data structures.")
    (license license:expat)))

(define-public ghc-mime-mail
  (package
    (name "ghc-mime-mail")
    (version "0.5.1")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "mime-mail" version))
              (sha256
               (base32
                "1s1wp8v1xlvw3r4qk1lv9zpm99ihka7a785zjl6i3fq1maqq955g"))))
    (build-system haskell-build-system)
    (arguments '(#:tests? #f))
    (inputs (list ghc-base64-bytestring ghc-random ghc-blaze-builder))
    (native-inputs (list ghc-hspec))
    (home-page "http://github.com/snoyberg/mime-mail")
    (synopsis "Compose MIME email messages.")
    (description
     "Hackage documentation generation is not reliable.  For up to date documentation,
please see: <http://www.stackage.org/package/mime-mail>.")
    (license license:expat)))

(define-public ghc-network-protocol-xmpp
  (package
    (name "ghc-network-protocol-xmpp")
    (version "0.4.10")
    (source
      (origin
        (method url-fetch)
        (uri (string-append
               "https://hackage.haskell.org/package/network-protocol-xmpp/network-protocol-xmpp-"
               version
               ".tar.gz"))
        (sha256
          (base32 "03xlw8337lzwp7f5jvbvgirf546pfmfsfjvnik08qjjy1rfn5jji"))))
    (build-system haskell-build-system)
    (inputs
      (list
        ghc-gnuidn
        ghc-gnutls
        ghc-gsasl
        ghc-libxml-sax
        ghc-monads-tf
        ghc-network
        ghc-network-simple
        ghc-xml-types))
    (home-page "https://git.singpolyma.net/network-protocol-xmpp")
    (synopsis "Client library for the XMPP protocol.")
    (description "")
    (license license:gpl3)))

(define-public ghc-concise
  (package
    (name "ghc-concise")
    (version "0.1.0.1")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "concise" version))
              (sha256
               (base32
                "09crgc6gjfidlad6263253xx1di6wfhc9awhira21s0z7rddy9sw"))))
    (build-system haskell-build-system)
    (inputs (list ghc-lens))
    (native-inputs (list ghc-tasty ghc-tasty-quickcheck ghc-quickcheck
                         ghc-quickcheck-instances))
    (home-page "https://github.com/frasertweedale/hs-concise")
    (synopsis "Utilities for Control.Lens.Cons")
    (description
     "concise provides a handful of functions to extend what you can do with
Control.Lens.Cons.")
    (license license:bsd-3)))

(define-public ghc-purebred-email
  (package
    (name "ghc-purebred-email")
    (version "0.5")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "purebred-email" version))
              (sha256
               (base32
                "0ibnykfqs438fhpwcq0yqkdnr67rql7ss07fcr5qckr4zxaw8ba1"))))
    (build-system haskell-build-system)
    (inputs (list ghc-attoparsec
                  ghc-case-insensitive
                  ghc-lens
                  ghc-base64-bytestring
                  ghc-concise
                  ghc-random
                  ghc-semigroupoids
                  ghc-stringsearch))
    (native-inputs (list ghc-tasty
                         ghc-tasty-hedgehog
                         ghc-tasty-quickcheck
                         ghc-tasty-hunit
                         ghc-tasty-golden
                         ghc-hedgehog
                         ghc-quickcheck-instances))
    (home-page "https://github.com/purebred-mua/purebred-email")
    (synopsis "types and parser for email messages (including MIME)")
    (description
     "The purebred email library.  RFC 5322, MIME, etc.  See \"Data.MIME\" for usage,
examples and API documentation. .  This is a general-purpose library for
processing and constructing email messages, originally written to meet the needs
of <https://github.com/purebred-mua/purebred purebred MUA>.  Transmission and
delivery of mail are not part of this library, but /purebred-email/ could be a
useful building block for such systems. .  Features and implemented
specifications include: . - <https://tools.ietf.org/html/rfc5322 RFC 5322>
message parsing and serialisation - MIME multipart messages
(<https://tools.ietf.org/html/rfc2046 RFC 2046>) - Convenient APIs for replying
and forward/bounce - Content transfer and charset decoding/encoding - MIME
message header extensions for non-ASCII text
(<https://tools.ietf.org/html/rfc2047 RFC 2047>) - MIME parameter value and
encoded word extensions (<https://tools.ietf.org/html/rfc2231 RFC 2231>) -
@@Content-Disposition@@ header field (<https://tools.ietf.org/html/rfc2183 RFC
2183>) - Address syntax in @@From@@ and @@Sender@@ fields
(<https://tools.ietf.org/html/rfc6854 RFC 6854>)")
    (license #f)))

(define-public ghc-quickcheck-text
  (package
    (name "ghc-quickcheck-text")
    (version "0.1.2.1")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "quickcheck-text" version))
              (sha256
               (base32
                "02dbs0k6igmsa1hcw8yfvp09v7038vp4zlsp9706km3cmswgshj4"))))
    (build-system haskell-build-system)
    (inputs (list ghc-quickcheck))
    (home-page "https://github.com/olorin/quickcheck-text")
    (synopsis "Alternative arbitrary instance for Text")
    (description
     "The usual Arbitrary instance for Text (in
<https://hackage.haskell.org/package/quickcheck-instances quickcheck-instances>)
only has single-byte instances and so isn't an ideal representation of a valid
UTF-8 character.  This package has generators for one-, two- and three-byte
UTF-8 characters (all that are currently in use).")
    (license license:expat)))

(define-public ghc-primitive-unlifted
  (package
    (name "ghc-primitive-unlifted")
    (version "0.1.3.1")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "primitive-unlifted" version))
              (sha256
               (base32
                "1gilzgclpvz200sybw86nmdm7084nrklscq48cs36qqlgcd0wcwb"))))
    (build-system haskell-build-system)
    (inputs (list ghc-primitive ghc-text-short))
    (native-inputs (list ghc-quickcheck-classes-base ghc-quickcheck
                         ghc-tasty-quickcheck ghc-tasty))
    (home-page "https://github.com/haskell-primitive/primitive-unlifted")
    (synopsis "Primitive GHC types with unlifted types inside")
    (description
     "Primitive GHC types with unlifted types inside.  There used to be a module named
`Data.Primitive.UnliftedArray` in the `primitive` library.  However, it turns
out that it is impossible to write such an API safely in versions of GHC before
8.10.1, thanks to some nasty interactions between unsafe coercions and the
foreign function interface.  This package also uses a somewhat different, and
more flexible, approach than that module did.")
    (license license:bsd-3)))

(define-public ghc-primitive-extras
  (package
    (name "ghc-primitive-extras")
    (version "0.10.1.5")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "primitive-extras" version))
              (sha256
               (base32
                "0xmigva8lss9h18q0a63mc9sridny40nyzkizr2vmgm5d9qniqjs"))))
    (build-system haskell-build-system)
    (inputs (list ghc-cereal
                  ghc-deferred-folds
                  ghc-focus
                  ghc-foldl
                  ghc-list-t
                  ghc-primitive
                  ghc-primitive-unlifted
                  ghc-profunctors
                  ghc-vector))
    (native-inputs (list ghc-quickcheck
                         ghc-quickcheck-instances
                         ghc-rerebase
                         ghc-tasty
                         ghc-tasty-hunit
                         ghc-tasty-quickcheck))
    (home-page "https://github.com/metrix-ai/primitive-extras")
    (synopsis "Extras for the \"primitive\" library")
    (description "")
    (license license:expat)))

(define-public ghc-stm-hamt
  (package
    (name "ghc-stm-hamt")
    (version "1.2.0.8")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "stm-hamt" version))
              (sha256
               (base32
                "1p3njvg5sixsgk12rldmvgcj8flmh00w968mzaavxl4j4axd8x3c"))))
    (build-system haskell-build-system)
    (inputs (list ghc-deferred-folds
                  ghc-focus
                  ghc-hashable
                  ghc-list-t
                  ghc-primitive
                  ghc-primitive-extras))
    (native-inputs (list ghc-quickcheck
                         ghc-quickcheck-instances
                         ghc-rerebase
                         ghc-tasty
                         ghc-tasty-hunit
                         ghc-tasty-quickcheck))
    (home-page "https://github.com/nikita-volkov/stm-hamt")
    (synopsis "STM-specialised Hash Array Mapped Trie")
    (description
     "This package provides a low-level data-structure, which can be used to implement
higher-level interfaces like hash-map and hash-set.  Such implementations are
presented by <http://hackage.haskell.org/package/stm-containers the
\"stm-containers\" library>.")
    (license license:expat)))

(define-public ghc-mtl-prelude
  (package
    (name "ghc-mtl-prelude")
    (version "2.0.3.1")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "mtl-prelude" version))
              (sha256
               (base32
                "0cqjl0mcnj6qgx46qxjygndzlgch4mc0q0sm3wbd4fynjfhdv9n4"))))
    (build-system haskell-build-system)
    (home-page "https://github.com/nikita-volkov/mtl-prelude")
    (synopsis
              "Reexports of most definitions from \"mtl\" and \"transformers\"")
    (description
     "This package only exports definitions from the \\\"mtl\\\" and \\\"transformers\\\"
libraries.  Unlike every module of \\\"mtl\\\" it does not reexport
@@Control.Monad@@ and @@Control.Monad.Fix@@. .  In combination with the
<http://hackage.haskell.org/package/base-prelude \"base-prelude\"> library, this
should give you a quite rich prelude. .  The @@2.*@@ versions are restricted by
the feature set of @@mtl-2.2@@ and @@transformers-0.4@@, however they provide
support for newer versions of those libraries as well.")
    (license license:expat)))

(define-public ghc-xmlgen
  (package
    (name "ghc-xmlgen")
    (version "0.6.2.2")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "xmlgen" version))
              (sha256
               (base32
                "1milbbr2iqwckqbq6i9sypinvs4hs7mzqn274x350psjfy6ajvwj"))))
    (build-system haskell-build-system)
    (inputs (list ghc-blaze-builder))
    (native-inputs (list ghc-hxt ghc-hunit ghc-quickcheck))
    (arguments
     `(#:tests? #f #:cabal-revision ("1"
                         "0vwnqd0lsw81llsn0psga5r6pw7jh69vfbj3rnz7c2fpkc0gjh3j")))
    (home-page "http://hackage.haskell.org/package/xmlgen")
    (synopsis "Fast XML generation library")
    (description "Library for high-performance XML generation.")
    (license license:bsd-3)))

(define-public ghc-cpphs
  (package
    (name "ghc-cpphs")
    (version "1.20.9.1")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "cpphs" version))
              (sha256
               (base32
                "17wi7fma2qaqdm1hwgaam3fd140v9bpa8ky0wg708h1pqc5v2nbz"))))
    (build-system haskell-build-system)
    (inputs (list ghc-polyparse))
    (arguments
     `(#:cabal-revision ("1"
                         "1f8jzs8zdh4wwbcq8fy6qqxkv75ypnvsm4yzw49wpr3b9vpnzlha")))
    (home-page "http://projects.haskell.org/cpphs/")
    (synopsis "A liberalised re-implementation of cpp, the C pre-processor.")
    (description
     "Cpphs is a re-implementation of the C pre-processor that is both more compatible
with Haskell, and itself written in Haskell so that it can be distributed with
compilers. .  This version of the C pre-processor is pretty-much
feature-complete and compatible with traditional (K&R) pre-processors.
Additional features include: a plain-text mode; an option to unlit literate code
files; and an option to turn off macro-expansion.")
    (license license:lgpl3)))

(define-public ghc-htf
  (package
    (name "ghc-htf")
    (version "0.15.0.0")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "HTF" version))
              (sha256
               (base32
                "16sbz9rr1v8p3b0qi6b9rvzqgbd4rr05qp2wiiy0nc2gh1qca4nq"))))
    (build-system haskell-build-system)
    (arguments '(#:tests? #f))
    (inputs (list ghc-diff
                  ghc-hunit
                  ghc-quickcheck
                  ghc-aeson
                  ghc-base64-bytestring
                  ghc-cpphs
                  ghc-haskell-src
                  ghc-lifted-base
                  ghc-monad-control
                  ghc-old-time
                  ghc-random
                  ghc-regex-compat
                  ghc-vector
                  ghc-xmlgen))
    (native-inputs (list ghc-aeson-pretty ghc-temporary
                         ghc-unordered-containers))
    (home-page "https://github.com/skogsbaer/HTF/")
    (synopsis "The Haskell Test Framework")
    (description
     "The Haskell Test Framework (/HTF/ for short) lets you define and organize unit
tests, QuickCheck properties, and black box tests in an easy and convenient way.
 HTF uses a custom preprocessor that collects test definitions automatically. .
HTF produces highly readable output for failing test cases: it provides exact
file name and line number information, it colors and pretty prints expected and
actual results, and it displays a diff highlighting the mismatching parts. .
The documentation of the \"Test.Framework.Tutorial\" module provides a tutorial
for HTF. The /sample/ provides a good starting point for a project using HTF.")
    (license license:lgpl2.1)))

(define-public ghc-list-t
  (package
    (name "ghc-list-t")
    (version "1.0.5.6")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "list-t" version))
              (sha256
               (base32
                "1ilbc3kjvqanwn4zysy9sdp45cizdqkfyibiymzb1ibg2s56a4sg"))))
    (build-system haskell-build-system)
    (inputs (list ghc-foldl ghc-logict ghc-mmorph ghc-monad-control
                  ghc-transformers-base))
    (native-inputs (list ghc-base-prelude ghc-htf ghc-mtl-prelude))
    (home-page "https://github.com/nikita-volkov/list-t")
    (synopsis "ListT done right")
    (description
     "This package provides a correct implementation of the list monad-transformer.
Useful for basic streaming.")
    (license license:expat)))

(define-public ghc-focus
  (package
    (name "ghc-focus")
    (version "1.0.3")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "focus" version))
              (sha256
               (base32
                "03h6gq0k5z9a7nar29qijfnd4gwxd8h16dfsig74bsdzazj50c1m"))))
    (build-system haskell-build-system)
    (native-inputs (list ghc-quickcheck
                         ghc-quickcheck-instances
                         ghc-rerebase
                         ghc-tasty
                         ghc-tasty-hunit
                         ghc-tasty-quickcheck))
    (home-page "https://github.com/nikita-volkov/focus")
    (synopsis
     "A general abstraction for manipulating elements of container data structures")
    (description
     "An API for construction of free-form strategies of access and manipulation of
elements of arbitrary data structures.  It allows to implement efficient
composite patterns, e.g., a simultaneous update and lookup of an element, and
even more complex things. .  Strategies are meant to be interpreted by the host
data structure libraries.  Thus they allow to implement all access and
modification patterns of a data structure with just a single function, which
interprets strategies. .  This library provides pure and monadic interfaces, so
it supports both immutable and mutable data structures.")
    (license license:expat)))

(define-public ghc-deferred-folds
  (package
    (name "ghc-deferred-folds")
    (version "0.9.18.2")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "deferred-folds" version))
              (sha256
               (base32
                "0amlxdgz1yfql1r7w6z9gy6gncihp5nm1fl2bxrk7027hc0wdp96"))))
    (build-system haskell-build-system)
    (inputs (list ghc-foldl ghc-hashable ghc-primitive
                  ghc-unordered-containers ghc-vector))
    (native-inputs (list ghc-quickcheck
                         ghc-quickcheck-instances
                         ghc-rerebase
                         ghc-tasty
                         ghc-tasty-hunit
                         ghc-tasty-quickcheck))
    (home-page "https://github.com/metrix-ai/deferred-folds")
    (synopsis "Abstractions over deferred folds")
    (description
     "This library is in an experimental state.  Users should be prepared for frequent
updates.")
    (license license:expat)))

(define-public ghc-stm-containers
  (package
    (name "ghc-stm-containers")
    (version "1.2")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "stm-containers" version))
              (sha256
               (base32
                "0yhpnxj7v880fy7vgjz5idpqfg2sm4dflp13k7fs0bqqlfv9hkbc"))))
    (build-system haskell-build-system)
    (arguments '(#:tests? #f))
    (inputs (list ghc-deferred-folds ghc-focus ghc-hashable ghc-list-t
                  ghc-stm-hamt))
    (native-inputs (list ghc-foldl
                         ghc-free
                         ghc-htf
                         ghc-quickcheck
                         ghc-quickcheck-text
                         ghc-rerebase))
    (home-page "https://github.com/nikita-volkov/stm-containers")
    (synopsis "Containers for STM")
    (description
     "This library is based on an STM-specialized implementation of Hash Array Mapped
Trie.  It provides efficient implementations of @@Map@@, @@Set@@ and other data
structures, which starting from version @@1@@ perform even better than their
counterparts from \\\"unordered-containers\\\", but also scale well on concurrent
access patterns. .  For details on performance of the library, which are a bit
outdated, see <http://nikita-volkov.github.io/stm-containers/ this blog post>.")
    (license license:expat)))

(define-public ghc-stm-delay
  (package
    (name "ghc-stm-delay")
    (version "0.1.1.1")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "stm-delay" version))
              (sha256
               (base32
                "0cla21v89gcvmr1iwzibq13v1yq02xg4h6k9l6kcprj7mhd5hcmi"))))
    (build-system haskell-build-system)
    (home-page "https://github.com/joeyadams/haskell-stm-delay")
    (synopsis "Updatable one-shot timer polled with STM")
    (description
     "This library lets you create a one-shot timer, poll it using STM, and update it
to ring at a different time than initially specified. .  It uses GHC event
manager timeouts when available (GHC 7.2+, @@-threaded@@, non-Windows OS),
yielding performance similar to @@threadDelay@@ and @@registerDelay@@.
Otherwise, it falls back to forked threads and @@threadDelay@@. . [0.1.1] Add
tryWaitDelayIO, improve performance for certain cases of @@newDelay@@ and
@@updateDelay@@, and improve example.")
    (license license:bsd-3)))

(define-public ghc-unexceptionalio-trans
  (package
    (name "ghc-unexceptionalio-trans")
    (version "0.5.1")
    (source (origin
              (method url-fetch)
              (uri (hackage-uri "unexceptionalio-trans" version))
              (sha256
               (base32
                "100sfbrpaldz37a176qpfkk1nx5acyh8pchjmb8g5vhzbhyrqniz"))))
    (build-system haskell-build-system)
    (inputs (list ghc-unexceptionalio))
    (arguments
     `(#:cabal-revision ("1"
                         "0f15n8hqqczwjrcqxwjp2mrd9iycv53sylv407c95nb6d4hw93ci")))
    (home-page "https://github.com/singpolyma/unexceptionalio-trans")
    (synopsis "A wrapper around UnexceptionalIO using monad transformers")
    (description
     "UnexceptionalIO provides a basic type to witness having caught all exceptions
you can safely handle.  This library builds on that with transformers like
ExceptT to provide a more ergonomic tool for many cases. .  It is intended that
you use qualified imports with this library. . > import UnexceptionalIO.Trans
(UIO) > import qualified UnexceptionalIO.Trans as UIO")
    (license #f)))

;;;;

(define %source-dir (dirname (current-filename)))
(define %git-dir (string-append %source-dir "/.git"))

; Bake a template by eval'ing the leaves
(define-public (bake tmpl)
 (cons
  (car tmpl)
  (map
   (lambda (x) (list (car x) (eval (cadr x) (current-module))))
   (cdr tmpl))))

; double-escaped template of the cheogram-smtp sexp
; This allows us to bake the expression without doing a full eval to a record,
; so it can be written
(define-public cheogram-smtp-template
  '(package
    (name "cheogram-smtp")
    (version (read-line (open-pipe* OPEN_READ "git" "--git-dir" %git-dir "describe" "--always" "--dirty")))
    (source
     `(origin
       (method git-fetch)
       (uri (git-reference
             (recursive? #t)
             (url "https://git.singpolyma.net/cheogram-smtp")
             (commit ,(read-line (open-pipe* OPEN_READ "git" "--git-dir" %git-dir "rev-parse" "HEAD")))))
       (file-name (git-file-name name version))
       (sha256
        (base32
         ,(read-line (open-pipe* OPEN_READ "guix" "hash" "-rx" %source-dir))))))
    (build-system 'haskell-build-system)
    (inputs
      '(list
        ghc-attoparsec
        ghc-basic-prelude
        ghc-case-insensitive
        ghc-cryptonite
        ghc-errors
        ghc-focus
        ghc-http-streams
        ghc-ipld-cid
        ghc-lens
        ghc-mime-mail
        ghc-mime-types
        ghc-network
        ghc-network-protocol-xmpp
        ghc-network-uri
        ghc-purebred-email
        ghc-stm-containers
        ghc-stm-delay
        ghc-unexceptionalio-trans
        ghc-uuid
        ghc-xml-types))
    (native-inputs
      '(list
        ghc-tasty
        ghc-tasty-hunit
        ghc-tasty-quickcheck
        ghc-tasty-discover
        ghc-quickcheck-instances
        ghc-generic-arbitrary
        ghc-gnuidn
        ghc-quickcheck))
    (home-page "https://git.singpolyma.net/cheogram")
    (synopsis "")
    (description "")
    (license 'license:agpl3)))

; Build clean from git the version from a local clone
; To build whatever is sitting in local use:
; guix build --with-source=$PWD -f guix.scm

(eval (bake cheogram-smtp-template) (current-module))

M incoming-email.hs => incoming-email.hs +1 -2
@@ 5,7 5,6 @@ import BasicPrelude
import Data.Functor                    ((<&>))
import Control.Concurrent.STM          (atomically)
import Control.Error                   (hush)
import Network                         (PortID (PortNumber))
import System.Exit                     (exitFailure)
import qualified Data.IPLD.CID         as CID
import qualified Data.ByteString       as ByteString


@@ 28,7 27,7 @@ runClient jid =
	jidStrDomain = XMPP.strDomain $ XMPP.jidDomain jid
	Just domainJid = XMPP.parseJID jidStrDomain
	domainStr = textToString jidStrDomain
	server = XMPP.Server domainJid domainStr (PortNumber 5222)
	server = XMPP.Server domainJid domainStr 5222

main :: IO ()
main = do

A manifest.scm => manifest.scm +7 -0
@@ 0,0 1,7 @@
(define cheogram-smtp (load "./guix.scm"))

(concatenate-manifests
  (list
    (specifications->manifest
      '("hlint"))
    (package->development-manifest cheogram-smtp)))