Browse Source

Merge remote-tracking branch 'upstream/master' into geonetwork

doublebyte1 8 years ago
parent
commit
4132946bff
100 changed files with 3874 additions and 741 deletions
  1. 9 0
      .github/ISSUE_TEMPLATE.md
  2. 2 13
      .travis.yml
  3. 9 13
      Dockerfile
  4. 1 1
      MAINTAINERS
  5. 76 47
      README.md
  6. 37 0
      bashbrew/.bashbrew-arch-to-goenv.sh
  7. 9 0
      bashbrew/.dockerignore
  8. 88 0
      bashbrew/Dockerfile.release
  9. 30 24
      bashbrew/go/src/bashbrew/cmd-build.go
  10. 3 0
      bashbrew/go/src/bashbrew/cmd-cat.go
  11. 42 11
      bashbrew/go/src/bashbrew/cmd-deps.go
  12. 5 0
      bashbrew/go/src/bashbrew/cmd-from.go
  13. 7 7
      bashbrew/go/src/bashbrew/cmd-list.go
  14. 15 4
      bashbrew/go/src/bashbrew/cmd-push.go
  15. 153 0
      bashbrew/go/src/bashbrew/cmd-put-shared.go
  16. 6 3
      bashbrew/go/src/bashbrew/cmd-tag.go
  17. 13 0
      bashbrew/go/src/bashbrew/config.go
  18. 10 5
      bashbrew/go/src/bashbrew/docker.go
  19. 57 16
      bashbrew/go/src/bashbrew/git.go
  20. 63 0
      bashbrew/go/src/bashbrew/hub.go
  21. 81 13
      bashbrew/go/src/bashbrew/main.go
  22. 36 0
      bashbrew/go/src/bashbrew/manifest-tool.go
  23. 20 2
      bashbrew/go/src/bashbrew/repo.go
  24. 12 5
      bashbrew/go/src/bashbrew/sort.go
  25. 3 3
      bashbrew/go/vendor/manifest
  26. 5 0
      bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/README.md
  27. 25 0
      bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/architecture/oci-platform.go
  28. 0 67
      bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/manifest/example.go
  29. 192 0
      bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/manifest/example_test.go
  30. 20 0
      bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/manifest/parse_test.go
  31. 317 19
      bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/manifest/rfc2822.go
  32. 38 0
      bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/manifest/testdata/bash
  33. 26 0
      bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/pkg/execpipe/execpipe_example_test.go
  34. 31 0
      bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/pkg/execpipe/execpipe_test.go
  35. 32 0
      bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/pkg/stripper/comments_example_test.go
  36. 8 0
      bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/pkg/templatelib/doc.go
  37. 42 3
      bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/pkg/templatelib/lib.go
  38. 221 0
      bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/pkg/templatelib/lib_example_test.go
  39. 45 0
      bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/pkg/templatelib/lib_test.go
  40. 3 0
      bashbrew/go/vendor/src/pault.ag/go/debian/AUTHORS
  41. 53 0
      bashbrew/go/vendor/src/pault.ag/go/debian/LICENSE
  42. 8 0
      bashbrew/go/vendor/src/pault.ag/go/debian/README.md
  43. 177 0
      bashbrew/go/vendor/src/pault.ag/go/debian/changelog/changelog.go
  44. 102 0
      bashbrew/go/vendor/src/pault.ag/go/debian/changelog/changelog_test.go
  45. 6 0
      bashbrew/go/vendor/src/pault.ag/go/debian/changelog/doc.go
  46. 16 0
      bashbrew/go/vendor/src/pault.ag/go/debian/control/changes.go
  47. 1 1
      bashbrew/go/vendor/src/pault.ag/go/debian/control/dsc.go
  48. 1 1
      bashbrew/go/vendor/src/pault.ag/go/debian/control/encode.go
  49. 1 1
      bashbrew/go/vendor/src/pault.ag/go/debian/control/parse.go
  50. 204 0
      bashbrew/go/vendor/src/pault.ag/go/debian/deb/ar.go
  51. 242 0
      bashbrew/go/vendor/src/pault.ag/go/debian/deb/deb.go
  52. 40 0
      bashbrew/go/vendor/src/pault.ag/go/debian/deb/doc.go
  53. 105 0
      bashbrew/go/vendor/src/pault.ag/go/debian/deb/tarfile.go
  54. 1 1
      bashbrew/go/vendor/src/pault.ag/go/debian/dependency/string.go
  55. 56 0
      bashbrew/manifest-tool.patch
  56. 1 1
      bashbrew/travis.sh
  57. 76 0
      build-and-push.sh
  58. 60 0
      children.sh
  59. 85 16
      diff-pr.sh
  60. 18 0
      heavy-hitters.txt
  61. 14 0
      library/adminer
  62. 4 2
      library/aerospike
  63. 8 7
      library/alpine
  64. 21 0
      library/amazonlinux
  65. 5 13
      library/arangodb
  66. 13 12
      library/backdrop
  67. 9 9
      library/bash
  68. 4 3
      library/bonita
  69. 80 41
      library/buildpack-deps
  70. 44 9
      library/busybox
  71. 14 10
      library/cassandra
  72. 0 13
      library/celery
  73. 16 9
      library/centos
  74. 6 6
      library/chronograf
  75. 1 1
      library/cirros
  76. 3 3
      library/clearlinux
  77. 26 12
      library/clojure
  78. 12 0
      library/composer
  79. 2 4
      library/consul
  80. 10 0
      library/convertigo
  81. 9 9
      library/couchbase
  82. 11 5
      library/crate
  83. 1 1
      library/crux
  84. 108 82
      library/debian
  85. 0 21
      library/django
  86. 45 36
      library/docker
  87. 40 11
      library/drupal
  88. 7 0
      library/eclipse-mosquitto
  89. 7 7
      library/eggdrop
  90. 0 37
      library/elasticsearch
  91. 23 3
      library/elixir
  92. 32 19
      library/erlang
  93. 25 17
      library/fedora
  94. 69 0
      library/flink
  95. 22 4
      library/fsharp
  96. 13 9
      library/gazebo
  97. 17 7
      library/gcc
  98. 20 3
      library/ghost
  99. 46 39
      library/golang
  100. 42 0
      library/gradle

+ 9 - 0
.github/ISSUE_TEMPLATE.md

@@ -0,0 +1,9 @@
+<!--
+
+WAIT!  Before you file an issue here, please keep in mind that your issue is _probably_ more appropriately filed somewhere else.
+
+Specifically, if your issue is in regards to the documentation of an image, it should be filed at https://github.com/docker-library/docs/issues
+
+If your issue is in regards to a specific image, please see the "Issues" section of the relevant image's description on the Docker Hub for information about where to file issues for that image.  For example, issues with the "python" image should be filed at https://github.com/docker-library/python/issues, NOT here.
+
+-->

+ 2 - 13
.travis.yml

@@ -1,22 +1,11 @@
 language: go
-go: 1.6.2
+go: 1.7.x
 
 # allow for use of Docker-based workers
 sudo: false
 
 install:
-    - |
-        GB_VERSION=$(awk '$1 == "ENV" && $2 == "GB_VERSION" { print $3; exit }' Dockerfile)
-        firstGo="${GOPATH%%:*}"
-        mkdir -p "$firstGo/src/github.com/constabulary"
-        (
-            cd "$firstGo/src/github.com/constabulary"
-            wget -qO- "https://github.com/constabulary/gb/archive/v${GB_VERSION}.tar.gz" \
-                | tar -xz
-            mv gb-* gb
-            cd gb
-            go install -v ./...
-        )
+    - go get -v -u github.com/constabulary/gb/...
 
 before_script:
     - env | sort

+ 9 - 13
Dockerfile

@@ -1,24 +1,16 @@
-FROM docker:1.10-git
+FROM docker:stable-git
 
 RUN apk add --no-cache \
 # bash for running scripts
 		bash \
 # go for compiling bashbrew
-		go
+		go libc-dev \
+# ssl for downloading files
+		libressl
 
 ENV GOPATH /go
 ENV PATH $GOPATH/bin:$PATH
 
-ENV GB_VERSION 0.4.1
-RUN set -x \
-	&& mkdir -p /go/src/github.com/constabulary \
-	&& cd /go/src/github.com/constabulary \
-	&& wget -qO- "https://github.com/constabulary/gb/archive/v${GB_VERSION}.tar.gz" \
-		| tar -xz \
-	&& mv gb-* gb \
-	&& cd gb \
-	&& go install -v ./...
-
 ENV DIR /usr/src/official-images
 ENV PATH $DIR/bashbrew/go/bin:$PATH
 
@@ -33,7 +25,11 @@ RUN mkdir -p "$BASHBREW_CACHE" \
 WORKDIR $DIR
 COPY . $DIR
 
-RUN cd bashbrew/go && gb build
+RUN set -ex; \
+	cd bashbrew/go; \
+	export GOPATH="$PWD:$PWD/vendor"; \
+	cd src; \
+	go install -v ./...
 
 VOLUME $BASHBREW_CACHE
 

+ 1 - 1
MAINTAINERS

@@ -1,4 +1,4 @@
 Tianon Gravi <[email protected]> (@tianon)
 Joseph Ferguson <[email protected]> (@yosifkit)
-Talon Bowler <[email protected]> (@moghedrin)
+# Emeritus: Talon Bowler <[email protected]> (@moghedrin)
 # Emeritus: Peter Salvatore <[email protected]> (@psftw)

+ 76 - 47
README.md

