diff --git a/gnu/local.mk b/gnu/local.mk
index 1d9de9a57e..211e9362b4 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -902,6 +902,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/evilwm-lost-focus-bug.patch		\
   %D%/packages/patches/evolution-data-server-locales.patch	\
   %D%/packages/patches/evolution-data-server-libical-compat.patch	\
+  %D%/packages/patches/exercism-disable-self-update.patch	\
   %D%/packages/patches/exiv2-CVE-2017-14860.patch		\
   %D%/packages/patches/exiv2-CVE-2017-14859-14862-14864.patch	\
   %D%/packages/patches/extempore-unbundle-external-dependencies.patch	\
diff --git a/gnu/packages/education.scm b/gnu/packages/education.scm
index d6c2cd02c3..7b52caa09b 100644
--- a/gnu/packages/education.scm
+++ b/gnu/packages/education.scm
@@ -7,6 +7,7 @@
 ;;; Copyright © 2018, 2019, 2020 Nicolas Goaziou <mail@nicolasgoaziou.fr>
 ;;; Copyright © 2020 Robert Smith <robertsmith@posteo.net>
 ;;; Copyright © 2020 Guy Fleury Iteriteka <gfleury@disroot.org>
+;;; Copyright © 2020 Jakub Kądziołka <kuba@kadziolka.net>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -39,6 +40,7 @@
   #:use-module (gnu packages gettext)
   #:use-module (gnu packages glib)
   #:use-module (gnu packages gnome)
+  #:use-module (gnu packages golang)
   #:use-module (gnu packages gtk)
   #:use-module (gnu packages image)
   #:use-module (gnu packages javascript)
@@ -68,6 +70,7 @@
   #:use-module (guix utils)
   #:use-module (guix build-system cmake)
   #:use-module (guix build-system gnu)
+  #:use-module (guix build-system go)
   #:use-module (guix build-system python)
   #:use-module (guix build-system qt)
   #:use-module (guix build-system trivial)
@@ -976,3 +979,35 @@ comparison flags, input-output devices, and a set of binary instructions.
 The package includes a compiler, a virtual machine, a GUI for the virtual
 machine, and more.")
     (license license:gpl3+)))
+
+(define-public exercism
+  (package
+    (name "exercism")
+    (version "3.0.13")
+    (source
+     (origin
+       (method git-fetch)
+       (uri (git-reference
+             (url "https://github.com/exercism/cli")
+             (commit (string-append "v" version))))
+       (file-name (git-file-name name version))
+       (sha256
+        (base32
+         "17gvz9a0sn4p36hf4l77bxhhfipf4x998iay31layqwbnzmb4xy7"))
+       (patches (search-patches "exercism-disable-self-update.patch"))))
+    (build-system go-build-system)
+    (arguments
+     `(#:import-path "github.com/exercism/cli/exercism"
+       #:unpack-path "github.com/exercism/cli"))
+    (inputs
+     `(("github.com/blang/semver" ,go-github-com-blang-semver)
+       ("github.com/spf13/cobra" ,go-github-com-spf13-cobra)
+       ("github.com/spf13/pflag" ,go-github-com-spf13-pflag)
+       ("github.com/spf13/viper" ,go-github-com-spf13-viper)
+       ("golang.org/x/net" ,go-golang-org-x-net)
+       ("golang.org/x/text" ,go-golang-org-x-text)))
+    (home-page "https://exercism.io")
+    (synopsis "Mentored learning for programming languages")
+    (description "Commandline client for exercism.io, a free service providing
+mentored learning for programming languages.")
+    (license license:expat)))
diff --git a/gnu/packages/golang.scm b/gnu/packages/golang.scm
index cfab23608d..de4b51ca4e 100644
--- a/gnu/packages/golang.scm
+++ b/gnu/packages/golang.scm
@@ -17,6 +17,7 @@
 ;;; Copyright @ 2019, 2020 Alex Griffin <a@ajgrf.com>
 ;;; Copyright © 2019 Arun Isaac <arunisaac@systemreboot.net>
 ;;; Copyright © 2020 Jack Hill <jackhill@jackhill.us>
+;;; Copyright © 2020 Jakub Kądziołka <kuba@kadziolka.net>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -1178,6 +1179,103 @@ incoming requests with their respective handler.")
 @code{clockwork.Clock} interface instead.")
       (license license:asl2.0))))
 
+(define-public go-github-com-spf13-afero
+  (package
+    (name "go-github-com-spf13-afero")
+    (version "1.2.2")
+    (source
+     (origin
+       (method git-fetch)
+       (uri (git-reference
+             (url "https://github.com/spf13/afero")
+             (commit (string-append "v" version))))
+       (file-name (git-file-name name version))
+       (sha256
+        (base32
+         "0j9r65qgd58324m85lkl49vk9dgwd62g7dwvkfcm3k6i9dc555a9"))))
+    (build-system go-build-system)
+    (arguments
+     `(#:import-path "github.com/spf13/afero"))
+    (propagated-inputs
+     `(("golang.org/x/text" ,go-golang-org-x-text)))
+    (home-page "https://github.com/spf13/afero")
+    (synopsis "Filesystem abstraction for Go")
+    (description "Filesystem abstraction for Go")
+    (license license:asl2.0)))
+
+(define-public go-github-com-spf13-cast
+  (package
+    (name "go-github-com-spf13-cast")
+    (version "1.3.1")
+    (source
+     (origin
+       (method git-fetch)
+       (uri (git-reference
+             (url "https://github.com/spf13/cast")
+             (commit (string-append "v" version))))
+       (file-name (git-file-name name version))
+       (sha256
+        (base32
+         "0lb84788glr0qzrq2ifi36rgvp96qrgywvxrr3ggq5hrbr38hgn1"))))
+    (build-system go-build-system)
+    (arguments
+     `(#:import-path "github.com/spf13/cast"))
+    (native-inputs
+     `(("go-github-com-stretchr-testify" ,go-github-com-stretchr-testify)))
+    (home-page "https://github.com/spf13/cast")
+    (synopsis "Safe and easy casting from one type to another in Go")
+    (description "Safe and easy casting from one type to another in Go")
+    (license license:expat)))
+
+(define-public go-github-com-spf13-cobra
+  (package
+    (name "go-github-com-spf13-cobra")
+    (version "1.0.0")
+    (source
+     (origin
+       (method git-fetch)
+       (uri (git-reference
+             (url "https://github.com/spf13/cobra")
+             (commit (string-append "v" version))))
+       (file-name (git-file-name name version))
+       (sha256
+        (base32
+         "0vbppqqhby302a5ayn0296jqr71qkcd4c9am7wzsk6z71fwdsa7h"))))
+    (build-system go-build-system)
+    (arguments
+     `(#:import-path "github.com/spf13/cobra"))
+    (propagated-inputs
+     `(("github.com/spf13/pflag" ,go-github-com-spf13-pflag)))
+    (home-page "https://github.com/spf13/cobra")
+    (synopsis "Go library for creating CLI applications")
+    (description "Cobra is both a library for creating powerful modern CLI
+applications as well as a program to generate applications and command files.")
+    (license license:asl2.0)))
+
+(define-public go-github-com-spf13-jwalterweatherman
+  (package
+    (name "go-github-com-spf13-jwalterweatherman")
+    (version "1.1.0")
+    (source
+     (origin
+       (method git-fetch)
+       (uri (git-reference
+             (url "https://github.com/spf13/jwalterweatherman")
+             (commit (string-append "v" version))))
+       (file-name (git-file-name name version))
+       (sha256
+        (base32
+         "1ywmkwci5zyd88ijym6f30fj5c0k2yayxarkmnazf5ybljv50q7b"))))
+    (build-system go-build-system)
+    (arguments
+     `(#:import-path "github.com/spf13/jwalterweatherman"))
+    (native-inputs
+     `(("go-github-com-stretchr-testify" ,go-github-com-stretchr-testify)))
+    (home-page "https://github.com/spf13/jwalterweatherman")
+    (synopsis "Go logging library")
+    (description "Go logging library")
+    (license license:expat)))
+
 (define-public go-github-com-spf13-pflag
   (package
     (name "go-github-com-spf13-pflag")
@@ -1190,8 +1288,8 @@ incoming requests with their respective handler.")
                (commit (string-append "v" version))))
         (file-name (git-file-name name version))
         (sha256
-          (base32
-            "0gpmacngd0gpslnbkzi263f5ishigzgh6pbdv9hp092rnjl4nd31"))))
+         (base32
+          "0gpmacngd0gpslnbkzi263f5ishigzgh6pbdv9hp092rnjl4nd31"))))
     (build-system go-build-system)
     (arguments
       '(#:import-path "github.com/spf13/pflag"))
@@ -1205,6 +1303,143 @@ with the
 GNU extensions} to the POSIX recommendations for command-line options.")
     (license license:bsd-3)))
 