@@ -8,16 +8,25 @@ See [Docker's documentation](https://docs.docker.com/docker-hub/official_repos/)
 
 ## Architectures other than amd64?
 
-Work is in-progress in the Docker Engine and Registry to properly support multiple architectures (see [docker/docker#15866](https://github.com/docker/docker/issues/15866)). While this work is ongoing, **temporary**, experimental builds of the official images for the following architectures are happening somewhat incrementally (with a strong bias towards images necessary for Docker's own CI to help hasten proper multiarch support upstream) via CI.
+Some images have been ported for other architectures, and many of these are officially supported (to various degrees).
 
--	ARMv5 (`armel`): https://hub.docker.com/u/armel/
--	ARMv7 (`armhf`): https://hub.docker.com/u/armhf/
--	ARMv8 (`arm64`): https://hub.docker.com/u/aarch64/
--	POWER8 (`ppc64le`): https://hub.docker.com/u/ppc64le/
--	System z (`s390x`): https://hub.docker.com/u/s390x/
--	x86/i686 (`i386`): https://hub.docker.com/u/i386/
+-	Architectures officially supported by Docker, Inc. for running Docker: (see [download.docker.com](https://download.docker.com/linux/))
+	-	IBM z Systems (`s390x`): https://hub.docker.com/u/s390x/
+	-	ARMv7 32-bit (`arm32v7`): https://hub.docker.com/u/arm32v7/
+	-	Windows x86-64 (`windows-amd64`): https://hub.docker.com/u/winamd64/
+	-	Linux x86-64 (`amd64`): https://hub.docker.com/u/amd64/
+-	Other architectures built by official images: (but *not* officially supported by Docker, Inc.)
+	-	IBM POWER8 (`ppc64le`): https://hub.docker.com/u/ppc64le/
+	-	x86/i686 (`i386`): https://hub.docker.com/u/i386/
+	-	ARMv8 64-bit (`arm64v8`): https://hub.docker.com/u/arm64v8/
+	-	ARMv6 32-bit (`arm32v6`): https://hub.docker.com/u/arm32v6/ (Raspberry Pi 1, Raspberry Pi Zero)
+	-	ARMv5 32-bit (`arm32v5`): https://hub.docker.com/u/arm32v5/
 
-If you are curious about how these images are built or have issues with them, please direct all comments to [issues on the `tianon/jenkins-groovy` repo](https://github.com/tianon/jenkins-groovy/issues) for now.
+As of 2017-09-12, these other architectures are included under the non-prefixed images via ["manifest lists"](https://docs.docker.com/registry/spec/manifest-v2-2/#manifest-list) (also known as ["indexes" in the OCI image specification](https://github.com/opencontainers/image-spec/blob/v1.0.0/image-index.md)), such that, for example, `docker run hello-world` should run as-is on all supported platforms.
+
+If you're curious about how these are built, head over to https://doi-janky.infosiftr.net/job/multiarch/ to see the build scaffolding.
+
+See the [multi-arch section](#multiple-architectures) below for recommendations in adding more architectures to an official image.
 
 ## Contributing to the standard library
 
@@ -112,7 +121,7 @@ All official images should provide a consistent interface. A beginning user shou
 
 #### Clarity
 
-Try to make the `Dockerfile` easy to understand/read. It may be tempting, for the sake of brevity, to put complicated initialization details into a standalone script and merely add a `RUN` command in the `Dockerfile`. However, this causes the resulting `Dockerfile` to be overly opaque, and such `Dockerfile`s are unlikely to pass review. Instead, it it recommended to put all the commands for initialization into the `Dockerfile` as appropriate `RUN` or `ENV` command combinations. To find good examples, look at the current official images.
+Try to make the `Dockerfile` easy to understand/read. It may be tempting, for the sake of brevity, to put complicated initialization details into a standalone script and merely add a `RUN` command in the `Dockerfile`. However, this causes the resulting `Dockerfile` to be overly opaque, and such `Dockerfile`s are unlikely to pass review. Instead, it is recommended to put all the commands for initialization into the `Dockerfile` as appropriate `RUN` or `ENV` command combinations. To find good examples, look at the current official images.
 
 Some examples at the time of writing:
 
@@ -122,9 +131,9 @@ Some examples at the time of writing:
 
 #### init
 
-Following the Docker guidelines it is highly recommended that the resulting image be just one concern per container; predominantly this means just one process per container, so there is no need for a full init system. There are two situations where an init-like process would be helpful for the container. The first being signal handling. If the process launched does not handle `SIGTERM` by exiting, it will not be killed since it is PID 1 in the container (see "NOTE" at the end of the [Foreground section](https://docs.docker.com/reference/run/#foreground) in the docker docs). The second situation would be zombie reaping. If the process spawns child processes and does not properly reap them it will lead to a full process table, which can prevent the whole system from spawning any new processes. For both of these concerns we recommend [tini](https://github.com/krallin/tini). It is incredibly small, has minimal external dependencies, fills each of these roles, and does only the necessary parts of reaping and signal forwarding.
+Following the Docker guidelines it is highly recommended that the resulting image be just one concern per container; predominantly this means just one process per container, so there is no need for a full init system. There are two situations where an init-like process would be helpful for the container. The first being signal handling. If the process launched does not handle `SIGTERM` by exiting, it will not be killed since it is PID 1 in the container (see "NOTE" at the end of the [Foreground section](https://docs.docker.com/engine/reference/run/#foreground) in the docker docs). The second situation would be zombie reaping. If the process spawns child processes and does not properly reap them it will lead to a full process table, which can prevent the whole system from spawning any new processes. For both of these concerns we recommend [tini](https://github.com/krallin/tini). It is incredibly small, has minimal external dependencies, fills each of these roles, and does only the necessary parts of reaping and signal forwarding.
 
-Here is a snippet of a Dockerfile to add in tini (be sure to use it in `CMD` or `ENTRYPOINT` as appropriate):
+Here is a snippet of a `Dockerfile` to add in tini (be sure to use it in `CMD` or `ENTRYPOINT` as appropriate):
 
 ```Dockerfile
 # grab tini for signal processing and zombie killing
@@ -156,7 +165,7 @@ This is one place that experience ends up trumping documentation for the path to
 
 ##### Image Build
 
-The `Dockerfile` should be written to help mitigate man-in-the-middle attacks during build: using https where possible; importing PGP keys with the full fingerprint in the Dockerfile to check package signing; embedding checksums directly in the `Dockerfile` if PGP signing is not provided. When importing PGP keys, we recommend using the [high-availability server pool](https://sks-keyservers.net/overview-of-pools.php#pool_ha) from sks-keyservers (`ha.pool.sks-keyservers.net`). Here are a few good and bad examples:
+The `Dockerfile` should be written to help mitigate man-in-the-middle attacks during build: using https where possible; importing PGP keys with the full fingerprint in the `Dockerfile` to check package signing; embedding checksums directly in the `Dockerfile` if PGP signing is not provided. When importing PGP keys, we recommend using the [high-availability server pool](https://sks-keyservers.net/overview-of-pools.php#pool_ha) from sks-keyservers (`ha.pool.sks-keyservers.net`). Here are a few good and bad examples:
 
 -	**Bad**: *download the file over http with no verification.*
 
@@ -172,7 +181,7 @@ The `Dockerfile` should be written to help mitigate man-in-the-middle attacks du
 	    # install
 	```
 
--	**Better**: *embed the checksum into the Dockerfile. It would be better to use https here too, if it is available.*
+-	**Better**: *embed the checksum into the `Dockerfile`. It would be better to use https here too, if it is available.*
 
 	```Dockerfile
 	ENV RUBY_DOWNLOAD_SHA256 5ffc0f317e429e6b29d4a98ac521c3ce65481bfd22a8cf845fa02a7b113d9b44
@@ -211,7 +220,57 @@ The `Dockerfile` should be written to help mitigate man-in-the-middle attacks du
 
 By default, Docker containers are executed with reduced privileges: whitelisted Linux capabilities, Control Groups, and a default Seccomp profile (1.10+ w/ host support). Software running in a container may require additional privileges in order to function correctly, and there are a number of command line options to customize container execution. See [`docker run` Reference](https://docs.docker.com/engine/reference/run/) and [Seccomp for Docker](https://docs.docker.com/engine/security/seccomp/) for reference.
 
-Official Repositories that require additional privileges should specify the minimal set of command line options for the software to function, and may still be rejected if this introduces significant portability or security issues. In general, `--privileged` is not allowed, but a combination of `--cap-add` and `--device` options may be acceptable. Additionally, `--volume` can be tricky as there are many host filesystem locations that introduce portability/security issues (i.e. X11 socket).
+Official Repositories that require additional privileges should specify the minimal set of command line options for the software to function, and may still be rejected if this introduces significant portability or security issues. In general, `--privileged` is not allowed, but a combination of `--cap-add` and `--device` options may be acceptable. Additionally, `--volume` can be tricky as there are many host filesystem locations that introduce portability/security issues (e.g. X11 socket).
+
+#### Multiple Architectures
+
+Each repo can specify multiple architectures for any and all tags. If no architecture is specified, images are built in Linux on `amd64` (aka x86-64). To specify more or different architectures, use the `Architectures` field (comma-delimited list, whitespace is trimmed). Valid architectures are found in [`oci-platform.go`](https://github.com/docker-library/official-images/blob/a7ad3081aa5f51584653073424217e461b72670a/bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/architecture/oci-platform.go#L14-L25):
+
+-	`amd64`
+-	`arm32v6`
+-	`arm32v7`
+-	`arm64v8`
+-	`i386`
+-	`ppc64le`
+-	`s390x`
+-	`windows-amd64`
+
+We strongly recommend that most images create a single `Dockerfile` per entry in the library file that can be used for multiple architectures. This means that each supported architecture will have the same `FROM` line (e.g. `FROM debian:jessie`). While official images are in the process of completing [image indexes](https://github.com/opencontainers/image-spec/blob/v1.0.0-rc6/image-index.md) to make this work naturally, the servers that build for non-amd64 architectures will pull the correct architecture-specific base and `docker tag` the base image to make the `FROM` work correctly. See [`golang`](https://github.com/docker-library/official-images/blob/master/library/golang), [`docker`](https://github.com/docker-library/official-images/blob/master/library/docker), [`haproxy`](https://github.com/docker-library/official-images/blob/master/library/haproxy), and [`php`](https://github.com/docker-library/official-images/blob/master/library/php) for examples of library files using one `Dockerfile` per entry and see their respective git repos for example `Dockerfile`s.
+
+For images that are `FROM scratch` like `debian` it will be necessary to have a different `Dockerfile` and build context in order to `ADD` architecture specific binaries. Since these images use the same `Tags`, they need to be in the same entry. Use the architecture specific fields for `GitRepo`, `GitFetch`, `GitCommit`, and `Directory`, which are the architecture concatenated with hyphen (`-`) and the field (e.g. `arm32v7-GitCommit`). Any architecture that does not have an architecture-specific field will use the default field (e.g. no `arm32v7-Directory` means `Directory` will be used for `arm32v7`). See the [`debian`](https://github.com/docker-library/official-images/blob/master/library/debian) or [`ubuntu`](https://github.com/docker-library/official-images/blob/master/library/ubuntu) files in the library for examples. The following is an example for [`hello-world`](https://github.com/docker-library/official-images/blob/master/library/hello-world):
+
+```
+Maintainers: Tianon Gravi <[email protected]> (@tianon),
+             Joseph Ferguson <[email protected]> (@yosifkit)
+GitRepo: https://github.com/docker-library/hello-world.git
+GitCommit: 7d0ee592e4ed60e2da9d59331e16ecdcadc1ed87
+
+Tags: latest
+Architectures: amd64, arm32v5, arm32v7, arm64v8, ppc64le, s390x
+# all the same commit; easy for us to generate this way since they could be different
+amd64-GitCommit: 7d0ee592e4ed60e2da9d59331e16ecdcadc1ed87
+amd64-Directory: amd64/hello-world
+arm32v5-GitCommit: 7d0ee592e4ed60e2da9d59331e16ecdcadc1ed87
+arm32v5-Directory: arm32v5/hello-world
+arm32v7-GitCommit: 7d0ee592e4ed60e2da9d59331e16ecdcadc1ed87
+arm32v7-Directory: arm32v7/hello-world
+arm64v8-GitCommit: 7d0ee592e4ed60e2da9d59331e16ecdcadc1ed87
+arm64v8-Directory: arm64v8/hello-world
+ppc64le-GitCommit: 7d0ee592e4ed60e2da9d59331e16ecdcadc1ed87
+ppc64le-Directory: ppc64le/hello-world
+s390x-GitCommit: 7d0ee592e4ed60e2da9d59331e16ecdcadc1ed87
+s390x-Directory: s390x/hello-world
+
+Tags: nanoserver
+Architectures: windows-amd64
+# if there is only one architecture, you can use the unprefixed fields
+Directory: amd64/hello-world/nanoserver
+# or use the prefixed versions
+windows-amd64-GitCommit: 7d0ee592e4ed60e2da9d59331e16ecdcadc1ed87
+Constraints: nanoserver
+```
+
+See the [instruction format section](#instruction-format) for more information on the format of the library file.
 
 ### Commitment
 
@@ -241,9 +300,9 @@ As described above, `latest` is really "default", so the image that it is an ali
 
 The manifest file format is officially based on [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt), and as such should be familiar to folks who are already familiar with the "headers" of many popular internet protocols/formats such as HTTP or email.
 
-The primary additions are inspired by the way Debian commonly uses 2822 -- namely, lines starting with `#` are ignored and "paragraphs" (or "entries") are separated by a blank line.
+The primary additions are inspired by the way Debian commonly uses 2822 -- namely, lines starting with `#` are ignored and "entries" are separated by a blank line.
 
-The first entry is the "global" metadata for the image. The only required field in the global entry is `Maintainers`, whose value is comma-separated in the format of `Name <email> (@github)` or `Name (@github)`. Any field specified in the global entry will be the default for the rest of the entries/paragraphs and can be overridden in an individual paragraph.
+The first entry is the "global" metadata for the image. The only required field in the global entry is `Maintainers`, whose value is comma-separated in the format of `Name <email> (@github)` or `Name (@github)`. Any field specified in the global entry will be the default for the rest of the entries and can be overridden in an individual entry.
 
 	# this is a comment and will be ignored
 	Maintainers: John Smith <[email protected]> (@example-jsmith),
@@ -274,37 +333,7 @@ The built image will be tagged as `<manifest-filename>:<tag>` (ie, `library/gola
 
 Optionally, if `Directory` is present, Bashbrew will look for the `Dockerfile` inside the specified subdirectory instead of at the root (and `Directory` will be used as the ["context" for the build](https://docs.docker.com/reference/builder/) instead of the top-level of the repository).
 
-#### Deprecated format
-
-This is the older, now-deprecated format for library manifest files. Its usage is discouraged (although it is still supported).
-
-	# maintainer: Your Name <[email protected]> (@github.name)
-	
-	# maintainer: John Smith <[email protected]> (@example-jsmith)
-	# maintainer: Anne Smith <[email protected]> (@example-asmith)
-	
-	
-	<Tag>: <GitRepo>@<GitCommit>
-	
-	4.1.1: git://github.com/docker-library/wordpress@bbef6075afa043cbfe791b8de185105065c02c01
-	4.1: git://github.com/docker-library/wordpress@bbef6075afa043cbfe791b8de185105065c02c01
-	4: git://github.com/docker-library/wordpress@bbef6075afa043cbfe791b8de185105065c02c01
-	latest: git://github.com/docker-library/wordpress@bbef6075afa043cbfe791b8de185105065c02c01
-	
-	
-	<Tag>: <GitRepo>@<GitCommit> <Directory>
-	
-	2.6.17: git://github.com/docker-library/redis@062335e0a8d20cab2041f25dfff2fbaf58544471 2.6
-	2.6: git://github.com/docker-library/redis@062335e0a8d20cab2041f25dfff2fbaf58544471 2.6
-	
-	2.8.19: git://github.com/docker-library/redis@062335e0a8d20cab2041f25dfff2fbaf58544471 2.8
-	2.8: git://github.com/docker-library/redis@062335e0a8d20cab2041f25dfff2fbaf58544471 2.8
-	2: git://github.com/docker-library/redis@062335e0a8d20cab2041f25dfff2fbaf58544471 2.8
-	latest: git://github.com/docker-library/redis@062335e0a8d20cab2041f25dfff2fbaf58544471 2.8
-	
-	experimental: git://github.com/tianon/dockerfiles@90d86ad63c4a06b7d04d14ad830381b876183b3c debian/experimental
-
-Using Git tags instead of explicit Git commit references is supported for the deprecated format only, but is heavily discouraged. For example, if a Git tag is changed on the referenced repository to point to another commit, **the image will not be rebuilt**. Instead, either create a new tag (or reference an exact commit) and submit a pull request.
+See the [multi-arch section](#multiple-architectures) for details on how to specify a different `GitRepo`, `GitFetch`, `GitCommit`, or `Directory` for a specific architecture.
 
 ### Creating a new repository
 

+ 37 - 0
bashbrew/.bashbrew-arch-to-goenv.sh

@@ -0,0 +1,37 @@
+#!/bin/sh
+set -euo pipefail
+
+# usage: (from within another script)
+#   eval "$(./.bashbrew-arch-to-goenv.sh)"
+# since we need those new environment variables in our other script
+
+bashbrewArch="$1"; shift # "amd64", "arm32v5", "windows-amd64", etc.
+
+os="${bashbrewArch%%-*}"
+[ "$os" != "$bashbrewArch" ] || os='linux'
+printf 'export GOOS="%s"\n' "$os"
+
+arch="${bashbrewArch#${os}-}"
+case "$arch" in
+	arm32v*)
+		printf 'export GOARCH="%s"\n' 'arm'
+		printf 'export GOARM="%s"\n' "${arch#arm32v}"
+		;;
+
+	arm64v*)
+		printf 'export GOARCH="%s"\n' 'arm64'
+		# no GOARM for arm64 (yet?) -- https://github.com/golang/go/blob/1e72bf62183ea21b9affffd4450d44d994393899/src/cmd/internal/objabi/util.go#L40
+		#printf 'export GOARM="%s"\n' "${arch#arm64v}"
+		printf 'unset GOARM\n'
+		;;
+
+	i386)
+		printf 'export GOARCH="%s"\n' '386'
+		printf 'unset GOARM\n'
+		;;
+
+	*)
+		printf 'export GOARCH="%s"\n' "$arch"
+		printf 'unset GOARM\n'
+		;;
+esac

+ 9 - 0
bashbrew/.dockerignore

@@ -0,0 +1,9 @@
+*.md
+*.sh
+.dockerignore
+Dockerfile*
+go/bin
+go/pkg
+go/vendor/bin
+go/vendor/pkg
+!.bashbrew-arch-to-goenv.sh

+ 88 - 0
bashbrew/Dockerfile.release

@@ -0,0 +1,88 @@
+FROM golang:1.8-alpine
+
+RUN apk add --no-cache \
+		file \
+		gnupg \
+		libressl
+
+WORKDIR /usr/src/bashbrew
+ENV GOPATH /usr/src/bashbrew:/usr/src/bashbrew/vendor
+ENV CGO_ENABLED 0
+
+ENV BASHBREW_ARCHES \
+		amd64 \
+		arm32v5 \
+		arm32v6 \
+		arm32v7 \
+		arm64v8 \
+		darwin-amd64 \
+		i386 \
+		ppc64le \
+		s390x \
+		windows-amd64
+
+COPY .bashbrew-arch-to-goenv.sh /usr/local/bin/
+
+# https://github.com/estesp/manifest-tool/releases
+ENV MANIFEST_TOOL_VERSION 0.6.0
+# gpg: key 0F386284C03A1162: public key "Philip Estes <[email protected]>" imported
+#ENV MANIFEST_TOOL_GPG_KEY 27F3EA268A97867EAF0BD05C0F386284C03A1162
+# TODO consume Phil's releases again (once he fixes https://github.com/estesp/manifest-tool/issues/47 properly)
+
+COPY manifest-tool.patch ./
+
+RUN set -euxo pipefail; \
+	\
+	mkdir -p bin; \
+	\
+	mkdir -p manifest-tool/src/github.com/estesp/manifest-tool; \
+	wget -qO- "https://github.com/estesp/manifest-tool/archive/v${MANIFEST_TOOL_VERSION}.tar.gz" \
+		| tar -xz --strip-components=1 -C manifest-tool/src/github.com/estesp/manifest-tool; \
+	( cd manifest-tool/src/github.com/estesp/manifest-tool && patch -p1 ) < manifest-tool.patch; \
+	for bashbrewArch in $BASHBREW_ARCHES; do \
+		( \
+			goEnv="$(.bashbrew-arch-to-goenv.sh "$bashbrewArch")"; eval "$goEnv"; \
+			[ "$GOOS" = 'windows' ] && ext='.exe' || ext=; \
+			GOPATH="$PWD/manifest-tool" \
+				go build \
+					-a -v \
+					-ldflags '-s -w' \
+# see https://github.com/golang/go/issues/9737#issuecomment-276817652 (and following comments) -- installsuffix is necessary (for now) to keep ARM
+# can remove "$bashbrewArch" from "installsuffix" in Go 1.10+ (https://github.com/golang/go/commit/1b53f15ebb00dd158af674df410c7941abb2b933)
+					-tags netgo -installsuffix "netgo-$bashbrewArch" \
+					-o "$PWD/bin/manifest-tool-$bashbrewArch$ext" \
+					github.com/estesp/manifest-tool \
+			; \
+			ls -lAFh "bin/manifest-tool-$bashbrewArch$ext"; \
+			file "bin/manifest-tool-$bashbrewArch$ext"; \
+		) \
+	done; \
+	\
+	ls -l bin; \
+	file bin/*
+
+COPY go .
+
+RUN set -euxo pipefail; \
+	\
+	mkdir -p bin; \
+	\
+	for bashbrewArch in $BASHBREW_ARCHES; do \
+		( \
+			goEnv="$(.bashbrew-arch-to-goenv.sh "$bashbrewArch")"; eval "$goEnv"; \
+			[ "$GOOS" = 'windows' ] && ext='.exe' || ext=; \
+			\
+			go build \
+				-a -v \
+				-ldflags '-s -w' \
+	# see https://github.com/golang/go/issues/9737#issuecomment-276817652 (and following comments) -- installsuffix is necessary (for now) to keep ARM
+	# can remove "$bashbrewArch" from "installsuffix" in Go 1.10+ (https://github.com/golang/go/commit/1b53f15ebb00dd158af674df410c7941abb2b933)
+				-tags netgo -installsuffix "netgo-$bashbrewArch" \
+				-o "bin/bashbrew-$bashbrewArch$ext" \
+				./src/bashbrew \
+			; \
+		) \
+	done; \
+	\
+	ls -l bin; \
+	file bin/*

+ 30 - 24
bashbrew/go/src/bashbrew/cmd-build.go

@@ -12,9 +12,9 @@ func cmdBuild(c *cli.Context) error {
 		return cli.NewMultiError(fmt.Errorf(`failed gathering repo list`), err)
 	}
 
-	repos, err = sortRepos(repos)
+	repos, err = sortRepos(repos, true)
 	if err != nil {
-		return cli.NewMultiError(fmt.Errorf(`failed sorting repo list`, err))
+		return cli.NewMultiError(fmt.Errorf(`failed sorting repo list`), err)
 	}
 
 	uniq := c.Bool("uniq")
@@ -26,6 +26,7 @@ func cmdBuild(c *cli.Context) error {
 	default:
 		return fmt.Errorf(`invalid value for --pull: %q`, pull)
 	}
+	dryRun := c.Bool("dry-run")
 
 	for _, repo := range repos {
 		r, err := fetch(repo)
@@ -33,7 +34,7 @@ func cmdBuild(c *cli.Context) error {
 			return cli.NewMultiError(fmt.Errorf(`failed fetching repo %q`, repo), err)
 		}
 
-		entries, err := r.SortedEntries()
+		entries, err := r.SortedEntries(true)
 		if err != nil {
 			return cli.NewMultiError(fmt.Errorf(`failed sorting entries list for %q`, repo), err)
 		}
@@ -60,8 +61,11 @@ func cmdBuild(c *cli.Context) error {
 					return fmt.Errorf(`unexpected value for --pull: %s`, pull)
 				}
 				if doPull {
+					// TODO detect if "from" is something we've built (ie, "python:3-onbuild" is "FROM python:3" but we don't want to pull "python:3" if we "bashbrew build python")
 					fmt.Printf("Pulling %s (%s)\n", from, r.EntryIdentifier(entry))
-					dockerPull(from)
+					if !dryRun {
+						dockerPull(from)
+					}
 				}
 			}
 
@@ -74,33 +78,35 @@ func cmdBuild(c *cli.Context) error {
 			_, err = dockerInspect("{{.Id}}", cacheTag)
 			if err != nil {
 				fmt.Printf("Building %s (%s)\n", cacheTag, r.EntryIdentifier(entry))
-
-				commit, err := r.fetchGitRepo(&entry)
-				if err != nil {
-					return cli.NewMultiError(fmt.Errorf(`failed fetching git repo for %q (tags %q)`, r.RepoName, entry.TagsString()), err)
-				}
-
-				archive, err := gitArchive(commit, entry.Directory)
-				if err != nil {
-					return cli.NewMultiError(fmt.Errorf(`failed generating git archive for %q (tags %q)`, r.RepoName, entry.TagsString()), err)
+				if !dryRun {
+					commit, err := r.fetchGitRepo(arch, &entry)
+					if err != nil {
+						return cli.NewMultiError(fmt.Errorf(`failed fetching git repo for %q (tags %q)`, r.RepoName, entry.TagsString()), err)
+					}
+
+					archive, err := gitArchive(commit, entry.ArchDirectory(arch))
+					if err != nil {
+						return cli.NewMultiError(fmt.Errorf(`failed generating git archive for %q (tags %q)`, r.RepoName, entry.TagsString()), err)
+					}
+					defer archive.Close()
+
+					err = dockerBuild(cacheTag, archive)
+					if err != nil {
+						return cli.NewMultiError(fmt.Errorf(`failed building %q (tags %q)`, r.RepoName, entry.TagsString()), err)
+					}
+					archive.Close() // be sure this happens sooner rather than later (defer might take a while, and we want to reap zombies more aggressively)
 				}
-				defer archive.Close()
-
-				err = dockerBuild(cacheTag, archive)
-				if err != nil {
-					return cli.NewMultiError(fmt.Errorf(`failed building %q (tags %q)`, r.RepoName, entry.TagsString()), err)
-				}
-				archive.Close() // be sure this happens sooner rather than later (defer might take a while, and we want to reap zombies more aggressively)
 			} else {
 				fmt.Printf("Using %s (%s)\n", cacheTag, r.EntryIdentifier(entry))
 			}
 
 			for _, tag := range r.Tags(namespace, uniq, entry) {
 				fmt.Printf("Tagging %s\n", tag)
-
-				err := dockerTag(cacheTag, tag)
-				if err != nil {
-					return cli.NewMultiError(fmt.Errorf(`failed tagging %q as %q`, cacheTag, tag), err)
+				if !dryRun {
+					err := dockerTag(cacheTag, tag)
+					if err != nil {
+						return cli.NewMultiError(fmt.Errorf(`failed tagging %q as %q`, cacheTag, tag), err)
+					}
 				}
 			}
 		}

+ 3 - 0
bashbrew/go/src/bashbrew/cmd-cat.go

@@ -42,6 +42,9 @@ func cmdCat(c *cli.Context) error {
 		"i": func() int {
 			return i
 		},
+		"arch": func() string {
+			return arch
+		},
 	}).Parse(format)
 	if err != nil {
 		return cli.NewMultiError(tmplMultiErr, err)

+ 42 - 11
bashbrew/go/src/bashbrew/cmd-deps.go

@@ -15,6 +15,11 @@ func cmdParents(c *cli.Context) error {
 	return cmdFamily(true, c)
 }
 
+type topsortDepthNodes struct {
+	depth int
+	nodes []*topsort.Node
+}
+
 func cmdFamily(parents bool, c *cli.Context) error {
 	depsRepos, err := repos(c.Bool("all"), c.Args()...)
 	if err != nil {
@@ -23,6 +28,7 @@ func cmdFamily(parents bool, c *cli.Context) error {
 
 	uniq := c.Bool("uniq")
 	applyConstraints := c.Bool("apply-constraints")
+	depth := c.Int("depth")
 
 	allRepos, err := repos(true)
 	if err != nil {
@@ -40,6 +46,10 @@ func cmdFamily(parents bool, c *cli.Context) error {
 		}
 
 		for _, entry := range r.Entries() {
+			if applyConstraints && r.SkipConstraints(entry) {
+				continue
+			}
+
 			for _, tag := range r.Tags("", false, entry) {
 				network.AddNode(tag, entry)
 			}
@@ -53,6 +63,10 @@ func cmdFamily(parents bool, c *cli.Context) error {
 			return cli.NewMultiError(fmt.Errorf(`failed fetching repo %q`, repo), err)
 		}
 		for _, entry := range r.Entries() {
+			if applyConstraints && r.SkipConstraints(entry) {
+				continue
+			}
+
 			from, err := r.DockerFrom(&entry)
 			if err != nil {
 				return cli.NewMultiError(fmt.Errorf(`failed fetching/scraping FROM for %q (tags %q)`, r.RepoName, entry.TagsString()), err)
@@ -77,24 +91,41 @@ func cmdFamily(parents bool, c *cli.Context) error {
 			}
 
 			for _, tag := range r.Tags("", uniq, entry) {
-				nodes := []*topsort.Node{}
+				nodes := []topsortDepthNodes{}
 				if parents {
-					nodes = append(nodes, network.Get(tag).InboundEdges...)
+					nodes = append(nodes, topsortDepthNodes{
+						depth: 1,
+						nodes: network.Get(tag).InboundEdges,
+					})
 				} else {
-					nodes = append(nodes, network.Get(tag).OutboundEdges...)
+					nodes = append(nodes, topsortDepthNodes{
+						depth: 1,
+						nodes: network.Get(tag).OutboundEdges,
+					})
 				}
 				for len(nodes) > 0 {
-					node := nodes[0]
+					depthNodes := nodes[0]
 					nodes = nodes[1:]
-					if seen[node] {
+					if depth > 0 && depthNodes.depth > depth {
 						continue
 					}
-					seen[node] = true
-					fmt.Printf("%s\n", node.Name)
-					if parents {
-						nodes = append(nodes, node.InboundEdges...)
-					} else {
-						nodes = append(nodes, node.OutboundEdges...)
+					for _, node := range depthNodes.nodes {
+						if seen[node] {
+							continue
+						}
+						seen[node] = true
+						fmt.Printf("%s\n", node.Name)
+						if parents {
+							nodes = append(nodes, topsortDepthNodes{
+								depth: depthNodes.depth + 1,
+								nodes: node.InboundEdges,
+							})
+						} else {
+							nodes = append(nodes, topsortDepthNodes{
+								depth: depthNodes.depth + 1,
+								nodes: node.OutboundEdges,
+							})
+						}
 					}
 				}
 			}

+ 5 - 0
bashbrew/go/src/bashbrew/cmd-from.go

@@ -14,6 +14,7 @@ func cmdFrom(c *cli.Context) error {
 
 	uniq := c.Bool("uniq")
 	namespace := ""
+	applyConstraints := c.Bool("apply-constraints")
 
 	for _, repo := range repos {
 		r, err := fetch(repo)
@@ -22,6 +23,10 @@ func cmdFrom(c *cli.Context) error {
 		}
 
 		for _, entry := range r.Entries() {
+			if applyConstraints && r.SkipConstraints(entry) {
+				continue
+			}
+
 			from, err := r.DockerFrom(&entry)
 			if err != nil {
 				return cli.NewMultiError(fmt.Errorf(`failed fetching/scraping FROM for %q (tags %q)`, r.RepoName, entry.TagsString()), err)

+ 7 - 7
bashbrew/go/src/bashbrew/cmd-list.go

@@ -13,19 +13,19 @@ func cmdList(c *cli.Context) error {
 		return cli.NewMultiError(fmt.Errorf(`failed gathering repo list`), err)
 	}
 
+	uniq := c.Bool("uniq")
+	namespace := ""
+	applyConstraints := c.Bool("apply-constraints")
+	onlyRepos := c.Bool("repos")
+
 	buildOrder := c.Bool("build-order")
 	if buildOrder {
-		repos, err = sortRepos(repos)
+		repos, err = sortRepos(repos, applyConstraints)
 		if err != nil {
 			return cli.NewMultiError(fmt.Errorf(`failed sorting repo list`), err)
 		}
 	}
 
-	uniq := c.Bool("uniq")
-	namespace := ""
-	applyConstraints := c.Bool("apply-constraints")
-	onlyRepos := c.Bool("repos")
-
 	for _, repo := range repos {
 		r, err := fetch(repo)
 		if err != nil {
@@ -45,7 +45,7 @@ func cmdList(c *cli.Context) error {
 
 		var entries []manifest.Manifest2822Entry
 		if buildOrder {
-			entries, err = r.SortedEntries()
+			entries, err = r.SortedEntries(applyConstraints)
 			if err != nil {
 				return cli.NewMultiError(fmt.Errorf(`failed sorting entries list for %q`, repo), err)
 			}

+ 15 - 4
bashbrew/go/src/bashbrew/cmd-push.go

@@ -2,6 +2,8 @@ package main
 
 import (
 	"fmt"
+	"os"
+	"time"
 
 	"github.com/codegangsta/cli"
 )
@@ -14,6 +16,7 @@ func cmdPush(c *cli.Context) error {
 
 	uniq := c.Bool("uniq")
 	namespace := c.String("namespace")
+	dryRun := c.Bool("dry-run")
 
 	if namespace == "" {
 		return fmt.Errorf(`"--namespace" is a required flag for "push"`)
@@ -31,10 +34,18 @@ func cmdPush(c *cli.Context) error {
 			}
 
 			for _, tag := range r.Tags(namespace, uniq, entry) {
-				fmt.Printf("Pushing %s\n", tag)
-				err = dockerPush(tag)
-				if err != nil {
-					return cli.NewMultiError(fmt.Errorf(`failed pushing %q`, tag), err)
+				created := dockerCreated(tag)
+				lastUpdated := fetchDockerHubTagMeta(tag).lastUpdatedTime()
+				if created.After(lastUpdated) {
+					fmt.Printf("Pushing %s\n", tag)
+					if !dryRun {
+						err = dockerPush(tag)
+						if err != nil {
+							return cli.NewMultiError(fmt.Errorf(`failed pushing %q`, tag), err)
+						}
+					}
+				} else {
+					fmt.Fprintf(os.Stderr, "skipping %s (created %s, last updated %s)\n", tag, created.Local().Format(time.RFC3339), lastUpdated.Local().Format(time.RFC3339))
 				}
 			}
 		}

+ 153 - 0
bashbrew/go/src/bashbrew/cmd-put-shared.go

@@ -0,0 +1,153 @@
+package main
+
+import (
+	"fmt"
+	"os"
+	"path"
+	"time"
+
+	"github.com/codegangsta/cli"
+
+	"github.com/docker-library/go-dockerlibrary/architecture"
+	"github.com/docker-library/go-dockerlibrary/manifest"
+)
+
+func entriesToManifestToolYaml(singleArch bool, r Repo, entries ...*manifest.Manifest2822Entry) (string, time.Time, error) {
+	yaml := ""
+	mru := time.Time{}
+	entryIdentifiers := []string{}
+	for _, entry := range entries {
+		entryIdentifiers = append(entryIdentifiers, r.EntryIdentifier(*entry))
+
+		for _, entryArch := range entry.Architectures {
+			if singleArch && entryArch != arch {
+				continue
+			}
+
+			var ok bool
+
+			var ociArch architecture.OCIPlatform
+			if ociArch, ok = architecture.SupportedArches[entryArch]; !ok {
+				// this should never happen -- the parser validates Architectures
+				panic("somehow, an unsupported architecture slipped past the parser validation: " + entryArch)
+			}
+
+			var archNamespace string
+			if archNamespace, ok = archNamespaces[entryArch]; !ok || archNamespace == "" {
+				fmt.Fprintf(os.Stderr, "warning: no arch-namespace specified for %q; skipping (%q)\n", entryArch, r.EntryIdentifier(*entry))
+				continue
+			}
+
+			archImage := fmt.Sprintf("%s/%s:%s", archNamespace, r.RepoName, entry.Tags[0])
+			archImageMeta := fetchDockerHubTagMeta(archImage)
+			if archU := archImageMeta.lastUpdatedTime(); archU.After(mru) {
+				mru = archU
+			}
+
+			yaml += fmt.Sprintf("  - image: %s\n    platform:\n", archImage)
+			yaml += fmt.Sprintf("      os: %s\n", ociArch.OS)
+			yaml += fmt.Sprintf("      architecture: %s\n", ociArch.Architecture)
+			if ociArch.Variant != "" {
+				yaml += fmt.Sprintf("      variant: %s\n", ociArch.Variant)
+			}
+		}
+	}
+
+	return "manifests:\n" + yaml, mru, nil
+}
+
+func tagsToManifestToolYaml(repo string, tags ...string) string {
+	yaml := fmt.Sprintf("image: %s:%s\n", repo, tags[0])
+	if len(tags) > 1 {
+		yaml += "tags:\n"
+		for _, tag := range tags[1:] {
+			yaml += fmt.Sprintf("  - %s\n", tag)
+		}
+	}
+	return yaml
+}
+
+func cmdPutShared(c *cli.Context) error {
+	repos, err := repos(c.Bool("all"), c.Args()...)
+	if err != nil {
+		return cli.NewMultiError(fmt.Errorf(`failed gathering repo list`), err)
+	}
+
+	namespace := c.String("namespace")
+	dryRun := c.Bool("dry-run")
+	singleArch := c.Bool("single-arch")
+
+	if namespace == "" {
+		return fmt.Errorf(`"--namespace" is a required flag for "put-shared"`)
+	}
+
+	for _, repo := range repos {
+		r, err := fetch(repo)
+		if err != nil {
+			return cli.NewMultiError(fmt.Errorf(`failed fetching repo %q`, repo), err)
+		}
+
+		targetRepo := path.Join(namespace, r.RepoName)
+
+		sharedTagGroups := []manifest.SharedTagGroup{}
+
+		if !singleArch {
+			// handle all multi-architecture tags first (regardless of whether they have SharedTags)
+			// turn them into SharedTagGroup objects so all manifest-tool invocations can be handled by a single process/loop
+			for _, entry := range r.Entries() {
+				entryCopy := entry
+				sharedTagGroups = append(sharedTagGroups, manifest.SharedTagGroup{
+					SharedTags: entry.Tags,
+					Entries:    []*manifest.Manifest2822Entry{&entryCopy},
+				})
+			}
+		}
+
+		// TODO do something smarter with r.TagName (ie, the user has done something crazy like "bashbrew put-shared single-repo:single-tag")
+		if r.TagName == "" {
+			sharedTagGroups = append(sharedTagGroups, r.Manifest.GetSharedTagGroups()...)
+		} else {
+			fmt.Fprintf(os.Stderr, "warning: a single tag was requested -- skipping SharedTags\n")
+		}
+
+		if len(sharedTagGroups) == 0 {
+			continue
+		}
+
+		for _, group := range sharedTagGroups {
+			yaml, mostRecentPush, err := entriesToManifestToolYaml(singleArch, *r, group.Entries...)
+			if err != nil {
+				return err
+			}
+
+			tagsToPush := []string{}
+			for _, tag := range group.SharedTags {
+				image := fmt.Sprintf("%s:%s", targetRepo, tag)
+				hubMeta := fetchDockerHubTagMeta(image)
+				tagUpdated := hubMeta.lastUpdatedTime()
+				if mostRecentPush.After(tagUpdated) ||
+					(!singleArch && len(hubMeta.Images) <= 1 &&
+						(len(group.Entries) > 1 || len(group.Entries[0].Architectures) > 1)) {
+					tagsToPush = append(tagsToPush, tag)
+				} else {
+					fmt.Fprintf(os.Stderr, "skipping %s (created %s, last updated %s)\n", image, mostRecentPush.Local().Format(time.RFC3339), tagUpdated.Local().Format(time.RFC3339))
+				}
+			}
+
+			if len(tagsToPush) == 0 {
+				continue
+			}
+
+			groupIdentifier := fmt.Sprintf("%s:%s", targetRepo, tagsToPush[0])
+			fmt.Printf("Putting %s\n", groupIdentifier)
+			if !dryRun {
+				tagYaml := tagsToManifestToolYaml(targetRepo, tagsToPush...) + yaml
+				if err := manifestToolPushFromSpec(tagYaml); err != nil {
+					return fmt.Errorf("failed pushing %s", groupIdentifier)
+				}
+			}
+		}
+	}
+
+	return nil
+}

+ 6 - 3
bashbrew/go/src/bashbrew/cmd-tag.go

@@ -15,6 +15,7 @@ func cmdTag(c *cli.Context) error {
 
 	uniq := c.Bool("uniq")
 	namespace := c.String("namespace")
+	dryRun := c.Bool("dry-run")
 
 	if namespace == "" {
 		return fmt.Errorf(`"--namespace" is a required flag for "tag"`)
@@ -34,9 +35,11 @@ func cmdTag(c *cli.Context) error {
 			for _, tag := range r.Tags("", uniq, entry) {
 				namespacedTag := path.Join(namespace, tag)
 				fmt.Printf("Tagging %s\n", namespacedTag)
-				err = dockerTag(tag, namespacedTag)
-				if err != nil {
-					return cli.NewMultiError(fmt.Errorf(`failed tagging %q as %q`, tag, namespacedTag), err)
+				if !dryRun {
+					err = dockerTag(tag, namespacedTag)
+					if err != nil {
+						return cli.NewMultiError(fmt.Errorf(`failed tagging %q as %q`, tag, namespacedTag), err)
+					}
 				}
 			}
 		}

+ 13 - 0
bashbrew/go/src/bashbrew/config.go

@@ -26,9 +26,13 @@ type FlagsConfigEntry struct {
 	BuildOrder string
 	Pull       string
 
+	Arch                 string
 	Constraints          []string `delim:"," strip:"\n\r\t "`
 	ExclusiveConstraints string
 	ApplyConstraints     string
+
+	// a list of "arch=namespace" mappings for pushing indexes (manifest lists)
+	ArchNamespaces []string `delim:"," strip:"\n\r\t "`
 }
 
 type FlagsConfig map[string]FlagsConfigEntry
@@ -55,6 +59,9 @@ func (dst *FlagsConfigEntry) Apply(src FlagsConfigEntry) {
 	if src.Pull != "" {
 		dst.Pull = src.Pull
 	}
+	if src.Arch != "" {
+		dst.Arch = src.Arch
+	}
 	if len(src.Constraints) > 0 {
 		dst.Constraints = src.Constraints[:]
 	}
@@ -64,6 +71,9 @@ func (dst *FlagsConfigEntry) Apply(src FlagsConfigEntry) {
 	if src.ApplyConstraints != "" {
 		dst.ApplyConstraints = src.ApplyConstraints
 	}
+	if len(src.ArchNamespaces) > 0 {
+		dst.ArchNamespaces = src.ArchNamespaces[:]
+	}
 }
 
 func (config FlagsConfigEntry) Vars() map[string]map[string]interface{} {
@@ -73,8 +83,11 @@ func (config FlagsConfigEntry) Vars() map[string]map[string]interface{} {
 			"cache":   config.Cache,
 			"debug":   config.Debug,
 
+			"arch":                  config.Arch,
 			"constraint":            config.Constraints,
 			"exclusive-constraints": config.ExclusiveConstraints,
+
+			"arch-namespace": config.ArchNamespaces,
 		},
 
 		"local": {

+ 10 - 5
bashbrew/go/src/bashbrew/docker.go

@@ -19,12 +19,16 @@ import (
 var dockerFromCache = map[string]string{}
 
 func (r Repo) DockerFrom(entry *manifest.Manifest2822Entry) (string, error) {
-	commit, err := r.fetchGitRepo(entry)
+	return r.ArchDockerFrom(arch, entry)
+}
+
+func (r Repo) ArchDockerFrom(arch string, entry *manifest.Manifest2822Entry) (string, error) {
+	commit, err := r.fetchGitRepo(arch, entry)
 	if err != nil {
 		return "", err
 	}
 
-	dockerfileFile := path.Join(entry.Directory, "Dockerfile")
+	dockerfileFile := path.Join(entry.ArchDirectory(arch), "Dockerfile")
 
 	cacheKey := strings.Join([]string{
 		commit,
@@ -56,6 +60,7 @@ func (r Repo) DockerFrom(entry *manifest.Manifest2822Entry) (string, error) {
 	return from, nil
 }
 
+// TODO determine multi-stage-builds impact here (once official images are willing/able to support them; post-17.06 at the earliest)
 func dockerfileFrom(dockerfile io.Reader) (string, error) {
 	scanner := bufio.NewScanner(dockerfile)
 	for scanner.Scan() {
@@ -130,9 +135,9 @@ func (r Repo) dockerBuildUniqueBits(entry *manifest.Manifest2822Entry) ([]string
 		dockerFromIdCache[from] = fromId
 	}
 	return []string{
-		entry.GitRepo,
-		entry.GitCommit,
-		entry.Directory,
+		entry.ArchGitRepo(arch),
+		entry.ArchGitCommit(arch),
+		entry.ArchDirectory(arch),
 		fromId,
 	}, nil
 }

+ 57 - 16
bashbrew/go/src/bashbrew/git.go

@@ -8,6 +8,7 @@ import (
 	"os/exec"
 	"path"
 	"path/filepath"
+	"regexp"
 	"strings"
 
 	"github.com/docker-library/go-dockerlibrary/manifest"
@@ -19,6 +20,9 @@ func gitCache() string {
 }
 
 func gitCommand(args ...string) *exec.Cmd {
+	if debugFlag {
+		fmt.Printf("$ git %q\n", args)
+	}
 	cmd := exec.Command("git", args...)
 	cmd.Dir = gitCache()
 	return cmd
@@ -70,16 +74,43 @@ func gitShow(commit string, file string) (io.ReadCloser, error) {
 	return gitStream("show", commit+":"+path.Clean(file))
 }
 
+// for gitNormalizeForTagUsage()
+// see http://stackoverflow.com/a/26382358/433558
+var (
+	gitBadTagChars = regexp.MustCompile(`(?:` + strings.Join([]string{
+		`[^0-9a-zA-Z/._-]+`,
+
+		// They can include slash `/` for hierarchical (directory) grouping, but no slash-separated component can begin with a dot `.` or end with the sequence `.lock`.
+		`/[.]+`,
+		`[.]lock(?:/|$)`,
+
+		// They cannot have two consecutive dots `..` anywhere.
+		`[.][.]+`,
+
+		// They cannot end with a dot `.`
+		// They cannot begin or end with a slash `/`
+		`[/.]+$`,
+		`^[/.]+`,
+	}, `|`) + `)`)
+
+	gitMultipleSlashes = regexp.MustCompile(`(?://+)`)
+)
+
+// strip/replace "bad" characters from text for use as a Git tag
+func gitNormalizeForTagUsage(text string) string {
+	return gitMultipleSlashes.ReplaceAllString(gitBadTagChars.ReplaceAllString(text, "-"), "/")
+}
+
 var gitRepoCache = map[string]string{}
 
-func (r Repo) fetchGitRepo(entry *manifest.Manifest2822Entry) (string, error) {
+func (r Repo) fetchGitRepo(arch string, entry *manifest.Manifest2822Entry) (string, error) {
 	cacheKey := strings.Join([]string{
-		entry.GitRepo,
-		entry.GitFetch,
-		entry.GitCommit,
+		entry.ArchGitRepo(arch),
+		entry.ArchGitFetch(arch),
+		entry.ArchGitCommit(arch),
 	}, "\n")
 	if commit, ok := gitRepoCache[cacheKey]; ok {
-		entry.GitCommit = commit
+		entry.SetGitCommit(arch, commit)
 		return commit, nil
 	}
 
@@ -88,17 +119,27 @@ func (r Repo) fetchGitRepo(entry *manifest.Manifest2822Entry) (string, error) {
 		return "", err
 	}
 
-	if manifest.GitCommitRegex.MatchString(entry.GitCommit) {
-		commit, err := getGitCommit(entry.GitCommit)
+	if manifest.GitCommitRegex.MatchString(entry.ArchGitCommit(arch)) {
+		commit, err := getGitCommit(entry.ArchGitCommit(arch))
 		if err == nil {
 			gitRepoCache[cacheKey] = commit
-			entry.GitCommit = commit
+			entry.SetGitCommit(arch, commit)
 			return commit, nil
 		}
 	}
 
-	fetchString := entry.GitFetch + ":"
-	if entry.GitFetch == manifest.DefaultLineBasedFetch {
+	fetchString := entry.ArchGitFetch(arch) + ":"
+	if entry.ArchGitCommit(arch) == "FETCH_HEAD" {
+		// fetch remote tag references to a local tag ref so that we can cache them and not re-fetch every time
+		localRef := "refs/tags/" + gitNormalizeForTagUsage(cacheKey)
+		commit, err := getGitCommit(localRef)
+		if err == nil {
+			gitRepoCache[cacheKey] = commit
+			entry.SetGitCommit(arch, commit)
+			return commit, nil
+		}
+		fetchString += localRef
+	} else if entry.ArchGitFetch(arch) == manifest.DefaultLineBasedFetch {
 		// backwards compat (see manifest/line-based.go in go-dockerlibrary)
 		refBase := "refs/remotes"
 		refBaseDir := filepath.Join(gitCache(), refBase)
@@ -116,17 +157,17 @@ func (r Repo) fetchGitRepo(entry *manifest.Manifest2822Entry) (string, error) {
 		// we create a temporary remote dir so that we can clean it up completely afterwards
 	}
 
-	if strings.HasPrefix(entry.GitRepo, "git://github.com/") {
-		fmt.Fprintf(os.Stderr, "warning: insecure protocol git:// detected: %s\n", entry.GitRepo)
-		entry.GitRepo = strings.Replace(entry.GitRepo, "git://", "https://", 1)
+	if strings.HasPrefix(entry.ArchGitRepo(arch), "git://github.com/") {
+		fmt.Fprintf(os.Stderr, "warning: insecure protocol git:// detected: %s\n", entry.ArchGitRepo(arch))
+		entry.SetGitRepo(arch, strings.Replace(entry.ArchGitRepo(arch), "git://", "https://", 1))
 	}
 
-	_, err = git("fetch", "--quiet", "--no-tags", entry.GitRepo, fetchString)
+	_, err = git("fetch", "--quiet", "--no-tags", entry.ArchGitRepo(arch), fetchString)
 	if err != nil {
 		return "", err
 	}
 
-	commit, err := getGitCommit(entry.GitCommit)
+	commit, err := getGitCommit(entry.ArchGitCommit(arch))
 	if err != nil {
 		return "", err
 	}
@@ -137,6 +178,6 @@ func (r Repo) fetchGitRepo(entry *manifest.Manifest2822Entry) (string, error) {
 	}
 
 	gitRepoCache[cacheKey] = commit
-	entry.GitCommit = commit
+	entry.SetGitCommit(arch, commit)
 	return commit, nil
 }

+ 63 - 0
bashbrew/go/src/bashbrew/hub.go

@@ -0,0 +1,63 @@
+package main
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+	"os"
+	"strings"
+	"time"
+)
+
+type dockerHubTagMeta struct {
+	// we don't care what's in these -- we just need to be able to count them
+	Images []interface{} `json:"images"`
+
+	LastUpdated string `json:"last_updated"`
+}
+
+func (meta dockerHubTagMeta) lastUpdatedTime() time.Time {
+	t, err := time.Parse(time.RFC3339Nano, meta.LastUpdated)
+	if err != nil {
+		return time.Time{}
+	}
+	return t
+}
+
+func fetchDockerHubTagMeta(repoTag string) dockerHubTagMeta {
+	repoTag = latestizeRepoTag(repoTag)
+	parts := strings.SplitN(repoTag, ":", 2)
+	repo, tag := parts[0], parts[1]
+
+	var meta dockerHubTagMeta
+
+	resp, err := http.Get(fmt.Sprintf("https://hub.docker.com/v2/repositories/%s/tags/%s/", repo, tag))
+	if err != nil {
+		return meta
+	}
+	defer resp.Body.Close()
+
+	err = json.NewDecoder(resp.Body).Decode(&meta)
+	if err != nil {
+		return meta
+	}
+
+	return meta
+}
+
+func dockerCreated(image string) time.Time {
+	created, err := dockerInspect("{{.Created}}", image)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "warning: error while fetching creation time of %q: %v\n", image, err)
+		return time.Now()
+	}
+	created = strings.TrimSpace(created)
+
+	t, err := time.Parse(time.RFC3339Nano, created)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "warning: error while parsing creation time of %q (%q): %v\n", image, created, err)
+		return time.Now()
+	}
+
+	return t
+}

+ 81 - 13
bashbrew/go/src/bashbrew/main.go

@@ -4,8 +4,11 @@ import (
 	"fmt"
 	"os"
 	"path/filepath"
+	"strings"
 
 	"github.com/codegangsta/cli"
+
+	"github.com/docker-library/go-dockerlibrary/manifest"
 )
 
 // TODO somewhere, ensure that the Docker engine we're talking to is API version 1.22+ (Docker 1.10+)
@@ -18,18 +21,26 @@ var (
 	defaultLibrary string
 	defaultCache   string
 
+	arch                 string
 	constraints          []string
 	exclusiveConstraints bool
 
+	archNamespaces map[string]string
+
 	debugFlag  = false
 	noSortFlag = false
 
 	// separated so that FlagsConfig.ApplyTo can access them
 	flagEnvVars = map[string]string{
 		"debug":   "BASHBREW_DEBUG",
+		"arch":    "BASHBREW_ARCH",
 		"config":  "BASHBREW_CONFIG",
 		"library": "BASHBREW_LIBRARY",
 		"cache":   "BASHBREW_CACHE",
+		"pull":    "BASHBREW_PULL",
+
+		"constraint":     "BASHBREW_CONSTRAINTS",
+		"arch-namespace": "BASHBREW_ARCH_NAMESPACES",
 	}
 )
 
@@ -72,15 +83,28 @@ func main() {
 			Usage: "do not apply any sorting, even via --build-order",
 		},
 
+		cli.StringFlag{
+			Name:   "arch",
+			Value:  manifest.DefaultArchitecture,
+			EnvVar: flagEnvVars["arch"],
+			Usage:  "the current platform architecture",
+		},
 		cli.StringSliceFlag{
-			Name:  "constraint",
-			Usage: "build constraints (see Constraints in Manifest2822Entry)",
+			Name:   "constraint",
+			EnvVar: flagEnvVars["constraint"],
+			Usage:  "build constraints (see Constraints in Manifest2822Entry)",
 		},
 		cli.BoolFlag{
 			Name:  "exclusive-constraints",
 			Usage: "skip entries which do not have Constraints",
 		},
 
+		cli.StringSliceFlag{
+			Name:   "arch-namespace",
+			EnvVar: flagEnvVars["arch-namespace"],
+			Usage:  `architecture to push namespace mappings for creating indexes/manifest lists ("arch=namespace" ala "s390x=tianons390x")`,
+		},
+
 		cli.StringFlag{
 			Name:   "config",
 			Value:  initDefaultConfigPath(),
@@ -127,9 +151,17 @@ func main() {
 			debugFlag = c.GlobalBool("debug")
 			noSortFlag = c.GlobalBool("no-sort")
 
+			arch = c.GlobalString("arch")
 			constraints = c.GlobalStringSlice("constraint")
 			exclusiveConstraints = c.GlobalBool("exclusive-constraints")
 
+			archNamespaces = map[string]string{}
+			for _, archMapping := range c.GlobalStringSlice("arch-namespace") {
+				splitArchMapping := strings.SplitN(archMapping, "=", 2)
+				splitArch, splitNamespace := strings.TrimSpace(splitArchMapping[0]), strings.TrimSpace(splitArchMapping[1])
+				archNamespaces[splitArch] = splitNamespace
+			}
+
 			defaultLibrary, err = filepath.Abs(c.GlobalString("library"))
 			if err != nil {
 				return err
@@ -157,6 +189,19 @@ func main() {
 			Name:  "namespace",
 			Usage: "a repo namespace to act upon/in",
 		},
+		"apply-constraints": cli.BoolFlag{
+			Name:  "apply-constraints",
+			Usage: "apply Constraints as if repos were building",
+		},
+		"depth": cli.IntFlag{
+			Name:  "depth",
+			Value: 0,
+			Usage: "maximum number of levels to traverse (0 for unlimited)",
+		},
+		"dry-run": cli.BoolFlag{
+			Name:  "dry-run",
+			Usage: "do everything except the final action (for testing whether actions will be performed)",
+		},
 	}
 
 	app.Commands = []cli.Command{
@@ -167,14 +212,11 @@ func main() {
 			Flags: []cli.Flag{
 				commonFlags["all"],
 				commonFlags["uniq"],
+				commonFlags["apply-constraints"],
 				cli.BoolFlag{
 					Name:  "build-order",
 					Usage: "sort by the order repos would need to build (topsort)",
 				},
-				cli.BoolFlag{
-					Name:  "apply-constraints",
-					Usage: "apply Constraints as if repos were building",
-				},
 				cli.BoolFlag{
 					Name:  "repos",
 					Usage: `list only repos, not repo:tag (unless "repo:tag" is explicitly specified)`,
@@ -191,10 +233,12 @@ func main() {
 				commonFlags["uniq"],
 				commonFlags["namespace"],
 				cli.StringFlag{
-					Name:  "pull",
-					Value: "missing",
-					Usage: `pull FROM before building (always, missing, never)`,
+					Name:   "pull",
+					Value:  "missing",
+					EnvVar: flagEnvVars["pull"],
+					Usage:  `pull FROM before building (always, missing, never)`,
 				},
+				commonFlags["dry-run"],
 			},
 			Before: subcommandBeforeFactory("build"),
 			Action: cmdBuild,
@@ -206,6 +250,7 @@ func main() {
 				commonFlags["all"],
 				commonFlags["uniq"],
 				commonFlags["namespace"],
+				commonFlags["dry-run"],
 			},
 			Before: subcommandBeforeFactory("tag"),
 			Action: cmdTag,
@@ -217,10 +262,26 @@ func main() {
 				commonFlags["all"],
 				commonFlags["uniq"],
 				commonFlags["namespace"],
+				commonFlags["dry-run"],
 			},
 			Before: subcommandBeforeFactory("push"),
 			Action: cmdPush,
 		},
+		{
+			Name:  "put-shared",
+			Usage: `update shared tags in the registry (and multi-architecture tags)`,
+			Flags: []cli.Flag{
+				commonFlags["all"],
+				commonFlags["namespace"],
+				commonFlags["dry-run"],
+				cli.BoolFlag{
+					Name:  "single-arch",
+					Usage: `only act on the current architecture (for pushing "amd64/hello-world:latest", for example)`,
+				},
+			},
+			Before: subcommandBeforeFactory("put-shared"),
+			Action: cmdPutShared,
+		},
 
 		{
 			Name: "children",
@@ -229,8 +290,11 @@ func main() {
 				"descendants",
 				"progeny",
 			},
-			Usage:  `print the repos built FROM a given repo or repo:tag`,
-			Flags:  []cli.Flag{},
+			Usage: `print the repos built FROM a given repo or repo:tag`,
+			Flags: []cli.Flag{
+				commonFlags["apply-constraints"],
+				commonFlags["depth"],
+			},
 			Before: subcommandBeforeFactory("children"),
 			Action: cmdOffspring,
 
@@ -242,8 +306,11 @@ func main() {
 				"ancestors",
 				"progenitors",
 			},
-			Usage:  `print the repos this repo or repo:tag is FROM`,
-			Flags:  []cli.Flag{},
+			Usage: `print the repos this repo or repo:tag is FROM`,
+			Flags: []cli.Flag{
+				commonFlags["apply-constraints"],
+				commonFlags["depth"],
+			},
 			Before: subcommandBeforeFactory("parents"),
 			Action: cmdParents,
 
@@ -277,6 +344,7 @@ func main() {
 			Flags: []cli.Flag{
 				commonFlags["all"],
 				commonFlags["uniq"],
+				commonFlags["apply-constraints"],
 			},
 			Before: subcommandBeforeFactory("from"),
 			Action: cmdFrom,

+ 36 - 0
bashbrew/go/src/bashbrew/manifest-tool.go

@@ -0,0 +1,36 @@
+package main
+
+import (
+	"fmt"
+	"io/ioutil"
+	"os"
+	"os/exec"
+)
+
+func manifestToolPushFromSpec(yamlSpec string) error {
+	yamlFile, err := ioutil.TempFile("", "bashbrew-manifest-tool-yaml-")
+	if err != nil {
+		return err
+	}
+	defer os.Remove(yamlFile.Name())
+
+	if _, err := yamlFile.Write([]byte(yamlSpec)); err != nil {
+		return err
+	}
+	if err := yamlFile.Close(); err != nil {
+		return err
+	}
+
+	args := []string{"push", "from-spec", "--ignore-missing", yamlFile.Name()}
+	if debugFlag {
+		args = append([]string{"--debug"}, args...)
+		fmt.Printf("$ manifest-tool %q\n", args)
+	}
+	cmd := exec.Command("manifest-tool", args...)
+	cmd.Stderr = os.Stderr
+	if debugFlag {
+		cmd.Stdout = os.Stdout
+	}
+
+	return cmd.Run()
+}

+ 20 - 2
bashbrew/go/src/bashbrew/repo.go

@@ -74,12 +74,26 @@ func (r Repo) EntryRepo(entry *manifest.Manifest2822Entry) *Repo {
 	}
 }
 
+var haveOutputSkippedMessage = map[string]bool{}
+
 func (r Repo) SkipConstraints(entry manifest.Manifest2822Entry) bool {
 	repoTag := r.RepoName + ":" + entry.Tags[0]
 
+	// TODO decide if "arch" and "constraints" should be handled separately (but probably not)
+	if !entry.HasArchitecture(arch) {
+		if !haveOutputSkippedMessage[repoTag] {
+			fmt.Fprintf(os.Stderr, "skipping %q (due to architecture %q; only %q supported)\n", repoTag, arch, entry.ArchitecturesString())
+			haveOutputSkippedMessage[repoTag] = true
+		}
+		return true
+	}
+
 	if len(entry.Constraints) == 0 {
 		if exclusiveConstraints {
-			fmt.Fprintf(os.Stderr, "skipping %q (due to exclusive constraints)\n", repoTag)
+			if !haveOutputSkippedMessage[repoTag] {
+				fmt.Fprintf(os.Stderr, "skipping %q (due to exclusive constraints)\n", repoTag)
+				haveOutputSkippedMessage[repoTag] = true
+			}
 		}
 		return exclusiveConstraints
 	}
@@ -111,7 +125,10 @@ NextConstraint:
 	}
 
 	if len(unsatisfactory) > 0 {
-		fmt.Fprintf(os.Stderr, "skipping %q (due to unsatisfactory constraints %q)\n", repoTag, unsatisfactory)
+		if !haveOutputSkippedMessage[repoTag] {
+			fmt.Fprintf(os.Stderr, "skipping %q (due to unsatisfactory constraints %q)\n", repoTag, unsatisfactory)
+			haveOutputSkippedMessage[repoTag] = true
+		}
 		return true
 	}
 
@@ -122,6 +139,7 @@ func (r Repo) Entries() []manifest.Manifest2822Entry {
 	if r.TagName == "" {
 		return r.Manifest.Entries
 	} else {
+		// TODO what if r.TagName isn't a single entry, but is a SharedTag ?
 		return []manifest.Manifest2822Entry{*r.Manifest.GetTag(r.TagName)}
 	}
 }

+ 12 - 5
bashbrew/go/src/bashbrew/sort.go

@@ -5,7 +5,7 @@ import (
 	"pault.ag/go/topsort"
 )
 
-func sortRepos(repos []string) ([]string, error) {
+func sortRepos(repos []string, applyConstraints bool) ([]string, error) {
 	rs := []*Repo{}
 	rsMap := map[*Repo]string{}
 	for _, repo := range repos {
@@ -26,7 +26,7 @@ func sortRepos(repos []string) ([]string, error) {
 		return repos, nil
 	}
 
-	rs, err := sortRepoObjects(rs)
+	rs, err := sortRepoObjects(rs, applyConstraints)
 	if err != nil {
 		return nil, err
 	}
@@ -38,7 +38,7 @@ func sortRepos(repos []string) ([]string, error) {
 	return ret, nil
 }
 
-func (r Repo) SortedEntries() ([]manifest.Manifest2822Entry, error) {
+func (r Repo) SortedEntries(applyConstraints bool) ([]manifest.Manifest2822Entry, error) {
 	entries := r.Entries()
 
 	// short circuit if we don't have to go further
@@ -52,7 +52,7 @@ func (r Repo) SortedEntries() ([]manifest.Manifest2822Entry, error) {
 		rs = append(rs, r.EntryRepo(&entries[i]))
 	}
 
-	rs, err := sortRepoObjects(rs)
+	rs, err := sortRepoObjects(rs, applyConstraints)
 	if err != nil {
 		return nil, err
 	}
@@ -64,7 +64,7 @@ func (r Repo) SortedEntries() ([]manifest.Manifest2822Entry, error) {
 	return ret, nil
 }
 
-func sortRepoObjects(rs []*Repo) ([]*Repo, error) {
+func sortRepoObjects(rs []*Repo, applyConstraints bool) ([]*Repo, error) {
 	// short circuit if we don't have to go further
 	if noSortFlag || len(rs) <= 1 {
 		return rs, nil
@@ -94,6 +94,13 @@ func sortRepoObjects(rs []*Repo) ([]*Repo, error) {
 
 	for _, r := range rs {
 		for _, entry := range r.Entries() {
+			if applyConstraints && r.SkipConstraints(entry) {
+				continue
+			}
+			if !entry.HasArchitecture(arch) {
+				continue
+			}
+
 			from, err := r.DockerFrom(&entry)
 			if err != nil {
 				return nil, err

+ 3 - 3
bashbrew/go/vendor/manifest

@@ -10,7 +10,7 @@
 		{
 			"importpath": "github.com/docker-library/go-dockerlibrary",
 			"repository": "https://github.com/docker-library/go-dockerlibrary",
-			"revision": "6c6566f129042695444eb647d5cee653ca943b0d",
+			"revision": "994859128ef56db39a0e164a348a249733b9ec91",
 			"branch": "master"
 		},
 		{
@@ -28,7 +28,7 @@
 		{
 			"importpath": "pault.ag/go/debian",
 			"repository": "https://github.com/paultag/go-debian",
-			"revision": "e7a23c7df0f545cdb75afbcc6d296bb93ce2786f",
+			"revision": "b655795f4ac31a20d5455c331fe5c1cf3c779bf3",
 			"branch": "master"
 		},
 		{
@@ -38,4 +38,4 @@
 			"branch": "master"
 		}
 	]
-}
+}

+ 5 - 0
bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/README.md

@@ -0,0 +1,5 @@
+# `import "github.com/docker-library/go-dockerlibrary/manifest"`
+
+[![Travis Build Status](https://travis-ci.org/docker-library/go-dockerlibrary.svg?branch=master)](https://travis-ci.org/docker-library/go-dockerlibrary) [![GoDoc](https://godoc.org/github.com/docker-library/go-dockerlibrary?status.svg)](https://godoc.org/github.com/docker-library/go-dockerlibrary) [![codecov](https://codecov.io/gh/docker-library/go-dockerlibrary/branch/master/graph/badge.svg)](https://codecov.io/gh/docker-library/go-dockerlibrary)
+
+This package contains the core parsing elements of [the `bashbrew` tool used by the Docker Official Images](https://github.com/docker-library/official-images/tree/master/bashbrew).

+ 25 - 0
bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/architecture/oci-platform.go

@@ -0,0 +1,25 @@
+package architecture
+
+// https://github.com/opencontainers/image-spec/blob/v1.0.0-rc6/image-index.md#image-index-property-descriptions
+// see "platform" (under "manifests")
+type OCIPlatform struct {
+	OS           string `json:"os"`
+	Architecture string `json:"architecture"`
+	Variant      string `json:"variant,omitempty"`
+
+	//OSVersion  string   `json:"os.version,omitempty"`
+	//OSFeatures []string `json:"os.features,omitempty"`
+}
+
+var SupportedArches = map[string]OCIPlatform{
+	"amd64":   {OS: "linux", Architecture: "amd64"},
+	"arm32v5": {OS: "linux", Architecture: "arm", Variant: "v5"},
+	"arm32v6": {OS: "linux", Architecture: "arm", Variant: "v6"},
+	"arm32v7": {OS: "linux", Architecture: "arm", Variant: "v7"},
+	"arm64v8": {OS: "linux", Architecture: "arm64", Variant: "v8"},
+	"i386":    {OS: "linux", Architecture: "386"},
+	"ppc64le": {OS: "linux", Architecture: "ppc64le"},
+	"s390x":   {OS: "linux", Architecture: "s390x"},
+
+	"windows-amd64": {OS: "windows", Architecture: "amd64"},
+}

+ 0 - 67
bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/manifest/example.go

@@ -1,67 +0,0 @@
-// +build ignore
-
-package main
-
-import (
-	"bufio"
-	"fmt"
-	"strings"
-
-	"github.com/docker-library/go-dockerlibrary/manifest"
-)
-
-func main() {
-	// TODO comment parsing
-	man, err := manifest.Parse(bufio.NewReader(strings.NewReader(`# RFC 2822
-
-	# I LOVE CAKE
-
-Maintainers: InfoSiftr <[email protected]> (@infosiftr),
-             Johan Euphrosine <[email protected]> (@proppy)
-GitRepo: https://github.com/docker-library/golang.git
-GitFetch: refs/heads/master
-
-
- # hi
-
-
- 	 # blasphemer
-
-
-# Go 1.6
-Tags: 1.6.1, 1.6, 1, latest
-GitCommit: 0ce80411b9f41e9c3a21fc0a1bffba6ae761825a
-Directory: 1.6
-
-
-# Go 1.5
-Tags: 1.5.3
-GitCommit: d7e2a8d90a9b8f5dfd5bcd428e0c33b68c40cc19
-Directory: 1.5
-
-
-Tags: 1.5
-GitCommit: d7e2a8d90a9b8f5dfd5bcd428e0c33b68c40cc19
-Directory: 1.5
-
-
-`)))
-	if err != nil {
-		panic(err)
-	}
-	fmt.Printf("-------------\n2822:\n%s\n", man)
-
-	man, err = manifest.Parse(bufio.NewReader(strings.NewReader(`
-# first set
-a: b@c d
-e: b@c d
-
- # second set
-f: g@h
-i: g@h j
-`)))
-	if err != nil {
-		panic(err)
-	}
-	fmt.Printf("-------------\nline-based:\n%v\n", man)
-}

+ 192 - 0
bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/manifest/example_test.go

@@ -0,0 +1,192 @@
+package manifest_test
+
+import (
+	"bufio"
+	"fmt"
+	"strings"
+
+	"github.com/docker-library/go-dockerlibrary/manifest"
+)
+
+func Example() {
+	man, err := manifest.Parse(bufio.NewReader(strings.NewReader(`# RFC 2822
+
+	# I LOVE CAKE
+
+Maintainers: InfoSiftr <[email protected]> (@infosiftr),
+             Johan Euphrosine <[email protected]> (@proppy)
+GitFetch: refs/heads/master
+GitRepo: https://github.com/docker-library/golang.git
+SharedTags: latest
+arm64v8-GitRepo: https://github.com/docker-library/golang.git
+Architectures: amd64, amd64
+
+
+ # hi
+
+
+ 	 # blasphemer
+
+
+# Go 1.6
+Tags: 1.6.1, 1.6, 1
+arm64v8-GitRepo: https://github.com/docker-library/golang.git
+Directory: 1.6
+GitCommit: 0ce80411b9f41e9c3a21fc0a1bffba6ae761825a
+Constraints: some-random-build-server
+
+
+# Go 1.5
+Tags: 1.5.3
+GitCommit: d7e2a8d90a9b8f5dfd5bcd428e0c33b68c40cc19
+SharedTags: 1.5.3-debian, 1.5-debian
+Directory: 1.5
+s390x-GitCommit: b6c460e7cd79b595267870a98013ec3078b490df
+i386-GitFetch: refs/heads/i386
+ppc64le-Directory: 1.5/ppc64le
+
+
+Tags: 1.5
+SharedTags: 1.5-debian
+GitCommit: d7e2a8d90a9b8f5dfd5bcd428e0c33b68c40cc19
+Directory: 1.5
+s390x-GitCommit: b6c460e7cd79b595267870a98013ec3078b490df
+i386-GitFetch: refs/heads/i386
+ppc64le-Directory: 1.5/ppc64le
+
+SharedTags: raspbian
+GitCommit: deadbeefdeadbeefdeadbeefdeadbeefdeadbeef
+Tags: raspbian-s390x
+Architectures: s390x, i386
+
+
+`)))
+	if err != nil {
+		panic(err)
+	}
+	fmt.Printf("-------------\n2822:\n%s\n", man)
+
+	fmt.Printf("\nShared Tag Groups:\n")
+	for _, group := range man.GetSharedTagGroups() {
+		fmt.Printf("\n  - %s\n", strings.Join(group.SharedTags, ", "))
+		for _, entry := range group.Entries {
+			fmt.Printf("    - %s\n", entry.TagsString())
+		}
+	}
+	fmt.Printf("\n")
+
+	man, err = manifest.Parse(bufio.NewReader(strings.NewReader(`
+# maintainer: InfoSiftr <[email protected]> (@infosiftr)
+# maintainer: John Smith <[email protected]> (@example-jsmith)
+
+# first set
+a: b@c d
+e: b@c d
+
+ # second set
+f: g@h
+i: g@h j
+`)))
+	if err != nil {
+		panic(err)
+	}
+	fmt.Printf("-------------\nline-based:\n%v\n", man)
+
+	// Output:
+	// -------------
+	// 2822:
+	// Maintainers: InfoSiftr <[email protected]> (@infosiftr), Johan Euphrosine <[email protected]> (@proppy)
+	// SharedTags: latest
+	// GitRepo: https://github.com/docker-library/golang.git
+	// arm64v8-GitRepo: https://github.com/docker-library/golang.git
+	//
+	// Tags: 1.6.1, 1.6, 1
+	// GitCommit: 0ce80411b9f41e9c3a21fc0a1bffba6ae761825a
+	// Directory: 1.6
+	// Constraints: some-random-build-server
+	//
+	// Tags: 1.5.3, 1.5
+	// SharedTags: 1.5.3-debian, 1.5-debian
+	// GitCommit: d7e2a8d90a9b8f5dfd5bcd428e0c33b68c40cc19
+	// Directory: 1.5
+	// i386-GitFetch: refs/heads/i386
+	// ppc64le-Directory: 1.5/ppc64le
+	// s390x-GitCommit: b6c460e7cd79b595267870a98013ec3078b490df
+	//
+	// Tags: raspbian-s390x
+	// SharedTags: raspbian
+	// Architectures: i386, s390x
+	// GitCommit: deadbeefdeadbeefdeadbeefdeadbeefdeadbeef
+	//
+	// Shared Tag Groups:
+	//
+	//   - latest
+	//     - 1.6.1, 1.6, 1
+	//
+	//   - 1.5.3-debian, 1.5-debian
+	//     - 1.5.3, 1.5
+	//
+	//   - raspbian
+	//     - raspbian-s390x
+	//
+	// -------------
+	// line-based:
+	// Maintainers: InfoSiftr <[email protected]> (@infosiftr), John Smith <[email protected]> (@example-jsmith)
+	// GitFetch: refs/heads/*
+	//
+	// Tags: a, e
+	// GitRepo: b
+	// GitCommit: c
+	// Directory: d
+	//
+	// Tags: f
+	// GitRepo: g
+	// GitFetch: refs/tags/h
+	// GitCommit: FETCH_HEAD
+	//
+	// Tags: i
+	// GitRepo: g
+	// GitFetch: refs/tags/h
+	// GitCommit: FETCH_HEAD
+	// Directory: j
+}
+
+func ExampleFetch_local() {
+	repoName, tagName, man, err := manifest.Fetch("testdata", "bash:4.4")
+	if err != nil {
+		panic(err)
+	}
+
+	fmt.Printf("%s:%s\n\n", repoName, tagName)
+
+	fmt.Println(man.GetTag(tagName).ClearDefaults(manifest.DefaultManifestEntry).String())
+
+	// Output:
+	// bash:4.4
+	//
+	// Maintainers: Tianon Gravi <[email protected]> (@tianon)
+	// Tags: 4.4.12, 4.4, 4, latest
+	// GitRepo: https://github.com/tianon/docker-bash.git
+	// GitCommit: 1cbb5cf49b4c53bd5a986abf7a1afeb9a80eac1e
+	// Directory: 4.4
+}
+
+func ExampleFetch_remote() {
+	repoName, tagName, man, err := manifest.Fetch("/home/jsmith/docker/official-images/library", "https://github.com/docker-library/official-images/raw/1a3c4cd6d5cd53bd538a6f56a69f94c5b35325a7/library/bash:4.4")
+	if err != nil {
+		panic(err)
+	}
+
+	fmt.Printf("%s:%s\n\n", repoName, tagName)
+
+	fmt.Println(man.GetTag(tagName).ClearDefaults(manifest.DefaultManifestEntry).String())
+
+	// Output:
+	// bash:4.4
+	//
+	// Maintainers: Tianon Gravi <[email protected]> (@tianon)
+	// Tags: 4.4.12, 4.4, 4, latest
+	// GitRepo: https://github.com/tianon/docker-bash.git
+	// GitCommit: 1cbb5cf49b4c53bd5a986abf7a1afeb9a80eac1e
+	// Directory: 4.4
+}

+ 20 - 0
bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/manifest/parse_test.go

@@ -0,0 +1,20 @@
+package manifest_test
+
+import (
+	"strings"
+	"testing"
+
+	"github.com/docker-library/go-dockerlibrary/manifest"
+)
+
+func TestParseError(t *testing.T) {
+	invalidManifest := `this is just completely bogus and invalid no matter how you slice it`
+
+	man, err := manifest.Parse(strings.NewReader(invalidManifest))
+	if err == nil {
+		t.Errorf("Expected error, got valid manifest instead:\n%s", man)
+	}
+	if !strings.HasPrefix(err.Error(), "cannot parse manifest in either format:") {
+		t.Errorf("Unexpected error: %v", err)
+	}
+}

+ 317 - 19
bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/manifest/rfc2822.go

@@ -5,8 +5,10 @@ import (
 	"fmt"
 	"io"
 	"regexp"
+	"sort"
 	"strings"
 
+	"github.com/docker-library/go-dockerlibrary/architecture"
 	"github.com/docker-library/go-dockerlibrary/pkg/stripper"
 
 	"pault.ag/go/debian/control"
@@ -26,27 +28,65 @@ type Manifest2822Entry struct {
 	control.Paragraph
 
 	Maintainers []string `delim:"," strip:"\n\r\t "`
-	Tags        []string `delim:"," strip:"\n\r\t "`
-	GitRepo     string
-	GitFetch    string
-	GitCommit   string
-	Directory   string
+
+	Tags       []string `delim:"," strip:"\n\r\t "`
+	SharedTags []string `delim:"," strip:"\n\r\t "`
+
+	Architectures []string `delim:"," strip:"\n\r\t "`
+
+	GitRepo   string
+	GitFetch  string
+	GitCommit string
+	Directory string
+
+	// architecture-specific versions of the above fields
+	ArchValues map[string]string
+	// "ARCH-FIELD: VALUE"
+	// ala, "s390x-GitCommit: deadbeef"
+	// (sourced from Paragraph.Values via .SeedArchValues())
+
 	Constraints []string `delim:"," strip:"\n\r\t "`
 }
 
-var DefaultManifestEntry = Manifest2822Entry{
-	GitFetch:  "refs/heads/master",
-	Directory: ".",
+var (
+	DefaultArchitecture = "amd64"
+
+	DefaultManifestEntry = Manifest2822Entry{
+		Architectures: []string{DefaultArchitecture},
+
+		GitFetch:  "refs/heads/master",
+		Directory: ".",
+	}
+)
+
+func deepCopyStringsMap(a map[string]string) map[string]string {
+	b := map[string]string{}
+	for k, v := range a {
+		b[k] = v
+	}
+	return b
 }
 
 func (entry Manifest2822Entry) Clone() Manifest2822Entry {
 	// SLICES! grr
 	entry.Maintainers = append([]string{}, entry.Maintainers...)
 	entry.Tags = append([]string{}, entry.Tags...)
+	entry.SharedTags = append([]string{}, entry.SharedTags...)
+	entry.Architectures = append([]string{}, entry.Architectures...)
 	entry.Constraints = append([]string{}, entry.Constraints...)
+	// and MAPS, oh my
+	entry.ArchValues = deepCopyStringsMap(entry.ArchValues)
 	return entry
 }
 
+func (entry *Manifest2822Entry) SeedArchValues() {
+	for field, val := range entry.Paragraph.Values {
+		if strings.HasSuffix(field, "-GitRepo") || strings.HasSuffix(field, "-GitFetch") || strings.HasSuffix(field, "-GitCommit") || strings.HasSuffix(field, "-Directory") {
+			entry.ArchValues[field] = val
+		}
+	}
+}
+
 const StringSeparator2822 = ", "
 
 func (entry Manifest2822Entry) MaintainersString() string {
@@ -57,23 +97,57 @@ func (entry Manifest2822Entry) TagsString() string {
 	return strings.Join(entry.Tags, StringSeparator2822)
 }
 
+func (entry Manifest2822Entry) SharedTagsString() string {
+	return strings.Join(entry.SharedTags, StringSeparator2822)
+}
+
+func (entry Manifest2822Entry) ArchitecturesString() string {
+	return strings.Join(entry.Architectures, StringSeparator2822)
+}
+
 func (entry Manifest2822Entry) ConstraintsString() string {
 	return strings.Join(entry.Constraints, StringSeparator2822)
 }
 
 // if this method returns "true", then a.Tags and b.Tags can safely be combined (for the purposes of building)
 func (a Manifest2822Entry) SameBuildArtifacts(b Manifest2822Entry) bool {
-	return a.GitRepo == b.GitRepo && a.GitFetch == b.GitFetch && a.GitCommit == b.GitCommit && a.Directory == b.Directory && a.ConstraintsString() == b.ConstraintsString()
+	// check xxxarch-GitRepo, etc. fields for sameness first
+	for _, key := range append(a.archFields(), b.archFields()...) {
+		if a.ArchValues[key] != b.ArchValues[key] {
+			return false
+		}
+	}
+
+	return a.ArchitecturesString() == b.ArchitecturesString() && a.GitRepo == b.GitRepo && a.GitFetch == b.GitFetch && a.GitCommit == b.GitCommit && a.Directory == b.Directory && a.ConstraintsString() == b.ConstraintsString()
+}
+
+// returns a list of architecture-specific fields in an Entry
+func (entry Manifest2822Entry) archFields() []string {
+	ret := []string{}
+	for key, val := range entry.ArchValues {
+		if val != "" {
+			ret = append(ret, key)
+		}
+	}
+	sort.Strings(ret)
+	return ret
 }
 
 // returns a new Entry with any of the values that are equal to the values in "defaults" cleared
 func (entry Manifest2822Entry) ClearDefaults(defaults Manifest2822Entry) Manifest2822Entry {
+	entry = entry.Clone() // make absolutely certain we have a deep clone
 	if entry.MaintainersString() == defaults.MaintainersString() {
 		entry.Maintainers = nil
 	}
 	if entry.TagsString() == defaults.TagsString() {
 		entry.Tags = nil
 	}
+	if entry.SharedTagsString() == defaults.SharedTagsString() {
+		entry.SharedTags = nil
+	}
+	if entry.ArchitecturesString() == defaults.ArchitecturesString() {
+		entry.Architectures = nil
+	}
 	if entry.GitRepo == defaults.GitRepo {
 		entry.GitRepo = ""
 	}
@@ -86,6 +160,11 @@ func (entry Manifest2822Entry) ClearDefaults(defaults Manifest2822Entry) Manifes
 	if entry.Directory == defaults.Directory {
 		entry.Directory = ""
 	}
+	for _, key := range defaults.archFields() {
+		if defaults.ArchValues[key] == entry.ArchValues[key] {
+			delete(entry.ArchValues, key)
+		}
+	}
 	if entry.ConstraintsString() == defaults.ConstraintsString() {
 		entry.Constraints = nil
 	}
@@ -100,6 +179,12 @@ func (entry Manifest2822Entry) String() string {
 	if str := entry.TagsString(); str != "" {
 		ret = append(ret, "Tags: "+str)
 	}
+	if str := entry.SharedTagsString(); str != "" {
+		ret = append(ret, "SharedTags: "+str)
+	}
+	if str := entry.ArchitecturesString(); str != "" {
+		ret = append(ret, "Architectures: "+str)
+	}
 	if str := entry.GitRepo; str != "" {
 		ret = append(ret, "GitRepo: "+str)
 	}
@@ -112,6 +197,9 @@ func (entry Manifest2822Entry) String() string {
 	if str := entry.Directory; str != "" {
 		ret = append(ret, "Directory: "+str)
 	}
+	for _, key := range entry.archFields() {
+		ret = append(ret, key+": "+entry.ArchValues[key])
+	}
 	if str := entry.ConstraintsString(); str != "" {
 		ret = append(ret, "Constraints: "+str)
 	}
@@ -133,6 +221,48 @@ func (manifest Manifest2822) String() string {
 	return strings.Join(ret, "\n\n")
 }
 
+func (entry *Manifest2822Entry) SetGitRepo(arch string, repo string) {
+	if entry.ArchValues == nil {
+		entry.ArchValues = map[string]string{}
+	}
+	entry.ArchValues[arch+"-GitRepo"] = repo
+}
+
+func (entry Manifest2822Entry) ArchGitRepo(arch string) string {
+	if val, ok := entry.ArchValues[arch+"-GitRepo"]; ok && val != "" {
+		return val
+	}
+	return entry.GitRepo
+}
+
+func (entry Manifest2822Entry) ArchGitFetch(arch string) string {
+	if val, ok := entry.ArchValues[arch+"-GitFetch"]; ok && val != "" {
+		return val
+	}
+	return entry.GitFetch
+}
+
+func (entry *Manifest2822Entry) SetGitCommit(arch string, commit string) {
+	if entry.ArchValues == nil {
+		entry.ArchValues = map[string]string{}
+	}
+	entry.ArchValues[arch+"-GitCommit"] = commit
+}
+
+func (entry Manifest2822Entry) ArchGitCommit(arch string) string {
+	if val, ok := entry.ArchValues[arch+"-GitCommit"]; ok && val != "" {
+		return val
+	}
+	return entry.GitCommit
+}
+
+func (entry Manifest2822Entry) ArchDirectory(arch string) string {
+	if val, ok := entry.ArchValues[arch+"-Directory"]; ok && val != "" {
+		return val
+	}
+	return entry.Directory
+}
+
 func (entry Manifest2822Entry) HasTag(tag string) bool {
 	for _, existingTag := range entry.Tags {
 		if tag == existingTag {
@@ -142,6 +272,26 @@ func (entry Manifest2822Entry) HasTag(tag string) bool {
 	return false
 }
 
+// HasSharedTag returns true if the given tag exists in entry.SharedTags.
+func (entry Manifest2822Entry) HasSharedTag(tag string) bool {
+	for _, existingTag := range entry.SharedTags {
+		if tag == existingTag {
+			return true
+		}
+	}
+	return false
+}
+
+// HasArchitecture returns true if the given architecture exists in entry.Architectures
+func (entry Manifest2822Entry) HasArchitecture(arch string) bool {
+	for _, existingArch := range entry.Architectures {
+		if arch == existingArch {
+			return true
+		}
+	}
+	return false
+}
+
 func (manifest Manifest2822) GetTag(tag string) *Manifest2822Entry {
 	for _, entry := range manifest.Entries {
 		if entry.HasTag(tag) {
@@ -151,16 +301,107 @@ func (manifest Manifest2822) GetTag(tag string) *Manifest2822Entry {
 	return nil
 }
 
+// GetSharedTag returns a list of entries with the given tag in entry.SharedTags (or the empty list if there are no entries with the given tag).
+func (manifest Manifest2822) GetSharedTag(tag string) []Manifest2822Entry {
+	ret := []Manifest2822Entry{}
+	for _, entry := range manifest.Entries {
+		if entry.HasSharedTag(tag) {
+			ret = append(ret, entry)
+		}
+	}
+	return ret
+}
+
+// GetAllSharedTags returns a list of the sum of all SharedTags in all entries of this image manifest (in the order they appear in the file).
+func (manifest Manifest2822) GetAllSharedTags() []string {
+	fakeEntry := Manifest2822Entry{}
+	for _, entry := range manifest.Entries {
+		fakeEntry.SharedTags = append(fakeEntry.SharedTags, entry.SharedTags...)
+	}
+	fakeEntry.DeduplicateSharedTags()
+	return fakeEntry.SharedTags
+}
+
+type SharedTagGroup struct {
+	SharedTags []string
+	Entries    []*Manifest2822Entry
+}
+
+// GetSharedTagGroups returns a map of shared tag groups to the list of entries they share (as described in https://github.com/docker-library/go-dockerlibrary/pull/2#issuecomment-277853597).
+func (manifest Manifest2822) GetSharedTagGroups() []SharedTagGroup {
+	inter := map[string][]string{}
+	interOrder := []string{} // order matters, and maps randomize order
+	interKeySep := ","
+	for _, sharedTag := range manifest.GetAllSharedTags() {
+		interKeyParts := []string{}
+		for _, entry := range manifest.GetSharedTag(sharedTag) {
+			interKeyParts = append(interKeyParts, entry.Tags[0])
+		}
+		interKey := strings.Join(interKeyParts, interKeySep)
+		if _, ok := inter[interKey]; !ok {
+			interOrder = append(interOrder, interKey)
+		}
+		inter[interKey] = append(inter[interKey], sharedTag)
+	}
+	ret := []SharedTagGroup{}
+	for _, tags := range interOrder {
+		group := SharedTagGroup{
+			SharedTags: inter[tags],
+			Entries:    []*Manifest2822Entry{},
+		}
+		for _, tag := range strings.Split(tags, interKeySep) {
+			group.Entries = append(group.Entries, manifest.GetTag(tag))
+		}
+		ret = append(ret, group)
+	}
+	return ret
+}
+
 func (manifest *Manifest2822) AddEntry(entry Manifest2822Entry) error {
+	if len(entry.Tags) < 1 {
+		return fmt.Errorf("missing Tags")
+	}
+	if entry.GitRepo == "" || entry.GitFetch == "" || entry.GitCommit == "" {
+		return fmt.Errorf("Tags %q missing one of GitRepo, GitFetch, or GitCommit", entry.TagsString())
+	}
+	if invalidMaintainers := entry.InvalidMaintainers(); len(invalidMaintainers) > 0 {
+		return fmt.Errorf("Tags %q has invalid Maintainers: %q (expected format %q)", entry.TagsString(), strings.Join(invalidMaintainers, ", "), MaintainersFormat)
+	}
+
+	entry.DeduplicateSharedTags()
+
+	if invalidArchitectures := entry.InvalidArchitectures(); len(invalidArchitectures) > 0 {
+		return fmt.Errorf("Tags %q has invalid Architectures: %q", entry.TagsString(), strings.Join(invalidArchitectures, ", "))
+	}
+
+	seenTag := map[string]bool{}
 	for _, tag := range entry.Tags {
-		if manifest.GetTag(tag) != nil {
-			return fmt.Errorf("Tags %q includes duplicate tag: %s", entry.TagsString(), tag)
+		if otherEntry := manifest.GetTag(tag); otherEntry != nil {
+			return fmt.Errorf("Tags %q includes duplicate tag: %q (duplicated in %q)", entry.TagsString(), tag, otherEntry.TagsString())
 		}
+		if otherEntries := manifest.GetSharedTag(tag); len(otherEntries) > 0 {
+			return fmt.Errorf("Tags %q includes tag conflicting with a shared tag: %q (shared tag in %q)", entry.TagsString(), tag, otherEntries[0].TagsString())
+		}
+		if seenTag[tag] {
+			return fmt.Errorf("Tags %q includes duplicate tag: %q", entry.TagsString(), tag)
+		}
+		seenTag[tag] = true
+	}
+	for _, tag := range entry.SharedTags {
+		if otherEntry := manifest.GetTag(tag); otherEntry != nil {
+			return fmt.Errorf("Tags %q includes conflicting shared tag: %q (duplicated in %q)", entry.TagsString(), tag, otherEntry.TagsString())
+		}
+		if seenTag[tag] {
+			return fmt.Errorf("Tags %q includes duplicate tag: %q (in SharedTags)", entry.TagsString(), tag)
+		}
+		seenTag[tag] = true
 	}
 
 	for i, existingEntry := range manifest.Entries {
 		if existingEntry.SameBuildArtifacts(entry) {
 			manifest.Entries[i].Tags = append(existingEntry.Tags, entry.Tags...)
+			manifest.Entries[i].SharedTags = append(existingEntry.SharedTags, entry.SharedTags...)
+			manifest.Entries[i].DeduplicateSharedTags()
 			return nil
 		}
 	}
@@ -192,20 +433,80 @@ func (entry Manifest2822Entry) InvalidMaintainers() []string {
 	return invalid
 }
 
+func (entry Manifest2822Entry) InvalidArchitectures() []string {
+	invalid := []string{}
+	for _, arch := range entry.Architectures {
+		if _, ok := architecture.SupportedArches[arch]; !ok {
+			invalid = append(invalid, arch)
+		}
+	}
+	return invalid
+}
+
+// DeduplicateSharedTags will remove duplicate values from entry.SharedTags, preserving order.
+func (entry *Manifest2822Entry) DeduplicateSharedTags() {
+	aggregate := []string{}
+	seen := map[string]bool{}
+	for _, tag := range entry.SharedTags {
+		if seen[tag] {
+			continue
+		}
+		seen[tag] = true
+		aggregate = append(aggregate, tag)
+	}
+	entry.SharedTags = aggregate
+}
+
+// DeduplicateArchitectures will remove duplicate values from entry.Architectures and sort the result.
+func (entry *Manifest2822Entry) DeduplicateArchitectures() {
+	aggregate := []string{}
+	seen := map[string]bool{}
+	for _, arch := range entry.Architectures {
+		if seen[arch] {
+			continue
+		}
+		seen[arch] = true
+		aggregate = append(aggregate, arch)
+	}
+	sort.Strings(aggregate)
+	entry.Architectures = aggregate
+}
+
 type decoderWrapper struct {
 	*control.Decoder
 }
 
 func (decoder *decoderWrapper) Decode(entry *Manifest2822Entry) error {
+	// reset Architectures and SharedTags so that they can be either inherited or replaced, not additive
+	sharedTags := entry.SharedTags
+	entry.SharedTags = nil
+	arches := entry.Architectures
+	entry.Architectures = nil
+
 	for {
 		err := decoder.Decoder.Decode(entry)
 		if err != nil {
 			return err
 		}
+
 		// ignore empty paragraphs (blank lines at the start, excess blank lines between paragraphs, excess blank lines at EOF)
-		if len(entry.Paragraph.Order) > 0 {
-			return nil
+		if len(entry.Paragraph.Order) == 0 {
+			continue
 		}
+
+		// if we had no SharedTags or Architectures, restore our "default" (original) values
+		if len(entry.SharedTags) == 0 {
+			entry.SharedTags = sharedTags
+		}
+		if len(entry.Architectures) == 0 {
+			entry.Architectures = arches
+		}
+		entry.DeduplicateArchitectures()
+
+		// pull out any new architecture-specific values from Paragraph.Values
+		entry.SeedArchValues()
+
+		return nil
 	}
 }
 
@@ -234,6 +535,9 @@ func Parse2822(readerIn io.Reader) (*Manifest2822, error) {
 	if len(manifest.Global.Tags) > 0 {
 		return nil, fmt.Errorf("global Tags not permitted")
 	}
+	if invalidArchitectures := manifest.Global.InvalidArchitectures(); len(invalidArchitectures) > 0 {
+		return nil, fmt.Errorf("invalid global Architectures: %q", strings.Join(invalidArchitectures, ", "))
+	}
 
 	for {
 		entry := manifest.Global.Clone()
@@ -246,12 +550,6 @@ func Parse2822(readerIn io.Reader) (*Manifest2822, error) {
 			return nil, err
 		}
 
-		if len(entry.Tags) < 1 {
-			return nil, fmt.Errorf("missing Tags")
-		}
-		if entry.GitRepo == "" || entry.GitFetch == "" || entry.GitCommit == "" {
-			return nil, fmt.Errorf("Tags %q missing one of GitRepo, GitFetch, or GitCommit", entry.TagsString())
-		}
 		if !GitFetchRegex.MatchString(entry.GitFetch) {
 			return nil, fmt.Errorf(`Tags %q has invalid GitFetch (must be "refs/heads/..." or "refs/tags/..."): %q`, entry.TagsString(), entry.GitFetch)
 		}

+ 38 - 0
bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/manifest/testdata/bash

@@ -0,0 +1,38 @@
+# this is a snapshot of https://github.com/docker-library/official-images/raw/1a3c4cd6d5cd53bd538a6f56a69f94c5b35325a7/library/bash
+
+# this file is generated via https://github.com/tianon/docker-bash/blob/cd1de3dfc885b3395cd354ddb988922350b092a7/generate-stackbrew-library.sh
+
+Maintainers: Tianon Gravi <[email protected]> (@tianon)
+GitRepo: https://github.com/tianon/docker-bash.git
+
+Tags: 4.4.12, 4.4, 4, latest
+GitCommit: 1cbb5cf49b4c53bd5a986abf7a1afeb9a80eac1e
+Directory: 4.4
+
+Tags: 4.3.48, 4.3
+GitCommit: 1cbb5cf49b4c53bd5a986abf7a1afeb9a80eac1e
+Directory: 4.3
+
+Tags: 4.2.53, 4.2
+GitCommit: 1cbb5cf49b4c53bd5a986abf7a1afeb9a80eac1e
+Directory: 4.2
+
+Tags: 4.1.17, 4.1
+GitCommit: 1cbb5cf49b4c53bd5a986abf7a1afeb9a80eac1e
+Directory: 4.1
+
+Tags: 4.0.44, 4.0
+GitCommit: 4438745d601d10d300e363f24205a3ca75307803
+Directory: 4.0
+
+Tags: 3.2.57, 3.2, 3
+GitCommit: 1cbb5cf49b4c53bd5a986abf7a1afeb9a80eac1e
+Directory: 3.2
+
+Tags: 3.1.23, 3.1
+GitCommit: 1cbb5cf49b4c53bd5a986abf7a1afeb9a80eac1e
+Directory: 3.1
+
+Tags: 3.0.22, 3.0
+GitCommit: 1cbb5cf49b4c53bd5a986abf7a1afeb9a80eac1e
+Directory: 3.0

+ 26 - 0
bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/pkg/execpipe/execpipe_example_test.go

@@ -0,0 +1,26 @@
+package execpipe_test
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"strings"
+
+	"github.com/docker-library/go-dockerlibrary/pkg/execpipe"
+)
+
+func Example() {
+	pipe, err := execpipe.RunCommand("go", "version")
+	if err != nil {
+		panic(err)
+	}
+	defer pipe.Close()
+
+	var buf bytes.Buffer
+	io.Copy(&buf, pipe)
+
+	fmt.Println(strings.SplitN(buf.String(), " version ", 2)[0])
+
+	// Output:
+	// go
+}

+ 31 - 0
bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/pkg/execpipe/execpipe_test.go

@@ -0,0 +1,31 @@
+package execpipe_test
+
+import (
+	"os"
+	"os/exec"
+	"testing"
+
+	"github.com/docker-library/go-dockerlibrary/pkg/execpipe"
+)
+
+func TestStdoutPipeError(t *testing.T) {
+	cmd := exec.Command("nothing", "really", "matters", "in", "the", "end")
+
+	// set "Stdout" so that "cmd.StdoutPipe" fails
+	// https://golang.org/src/os/exec/exec.go?s=16834:16883#L587
+	cmd.Stdout = os.Stdout
+
+	_, err := execpipe.Run(cmd)
+	if err == nil {
+		t.Errorf("Expected execpipe.Run to fail -- it did not")
+	}
+}
+
+func TestStartError(t *testing.T) {
+	// craft a definitely-invalid command so that "cmd.Start" fails
+	// https://golang.org/src/os/exec/exec.go?s=8739:8766#L303
+	_, err := execpipe.RunCommand("nothing-really-matters-in-the-end--bogus-command")
+	if err == nil {
+		t.Errorf("Expected execpipe.RunCommand to fail -- it did not")
+	}
+}

+ 32 - 0
bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/pkg/stripper/comments_example_test.go

@@ -0,0 +1,32 @@
+package stripper_test
+
+import (
+	"io"
+	"os"
+	"strings"
+
+	"github.com/docker-library/go-dockerlibrary/pkg/stripper"
+)
+
+func ExampleCommentStripper() {
+	r := strings.NewReader(`
+# opening comment
+a: b
+# comment!
+c: d # not a comment
+
+# another cheeky comment
+e: f
+`)
+
+	comStrip := stripper.NewCommentStripper(r)
+
+	// using CopyBuffer to force smaller Read sizes (better testing coverage that way)
+	io.CopyBuffer(os.Stdout, comStrip, make([]byte, 32))
+
+	// Output:
+	// a: b
+	// c: d # not a comment
+	//
+	// e: f
+}

+ 8 - 0
bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/pkg/templatelib/doc.go

@@ -0,0 +1,8 @@
+/*
+Package templatelib implements a group of useful functions for use with the stdlib text/template package.
+
+Usage:
+
+	tmpl, err := template.New("some-template").Funcs(templatelib.FuncMap).Parse("Hi, {{ join " " .Names }}")
+*/
+package templatelib

+ 42 - 3
bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/pkg/templatelib/lib.go

@@ -3,6 +3,7 @@ package templatelib
 import (
 	"encoding/json"
 	"fmt"
+	"os"
 	"reflect"
 	"strings"
 	"text/template"
@@ -67,12 +68,15 @@ func stringsModifierActionFactory(a func(string, string) string) func([]string,
 	}
 }
 
-// TODO write some tests for these
-
 var FuncMap = template.FuncMap{
+	// {{- $isGitHub := hasPrefix "https://github.com/" $url -}}
+	// {{- $isHtml := hasSuffix ".html" $url -}}
 	"hasPrefix": swapStringsFuncBoolArgsOrder(strings.HasPrefix),
 	"hasSuffix": swapStringsFuncBoolArgsOrder(strings.HasSuffix),
 
+	// {{- $hugeIfTrue := .SomeValue | ternary "HUGE" "not so huge" -}}
+	// if .SomeValue is truthy, $hugeIfTrue will be "HUGE"
+	// (otherwise, "not so huge")
 	"ternary": func(truthy interface{}, falsey interface{}, val interface{}) interface{} {
 		if t, ok := template.IsTrue(val); !ok {
 			panic(fmt.Sprintf(`template.IsTrue(%+v) says things are NOT OK`, val))
@@ -83,17 +87,52 @@ var FuncMap = template.FuncMap{
 		}
 	},
 
+	// First Tag: {{- .Tags | first -}}
+	// Last Tag:  {{- .Tags | last -}}
 	"first": thingsActionFactory("first", true, func(args []interface{}, arg interface{}) interface{} { return arg }),
 	"last":  thingsActionFactory("last", false, func(args []interface{}, arg interface{}) interface{} { return arg }),
 
+	// JSON data dump: {{ json . }}
+	// (especially nice for taking data and piping it to "jq")
+	// (ie "some-tool inspect --format '{{ json . }}' some-things | jq .")
 	"json": func(v interface{}) (string, error) {
 		j, err := json.Marshal(v)
 		return string(j), err
 	},
-	"join":         stringsActionFactory("join", true, strings.Join),
+
+	// Everybody: {{- join ", " .Names -}}
+	// Concat: {{- join "/" "https://github.com" "jsmith" "some-repo" -}}
+	"join": stringsActionFactory("join", true, strings.Join),
+
+	// {{- $mungedUrl := $url | replace "git://" "https://" | trimSuffixes ".git" -}}
+	// turns: git://github.com/jsmith/some-repo.git
+	// into: https://github.com/jsmith/some-repo
 	"trimPrefixes": stringsActionFactory("trimPrefixes", false, stringsModifierActionFactory(strings.TrimPrefix)),
 	"trimSuffixes": stringsActionFactory("trimSuffixes", false, stringsModifierActionFactory(strings.TrimSuffix)),
 	"replace": stringsActionFactory("replace", false, func(strs []string, str string) string {
 		return strings.NewReplacer(strs...).Replace(str)
 	}),
+
+	// {{- getenv "PATH" -}}
+	// {{- getenv "HOME" "no HOME set" -}}
+	// {{- getenv "HOME" "is set" "is NOT set (or is empty)" -}}
+	"getenv": thingsActionFactory("getenv", true, func(args []interface{}, arg interface{}) interface{} {
+		var (
+			val                  = os.Getenv(arg.(string))
+			setVal   interface{} = val
+			unsetVal interface{} = ""
+		)
+		if len(args) == 2 {
+			setVal, unsetVal = args[0], args[1]
+		} else if len(args) == 1 {
+			unsetVal = args[0]
+		} else if len(args) != 0 {
+			panic(fmt.Sprintf(`expected between 1 and 3 arguments to "getenv", got %d`, len(args)+1))
+		}
+		if val != "" {
+			return setVal
+		} else {
+			return unsetVal
+		}
+	}),
 }

+ 221 - 0
bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/pkg/templatelib/lib_example_test.go

@@ -0,0 +1,221 @@
+package templatelib_test
+
+import (
+	"os"
+	"text/template"
+
+	"github.com/docker-library/go-dockerlibrary/pkg/templatelib"
+)
+
+func Example_prefixSuffix() {
+	tmpl, err := template.New("github-or-html").Funcs(templatelib.FuncMap).Parse(`
+		{{- . -}}
+
+		{{- if hasPrefix "https://github.com/" . -}}
+			{{- " " -}} GitHub
+		{{- end -}}
+
+		{{- if hasSuffix ".html" . -}}
+			{{- " " -}} HTML
+		{{- end -}}
+
+		{{- "\n" -}}
+	`)
+	if err != nil {
+		panic(err)
+	}
+
+	err = tmpl.Execute(os.Stdout, "https://github.com/example/example")
+	if err != nil {
+		panic(err)
+	}
+
+	err = tmpl.Execute(os.Stdout, "https://example.com/test.html")
+	if err != nil {
+		panic(err)
+	}
+
+	err = tmpl.Execute(os.Stdout, "https://example.com")
+	if err != nil {
+		panic(err)
+	}
+
+	err = tmpl.Execute(os.Stdout, "https://github.com/example/example/raw/master/test.html")
+	if err != nil {
+		panic(err)
+	}
+
+	// Output:
+	// https://github.com/example/example GitHub
+	// https://example.com/test.html HTML
+	// https://example.com
+	// https://github.com/example/example/raw/master/test.html GitHub HTML
+}
+
+func Example_ternary() {
+	tmpl, err := template.New("huge-if-true").Funcs(templatelib.FuncMap).Parse(`
+		{{- range $a := . -}}
+			{{ printf "%#v: %s\n" $a (ternary "HUGE" "not so huge" $a) }}
+		{{- end -}}
+	`)
+
+	err = tmpl.Execute(os.Stdout, []interface{}{
+		true,
+		false,
+		"true",
+		"false",
+		"",
+		nil,
+		1,
+		0,
+		9001,
+		[]bool{},
+		[]bool{false},
+	})
+	if err != nil {
+		panic(err)
+	}
+
+	// Output:
+	// true: HUGE
+	// false: not so huge
+	// "true": HUGE
+	// "false": HUGE
+	// "": not so huge
+	// <nil>: not so huge
+	// 1: HUGE
+	// 0: not so huge
+	// 9001: HUGE
+	// []bool{}: not so huge
+	// []bool{false}: HUGE
+}
+
+func Example_firstLast() {
+	tmpl, err := template.New("first-and-last").Funcs(templatelib.FuncMap).Parse(`First: {{ . | first }}, Last: {{ . | last }}`)
+
+	err = tmpl.Execute(os.Stdout, []interface{}{
+		"a",
+		"b",
+		"c",
+	})
+	if err != nil {
+		panic(err)
+	}
+
+	// Output:
+	// First: a, Last: c
+}
+
+func Example_json() {
+	tmpl, err := template.New("json").Funcs(templatelib.FuncMap).Parse(`
+		{{- json . -}}
+	`)
+
+	err = tmpl.Execute(os.Stdout, map[string]interface{}{
+		"a": []string{"1", "2", "3"},
+		"b": map[string]bool{"1": true, "2": false, "3": true},
+		"c": nil,
+	})
+	if err != nil {
+		panic(err)
+	}
+
+	// Output:
+	// {"a":["1","2","3"],"b":{"1":true,"2":false,"3":true},"c":null}
+}
+
+func Example_join() {
+	tmpl, err := template.New("join").Funcs(templatelib.FuncMap).Parse(`
+		Array: {{ . | join ", " }}{{ "\n" -}}
+		Args: {{ join ", " "a" "b" "c" -}}
+	`)
+
+	err = tmpl.Execute(os.Stdout, []string{
+		"1",
+		"2",
+		"3",
+	})
+	if err != nil {
+		panic(err)
+	}
+
+	// Output:
+	// Array: 1, 2, 3
+	// Args: a, b, c
+}
+
+func Example_trimReplaceGitToHttps() {
+	tmpl, err := template.New("git-to-https").Funcs(templatelib.FuncMap).Parse(`
+		{{- range . -}}
+			{{- . | replace "git://" "https://" | trimSuffixes ".git" }}{{ "\n" -}}
+		{{- end -}}
+	`)
+
+	err = tmpl.Execute(os.Stdout, []string{
+		"git://github.com/jsmith/some-repo.git",
+		"https://github.com/jsmith/some-repo.git",
+		"https://github.com/jsmith/some-repo",
+	})
+	if err != nil {
+		panic(err)
+	}
+
+	// Output:
+	// https://github.com/jsmith/some-repo
+	// https://github.com/jsmith/some-repo
+	// https://github.com/jsmith/some-repo
+}
+
+func Example_trimReplaceGitToGo() {
+	tmpl, err := template.New("git-to-go").Funcs(templatelib.FuncMap).Parse(`
+		{{- range . -}}
+			{{- . | trimPrefixes "git://" "http://" "https://" "ssh://" | trimSuffixes ".git" }}{{ "\n" -}}
+		{{- end -}}
+	`)
+
+	err = tmpl.Execute(os.Stdout, []string{
+		"git://github.com/jsmith/some-repo.git",
+		"https://github.com/jsmith/some-repo.git",
+		"https://github.com/jsmith/some-repo",
+		"ssh://github.com/jsmith/some-repo.git",
+		"github.com/jsmith/some-repo",
+	})
+	if err != nil {
+		panic(err)
+	}
+
+	// Output:
+	// github.com/jsmith/some-repo
+	// github.com/jsmith/some-repo
+	// github.com/jsmith/some-repo
+	// github.com/jsmith/some-repo
+	// github.com/jsmith/some-repo
+}
+
+func Example_getenv() {
+	tmpl, err := template.New("getenv").Funcs(templatelib.FuncMap).Parse(`
+		The FOO environment variable {{ getenv "FOO" "is set" "is not set" }}. {{- "\n" -}}
+		BAR: {{ getenv "BAR" "not set" }} {{- "\n" -}}
+		BAZ: {{ getenv "BAZ" "not set" }} {{- "\n" -}}
+		{{- $env := getenv "FOOBARBAZ" -}}
+		{{- if eq $env "" -}}
+			FOOBARBAZ {{- "\n" -}}
+		{{- end -}}
+	`)
+
+	os.Setenv("FOO", "")
+	os.Unsetenv("BAR")
+	os.Setenv("BAZ", "foobar")
+	os.Unsetenv("FOOBARBAZ")
+
+	err = tmpl.Execute(os.Stdout, nil)
+	if err != nil {
+		panic(err)
+	}
+
+	// Output:
+	// The FOO environment variable is not set.
+	// BAR: not set
+	// BAZ: foobar
+	// FOOBARBAZ
+}

+ 45 - 0
bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/pkg/templatelib/lib_test.go

@@ -0,0 +1,45 @@
+package templatelib_test
+
+import (
+	"testing"
+	"text/template"
+	"unsafe"
+
+	"github.com/docker-library/go-dockerlibrary/pkg/templatelib"
+)
+
+func TestTernaryPanic(t *testing.T) {
+	// one of the only places template.IsTrue will return "false" for the "ok" value is an UnsafePointer (hence this test)
+
+	defer func() {
+		if r := recover(); r == nil {
+			t.Errorf("Expected panic, executed successfully instead")
+		} else if errText, ok := r.(string); !ok || errText != `template.IsTrue(<nil>) says things are NOT OK` {
+			t.Errorf("Unexpected panic: %v", errText)
+		}
+	}()
+
+	tmpl, err := template.New("unsafe-pointer").Funcs(templatelib.FuncMap).Parse(`{{ ternary "true" "false" . }}`)
+
+	err = tmpl.Execute(nil, unsafe.Pointer(uintptr(0)))
+	if err != nil {
+		t.Errorf("Expected panic, got error instead: %v", err)
+	}
+}
+
+func TestJoinPanic(t *testing.T) {
+	defer func() {
+		if r := recover(); r == nil {
+			t.Errorf("Expected panic, executed successfully instead")
+		} else if errText, ok := r.(string); !ok || errText != `"join" requires at least one argument` {
+			t.Errorf("Unexpected panic: %v", r)
+		}
+	}()
+
+	tmpl, err := template.New("join-no-arg").Funcs(templatelib.FuncMap).Parse(`{{ join }}`)
+
+	err = tmpl.Execute(nil, nil)
+	if err != nil {
+		t.Errorf("Expected panic, got error instead: %v", err)
+	}
+}

+ 3 - 0
bashbrew/go/vendor/src/pault.ag/go/debian/AUTHORS

@@ -0,0 +1,3 @@
+Paul Tagliamonte <[email protected]>
+Tianon Gravi <[email protected]>
+Michael Stapelberg <[email protected]>

+ 53 - 0
bashbrew/go/vendor/src/pault.ag/go/debian/LICENSE

@@ -0,0 +1,53 @@
+Copyright (c) Paul R. Tagliamonte <[email protected]>, 2015-2016
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+
+Version module
+==============
+
+Copyright © 2012 Michael Stapelberg and contributors
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+    * Neither the name of Michael Stapelberg nor the
+      names of contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY Michael Stapelberg ''AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL Michael Stapelberg BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 8 - 0
bashbrew/go/vendor/src/pault.ag/go/debian/README.md

@@ -0,0 +1,8 @@
+go-debian
+=========
+
+`go-debian` is a Debian Toolbelt for Go hackers! This package contains a bunch
+of helpful routines to help work with fun bits of Debian data.
+
+
+[![GoDoc](https://godoc.org/pault.ag/go/debian?status.svg)](https://godoc.org/pault.ag/go/debian)

+ 177 - 0
bashbrew/go/vendor/src/pault.ag/go/debian/changelog/changelog.go

@@ -0,0 +1,177 @@
+/* {{{ Copyright (c) Paul R. Tagliamonte <[email protected]>, 2015
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE. }}} */
+
+package changelog
+
+import (
+	"bufio"
+	"fmt"
+	"io"
+	"os"
+	"strings"
+	"time"
+
+	"pault.ag/go/debian/version"
+)
+
+// A ChangelogEntry is the encapsulation for each entry for a given version
+// in a series of uploads.
+type ChangelogEntry struct {
+	Source    string
+	Version   version.Version
+	Target    string
+	Arguments map[string]string
+	Changelog string
+	ChangedBy string
+	When      time.Time
+}
+
+const whenLayout = time.RFC1123Z // "Mon, 02 Jan 2006 15:04:05 -0700"
+
+type ChangelogEntries []ChangelogEntry
+
+func trim(line string) string {
+	return strings.Trim(line, "\n\r\t ")
+}
+
+func partition(line, delim string) (string, string) {
+	entries := strings.SplitN(line, delim, 2)
+	if len(entries) != 2 {
+		return line, ""
+	}
+	return entries[0], entries[1]
+
+}
+
+func ParseOne(reader *bufio.Reader) (*ChangelogEntry, error) {
+	changeLog := ChangelogEntry{}
+
+	var header string
+	for {
+		line, err := reader.ReadString('\n')
+		if err != nil {
+			return nil, err
+		}
+		if line == "\n" {
+			continue
+		}
+		if !strings.HasPrefix(line, " ") {
+			/* Great. Let's work with this. */
+			header = line
+			break
+		} else {
+			return nil, fmt.Errorf("Unexpected line: %s", line)
+		}
+	}
+
+	/* OK, so, we have a header. Let's run with it
+	 * hello (2.10-1) unstable; urgency=low */
+
+	arguments, options := partition(header, ";")
+	/* Arguments: hello (2.10-1) unstable
+	 * Options:   urgency=low, other=bar */
+
+	source, remainder := partition(arguments, "(")
+	versionString, suite := partition(remainder, ")")
+
+	var err error
+
+	changeLog.Source = trim(source)
+	changeLog.Version, err = version.Parse(trim(versionString))
+	if err != nil {
+		return nil, err
+	}
+	changeLog.Target = trim(suite)
+
+	changeLog.Arguments = map[string]string{}
+
+	for _, entry := range strings.Split(options, ",") {
+		key, value := partition(trim(entry), "=")
+		changeLog.Arguments[trim(key)] = trim(value)
+	}
+
+	var signoff string
+	/* OK, we've got the header. Let's zip down. */
+	for {
+		line, err := reader.ReadString('\n')
+		if err != nil {
+			return nil, err
+		}
+		if !strings.HasPrefix(line, " ") && trim(line) != "" {
+			return nil, fmt.Errorf("Error! Didn't get ending line!")
+		}
+
+		if strings.HasPrefix(line, " -- ") {
+			signoff = line
+			break
+		}
+
+		changeLog.Changelog = changeLog.Changelog + line
+	}
+
+	/* Right, so we have a signoff line */
+	_, signoff = partition(signoff, "--")  /* Get rid of the leading " -- " */
+	whom, when := partition(signoff, "  ") /* Split on the "  " */
+	changeLog.ChangedBy = trim(whom)
+	changeLog.When, err = time.Parse(whenLayout, trim(when))
+	if err != nil {
+		return nil, fmt.Errorf("Failed parsing When %q: %v", when, err)
+	}
+
+	return &changeLog, nil
+}
+
+func ParseFileOne(path string) (*ChangelogEntry, error) {
+	f, err := os.Open(path)
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+
+	return ParseOne(bufio.NewReader(f))
+}
+
+func Parse(reader io.Reader) (ChangelogEntries, error) {
+	stream := bufio.NewReader(reader)
+	ret := ChangelogEntries{}
+	for {
+		entry, err := ParseOne(stream)
+		if err == io.EOF {
+			break
+		}
+		if err != nil {
+			return ChangelogEntries{}, err
+		}
+		ret = append(ret, *entry)
+	}
+	return ret, nil
+}
+
+func ParseFile(path string) (ChangelogEntries, error) {
+	f, err := os.Open(path)
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+
+	return Parse(bufio.NewReader(f))
+}
+
+// vim: foldmethod=marker

+ 102 - 0
bashbrew/go/vendor/src/pault.ag/go/debian/changelog/changelog_test.go

@@ -0,0 +1,102 @@
+/* {{{ Copyright (c) Paul R. Tagliamonte <[email protected]>, 2015
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE. }}} */
+
+package changelog_test
+
+import (
+	"bufio"
+	"io"
+	"log"
+	"strings"
+	"testing"
+
+	"pault.ag/go/debian/changelog"
+)
+
+/*
+ *
+ */
+
+func isok(t *testing.T, err error) {
+	if err != nil && err != io.EOF {
+		log.Printf("Error! Error is not nil! %s\n", err)
+		t.FailNow()
+	}
+}
+
+func notok(t *testing.T, err error) {
+	if err == nil {
+		log.Printf("Error! Error is nil!\n")
+		t.FailNow()
+	}
+}
+
+func assert(t *testing.T, expr bool) {
+	if !expr {
+		log.Printf("Assertion failed!")
+		t.FailNow()
+	}
+}
+
+/*
+ *
+ */
+
+// {{{ test changelog entry
+var changeLog = `hello (2.10-1) unstable; urgency=low
+
+  * New upstream release.
+  * debian/patches: Drop 01-fix-i18n-of-default-message, no longer needed.
+  * debian/patches: Drop 99-config-guess-config-sub, no longer needed.
+  * debian/rules: Drop override_dh_auto_build hack, no longer needed.
+  * Standards-Version: 3.9.6 (no changes for this).
+
+ -- Santiago Vila <[email protected]>  Sun, 22 Mar 2015 11:56:00 +0100
+
+hello (2.9-2) unstable; urgency=low
+
+  * Apply patch from Reuben Thomas to fix i18n of default message.
+    This is upstream commit c4aed00. Closes: #767172.
+  * The previous change in src/hello.c trigger a rebuild of man/hello.1
+    that we don't need. Add a "touch man/hello.1" to avoid it.
+  * Use Breaks: hello-debhelper (<< 2.9), not Conflicts,
+    as hello-debhelper is deprecated.
+  * Restore simple watch file from old hello package that was lost
+    when the packages were renamed.
+  * Update 99-config-guess-config-sub patch.
+
+ -- Santiago Vila <[email protected]>  Thu, 06 Nov 2014 12:03:40 +0100
+`
+
+// }}}
+
+func TestChangelogEntry(t *testing.T) {
+	changeLog, err := changelog.ParseOne(bufio.NewReader(strings.NewReader(changeLog)))
+	isok(t, err)
+	assert(t, changeLog.ChangedBy == "Santiago Vila <[email protected]>")
+}
+
+func TestChangelogEntries(t *testing.T) {
+	changeLogs, err := changelog.Parse(strings.NewReader(changeLog))
+	isok(t, err)
+	assert(t, len(changeLogs) == 2)
+}
+
+// vim: foldmethod=marker

+ 6 - 0
bashbrew/go/vendor/src/pault.ag/go/debian/changelog/doc.go

@@ -0,0 +1,6 @@
+/*
+
+Parse the Debian changelog format.
+
+*/
+package changelog

+ 16 - 0
bashbrew/go/vendor/src/pault.ag/go/debian/control/changes.go

@@ -24,6 +24,7 @@ import (
 	"bufio"
 	"fmt"
 	"os"
+	"path"
 	"path/filepath"
 	"strconv"
 	"strings"
@@ -123,6 +124,21 @@ func ParseChanges(reader *bufio.Reader, path string) (*Changes, error) {
 	return ret, Unmarshal(ret, reader)
 }
 
+// Return a list of FileListChangesFileHash entries from the `changes.Files`
+// entry, with the exception that each `Filename` will be joined to the root
+// directory of the Changes file.
+func (changes *Changes) AbsFiles() []FileListChangesFileHash {
+	ret := []FileListChangesFileHash{}
+
+	baseDir := filepath.Dir(changes.Filename)
+	for _, hash := range changes.Files {
+		hash.Filename = path.Join(baseDir, hash.Filename)
+		ret = append(ret, hash)
+	}
+
+	return ret
+}
+
 // Return a DSC struct for the DSC listed in the .changes file. This requires
 // Changes.Filename to be correctly set, and for the .dsc file to exist
 // in the correct place next to the .changes.

+ 1 - 1
bashbrew/go/vendor/src/pault.ag/go/debian/control/dsc.go

@@ -31,7 +31,7 @@ import (
 	"pault.ag/go/topsort"
 )
 
-// A DSC is the ecapsulation of a Debian .dsc control file. This contains
+// A DSC is the encapsulation of a Debian .dsc control file. This contains
 // information about the source package, and is general handy.
 //
 // The Debian source control file is generated by dpkg-source when it builds

+ 1 - 1
bashbrew/go/vendor/src/pault.ag/go/debian/control/encode.go

@@ -55,7 +55,7 @@ func ConvertToParagraph(incoming interface{}) (*Paragraph, error) {
 	return convertToParagraph(data.Elem())
 }
 
-// Top-level conversaion dispatch {{{
+// Top-level conversion dispatch {{{
 
 func convertToParagraph(data reflect.Value) (*Paragraph, error) {
 	order := []string{}

+ 1 - 1
bashbrew/go/vendor/src/pault.ag/go/debian/control/parse.go

@@ -267,7 +267,7 @@ func (p *ParagraphReader) Next() (*Paragraph, error) {
 func (p *ParagraphReader) decodeClearsig(keyring *openpgp.EntityList) error {
 	// One *massive* downside here is that the OpenPGP module in Go operates
 	// on byte arrays in memory, and *not* on Readers and Writers. This is a
-	// huge PITA because it does't need to be that way, and this forces
+	// huge PITA because it doesn't need to be that way, and this forces
 	// clearsigned documents into memory. Which fucking sucks. But here
 	// we are. It's likely worth a bug or two on this.
 

+ 204 - 0
bashbrew/go/vendor/src/pault.ag/go/debian/deb/ar.go

@@ -0,0 +1,204 @@
+/* {{{ Copyright (c) Paul R. Tagliamonte <[email protected]>, 2015
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE. }}} */
+
+package deb
+
+import (
+	"fmt"
+	"io"
+	"io/ioutil"
+	"strconv"
+	"strings"
+)
+
+// ArEntry {{{
+
+// Container type to access the different parts of a Debian `ar(1)` Archive.
+//
+// The most interesting parts of this are the `Name` attribute, Data
+// `io.Reader`, and the Tarfile helpers. This will allow the developer to
+// programmatically inspect the information inside without forcing her to
+// unpack the .deb to the filesystem.
+type ArEntry struct {
+	Name      string
+	Timestamp int64
+	OwnerID   int64
+	GroupID   int64
+	FileMode  string
+	Size      int64
+	Data      io.Reader
+}
+
+// }}}
+
+// Ar {{{
+
+// This struct encapsulates a Debian .deb flavored `ar(1)` archive.
+type Ar struct {
+	in         io.Reader
+	lastReader *io.Reader
+	offset     bool
+}
+
+// LoadAr {{{
+
+// Load an Ar archive reader from an io.Reader
+func LoadAr(in io.Reader) (*Ar, error) {
+	if err := checkAr(in); err != nil {
+		return nil, err
+	}
+	debFile := Ar{in: in}
+	return &debFile, nil
+}
+
+// }}}
+
+// Next {{{
+
+// Function to jump to the next file in the Debian `ar(1)` archive, and
+// return the next member.
+func (d *Ar) Next() (*ArEntry, error) {
+	if d.lastReader != nil {
+		/* Before we do much more, let's empty out the reader, since we
+		 * can't be sure of our position in the reader until the LimitReader
+		 * is empty */
+		if _, err := io.Copy(ioutil.Discard, *d.lastReader); err != nil {
+			return nil, err
+		}
+		if d.offset {
+			/* .ar archives align on 2 byte boundaries, so if we're odd, go
+			 * ahead and read another byte. If we get an io.EOF, it's fine
+			 * to return it. */
+			_, err := d.in.Read(make([]byte, 1))
+			if err != nil {
+				return nil, err
+			}
+		}
+	}
+
+	line := make([]byte, 60)
+
+	count, err := d.in.Read(line)
+	if err != nil {
+		return nil, err
+	}
+	if count == 1 && line[0] == '\n' {
+		return nil, io.EOF
+	}
+	if count != 60 {
+		return nil, fmt.Errorf("Caught a short read at the end")
+	}
+	entry, err := parseArEntry(line)
+	if err != nil {
+		return nil, err
+	}
+
+	entry.Data = io.LimitReader(d.in, entry.Size)
+	d.lastReader = &entry.Data
+	d.offset = (entry.Size % 2) == 1
+
+	return entry, nil
+}
+
+// }}}
+
+// toDecimal {{{
+
+// Take a byte array, and return an int64
+func toDecimal(input []byte) (int64, error) {
+	stream := strings.TrimSpace(string(input))
+	out, err := strconv.Atoi(stream)
+	return int64(out), err
+}
+
+// }}}
+
+// }}}
+
+// AR Format Hackery {{{
+
+// parseArEntry {{{
+
+// Take the AR format line, and create an ArEntry (without .Data set)
+// to be returned to the user later.
+//
+// +-------------------------------------------------------
+// | Offset  Length  Name                         Format
+// +-------------------------------------------------------
+// | 0       16      File name                    ASCII
+// | 16      12      File modification timestamp  Decimal
+// | 28      6       Owner ID                     Decimal
+// | 34      6       Group ID                     Decimal
+// | 40      8       File mode                    Octal
+// | 48      10      File size in bytes           Decimal
+// | 58      2       File magic                   0x60 0x0A
+//
+func parseArEntry(line []byte) (*ArEntry, error) {
+	if len(line) != 60 {
+		return nil, fmt.Errorf("Malformed file entry line length")
+	}
+
+	if line[58] != 0x60 && line[59] != 0x0A {
+		return nil, fmt.Errorf("Malformed file entry line endings")
+	}
+
+	entry := ArEntry{
+		Name:     strings.TrimSpace(string(line[0:16])),
+		FileMode: strings.TrimSpace(string(line[48:58])),
+	}
+
+	for target, value := range map[*int64][]byte{
+		&entry.Timestamp: line[16:28],
+		&entry.OwnerID:   line[28:34],
+		&entry.GroupID:   line[34:40],
+		&entry.Size:      line[48:58],
+	} {
+		intValue, err := toDecimal(value)
+		if err != nil {
+			return nil, err
+		}
+		*target = intValue
+	}
+
+	return &entry, nil
+}
+
+// }}}
+
+// checkAr {{{
+
+// Given a brand spank'n new os.File entry, go ahead and make sure it looks
+// like an `ar(1)` archive, and not some random file.
+func checkAr(reader io.Reader) error {
+	header := make([]byte, 8)
+	if _, err := reader.Read(header); err != nil {
+		return err
+	}
+	if string(header) != "!<arch>\n" {
+		return fmt.Errorf("Header doesn't look right!")
+	}
+	return nil
+}
+
+// }}}
+
+// }}}
+
+// vim: foldmethod=marker

+ 242 - 0
bashbrew/go/vendor/src/pault.ag/go/debian/deb/deb.go

@@ -0,0 +1,242 @@
+/* {{{ Copyright (c) Paul R. Tagliamonte <[email protected]>, 2015
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE. }}} */
+
+package deb
+
+import (
+	"archive/tar"
+	"bufio"
+	"fmt"
+	"io"
+	"os"
+	"path"
+	"strings"
+
+	"pault.ag/go/debian/control"
+	"pault.ag/go/debian/dependency"
+	"pault.ag/go/debian/version"
+)
+
+// Control {{{
+
+// Binary Control format, as exists in the Control section of the `.deb`
+// archive, as defined in Debian Policy, section 5.3, entitled "Binary
+// package control files -- DEBIAN/control".
+type Control struct {
+	control.Paragraph
+
+	Package       string `required:"true"`
+	Source        string
+	Version       version.Version `required:"true"`
+	Architecture  dependency.Arch `required:"true"`
+	Maintainer    string          `required:"true"`
+	InstalledSize int             `control:"Installed-Size"`
+	Depends       dependency.Dependency
+	Recommends    dependency.Dependency
+	Suggests      dependency.Dependency
+	Breaks        dependency.Dependency
+	Replaces      dependency.Dependency
+	BuiltUsing    dependency.Dependency `control:"Built-Using"`
+	Section       string
+	Priority      string
+	Homepage      string
+	Description   string `required:"true"`
+}
+
+func (c Control) SourceName() string {
+	if c.Source == "" {
+		return c.Package
+	}
+	return c.Source
+}
+
+// }}}
+
+// Deb {{{
+
+// Container struct to encapsulate a `.deb` file on disk. This contains
+// information about what exactly we're looking at. When loaded. information
+// regarding the Control file is read from the control section of the .deb,
+// and Unmarshaled into the `Control` member of the Struct.
+type Deb struct {
+	Control Control
+	Path    string
+	Data    *tar.Reader
+}
+
+// Load {{{
+
+// Load {{{
+
+// Given a reader, and the file path to the file (for use in the Deb later)
+// create a deb.Deb object, and populate the Control and Data members.
+func Load(in io.Reader, pathname string) (*Deb, error) {
+	ar, err := LoadAr(in)
+	if err != nil {
+		return nil, err
+	}
+	deb, err := loadDeb(ar)
+	if err != nil {
+		return nil, err
+	}
+	deb.Path = pathname
+	return deb, nil
+}
+
+// }}}
+
+// LoadFile {{{
+
+type Closer func() error
+
+func LoadFile(path string) (*Deb, Closer, error) {
+	fd, err := os.Open(path)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	debFile, err := Load(fd, path)
+	if err != nil {
+		fd.Close()
+		return nil, nil, err
+	}
+
+	return debFile, fd.Close, nil
+
+}
+
+// }}}
+
+// Debian .deb Loader Internals {{{
+
+// Top-level .deb loader dispatch on Version {{{
+
+// Look for the debian-binary member and figure out which version to read
+// it as. Return the newly created .deb struct.
+func loadDeb(archive *Ar) (*Deb, error) {
+	for {
+		member, err := archive.Next()
+		if err == io.EOF {
+			return nil, fmt.Errorf("Archive contains no binary version member!")
+		}
+		if err != nil {
+			return nil, err
+		}
+		if member.Name == "debian-binary" {
+			reader := bufio.NewReader(member.Data)
+			version, err := reader.ReadString('\n')
+			if err != nil {
+				return nil, err
+			}
+			switch version {
+			case "2.0\n":
+				return loadDeb2(archive)
+			default:
+				return nil, fmt.Errorf("Unknown binary version: '%s'", version)
+			}
+		}
+	}
+}
+
+// }}}
+
+// Debian .deb format 2.0 {{{
+
+// Top-level .deb loader dispatch for 2.0 {{{
+
+// Load a Debian 2.x series .deb - track down the control and data members.
+func loadDeb2(archive *Ar) (*Deb, error) {
+	ret := Deb{}
+
+	if err := loadDeb2Control(archive, &ret); err != nil {
+		return nil, err
+	}
+
+	if err := loadDeb2Data(archive, &ret); err != nil {
+		return nil, err
+	}
+
+	return &ret, nil
+}
+
+// }}}
+
+// Decode .deb 2.0 control data into the struct {{{
+
+// Load a Debian 2.x series .deb control file and write it out to
+// the deb.Deb.Control member.
+func loadDeb2Control(archive *Ar, deb *Deb) error {
+	for {
+		member, err := archive.Next()
+		if err == io.EOF {
+			return fmt.Errorf("Missing or out of order .deb member 'control'")
+		}
+		if err != nil {
+			return err
+		}
+		if strings.HasPrefix(member.Name, "control.") {
+			archive, err := member.Tarfile()
+			if err != nil {
+				return err
+			}
+			for {
+				member, err := archive.Next()
+				if err != nil {
+					return err
+				}
+				if path.Clean(member.Name) == "control" {
+					return control.Unmarshal(&deb.Control, archive)
+				}
+			}
+		}
+	}
+}
+
+// }}}
+
+// Decode .deb 2.0 package data into the struct {{{
+
+// Load a Debian 2.x series .deb data file and write it out to
+// the deb.Deb.Data member.
+func loadDeb2Data(archive *Ar, deb *Deb) error {
+	for {
+		member, err := archive.Next()
+		if err == io.EOF {
+			return fmt.Errorf("Missing or out of order .deb member 'data'")
+		}
+		if err != nil {
+			return err
+		}
+		if strings.HasPrefix(member.Name, "data.") {
+			archive, err := member.Tarfile()
+			if err != nil {
+				return err
+			}
+			deb.Data = archive
+			return nil
+		}
+	}
+}
+
+// }}}
+
+// }}} }}} }}} }}}
+
+// vim: foldmethod=marker

+ 40 - 0
bashbrew/go/vendor/src/pault.ag/go/debian/deb/doc.go

@@ -0,0 +1,40 @@
+/*
+
+This module provides an API to access and programmatically process
+Debian `.deb` archives on disk.
+
+Debian files, at a high level, are `ar(1)` archives, which
+contain a few sections, most notably the `control` member, which contains
+information about the Debian package itself, and the `data` member, which
+contains the actual contents of the files, as they should be written out
+on disk.
+
+Here's a trivial example, which will print out the Package name for a
+`.deb` archive given on the command line:
+
+	package main
+
+	import (
+		"log"
+		"os"
+
+		"pault.ag/go/debian/deb"
+	)
+
+	func main() {
+		path := os.Args[1]
+		fd, err := os.Open(path)
+		if err != nil {
+			panic(err)
+		}
+		defer fd.Close()
+
+		debFile, err := deb.Load(fd, path)
+		if err != nil {
+			panic(err)
+		}
+		log.Printf("Package: %s\n", debFile.Control.Package)
+	}
+
+*/
+package deb

+ 105 - 0
bashbrew/go/vendor/src/pault.ag/go/debian/deb/tarfile.go

@@ -0,0 +1,105 @@
+/* {{{ Copyright (c) Paul R. Tagliamonte <[email protected]>, 2015
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE. }}} */
+
+package deb
+
+import (
+	"fmt"
+	"io"
+	"strings"
+
+	"archive/tar"
+
+	"compress/bzip2"
+	"compress/gzip"
+	"xi2.org/x/xz"
+)
+
+// known compression types {{{
+
+type compressionReader func(io.Reader) (io.Reader, error)
+
+func gzipNewReader(r io.Reader) (io.Reader, error) {
+	return gzip.NewReader(r)
+}
+
+func xzNewReader(r io.Reader) (io.Reader, error) {
+	return xz.NewReader(r, 0)
+}
+
+func bzipNewReader(r io.Reader) (io.Reader, error) {
+	return bzip2.NewReader(r), nil
+}
+
+var knownCompressionAlgorithms = map[string]compressionReader{
+	".tar.gz":  gzipNewReader,
+	".tar.bz2": bzipNewReader,
+	".tar.xz":  xzNewReader,
+}
+
+// }}}
+
+// IsTarfile {{{
+
+// Check to see if the given ArEntry is, in fact, a Tarfile. This method
+// will return `true` for `control.tar.*` and `data.tar.*` files.
+//
+// This will return `false` for the `debian-binary` file. If this method
+// returns `true`, the `.Tarfile()` method will be around to give you a
+// tar.Reader back.
+func (e *ArEntry) IsTarfile() bool {
+	return e.getCompressionReader() != nil
+}
+
+// }}}
+
+// Tarfile {{{
+
+// `.Tarfile()` will return a `tar.Reader` created from the ArEntry member
+// to allow further inspection of the contents of the `.deb`.
+func (e *ArEntry) Tarfile() (*tar.Reader, error) {
+	decompressor := e.getCompressionReader()
+	if decompressor == nil {
+		return nil, fmt.Errorf("%s appears to not be a tarfile", e.Name)
+	}
+	reader, err := (*decompressor)(e.Data)
+	if err != nil {
+		return nil, err
+	}
+	return tar.NewReader(reader), nil
+}
+
+// }}}
+
+// getCompressionReader {{{
+
+// Get a compressionReader that we can use to unpack the member.
+func (e *ArEntry) getCompressionReader() *compressionReader {
+	for key, decompressor := range knownCompressionAlgorithms {
+		if strings.HasSuffix(e.Name, key) {
+			return &decompressor
+		}
+	}
+	return nil
+}
+
+// }}}
+
+// vim: foldmethod=marker

+ 1 - 1
bashbrew/go/vendor/src/pault.ag/go/debian/dependency/string.go

@@ -31,7 +31,7 @@ func (a Arch) MarshalControl() (string, error) {
 func (a Arch) String() string {
 	/* ABI-OS-CPU -- gnu-linux-amd64 */
 	els := []string{}
-	if a.ABI != "any" && a.ABI != "all" && a.ABI != "gnu" {
+	if a.ABI != "any" && a.ABI != "all" && a.ABI != "gnu" && a.ABI != "" {
 		els = append(els, a.ABI)
 	}
 

+ 56 - 0
bashbrew/manifest-tool.patch

@@ -0,0 +1,56 @@
+https://github.com/estesp/manifest-tool/issues/47
+
+diff --git a/vendor/github.com/docker/distribution/reference/reference.go b/vendor/github.com/docker/distribution/reference/reference.go
+index 52da523..3cf3d98 100644
+--- a/vendor/github.com/docker/distribution/reference/reference.go
++++ b/vendor/github.com/docker/distribution/reference/reference.go
+@@ -100,6 +100,13 @@ func (f *Field) UnmarshalText(p []byte) error {
+ 	return nil
+ }
+ 
++func remoteName(name string) string {
++	if !strings.ContainsRune(name, '/') {
++		return "library/" + name
++	}
++	return name
++}
++
+ // Named is an object with a full name
+ type Named interface {
+ 	Reference
+@@ -304,7 +311,7 @@ func (r reference) String() string {
+ }
+ 
+ func (r reference) Name() string {
+-	return r.name
++	return remoteName(r.name)
+ }
+ 
+ func (r reference) Tag() string {
+@@ -322,7 +329,7 @@ func (r repository) String() string {
+ }
+ 
+ func (r repository) Name() string {
+-	return string(r)
++	return remoteName(string(r))
+ }
+ 
+ type digestReference digest.Digest
+@@ -345,7 +352,7 @@ func (t taggedReference) String() string {
+ }
+ 
+ func (t taggedReference) Name() string {
+-	return t.name
++	return remoteName(t.name)
+ }
+ 
+ func (t taggedReference) Tag() string {
+@@ -362,7 +369,7 @@ func (c canonicalReference) String() string {
+ }
+ 
+ func (c canonicalReference) Name() string {
+-	return c.name
++	return remoteName(c.name)
+ }
+ 
+ func (c canonicalReference) Digest() digest.Digest {

+ 1 - 1
bashbrew/travis.sh

@@ -45,7 +45,7 @@ cmds=(
 if [ "$extraCommands" ]; then
 	cmds+=(
 		'list --build-order'
-		'from'
+		'from --apply-constraints'
 	)
 fi
 

+ 76 - 0
build-and-push.sh

@@ -0,0 +1,76 @@
+#!/bin/bash
+set -eu -o pipefail
+
+# set "$0" so that tmux shows something more useful than "bash" in the statusbar
+desired0='b-a-p'
+if ! grep -q "$desired0" "/proc/$$/cmdline"; then
+	exec -a "$desired0" "$SHELL" -- "$BASH_SOURCE" "$@"
+fi
+
+if [ "$#" -eq 0 ]; then
+	self="$(basename "$0")"
+	cat >&2 <<-EOF
+		error: missing arguments
+		usage: $self <build args>
+		   ie: $self debian ubuntu
+	EOF
+	exit 1
+fi
+
+# allow for specifying an alternate path to "bashbrew"
+: "${BASHBREW:=bashbrew}"
+
+# normalize "$@" to be the "--uniq" versions (and deduplicate)
+# also grab the list of associated repos in explicit build order (so we can build/push grouped by repo)
+IFS=$'\n'
+set -- $("$BASHBREW" list --uniq --repos "$@" | sort -u | xargs "$BASHBREW" list --uniq --repos --build-order --apply-constraints)
+repos=( $(echo "$*" | cut -d: -f1 | xargs "$BASHBREW" list --repos --build-order --apply-constraints) )
+unset IFS
+
+declare -A repoTags=()
+for repoTag; do
+	repo="${repoTag%%:*}"
+	repoTags[$repo]+=" $repoTag"
+done
+
+# fill "$@" back up with the corrected build order (especially for the "Children:" output)
+set --
+for repo in "${repos[@]}"; do
+	set -- "$@" ${repoTags[$repo]}
+done
+
+children="$("$(dirname "$BASH_SOURCE")/children.sh" "$@")"
+
+echo
+echo
+echo "Children: (of $*)"
+echo "${children:-<none>}"
+echo
+echo
+
+for repo in "${repos[@]}"; do
+	tags=( ${repoTags[$repo]} )
+	(
+		set -x
+		time "$BASHBREW" build "${tags[@]}"
+		time "$BASHBREW" tag "${tags[@]}"
+		time "$BASHBREW" push "${tags[@]}"
+	)
+done
+
+echo
+echo
+echo "Children: (of $*)"
+echo "${children:-<none>}"
+echo
+echo
+
+if [ "$children" ]; then
+	echo 'Suggested command:'
+	echo "  ./children.sh $* | xargs ./build-and-push.sh"
+	echo
+fi
+
+# end by printing only warnings (stderr) for images we skipped (such as "windowsservercore" when building on Linux)
+# this helps remind us to switch BASHBREW or servers
+"$BASHBREW" list --apply-constraints "$@" > /dev/null

+ 60 - 0
children.sh

@@ -0,0 +1,60 @@
+#!/bin/bash
+set -eu -o pipefail
+
+# "bashbrew children" can't work with "--uniq" and "bashbrew build" will build the entire "tag group", so we need to filter the output to just uniq values
+
+: "${BASHBREW:=bashbrew}"
+
+IFS=$'\n'
+set -- $("$BASHBREW" list --uniq --repos --build-order --apply-constraints "$@")
+
+# \o/ https://github.com/docker-library/official-images/commit/9e57342714f99074ec205eea668c8b73aada36ec
+comm -13 \
+		<("$BASHBREW" list "$@" | sort -u) \
+		<("$BASHBREW" children --apply-constraints "$@" | sort -u) \
+	| xargs --no-run-if-empty "$BASHBREW" list --build-order --apply-constraints --uniq
+exit 0
+
+children=( $("$BASHBREW" children --apply-constraints "$@") )
+
+[ "${#children[@]}" -gt 0 ] || exit 0
+
+# just repo names so we can get the right build-order for all of their tags
+childrenRepos=( $(echo "${children[*]}" | cut -d: -f1 | sort -u) )
+
+# all uniq tags from all repos which have relevant children, in proper build order
+childrenReposUniq=( $("$BASHBREW" list --uniq --build-order --apply-constraints "${childrenRepos[@]}") )
+
+# the canonical ("uniq") versions of the children we're after (same as the values now in "childrenReposUniq")
+#   use "comm" to suppress "$@" from the list of children we care about
+childrenUniq=(
+	$(
+		comm -13 \
+			<(
+				"$BASHBREW" list --uniq "$@" \
+					| sort -u
+			) \
+			<(
+				"$BASHBREW" list --uniq "${children[@]}" \
+					| sort -u
+			)
+	)
+)
+
+[ "${#childrenUniq[@]}" -gt 0 ] || exit 0
+
+unset IFS
+
+# create a lookup table of whether we should return a particular tag
+declare -A wantChild=()
+for child in "${childrenUniq[@]}"; do
+	wantChild["$child"]=1
+done
+
+# loop over the canonical build order and print out tags we want :)
+for child in "${childrenReposUniq[@]}"; do
+	[ "${wantChild[$child]:-}" ] || continue
+	echo "$child"
+done
+
+# note that we can't use "comm" by itself here because "childrenUniq" and "childrenReposUniq" are not in the same order, which "comm" requires

+ 85 - 16
diff-pr.sh

@@ -18,6 +18,35 @@ allFiles=
 listTarballContents=1
 findCopies='20%'
 
+uninterestingTarballContent=(
+	# "config_diff_2017_01_07.log"
+	'var/log/YaST2/'
+
+	# "ks-script-mqmz_080.log"
+	# "ks-script-ycfq606i.log"
+	'var/log/anaconda/'
+
+	# "2016-12-20/"
+	'var/lib/yum/history/'
+	'var/lib/dnf/history/'
+
+	# "a/f8c032d2be757e1a70f00336b55c434219fee230-acl-2.2.51-12.el7-x86_64/var_uuid"
+	'var/lib/yum/yumdb/'
+	'var/lib/dnf/yumdb/'
+
+	# "b42ff584.0"
+	'etc/pki/tls/rootcerts/'
+)
+
+# prints "$2$1$3$1...$N"
+join() {
+	local sep="$1"; shift
+	local out; printf -v out "${sep//%/%%}%s" "$@"
+	echo "${out#$sep}"
+}
+
+uninterestingTarballGrep="^([.]?/)?($(join '|' "${uninterestingTarballContent[@]}"))"
+
 if [ "$#" -eq 0 ]; then
 	usage >&2
 	exit 1
@@ -45,24 +74,55 @@ fi
 
 export BASHBREW_CACHE="${BASHBREW_CACHE:-${XDG_CACHE_HOME:-$HOME/.cache}/bashbrew}"
 export BASHBREW_LIBRARY="$PWD/oi/library"
+export BASHBREW_ARCH='amd64' # TODO something smarter with arches
+
+# "bashbrew cat" template for duplicating something like "bashbrew list --uniq" but with architectures too
+archesListTemplate='
+	{{- range $e := $.Entries -}}
+		{{- range .Architectures -}}
+			{{- $.RepoName -}}:{{- $e.Tags | last -}}
+			{{- " @ " -}}
+			{{- . -}}
+			{{- "\n" -}}
+		{{- end -}}
+	{{- end -}}
+'
+# ... and SharedTags
+sharedTagsListTemplate='
+	{{- range $group := .Manifest.GetSharedTagGroups -}}
+		{{- range $tag := $group.SharedTags -}}
+			{{- join ":" $.RepoName $tag -}}
+			{{- " -- " -}}
+			{{- range $i, $e := $group.Entries -}}
+				{{- if gt $i 0 -}}
+					{{- ", " -}}
+				{{- end -}}
+				{{- join ":" $.RepoName ($e.Tags | last) -}}
+			{{- end -}}
+			{{- "\n" -}}
+		{{- end -}}
+	{{- end -}}
+'
 
 # TODO something less hacky than "git archive" hackery, like a "bashbrew archive" or "bashbrew context" or something
 template='
-{{- range $.Entries -}}
-	{{- $from := $.DockerFrom . -}}
-	git -C "$BASHBREW_CACHE/git" archive --format=tar
-	{{- " " -}}
-	{{- "--prefix=" -}}
-	{{- $.RepoName -}}
-	_
-	{{- .Tags | last -}}
-	{{- "/" -}}
-	{{- " " -}}
-	{{- .GitCommit -}}
-	{{- ":" -}}
-	{{- (eq .Directory ".") | ternary "" .Directory -}}
-	{{- "\n" -}}
-{{- end -}}
+	{{- range $.Entries -}}
+		{{- $arch := .Architectures | first -}}
+		{{- $from := $.ArchDockerFrom $arch . -}}
+		git -C "$BASHBREW_CACHE/git" archive --format=tar
+		{{- " " -}}
+		{{- "--prefix=" -}}
+		{{- $.RepoName -}}
+		_
+		{{- .Tags | last -}}
+		{{- "/" -}}
+		{{- " " -}}
+		{{- .ArchGitCommit $arch -}}
+		{{- ":" -}}
+		{{- $dir := .ArchDirectory $arch -}}
+		{{- (eq $dir ".") | ternary "" $dir -}}
+		{{- "\n" -}}
+	{{- end -}}
 '
 
 copy-tar() {
@@ -124,7 +184,10 @@ copy-tar() {
 				if [ "$listTarballContents" ]; then
 					case "$g" in
 						*.tar.*|*.tgz)
-							tar -tf "$dst/$dDirName/$g" | sort > "$dst/$dDirName/$g  'tar -t'"
+							tar -tf "$dst/$dDirName/$g" \
+								| grep -vE "$uninterestingTarballGrep" \
+								| sort \
+								> "$dst/$dDirName/$g  'tar -t'"
 							;;
 					esac
 				fi
@@ -136,6 +199,9 @@ copy-tar() {
 mkdir temp
 git -C temp init --quiet
 
+bashbrew list "${images[@]}" | sort -V > temp/_bashbrew-list || :
+bashbrew cat --format "$archesListTemplate" "${images[@]}" | sort -V > temp/_bashbrew-arches || :
+bashbrew cat --format "$sharedTagsListTemplate" "${images[@]}" | grep -vE '^$' | sort -V > temp/_bashbrew-shared-tags || :
 for image in "${images[@]}"; do
 	if script="$(bashbrew cat -f "$template" "$image")"; then
 		mkdir tar
@@ -150,6 +216,9 @@ git -C temp commit --quiet --allow-empty -m 'initial' || :
 git -C oi checkout --quiet pull
 
 git -C temp rm --quiet -rf . || :
+bashbrew list "${images[@]}" | sort -V > temp/_bashbrew-list || :
+bashbrew cat --format "$archesListTemplate" "${images[@]}" | sort -V > temp/_bashbrew-arches || :
+bashbrew cat --format "$sharedTagsListTemplate" "${images[@]}" | grep -vE '^$' | sort -V > temp/_bashbrew-shared-tags || :
 script="$(bashbrew cat -f "$template" "${images[@]}")"
 mkdir tar
 ( eval "$script" | tar -xiC tar )

+ 18 - 0
heavy-hitters.txt

@@ -0,0 +1,18 @@
+# repositories which we've been asked to leave at least 15 minutes in between pushes of
+# (so as to be kind to the automated build queues)
+
+ubuntu
+debian
+java
+python
+perl
+php
+buildpack-deps
+alpine
+centos
+
+# to get a one-liner "grep" to take a list and pare it down to just heavy hitters, use something like:
+#   echo "grep -E '^($(grep -vE '^$|^#' heavy-hitters.txt | paste -sd '|'))(:|\$)'"
+# output will be something like:
+#   grep -E '^(foo|bar|baz|...)(:|$)'
+# (swap "-E" to "-vE" to exclude instead of include)

+ 14 - 0
library/adminer

@@ -0,0 +1,14 @@
+# this file is generated via https://github.com/TimWolla/docker-adminer/blob/6cdded81c255317d89b15981707f33b553b60c42/generate-stackbrew-library.sh
+
+Maintainers: Tim Düsterhus <[email protected]> (@TimWolla)
+GitRepo: https://github.com/TimWolla/docker-adminer.git
+
+Tags: 4.3.1-standalone, 4.3-standalone, 4-standalone, standalone, 4.3.1, 4.3, 4, latest
+Architectures: amd64
+GitCommit: 73de6b9a7979ded5d2289fe015fffe81fa32e0a4
+Directory: 4.3
+
+Tags: 4.3.1-fastcgi, 4.3-fastcgi, 4-fastcgi, fastcgi
+Architectures: amd64
+GitCommit: e7677ec95176973e991b063d8782876207738ce1
+Directory: 4.3/fastcgi

+ 4 - 2
library/aerospike

@@ -1,4 +1,6 @@
 # maintainer: Lucien Volmar <[email protected]> (@volmarl)
 
-3.10.0.3: git://github.com/aerospike/aerospike-server.docker@33a4dade9e13ebd34c7bc879d491ce6904bc52fa
-latest: git://github.com/aerospike/aerospike-server.docker@33a4dade9e13ebd34c7bc879d491ce6904bc52fa
+3.12.1.3: git://github.com/aerospike/aerospike-server.docker@eb4758c8bcb30158cef593383ac0aab119b066c1
+3.13.0.4: git://github.com/aerospike/aerospike-server.docker@b15fcaa6058d95efb27f3e08256215b5bde9180d
+3.14.1.2: git://github.com/aerospike/aerospike-server.docker@21b823c72214a79f1d6c79ba3243c38823282314
+latest: git://github.com/aerospike/aerospike-server.docker@21b823c72214a79f1d6c79ba3243c38823282314

+ 8 - 7
library/alpine

@@ -1,9 +1,10 @@
 # maintainer: Glider Labs <[email protected]> (@gliderlabs)
 
-3.1: git://github.com/gliderlabs/docker-alpine@8179fe722094b8724b7e9eb1d573173baf6ca977 versions/library-3.1
-3.2: git://github.com/gliderlabs/docker-alpine@5636e9a91b543fa507271fbbc9b5d1db59ce986f versions/library-3.2
-3.3: git://github.com/gliderlabs/docker-alpine@bc90ea0c90880b44cc7f405cbe6ec27ed453fda7 versions/library-3.3
-3.4: git://github.com/gliderlabs/docker-alpine@a83f6c797a617f580ff717efe9e53543f7beca43 versions/library-3.4
-latest: git://github.com/gliderlabs/docker-alpine@a83f6c797a617f580ff717efe9e53543f7beca43 versions/library-3.4
-edge: git://github.com/gliderlabs/docker-alpine@64804257e6997cdc88c39e949b6a9df492621691 versions/library-edge
-
+3.1: git://github.com/gliderlabs/docker-alpine@6b5697882749ae8fb8a1c5ad6ba87d3b59ab0a2a versions/library-3.1
+3.2: git://github.com/gliderlabs/docker-alpine@3fbbd4c387d2934b13ea2526ce82f80e20301278 versions/library-3.2
+3.3: git://github.com/gliderlabs/docker-alpine@12b2d14e105813a3ff0f4bf7c6a61058c83debad versions/library-3.3
+3.4: git://github.com/gliderlabs/docker-alpine@7f558cc0542cf47b28686385cc0a2cc41fe10325 versions/library-3.4
+3.5: git://github.com/gliderlabs/docker-alpine@9b354b8bb3cc7b343e72ef4ec34ef38ec525728d versions/library-3.5
+3.6: git://github.com/gliderlabs/docker-alpine@c6cb2bbffbc92d4c35cdaf584dd1c43a860104ea versions/library-3.6
+latest: git://github.com/gliderlabs/docker-alpine@c6cb2bbffbc92d4c35cdaf584dd1c43a860104ea versions/library-3.6
+edge: git://github.com/gliderlabs/docker-alpine@c0f432b0e678c1096e041e7e63a089444ad544c9 versions/library-edge

+ 21 - 0
library/amazonlinux

@@ -0,0 +1,21 @@
+Maintainers: Amazon Linux Team <[email protected]> (@aws),
+             Iliana Weller (@ilianaw),
+             Praveen K Paladugu (@praveen-pk),
+             Eric Warehime (@Eric-Warehime)
+GitRepo: https://github.com/aws/amazon-linux-docker-images.git
+
+Tags: 2017.03.0.20170812, 2017.03, latest
+GitFetch: refs/heads/2017.03
+GitCommit: 577139a6f2571e3adb59cfd34d61bc07e2fba238
+
+Tags: 2017.03.0.20170812-with-sources, 2017.03-with-sources, with-sources
+GitFetch: refs/heads/2017.03-with-sources
+GitCommit: 47f91aec4a189232a7feb1ec544a3a6af0347113
+
+Tags: 2016.09.1.20161221, 2016.09
+GitFetch: refs/heads/2016.09
+GitCommit: e1b56e68ebd2b274c64e0a0a18ae0a9a8122822d
+
+Tags: 2016.09.1.20161221-with-sources, 2016.09-with-sources
+GitFetch: refs/heads/2016.09-with-sources
+GitCommit: 2de60e8c98421694c293639659a88ed81ce29298

+ 5 - 13
library/arangodb

@@ -1,18 +1,10 @@
 # maintainer: Frank Celler <[email protected]> (@fceller)
 # maintainer: Wilfried Goesgens <[email protected]> (@dothebart)
 
-2.5.5: git://github.com/arangodb/arangodb-docker@636cd874df38edd77a187c08e1803693b3d978d3 jessie/2.5.5
-2.5: git://github.com/arangodb/arangodb-docker@636cd874df38edd77a187c08e1803693b3d978d3 jessie/2.5.5
+2.8: https://github.com/arangodb/arangodb-docker@d6fca9a137cd21345b1d380fc0e72daacb6130ce jessie/2.8.11
+2.8.11: https://github.com/arangodb/arangodb-docker@d6fca9a137cd21345b1d380fc0e72daacb6130ce jessie/2.8.11
 
-2.6: git://github.com/arangodb/arangodb-docker@803663b157696616d70e2bb44ce6e256f912e3a6 jessie/2.6.10
-2.6.10: git://github.com/arangodb/arangodb-docker@803663b157696616d70e2bb44ce6e256f912e3a6 jessie/2.6.10
 
-2.7: git://github.com/arangodb/arangodb-docker@dbfcc5f3edb37f622a2acd221b58106547b05fae jessie/2.7.5
-2.7.5: git://github.com/arangodb/arangodb-docker@dbfcc5f3edb37f622a2acd221b58106547b05fae jessie/2.7.5
-
-2.8: git://github.com/arangodb/arangodb-docker@05366cb4c6a6aab8e1ff9ca74c81b09d9a57b5b5 jessie/2.8.11
-2.8.11: git://github.com/arangodb/arangodb-docker@05366cb4c6a6aab8e1ff9ca74c81b09d9a57b5b5 jessie/2.8.11
-
-3.0: git://github.com/arangodb/arangodb-docker@b71073b2e36acff7d0660b7f73e659f16facbf99 jessie/3.0.10
-3.0.10: git://github.com/arangodb/arangodb-docker@b71073b2e36acff7d0660b7f73e659f16facbf99 jessie/3.0.10
-latest: git://github.com/arangodb/arangodb-docker@b71073b2e36acff7d0660b7f73e659f16facbf99 jessie/3.0.10
+3.2: https://github.com/arangodb/arangodb-docker@a921ff4451f6cf1c8c426438d43a40c42f8a3e3e stretch/3.2.3
+3.2.3: https://github.com/arangodb/arangodb-docker@a921ff4451f6cf1c8c426438d43a40c42f8a3e3e stretch/3.2.3
+latest: https://github.com/arangodb/arangodb-docker@a921ff4451f6cf1c8c426438d43a40c42f8a3e3e stretch/3.2.3

+ 13 - 12
library/backdrop

@@ -1,15 +1,16 @@
 # maintainer: Mike Pirog <[email protected]> (@pirog)
+# maintainer: Geoff St. Pierre <[email protected]> (@serundeputy)
 
-1.5.1: git://github.com/backdrop-ops/backdrop-docker@b15a1b4b376ef28ba10f4625be32e6fff2e1f3b7 1/apache
-1.5: git://github.com/backdrop-ops/backdrop-docker@b15a1b4b376ef28ba10f4625be32e6fff2e1f3b7 1/apache
-1: git://github.com/backdrop-ops/backdrop-docker@b15a1b4b376ef28ba10f4625be32e6fff2e1f3b7 1/apache
-1.5.0-apache: git://github.com/backdrop-ops/backdrop-docker@b15a1b4b376ef28ba10f4625be32e6fff2e1f3b7 1/apache
-1.5-apache: git://github.com/backdrop-ops/backdrop-docker@b15a1b4b376ef28ba10f4625be32e6fff2e1f3b7 1/apache
-1-apache: git://github.com/backdrop-ops/backdrop-docker@b15a1b4b376ef28ba10f4625be32e6fff2e1f3b7 1/apache
-apache: git://github.com/backdrop-ops/backdrop-docker@b15a1b4b376ef28ba10f4625be32e6fff2e1f3b7 1/apache
-latest: git://github.com/backdrop-ops/backdrop-docker@b15a1b4b376ef28ba10f4625be32e6fff2e1f3b7 1/apache
+1.7.2: git://github.com/backdrop-ops/backdrop-docker@bb4107d27e7e4c4968826c1e26a5c504d3e03276 1/apache
+1.7: git://github.com/backdrop-ops/backdrop-docker@bb4107d27e7e4c4968826c1e26a5c504d3e03276 1/apache
+1: git://github.com/backdrop-ops/backdrop-docker@bb4107d27e7e4c4968826c1e26a5c504d3e03276 1/apache
+1.7.2-apache: git://github.com/backdrop-ops/backdrop-docker@bb4107d27e7e4c4968826c1e26a5c504d3e03276 1/apache
+1.7-apache: git://github.com/backdrop-ops/backdrop-docker@bb4107d27e7e4c4968826c1e26a5c504d3e03276 1/apache
+1-apache: git://github.com/backdrop-ops/backdrop-docker@bb4107d27e7e4c4968826c1e26a5c504d3e03276 1/apache
+apache: git://github.com/backdrop-ops/backdrop-docker@bb4107d27e7e4c4968826c1e26a5c504d3e03276 1/apache
+latest: git://github.com/backdrop-ops/backdrop-docker@bb4107d27e7e4c4968826c1e26a5c504d3e03276 1/apache
 
-1.5.1-fpm: git://github.com/backdrop-ops/backdrop-docker@b15a1b4b376ef28ba10f4625be32e6fff2e1f3b7 1/fpm
-1.5-fpm: git://github.com/backdrop-ops/backdrop-docker@b15a1b4b376ef28ba10f4625be32e6fff2e1f3b7 1/fpm
-1-fpm: git://github.com/backdrop-ops/backdrop-docker@b15a1b4b376ef28ba10f4625be32e6fff2e1f3b7 1/fpm
-fpm: git://github.com/backdrop-ops/backdrop-docker@b15a1b4b376ef28ba10f4625be32e6fff2e1f3b7 1/fpm
+1.7.2-fpm: git://github.com/backdrop-ops/backdrop-docker@bb4107d27e7e4c4968826c1e26a5c504d3e03276 1/fpm
+1.7-fpm: git://github.com/backdrop-ops/backdrop-docker@bb4107d27e7e4c4968826c1e26a5c504d3e03276 1/fpm
+1-fpm: git://github.com/backdrop-ops/backdrop-docker@bb4107d27e7e4c4968826c1e26a5c504d3e03276 1/fpm
+fpm: git://github.com/backdrop-ops/backdrop-docker@bb4107d27e7e4c4968826c1e26a5c504d3e03276 1/fpm

+ 9 - 9
library/bash

@@ -3,34 +3,34 @@
 Maintainers: Tianon Gravi <[email protected]> (@tianon)
 GitRepo: https://github.com/tianon/docker-bash.git
 
-Tags: 4.4.0, 4.4, 4, latest
-GitCommit: 4813d8692c050fab37ce67f205977b11c4eea42c
+Tags: 4.4.12, 4.4, 4, latest
+GitCommit: 75358344e900aa56e64722b2241a6bcd39ca67ee
 Directory: 4.4
 
 Tags: 4.3.48, 4.3
-GitCommit: 2f7c9c45567b18b74c321f0ff1e460ae1117a9b5
+GitCommit: 75358344e900aa56e64722b2241a6bcd39ca67ee
 Directory: 4.3
 
 Tags: 4.2.53, 4.2
-GitCommit: 4813d8692c050fab37ce67f205977b11c4eea42c
+GitCommit: 75358344e900aa56e64722b2241a6bcd39ca67ee
 Directory: 4.2
 
 Tags: 4.1.17, 4.1
-GitCommit: 4813d8692c050fab37ce67f205977b11c4eea42c
+GitCommit: 75358344e900aa56e64722b2241a6bcd39ca67ee
 Directory: 4.1
 
 Tags: 4.0.44, 4.0
-GitCommit: 4813d8692c050fab37ce67f205977b11c4eea42c
+GitCommit: 75358344e900aa56e64722b2241a6bcd39ca67ee
 Directory: 4.0
 
 Tags: 3.2.57, 3.2, 3
-GitCommit: 4813d8692c050fab37ce67f205977b11c4eea42c
+GitCommit: 75358344e900aa56e64722b2241a6bcd39ca67ee
 Directory: 3.2
 
 Tags: 3.1.23, 3.1
-GitCommit: 4813d8692c050fab37ce67f205977b11c4eea42c
+GitCommit: 75358344e900aa56e64722b2241a6bcd39ca67ee
 Directory: 3.1
 
 Tags: 3.0.22, 3.0
-GitCommit: 0fb93762d52d5f73ea53557706f19a255ef990d1
+GitCommit: 75358344e900aa56e64722b2241a6bcd39ca67ee
 Directory: 3.0

+ 4 - 3
library/bonita

@@ -1,7 +1,8 @@
 # maintainer: Jérémy Jacquier-Roux <[email protected]> (@JeremJR)
 # maintainer: Guillaume Rosinosky <[email protected]> (@guillaumerosinosky)
 # maintainer: Truc Nguyen <[email protected]> (@tnguyen1)
+# maintainer: Laurent Leseigneur <[email protected]> (@laurentleseigneur)
 
-7.2.4: git://github.com/Bonitasoft-Community/docker_bonita@c8d6cbb007b77a9ce5b22a7e874608962f863e99 7.2
-7.3.3: git://github.com/Bonitasoft-Community/docker_bonita@19d78ec0f212891e97814b2db30891b9b280f7e5 7.3
-latest: git://github.com/Bonitasoft-Community/docker_bonita@19d78ec0f212891e97814b2db30891b9b280f7e5 7.3
+7.4.3: git://github.com/Bonitasoft-Community/docker_bonita@5e4d4c6d86a90b2f7639215e4098097200a8751a 7.4
+7.5.4: git://github.com/Bonitasoft-Community/docker_bonita@3d28a037ecf87d6b710b1debe43ccf7fc31282e2 7.5
+latest: git://github.com/Bonitasoft-Community/docker_bonita@3d28a037ecf87d6b710b1debe43ccf7fc31282e2 7.5

+ 80 - 41
library/buildpack-deps

@@ -1,101 +1,140 @@
-# this file is generated via https://github.com/docker-library/buildpack-deps/blob/974c358f7d1b545fbfe388dec9d149aea1b8116f/generate-stackbrew-library.sh
+# this file is generated via https://github.com/docker-library/buildpack-deps/blob/7bbf2f06c74e0a8ca54c97f5a0f0b729b39011df/generate-stackbrew-library.sh
 
 Maintainers: Tianon Gravi <[email protected]> (@tianon),
              Joseph Ferguson <[email protected]> (@yosifkit)
 GitRepo: https://github.com/docker-library/buildpack-deps.git
 
-Tags: jessie-curl, curl
-GitCommit: a0a59c61102e8b079d568db69368fb89421f75f2
+Tags: artful-curl
+Architectures: amd64, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: 36018aca7e9637c9c04ff623625e59de12d7f161
+Directory: artful/curl
+
+Tags: artful-scm
+Architectures: amd64, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: 36018aca7e9637c9c04ff623625e59de12d7f161
+Directory: artful/scm
+
+Tags: artful
+Architectures: amd64, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: 5d86449454958f224035b5b200bfd3be9c088ff3
+Directory: artful
+
+Tags: buster-curl
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: 72021102be2a05177d2c01e466495ba1c9d0b4f5
+Directory: buster/curl
+
+Tags: buster-scm
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: 99a1c33fda559272e9322b02a5d778bbd04154e7
+Directory: buster/scm
+
+Tags: buster
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: 5d86449454958f224035b5b200bfd3be9c088ff3
+Directory: buster
+
+Tags: jessie-curl
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: 9f60e19008458220114f1a0b6cd3710f1015d402
 Directory: jessie/curl
 
-Tags: jessie-scm, scm
+Tags: jessie-scm
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
 GitCommit: 1845b3f918f69b4c97912b0d4d68a5658458e84f
 Directory: jessie/scm
 
-Tags: jessie, latest
-GitCommit: 11492c68d993221fd5cd4d8a980354634fc165dd
+Tags: jessie
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: 5d86449454958f224035b5b200bfd3be9c088ff3
 Directory: jessie
 
-Tags: precise-curl
-GitCommit: af914a5bde2a749884177393c8140384048dc5f9
-Directory: precise/curl
-
-Tags: precise-scm
-GitCommit: 1845b3f918f69b4c97912b0d4d68a5658458e84f
-Directory: precise/scm
-
-Tags: precise
-GitCommit: 11492c68d993221fd5cd4d8a980354634fc165dd
-Directory: precise
-
 Tags: sid-curl
-GitCommit: a0a59c61102e8b079d568db69368fb89421f75f2
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: 9f60e19008458220114f1a0b6cd3710f1015d402
 Directory: sid/curl
 
 Tags: sid-scm
-GitCommit: 1845b3f918f69b4c97912b0d4d68a5658458e84f
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: 99a1c33fda559272e9322b02a5d778bbd04154e7
 Directory: sid/scm
 
 Tags: sid
-GitCommit: 11492c68d993221fd5cd4d8a980354634fc165dd
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: 5d86449454958f224035b5b200bfd3be9c088ff3
 Directory: sid
 
-Tags: stretch-curl
-GitCommit: c7478e564dd5dc063cdb0231764379a6916fe525
+Tags: stretch-curl, curl
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: 9f60e19008458220114f1a0b6cd3710f1015d402
 Directory: stretch/curl
 
-Tags: stretch-scm
+Tags: stretch-scm, scm
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
 GitCommit: 1845b3f918f69b4c97912b0d4d68a5658458e84f
 Directory: stretch/scm
 
-Tags: stretch
-GitCommit: 11492c68d993221fd5cd4d8a980354634fc165dd
+Tags: stretch, latest
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: 5d86449454958f224035b5b200bfd3be9c088ff3
 Directory: stretch
 
 Tags: trusty-curl
-GitCommit: af914a5bde2a749884177393c8140384048dc5f9
+Architectures: amd64, arm32v7, arm64v8, i386, ppc64le
+GitCommit: 9f60e19008458220114f1a0b6cd3710f1015d402
 Directory: trusty/curl
 
 Tags: trusty-scm
+Architectures: amd64, arm32v7, arm64v8, i386, ppc64le
 GitCommit: 1845b3f918f69b4c97912b0d4d68a5658458e84f
 Directory: trusty/scm
 
 Tags: trusty
-GitCommit: 11492c68d993221fd5cd4d8a980354634fc165dd
+Architectures: amd64, arm32v7, arm64v8, i386, ppc64le
+GitCommit: 5d86449454958f224035b5b200bfd3be9c088ff3
 Directory: trusty
 
 Tags: wheezy-curl
-GitCommit: a0a59c61102e8b079d568db69368fb89421f75f2
+Architectures: amd64, arm32v5, arm32v7, i386
+GitCommit: 9f60e19008458220114f1a0b6cd3710f1015d402
 Directory: wheezy/curl
 
 Tags: wheezy-scm
+Architectures: amd64, arm32v5, arm32v7, i386
 GitCommit: 1845b3f918f69b4c97912b0d4d68a5658458e84f
 Directory: wheezy/scm
 
 Tags: wheezy
-GitCommit: 11492c68d993221fd5cd4d8a980354634fc165dd
+Architectures: amd64, arm32v5, arm32v7, i386
+GitCommit: 5d86449454958f224035b5b200bfd3be9c088ff3
 Directory: wheezy
 
 Tags: xenial-curl
-GitCommit: 2da658b9a1b91fa61d63ffad2ea52685cac6c702
+Architectures: amd64, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: 9f60e19008458220114f1a0b6cd3710f1015d402
 Directory: xenial/curl
 
 Tags: xenial-scm
+Architectures: amd64, arm32v7, arm64v8, i386, ppc64le, s390x
 GitCommit: 2da658b9a1b91fa61d63ffad2ea52685cac6c702
 Directory: xenial/scm
 
 Tags: xenial
-GitCommit: 11492c68d993221fd5cd4d8a980354634fc165dd
+Architectures: amd64, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: 5d86449454958f224035b5b200bfd3be9c088ff3
 Directory: xenial
 
-Tags: yakkety-curl
-GitCommit: a94a81caf4d56853baade2cdd794dbe0c93396b2
-Directory: yakkety/curl
+Tags: zesty-curl
+Architectures: amd64, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: 9f60e19008458220114f1a0b6cd3710f1015d402
+Directory: zesty/curl
 
-Tags: yakkety-scm
-GitCommit: a94a81caf4d56853baade2cdd794dbe0c93396b2
-Directory: yakkety/scm
+Tags: zesty-scm
+Architectures: amd64, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: 9aa327dcc582d5384affbc5a19672e3077489e97
+Directory: zesty/scm
 
-Tags: yakkety
-GitCommit: a94a81caf4d56853baade2cdd794dbe0c93396b2
-Directory: yakkety
+Tags: zesty
+Architectures: amd64, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: 5d86449454958f224035b5b200bfd3be9c088ff3
+Directory: zesty

+ 44 - 9
library/busybox

@@ -1,19 +1,54 @@
-# this file is generated via https://github.com/docker-library/busybox/blob/e9f53b4c228785d94b53d5aafe46eeb089fe52fe/generate-stackbrew-library.sh
+# this file is generated via https://github.com/docker-library/busybox/blob/4a92cf317f8c3dfac06c79484f4f3e34d83256e3/generate-stackbrew-library.sh
 
 Maintainers: Tianon Gravi <[email protected]> (@tianon),
              Joseph Ferguson <[email protected]> (@yosifkit),
              Jérôme Petazzoni <[email protected]> (@jpetazzo)
 GitRepo: https://github.com/docker-library/busybox.git
-GitFetch: refs/heads/dist
+GitCommit: 4a92cf317f8c3dfac06c79484f4f3e34d83256e3
+# https://github.com/docker-library/busybox/tree/dist-amd64
+amd64-GitFetch: refs/heads/dist-amd64
+amd64-GitCommit: 0d5f38edcc90e99c3288df859cbc27d72f2b5e88
+# https://github.com/docker-library/busybox/tree/dist-arm32v5
+arm32v5-GitFetch: refs/heads/dist-arm32v5
+arm32v5-GitCommit: b6e67ee942f0ecae7819d31604ada99f1a408e8d
+# https://github.com/docker-library/busybox/tree/dist-arm32v6
+arm32v6-GitFetch: refs/heads/dist-arm32v6
+arm32v6-GitCommit: 757c14ea6d0b4f9b6045c34c9670e2c943c42c21
+# https://github.com/docker-library/busybox/tree/dist-arm32v7
+arm32v7-GitFetch: refs/heads/dist-arm32v7
+arm32v7-GitCommit: aee4ce152d20ef71b2521e7599055e64b2e0a874
+# https://github.com/docker-library/busybox/tree/dist-arm64v8
+arm64v8-GitFetch: refs/heads/dist-arm64v8
+arm64v8-GitCommit: 23fbd9c43e0f4bec7605091bfba23db278c367ac
+# https://github.com/docker-library/busybox/tree/dist-i386
+i386-GitFetch: refs/heads/dist-i386
+i386-GitCommit: 13b3f91d668f61470546573f0804f67ea24dd7cc
+# https://github.com/docker-library/busybox/tree/dist-ppc64le
+ppc64le-GitFetch: refs/heads/dist-ppc64le
+ppc64le-GitCommit: ca0b6563d934175967ca9a1a0fd24eab7550db60
+# https://github.com/docker-library/busybox/tree/dist-s390x
+s390x-GitFetch: refs/heads/dist-s390x
+s390x-GitCommit: ab8a925d278a68cf755a24e61a1f571d50535da1
 
-Tags: 1.25.1-glibc, 1.25-glibc, 1-glibc, glibc
-GitCommit: ad6b0303b320f64e63fef9291fcac5a4742c0855
+Tags: 1.27.2-uclibc, 1.27-uclibc, 1-uclibc, uclibc
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386
+Directory: uclibc
+
+Tags: 1.27.2-glibc, 1.27-glibc, 1-glibc, glibc
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
 Directory: glibc
 
-Tags: 1.25.1-musl, 1.25-musl, 1-musl, musl
-GitCommit: ad6b0303b320f64e63fef9291fcac5a4742c0855
+Tags: 1.27.2-musl, 1.27-musl, 1-musl, musl
+Architectures: amd64, arm32v6, arm64v8, i386, ppc64le, s390x
 Directory: musl
 
-Tags: 1.25.1-uclibc, 1.25-uclibc, 1-uclibc, uclibc, 1.25.1, 1.25, 1, latest
-GitCommit: ad6b0303b320f64e63fef9291fcac5a4742c0855
-Directory: uclibc
+Tags: 1.27.2, 1.27, 1, latest
+Architectures: amd64, arm32v5, arm32v6, arm32v7, arm64v8, i386, ppc64le, s390x
+amd64-Directory: uclibc
+arm32v5-Directory: uclibc
+arm32v6-Directory: musl
+arm32v7-Directory: uclibc
+arm64v8-Directory: uclibc
+i386-Directory: uclibc
+ppc64le-Directory: glibc
+s390x-Directory: glibc

+ 14 - 10
library/cassandra

@@ -1,21 +1,25 @@
-# this file is generated via https://github.com/docker-library/cassandra/blob/7832a56e4da025d9d87db6cab5c056564995958c/generate-stackbrew-library.sh
+# this file is generated via https://github.com/docker-library/cassandra/blob/e3667b174ec7705ee383c98a5dab78789be3ff86/generate-stackbrew-library.sh
 
 Maintainers: Tianon Gravi <[email protected]> (@tianon),
              Joseph Ferguson <[email protected]> (@yosifkit)
 GitRepo: https://github.com/docker-library/cassandra.git
 
-Tags: 2.1.16, 2.1
-GitCommit: 3204fb896811b4d20527b8d4a509d65189fd6913
+Tags: 2.1.18, 2.1
+Architectures: amd64, i386
+GitCommit: ca3c9df03cab318d34377bba0610c741253b0466
 Directory: 2.1
 
-Tags: 2.2.8, 2.2, 2
-GitCommit: ef57ef961003e27469b86178f0b4d184bb64d82e
+Tags: 2.2.10, 2.2, 2
+Architectures: amd64, i386
+GitCommit: ca3c9df03cab318d34377bba0610c741253b0466
 Directory: 2.2
 
-Tags: 3.0.9, 3.0
-GitCommit: ef57ef961003e27469b86178f0b4d184bb64d82e
+Tags: 3.0.14, 3.0
+Architectures: amd64, arm64v8, i386, ppc64le
+GitCommit: ca3c9df03cab318d34377bba0610c741253b0466
 Directory: 3.0
 
-Tags: 3.9, 3, latest
-GitCommit: ce8566d1ce825d2d0e16b2b0b76befed1defe62c
-Directory: 3.9
+Tags: 3.11.0, 3.11, 3, latest
+Architectures: amd64, arm64v8, i386, ppc64le
+GitCommit: ca3c9df03cab318d34377bba0610c741253b0466
+Directory: 3.11

+ 0 - 13
library/celery

@@ -1,13 +0,0 @@
-# this file is generated via https://github.com/docker-library/celery/blob/2b56f641be3c38c4367fa7501268b43398199922/generate-stackbrew-library.sh
-
-Maintainers: Tianon Gravi <[email protected]> (@tianon),
-             Joseph Ferguson <[email protected]> (@yosifkit)
-GitRepo: https://github.com/docker-library/celery.git
-
-Tags: 4.0.0rc7, 4.0, 4
-GitCommit: b09801f4d59adda61b58d4c0d90c1d10a717dd9b
-Directory: 4.0
-
-Tags: 3.1.25, 3.1, 3, latest
-GitCommit: e6b17d6339f3cf26a0bfd7083cd2ae926f6e5130
-Directory: 3.1

+ 16 - 9
library/centos

@@ -5,15 +5,22 @@ Constraints: !aufs
 
 Tags: latest, centos7, 7
 GitFetch: refs/heads/CentOS-7
-GitCommit: 155416b523b3353f97015f1942bab8152992a689
+GitCommit: 16dab97b0ce72b1db7a2f9b02c76e452cb0a63cb
+arm64v8-GitFetch: refs/heads/CentOS-7-aarch64
+arm64v8-GitCommit: d8521aa559c767d815e9bb05f7d05ea8ab781930
+Architectures: amd64, arm64v8
 
 Tags: centos6, 6
 GitFetch: refs/heads/CentOS-6
-GitCommit: 83a75fbb40f80935d91b876115704f6e12334575
+GitCommit: 4921b2bfbe7477feb2d6d35c8ce82c08153ab606
 
-Tags: centos5, 5
-GitFetch: refs/heads/CentOS-5
-GitCommit: 4bf8330498e1c10cf365aff31d2a8a5c3254c2cf
+Tags: centos7.4.1708, 7.4.1708
+GitFetch: refs/heads/CentOS-7.4.1708
+GitCommit: 66add29c188e42d4d855f4d4acdb2b73d547edb6
+
+Tags: centos7.3.1611, 7.3.1611
+GitFetch: refs/heads/CentOS-7.3.1611
+GitCommit: 5bbaef9f60ab9e3eeb61acec631c2d91f8714fff
 
 Tags: centos7.2.1511, 7.2.1511
 GitFetch: refs/heads/CentOS-7.2.1511
@@ -27,6 +34,10 @@ Tags: centos7.0.1406, 7.0.1406
 GitFetch: refs/heads/CentOS-7.0.1406
 GitCommit: f1d1e0bd83baef08e257da50e6fb446e4dd1b90c
 
+Tags: centos6.9, 6.9
+GitFetch: refs/heads/CentOS-6.9
+GitCommit: 4f329fe087b0152df26344cecee9ba30b03b1a7b
+
 Tags: centos6.8, 6.8
 GitFetch: refs/heads/CentOS-6.8
 GitCommit: f32666d2af356ed6835942ed753a4970e18bca94
@@ -38,7 +49,3 @@ GitCommit: d0b72df83f49da844f88aabebe3826372f675370
 Tags: centos6.6, 6.6
 GitFetch: refs/heads/CentOS-6.6
 GitCommit: 8911843d9a6cc71aadd81e491f94618aded94f30
-
-Tags: centos5.11, 5.11
-GitFetch: refs/heads/CentOS-5.11
-GitCommit: 2d0554464ae19f4fd70d1b540c8968dbe872797b

+ 6 - 6
library/chronograf

@@ -1,11 +1,11 @@
 Maintainers: Jonathan A. Sternberg <[email protected]> (@jsternberg)
 
-Tags: 0.13, 0.13.0, latest
+Tags: 1.3, 1.3.8, 1.3.8.1, latest
 GitRepo: git://github.com/influxdata/influxdata-docker
-GitCommit: 22b661b4c141d237669f94e4740f234b7be43a7b
-Directory: chronograf/0.13
+GitCommit: a87af8785e2ecfe6b7e92254d90d1c45707e6051
+Directory: chronograf/1.3
 
-Tags: 1.0.0-rc1
+Tags: 1.3-alpine, 1.3.8-alpine, 1.3.8.1-alpine, alpine
 GitRepo: git://github.com/influxdata/influxdata-docker
-GitCommit: 22b661b4c141d237669f94e4740f234b7be43a7b
-Directory: chronograf/1.0
+GitCommit: a87af8785e2ecfe6b7e92254d90d1c45707e6051
+Directory: chronograf/1.3/alpine

+ 1 - 1
library/cirros

@@ -1,4 +1,4 @@
-# maintainer: Eric Windisch <[email protected]> (@ewindisch)
+# maintainer: Erica Windisch <[email protected]> (@ewindisch)
 # Supporting latest & -1 stable releases of CirrOS.
 
 latest: git://github.com/ewindisch/docker-cirros@fd9aa114c465237518535d3545d4f9c4bc1d0aa5

+ 3 - 3
library/clearlinux

@@ -1,4 +1,4 @@
-# maintainer: William Douglas <[email protected]>
+# maintainer: William Douglas <[email protected]> (@bryteise)
 
-latest: git://github.com/clearlinux/docker-brew-clearlinux@f6a54bbf4b1b63f0549b81ba092828ce699f3878
-base: git://github.com/clearlinux/docker-brew-clearlinux@f6a54bbf4b1b63f0549b81ba092828ce699f3878
+latest: git://github.com/clearlinux/docker-brew-clearlinux@1856b9f9d8340774f4a77171bac9e1476fc0b8c1
+base: git://github.com/clearlinux/docker-brew-clearlinux@1856b9f9d8340774f4a77171bac9e1476fc0b8c1

+ 26 - 12
library/clojure

@@ -1,12 +1,26 @@
-# maintainer: Paul Lam <[email protected]> (@Quantisan)
-# maintainer: Wes Morgan <[email protected]> (@cap10morgan)
-
-latest: git://github.com/Quantisan/docker-clojure@c77c13529de02183433da15e8227eba63cc96724
-onbuild: git://github.com/Quantisan/docker-clojure@c77c13529de02183433da15e8227eba63cc96724 onbuild
-alpine: git://github.com/Quantisan/docker-clojure@c77c13529de02183433da15e8227eba63cc96724 alpine
-alpine-onbuild: git://github.com/Quantisan/docker-clojure@c77c13529de02183433da15e8227eba63cc96724 alpine-onbuild
-
-lein-2.7.1: git://github.com/Quantisan/docker-clojure@c77c13529de02183433da15e8227eba63cc96724
-lein-2.7.1-onbuild: git://github.com/Quantisan/docker-clojure@c77c13529de02183433da15e8227eba63cc96724 onbuild
-lein-2.7.1-alpine: git://github.com/Quantisan/docker-clojure@c77c13529de02183433da15e8227eba63cc96724 alpine
-lein-2.7.1-alpine-onbuild: git://github.com/Quantisan/docker-clojure@c77c13529de02183433da15e8227eba63cc96724 alpine-onbuild
+Maintainers: Paul Lam <[email protected]> (@Quantisan),
+             Wes Morgan <[email protected]> (@cap10morgan)
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
+GitRepo: https://github.com/Quantisan/docker-clojure.git
+GitCommit: 54d3dcd9756fb53c489eb9cb8debd80a1a5f6430
+
+Tags: lein-2.7.1, lein, latest
+Directory: debian/lein
+
+Tags: lein-2.7.1-onbuild, lein-onbuild, onbuild
+Directory: debian/lein/onbuild
+
+Tags: lein-2.7.1-alpine, lein-alpine, alpine
+Architectures: amd64
+Directory: alpine/lein
+
+Tags: lein-2.7.1-alpine-onbuild, lein-alpine-onbuild, alpine-onbuild
+Architectures: amd64
+Directory: alpine/lein/onbuild
+
+Tags: boot-2.7.2, boot
+Directory: debian/boot
+
+Tags: boot-2.7.2-alpine, boot-alpine
+Architectures: amd64
+Directory: alpine/boot

+ 12 - 0
library/composer

@@ -0,0 +1,12 @@
+# this file was generated using https://github.com/composer/docker/blob/0759dcda9eb27ee6467166b658de3e03dea4e732/generate-manifest.sh
+
+Maintainers: Composer (@composer), Rob Bast (@alcohol)
+GitRepo: https://github.com/composer/docker.git
+
+Tags: 1.5.2, 1.5, 1, latest
+GitCommit: cbfc849e710828ff5b0cf7c0b69b79126c4d5b26
+Directory: 1.5
+
+Tags: 1.4.3, 1.4
+GitCommit: ea0ec1efa4b15f4ad7b809793eecbb76633dcbb8
+Directory: 1.4

+ 2 - 4
library/consul

@@ -1,6 +1,4 @@
 # maintainer: James Phillips <[email protected]> (@slackpad)
 
-latest: git://github.com/hashicorp/docker-consul@470868df3885ad93f45a2c63c648bf119a544fa4 0.X
-0.7.0: git://github.com/hashicorp/docker-consul@470868df3885ad93f45a2c63c648bf119a544fa4 0.X
-v0.7.0: git://github.com/hashicorp/docker-consul@470868df3885ad93f45a2c63c648bf119a544fa4 0.X
-v0.6.4: git://github.com/hashicorp/docker-consul@9a59dc1a87adc164b72ac67bc9e4364a3fc4138d 0.6
+latest: git://github.com/hashicorp/docker-consul@20ea5d641cf0c7e61e695f373b648a45a3ebe151 0.X
+0.9.3: git://github.com/hashicorp/docker-consul@20ea5d641cf0c7e61e695f373b648a45a3ebe151 0.X

+ 10 - 0
library/convertigo

@@ -0,0 +1,10 @@
+Maintainers: Nicolas Albert <[email protected]> (@nicolas-albert), Olivier Picciotto <[email protected]> (@opicciotto)
+GitRepo: https://github.com/convertigo/docker
+
+Tags: 7.4.6, 7.4, latest
+GitCommit: fb5ac90d57ebb78b00fe1bdb306bef7ad268cce5
+Directory: 7.4/7.4.6
+
+Tags: web-connector-7.4.6, web-connector-7.4, web-connector
+GitCommit: fb5ac90d57ebb78b00fe1bdb306bef7ad268cce5
+Directory: 7.4/7.4.6/web-connector

+ 9 - 9
library/couchbase

@@ -1,15 +1,15 @@
 # maintainer: Couchbase Docker Team <[email protected]> (@couchbase)
 
-latest: git://github.com/couchbase/docker@7bc8fe5beebae76f0d27963422057fb570c8ef59 enterprise/couchbase-server/4.5.1
-enterprise: git://github.com/couchbase/docker@7bc8fe5beebae76f0d27963422057fb570c8ef59 enterprise/couchbase-server/4.5.1
-4.5.1: git://github.com/couchbase/docker@7bc8fe5beebae76f0d27963422057fb570c8ef59 enterprise/couchbase-server/4.5.1
-enterprise-4.5.1: git://github.com/couchbase/docker@7bc8fe5beebae76f0d27963422057fb570c8ef59 enterprise/couchbase-server/4.5.1
+latest: git://github.com/couchbase/docker@abdfa74c6281d57974b356731a60b5fa68e14f9f enterprise/couchbase-server/4.6.3
+enterprise: git://github.com/couchbase/docker@abdfa74c6281d57974b356731a60b5fa68e14f9f enterprise/couchbase-server/4.6.3
+4.6.3: git://github.com/couchbase/docker@abdfa74c6281d57974b356731a60b5fa68e14f9f enterprise/couchbase-server/4.6.3
+enterprise-4.6.3: git://github.com/couchbase/docker@abdfa74c6281d57974b356731a60b5fa68e14f9f enterprise/couchbase-server/4.6.3
 
-community: git://github.com/couchbase/docker@7bc8fe5beebae76f0d27963422057fb570c8ef59 community/couchbase-server/4.1.1
-community-4.1.1: git://github.com/couchbase/docker@7bc8fe5beebae76f0d27963422057fb570c8ef59 community/couchbase-server/4.1.1
+community: git://github.com/couchbase/docker@abdfa74c6281d57974b356731a60b5fa68e14f9f community/couchbase-server/4.5.1
+community-4.5.1: git://github.com/couchbase/docker@abdfa74c6281d57974b356731a60b5fa68e14f9f community/couchbase-server/4.5.1
 
-3.1.6: git://github.com/couchbase/docker@7bc8fe5beebae76f0d27963422057fb570c8ef59 enterprise/couchbase-server/3.1.6
-enterprise-3.1.6: git://github.com/couchbase/docker@7bc8fe5beebae76f0d27963422057fb570c8ef59 enterprise/couchbase-server/3.1.6
+3.1.6: git://github.com/couchbase/docker@abdfa74c6281d57974b356731a60b5fa68e14f9f enterprise/couchbase-server/3.1.6
+enterprise-3.1.6: git://github.com/couchbase/docker@abdfa74c6281d57974b356731a60b5fa68e14f9f enterprise/couchbase-server/3.1.6
 
-community-3.1.3: git://github.com/couchbase/docker@7bc8fe5beebae76f0d27963422057fb570c8ef59 community/couchbase-server/3.1.3
+community-3.1.3: git://github.com/couchbase/docker@abdfa74c6281d57974b356731a60b5fa68e14f9f community/couchbase-server/3.1.3
 

+ 11 - 5
library/crate

@@ -5,11 +5,17 @@
 # maintainer: Christian Haudum <[email protected]> (@chaudum)
 # maintainer: Ruslan Kovalov <[email protected]> (@kovrus)
 # maintainer: Claus Matzinger <[email protected]> (@celaus)
+# maintainer: Christian Bader <[email protected]> (@christianbader)
+# maintainer: Mika Naylor <[email protected]> (@autophagy)
 
 # see also https://crate.io
 
-latest: git://github.com/crate/docker-crate@c1fef97dacc607792b0002f8b7bf29761f408438
-0.55: git://github.com/crate/docker-crate@6f946af1ea0e0aefd75dd9fa781572e728cb8c88
-0.55.7: git://github.com/crate/docker-crate@6f946af1ea0e0aefd75dd9fa781572e728cb8c88
-0.56: git://github.com/crate/docker-crate@c1fef97dacc607792b0002f8b7bf29761f408438
-0.56.3: git://github.com/crate/docker-crate@c1fef97dacc607792b0002f8b7bf29761f408438
+latest: git://github.com/crate/docker-crate@e8924e1bd476311cadc92a50ea06b992e0672eb3
+1.0: git://github.com/crate/docker-crate@89e1557944b257c9e56b0e93a458eb6f0238ece3
+1.0.6: git://github.com/crate/docker-crate@89e1557944b257c9e56b0e93a458eb6f0238ece3
+1.1: git://github.com/crate/docker-crate@019830ed59c4b110f8c93f30430d282818ad95ec
+1.1.6: git://github.com/crate/docker-crate@019830ed59c4b110f8c93f30430d282818ad95ec
+2.0: git://github.com/crate/docker-crate@79d51bb263104ccd2d3c57a5d74c16d6f0466d21
+2.0.7: git://github.com/crate/docker-crate@79d51bb263104ccd2d3c57a5d74c16d6f0466d21
+2.1: git://github.com/crate/docker-crate@e8924e1bd476311cadc92a50ea06b992e0672eb3
+2.1.6: git://github.com/crate/docker-crate@e8924e1bd476311cadc92a50ea06b992e0672eb3

+ 1 - 1
library/crux

@@ -1,4 +1,4 @@
-# maintainer: James Mills <[email protected]> (@therealprologic)
+# maintainer: James Mills <[email protected]> (@prologic)
 
 latest: git://github.com/prologic/docker-crux@c614d61c53c05c02a43a34187fa1370db2c61524
 3.1: git://github.com/prologic/docker-crux@c614d61c53c05c02a43a34187fa1370db2c61524

+ 108 - 82
library/debian

@@ -1,126 +1,152 @@
+# tarballs built by debuerreotype
+# see https://github.com/debuerreotype/debuerreotype
+
 Maintainers: Tianon Gravi <[email protected]> (@tianon),
              Paul Tagliamonte <[email protected]> (@paultag)
-GitRepo: https://github.com/tianon/docker-brew-debian.git
-
-# commits: (master..dist-stable)
-#  - 2c836bc 2016-11-04 debootstraps
-
-# commits: (master..dist-unstable)
-#  - 9b1dd4b 2016-11-04 debootstraps
-
-# commits: (master..dist-oldstable)
-#  - 1626bb6 2016-11-04 debootstraps
-
-Tags: 8.6, 8, jessie, latest
-GitFetch: refs/heads/dist-stable
-GitCommit: 2c836bc53feb12f70a07dacaa6256d4d66624f38
+GitRepo: https://github.com/debuerreotype/docker-debian-artifacts.git
+GitCommit: fa5e408fa2e9a74c025f21cbfa2449ea349afd26
+# https://github.com/debuerreotype/docker-debian-artifacts/tree/dist-amd64
+amd64-GitFetch: refs/heads/dist-amd64
+amd64-GitCommit: 97dc072ae1e6c66c1ccc71ead334ce5d5fc201f0
+# https://github.com/debuerreotype/docker-debian-artifacts/tree/dist-arm32v5
+arm32v5-GitFetch: refs/heads/dist-arm32v5
+arm32v5-GitCommit: 38d2cf181e221d0a6f711141f12f8c736c6b3a42
+# https://github.com/debuerreotype/docker-debian-artifacts/tree/dist-arm32v7
+arm32v7-GitFetch: refs/heads/dist-arm32v7
+arm32v7-GitCommit: f2d531efa61c7a75a8d913716941d60177721359
+# https://github.com/debuerreotype/docker-debian-artifacts/tree/dist-arm64v8
+arm64v8-GitFetch: refs/heads/dist-arm64v8
+arm64v8-GitCommit: b8bcc93c8255874ce3235a4fa325af3b17036cb8
+# https://github.com/debuerreotype/docker-debian-artifacts/tree/dist-i386
+i386-GitFetch: refs/heads/dist-i386
+i386-GitCommit: e2e165b29d40fc2fa39ecbe78839ff0142caa4ec
+# https://github.com/debuerreotype/docker-debian-artifacts/tree/dist-ppc64le
+ppc64le-GitFetch: refs/heads/dist-ppc64le
+ppc64le-GitCommit: 4b4b334892988ce15172094b740911b81de851e9
+# https://github.com/debuerreotype/docker-debian-artifacts/tree/dist-s390x
+s390x-GitFetch: refs/heads/dist-s390x
+s390x-GitCommit: 4f46f250ac27924935c2a5db431cbef2f00714dd
+
+# buster -- Debian x.y Testing distribution - Not Released
+Tags: buster, buster-20170907
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
+Directory: buster
+
+Tags: buster-slim
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
+Directory: buster/slim
+
+# experimental -- Experimental packages - not released; use at your own risk.
+Tags: experimental, experimental-20170907
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
+Directory: experimental
+
+# jessie -- Debian 8.9 Released 22 July 2017
+Tags: jessie, jessie-20170907, 8.9, 8
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
 Directory: jessie
 
+Tags: jessie-backports
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
+Directory: jessie/backports
+
 Tags: jessie-slim
-GitFetch: refs/heads/dist-stable
-GitCommit: 2c836bc53feb12f70a07dacaa6256d4d66624f38
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
 Directory: jessie/slim
 
-Tags: jessie-backports
-GitFetch: refs/heads/dist-stable
-GitCommit: 2c836bc53feb12f70a07dacaa6256d4d66624f38
-Directory: jessie/backports
+# oldoldstable -- Debian 7.11 Released 04 June 2016
+Tags: oldoldstable, oldoldstable-20170907
+Architectures: amd64, arm32v5, arm32v7, i386
+Directory: oldoldstable
+
+Tags: oldoldstable-backports
+Architectures: amd64, arm32v5, arm32v7, i386
+Directory: oldoldstable/backports
+
+Tags: oldoldstable-slim
+Architectures: amd64, arm32v5, arm32v7, i386
+Directory: oldoldstable/slim
 
-Tags: oldstable
-GitFetch: refs/heads/dist-oldstable
-GitCommit: 1626bb6698f1cab6e7529a4238717270699a8246
+# oldstable -- Debian 8.9 Released 22 July 2017
+Tags: oldstable, oldstable-20170907
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
 Directory: oldstable
 
+Tags: oldstable-backports
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
+Directory: oldstable/backports
+
 Tags: oldstable-slim
-GitFetch: refs/heads/dist-oldstable
-GitCommit: 1626bb6698f1cab6e7529a4238717270699a8246
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
 Directory: oldstable/slim
 
-Tags: oldstable-backports
-GitFetch: refs/heads/dist-oldstable
-GitCommit: 1626bb6698f1cab6e7529a4238717270699a8246
-Directory: oldstable/backports
+# rc-buggy -- Experimental packages - not released; use at your own risk.
+Tags: rc-buggy, rc-buggy-20170907
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
+Directory: rc-buggy
 
-Tags: sid
-GitFetch: refs/heads/dist-unstable
-GitCommit: 9b1dd4b1594b8df02f7caa739e84b187edaab404
+# sid -- Debian x.y Unstable - Not Released
+Tags: sid, sid-20170907
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
 Directory: sid
 
 Tags: sid-slim
-GitFetch: refs/heads/dist-unstable
-GitCommit: 9b1dd4b1594b8df02f7caa739e84b187edaab404
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
 Directory: sid/slim
 
-Tags: stable
-GitFetch: refs/heads/dist-stable
-GitCommit: 2c836bc53feb12f70a07dacaa6256d4d66624f38
+# stable -- Debian 9.1 Released 22 July 2017
+Tags: stable, stable-20170907
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
 Directory: stable
 
-Tags: stable-slim
-GitFetch: refs/heads/dist-stable
-GitCommit: 2c836bc53feb12f70a07dacaa6256d4d66624f38
-Directory: stable/slim
-
 Tags: stable-backports
-GitFetch: refs/heads/dist-stable
-GitCommit: 2c836bc53feb12f70a07dacaa6256d4d66624f38
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
 Directory: stable/backports
 
-Tags: stretch
-GitFetch: refs/heads/dist-unstable
-GitCommit: 9b1dd4b1594b8df02f7caa739e84b187edaab404
+Tags: stable-slim
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
+Directory: stable/slim
+
+# stretch -- Debian 9.1 Released 22 July 2017
+Tags: stretch, stretch-20170907, 9.1, 9, latest
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
 Directory: stretch
 
+Tags: stretch-backports
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
+Directory: stretch/backports
+
 Tags: stretch-slim
-GitFetch: refs/heads/dist-unstable
-GitCommit: 9b1dd4b1594b8df02f7caa739e84b187edaab404
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
 Directory: stretch/slim
 
-Tags: testing
-GitFetch: refs/heads/dist-unstable
-GitCommit: 9b1dd4b1594b8df02f7caa739e84b187edaab404
+# testing -- Debian x.y Testing distribution - Not Released
+Tags: testing, testing-20170907
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
 Directory: testing
 
 Tags: testing-slim
-GitFetch: refs/heads/dist-unstable
-GitCommit: 9b1dd4b1594b8df02f7caa739e84b187edaab404
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
 Directory: testing/slim
 
-Tags: unstable
-GitFetch: refs/heads/dist-unstable
-GitCommit: 9b1dd4b1594b8df02f7caa739e84b187edaab404
+# unstable -- Debian x.y Unstable - Not Released
+Tags: unstable, unstable-20170907
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
 Directory: unstable
 
 Tags: unstable-slim
-GitFetch: refs/heads/dist-unstable
-GitCommit: 9b1dd4b1594b8df02f7caa739e84b187edaab404
+Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, ppc64le, s390x
 Directory: unstable/slim
 
-Tags: 7.11, 7, wheezy
-GitFetch: refs/heads/dist-oldstable
-GitCommit: 1626bb6698f1cab6e7529a4238717270699a8246
+# wheezy -- Debian 7.11 Released 04 June 2016
+Tags: wheezy, wheezy-20170907, 7.11, 7
+Architectures: amd64, arm32v5, arm32v7, i386
 Directory: wheezy
 
-Tags: wheezy-slim
-GitFetch: refs/heads/dist-oldstable
-GitCommit: 1626bb6698f1cab6e7529a4238717270699a8246
-Directory: wheezy/slim
-
 Tags: wheezy-backports
-GitFetch: refs/heads/dist-oldstable
-GitCommit: 1626bb6698f1cab6e7529a4238717270699a8246
+Architectures: amd64, arm32v5, arm32v7, i386
 Directory: wheezy/backports
 
-# sid + rc-buggy
-Tags: rc-buggy
-GitRepo: https://github.com/tianon/dockerfiles.git
-GitFetch: refs/heads/master
-GitCommit: 22a998f815d55217afa0075411b810b8889ceac1
-Directory: debian/rc-buggy
-
-# unstable + experimental
-Tags: experimental
-GitRepo: https://github.com/tianon/dockerfiles.git
-GitFetch: refs/heads/master
-GitCommit: 22a998f815d55217afa0075411b810b8889ceac1
-Directory: debian/experimental
+Tags: wheezy-slim
+Architectures: amd64, arm32v5, arm32v7, i386
+Directory: wheezy/slim

+ 0 - 21
library/django

@@ -1,21 +0,0 @@
-# this file is generated via https://github.com/docker-library/django/blob/e73a3bd34657b3fb6c87c78e16036efc474ec468/generate-stackbrew-library.sh
-
-Maintainers: Tianon Gravi <[email protected]> (@tianon),
-             Joseph Ferguson <[email protected]> (@yosifkit)
-GitRepo: https://github.com/docker-library/django.git
-
-Tags: 1.10.3-python3, 1.10-python3, 1-python3, python3, 1.10.3, 1.10, 1, latest
-GitCommit: 642cc5e4ccdc2f706d445b072ebc6c4193e22c10
-Directory: 3.4
-
-Tags: python3-onbuild, onbuild
-GitCommit: 4fe080675e4a85ef6ee25c811e9d3d3ef0905794
-Directory: 3.4/onbuild
-
-Tags: 1.10.3-python2, 1.10-python2, 1-python2, python2
-GitCommit: 642cc5e4ccdc2f706d445b072ebc6c4193e22c10
-Directory: 2.7
-
-Tags: python2-onbuild
-GitCommit: cecbb2bbbcb69d1b8358398eaf8d9638e3bdd447
-Directory: 2.7/onbuild

+ 45 - 36
library/docker

@@ -1,41 +1,50 @@
-# this file is generated via https://github.com/docker-library/docker/blob/a7fc73eef011c47cc2518149bc77a4b9bc7f9f41/generate-stackbrew-library.sh
+# this file is generated via https://github.com/docker-library/docker/blob/ce8784112e81f724c96dae8272dd7367d712f3e9/generate-stackbrew-library.sh
 
 Maintainers: Tianon Gravi <[email protected]> (@tianon),
              Joseph Ferguson <[email protected]> (@yosifkit)
 GitRepo: https://github.com/docker-library/docker.git
 
-Tags: 1.12.3, 1.12, 1, latest
-GitCommit: 36e2107fb879d5d5c3dbb5d8d93aeef0a2d45ac8
-Directory: 1.12
-
-Tags: 1.12.3-dind, 1.12-dind, 1-dind, dind
-GitCommit: 5e30187978ad75d0f2ae5fc6c2a0b668bdf16885
-Directory: 1.12/dind
-
-Tags: 1.12.3-git, 1.12-git, 1-git, git
-GitCommit: 746d9052066ccfbcb98df7d9ae71cf05d8877419
-Directory: 1.12/git
-
-Tags: 1.12.3-experimental, 1.12-experimental, 1-experimental, experimental
-GitCommit: 36e2107fb879d5d5c3dbb5d8d93aeef0a2d45ac8
-Directory: 1.12/experimental
-
-Tags: 1.12.3-experimental-dind, 1.12-experimental-dind, 1-experimental-dind, experimental-dind
-GitCommit: 5e30187978ad75d0f2ae5fc6c2a0b668bdf16885
-Directory: 1.12/experimental/dind
-
-Tags: 1.12.3-experimental-git, 1.12-experimental-git, 1-experimental-git, experimental-git
-GitCommit: eb714a73e7e3f87705f468c3c6e9f4e316136bf5
-Directory: 1.12/experimental/git
-
-Tags: 1.11.2, 1.11
-GitCommit: 5e30187978ad75d0f2ae5fc6c2a0b668bdf16885
-Directory: 1.11
-
-Tags: 1.11.2-dind, 1.11-dind
-GitCommit: 5e30187978ad75d0f2ae5fc6c2a0b668bdf16885
-Directory: 1.11/dind
-
-Tags: 1.11.2-git, 1.11-git
-GitCommit: 866c3fbd87e8eeed524fdf19ba2d63288ad49cd2
-Directory: 1.11/git
+Tags: 17.09.0-ce-rc2, 17.09.0-ce, 17.09.0, 17.09-rc, rc, test
+Architectures: amd64
+GitCommit: e90d458a6147f66630e7ad9877d7aa3c6d541414
+Directory: 17.09-rc
+
+Tags: 17.09.0-ce-rc2-dind, 17.09.0-ce-dind, 17.09.0-dind, 17.09-rc-dind, rc-dind, test-dind
+Architectures: amd64
+GitCommit: ce8784112e81f724c96dae8272dd7367d712f3e9
+Directory: 17.09-rc/dind
+
+Tags: 17.09.0-ce-rc2-git, 17.09.0-ce-git, 17.09.0-git, 17.09-rc-git, rc-git, test-git
+Architectures: amd64
+GitCommit: ce8784112e81f724c96dae8272dd7367d712f3e9
+Directory: 17.09-rc/git
+
+Tags: 17.07.0-ce, 17.07.0, 17.07, 17, edge, latest
+Architectures: amd64
+GitCommit: a8f8fa1b57349cc22c80e7d6cbbdb512ffee2bd2
+Directory: 17.07
+
+Tags: 17.07.0-ce-dind, 17.07.0-dind, 17.07-dind, 17-dind, edge-dind, dind
+Architectures: amd64
+GitCommit: a8f8fa1b57349cc22c80e7d6cbbdb512ffee2bd2
+Directory: 17.07/dind
+
+Tags: 17.07.0-ce-git, 17.07.0-git, 17.07-git, 17-git, edge-git, git
+Architectures: amd64
+GitCommit: a8f8fa1b57349cc22c80e7d6cbbdb512ffee2bd2
+Directory: 17.07/git
+
+Tags: 17.06.2-ce, 17.06.2, 17.06, stable
+Architectures: amd64
+GitCommit: b33b5bffb560d4e4148506860d7c6b393315e339
+Directory: 17.06
+
+Tags: 17.06.2-ce-dind, 17.06.2-dind, 17.06-dind, stable-dind
+Architectures: amd64
+GitCommit: e68e4e6ec06c055a95d441144b0e34d0872f2665
+Directory: 17.06/dind
+
+Tags: 17.06.2-ce-git, 17.06.2-git, 17.06-git, stable-git
+Architectures: amd64
+GitCommit: e68e4e6ec06c055a95d441144b0e34d0872f2665
+Directory: 17.06/git

+ 40 - 11
library/drupal

@@ -1,21 +1,50 @@
-# this file is generated via https://github.com/docker-library/drupal/blob/7f849190fd64db8d6b55c05bd52773e50c5f8326/generate-stackbrew-library.sh
+# this file is generated via https://github.com/docker-library/drupal/blob/4cabbdd883753a3b20d826cf5fed5e741291827b/generate-stackbrew-library.sh
 
 Maintainers: Tianon Gravi <[email protected]> (@tianon),
              Joseph Ferguson <[email protected]> (@yosifkit)
 GitRepo: https://github.com/docker-library/drupal.git
 
-Tags: 8.2.2-apache, 8.2-apache, 8-apache, apache, 8.2.2, 8.2, 8, latest
-GitCommit: 9cd16801643ce9a8373bd74c74ff1a1565842795
-Directory: 8.2/apache
+Tags: 8.4.0-rc1-apache, 8.4-rc-apache, rc-apache, 8.4.0-rc1, 8.4-rc, rc
+Architectures: amd64, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: c561323f3add389efbb3826593f3a45fede5d14b
+Directory: 8.4-rc/apache
 
-Tags: 8.2.2-fpm, 8.2-fpm, 8-fpm, fpm
-GitCommit: 9cd16801643ce9a8373bd74c74ff1a1565842795
-Directory: 8.2/fpm
+Tags: 8.4.0-rc1-fpm, 8.4-rc-fpm, rc-fpm
+Architectures: amd64, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: c561323f3add389efbb3826593f3a45fede5d14b
+Directory: 8.4-rc/fpm
 
-Tags: 7.51-apache, 7-apache, 7.51, 7
-GitCommit: 814261d4b2d82854c50746c3e480dd514d5aa1d0
+Tags: 8.4.0-rc1-fpm-alpine, 8.4-rc-fpm-alpine, rc-fpm-alpine
+Architectures: amd64
+GitCommit: c561323f3add389efbb3826593f3a45fede5d14b
+Directory: 8.4-rc/fpm-alpine
+
+Tags: 8.3.7-apache, 8.3-apache, 8-apache, apache, 8.3.7, 8.3, 8, latest
+Architectures: amd64, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: 6eb80c71ff39e076633362adf0dc67dd252f1753
+Directory: 8.3/apache
+
+Tags: 8.3.7-fpm, 8.3-fpm, 8-fpm, fpm
+Architectures: amd64, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: 6eb80c71ff39e076633362adf0dc67dd252f1753
+Directory: 8.3/fpm
+
+Tags: 8.3.7-fpm-alpine, 8.3-fpm-alpine, 8-fpm-alpine, fpm-alpine
+Architectures: amd64
+GitCommit: 6eb80c71ff39e076633362adf0dc67dd252f1753
+Directory: 8.3/fpm-alpine
+
+Tags: 7.56-apache, 7-apache, 7.56, 7
+Architectures: amd64, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: a8e09f524b89b61534f376e45b885d433d867c88
 Directory: 7/apache
 
-Tags: 7.51-fpm, 7-fpm
-GitCommit: 814261d4b2d82854c50746c3e480dd514d5aa1d0
+Tags: 7.56-fpm, 7-fpm
+Architectures: amd64, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: a8e09f524b89b61534f376e45b885d433d867c88
 Directory: 7/fpm
+
+Tags: 7.56-fpm-alpine, 7-fpm-alpine
+Architectures: amd64
+GitCommit: a8e09f524b89b61534f376e45b885d433d867c88
+Directory: 7/fpm-alpine

+ 7 - 0
library/eclipse-mosquitto

@@ -0,0 +1,7 @@
+Maintainers: David Audet <[email protected]> (@daudetCA)
+GitRepo: https://github.com/eclipse/mosquitto.git
+
+Tags: 1.4.12, latest
+GitCommit: 0bb602ed7a89da80d25e6b959a130fdcf0556be5
+GitFetch:  refs/heads/develop
+Directory: docker/1.4.12

+ 7 - 7
library/eggdrop

@@ -2,13 +2,13 @@ Maintainers: Geo Van O <[email protected]> (@vanosg)
 GitRepo: https://github.com/eggheads/eggdrop-docker.git
 
 Tags: develop
-GitCommit: f8d397fb8d6e78720cd3cf930f84bfccfef19b89
-Directory: 1.8
+GitCommit: 39fc15007ed450be1355b8ea39c6bf9a22343004
+Directory: develop
 
-Tags: 1.8, 1.8.0, 1.8.0rc2
-GitCommit: f8d397fb8d6e78720cd3cf930f84bfccfef19b89
-Directory: 1.8rc2
+Tags: 1.8, 1.8.2, stable, latest
+GitCommit: b351e05e1040a1bbd446df3753d9b8a1d0a54673
+Directory: 1.8
 
-Tags: 1.6, 1.6.21, stable, latest
-GitCommit: 87d717b0c05d4c43460a411c9871e9190c94f8bb
+Tags: 1.6, 1.6.21
+GitCommit: 954bb0048b93945aa7fcd98eda0a27b8526f9eaa
 Directory: 1.6

+ 0 - 37
library/elasticsearch

@@ -1,37 +0,0 @@
-# this file is generated via https://github.com/docker-library/elasticsearch/blob/8bb7acf80ebeff0747c998fe6b2275a9cacb3a9a/generate-stackbrew-library.sh
-
-Maintainers: Tianon Gravi <[email protected]> (@tianon),
-             Joseph Ferguson <[email protected]> (@yosifkit)
-GitRepo: https://github.com/docker-library/elasticsearch.git
-
-Tags: 1.6.2, 1.6
-GitCommit: 8347a4697d32878dbacd7086b34f76a9e19113ae
-Directory: 1.6
-
-Tags: 1.7.5, 1.7, 1
-GitCommit: 8347a4697d32878dbacd7086b34f76a9e19113ae
-Directory: 1.7
-
-Tags: 2.0.2, 2.0
-GitCommit: 8347a4697d32878dbacd7086b34f76a9e19113ae
-Directory: 2.0
-
-Tags: 2.1.2, 2.1
-GitCommit: 8347a4697d32878dbacd7086b34f76a9e19113ae
-Directory: 2.1
-
-Tags: 2.2.2, 2.2
-GitCommit: 8347a4697d32878dbacd7086b34f76a9e19113ae
-Directory: 2.2
-
-Tags: 2.3.5, 2.3
-GitCommit: 8347a4697d32878dbacd7086b34f76a9e19113ae
-Directory: 2.3
-
-Tags: 2.4.1, 2.4, 2
-GitCommit: 8347a4697d32878dbacd7086b34f76a9e19113ae
-Directory: 2.4
-
-Tags: 5.0.0, 5.0, 5, latest
-GitCommit: acd142324bdd9b4cb06a8e08bd701b340deaa02d
-Directory: 5.0

+ 23 - 3
library/elixir

@@ -1,13 +1,33 @@
-# this file is generated via https://github.com/c0b/docker-elixir/blob/d8d656d7c0dc9dd2956a22276c93cb97568ea6d4/generate-stackbrew-library.sh
+# this file is generated via https://github.com/c0b/docker-elixir/blob/a57ae22bc9505ccdc7662f2556143e1048361d47/generate-stackbrew-library.sh
 
 Maintainers: Mr C0B <[email protected]> (@c0b)
 GitRepo: https://github.com/c0b/docker-elixir.git
 
-Tags: 1.3.4, 1.3, latest
+Tags: 1.5.1, 1.5, latest
+GitCommit: 162a4ccf85fa7ebcefdbf43903099b0907f6babd
+Directory: 1.5
+
+Tags: 1.5.1-slim, 1.5-slim, slim
+GitCommit: 162a4ccf85fa7ebcefdbf43903099b0907f6babd
+Directory: 1.5/slim
+
+Tags: 1.5.1-alpine, 1.5-alpine, alpine
+GitCommit: 162a4ccf85fa7ebcefdbf43903099b0907f6babd
+Directory: 1.5/alpine
+
+Tags: 1.4.5, 1.4
+GitCommit: 8f1888ae05506b9ad12e1b97f084a15e7588f442
+Directory: 1.4
+
+Tags: 1.4.5-slim, 1.4-slim
+GitCommit: 8f1888ae05506b9ad12e1b97f084a15e7588f442
+Directory: 1.4/slim
+
+Tags: 1.3.4, 1.3
 GitCommit: d8d656d7c0dc9dd2956a22276c93cb97568ea6d4
 Directory: 1.3
 
-Tags: 1.3.4-slim, 1.3-slim, slim
+Tags: 1.3.4-slim, 1.3-slim
 GitCommit: d8d656d7c0dc9dd2956a22276c93cb97568ea6d4
 Directory: 1.3/slim
 

+ 32 - 19
library/erlang

@@ -1,36 +1,49 @@
-# this file is generated via https://github.com/c0b/docker-erlang-otp/blob/65d3a1ff75dfe46467b2fc93a0fd6f5009ba02f4/generate-stackbrew-library.sh
+# this file is generated via https://github.com/c0b/docker-erlang-otp/blob/e7d145c915458e5bbb857a57c9aad7125f95a853/generate-stackbrew-library.sh
 
 Maintainers: Mr C0B <[email protected]> (@c0b)
 GitRepo: https://github.com/c0b/docker-erlang-otp.git
 
-Tags: 19.1.5, 19.1, 19, latest
-GitCommit: 5e1399b65a48c81595b5ec58b0e3f70444c3067f
+Tags: 20.0.4, 20.0, 20, latest
+Architectures: amd64, arm32v7, arm64v8, i386, s390x, ppc64le
+GitCommit: e7d145c915458e5bbb857a57c9aad7125f95a853
+Directory: 20
+
+Tags: 20.0.4-slim, 20.0-slim, 20-slim, slim
+Architectures: amd64, arm32v7, arm64v8, i386, s390x, ppc64le
+GitCommit: e7d145c915458e5bbb857a57c9aad7125f95a853
+Directory: 20/slim
+
+Tags: 20.0.4-alpine, 20.0-alpine, 20-alpine, alpine
+Architectures: amd64
+GitCommit: e7d145c915458e5bbb857a57c9aad7125f95a853
+Directory: 20/alpine
+
+Tags: 19.3.6.2, 19.3.6, 19.3, 19
+Architectures: amd64, arm32v7, arm64v8, i386, s390x
+GitCommit: e7d145c915458e5bbb857a57c9aad7125f95a853
 Directory: 19
 
-Tags: 19.1.5-slim, 19.1-slim, 19-slim, slim
-GitCommit: 5e1399b65a48c81595b5ec58b0e3f70444c3067f
+Tags: 19.3.6.2-slim, 19.3.6-slim, 19.3-slim, 19-slim
+Architectures: amd64, arm32v7, arm64v8, i386, s390x
+GitCommit: e7d145c915458e5bbb857a57c9aad7125f95a853
 Directory: 19/slim
 
-Tags: 19.1.5-onbuild, 19.1-onbuild, 19-onbuild, onbuild
-GitCommit: 9be249effe93e3c61fa0749078e55ef8d050a16e
-Directory: 19/onbuild
-
-Tags: 18.3.4.4, 18.3.4, 18.3, 18
-GitCommit: 7f5e7b4768136caa5f15e0b84d6b503fa430ef7b
+Tags: 18.3.4.5, 18.3.4, 18.3, 18
+Architectures: amd64, arm32v7, arm64v8, i386, s390x
+GitCommit: e7d145c915458e5bbb857a57c9aad7125f95a853
 Directory: 18
 
-Tags: 18.3.4.4-slim, 18.3.4-slim, 18.3-slim, 18-slim
-GitCommit: 7f5e7b4768136caa5f15e0b84d6b503fa430ef7b
+Tags: 18.3.4.5-slim, 18.3.4-slim, 18.3-slim, 18-slim
+Architectures: amd64, arm32v7, arm64v8, i386, s390x
+GitCommit: e7d145c915458e5bbb857a57c9aad7125f95a853
 Directory: 18/slim
 
-Tags: 18.3.4.4-onbuild, 18.3.4-onbuild, 18.3-onbuild, 18-onbuild
-GitCommit: 20e41464075dc0fc76709be77701530eddb6fe33
-Directory: 18/onbuild
-
 Tags: 17.5.6.9, 17.5.6, 17.5, 17
-GitCommit: ea32d5f6f1735f9f55bee04b112166da96eb9c73
+Architectures: amd64, arm32v7, arm64v8, i386, s390x, ppc64le
+GitCommit: e7d145c915458e5bbb857a57c9aad7125f95a853
 Directory: 17
 
 Tags: 17.5.6.9-slim, 17.5.6-slim, 17.5-slim, 17-slim
-GitCommit: ea32d5f6f1735f9f55bee04b112166da96eb9c73
+Architectures: amd64, arm32v7, arm64v8, i386, s390x, ppc64le
+GitCommit: e7d145c915458e5bbb857a57c9aad7125f95a853
 Directory: 17/slim

+ 25 - 17
library/fedora

@@ -3,26 +3,34 @@ Maintainers: Adam Miller <[email protected]> (@maxamillion),
 GitRepo: https://github.com/fedora-cloud/docker-brew-fedora.git
 Constraints: !aufs
 
-Tags: latest, 24
-GitFetch: refs/heads/24
-GitCommit: 1762564a8ddc8448a62e101b0094a9c247ef94f8
+Tags: latest, 26
+Architectures: amd64, arm32v7, arm64v8, ppc64le
+GitFetch: refs/heads/26
+GitCommit: 1cea10502253a1a5b913eb1e59a7dc7482cbc0fa
+amd64-Directory: x86_64/
+arm32v7-Directory: armhfp/
+arm64v8-Directory: aarch64/
+ppc64le-Directory: ppc64le/
 
-Tags: 23
-GitFetch: refs/heads/23
-GitCommit: ec63b8db44c2d8c97e29faeb55955ca25bd9076e
+Tags: 26-modular
+Architectures: amd64
+GitFetch: refs/heads/26-modular
+GitCommit: d5dd6eb44f0651788edb6f81a5537c09b07022c4
+amd64-Directory: x86_64/
 
-Tags: 22
-GitFetch: refs/heads/22
-GitCommit: bccd42bf4e9102ef10eff372488167948fdd0430
+Tags: 25
+GitFetch: refs/heads/25
+GitCommit: 0603cc1536e4f62b77d1c34e39df55908f56aa48
 
-Tags: 21
-GitFetch: refs/heads/21
-GitCommit: e32493b9601c3535cd6e0d0a8ff61d8fa95afb83
+Tags: 24
+GitFetch: refs/heads/24
+GitCommit: f3726622b5012c1f374bf9f596616eab3cd4988c
 
 Tags: rawhide
+Architectures: amd64, arm32v7, arm64v8, ppc64le
 GitFetch: refs/heads/rawhide
-GitCommit: 40fb5b05b614631b014e71e5dece31e41f8be010
-
-Tags: 20, heisenbug
-GitFetch: refs/heads/20
-GitCommit: 10ada29063147fde9e39190f4c2344b6e6e659e6
+GitCommit: 068835147960bde07171f320e1d2a037d62c07eb
+amd64-Directory: x86_64/
+arm32v7-Directory: armhfp/
+arm64v8-Directory: aarch64/
+ppc64le-Directory: ppc64le/

+ 69 - 0
library/flink

@@ -0,0 +1,69 @@
+# this file is generated via https://github.com/docker-flink/docker-flink/blob/a7f95c5f70cf393adc8d62ad1f03965162cfeb11/generate-stackbrew-library.sh
+
+Maintainers: Patrick Lucas <[email protected]> (@patricklucas),
+             Ismaël Mejía <[email protected]> (@iemejia)
+GitRepo: https://github.com/docker-flink/docker-flink.git
+
+Tags: 1.2.1-hadoop2-scala_2.10
+GitCommit: 38f86f24c029a524a01db7dd273e991c69b3c9f2
+Directory: 1.2/hadoop2-scala_2.10-debian
+
+Tags: 1.2.1-hadoop2-scala_2.11, 1.2.1-hadoop2, 1.2-hadoop2
+GitCommit: 38f86f24c029a524a01db7dd273e991c69b3c9f2
+Directory: 1.2/hadoop2-scala_2.11-debian
+
+Tags: 1.2.1-hadoop24-scala_2.10
+GitCommit: 38f86f24c029a524a01db7dd273e991c69b3c9f2
+Directory: 1.2/hadoop24-scala_2.10-debian
+
+Tags: 1.2.1-hadoop24-scala_2.11, 1.2.1-hadoop24, 1.2-hadoop24
+GitCommit: 38f86f24c029a524a01db7dd273e991c69b3c9f2
+Directory: 1.2/hadoop24-scala_2.11-debian
+
+Tags: 1.2.1-hadoop26-scala_2.10
+GitCommit: 38f86f24c029a524a01db7dd273e991c69b3c9f2
+Directory: 1.2/hadoop26-scala_2.10-debian
+
+Tags: 1.2.1-hadoop26-scala_2.11, 1.2.1-hadoop26, 1.2-hadoop26
+GitCommit: 38f86f24c029a524a01db7dd273e991c69b3c9f2
+Directory: 1.2/hadoop26-scala_2.11-debian
+
+Tags: 1.2.1-hadoop27-scala_2.10, 1.2.1-scala_2.10, 1.2-scala_2.10
+GitCommit: 38f86f24c029a524a01db7dd273e991c69b3c9f2
+Directory: 1.2/hadoop27-scala_2.10-debian
+
+Tags: 1.2.1-hadoop27-scala_2.11, 1.2.1-scala_2.11, 1.2-scala_2.11, 1.2.1-hadoop27, 1.2-hadoop27, 1.2.1, 1.2
+GitCommit: 38f86f24c029a524a01db7dd273e991c69b3c9f2
+Directory: 1.2/hadoop27-scala_2.11-debian
+
+Tags: 1.3.2-hadoop2-scala_2.10
+GitCommit: c7d0506a96369512563ffb6c0afc8dba09430845
+Directory: 1.3/hadoop2-scala_2.10-debian
+
+Tags: 1.3.2-hadoop2-scala_2.11, 1.3.2-hadoop2, 1.3-hadoop2, hadoop2
+GitCommit: c7d0506a96369512563ffb6c0afc8dba09430845
+Directory: 1.3/hadoop2-scala_2.11-debian
+
+Tags: 1.3.2-hadoop24-scala_2.10
+GitCommit: c7d0506a96369512563ffb6c0afc8dba09430845
+Directory: 1.3/hadoop24-scala_2.10-debian
+
+Tags: 1.3.2-hadoop24-scala_2.11, 1.3.2-hadoop24, 1.3-hadoop24, hadoop24
+GitCommit: c7d0506a96369512563ffb6c0afc8dba09430845
+Directory: 1.3/hadoop24-scala_2.11-debian
+
+Tags: 1.3.2-hadoop26-scala_2.10
+GitCommit: c7d0506a96369512563ffb6c0afc8dba09430845
+Directory: 1.3/hadoop26-scala_2.10-debian
+
+Tags: 1.3.2-hadoop26-scala_2.11, 1.3.2-hadoop26, 1.3-hadoop26, hadoop26
+GitCommit: c7d0506a96369512563ffb6c0afc8dba09430845
+Directory: 1.3/hadoop26-scala_2.11-debian
+
+Tags: 1.3.2-hadoop27-scala_2.10, 1.3.2-scala_2.10, 1.3-scala_2.10, scala_2.10
+GitCommit: c7d0506a96369512563ffb6c0afc8dba09430845
+Directory: 1.3/hadoop27-scala_2.10-debian
+
+Tags: 1.3.2-hadoop27-scala_2.11, 1.3.2-scala_2.11, 1.3-scala_2.11, scala_2.11, 1.3.2-hadoop27, 1.3-hadoop27, hadoop27, 1.3.2, 1.3, latest
+GitCommit: c7d0506a96369512563ffb6c0afc8dba09430845
+Directory: 1.3/hadoop27-scala_2.11-debian

+ 22 - 4
library/fsharp

@@ -1,5 +1,23 @@
-# maintainer: Henrik Feldt <[email protected]> (@haf)
+Maintainers: Dave Curylo <[email protected]> (@ninjarobot),
+             Steve Desmond <[email protected]> (@stevedesmond-ca)
+GitRepo: https://github.com/fsprojects/docker-fsharp.git
 
-4.0.0.4: git://github.com/fsprojects/docker-fsharp@57b3ddadc85a63bf586ab89b523bb8326dad9c12 4.0.0.4
-4.0.1.1: git://github.com/fsprojects/docker-fsharp@57b3ddadc85a63bf586ab89b523bb8326dad9c12 4.0.1.1
-latest: git://github.com/fsprojects/docker-fsharp@57b3ddadc85a63bf586ab89b523bb8326dad9c12 4.0.1.1
+Tags: latest, 4, 4.1, 4.1.25
+GitCommit: 96cd7752113e7b4e32fbd6437600816f4b361994
+Directory: 4.1.25/mono
+
+Tags: 4.1.18
+GitCommit: ad4c4d67a1975b2b0ff0acc49dc46b3271836831
+Directory: 4.1.18/mono
+
+Tags: 4.1.0.1
+GitCommit: a28196740e38035beea04c41d5862136413281e3
+Directory: 4.1.0.1/mono
+
+Tags: 4.0, 4.0.1, 4.0.1.1
+GitCommit: a28196740e38035beea04c41d5862136413281e3
+Directory: 4.0.1.1
+
+Tags: 4.0.0.4
+GitCommit: a28196740e38035beea04c41d5862136413281e3
+Directory: 4.0.0.4

+ 13 - 9
library/gazebo

@@ -1,18 +1,22 @@
 # maintainer: Nate Koenig <[email protected]> (@nkoenig)
 
-gzserver4:      git://github.com/osrf/docker_images@32010a4955ccbfb2427063e67a75d13617749963 gazebo/gazebo4/gzserver4
-libgazebo4:     git://github.com/osrf/docker_images@32010a4955ccbfb2427063e67a75d13617749963 gazebo/gazebo4/libgazebo4
+gzserver4:      git://github.com/osrf/docker_images@113c7241bac8ca94c238b1a5bf5ce71ee2a7f219 gazebo/gazebo4/gzserver4
+libgazebo4:     git://github.com/osrf/docker_images@113c7241bac8ca94c238b1a5bf5ce71ee2a7f219 gazebo/gazebo4/libgazebo4
 # Docker EOL: 2016-01-25
 
-gzserver5:      git://github.com/osrf/docker_images@32010a4955ccbfb2427063e67a75d13617749963 gazebo/gazebo5/gzserver5
-libgazebo5:     git://github.com/osrf/docker_images@32010a4955ccbfb2427063e67a75d13617749963 gazebo/gazebo5/libgazebo5
+gzserver5:      git://github.com/osrf/docker_images@113c7241bac8ca94c238b1a5bf5ce71ee2a7f219 gazebo/gazebo5/gzserver5
+libgazebo5:     git://github.com/osrf/docker_images@113c7241bac8ca94c238b1a5bf5ce71ee2a7f219 gazebo/gazebo5/libgazebo5
 # Docker EOL: 2017-01-25
 
-gzserver6:      git://github.com/osrf/docker_images@32010a4955ccbfb2427063e67a75d13617749963 gazebo/gazebo6/gzserver6
-libgazebo6:     git://github.com/osrf/docker_images@32010a4955ccbfb2427063e67a75d13617749963 gazebo/gazebo6/libgazebo6
+gzserver6:      git://github.com/osrf/docker_images@113c7241bac8ca94c238b1a5bf5ce71ee2a7f219 gazebo/gazebo6/gzserver6
+libgazebo6:     git://github.com/osrf/docker_images@113c7241bac8ca94c238b1a5bf5ce71ee2a7f219 gazebo/gazebo6/libgazebo6
 # Docker EOL: 2017-01-25
 
-gzserver7:      git://github.com/osrf/docker_images@32010a4955ccbfb2427063e67a75d13617749963 gazebo/gazebo7/gzserver7
-libgazebo7:     git://github.com/osrf/docker_images@32010a4955ccbfb2427063e67a75d13617749963 gazebo/gazebo7/libgazebo7
-latest:         git://github.com/osrf/docker_images@32010a4955ccbfb2427063e67a75d13617749963 gazebo/gazebo7/libgazebo7
+gzserver7:      git://github.com/osrf/docker_images@113c7241bac8ca94c238b1a5bf5ce71ee2a7f219 gazebo/gazebo7/gzserver7
+libgazebo7:     git://github.com/osrf/docker_images@113c7241bac8ca94c238b1a5bf5ce71ee2a7f219 gazebo/gazebo7/libgazebo7
 # Docker EOL: 2021-01-25
+
+gzserver8:      git://github.com/osrf/docker_images@113c7241bac8ca94c238b1a5bf5ce71ee2a7f219 gazebo/gazebo8/gzserver8
+libgazebo8:     git://github.com/osrf/docker_images@113c7241bac8ca94c238b1a5bf5ce71ee2a7f219 gazebo/gazebo8/libgazebo8
+latest:         git://github.com/osrf/docker_images@113c7241bac8ca94c238b1a5bf5ce71ee2a7f219 gazebo/gazebo8/libgazebo8
+# Docker EOL: 2019-01-25

+ 17 - 7
library/gcc

@@ -1,4 +1,4 @@
-# this file is generated via https://github.com/docker-library/gcc/blob/8c7687860cdd4ef9227c249ca4587984e2636a55/generate-stackbrew-library.sh
+# this file is generated via https://github.com/docker-library/gcc/blob/e21e2f607ba2623b0d8fc8a9a6bbfad8df1cf511/generate-stackbrew-library.sh
 
 Maintainers: Tianon Gravi <[email protected]> (@tianon),
              Joseph Ferguson <[email protected]> (@yosifkit)
@@ -6,18 +6,28 @@ GitRepo: https://github.com/docker-library/gcc.git
 
 # Last Modified: 2016-08-03
 Tags: 4.9.4, 4.9, 4
-GitCommit: 8c7687860cdd4ef9227c249ca4587984e2636a55
+Architectures: amd64, arm64v8, ppc64le, s390x
+GitCommit: 3b33871fe9558262cb5ed6253d358f76710e9ccb
 Directory: 4.9
 # Docker EOL: 2017-08-03
 
 # Last Modified: 2016-06-03
 Tags: 5.4.0, 5.4, 5
-GitCommit: 8c7687860cdd4ef9227c249ca4587984e2636a55
+Architectures: amd64, arm64v8, ppc64le, s390x
+GitCommit: 3b33871fe9558262cb5ed6253d358f76710e9ccb
 Directory: 5
 # Docker EOL: 2017-06-03
 
-# Last Modified: 2016-08-22
-Tags: 6.2.0, 6.2, 6, latest
-GitCommit: 8c7687860cdd4ef9227c249ca4587984e2636a55
+# Last Modified: 2017-07-04
+Tags: 6.4.0, 6.4, 6
+Architectures: amd64, arm64v8, ppc64le, s390x
+GitCommit: c1fe37de30fbe69e83f042b4a9426b11cb624bca
 Directory: 6
-# Docker EOL: 2017-08-22
+# Docker EOL: 2018-07-04
+
+# Last Modified: 2017-08-14
+Tags: 7.2.0, 7.2, 7, latest
+Architectures: amd64, arm64v8, ppc64le, s390x
+GitCommit: 3ccb804e330766ba05abe7fe990512f152a08254
+Directory: 7
+# Docker EOL: 2018-08-14

+ 20 - 3
library/ghost

@@ -1,8 +1,25 @@
-# this file is generated via https://github.com/docker-library/ghost/blob/8652c806a1af1beef0f9c4ec146262e50f6a4875/generate-stackbrew-library.sh
+# this file is generated via https://github.com/docker-library/ghost/blob/8d1ed041ef46982fe5a15bed9e662c0045b23c75/generate-stackbrew-library.sh
 
 Maintainers: Tianon Gravi <[email protected]> (@tianon),
              Joseph Ferguson <[email protected]> (@yosifkit)
 GitRepo: https://github.com/docker-library/ghost.git
 
-Tags: 0.11.3, 0.11, 0, latest
-GitCommit: 9e9522838f378c6c4acaf87a5fabaceab34cd2e0
+Tags: 1.8.6, 1.8, 1, latest
+Architectures: amd64, arm32v7, arm64v8, ppc64le, s390x
+GitCommit: 8a63e148794b0dc626a1b0abcfd28829230dbca1
+Directory: 1/debian
+
+Tags: 1.8.6-alpine, 1.8-alpine, 1-alpine, alpine
+Architectures: amd64
+GitCommit: 8a63e148794b0dc626a1b0abcfd28829230dbca1
+Directory: 1/alpine
+
+Tags: 0.11.11, 0.11, 0
+Architectures: amd64, arm32v7, arm64v8, ppc64le, s390x
+GitCommit: 0a3f9385d624bc3511b4f702671dcc27ae96de66
+Directory: 0/debian
+
+Tags: 0.11.11-alpine, 0.11-alpine, 0-alpine
+Architectures: amd64
+GitCommit: fabb247507dc8b2d20c5795d688c4167b98caf4a
+Directory: 0/alpine

+ 46 - 39
library/golang

@@ -1,58 +1,65 @@
-# this file is generated via https://github.com/docker-library/golang/blob/389d5dcc78e78b700b5485d4608b9f094b2e485b/generate-stackbrew-library.sh
+# this file is generated via https://github.com/docker-library/golang/blob/e0ac3d629dc06dcf25ba6724f7126a79723a74af/generate-stackbrew-library.sh
 
 Maintainers: Tianon Gravi <[email protected]> (@tianon),
              Joseph Ferguson <[email protected]> (@yosifkit),
              Johan Euphrosine <[email protected]> (@proppy)
 GitRepo: https://github.com/docker-library/golang.git
 
-Tags: 1.6.3, 1.6
-GitCommit: 85df9970e9548f38248d36f6f4341e2aea128515
-Directory: 1.6
+Tags: 1.9.0-stretch, 1.9-stretch, 1-stretch, stretch, 1.9.0, 1.9, 1, latest
+Architectures: amd64, arm32v7, arm64v8, i386, ppc64le, s390x
+GitCommit: 94e49ca93c5bbf172e462cea8872c77f9bc08c10
+Directory: 1.9/stretch
 
-Tags: 1.6.3-onbuild, 1.6-onbuild
-GitCommit: ce284e14cdee73fbaa8fb680011a812f272eae2e
-Directory: 1.6/onbuild
+Tags: 1.9.0-alpine3.6, 1.9-alpine3.6, 1-alpine3.6, alpine3.6, 1.9.0-alpine, 1.9-alpine, 1-alpine, alpine
+Architectures: amd64
+GitCommit: 94e49ca93c5bbf172e462cea8872c77f9bc08c10
+Directory: 1.9/alpine3.6
 
-Tags: 1.6.3-wheezy, 1.6-wheezy
-GitCommit: 85df9970e9548f38248d36f6f4341e2aea128515
-Directory: 1.6/wheezy
-
-Tags: 1.6.3-alpine, 1.6-alpine
-GitCommit: 9f666dc2f4f51df564613f787d28b3a2353243e0
-Directory: 1.6/alpine
-
-Tags: 1.6.3-windowsservercore, 1.6-windowsservercore
-GitCommit: cba64e4f78b2ef64b2938caaa33d699cbca4f9a4
-Directory: 1.6/windows/windowsservercore
+Tags: 1.9.0-windowsservercore, 1.9-windowsservercore, 1-windowsservercore, windowsservercore
+Architectures: windows-amd64
+GitCommit: f34c645c8402bd8f6b70f530545ad7845dfefbcc
+Directory: 1.9/windows/windowsservercore
 Constraints: windowsservercore
 
-Tags: 1.6.3-nanoserver, 1.6-nanoserver
-GitCommit: cba64e4f78b2ef64b2938caaa33d699cbca4f9a4
-Directory: 1.6/windows/nanoserver
+Tags: 1.9.0-nanoserver, 1.9-nanoserver, 1-nanoserver, nanoserver
+Architectures: windows-amd64
+GitCommit: f34c645c8402bd8f6b70f530545ad7845dfefbcc
+Directory: 1.9/windows/nanoserver
 Constraints: nanoserver
 
-Tags: 1.7.3, 1.7, 1, latest
-GitCommit: 4fd5df86eea53623b1009b3621b40a97f9f359e5
-Directory: 1.7
+Tags: 1.8.3-stretch, 1.8-stretch
+Architectures: amd64, arm32v7, i386, ppc64le, s390x
+GitCommit: 94e49ca93c5bbf172e462cea8872c77f9bc08c10
+Directory: 1.8/stretch
+
+Tags: 1.8.3-jessie, 1.8-jessie, 1.8.3, 1.8
+Architectures: amd64, arm32v7, i386, ppc64le, s390x
+GitCommit: 94e49ca93c5bbf172e462cea8872c77f9bc08c10
+Directory: 1.8/jessie
 
-Tags: 1.7.3-onbuild, 1.7-onbuild, 1-onbuild, onbuild
-GitCommit: 2372c8cafe9cc958bade33ad0b8b54de8869c21f
-Directory: 1.7/onbuild
+Tags: 1.8.3-alpine3.6, 1.8-alpine3.6
+Architectures: amd64
+GitCommit: 94e49ca93c5bbf172e462cea8872c77f9bc08c10
+Directory: 1.8/alpine3.6
 
-Tags: 1.7.3-wheezy, 1.7-wheezy, 1-wheezy, wheezy
-GitCommit: 4fd5df86eea53623b1009b3621b40a97f9f359e5
-Directory: 1.7/wheezy
+Tags: 1.8.3-alpine3.5, 1.8-alpine3.5, 1.8.3-alpine, 1.8-alpine
+Architectures: amd64
+GitCommit: 94e49ca93c5bbf172e462cea8872c77f9bc08c10
+Directory: 1.8/alpine3.5
 
-Tags: 1.7.3-alpine, 1.7-alpine, 1-alpine, alpine
-GitCommit: 4fd5df86eea53623b1009b3621b40a97f9f359e5
-Directory: 1.7/alpine
+Tags: 1.8.3-onbuild, 1.8-onbuild
+Architectures: amd64, arm32v7, i386, ppc64le, s390x
+GitCommit: 132cd70768e3bc269902e4c7b579203f66dc9f64
+Directory: 1.8/onbuild
 
-Tags: 1.7.3-windowsservercore, 1.7-windowsservercore, 1-windowsservercore, windowsservercore
-GitCommit: 4fd5df86eea53623b1009b3621b40a97f9f359e5
-Directory: 1.7/windows/windowsservercore
+Tags: 1.8.3-windowsservercore, 1.8-windowsservercore
+Architectures: windows-amd64
+GitCommit: 64b88dc3e9d83e71eafc000fed1f0d5e289b3e65
+Directory: 1.8/windows/windowsservercore
 Constraints: windowsservercore
 
-Tags: 1.7.3-nanoserver, 1.7-nanoserver, 1-nanoserver, nanoserver
-GitCommit: 4fd5df86eea53623b1009b3621b40a97f9f359e5
-Directory: 1.7/windows/nanoserver
+Tags: 1.8.3-nanoserver, 1.8-nanoserver
+Architectures: windows-amd64
+GitCommit: 64b88dc3e9d83e71eafc000fed1f0d5e289b3e65
+Directory: 1.8/windows/nanoserver
 Constraints: nanoserver

+ 42 - 0
library/gradle

@@ -0,0 +1,42 @@
+Maintainers: Keegan Witt <[email protected]> (@keeganwitt)
+GitRepo: https://github.com/keeganwitt/docker-gradle.git
+
+Tags: 4.1.0-jdk7, 4.1-jdk7, jdk7
+GitCommit: 00d3f868a538e9e60045b2c42fb0146590649402
+Directory: jdk7
+
+Tags: 4.1.0-jre7, 4.1-jre7, jre7
+GitCommit: 00d3f868a538e9e60045b2c42fb0146590649402
+Directory: jre7
+
+Tags: 4.1.0-jdk7-alpine, 4.1-jdk7-alpine, jdk7-alpine
+GitCommit: 00d3f868a538e9e60045b2c42fb0146590649402
+Directory: jdk7-alpine
+
+Tags: 4.1.0-jre7-alpine, 4.1-jre7-alpine, jre7-alpine
+GitCommit: 00d3f868a538e9e60045b2c42fb0146590649402
+Directory: jre7-alpine
+
+Tags: 4.1.0-jdk8, 4.1-jdk8, jdk8, 4.1.0-jdk, 4.1-jdk, jdk, 4.1.0, 4.1, latest
+GitCommit: 00d3f868a538e9e60045b2c42fb0146590649402
+Directory: jdk8
+
+Tags: 4.1.0-jre8, 4.1-jre8, jre8, 4.1.0-jre, 4.1-jre, jre
+GitCommit: 00d3f868a538e9e60045b2c42fb0146590649402
+Directory: jre8
+
+Tags: 4.1.0-jdk8-alpine, 4.1-jdk8-alpine, jdk8-alpine, 4.1.0-jdk-alpine, 4.1-jdk-alpine, jdk-alpine, 4.1.0-alpine, 4.1-alpine, alpine
+GitCommit: 00d3f868a538e9e60045b2c42fb0146590649402
+Directory: jdk8-alpine
+
+Tags: 4.1.0-jre8-alpine, 4.1-jre8-alpine, jre8-alpine, 4.1.0-jre-alpine, 4.1-jre-alpine, jre-alpine
+GitCommit: 00d3f868a538e9e60045b2c42fb0146590649402
+Directory: jre8-alpine
+
+Tags: 4.1.0-jdk9, 4.1-jdk9, jdk9
+GitCommit: 00d3f868a538e9e60045b2c42fb0146590649402
+Directory: jdk9
+
+Tags: 4.1.0-jre9, 4.1-jre9, jre9
+GitCommit: 00d3f868a538e9e60045b2c42fb0146590649402
+Directory: jre9

Some files were not shown because too many files changed in this diff