+(define-public go-github-com-spf13-viper
+  (package
+    (name "go-github-com-spf13-viper")
+    (version "1.7.0")
+    (source
+     (origin
+       (method git-fetch)
+       (uri (git-reference
+             (url "https://github.com/spf13/viper.git")
+             (commit (string-append "v" version))))
+       (file-name (git-file-name name version))
+       (sha256
+        (base32
+         "099n2g7fg6r8hqyszqw2axr775qyhyvwhsykvgw0f0s16ql48h5c"))))
+    (build-system go-build-system)
+    (arguments
+     '(#:import-path "github.com/spf13/viper"))
+    (propagated-inputs
+     `(("github.com/spf13/afero" ,go-github-com-spf13-afero)
+       ("github.com/spf13/cast" ,go-github-com-spf13-cast)
+       ("github.com/spf13/pflag" ,go-github-com-spf13-pflag)
+       ("github.com/spf13/jwalterweatherman" ,go-github-com-spf13-jwalterweatherman)
+       ("github.com/fsnotify/fsnotify" ,go-github-com-fsnotify-fsnotify)
+       ("github.com/hashicorp/hcl" ,go-github-com-hashicorp-hcl)
+       ("github.com/magiconair/properties" ,go-github-com-magiconair-properties)
+       ("github.com/mitchellh/mapstructure" ,go-github-com-mitchellh-mapstructure)
+       ("github.com/pelletier/go-toml" ,go-github-com-pelletier-go-toml)
+       ("github.com/subosito/gotenv" ,go-github-com-subosito-gotenv)
+
+       ("gopkg.in/ini.v1" ,go-gopkg-in-ini-v1)
+       ("gopkg.in/yaml.v2" ,go-gopkg-in-yaml-v2)))
+    (native-inputs
+     `(("go-github-com-stretchr-testify" ,go-github-com-stretchr-testify)))
+    (home-page "https://github.com/spf13/viper")
+    (synopsis "Go configuration with fangs")
+    (description
+     "Viper is a complete configuration solution for Go applications including
+12-Factor apps.  It is designed to work within an application, and can handle
+all types of configuration needs and formats.")
+    (license license:expat)))
+
+(define-public go-github-com-fsnotify-fsnotify
+  (package
+    (name "go-github-com-fsnotify-fsnotify")
+    (version "1.4.9")
+    (source
+     (origin
+       (method git-fetch)
+       (uri (git-reference
+             (url "https://github.com/fsnotify/fsnotify")
+             (commit (string-append "v" version))))
+       (file-name (git-file-name name version))
+       (sha256
+        (base32
+         "1i1r72knpbfwwql9frn9bqc3nhfc2ai5m6qllcyr6wban62lr40x"))))
+    (build-system go-build-system)
+    (arguments
+     `(#:import-path "github.com/fsnotify/fsnotify"))
+    (propagated-inputs
+     `(("golang.org/x/sys" ,go-golang-org-x-sys)))
+    (home-page "https://github.com/fsnotify/fsnotify")
+    (synopsis "File system notifications for Go")
+    (description "File system notifications for Go")
+    (license license:bsd-3)))
+
+(define-public go-github-com-magiconair-properties
+  (package
+    (name "go-github-com-magiconair-properties")
+    (version "1.8.1")
+    (source
+     (origin
+       (method git-fetch)
+       (uri (git-reference
+             (url "https://github.com/magiconair/properties")
+             (commit (string-append "v" version))))
+       (file-name (git-file-name name version))
+       (sha256
+        (base32
+         "19zqw1x0w0crh8zc84yy82nkcc5yjz72gviaf2xjgfm5a8np7nyb"))))
+    (build-system go-build-system)
+    (arguments
+     `(#:import-path "github.com/magiconair/properties"))
+    (home-page "https://github.com/magiconair/properties")
+    (synopsis "Java properties scanner for Go")
+    (description "Java properties scanner for Go")
+    (license license:bsd-2)))
+
+(define-public go-github-com-pelletier-go-toml
+  (package
+    (name "go-github-com-pelletier-go-toml")
+    (version "1.8.0")
+    (source
+     (origin
+       (method git-fetch)
+       (uri (git-reference
+             (url "https://github.com/pelletier/go-toml")
+             (commit (string-append "v" version))))
+       (file-name (git-file-name name version))
+       (sha256
+        (base32
+         "0fxmjm85c9h43lvqz71wr93fcc63bhj82nwby80222xx8ja63g7y"))))
+    (build-system go-build-system)
+    (arguments
+     `(#:import-path "github.com/pelletier/go-toml"))
+    (native-inputs
+     `(("github.com/BurntSushi/toml" ,go-github-com-burntsushi-toml)
+       ("github.com/davecgh/go-spew" ,go-github-com-davecgh-go-spew)
+       ("gopkg.in/yaml.v2" ,go-gopkg-in-yaml-v2)))
+    (home-page "https://github.com/pelletier/go-toml")
+    (synopsis "Go library for the TOML configuration language")
+    (description "Go library for the TOML configuration language")
+    (license license:expat)))
+
+(define-public go-github-com-subosito-gotenv
+  (package
+    (name "go-github-com-subosito-gotenv")
+    (version "1.2.0")
+    (source
+     (origin
+       (method git-fetch)
+       (uri (git-reference
+             (url "https://github.com/subosito/gotenv")
+             (commit (string-append "v" version))))
+       (file-name (git-file-name name version))
+       (sha256
+        (base32
+         "0mav91j7r4arjkpq5zcf9j74f6pww8ic53x43wy7kg3ibw31yjs5"))))
+    (build-system go-build-system)
+    (arguments
+     `(#:import-path "github.com/subosito/gotenv"))
+    (native-inputs
+     `(("go-github-com-stretchr-testify" ,go-github-com-stretchr-testify)))
+    (home-page "https://github.com/subosito/gotenv")
+    (synopsis "Go library for loading environment variables from files")
+    (description "Go library for loading environment variables from files")
+    (license license:expat)))
+
 (define-public go-github-com-sirupsen-logrus
   (package
     (name "go-github-com-sirupsen-logrus")
@@ -1473,6 +1708,30 @@ which satisfies the cron expression.")
       (description "This package provides a test library for the Go language.")
       (license license:asl2.0))))
 
+(define-public go-gopkg-in-ini-v1
+  (package
+    (name "go-gopkg-in-ini-v1")
+    (version "1.56.0")
+    (source
+     (origin
+       (method git-fetch)
+       (uri (git-reference
+             (url "https://github.com/go-ini/ini")
+             (commit (string-append "v" version))))
+       (file-name (git-file-name name version))
+       (sha256
+        (base32
+         "0j5z0cngg6mq2f9id083jcdi7k6r2h35714pashv6sdv2q7bmfc5"))))
+    (build-system go-build-system)
+    (arguments
+     '(#:import-path "gopkg.in/ini.v1"
+       ;; Requires large unpackaged test framework
+       #:tests? #f))
+    (home-page "https://gopkg.in/ini.v1")
+    (synopsis "Go library for ini files")
+    (description "Go library for ini files")
+    (license license:asl2.0)))
+
 (define-public go-gopkg-in-yaml-v2
   (package
     (name "go-gopkg-in-yaml-v2")
@@ -2405,6 +2664,28 @@ the current user without cgo.  This library does that, enabling
 cross-compilation.")
       (license license:expat))))
 
+(define-public go-github-com-mitchellh-mapstructure
+  (package
+    (name "go-github-com-mitchellh-mapstructure")
+    (version "1.1.2") ;; NOTE: Updating to 1.3.1 breaks tests on viper-1.7.0
+    (source
+     (origin
+       (method git-fetch)
+       (uri (git-reference
+             (url "https://github.com/mitchellh/mapstructure")
+             (commit (string-append "v" version))))
+       (file-name (git-file-name name version))
+       (sha256
+        (base32
+         "03bpv28jz9zhn4947saqwi328ydj7f6g6pf1m2d4m5zdh5jlfkrr"))))
+    (build-system go-build-system)
+    (arguments
+     `(#:import-path "github.com/mitchellh/mapstructure"))
+    (home-page "https://github.com/mitchellh/mapstructure")
+    (synopsis "Go library for decoding generic map values")
+    (description "Go library for decoding generic map values")
+    (license license:expat)))
+
 (define-public go-github-com-multiformats-go-multiaddr
   (let ((commit "fe1c46f8be5af4aff4db286e08839295bd922efb")
         (revision "0"))
diff --git a/gnu/packages/patches/exercism-disable-self-update.patch b/gnu/packages/patches/exercism-disable-self-update.patch
new file mode 100644
index 0000000000..a96cbfbc55
--- /dev/null
+++ b/gnu/packages/patches/exercism-disable-self-update.patch
@@ -0,0 +1,79 @@
+From bc22f7d43c12c5f79c71b0319666e71f29d61322 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jakub=20K=C4=85dzio=C5=82ka?= <kuba@kadziolka.net>
+Date: Mon, 25 May 2020 18:53:04 +0200
+Subject: [PATCH] Disable self-update.
+
+Based on a Fedora patch by Elliott Sales de Andrade.
+---
+ cli/cli.go | 44 +-------------------------------------------
+ 1 file changed, 1 insertion(+), 43 deletions(-)
+
+diff --git a/cli/cli.go b/cli/cli.go
+index 4312eb0..5f62297 100644
+--- a/cli/cli.go
++++ b/cli/cli.go
+@@ -10,13 +10,10 @@ import (
+ 	"io"
+ 	"io/ioutil"
+ 	"net/http"
+-	"runtime"
+ 	"strings"
+ 	"time"
+ 
+ 	"github.com/blang/semver"
+-	"github.com/exercism/cli/debug"
+-	update "github.com/inconshreveable/go-update"
+ )
+ 
+ var (
+@@ -95,46 +92,7 @@ func (c *CLI) IsUpToDate() (bool, error) {
+ 
+ // Upgrade allows the user to upgrade to the latest version of the CLI.
+ func (c *CLI) Upgrade() error {
+-	var (
+-		OS   = osMap[runtime.GOOS]
+-		ARCH = archMap[runtime.GOARCH]
+-	)
+-
+-	if OS == "" || ARCH == "" {
+-		return fmt.Errorf("unable to upgrade: OS %s ARCH %s", OS, ARCH)
+-	}
+-
+-	buildName := fmt.Sprintf("%s-%s", OS, ARCH)
+-	if BuildARCH == "arm" {
+-		if BuildARM == "" {
+-			return fmt.Errorf("unable to upgrade: arm version not found")
+-		}
+-		buildName = fmt.Sprintf("%s-v%s", buildName, BuildARM)
+-	}
+-
+-	var downloadRC *bytes.Reader
+-	for _, a := range c.LatestRelease.Assets {
+-		if strings.Contains(a.Name, buildName) {
+-			debug.Printf("Downloading %s\n", a.Name)
+-			var err error
+-			downloadRC, err = a.download()
+-			if err != nil {
+-				return fmt.Errorf("error downloading executable: %s", err)
+-			}
+-			break
+-		}
+-	}
+-	if downloadRC == nil {
+-		return fmt.Errorf("no executable found for %s/%s%s", BuildOS, BuildARCH, BuildARM)
+-	}
+-
+-	bin, err := extractBinary(downloadRC, OS)
+-	if err != nil {
+-		return err
+-	}
+-	defer bin.Close()
+-
+-	return update.Apply(bin, update.Options{})
++	return fmt.Errorf("Please use Guix to update Exercism")
+ }
+ 
+ func (c *CLI) fetchLatestRelease() error {
+-- 
+2.26.2
+
