# Technical Documentation: containers/skopeo

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/containers/skopeo)

### Overview (`README.md`)

<p align="center">
   <img src="https://raw.githubusercontent.com/podman-container-tools/skopeo/main/docs/skopeo.svg" width="250" alt="Skopeo">
</p>

----


[](https://www.bestpractices.dev/projects/10516)

`skopeo` is a command line utility that performs various operations on container images and image repositories.

`skopeo` does not require the user to be running as root to do most of its operations.

`skopeo` does not require a daemon to be running to perform its operations.

`skopeo` can work with [OCI images](https://github.com/opencontainers/image-spec) as well as the original Docker v2 images.

Skopeo works with API V2 container image registries such as [docker.io](https://docker.io) and [quay.io](https://quay.io) registries, private registries, local directories and local OCI-layout directories. Skopeo can perform operations which consist of:

 * Copying an image from and to various storage mechanisms.
   For example you can copy images from one registry to another, without requiring privilege.
 * Inspecting a remote image showing its properties including its layers, without requiring you to pull the image to the host.
 * Deleting an image from an image repository.
 * Syncing an external image repository to an internal registry for air-gapped deployments.
 * When required by the repository, skopeo can pass the appropriate credentials and certificates for authentication.

 Skopeo operates on the following image and repository types:

 * containers-storage:docker-reference
         An image located in a local containers/storage image store.  Both the location and image store are specified in /etc/containers/storage.conf. (This is  the backend for [Podman](https://podman.io), [CRI-O](https://cri-o.io), [Buildah](https://buildah.io) and friends)

 * dir:path
         An existing local directory path storing the manifest, layer tarballs and signatures as individual files. This is a non-standardized format, primarily useful for debugging or noninvasive container inspection.

 * docker://docker-reference
         An image in a registry implementing the "Docker Registry HTTP API V2". By default, uses the authorization state in `$XDG_RUNTIME_DIR/containers/auth.json`, which is set using `skopeo login`.

 * docker-archive:path[:docker-reference]
         An image is stored in a `docker save`-formatted file.  docker-reference is only used when creating such a file, and it must not contain a digest.

 * docker-daemon:docker-reference
         An image docker-reference stored in the docker daemon internal storage.  docker-reference must contain either a tag or a digest.  Alternatively, when reading images, the format can also be docker-daemon:algo:digest (an image ID).

 * oci:path:tag
         An image tag in a directory compliant with "Open Container Image Layout Specification" at path.

[Obtaining skopeo](./install.md)
-

For a detailed description how to install or build skopeo, see
[install.md](./install.md).

Skopeo is also available as a Container Image on [quay.io](https://quay.io/skopeo/stable).  For more information, see the [Skopeo Image](https://github.com/containers/image_build/blob/main/skopeo/README.md) page.

Skopeo has no separate project website. This repository, and the container images
documented above, are the only upstream builds; users can also use packages from
distributions they trust, as documented in [install.md](./install.md). Other
websites presenting themselves as the home of skopeo or offering their own skopeo
downloads are not affiliated with the project.

## Inspecting a repository
`skopeo` is able to _inspect_ a repository on a container registry and fetch images layers.
The _inspect_ command fetches the repository's manifest and it is able to show you a `docker inspect`-like
json output about a whole repository or a tag. This tool, in contrast to `docker inspect`, helps you gather useful information about
a repository or a tag before pulling it (using disk space).  The inspect command can show you which tags are available for the given 
repository, the labels the image has, the creation date and operating system of the image and more.  

Examples:

#### Show properties of fedora:latest
```console
$ skopeo inspect docker://registry.fedoraproject.org/fedora:latest
{
    "Name": "registry.fedoraproject.org/fedora",
    "Digest": "sha256:0f65bee641e821f8118acafb44c2f8fe30c2fc6b9a2b3729c0660376391aa117",
    "RepoTags": [
        "34-aarch64",
        "34",
        "latest",
        ...
    ],
    "Created": "2022-11-24T13:54:18Z",
    "DockerVersion": "1.10.1",
    "Labels": {
        "license": "MIT",
        "name": "fedora",
        "vendor": "Fedora Project",
        "version": "37"
    },
    "Architecture": "amd64",
    "Os": "linux",
    "Layers": [
        "sha256:2a0fc6bf62e155737f0ace6142ee686f3c471c1aab4241dc3128904db46288f0"
    ],
    "LayersData": [
        {
            "MIMEType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
            "Digest": "sha256:2a0fc6bf62e155737f0ace6142ee686f3c471c1aab4241dc3128904db46288f0",
            "Size": 71355009,
            "Annotations": null
        }
    ],
    "Env": [
        "DISTTAG=f37container",
        "FGC=f37",
        "container=oci"
    ]
}
```

#### Show container configuration from `fedora:latest`

```console
$ skopeo inspect --config docker://registry.fedoraproject.org/fedora:latest  | jq
{
  "created": "2020-04-29T06:48:16Z",
  "architecture": "amd64",
  "os": "linux",
  "config": {
    "Env": [
      "DISTTAG=f32container",
      "FGC=f32",
      "container=oci"
    ],
    "Cmd": [
      "/bin/bash"
    ],
    "Labels": {
      "license": "MIT",
      "name": "fedora",
      "vendor": "Fedora Project",
      "version": "32"
    }
  },
  "rootfs": {
    "type": "layers",
    "diff_ids": [
      "sha256:a4c0fa2b217d3fd63d51e55a6fd59432e543d499c0df2b1acd48fbe424f2ddd1"
    ]
  },
  "history": [
    {
      "created": "2020-04-29T06:48:16Z",
      "comment": "Created by Image Factory"
    }
  ]
}
```
#### Show unverified image's digest
```console
$ skopeo inspect docker://registry.fedoraproject.org/fedora:latest | jq '.Digest'
"sha256:655721ff613ee766a4126cb5e0d5ae81598e1b0c3bcf7017c36c4d72cb092fe9"
```

## Copying images

`skopeo` can copy container images between various storage mechanisms, including:
* Container registries

  -  The Quay, Docker Hub, OpenShift, GCR, Artifactory ...

* Container Storage backends

  -  [github.com/containers/storage](https://github.com/containers/storage) (Backend for [Podman](https://podman.io), [CRI-O](https://cri-o.io), [Buildah](https://buildah.io) and friends)

  -  Docker daemon storage

* Local directories

* Local OCI-layout directories

```console
$ skopeo copy docker://quay.io/buildah/stable docker://registry.internal.company.com/buildah
$ skopeo copy oci:busybox_ocilayout:latest dir:existingemptydirectory
```

## Deleting images
```console
$ skopeo delete docker://localhost:5000/imagename:latest
```

## Syncing registries
```console
$ skopeo sync --src docker --dest dir registry.example.com/busybox /media/usb
```

## Authenticating to a registry

#### Private registries with authentication
skopeo uses credentials from the --creds (for skopeo inspect|delete) or --src-creds|--dest-creds (for skopeo copy) flags, if set; otherwise it uses configuration set by skopeo login, podman login, buildah login, or docker login.

```console
$ skopeo login --username USER myregistrydomain.com:5000
Password:
$ skopeo inspect docker://myregistrydomain.com:5000/busybox
{"Tag":"latest","Digest":"sha256:473bb2189d7b913ed7187a33d11e743fdc2f88931122a44d91a301b64419f092","RepoTags":["latest"],"Comment":"","Created":"2016-01-15T18:06:41.282540103Z","ContainerConfig":{"Hostname":"aded96b43f48","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":["/bin/sh","-c","#(nop) CMD [\"sh\"]"],"Image":"9e77fef7a1c9f989988c06620dabc4020c607885b959a2cbd7c2283c91da3e33","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"DockerVersion":"1.8.3","Author":"","Config":{"Hostname":"aded96b43f48","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":["sh"],"Image":"9e77fef7a1c9f989988c06620dabc4020c607885b959a2cbd7c2283c91da3e33","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"Architecture":"amd64","Os":"linux"}
$ skopeo logout myregistrydomain.com:5000
```

#### Using --creds directly

```console
$ skopeo inspect --creds=testuser:testpassword docker://myregistrydomain.com:5000/busybox
{"Tag":"latest","Digest":"sha256:473bb2189d7b913ed7187a33d11e743fdc2f88931122a44d91a301b64419f092","RepoTags":["latest"],"Comment":"","Created":"2016-01-15T18:06:41.282540103Z","ContainerConfig":{"Hostname":"aded96b43f48","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":["/bin/sh","-c","#(nop) CMD [\"sh\"]"],"Image":"9e77fef7a1c9f989988c06620dabc4020c607885b959a2cbd7c2283c91da3e33","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"DockerVersion":"1.8.3","Author":"","Config":{"Hostname":"aded96b43f48","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":["sh"],"Image":"9e77fef7a1c9f989988c06620dabc4020c607885b959a2cbd7c2283c91da3e33","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"Architecture":"amd64","Os":"linux"}
```

```console
$ skopeo copy --src-creds=testuser:testpassword docker://myregistrydomain.com:5000/private oci:local_oci_image
```

Contributing
-

Please read the [contribution guide](CONTRIBUTING.md) if you want to collaborate in the project.

## Commands
| Command                                            | Description                                                                                  |
| -------------------------------------------------- | ---------------------------------------------------------------------------------------------|
| [skopeo-copy(1)](/docs/skopeo-copy.1.md)           | Copy an image (manifest, filesystem layers, signatures) from one location to another.        |
| [skopeo-delete(1)](/docs/skopeo-delete.1.md)       | Mark the image-name for later deletion by the registry's garbage collector.                                                                |
| [skopeo-generate-sigstore-key(1)](/docs/skopeo-generate-sigstore-key.1.md)    | Generate a sigstore public/private key pair.  |
| [skopeo-inspect(1)](/docs/skopeo-inspect.1.md)     | Return  low-level  information about image-name in a registry.                                |
| [skopeo-list-tags(1)](/docs/skopeo-list-tags.1.md) | Return a list of tags for the transport-specific image repository.                               |
| [skopeo-login(1)](/docs/skopeo-login.1.md)         | Login to a container registry.                                                               |
| [skopeo-logout(1)](/docs/skopeo-logout.1.md)       | Logout of a container registry.                                                              |
| [skopeo-manifest-digest(1)](/docs/skopeo-manifest-digest.1.md)    | Compute a manifest digest for a manifest-file and write it to standard output.   |
| [skopeo-standalone-sign(1)](/docs/skopeo-standalone-sign.1.md)    | Debugging tool - Sign an image locally without uploading.                     |
| [skopeo-standalone-verify(1)](/docs/skopeo-standalone-verify.1.md)| Debugging tool - Verify an image signature from local files.                  |
| [skopeo-sync(1)](/docs/skopeo-sync.1.md)           | Synchronize images between registry repositories and local directories.                      |

License
-
skopeo is licensed under the Apache License, Version 2.0. See
[LICENSE](LICENSE) for the full license text.

---

### Overview (`contrib/skopeoimage/README.md`)

The skopeo container image build context and automation have been
moved to [https://github.com/containers/image_build/tree/main/skopeo](https://github.com/containers/image_build/tree/main/skopeo)

---

### Overview (`vendor/dario.cat/mergo/README.md`)

# Mergo

[![GitHub release][5]][6]
[![GoCard][7]][8]
[![Test status][1]][2]
[![OpenSSF Scorecard][21]][22]
[![OpenSSF Best Practices][19]][20]
[![Coverage status][9]][10]
[![Sourcegraph][11]][12]
[![FOSSA status][13]][14]

[![GoDoc][3]][4]
[![Become my sponsor][15]][16]
[![Tidelift][17]][18]

[1]: https://github.com/imdario/mergo/workflows/tests/badge.svg?branch=master
[2]: https://github.com/imdario/mergo/actions/workflows/tests.yml
[3]: https://godoc.org/github.com/imdario/mergo?status.svg
[4]: https://godoc.org/github.com/imdario/mergo
[5]: https://img.shields.io/github/release/imdario/mergo.svg
[6]: https://github.com/imdario/mergo/releases
[7]: https://goreportcard.com/badge/imdario/mergo
[8]: https://goreportcard.com/report/github.com/imdario/mergo
[9]: https://coveralls.io/repos/github/imdario/mergo/badge.svg?branch=master
[10]: https://coveralls.io/github/imdario/mergo?branch=master
[11]: https://sourcegraph.com/github.com/imdario/mergo/-/badge.svg
[12]: https://sourcegraph.com/github.com/imdario/mergo?badge
[13]: https://app.fossa.io/api/projects/git%2Bgithub.com%2Fimdario%2Fmergo.svg?type=shield
[14]: https://app.fossa.io/projects/git%2Bgithub.com%2Fimdario%2Fmergo?ref=badge_shield
[15]: https://img.shields.io/github/sponsors/imdario
[16]: https://github.com/sponsors/imdario
[17]: https://tidelift.com/badges/package/go/github.com%2Fimdario%2Fmergo
[18]: https://tidelift.com/subscription/pkg/go-github.com-imdario-mergo
[19]: https://bestpractices.coreinfrastructure.org/projects/7177/badge
[20]: https://bestpractices.coreinfrastructure.org/projects/7177
[21]: https://api.securityscorecards.dev/projects/github.com/imdario/mergo/badge
[22]: https://api.securityscorecards.dev/projects/github.com/imdario/mergo

A helper to merge structs and maps in Golang. Useful for configuration default values, avoiding messy if-statements.

Mergo merges same-type structs and maps by setting default values in zero-value fields. Mergo won't merge unexported (private) fields. It will do recursively any exported one. It also won't merge structs inside maps (because they are not addressable using Go reflection).

Also a lovely [comune](http://en.wikipedia.org/wiki/Mergo) (municipality) in the Province of Ancona in the Italian region of Marche.

## Status

Mergo is stable and frozen, ready for production. Check a short list of the projects using at large scale it [here](https://github.com/imdario/mergo#mergo-in-the-wild).

No new features are accepted. They will be considered for a future v2 that improves the implementation and fixes bugs for corner cases.

### Important notes

#### 1.0.0

In [1.0.0](//github.com/imdario/mergo/releases/tag/1.0.0) Mergo moves to a vanity URL `dario.cat/mergo`. No more v1 versions will be released.

If the vanity URL is causing issues in your project due to a dependency pulling Mergo - it isn't a direct dependency in your project - it is recommended to use [replace](https://github.com/golang/go/wiki/Modules#when-should-i-use-the-replace-directive) to pin the version to the last one with the old import URL:

```
replace github.com/imdario/mergo => github.com/imdario/mergo v0.3.16
```

#### 0.3.9

Please keep in mind that a problematic PR broke [0.3.9](//github.com/imdario/mergo/releases/tag/0.3.9). I reverted it in [0.3.10](//github.com/imdario/mergo/releases/tag/0.3.10), and I consider it stable but not bug-free. Also, this version adds support for go modules.

Keep in mind that in [0.3.2](//github.com/imdario/mergo/releases/tag/0.3.2), Mergo changed `Merge()`and `Map()` signatures to support [transformers](#transformers). I added an optional/variadic argument so that it won't break the existing code.

If you were using Mergo before April 6th, 2015, please check your project works as intended after updating your local copy with ```go get -u dario.cat/mergo```. I apologize for any issue caused by its previous behavior and any future bug that Mergo could cause in existing projects after the change (release 0.2.0).

### Donations

If Mergo is useful to you, consider buying me a coffee, a beer, or making a monthly donation to allow me to keep building great free software. :heart_eyes:

<a href="https://liberapay.com/dario/donate"><img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg"></a>
<a href='https://github.com/sponsors/imdario' target='_blank'><img alt="Become my sponsor" src="https://img.shields.io/github/sponsors/imdario?style=for-the-badge" /></a>

### Mergo in the wild

Mergo is used by [thousands](https://deps.dev/go/dario.cat%2Fmergo/v1.0.0/dependents) [of](https://deps.dev/go/github.com%2Fimdario%2Fmergo/v0.3.16/dependents) [projects](https://deps.dev/go/github.com%2Fimdario%2Fmergo/v0.3.12), including:

* [containerd/containerd](https://github.com/containerd/containerd)
* [datadog/datadog-agent](https://github.com/datadog/datadog-agent)
* [docker/cli/](https://github.com/docker/cli/)
* [goreleaser/goreleaser](https://github.com/goreleaser/goreleaser)
* [go-micro/go-micro](https://github.com/go-micro/go-micro)
* [grafana/loki](https://github.com/grafana/loki)
* [masterminds/sprig](github.com/Masterminds/sprig)
* [moby/moby](https://github.com/moby/moby)
* [slackhq/nebula](https://github.com/slackhq/nebula)
* [volcano-sh/volcano](https://github.com/volcano-sh/volcano)

## Install

    go get dario.cat/mergo

    // use in your .go code
    import (
        "dario.cat/mergo"
    )

## Usage

You can only merge same-type structs with exported fields initialized as zero value of their type and same-types maps. Mergo won't merge unexported (private) fields but will do recursively any exported one. It won't merge empty structs value as [they are zero values](https://golang.org/ref/spec#The_zero_value) too. Also, maps will be merged recursively except for structs inside maps (because they are not addressable using Go reflection).

```go
if err := mergo.Merge(&dst, src); err != nil {
    // ...
}
```

Also, you can merge overwriting values using the transformer `WithOverride`.

```go
if err := mergo.Merge(&dst, src, mergo.WithOverride); err != nil {
    // ...
}
```

If you need to override pointers, so the source pointer's value is assigned to the destination's pointer, you must use `WithoutDereference`:

```go
package main

import (
	"fmt"

	"dario.cat/mergo"
)

type Foo struct {
	A *string
	B int64
}

func main() {
	first := "first"
	second := "second"
	src := Foo{
		A: &first,
		B: 2,
	}

	dest := Foo{
		A: &second,
		B: 1,
	}

	mergo.Merge(&dest, src, mergo.WithOverride, mergo.WithoutDereference)
}
```

Additionally, you can map a `map[string]interface{}` to a struct (and otherwise, from struct to map), following the same restrictions as in `Merge()`. Keys are capitalized to find each corresponding exported field.

```go
if err := mergo.Map(&dst, srcMap); err != nil {
    // ...
}
```

Warning: if you map a struct to map, it won't do it recursively. Don't expect Mergo to map struct members of your struct as `map[string]interface{}`. They will be just assigned as values.

Here is a nice example:

```go
package main

import (
	"fmt"
	"dario.cat/mergo"
)

type Foo struct {
	A string
	B int64
}

func main() {
	src := Foo{
		A: "one",
		B: 2,
	}
	dest := Foo{
		A: "two",
	}
	mergo.Merge(&dest, src)
	fmt.Println(dest)
	// Will print
	// {two 2}
}
```

### Transformers

Transformers allow to merge specific types differently than in the default behavior. In other words, now you can customize how some types are merged. For example, `time.Time` is a struct; it doesn't have zero value but IsZero can return true because it has fields with zero value. How can we merge a non-zero `time.Time`?

```go
package main

import (
	"fmt"
	"dario.cat/mergo"
    "reflect"
    "time"
)

type timeTransformer struct {
}

func (t timeTransformer) Transformer(typ reflect.Type) func(dst, src reflect.Value) error {
	if typ == reflect.TypeOf(time.Time{}) {
		return func(dst, src reflect.Value) error {
			if dst.CanSet() {
				isZero := dst.MethodByName("IsZero")
				result := isZero.Call([]reflect.Value{})
				if result[0].Bool() {
					dst.Set(src)
				}
			}
			return nil
		}
	}
	return nil
}

type Snapshot struct {
	Time time.Time
	// ...
}

func main() {
	src := Snapshot{time.Now()}
	dest := Snapshot{}
	mergo.Merge(&dest, src, mergo.WithTransformers(timeTransformer{}))
	fmt.Println(dest)
	// Will print
	// { 2018-01-12 01:15:00 +0000 UTC m=+0.000000001 }
}
```

## Contact me

If I can help you, you have an idea or you are using Mergo in your projects, don't hesitate to drop me a line (or a pull request): [@im_dario](https://twitter.com/im_dario)

## About

Written by [Dario Castañé](http://dario.im).

## License

[BSD 3-Clause](http://opensource.org/licenses/BSD-3-Clause) license, as [Go language](http://golang.org/LICENSE).

[](https://app.fossa.io/projects/git%2Bgithub.com%2Fimdario%2Fmergo?ref=badge_large)

---

### Overview (`vendor/go.opentelemetry.io/otel/README.md`)

# OpenTelemetry-Go

[](https://github.com/open-telemetry/opentelemetry-go/actions/workflows/ci.yml)
[](https://app.codecov.io/gh/open-telemetry/opentelemetry-go?branch=main)
[](https://pkg.go.dev/go.opentelemetry.io/otel)
[](https://goreportcard.com/report/go.opentelemetry.io/otel)
[](https://scorecard.dev/viewer/?uri=github.com/open-telemetry/opentelemetry-go)
[](https://www.bestpractices.dev/projects/9996)
[](https://issues.oss-fuzz.com/issues?q=project:opentelemetry-go)
[](https://app.fossa.com/projects/custom%2B162%2Fgithub.com%2Fopen-telemetry%2Fopentelemetry-go?ref=badge_shield&issueType=license)
[](https://cloud-native.slack.com/archives/C01NPAXACKT)

OpenTelemetry-Go is the [Go](https://golang.org/) implementation of [OpenTelemetry](https://opentelemetry.io/).
It provides a set of APIs to directly measure performance and behavior of your software and send this data to observability platforms.

## Project Status

| Signal  | Status             |
|---------|--------------------|
| Traces  | Stable             |
| Metrics | Stable             |
| Logs    | Beta[^1]           |

Progress and status specific to this repository is tracked in our
[project boards](https://github.com/open-telemetry/opentelemetry-go/projects)
and
[milestones](https://github.com/open-telemetry/opentelemetry-go/milestones).

Project versioning information and stability guarantees can be found in the
[versioning documentation](VERSIONING.md).

[^1]: https://github.com/orgs/open-telemetry/projects/43

### Compatibility

OpenTelemetry-Go ensures compatibility with the current supported versions of
the [Go language](https://golang.org/doc/devel/release#policy):

> Each major Go release is supported until there are two newer major releases.
> For example, Go 1.5 was supported until the Go 1.7 release, and Go 1.6 was supported until the Go 1.8 release.

For versions of Go that are no longer supported upstream, opentelemetry-go will
stop ensuring compatibility with these versions in the following manner:

- A minor release of opentelemetry-go will be made to add support for the new
  supported release of Go.
- The following minor release of opentelemetry-go will remove compatibility
  testing for the oldest (now archived upstream) version of Go. This, and
  future, releases of opentelemetry-go may include features only supported by
  the currently supported versions of Go.

Currently, this project supports the following environments.

| OS       | Go Version | Architecture |
|----------|------------|--------------|
| Ubuntu   | 1.27       | amd64        |
| Ubuntu   | 1.26       | amd64        |
| Ubuntu   | 1.25       | amd64        |
| Ubuntu   | 1.27       | 386          |
| Ubuntu   | 1.26       | 386          |
| Ubuntu   | 1.25       | 386          |
| Ubuntu   | 1.27       | arm64        |
| Ubuntu   | 1.26       | arm64        |
| Ubuntu   | 1.25       | arm64        |
| macOS    | 1.27       | amd64        |
| macOS    | 1.26       | amd64        |
| macOS    | 1.25       | amd64        |
| macOS    | 1.27       | arm64        |
| macOS    | 1.26       | arm64        |
| macOS    | 1.25       | arm64        |
| Windows  | 1.27       | amd64        |
| Windows  | 1.26       | amd64        |
| Windows  | 1.25       | amd64        |
| Windows  | 1.27       | 386          |
| Windows  | 1.26       | 386          |
| Windows  | 1.25       | 386          |

While this project should work for other systems, no compatibility guarantees
are made for those systems currently.

## Getting Started

You can find a getting started guide on [opentelemetry.io](https://opentelemetry.io/docs/languages/go/getting-started/).

OpenTelemetry's goal is to provide a single set of APIs to capture distributed
traces and metrics from your application and send them to an observability
platform. This project allows you to do just that for applications written in
Go. There are two steps to this process: instrument your application, and
configure an exporter.

### Instrumentation

To start capturing distributed traces and metric events from your application
it first needs to be instrumented. The easiest way to do this is by using an
instrumentation library for your code. Be sure to check out [the officially
supported instrumentation
libraries](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main/instrumentation).

If you need to extend the telemetry an instrumentation library provides or want
to build your own instrumentation for your application directly you will need
to use the
[Go otel](https://pkg.go.dev/go.opentelemetry.io/otel)
package. The [examples](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main/examples)
are a good way to see some practical uses of this process.

### Export

Now that your application is instrumented to collect telemetry, it needs an
export pipeline to send that telemetry to an observability platform.

All officially supported exporters for the OpenTelemetry project are contained in the [exporters directory](./exporters).

| Exporter                              | Logs | Metrics | Traces |
|---------------------------------------|:----:|:-------:|:------:|
| [OTLP](./exporters/otlp/)             |  ✓   |    ✓    |   ✓    |
| [Prometheus](./exporters/prometheus/) |      |    ✓    |        |
| [stdout](./exporters/stdout/)         |  ✓   |    ✓    |   ✓    |
| [Zipkin](./exporters/zipkin/)         |      |         |   ✓    |

## Contributing

See the [contributing documentation](CONTRIBUTING.md).

### Emeritus

- [Alex Kats](https://github.com/akats7), Triager

For more information about the emeritus role, see the
[community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#emeritus-maintainerapprovertriager).

---

### Overview (`vendor/go.podman.io/storage/README.md`)

`storage` is a Go library which aims to provide methods for storing filesystem
layers, container images, and containers.  A `containers-storage` CLI wrapper
is also included for manual and scripting use.

To build the CLI wrapper, use 'make binary'.

Operations which use VMs expect to launch them using 'vagrant', defaulting to
using its 'libvirt' provider.  The boxes used are also available for the
'virtualbox' provider, and can be selected by setting $VAGRANT_PROVIDER to
'virtualbox' before kicking off the build.

The library manages three types of items: layers, images, and containers.

A *layer* is a copy-on-write filesystem which is notionally stored as a set of
changes relative to its *parent* layer, if it has one.  A given layer can only
have one parent, but any layer can be the parent of multiple layers.  Layers
which are parents of other layers should be treated as read-only.

An *image* is a reference to a particular layer (its _top_ layer), along with
other information which the library can manage for the convenience of its
caller.  This information typically includes configuration templates for
running a binary contained within the image's layers, and may include
cryptographic signatures.  Multiple images can reference the same layer, as the
differences between two images may not be in their layer contents.

A *container* is a read-write layer which is a child of an image's top layer,
along with information which the library can manage for the convenience of its
caller.  This information typically includes configuration information for
running the specific container.  Multiple containers can be derived from a
single image.

Layers, images, and containers are represented primarily by 32 character
hexadecimal IDs, but items of each kind can also have one or more arbitrary
names attached to them, which the library will automatically resolve to IDs
when they are passed in to API calls which expect IDs.

The library can store what it calls *metadata* for each of these types of
items.  This is expected to be a small piece of data, since it is cached in
memory and stored along with the library's own bookkeeping information.

Additionally, the library can store one or more of what it calls *big data* for
images and containers.  This is a named chunk of larger data, which is only in
memory when it is being read from or being written to its own disk file.

**[Contributing](../CONTRIBUTING.md)**
Information about contributing to this project.

---

### Overview (`vendor/google.golang.org/grpc/README.md`)

# gRPC-Go

[][API]
[](https://goreportcard.com/report/github.com/grpc/grpc-go)
[](https://codecov.io/gh/grpc/grpc-go)

The [Go][] implementation of [gRPC][]: A high performance, open source, general
RPC framework that puts mobile and HTTP/2 first. For more information see the
[Go gRPC docs][], or jump directly into the [quick start][].

## Prerequisites

- **[Go][]**: any one of the **two latest major** [releases][go-releases].

## Installation

Simply add the following import to your code, and then `go [build|run|test]`
will automatically fetch the necessary dependencies:


```go
import "google.golang.org/grpc"
```

> **Note:** If you are trying to access `grpc-go` from **China**, see the
> [FAQ](#FAQ) below.

## Learn more

- [Go gRPC docs][], which include a [quick start][] and [API
  reference][API] among other resources
- [Low-level technical docs](Documentation) from this repository
- [Performance benchmark][]
- [Examples](examples)
- [Contribution guidelines](CONTRIBUTING.md)

## FAQ

### I/O Timeout Errors

The `golang.org` domain may be blocked from some countries. `go get` usually
produces an error like the following when this happens:

```console
$ go get -u google.golang.org/grpc
package google.golang.org/grpc: unrecognized import path "google.golang.org/grpc" (https fetch: Get https://google.golang.org/grpc?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)
```

To build Go code, there are several options:

- Set up a VPN and access google.golang.org through that.

- With Go module support: it is possible to use the `replace` feature of `go
  mod` to create aliases for golang.org packages.  In your project's directory:

  ```sh
  go mod edit -replace=google.golang.org/grpc=github.com/grpc/grpc-go@latest
  go mod tidy
  go mod vendor
  go build -mod=vendor
  ```

  Again, this will need to be done for all transitive dependencies hosted on
  golang.org as well. For details, refer to [golang/go issue
  #28652](https://github.com/golang/go/issues/28652).

### Compiling error, undefined: grpc.SupportPackageIsVersion

Please update to the latest version of gRPC-Go using
`go get google.golang.org/grpc`.

### How to turn on logging

The default logger is controlled by environment variables. Turn everything on
like this:

```console
$ export GRPC_GO_LOG_VERBOSITY_LEVEL=99
$ export GRPC_GO_LOG_SEVERITY_LEVEL=info
```

### The RPC failed with error `"code = Unavailable desc = transport is closing"`

This error means the connection the RPC is using was closed, and there are many
possible reasons, including:
 1. mis-configured transport credentials, connection failed on handshaking
 1. bytes disrupted, possibly by a proxy in between
 1. server shutdown
 1. Keepalive parameters caused connection shutdown, for example if you have
    configured your server to terminate connections regularly to [trigger DNS
    lookups](https://github.com/grpc/grpc-go/issues/3170#issuecomment-552517779).
    If this is the case, you may want to increase your
    [MaxConnectionAgeGrace](https://pkg.go.dev/google.golang.org/grpc/keepalive?tab=doc#ServerParameters),
    to allow longer RPC calls to finish.

It can be tricky to debug this because the error happens on the client side but
the root cause of the connection being closed is on the server side. Turn on
logging on __both client and server__, and see if there are any transport
errors.

[API]: https://pkg.go.dev/google.golang.org/grpc
[Go]: https://golang.org
[Go module]: https://github.com/golang/go/wiki/Modules
[gRPC]: https://grpc.io
[Go gRPC docs]: https://grpc.io/docs/languages/go
[Performance benchmark]: https://performance-dot-grpc-testing.appspot.com/explore?dashboard=5180705743044608
[quick start]: https://grpc.io/docs/languages/go/quickstart
[go-releases]: https://golang.org/doc/devel/release.html

---

### Overview (`vendor/github.com/BurntSushi/toml/README.md`)

TOML stands for Tom's Obvious, Minimal Language. This Go package provides a
reflection interface similar to Go's standard library `json` and `xml` packages.

Compatible with TOML version [v1.1.0](https://toml.io/en/v1.1.0).

Documentation: https://pkg.go.dev/github.com/BurntSushi/toml

See the [releases page](https://github.com/BurntSushi/toml/releases) for a
changelog; this information is also in the git tag annotations (e.g. `git show
v0.4.0`).

This library requires Go 1.18 or newer; add it to your go.mod with:

    % go get github.com/BurntSushi/toml@latest

It also comes with a TOML validator CLI tool:

    % go install github.com/BurntSushi/toml/cmd/tomlv@latest
    % tomlv some-toml-file.toml

### Examples
For the simplest example, consider some TOML file as just a list of keys and
values:

```toml
Age = 25
Cats = [ "Cauchy", "Plato" ]
Pi = 3.14
Perfection = [ 6, 28, 496, 8128 ]
DOB = 1987-07-05T05:45:00Z
```

Which can be decoded with:

```go
type Config struct {
	Age        int
	Cats       []string
	Pi         float64
	Perfection []int
	DOB        time.Time
}

var conf Config
_, err := toml.Decode(tomlData, &conf)
```

You can also use struct tags if your struct field name doesn't map to a TOML key
value directly:

```toml
some_key_NAME = "wat"
```

```go
type TOML struct {
    ObscureKey string `toml:"some_key_NAME"`
}
```

Beware that like other decoders **only exported fields** are considered when
encoding and decoding; private fields are silently ignored.

### Using the `Marshaler` and `encoding.TextUnmarshaler` interfaces
Here's an example that automatically parses values in a `mail.Address`:

```toml
contacts = [
    "Donald Duck <donald@duckburg.com>",
    "Scrooge McDuck <scrooge@duckburg.com>",
]
```

Can be decoded with:

```go
// Create address type which satisfies the encoding.TextUnmarshaler interface.
type address struct {
	*mail.Address
}

func (a *address) UnmarshalText(text []byte) error {
	var err error
	a.Address, err = mail.ParseAddress(string(text))
	return err
}

// Decode it.
func decode() {
	blob := `
		contacts = [
			"Donald Duck <donald@duckburg.com>",
			"Scrooge McDuck <scrooge@duckburg.com>",
		]
	`

	var contacts struct {
		Contacts []address
	}

	_, err := toml.Decode(blob, &contacts)
	if err != nil {
		log.Fatal(err)
	}

	for _, c := range contacts.Contacts {
		fmt.Printf("%#v\n", c.Address)
	}

	// Output:
	// &mail.Address{Name:"Donald Duck", Address:"donald@duckburg.com"}
	// &mail.Address{Name:"Scrooge McDuck", Address:"scrooge@duckburg.com"}
}
```

To target TOML specifically you can implement `UnmarshalTOML` TOML interface in
a similar way.

### More complex usage
See the [`_example/`](/_example) directory for a more complex example.

---

### Overview (`vendor/github.com/Microsoft/go-winio/README.md`)

# go-winio [](https://github.com/microsoft/go-winio/actions/workflows/ci.yml)

This repository contains utilities for efficiently performing Win32 IO operations in
Go. Currently, this is focused on accessing named pipes and other file handles, and
for using named pipes as a net transport.

This code relies on IO completion ports to avoid blocking IO on system threads, allowing Go
to reuse the thread to schedule another goroutine. This limits support to Windows Vista and
newer operating systems. This is similar to the implementation of network sockets in Go's net
package.

Please see the LICENSE file for licensing information.

## Contributing

This project welcomes contributions and suggestions.
Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that
you have the right to, and actually do, grant us the rights to use your contribution.
For details, visit [Microsoft CLA](https://cla.microsoft.com).

When you submit a pull request, a CLA-bot will automatically determine whether you need to
provide a CLA and decorate the PR appropriately (e.g., label, comment).
Simply follow the instructions provided by the bot.
You will only need to do this once across all repos using our CLA.

Additionally, the pull request pipeline requires the following steps to be performed before
mergining.

### Code Sign-Off

We require that contributors sign their commits using [`git commit --signoff`][git-commit-s]
to certify they either authored the work themselves or otherwise have permission to use it in this project.

A range of commits can be signed off using [`git rebase --signoff`][git-rebase-s].

Please see [the developer certificate](https://developercertificate.org) for more info,
as well as to make sure that you can attest to the rules listed.
Our CI uses the DCO Github app to ensure that all commits in a given PR are signed-off.

### Linting

Code must pass a linting stage, which uses [`golangci-lint`][lint].
The linting settings are stored in [`.golangci.yaml`](./.golangci.yaml), and can be run
automatically with VSCode by adding the following to your workspace or folder settings:

```json
    "go.lintTool": "golangci-lint",
    "go.lintOnSave": "package",
```

Additional editor [integrations options are also available][lint-ide].

Alternatively, `golangci-lint` can be [installed locally][lint-install] and run from the repo root:

```shell
# use . or specify a path to only lint a package
# to show all lint errors, use flags "--max-issues-per-linter=0 --max-same-issues=0"
> golangci-lint run ./...
```

### Go Generate

The pipeline checks that auto-generated code, via `go generate`, are up to date.

This can be done for the entire repo:

```shell
> go generate ./...
```

## Code of Conduct

This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.

## Special Thanks

Thanks to [natefinch][natefinch] for the inspiration for this library.
See [npipe](https://github.com/natefinch/npipe) for another named pipe implementation.

[lint]: https://golangci-lint.run/
[lint-ide]: https://golangci-lint.run/usage/integrations/#editor-integration
[lint-install]: https://golangci-lint.run/usage/install/#local-installation

[git-commit-s]: https://git-scm.com/docs/git-commit#Documentation/git-commit.txt--s
[git-rebase-s]: https://git-scm.com/docs/git-rebase#Documentation/git-rebase.txt---signoff

[natefinch]: https://github.com/natefinch

---

### Overview (`vendor/github.com/VividCortex/ewma/README.md`)

# EWMA

[](https://godoc.org/github.com/VividCortex/ewma)

[](https://codecov.io/gh/VividCortex/ewma)

This repo provides Exponentially Weighted Moving Average algorithms, or EWMAs for short, [based on our
Quantifying Abnormal Behavior talk](https://vividcortex.com/blog/2013/07/23/a-fast-go-library-for-exponential-moving-averages/).

### Exponentially Weighted Moving Average

An exponentially weighted moving average is a way to continuously compute a type of
average for a series of numbers, as the numbers arrive. After a value in the series is
added to the average, its weight in the average decreases exponentially over time. This
biases the average towards more recent data. EWMAs are useful for several reasons, chiefly
their inexpensive computational and memory cost, as well as the fact that they represent
the recent central tendency of the series of values.

The EWMA algorithm requires a decay factor, alpha. The larger the alpha, the more the average
is biased towards recent history. The alpha must be between 0 and 1, and is typically
a fairly small number, such as 0.04. We will discuss the choice of alpha later.

The algorithm works thus, in pseudocode:

1. Multiply the next number in the series by alpha.
2. Multiply the current value of the average by 1 minus alpha.
3. Add the result of steps 1 and 2, and store it as the new current value of the average.
4. Repeat for each number in the series.

There are special-case behaviors for how to initialize the current value, and these vary
between implementations. One approach is to start with the first value in the series;
another is to average the first 10 or so values in the series using an arithmetic average,
and then begin the incremental updating of the average. Each method has pros and cons.

It may help to look at it pictorially. Suppose the series has five numbers, and we choose
alpha to be 0.50 for simplicity. Here's the series, with numbers in the neighborhood of 300.



Now let's take the moving average of those numbers. First we set the average to the value
of the first number.



Next we multiply the next number by alpha, multiply the current value by 1-alpha, and add
them to generate a new value.



This continues until we are done.



Notice how each of the values in the series decays by half each time a new value
is added, and the top of the bars in the lower portion of the image represents the
size of the moving average. It is a smoothed, or low-pass, average of the original
series.

For further reading, see [Exponentially weighted moving average](http://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average) on wikipedia.

### Choosing Alpha

Consider a fixed-size sliding-window moving average (not an exponentially weighted moving average)
that averages over the previous N samples. What is the average age of each sample? It is N/2.

Now suppose that you wish to construct a EWMA whose samples have the same average age. The formula
to compute the alpha required for this is: alpha = 2/(N+1). Proof is in the book
"Production and Operations Analysis" by Steven Nahmias.

So, for example, if you have a time-series with samples once per second, and you want to get the
moving average over the previous minute, you should use an alpha of .032786885. This, by the way,
is the constant alpha used for this repository's SimpleEWMA.

### Implementations

This repository contains two implementations of the EWMA algorithm, with different properties.

The implementations all conform to the MovingAverage interface, and the constructor returns
that type.

Current implementations assume an implicit time interval of 1.0 between every sample added.
That is, the passage of time is treated as though it's the same as the arrival of samples.
If you need time-based decay when samples are not arriving precisely at set intervals, then
this package will not support your needs at present.

#### SimpleEWMA

A SimpleEWMA is designed for low CPU and memory consumption. It **will** have different behavior than the VariableEWMA
for multiple reasons. It has no warm-up period and it uses a constant
decay.  These properties let it use less memory.  It will also behave
differently when it's equal to zero, which is assumed to mean
uninitialized, so if a value is likely to actually become zero over time,
then any non-zero value will cause a sharp jump instead of a small change.

#### VariableEWMA

Unlike SimpleEWMA, this supports a custom age which must be stored, and thus uses more memory.
It also has a "warmup" time when you start adding values to it. It will report a value of 0.0
until you have added the required number of samples to it. It uses some memory to store the
number of samples added to it. As a result it uses a little over twice the memory of SimpleEWMA.

## Usage

### API Documentation

View the GoDoc generated documentation [here](http://godoc.org/github.com/VividCortex/ewma).

```go
package main

import "github.com/VividCortex/ewma"

func main() {
	samples := [100]float64{
		4599, 5711, 4746, 4621, 5037, 4218, 4925, 4281, 5207, 5203, 5594, 5149,
	}

	e := ewma.NewMovingAverage()  //=> Returns a SimpleEWMA if called without params
	a := ewma.NewMovingAverage(5) //=> returns a VariableEWMA with a decay of 2 / (5 + 1)

	for _, f := range samples {
		e.Add(f)
		a.Add(f)
	}

	e.Value() //=> 13.577404704631077
	a.Value() //=> 1.5806140565521463e-12
}
```

## Contributing

We only accept pull requests for minor fixes or improvements. This includes:

* Small bug fixes
* Typos
* Documentation or comments

Please open issues to discuss new features. Pull requests for new features will be rejected,
so we recommend forking the repository and making changes in your fork for your use case.

## License

This repository is Copyright (c) 2013 VividCortex, Inc. All rights reserved.
It is licensed under the MIT license. Please see the LICENSE file for applicable license terms.

---

### Overview (`vendor/github.com/acarl005/stripansi/README.md`)

Strip ANSI
==========

This Go package removes ANSI escape codes from strings.

Ideally, we would prevent these from appearing in any text we want to process.
However, sometimes this can't be helped, and we need to be able to deal with that noise.
This will use a regexp to remove those unwanted escape codes.


## Install

```sh
$ go get -u github.com/acarl005/stripansi
```

## Usage

```go
import (
	"fmt"
	"github.com/acarl005/stripansi"
)

func main() {
	msg := "\x1b[38;5;140m foo\x1b[0m bar"
	cleanMsg := stripansi.Strip(msg)
	fmt.Println(cleanMsg) // " foo bar"
}
```

---

### Overview (`vendor/github.com/containerd/errdefs/README.md`)

# errdefs

A Go package for defining and checking common containerd errors.

## Project details

**errdefs** is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE).
As a containerd sub-project, you will find the:
 * [Project governance](https://github.com/containerd/project/blob/main/GOVERNANCE.md),
 * [Maintainers](https://github.com/containerd/project/blob/main/MAINTAINERS),
 * and [Contributing guidelines](https://github.com/containerd/project/blob/main/CONTRIBUTING.md)

information in our [`containerd/project`](https://github.com/containerd/project) repository.

---

### Overview (`vendor/github.com/containers/libtrust/README.md`)

# libtrust

> **WARNING** this library is no longer actively developed, and will be integrated
> in the [docker/distribution][https://www.github.com/docker/distribution]
> repository in future.

Libtrust is library for managing authentication and authorization using public key cryptography.

Authentication is handled using the identity attached to the public key.
Libtrust provides multiple methods to prove possession of the private key associated with an identity.
 - TLS x509 certificates
 - Signature verification
 - Key Challenge

Authorization and access control is managed through a distributed trust graph.
Trust servers are used as the authorities of the trust graph and allow caching portions of the graph for faster access.

## Copyright and license

Code and documentation copyright 2014 Docker, inc. Code released under the Apache 2.0 license.
Docs released under Creative commons.

---

### Overview (`vendor/github.com/containers/ocicrypt/README.md`)

# OCIcrypt Library

The `ocicrypt` library is the OCI image spec implementation of container image encryption. More details of the spec can be seen in the [OCI repository](https://github.com/opencontainers/image-spec/pull/775). The purpose of this library is to encode spec structures and consts in code, as well as provide a consistent implementation of image encryption across container runtimes and build tools.

Consumers of OCIcrypt:

- [containerd/imgcrypt](https://github.com/containerd/imgcrypt)
- [cri-o](https://github.com/cri-o/cri-o)
- [skopeo](https://github.com/containers/skopeo)


## Usage

There are various levels of usage for this library. The main consumers of these would be runtime/build tools, and a more specific use would be in the ability to extend cryptographic function.

### Runtime/Build tool usage

The general exposed interface a runtime/build tool would use, would be to perform encryption or decryption of layers:

```
package "github.com/containers/ocicrypt"
func EncryptLayer(ec *config.EncryptConfig, encOrPlainLayerReader io.Reader, desc ocispec.Descriptor) (io.Reader, EncryptLayerFinalizer, error)
func DecryptLayer(dc *config.DecryptConfig, encLayerReader io.Reader, desc ocispec.Descriptor, unwrapOnly bool) (io.Reader, digest.Digest, error)
```

The settings/parameters to these functions can be specified via creation of an encryption config with the `github.com/containers/ocicrypt/config` package. We note that because setting of annotations and other fields of the layer descriptor is done through various means in different runtimes/build tools, it is the responsibility of the caller to still ensure that the layer descriptor follows the OCI specification (i.e. encoding, setting annotations, etc.).


### Crypto Agility and Extensibility

The implementation for both symmetric and asymmetric encryption used in this library are behind 2 main interfaces, which users can extend if need be. These are in the following packages:
- github.com/containers/ocicrypt/blockcipher - LayerBlockCipher interface for block ciphers
- github.com/containers/ocicrypt/keywrap - KeyWrapper interface for key wrapping

We note that adding interfaces here is risky outside the OCI spec is not recommended, unless for very specialized and confined usecases. Please open an issue or PR if there is a general usecase that could be added to the OCI spec.


#### Keyprovider interface

As part of the keywrap interface, there is a [keyprovider](https://github.com/containers/ocicrypt/blob/main/docs/keyprovider.md) implementation that allows one to call out to a binary or service.


## Security Issues

We consider security issues related to this library critical. Please report and security related issues by emailing maintainers in the [MAINTAINERS](MAINTAINERS) file.


## Ocicrypt Pkcs11 Support

Ocicrypt Pkcs11 support is currently experiemental. For more details, please refer to the [this document](docs/pkcs11.md).

---

### Overview (`vendor/github.com/cyphar/filepath-securejoin/README.md`)

## `filepath-securejoin` ##

[](https://pkg.go.dev/github.com/cyphar/filepath-securejoin)
[](https://github.com/cyphar/filepath-securejoin/actions/workflows/ci.yml)

### Old API ###

This library was originally just an implementation of `SecureJoin` which was
[intended to be included in the Go standard library][go#20126] as a safer
`filepath.Join` that would restrict the path lookup to be inside a root
directory.

The implementation was based on code that existed in several container
runtimes. Unfortunately, this API is **fundamentally unsafe** against attackers
that can modify path components after `SecureJoin` returns and before the
caller uses the path, allowing for some fairly trivial TOCTOU attacks.

`SecureJoin` (and `SecureJoinVFS`) are still provided by this library to
support legacy users, but new users are strongly suggested to avoid using
`SecureJoin` and instead use the [new api](#new-api) or switch to
[libpathrs][libpathrs].

With the above limitations in mind, this library guarantees the following:

* If no error is set, the resulting string **must** be a child path of
  `root` and will not contain any symlink path components (they will all be
  expanded).

* When expanding symlinks, all symlink path components **must** be resolved
  relative to the provided root. In particular, this can be considered a
  userspace implementation of how `chroot(2)` operates on file paths. Note that
  these symlinks will **not** be expanded lexically (`filepath.Clean` is not
  called on the input before processing).

* Non-existent path components are unaffected by `SecureJoin` (similar to
  `filepath.EvalSymlinks`'s semantics).

* The returned path will always be `filepath.Clean`ed and thus not contain any
  `..` components.

A (trivial) implementation of this function on GNU/Linux systems could be done
with the following (note that this requires root privileges and is far more
opaque than the implementation in this library, and also requires that
`readlink` is inside the `root` path and is trustworthy):

```go
package securejoin

import (
	"os/exec"
	"path/filepath"
)

func SecureJoin(root, unsafePath string) (string, error) {
	unsafePath = string(filepath.Separator) + unsafePath
	cmd := exec.Command("chroot", root,
		"readlink", "--canonicalize-missing", "--no-newline", unsafePath)
	output, err := cmd.CombinedOutput()
	if err != nil {
		return "", err
	}
	expanded := string(output)
	return filepath.Join(root, expanded), nil
}
```

[libpathrs]: https://github.com/openSUSE/libpathrs
[go#20126]: https://github.com/golang/go/issues/20126

### <a name="new-api" /> New API ###
[#new-api]: #new-api

While we recommend users switch to [libpathrs][libpathrs] as soon as it has a
stable release, some methods implemented by libpathrs have been ported to this
library to ease the transition. These APIs are only supported on Linux.

These APIs are implemented such that `filepath-securejoin` will
opportunistically use certain newer kernel APIs that make these operations far
more secure. In particular:

* All of the lookup operations will use [`openat2`][openat2.2] on new enough
  kernels (Linux 5.6 or later) to restrict lookups through magic-links and
  bind-mounts (for certain operations) and to make use of `RESOLVE_IN_ROOT` to
  efficiently resolve symlinks within a rootfs.

* The APIs provide hardening against a malicious `/proc` mount to either detect
  or avoid being tricked by a `/proc` that is not legitimate. This is done
  using [`openat2`][openat2.2] for all users, and privileged users will also be
  further protected by using [`fsopen`][fsopen.2] and [`open_tree`][open_tree.2]
  (Linux 5.2 or later).

[openat2.2]: https://www.man7.org/linux/man-pages/man2/openat2.2.html
[fsopen.2]: https://github.com/brauner/man-pages-md/blob/main/fsopen.md
[open_tree.2]: https://github.com/brauner/man-pages-md/blob/main/open_tree.md

#### `OpenInRoot` ####

```go
func OpenInRoot(root, unsafePath string) (*os.File, error)
func OpenatInRoot(root *os.File, unsafePath string) (*os.File, error)
func Reopen(handle *os.File, flags int) (*os.File, error)
```

`OpenInRoot` is a much safer version of

```go
path, err := securejoin.SecureJoin(root, unsafePath)
file, err := os.OpenFile(path, unix.O_PATH|unix.O_CLOEXEC)
```

that protects against various race attacks that could lead to serious security
issues, depending on the application. Note that the returned `*os.File` is an
`O_PATH` file descriptor, which is quite restricted. Callers will probably need
to use `Reopen` to get a more usable handle (this split is done to provide
useful features like PTY spawning and to avoid users accidentally opening bad
inodes that could cause a DoS).

Callers need to be careful in how they use the returned `*os.File`. Usually it
is only safe to operate on the handle directly, and it is very easy to create a
security issue. [libpathrs][libpathrs] provides far more helpers to make using
these handles safer -- there is currently no plan to port them to
`filepath-securejoin`.

`OpenatInRoot` is like `OpenInRoot` except that the root is provided using an
`*os.File`. This allows you to ensure that multiple `OpenatInRoot` (or
`MkdirAllHandle`) calls are operating on the same rootfs.

> **NOTE**: Unlike `SecureJoin`, `OpenInRoot` will error out as soon as it hits
> a dangling symlink or non-existent path. This is in contrast to `SecureJoin`
> which treated non-existent components as though they were real directories,
> and would allow for partial resolution of dangling symlinks. These behaviours
> are at odds with how Linux treats non-existent paths and dangling symlinks,
> and so these are no longer allowed.

#### `MkdirAll` ####

```go
func MkdirAll(root, unsafePath string, mode int) error
func MkdirAllHandle(root *os.File, unsafePath string, mode int) (*os.File, error)
```

`MkdirAll` is a much safer version of

```go
path, err := securejoin.SecureJoin(root, unsafePath)
err = os.MkdirAll(path, mode)
```

that protects against the same kinds of races that `OpenInRoot` protects
against.

`MkdirAllHandle` is like `MkdirAll` except that the root is provided using an
`*os.File` (the reason for this is the same as with `OpenatInRoot`) and an
`*os.File` of the final created directory is returned (this directory is
guaranteed to be effectively identical to the directory created by
`MkdirAllHandle`, which is not possible to ensure by just using `OpenatInRoot`
after `MkdirAll`).

> **NOTE**: Unlike `SecureJoin`, `MkdirAll` will error out as soon as it hits
> a dangling symlink or non-existent path. This is in contrast to `SecureJoin`
> which treated non-existent components as though they were real directories,
> and would allow for partial resolution of dangling symlinks. These behaviours
> are at odds with how Linux treats non-existent paths and dangling symlinks,
> and so these are no longer allowed. This means that `MkdirAll` will not
> create non-existent directories referenced by a dangling symlink.

### License ###

`SPDX-License-Identifier: BSD-3-Clause AND MPL-2.0`

Some of the code in this project is derived from Go, and is licensed under a
BSD 3-clause license (available in `LICENSE.BSD`). Other files (many of which
are derived from [libpathrs][libpathrs]) are licensed under the Mozilla Public
License version 2.0 (available in `LICENSE.MPL-2.0`). If you are using the
["New API" described above][#new-api], you are probably using code from files
released under this license.

Every source file in this project has a copyright header describing its
license. Please check the license headers of each file to see what license
applies to it.

See [COPYING.md](./COPYING.md) for some more details.

[umoci]: https://github.com/opencontainers/umoci

---

### Overview (`vendor/github.com/distribution/reference/README.md`)

# Distribution reference

Go library to handle references to container images.

<img src="/distribution-logo.svg" width="200px" />

[](https://github.com/distribution/reference/actions?query=workflow%3ACI)
[](https://pkg.go.dev/github.com/distribution/reference)
[](LICENSE)
[](https://codecov.io/gh/distribution/reference)
[](https://app.fossa.com/projects/custom%2B162%2Fgithub.com%2Fdistribution%2Freference?ref=badge_shield)

This repository contains a library for handling references to container images held in container registries. Please see [godoc](https://pkg.go.dev/github.com/distribution/reference) for details.

## Contribution

Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute
issues, fixes, and patches to this project.

## Communication

For async communication and long running discussions please use issues and pull requests on the github repo.
This will be the best place to discuss design and implementation.

For sync communication we have a #distribution channel in the [CNCF Slack](https://slack.cncf.io/)
that everyone is welcome to join and chat about development.

## Licenses

The distribution codebase is released under the [Apache 2.0 license](LICENSE).

---

### Overview (`vendor/github.com/docker/go-units/README.md`)

[](https://godoc.org/github.com/docker/go-units)

# Introduction

go-units is a library to transform human friendly measurements into machine friendly values.

## Usage

See the [docs in godoc](https://godoc.org/github.com/docker/go-units) for examples and documentation.

## Copyright and license

Copyright © 2015 Docker, Inc.

go-units is licensed under the Apache License, Version 2.0.
See [LICENSE](LICENSE) for the full text of the license.

---

### Overview (`vendor/github.com/felixge/httpsnoop/README.md`)

# httpsnoop

Package httpsnoop provides an easy way to capture http related metrics (i.e.
response time, bytes written, and http status code) from your application's
http.Handlers.

Doing this requires non-trivial wrapping of the http.ResponseWriter interface,
which is also exposed for users interested in a more low-level API.

[](https://pkg.go.dev/github.com/felixge/httpsnoop)
[](https://github.com/felixge/httpsnoop/actions/workflows/main.yaml)

## Usage Example

```go
// myH is your app's http handler, perhaps a http.ServeMux or similar.
var myH http.Handler
// wrappedH wraps myH in order to log every request.
wrappedH := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	m := httpsnoop.CaptureMetrics(myH, w, r)
	log.Printf(
		"%s %s (code=%d dt=%s written=%d)",
		r.Method,
		r.URL,
		m.Code,
		m.Duration,
		m.Written,
	)
})
http.ListenAndServe(":8080", wrappedH)
```

## Why this package exists

Instrumenting an application's http.Handler is surprisingly difficult.

However if you google for e.g. "capture ResponseWriter status code" you'll find
lots of advise and code examples that suggest it to be a fairly trivial
undertaking. Unfortunately everything I've seen so far has a high chance of
breaking your application.

The main problem is that a `http.ResponseWriter` often implements additional
interfaces such as `http.Flusher`, `http.CloseNotifier`, `http.Hijacker`, `http.Pusher`, and
`io.ReaderFrom`. So the naive approach of just wrapping `http.ResponseWriter`
in your own struct that also implements the `http.ResponseWriter` interface
will hide the additional interfaces mentioned above. This has a high change of
introducing subtle bugs into any non-trivial application.

Another approach I've seen people take is to return a struct that implements
all of the interfaces above. However, that's also problematic, because it's
difficult to fake some of these interfaces behaviors when the underlying
`http.ResponseWriter` doesn't have an implementation. It's also dangerous,
because an application may choose to operate differently, merely because it
detects the presence of these additional interfaces.

This package solves this problem by checking which additional interfaces a
`http.ResponseWriter` implements, returning a wrapped version implementing the
exact same set of interfaces.

Additionally this package properly handles edge cases such as `WriteHeader` not
being called, or called more than once, as well as concurrent calls to
`http.ResponseWriter` methods, and even calls happening after the wrapped
`ServeHTTP` has already returned.

Unfortunately this package is not perfect either. It's possible that it is
still missing some interfaces provided by the go core (let me know if you find
one), and it won't work for applications adding their own interfaces into the
mix. You can however use `httpsnoop.Unwrap(w)` to access the underlying
`http.ResponseWriter` and type-assert the result to its other interfaces.

However, hopefully the explanation above has sufficiently scared you of rolling
your own solution to this problem. httpsnoop may still break your application,
but at least it tries to avoid it as much as possible.

Anyway, the real problem here is that smuggling additional interfaces inside
`http.ResponseWriter` is a problematic design choice, but it probably goes as
deep as the Go language specification itself. But that's okay, I still prefer
Go over the alternatives ;).

## Performance

```
BenchmarkBaseline-8      	   20000	     94912 ns/op
BenchmarkCaptureMetrics-8	   20000	     95461 ns/op
```

As you can see, using `CaptureMetrics` on a vanilla http.Handler introduces an
overhead of ~500 ns per http request on my machine. However, the margin of
error appears to be larger than that, therefor it should be reasonable to
assume that the overhead introduced by `CaptureMetrics` is absolutely
negligible.

## License

MIT

---

### Overview (`vendor/github.com/go-logr/logr/README.md`)

# A minimal logging API for Go

[](https://pkg.go.dev/github.com/go-logr/logr)
[](https://goreportcard.com/report/github.com/go-logr/logr)
[](https://securityscorecards.dev/viewer/?platform=github.com&org=go-logr&repo=logr)

logr offers an(other) opinion on how Go programs and libraries can do logging
without becoming coupled to a particular logging implementation.  This is not
an implementation of logging - it is an API.  In fact it is two APIs with two
different sets of users.

The `Logger` type is intended for application and library authors.  It provides
a relatively small API which can be used everywhere you want to emit logs.  It
defers the actual act of writing logs (to files, to stdout, or whatever) to the
`LogSink` interface.

The `LogSink` interface is intended for logging library implementers.  It is a
pure interface which can be implemented by logging frameworks to provide the actual logging
functionality.

This decoupling allows application and library developers to write code in
terms of `logr.Logger` (which has very low dependency fan-out) while the
implementation of logging is managed "up stack" (e.g. in or near `main()`.)
Application developers can then switch out implementations as necessary.

Many people assert that libraries should not be logging, and as such efforts
like this are pointless.  Those people are welcome to convince the authors of
the tens-of-thousands of libraries that *DO* write logs that they are all
wrong.  In the meantime, logr takes a more practical approach.

## Typical usage

Somewhere, early in an application's life, it will make a decision about which
logging library (implementation) it actually wants to use.  Something like:

```
    func main() {
        // ... other setup code ...

        // Create the "root" logger.  We have chosen the "logimpl" implementation,
        // which takes some initial parameters and returns a logr.Logger.
        logger := logimpl.New(param1, param2)

        // ... other setup code ...
```

Most apps will call into other libraries, create structures to govern the flow,
etc.  The `logr.Logger` object can be passed to these other libraries, stored
in structs, or even used as a package-global variable, if needed.  For example:

```
    app := createTheAppObject(logger)
    app.Run()
```

Outside of this early setup, no other packages need to know about the choice of
implementation.  They write logs in terms of the `logr.Logger` that they
received:

```
    type appObject struct {
        // ... other fields ...
        logger logr.Logger
        // ... other fields ...
    }

    func (app *appObject) Run() {
        app.logger.Info("starting up", "timestamp", time.Now())

        // ... app code ...
```

## Background

If the Go standard library had defined an interface for logging, this project
probably would not be needed.  Alas, here we are.

When the Go developers started developing such an interface with
[slog](https://github.com/golang/go/issues/56345), they adopted some of the
logr design but also left out some parts and changed others:

| Feature | logr | slog |
|---------|------|------|
| High-level API | `Logger` (passed by value) | `Logger` (passed by [pointer](https://github.com/golang/go/issues/59126)) |
| Low-level API | `LogSink` | `Handler` |
| Stack unwinding | done by `LogSink` | done by `Logger` |
| Skipping helper functions | `WithCallDepth`, `WithCallStackHelper` | [not supported by Logger](https://github.com/golang/go/issues/59145) |
| Generating a value for logging on demand | `Marshaler` | `LogValuer` |
| Log levels | >= 0, higher meaning "less important" | positive and negative, with 0 for "info" and higher meaning "more important" |
| Error log entries | always logged, don't have a verbosity level | normal log entries with level >= `LevelError` |
| Passing logger via context | `NewContext`, `FromContext` | no API |
| Adding a name to a logger | `WithName` | no API |
| Modify verbosity of log entries in a call chain | `V` | no API |
| Grouping of key/value pairs | not supported | `WithGroup`, `GroupValue` |
| Pass context for extracting additional values | no API | API variants like `InfoCtx` |

The high-level slog API is explicitly meant to be one of many different APIs
that can be layered on top of a shared `slog.Handler`. logr is one such
alternative API, with [interoperability](#slog-interoperability) provided by
some conversion functions.

### Inspiration

Before you consider this package, please read [this blog post by the
inimitable Dave Cheney][warning-makes-no-sense].  We really appreciate what
he has to say, and it largely aligns with our own experiences.

### Differences from Dave's ideas

The main differences are:

1. Dave basically proposes doing away with the notion of a logging API in favor
of `fmt.Printf()`.  We disagree, especially when you consider things like output
locations, timestamps, file and line decorations, and structured logging.  This
package restricts the logging API to just 2 types of logs: info and error.

Info logs are things you want to tell the user which are not errors.  Error
logs are, well, errors.  If your code receives an `error` from a subordinate
function call and is logging that `error` *and not returning it*, use error
logs.

2. Verbosity-levels on info logs.  This gives developers a chance to indicate
arbitrary grades of importance for info logs, without assigning names with
semantic meaning such as "warning", "trace", and "debug."  Superficially this
may feel very similar, but the primary difference is the lack of semantics.
Because verbosity is a numerical value, it's safe to assume that an app running
with higher verbosity means more (and less important) logs will be generated.

## Implementations (non-exhaustive)

There are implementations for the following logging libraries:

- **a function** (can bridge to non-structured libraries): [funcr](https://github.com/go-logr/logr/tree/master/funcr)
- **a testing.T** (for use in Go tests, with JSON-like output): [testr](https://github.com/go-logr/logr/tree/master/testr)
- **github.com/google/glog**: [glogr](https://github.com/go-logr/glogr)
- **k8s.io/klog** (for Kubernetes): [klogr](https://git.k8s.io/klog/klogr)
- **a testing.T** (with klog-like text output): [ktesting](https://git.k8s.io/klog/ktesting)
- **go.uber.org/zap**: [zapr](https://github.com/go-logr/zapr)
- **log** (the Go standard library logger): [stdr](https://github.com/go-logr/stdr)
- **github.com/sirupsen/logrus**: [logrusr](https://github.com/bombsimon/logrusr)
- **github.com/wojas/genericr**: [genericr](https://github.com/wojas/genericr) (makes it easy to implement your own backend)
- **logfmt** (Heroku style [logging](https://www.brandur.org/logfmt)): [logfmtr](https://github.com/iand/logfmtr)
- **github.com/rs/zerolog**: [zerologr](https://github.com/go-logr/zerologr)
- **github.com/go-kit/log**: [gokitlogr](https://github.com/tonglil/gokitlogr) (also compatible with github.com/go-kit/kit/log since v0.12.0)
- **bytes.Buffer** (writing to a buffer): [bufrlogr](https://github.com/tonglil/buflogr) (useful for ensuring values were logged, like during testing)

## slog interoperability

Interoperability goes both ways, using the `logr.Logger` API with a `slog.Handler`
and using the `slog.Logger` API with a `logr.LogSink`. `FromSlogHandler` and
`ToSlogHandler` convert between a `logr.Logger` and a `slog.Handler`.
As usual, `slog.New` can be used to wrap such a `slog.Handler` in the high-level
slog API.

### Using a `logr.LogSink` as backend for slog

Ideally, a logr sink implementation should support both logr and slog by
implementing both the normal logr interface(s) and `SlogSink`.  Because
of a conflict in the parameters of the common `Enabled` method, it is [not
possible to implement both slog.Handler and logr.Sink in the same
type](https://github.com/golang/go/issues/59110).

If both are supported, log calls can go from the high-level APIs to the backend
without the need to convert parameters. `FromSlogHandler` and `ToSlogHandler` can
convert back and forth without adding additional wrappers, with one exception:
when `Logger.V` was used to adjust the verbosity for a `slog.Handler`, then
`ToSlogHandler` has to use a wrapper which adjusts the verbosity for future
log calls.

Such an implementation should also support values that implement specific
interfaces from both packages for logging (`logr.Marshaler`, `slog.LogValuer`,
`slog.GroupValue`). logr does not convert those.

Not supporting slog has several drawbacks:
- Recording source code locations works correctly if the handler gets called
  through `slog.Logger`, but may be wrong in other cases. That's because a
  `logr.Sink` does its own stack unwinding instead of using the program counter
  provided by the high-level API.
- slog levels <= 0 can be mapped to logr levels by negating the level without a
  loss of information. But all slog levels > 0 (e.g. `slog.LevelWarning` as
  used by `slog.Logger.Warn`) must be mapped to 0 before calling the sink
  because logr does not support "more important than info" levels.
- The slog group concept is supported by prefixing each key in a key/value
  pair with the group names, separated by a dot. For structured output like
  JSON it would be better to group the key/value pairs inside an object.
- Special slog values and interfaces don't work as expected.
- The overhead is likely to be higher.

These drawbacks are severe enough that applications using a mixture of slog and
logr should switch to a different backend.

### Using a `slog.Handler` as backend for logr

Using a plain `slog.Handler` without support for logr works better than the
other direction:
- All logr verbosity levels can be mapped 1:1 to their corresponding slog level
  by negating them.
- Stack unwinding is done by the `SlogSink` and the resulting program
  counter is passed to the `slog.Handler`.
- Names added via `Logger.WithName` are gathered and recorded in an additional
  attribute with `logger` as key and the names separated by slash as value.
- `Logger.Error` is turned into a log record with `slog.LevelError` as level
  and an additional attribute with `err` as key, if an error was provided.

The main drawback is that `logr.Marshaler` will not be supported. Types should
ideally support both `logr.Marshaler` and `slog.Valuer`. If compatibility
with logr implementations without slog support is not important, then
`slog.Valuer` is sufficient.

### Context support for slog

Storing a logger in a `context.Context` is not supported by
slog. `NewContextWithSlogLogger` and `FromContextAsSlogLogger` can be
used to fill this gap. They store and retrieve a `slog.Logger` pointer
under the same context key that is also used by `NewContext` and
`FromContext` for `logr.Logger` value.

When `NewContextWithSlogLogger` is followed by `FromContext`, the latter will
automatically convert the `slog.Logger` to a
`logr.Logger`. `FromContextAsSlogLogger` does the same for the other direction.

With this approach, binaries which use either slog or logr are as efficient as
possible with no unnecessary allocations. This is also why the API stores a
`slog.Logger` pointer: when storing a `slog.Handler`, creating a `slog.Logger`
on retrieval would need to allocate one.

The downside is that switching back and forth needs more allocations. Because
logr is the API that is already in use by different packages, in particular
Kubernetes, the recommendation is to use the `logr.Logger` API in code which
uses contextual logging.

An alternative to adding values to a logger and storing that logger in the
context is to store the values in the context and to configure a logging
backend to extract those values when emitting log entries. This only works when
log calls are passed the context, which is not supported by the logr API.

With the slog API, it is possible, but not
required. https://github.com/veqryn/slog-context is a package for slog which
provides additional support code for this approach. It also contains wrappers
for the context functions in logr, so developers who prefer to not use the logr
APIs directly can use those instead and the resulting code will still be
interoperable with logr.

## FAQ

### Conceptual

#### Why structured logging?

- **Structured logs are more easily queryable**: Since you've got
  key-value pairs, it's much easier to query your structured logs for
  particular values by filtering on the contents of a particular key --
  think searching request logs for error codes, Kubernetes reconcilers for
  the name and namespace of the reconciled object, etc.

- **Structured logging makes it easier to have cross-referenceable logs**:
  Similarly to searchability, if you maintain conventions around your
  keys, it becomes easy to gather all log lines related to a particular
  concept.

- **Structured logs allow better dimensions of filtering**: if you have
  structure to your logs, you've got more precise control over how much
  information is logged -- you might choose in a particular configuration
  to log certain keys but not others, only log lines where a certain key
  matches a certain value, etc., instead of just having v-levels and names
  to key off of.

- **Structured logs better represent structured data**: sometimes, the
  data that you want to log is inherently structured (think tuple-link
  objects.)  Structured logs allow you to preserve that structure when
  outputting.

#### Why V-levels?

**V-levels give operators an easy way to control the chattiness of log
operations**.  V-levels provide a way for a given package to distinguish
the relative importance or verbosity of a given log message.  Then, if
a particular logger or package is logging too many messages, the user
of the package can simply change the v-levels for that library.

#### Why not named levels, like Info/Warning/Error?

Read [Dave Cheney's post][warning-makes-no-sense].  Then read [Differences
from Dave's ideas](#differences-from-daves-ideas).

#### Why not allow format strings, too?

**Format strings negate many of the benefits of structured logs**:

- They're not easily searchable without resorting to fuzzy searching,
  regular expressions, etc.

- They don't store structured data well, since contents are flattened into
  a string.

- They're not cross-referenceable.

- They don't compress easily, since the message is not constant.

(Unless you turn positional parameters into key-value pairs with numerical
keys, at which point you've gotten key-value logging with meaningless
keys.)

### Practical

#### Why key-value pairs, and not a map?

Key-value pairs are *much* easier to optimize, especially around
allocations.  Zap (a structured logger that inspired logr's interface) has
[performance measurements](https://github.com/uber-go/zap#performance)
that show this quite nicely.

While the interface ends up being a little less obvious, you get
potentially better performance, plus avoid making users type
`map[string]string{}` every time they want to log.

#### What if my V-levels differ between libraries?

That's fine.  Control your V-levels on a per-logger basis, and use the
`WithName` method to pass different loggers to different libraries.

Generally, you should take care to ensure that you have relatively
consistent V-levels within a given logger, however, as this makes deciding
on what verbosity of logs to request easier.

#### But I really want to use a format string!

That's not actually a question.  Assuming your question is "how do
I convert my mental model of logging with format strings to logging with
constant messages":

1. Figure out what the error actually is, as you'd write in a TL;DR style,
   and use that as a message.

2. For every place you'd write a format specifier, look to the word before
   it, and add that as a key value pair.

For instance, consider the following examples (all taken from spots in the
Kubernetes codebase):

- `klog.V(4).Infof("Client is returning errors: code %v, error %v",
  responseCode, err)` becomes `logger.Error(err, "client returned an
  error", "code", responseCode)`

- `klog.V(4).Infof("Got a Retry-After %ds response for attempt %d to %v",
  seconds, retries, url)` becomes `logger.V(4).Info("got a retry-after
  response when requesting url", "attempt", retries, "after
  seconds", seconds, "url", url)`

If you *really* must use a format string, use it in a key's value, and
call `fmt.Sprintf` yourself.  For instance: `log.Printf("unable to
reflect over type %T")` becomes `logger.Info("unable to reflect over
type", "type", fmt.Sprintf("%T"))`.  In general though, the cases where
this is necessary should be few and far between.

#### How do I choose my V-levels?

This is basically the only hard constraint: increase V-levels to denote
more verbose or more debug-y logs.

Otherwise, you can start out with `0` as "you always want to see this",
`1` as "common logging that you might *possibly* want to turn off", and
`10` as "I would like to performance-test your log collection stack."

Then gradually choose levels in between as you need them, working your way
down from 10 (for debug and trace style logs) and up from 1 (for chattier
info-type logs). For reference, slog pre-defines -4 for debug logs
(corresponds to 4 in logr), which matches what is
[recommended for Kubernetes](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md#what-method-to-use).

#### How do I choose my keys?

Keys are fairly flexible, and can hold more or less any string
value. For best compatibility with implementations and consistency
with existing code in other projects, there are a few conventions you
should consider.

- Make your keys human-readable.
- Constant keys are generally a good idea.
- Be consistent across your codebase.
- Keys should naturally match parts of the message string.
- Use lower case for simple keys and
  [lowerCamelCase](https://en.wiktionary.org/wiki/lowerCamelCase) for
  more complex ones. Kubernetes is one example of a project that has
  [adopted that
  convention](https://github.com/kubernetes/community/blob/HEAD/contributors/devel/sig-instrumentation/migration-to-structured-logging.md#name-arguments).

While key names are mostly unrestricted (and spaces are acceptable),
it's generally a good idea to stick to printable ascii characters, or at
least match the general character set of your log lines.

#### Why should keys be constant values?

The point of structured logging is to make later log processing easier.  Your
keys are, effectively, the schema of each log message.  If you use different
keys across instances of the same log line, you will make your structured logs
much harder to use.  `Sprintf()` is for values, not for keys!

#### Why is this not a pure interface?

The Logger type is implemented as a struct in order to allow the Go compiler to
optimize things like high-V `Info` logs that are not triggered.  Not all of
these implementations are implemented yet, but this structure was suggested as
a way to ensure they *can* be implemented.  All of the real work is behind the
`LogSink` interface.

[warning-makes-no-sense]: http://dave.cheney.net/2015/11/05/lets-talk-about-logging

---

### Overview (`vendor/github.com/go-logr/stdr/README.md`)

# Minimal Go logging using logr and Go's standard library

[](https://pkg.go.dev/github.com/go-logr/stdr)

This package implements the [logr interface](https://github.com/go-logr/logr)
in terms of Go's standard log package(https://pkg.go.dev/log).

---

### Overview (`vendor/github.com/google/uuid/README.md`)

# uuid
The uuid package generates and inspects UUIDs based on
[RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122)
and DCE 1.1: Authentication and Security Services. 

This package is based on the github.com/pborman/uuid package (previously named
code.google.com/p/go-uuid).  It differs from these earlier packages in that
a UUID is a 16 byte array rather than a byte slice.  One loss due to this
change is the ability to represent an invalid UUID (vs a NIL UUID).

###### Install
```sh
go get github.com/google/uuid
```

###### Documentation 
[](https://pkg.go.dev/github.com/google/uuid)

Full `go doc` style documentation for the package can be viewed online without
installing this package by using the GoDoc site here: 
http://pkg.go.dev/github.com/google/uuid

---

### Overview (`vendor/github.com/gorilla/mux/README.md`)

# gorilla/mux


[](https://codecov.io/github/gorilla/mux)
[](https://godoc.org/github.com/gorilla/mux)
[](https://sourcegraph.com/github.com/gorilla/mux?badge)




Package `gorilla/mux` implements a request router and dispatcher for matching incoming requests to
their respective handler.

The name mux stands for "HTTP request multiplexer". Like the standard `http.ServeMux`, `mux.Router` matches incoming requests against a list of registered routes and calls a handler for the route that matches the URL or other conditions. The main features are:

* It implements the `http.Handler` interface so it is compatible with the standard `http.ServeMux`.
* Requests can be matched based on URL host, path, path prefix, schemes, header and query values, HTTP methods or using custom matchers.
* URL hosts, paths and query values can have variables with an optional regular expression.
* Registered URLs can be built, or "reversed", which helps maintaining references to resources.
* Routes can be used as subrouters: nested routes are only tested if the parent route matches. This is useful to define groups of routes that share common conditions like a host, a path prefix or other repeated attributes. As a bonus, this optimizes request matching.

---

* [Install](#install)
* [Examples](#examples)
* [Matching Routes](#matching-routes)
* [Static Files](#static-files)
* [Serving Single Page Applications](#serving-single-page-applications) (e.g. React, Vue, Ember.js, etc.)
* [Registered URLs](#registered-urls)
* [Walking Routes](#walking-routes)
* [Graceful Shutdown](#graceful-shutdown)
* [Middleware](#middleware)
* [Handling CORS Requests](#handling-cors-requests)
* [Testing Handlers](#testing-handlers)
* [Full Example](#full-example)

---

## Install

With a [correctly configured](https://golang.org/doc/install#testing) Go toolchain:

```sh
go get -u github.com/gorilla/mux
```

## Examples

Let's start registering a couple of URL paths and handlers:

```go
func main() {
    r := mux.NewRouter()
    r.HandleFunc("/", HomeHandler)
    r.HandleFunc("/products", ProductsHandler)
    r.HandleFunc("/articles", ArticlesHandler)
    http.Handle("/", r)
}
```

Here we register three routes mapping URL paths to handlers. This is equivalent to how `http.HandleFunc()` works: if an incoming request URL matches one of the paths, the corresponding handler is called passing (`http.ResponseWriter`, `*http.Request`) as parameters.

Paths can have variables. They are defined using the format `{name}` or `{name:pattern}`. If a regular expression pattern is not defined, the matched variable will be anything until the next slash. For example:

```go
r := mux.NewRouter()
r.HandleFunc("/products/{key}", ProductHandler)
r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler)
r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)
```

The names are used to create a map of route variables which can be retrieved calling `mux.Vars()`:

```go
func ArticlesCategoryHandler(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    w.WriteHeader(http.StatusOK)
    fmt.Fprintf(w, "Category: %v\n", vars["category"])
}
```

And this is all you need to know about the basic usage. More advanced options are explained below.

### Matching Routes

Routes can also be restricted to a domain or subdomain. Just define a host pattern to be matched. They can also have variables:

```go
r := mux.NewRouter()
// Only matches if domain is "www.example.com".
r.Host("www.example.com")
// Matches a dynamic subdomain.
r.Host("{subdomain:[a-z]+}.example.com")
```

There are several other matchers that can be added. To match path prefixes:

```go
r.PathPrefix("/products/")
```

...or HTTP methods:

```go
r.Methods("GET", "POST")
```

...or URL schemes:

```go
r.Schemes("https")
```

...or header values:

```go
r.Headers("X-Requested-With", "XMLHttpRequest")
```

...or query values:

```go
r.Queries("key", "value")
```

...or to use a custom matcher function:

```go
r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool {
    return r.ProtoMajor == 0
})
```

...and finally, it is possible to combine several matchers in a single route:

```go
r.HandleFunc("/products", ProductsHandler).
  Host("www.example.com").
  Methods("GET").
  Schemes("http")
```

Routes are tested in the order they were added to the router. If two routes match, the first one wins:

```go
r := mux.NewRouter()
r.HandleFunc("/specific", specificHandler)
r.PathPrefix("/").Handler(catchAllHandler)
```

Setting the same matching conditions again and again can be boring, so we have a way to group several routes that share the same requirements. We call it "subrouting".

For example, let's say we have several URLs that should only match when the host is `www.example.com`. Create a route for that host and get a "subrouter" from it:

```go
r := mux.NewRouter()
s := r.Host("www.example.com").Subrouter()
```

Then register routes in the subrouter:

```go
s.HandleFunc("/products/", ProductsHandler)
s.HandleFunc("/products/{key}", ProductHandler)
s.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)
```

The three URL paths we registered above will only be tested if the domain is `www.example.com`, because the subrouter is tested first. This is not only convenient, but also optimizes request matching. You can create subrouters combining any attribute matchers accepted by a route.

Subrouters can be used to create domain or path "namespaces": you define subrouters in a central place and then parts of the app can register its paths relatively to a given subrouter.

There's one more thing about subroutes. When a subrouter has a path prefix, the inner routes use it as base for their paths:

```go
r := mux.NewRouter()
s := r.PathPrefix("/products").Subrouter()
// "/products/"
s.HandleFunc("/", ProductsHandler)
// "/products/{key}/"
s.HandleFunc("/{key}/", ProductHandler)
// "/products/{key}/details"
s.HandleFunc("/{key}/details", ProductDetailsHandler)
```


### Static Files

Note that the path provided to `PathPrefix()` represents a "wildcard": calling
`PathPrefix("/static/").Handler(...)` means that the handler will be passed any
request that matches "/static/\*". This makes it easy to serve static files with mux:

```go
func main() {
    var dir string

    flag.StringVar(&dir, "dir", ".", "the directory to serve files from. Defaults to the current dir")
    flag.Parse()
    r := mux.NewRouter()

    // This will serve files under http://localhost:8000/static/<filename>
    r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(dir))))

    srv := &http.Server{
        Handler:      r,
        Addr:         "127.0.0.1:8000",
        // Good practice: enforce timeouts for servers you create!
        WriteTimeout: 15 * time.Second,
        ReadTimeout:  15 * time.Second,
    }

    log.Fatal(srv.ListenAndServe())
}
```

### Serving Single Page Applications

Most of the time it makes sense to serve your SPA on a separate web server from your API,
but sometimes it's desirable to serve them both from one place. It's possible to write a simple
handler for serving your SPA (for use with React Router's [BrowserRouter](https://reacttraining.com/react-router/web/api/BrowserRouter) for example), and leverage
mux's powerful routing for your API endpoints.

```
/* Detailed source-code truncated for AI context efficiency. */
```

### Registered URLs

Now let's see how to build registered URLs.

Routes can be named. All routes that define a name can have their URLs built, or "reversed". We define a name calling `Name()` on a route. For example:

```go
r := mux.NewRouter()
r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
  Name("article")
```

To build a URL, get the route and call the `URL()` method, passing a sequence of key/value pairs for the route variables. For the previous route, we would do:

```go
url, err := r.Get("article").URL("category", "technology", "id", "42")
```

...and the result will be a `url.URL` with the following path:

```
"/articles/technology/42"
```

This also works for host and query value variables:

```go
r := mux.NewRouter()
r.Host("{subdomain}.example.com").
  Path("/articles/{category}/{id:[0-9]+}").
  Queries("filter", "{filter}").
  HandlerFunc(ArticleHandler).
  Name("article")

// url.String() will be "http://news.example.com/articles/technology/42?filter=gorilla"
url, err := r.Get("article").URL("subdomain", "news",
                                 "category", "technology",
                                 "id", "42",
                                 "filter", "gorilla")
```

All variables defined in the route are required, and their values must conform to the corresponding patterns. These requirements guarantee that a generated URL will always match a registered route -- the only exception is for explicitly defined "build-only" routes which never match.

Regex support also exists for matching Headers within a route. For example, we could do:

```go
r.HeadersRegexp("Content-Type", "application/(text|json)")
```

...and the route will match both requests with a Content-Type of `application/json` as well as `application/text`

There's also a way to build only the URL host or path for a route: use the methods `URLHost()` or `URLPath()` instead. For the previous route, we would do:

```go
// "http://news.example.com/"
host, err := r.Get("article").URLHost("subdomain", "news")

// "/articles/technology/42"
path, err := r.Get("article").URLPath("category", "technology", "id", "42")
```

And if you use subrouters, host and path defined separately can be built as well:

```go
r := mux.NewRouter()
s := r.Host("{subdomain}.example.com").Subrouter()
s.Path("/articles/{category}/{id:[0-9]+}").
  HandlerFunc(ArticleHandler).
  Name("article")

// "http://news.example.com/articles/technology/42"
url, err := r.Get("article").URL("subdomain", "news",
                                 "category", "technology",
                                 "id", "42")
```

To find all the required variables for a given route when calling `URL()`, the method `GetVarNames()` is available:
```go
r := mux.NewRouter()
r.Host("{domain}").
    Path("/{group}/{item_id}").
    Queries("some_data1", "{some_data1}").
    Queries("some_data2", "{some_data2}").
    Name("article")

// Will print [domain group item_id some_data1 some_data2] <nil>
fmt.Println(r.Get("article").GetVarNames())

```
### Walking Routes

The `Walk` function on `mux.Router` can be used to visit all of the routes that are registered on a router. For example,
the following prints all of the registered routes:

```go
package main

import (
	"fmt"
	"net/http"
	"strings"

	"github.com/gorilla/mux"
)

func handler(w http.ResponseWriter, r *http.Request) {
	return
}

func main() {
	r := mux.NewRouter()
	r.HandleFunc("/", handler)
	r.HandleFunc("/products", handler).Methods("POST")
	r.HandleFunc("/articles", handler).Methods("GET")
	r.HandleFunc("/articles/{id}", handler).Methods("GET", "PUT")
	r.HandleFunc("/authors", handler).Queries("surname", "{surname}")
	err := r.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
		pathTemplate, err := route.GetPathTemplate()
		if err == nil {
			fmt.Println("ROUTE:", pathTemplate)
		}
		pathRegexp, err := route.GetPathRegexp()
		if err == nil {
			fmt.Println("Path regexp:", pathRegexp)
		}
		queriesTemplates, err := route.GetQueriesTemplates()
		if err == nil {
			fmt.Println("Queries templates:", strings.Join(queriesTemplates, ","))
		}
		queriesRegexps, err := route.GetQueriesRegexp()
		if err == nil {
			fmt.Println("Queries regexps:", strings.Join(queriesRegexps, ","))
		}
		methods, err := route.GetMethods()
		if err == nil {
			fmt.Println("Methods:", strings.Join(methods, ","))
		}
		fmt.Println()
		return nil
	})

	if err != nil {
		fmt.Println(err)
	}

	http.Handle("/", r)
}
```

### Graceful Shutdown

Go 1.8 introduced the ability to [gracefully shutdown](https://golang.org/doc/go1.8#http_shutdown) a `*http.Server`. Here's how to do that alongside `mux`:

```
/* Detailed source-code truncated for AI context efficiency. */
```

### Middleware

Mux supports the addition of middlewares to a [Router](https://godoc.org/github.com/gorilla/mux#Router), which are executed in the order they are added if a match is found, including its subrouters.
Middlewares are (typically) small pieces of code which take one request, do something with it, and pass it down to another middleware or the final handler. Some common use cases for middleware are request logging, header manipulation, or `ResponseWriter` hijacking.

Mux middlewares are defined using the de facto standard type:

```go
type MiddlewareFunc func(http.Handler) http.Handler
```

Typically, the returned handler is a closure which does something with the http.ResponseWriter and http.Request passed to it, and then calls the handler passed as parameter to the MiddlewareFunc. This takes advantage of closures being able access variables from the context where they are created, while retaining the signature enforced by the receivers.

A very basic middleware which logs the URI of the request being handled could be written as:

```go
func loggingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Do stuff here
        log.Println(r.RequestURI)
        // Call the next handler, which can be another middleware in the chain, or the final handler.
        next.ServeHTTP(w, r)
    })
}
```

Middlewares can be added to a router using `Router.Use()`:

```go
r := mux.NewRouter()
r.HandleFunc("/", handler)
r.Use(loggingMiddleware)
```

A more complex authentication middleware, which maps session token to users, could be written as:

```go
// Define our struct
type authenticationMiddleware struct {
	tokenUsers map[string]string
}

// Initialize it somewhere
func (amw *authenticationMiddleware) Populate() {
	amw.tokenUsers["00000000"] = "user0"
	amw.tokenUsers["aaaaaaaa"] = "userA"
	amw.tokenUsers["05f717e5"] = "randomUser"
	amw.tokenUsers["deadbeef"] = "user0"
}

// Middleware function, which will be called for each request
func (amw *authenticationMiddleware) Middleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        token := r.Header.Get("X-Session-Token")

        if user, found := amw.tokenUsers[token]; found {
        	// We found the token in our map
        	log.Printf("Authenticated user %s\n", user)
        	// Pass down the request to the next middleware (or final handler)
        	next.ServeHTTP(w, r)
        } else {
        	// Write an error and stop the handler chain
        	http.Error(w, "Forbidden", http.StatusForbidden)
        }
    })
}
```

```go
r := mux.NewRouter()
r.HandleFunc("/", handler)

amw := authenticationMiddleware{tokenUsers: make(map[string]string)}
amw.Populate()

r.Use(amw.Middleware)
```

Note: The handler chain will be stopped if your middleware doesn't call `next.ServeHTTP()` with the corresponding parameters. This can be used to abort a request if the middleware writer wants to. Middlewares _should_ write to `ResponseWriter` if they _are_ going to terminate the request, and they _should not_ write to `ResponseWriter` if they _are not_ going to terminate it.

### Handling CORS Requests

[CORSMethodMiddleware](https://godoc.org/github.com/gorilla/mux#CORSMethodMiddleware) intends to make it easier to strictly set the `Access-Control-Allow-Methods` response header.

* You will still need to use your own CORS handler to set the other CORS headers such as `Access-Control-Allow-Origin`
* The middleware will set the `Access-Control-Allow-Methods` header to all the method matchers (e.g. `r.Methods(http.MethodGet, http.MethodPut, http.MethodOptions)` -> `Access-Control-Allow-Methods: GET,PUT,OPTIONS`) on a route
* If you do not specify any methods, then:
> _Important_: there must be an `OPTIONS` method matcher for the middleware to set the headers.

Here is an example of using `CORSMethodMiddleware` along with a custom `OPTIONS` handler to set all the required CORS headers:

```go
package main

import (
	"net/http"
	"github.com/gorilla/mux"
)

func main() {
    r := mux.NewRouter()

    // IMPORTANT: you must specify an OPTIONS method matcher for the middleware to set CORS headers
    r.HandleFunc("/foo", fooHandler).Methods(http.MethodGet, http.MethodPut, http.MethodPatch, http.MethodOptions)
    r.Use(mux.CORSMethodMiddleware(r))
    
    http.ListenAndServe(":8080", r)
}

func fooHandler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Access-Control-Allow-Origin", "*")
    if r.Method == http.MethodOptions {
        return
    }

    w.Write([]byte("foo"))
}
```

And an request to `/foo` using something like:

```bash
curl localhost:8080/foo -v
```

Would look like:

```bash
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /foo HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.59.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Access-Control-Allow-Methods: GET,PUT,PATCH,OPTIONS
< Access-Control-Allow-Origin: *
< Date: Fri, 28 Jun 2019 20:13:30 GMT
< Content-Length: 3
< Content-Type: text/plain; charset=utf-8
< 
* Connection #0 to host localhost left intact
foo
```

### Testing Handlers

Testing handlers in a Go web application is straightforward, and _mux_ doesn't complicate this any further. Given two files: `endpoints.go` and `endpoints_test.go`, here's how we'd test an application using _mux_.

First, our simple HTTP handler:

```go
// endpoints.go
package main

func HealthCheckHandler(w http.ResponseWriter, r *http.Request) {
    // A very simple health check.
    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(http.StatusOK)

    // In the future we could report back on the status of our DB, or our cache
    // (e.g. Redis) by performing a simple PING, and include them in the response.
    io.WriteString(w, `{"alive": true}`)
}

func main() {
    r := mux.NewRouter()
    r.HandleFunc("/health", HealthCheckHandler)

    log.Fatal(http.ListenAndServe("localhost:8080", r))
}
```

Our test code:

```go
// endpoints_test.go
package main

import (
    "net/http"
    "net/http/httptest"
    "testing"
)

func TestHealthCheckHandler(t *testing.T) {
    // Create a request to pass to our handler. We don't have any query parameters for now, so we'll
    // pass 'nil' as the third parameter.
    req, err := http.NewRequest("GET", "/health", nil)
    if err != nil {
        t.Fatal(err)
    }

    // We create a ResponseRecorder (which satisfies http.ResponseWriter) to record the response.
    rr := httptest.NewRecorder()
    handler := http.HandlerFunc(HealthCheckHandler)

    // Our handlers satisfy http.Handler, so we can call their ServeHTTP method
    // directly and pass in our Request and ResponseRecorder.
    handler.ServeHTTP(rr, req)

    // Check the status code is what we expect.
    if status := rr.Code; status != http.StatusOK {
        t.Errorf("handler returned wrong status code: got %v want %v",
            status, http.StatusOK)
    }

    // Check the response body is what we expect.
    expected := `{"alive": true}`
    if rr.Body.String() != expected {
        t.Errorf("handler returned unexpected body: got %v want %v",
            rr.Body.String(), expected)
    }
}
```

In the case that our routes have [variables](#examples), we can pass those in the request. We could write
[table-driven tests](https://dave.cheney.net/2013/06/09/writing-table-driven-tests-in-go) to test multiple
possible route variables as needed.

```go
// endpoints.go
func main() {
    r := mux.NewRouter()
    // A route with a route variable:
    r.HandleFunc("/metrics/{type}", MetricsHandler)

    log.Fatal(http.ListenAndServe("localhost:8080", r))
}
```

Our test file, with a table-driven test of `routeVariables`:

```go
// endpoints_test.go
func TestMetricsHandler(t *testing.T) {
    tt := []struct{
        routeVariable string
        shouldPass bool
    }{
        {"goroutines", true},
        {"heap", true},
        {"counters", true},
        {"queries", true},
        {"adhadaeqm3k", false},
    }

    for _, tc := range tt {
        path := fmt.Sprintf("/metrics/%s", tc.routeVariable)
        req, err := http.NewRequest("GET", path, nil)
        if err != nil {
            t.Fatal(err)
        }

        rr := httptest.NewRecorder()
	
	// To add the vars to the context, 
	// we need to create a router through which we can pass the request.
	router := mux.NewRouter()
        router.HandleFunc("/metrics/{type}", MetricsHandler)
        router.ServeHTTP(rr, req)

        // In this case, our MetricsHandler returns a non-200 response
        // for a route variable it doesn't know about.
        if rr.Code == http.StatusOK && !tc.shouldPass {
            t.Errorf("handler should have failed on routeVariable %s: got %v want %v",
                tc.routeVariable, rr.Code, http.StatusOK)
        }
    }
}
```

## Full Example

Here's a complete, runnable example of a small `mux` based server:

```go
package main

import (
    "net/http"
    "log"
    "github.com/gorilla/mux"
)

func YourHandler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Gorilla!\n"))
}

func main() {
    r := mux.NewRouter()
    // Routes consist of a path and a handler function.
    r.HandleFunc("/", YourHandler)

    // Bind to a port and pass our router in
    log.Fatal(http.ListenAndServe(":8000", r))
}
```

## License

BSD licensed. See the LICENSE file for details.

---

### Overview (`vendor/github.com/hashicorp/go-cleanhttp/README.md`)

# cleanhttp

Functions for accessing "clean" Go http.Client values

-------------

The Go standard library contains a default `http.Client` called
`http.DefaultClient`. It is a common idiom in Go code to start with
`http.DefaultClient` and tweak it as necessary, and in fact, this is
encouraged; from the `http` package documentation:

> The Client's Transport typically has internal state (cached TCP connections),
so Clients should be reused instead of created as needed. Clients are safe for
concurrent use by multiple goroutines.

Unfortunately, this is a shared value, and it is not uncommon for libraries to
assume that they are free to modify it at will. With enough dependencies, it
can be very easy to encounter strange problems and race conditions due to
manipulation of this shared value across libraries and goroutines (clients are
safe for concurrent use, but writing values to the client struct itself is not
protected).

Making things worse is the fact that a bare `http.Client` will use a default
`http.Transport` called `http.DefaultTransport`, which is another global value
that behaves the same way. So it is not simply enough to replace
`http.DefaultClient` with `&http.Client{}`.

This repository provides some simple functions to get a "clean" `http.Client`
-- one that uses the same default values as the Go standard library, but
returns a client that does not share any state with other clients.

---

### Overview (`vendor/github.com/hashicorp/go-multierror/README.md`)

# go-multierror

[](https://circleci.com/gh/hashicorp/go-multierror)
[](https://pkg.go.dev/github.com/hashicorp/go-multierror)


[circleci]: https://app.circleci.com/pipelines/github/hashicorp/go-multierror
[godocs]: https://pkg.go.dev/github.com/hashicorp/go-multierror

`go-multierror` is a package for Go that provides a mechanism for
representing a list of `error` values as a single `error`.

This allows a function in Go to return an `error` that might actually
be a list of errors. If the caller knows this, they can unwrap the
list and access the errors. If the caller doesn't know, the error
formats to a nice human-readable format.

`go-multierror` is fully compatible with the Go standard library
[errors](https://golang.org/pkg/errors/) package, including the
functions `As`, `Is`, and `Unwrap`. This provides a standardized approach
for introspecting on error values.

## Installation and Docs

Install using `go get github.com/hashicorp/go-multierror`.

Full documentation is available at
https://pkg.go.dev/github.com/hashicorp/go-multierror

### Requires go version 1.13 or newer

`go-multierror` requires go version 1.13 or newer. Go 1.13 introduced
[error wrapping](https://golang.org/doc/go1.13#error_wrapping), which
this library takes advantage of.

If you need to use an earlier version of go, you can use the
[v1.0.0](https://github.com/hashicorp/go-multierror/tree/v1.0.0)
tag, which doesn't rely on features in go 1.13.

If you see compile errors that look like the below, it's likely that
you're on an older version of go:

```
/go/src/github.com/hashicorp/go-multierror/multierror.go:112:9: undefined: errors.As
/go/src/github.com/hashicorp/go-multierror/multierror.go:117:9: undefined: errors.Is
```

## Usage

go-multierror is easy to use and purposely built to be unobtrusive in
existing Go applications/libraries that may not be aware of it.

**Building a list of errors**

The `Append` function is used to create a list of errors. This function
behaves a lot like the Go built-in `append` function: it doesn't matter
if the first argument is nil, a `multierror.Error`, or any other `error`,
the function behaves as you would expect.

```go
var result error

if err := step1(); err != nil {
	result = multierror.Append(result, err)
}
if err := step2(); err != nil {
	result = multierror.Append(result, err)
}

return result
```

**Customizing the formatting of the errors**

By specifying a custom `ErrorFormat`, you can customize the format
of the `Error() string` function:

```go
var result *multierror.Error

// ... accumulate errors here, maybe using Append

if result != nil {
	result.ErrorFormat = func([]error) string {
		return "errors!"
	}
}
```

**Accessing the list of errors**

`multierror.Error` implements `error` so if the caller doesn't know about
multierror, it will work just fine. But if you're aware a multierror might
be returned, you can use type switches to access the list of errors:

```go
if err := something(); err != nil {
	if merr, ok := err.(*multierror.Error); ok {
		// Use merr.Errors
	}
}
```

You can also use the standard [`errors.Unwrap`](https://golang.org/pkg/errors/#Unwrap)
function. This will continue to unwrap into subsequent errors until none exist.

**Extracting an error**

The standard library [`errors.As`](https://golang.org/pkg/errors/#As)
function can be used directly with a multierror to extract a specific error:

```go
// Assume err is a multierror value
err := somefunc()

// We want to know if "err" has a "RichErrorType" in it and extract it.
var errRich RichErrorType
if errors.As(err, &errRich) {
	// It has it, and now errRich is populated.
}
```

**Checking for an exact error value**

Some errors are returned as exact errors such as the [`ErrNotExist`](https://golang.org/pkg/os/#pkg-variables)
error in the `os` package. You can check if this error is present by using
the standard [`errors.Is`](https://golang.org/pkg/errors/#Is) function.

```go
// Assume err is a multierror value
err := somefunc()
if errors.Is(err, os.ErrNotExist) {
	// err contains os.ErrNotExist
}
```

**Returning a multierror only if there are errors**

If you build a `multierror.Error`, you can use the `ErrorOrNil` function
to return an `error` implementation only if there are errors to return:

```go
var result *multierror.Error

// ... accumulate errors here

// Return the `error` only if errors were added to the multierror, otherwise
// return nil since there are no errors.
return result.ErrorOrNil()
```

---

### Overview (`vendor/github.com/hashicorp/go-retryablehttp/README.md`)

go-retryablehttp
================

[][travis]
[][godocs]

[travis]: http://travis-ci.org/hashicorp/go-retryablehttp
[godocs]: http://godoc.org/github.com/hashicorp/go-retryablehttp

The `retryablehttp` package provides a familiar HTTP client interface with
automatic retries and exponential backoff. It is a thin wrapper over the
standard `net/http` client library and exposes nearly the same public API. This
makes `retryablehttp` very easy to drop into existing programs.

`retryablehttp` performs automatic retries under certain conditions. Mainly, if
an error is returned by the client (connection errors, etc.), or if a 500-range
response code is received (except 501), then a retry is invoked after a wait
period.  Otherwise, the response is returned and left to the caller to
interpret.

The main difference from `net/http` is that requests which take a request body
(POST/PUT et. al) can have the body provided in a number of ways (some more or
less efficient) that allow "rewinding" the request body if the initial request
fails so that the full request can be attempted again. See the
[godoc](http://godoc.org/github.com/hashicorp/go-retryablehttp) for more
details.

Version 0.6.0 and before are compatible with Go prior to 1.12. From 0.6.1 onward, Go 1.12+ is required.
From 0.6.7 onward, Go 1.13+ is required.

Example Use
===========

Using this library should look almost identical to what you would do with
`net/http`. The most simple example of a GET request is shown below:

```go
resp, err := retryablehttp.Get("/foo")
if err != nil {
    panic(err)
}
```

The returned response object is an `*http.Response`, the same thing you would
usually get from `net/http`. Had the request failed one or more times, the above
call would block and retry with exponential backoff.

## Getting a stdlib `*http.Client` with retries

It's possible to convert a `*retryablehttp.Client` directly to a `*http.Client`.
This makes use of retryablehttp broadly applicable with minimal effort. Simply
configure a `*retryablehttp.Client` as you wish, and then call `StandardClient()`:

```go
retryClient := retryablehttp.NewClient()
retryClient.RetryMax = 10

standardClient := retryClient.StandardClient() // *http.Client
```

For more usage and examples see the
[pkg.go.dev](https://pkg.go.dev/github.com/hashicorp/go-retryablehttp).

---

### Overview (`vendor/github.com/inconshreveable/mousetrap/README.md`)

# mousetrap

mousetrap is a tiny library that answers a single question.

On a Windows machine, was the process invoked by someone double clicking on
the executable file while browsing in explorer?

### Motivation

Windows developers unfamiliar with command line tools will often "double-click"
the executable for a tool. Because most CLI tools print the help and then exit
when invoked without arguments, this is often very frustrating for those users.

mousetrap provides a way to detect these invocations so that you can provide
more helpful behavior and instructions on how to run the CLI tool. To see what
this looks like, both from an organizational and a technical perspective, see
https://inconshreveable.com/09-09-2014/sweat-the-small-stuff/

### The interface

The library exposes a single interface:

    func StartedByExplorer() (bool)

---

### Overview (`vendor/github.com/json-iterator/go/README.md`)

[](https://sourcegraph.com/github.com/json-iterator/go?badge)
[](https://pkg.go.dev/github.com/json-iterator/go)
[](https://travis-ci.org/json-iterator/go)
[](https://codecov.io/gh/json-iterator/go)
[](https://goreportcard.com/report/github.com/json-iterator/go)
[](https://raw.githubusercontent.com/json-iterator/go/master/LICENSE)
[](https://gitter.im/json-iterator/Lobby)

A high-performance 100% compatible drop-in replacement of "encoding/json"

# Benchmark



Source code: https://github.com/json-iterator/go-benchmark/blob/master/src/github.com/json-iterator/go-benchmark/benchmark_medium_payload_test.go

Raw Result (easyjson requires static code generation)

|                 | ns/op       | allocation bytes | allocation times |
| --------------- | ----------- | ---------------- | ---------------- |
| std decode      | 35510 ns/op | 1960 B/op        | 99 allocs/op     |
| easyjson decode | 8499 ns/op  | 160 B/op         | 4 allocs/op      |
| jsoniter decode | 5623 ns/op  | 160 B/op         | 3 allocs/op      |
| std encode      | 2213 ns/op  | 712 B/op         | 5 allocs/op      |
| easyjson encode | 883 ns/op   | 576 B/op         | 3 allocs/op      |
| jsoniter encode | 837 ns/op   | 384 B/op         | 4 allocs/op      |

Always benchmark with your own workload.
The result depends heavily on the data input.

# Usage

100% compatibility with standard lib

Replace

```go
import "encoding/json"
json.Marshal(&data)
```

with

```go
import jsoniter "github.com/json-iterator/go"

var json = jsoniter.ConfigCompatibleWithStandardLibrary
json.Marshal(&data)
```

Replace

```go
import "encoding/json"
json.Unmarshal(input, &data)
```

with

```go
import jsoniter "github.com/json-iterator/go"

var json = jsoniter.ConfigCompatibleWithStandardLibrary
json.Unmarshal(input, &data)
```

[More documentation](http://jsoniter.com/migrate-from-go-std.html)

# How to get

```
go get github.com/json-iterator/go
```

# Contribution Welcomed !

Contributors

- [thockin](https://github.com/thockin)
- [mattn](https://github.com/mattn)
- [cch123](https://github.com/cch123)
- [Oleg Shaldybin](https://github.com/olegshaldybin)
- [Jason Toffaletti](https://github.com/toffaletti)

Report issue or pull request, or email taowen@gmail.com, or [](https://gitter.im/json-iterator/Lobby)

---

### Overview (`vendor/github.com/klauspost/compress/README.md`)

# compress

This package provides various compression algorithms.

* [zstandard](https://github.com/klauspost/compress/tree/master/zstd#zstd) compression and decompression in pure Go.
* [S2](https://github.com/klauspost/compress/tree/master/s2#s2-compression) is a high performance replacement for Snappy.
* Optimized [deflate](https://godoc.org/github.com/klauspost/compress/flate) packages which can be used as a dropin replacement for [gzip](https://godoc.org/github.com/klauspost/compress/gzip), [zip](https://godoc.org/github.com/klauspost/compress/zip) and [zlib](https://godoc.org/github.com/klauspost/compress/zlib).
* [snappy](https://github.com/klauspost/compress/tree/master/snappy) is a drop-in replacement for `github.com/golang/snappy` offering better compression and concurrent streams.
* [lzw](https://github.com/klauspost/compress/tree/master/lzw) is a drop-in replacement for `compress/lzw` with 1.4-4x faster decompression and 1.1-2.7x faster compression, depending on the data.
* [huff0](https://github.com/klauspost/compress/tree/master/huff0) and [FSE](https://github.com/klauspost/compress/tree/master/fse) implementations for raw entropy encoding.
* [Xpress](https://github.com/klauspost/compress/tree/master/xpress) decompression of the Microsoft XPRESS (MS-XCA) plain LZ77 and LZ77+Huffman formats (the LZ77+Huffman variant is the one used in WIM images and Windows Compact OS / WOF data).
* [gzhttp](https://github.com/klauspost/compress/tree/master/gzhttp) Provides client and server wrappers for handling gzipped/zstd HTTP requests efficiently.
* [pgzip](https://github.com/klauspost/pgzip) is a separate package that provides a very fast parallel gzip implementation.

[](https://pkg.go.dev/github.com/klauspost/compress?tab=subdirectories)
[](https://github.com/klauspost/compress/actions/workflows/go.yml)
[](https://sourcegraph.com/github.com/klauspost/compress?badge)

# package usage

Use `go get github.com/klauspost/compress@latest` to add it to your project.

This package will support the current Go version and 2 versions back.

* Use the `nounsafe` tag to disable all use of the "unsafe" package.
* Use the `noasm` tag to disable all assembly across packages.

Use the links above for more information on each.

# changelog

* Sep 25th, 2026 [1.20.1](https://github.com/klauspost/compress/releases/tag/v1.20.1)
	* zstd: Apply reset options to reused frame decoders by @pellared in https://github.com/klauspost/compress/pull/1226
	* flate: Report unexpected EOF for truncated Huffman extra bits by @rupayon123 in https://github.com/klauspost/compress/pull/1229
	* flate: Avoid FMA in EstimatedBits for portable rounding by @malt3 in https://github.com/klauspost/compress/pull/1224
	* gzhttp: Preserve caller request headers in Transport by @jakezwang in https://github.com/klauspost/compress/pull/1225
	* gzhttp: Only decompress a request when gzip is the outermost coding by @youdie006 in https://github.com/klauspost/compress/pull/1223
	* zstd/huff0: Optimizations by @lizthegrey in https://github.com/klauspost/compress/pull/1203 https://github.com/klauspost/compress/pull/1205 https://github.com/klauspost/compress/pull/1207 https://github.com/klauspost/compress/pull/1204 https://github.com/klauspost/compress/pull/1208 https://github.com/klauspost/compress/pull/1211 https://github.com/klauspost/compress/pull/1209 https://github.com/klauspost/compress/pull/1210
	* flate: Speed improvements by @alex in https://github.com/klauspost/compress/pull/1220 https://github.com/klauspost/compress/pull/1218 https://github.com/klauspost/compress/pull/1216 https://github.com/klauspost/compress/pull/1215 https://github.com/klauspost/compress/pull/1214 https://github.com/klauspost/compress/pull/1217

* Sep 2nd, 2026 [1.20.0](https://github.com/klauspost/compress/releases/tag/v1.20.0)
	* lzw: Add lzw reader/writer in https://github.com/klauspost/compress/pull/1189
	* xpress: Add Microsoft XPRESS (MS-XCA) decompression by @MP-GOWTHAM in https://github.com/klauspost/compress/pull/1195
	* s2: arm64 assembly encoders by @lizthegrey in https://github.com/klauspost/compress/pull/1187
	* zstd, huff0: Improved arm64 assembly by @lizthegrey in https://github.com/klauspost/compress/pull/1175 https://github.com/klauspost/compress/pull/1199 https://github.com/klauspost/compress/pull/1197
	* flate: Writer L7-9 with dictionary can emit the dictionary to stream in https://github.com/klauspost/compress/pull/1201
	* gzhttp: Limit jitter hash to jitterBuffer bytes by @VedantMadane in https://github.com/klauspost/compress/pull/1192
	* s2: Clamp the Go EncodeBetter skip to match the assembly by @lizthegrey in https://github.com/klauspost/compress/pull/1190
	* xxhash: Bound input of non-preemptive assembly by @AskAlexSharov in https://github.com/klauspost/compress/pull/1196

* Aug 6th, 2026 [1.19.2](https://github.com/klauspost/compress/releases/tag/v1.19.2)
	* huff0: Add arm64 assembly for Decompress4X/1X by @lizthegrey in https://github.com/klauspost/compress/pull/1172
	* zstd: Re-enable unsafe decodeSync memory copies by @lizthegrey in https://github.com/klauspost/compress/pull/1171
	* zstd: Fix arm64 asm frame offsets placing locals on the saved LR slot by @lizthegrey in https://github.com/klauspost/compress/pull/1176
	* zstd: Avoid racing MaxDecodedSize write on shared dict litEnc by @zanarellidev in https://github.com/klauspost/compress/pull/1182
	* zstd: Keep BuildDict recent-offsets positive and loadable by @zanarellidev in https://github.com/klauspost/compress/pull/1184
	* zstd: Handle zero-literal BuildDict corpus by @cyphercodes in https://github.com/klauspost/compress/pull/1178
	* zstd: Don't clear the registered dictionary when decoding past the window by @sueun-dev in https://github.com/klauspost/compress/pull/1177

* Jul 20th, 2026 [1.19.1](https://github.com/klauspost/compress/releases/tag/v1.19.1)
	* zstd: Validate SnappyConverter literal copies in https://github.com/klauspost/compress/pull/1170
	* flate: Use `Peek` instead of `ReadByte` for the `bufio.Reader` decode path by @joechenrh in https://github.com/klauspost/compress/pull/1169
	* zstd: Bump avo pin, regenerate arm64 asm by @lizthegrey in https://github.com/klauspost/compress/pull/1167

* Jul 1st, 2026 [1.19.0](https://github.com/klauspost/compress/releases/tag/v1.19.0)
	* zstd: Add true concurrent stream encoding in https://github.com/klauspost/compress/pull/1136
	* zstd: arm64 decoder asm by @lizthegrey in https://github.com/klauspost/compress/pull/1160
	* flate: Add inflate checkpoints in https://github.com/klauspost/compress/pull/1154
	* zstd: avoid unused BuildDict encoder allocation by @snissn in https://github.com/klauspost/compress/pull/1147
	* snappy/s2: Limit length of varint in `decodedLen` by @eustas in https://github.com/klauspost/compress/pull/1148
	* gzhttp: match qvalue parameter case-insensitively (RFC 7231) by @z9z in https://github.com/klauspost/compress/pull/1149
	* zip: add NameDecoder callback for legacy encoding rewrite by @SAY-5 in https://github.com/klauspost/compress/pull/1150
	* huff0: Allow building tables from histogram in https://github.com/klauspost/compress/pull/1155
	* huff0: Allow building table from oversized histogram in https://github.com/klauspost/compress/pull/1156
	* s2sx: Clean symlink targets in https://github.com/klauspost/compress/pull/1163

<details>
	<summary>See changes to v1.18.x</summary>

* Jun 30th, 2026 [1.18.7](https://github.com/klauspost/compress/releases/tag/v1.18.7)
	* s2: Fix `NewDict` out-of-bounds read. Security release without other changes.

* Apr 30th, 2026 [1.18.6](https://github.com/klauspost/compress/releases/tag/v1.18.6)
	* s2: Fix amd64 stack frame corruption in https://github.com/klauspost/compress/pull/1145
	* gzhttp: Canonicalize ETag header by @justinmayhew in https://github.com/klauspost/compress/pull/1139
	* Pool hash tables in Go encode paths to reduce allocations by @huynhanx03 in https://github.com/klauspost/compress/pull/1143

* Mar 20th, 2026 [1.18.5](https://github.com/klauspost/compress/releases/tag/v1.18.5)
	* zstd: Fix crash when changing encoder dictionary with same ID in https://github.com/klauspost/compress/pull/1135
	* zstd: Default to full zero frames in https://github.com/klauspost/compress/pull/1134
	* flate: Clean up histogram order in https://github.com/klauspost/compress/pull/1133

* Feb 9th, 2026 [1.18.4](https://github.com/klauspost/compress/releases/tag/v1.18.4)
	* gzhttp: Add zstandard to server handler wrapper https://github.com/klauspost/compress/pull/1121
	* zstd: Add ResetWithOptions to encoder/decoder https://github.com/klauspost/compress/pull/1122
	* gzhttp: preserve qvalue when extra parameters follow in Accept-Encoding by @analytically in https://github.com/klauspost/compress/pull/1116

* Jan 16th, 2026 [1.18.3](https://github.com/klauspost/compress/releases/tag/v1.18.3)
	* Downstream CVE-2025-61728. See [golang/go#77102](https://github.com/golang/go/issues/77102).

* Dec 1st, 2025 - [1.18.2](https://github.com/klauspost/compress/releases/tag/v1.18.2)
	* flate: Fix invalid encoding on level 9 with single value input in https://github.com/klauspost/compress/pull/1115
	* flate: reduce stateless allocations by @RXamzin in https://github.com/klauspost/compress/pull/1106

* Oct 20, 2025 - [1.18.1](https://github.com/klauspost/compress/releases/tag/v1.18.1) - RETRACTED
  * zstd: Add simple zstd EncodeTo/DecodeTo functions  https://github.com/klauspost/compress/pull/1079
  * zstd: Fix incorrect buffer size in dictionary encodes https://github.com/klauspost/compress/pull/1059
  * s2: check for cap, not len of buffer in EncodeBetter/Best by @vdarulis in https://github.com/klauspost/compress/pull/1080
  * zlib: Avoiding extra allocation in zlib.reader.Reset by @travelpolicy in https://github.com/klauspost/compress/pull/1086
  * gzhttp: remove redundant err check in zstdReader by @ryanfowler in https://github.com/klauspost/compress/pull/1090
  * flate: Faster load+store https://github.com/klauspost/compress/pull/1104
  * flate: Simplify matchlen https://github.com/klauspost/compress/pull/1101
  * flate: Use exact sizes for huffman tables https://github.com/klauspost/compress/pull/1103

* Feb 19th, 2025 - [1.18.0](https://github.com/klauspost/compress/releases/tag/v1.18.0)
  * Add unsafe little endian loaders https://github.com/klauspost/compress/pull/1036
  * fix: check `r.err != nil` but return a nil value error `err` by @alingse in https://github.com/klauspost/compress/pull/1028
  * flate: Simplify L4-6 loading https://github.com/klauspost/compress/pull/1043
  * flate: Simplify matchlen (remove asm) https://github.com/klauspost/compress/pull/1045
  * s2: Improve small block compression speed w/o asm https://github.com/klauspost/compress/pull/1048
  * flate: Fix matchlen L5+L6 https://github.com/klauspost/compress/pull/1049
  * flate: Cleanup & reduce casts https://github.com/klauspost/compress/pull/1050

</details>

<details>
	<summary>See changes to v1.17.x</summary>

* Oct 11th, 2024 - [1.17.11](https://github.com/klauspost/compress/releases/tag/v1.17.11)
  * zstd: Fix extra CRC written with multiple Close calls https://github.com/klauspost/compress/pull/1017
  * s2: Don't use stack for index tables https://github.com/klauspost/compress/pull/1014
  * gzhttp: No content-type on no body response code by @juliens in https://github.com/klauspost/compress/pull/1011
  * gzhttp: Do not set the content-type when response has no body by @kevinpollet in https://github.com/klauspost/compress/pull/1013

* Sep 23rd, 2024 - [1.17.10](https://github.com/klauspost/compress/releases/tag/v1.17.10)
	* gzhttp: Add TransportAlwaysDecompress option. https://github.com/klauspost/compress/pull/978
	* gzhttp: Add supported decompress request body by @mirecl in https://github.com/klauspost/compress/pull/1002
	* s2: Add EncodeBuffer buffer recycling callback https://github.com/klauspost/compress/pull/982
	* zstd: Improve memory usage on small streaming encodes https://github.com/klauspost/compress/pull/1007
	* flate: read data written with partial flush by @vajexal in https://github.com/klauspost/compress/pull/996

* Jun 12th, 2024 - [1.17.9](https://github.com/klauspost/compress/releases/tag/v1.17.9)
	* s2: Reduce ReadFrom temporary allocations https://github.com/klauspost/compress/pull/949
	* flate, zstd: Shave some bytes off amd64 matchLen by @greatroar in https://github.com/klauspost/compress/pull/963
	* Upgrade zip/zlib to 1.22.4 upstream https://github.com/klauspost/compress/pull/970 https://github.com/klauspost/compress/pull/971
	* zstd: BuildDict fails with RLE table https://github.com/klauspost/compress/pull/951

* Apr 9th, 2024 - [1.17.8](https://github.com/klauspost/compress/releases/tag/v1.17.8)
	* zstd: Reject blocks where reserved values are not 0 https://github.com/klauspost/compress/pull/885
	* zstd: Add RLE detection+encoding https://github.com/klauspost/compress/pull/938

* Feb 21st, 2024 - [1.17.7](https://github.com/klauspost/compress/releases/tag/v1.17.7)
	* s2: Add AsyncFlush method: Complete the block without flushing by @Jille in https://github.com/klauspost/compress/pull/927
	* s2: Fix literal+repeat exceeds dst crash https://github.com/klauspost/compress/pull/930
  
* Feb 5th, 2024 - [1.17.6](https://github.com/klauspost/compress/releases/tag/v1.17.6)
	* zstd: Fix incorrect repeat coding in best mode https://github.com/klauspost/compress/pull/923
	* s2: Fix DecodeConcurrent deadlock on errors https://github.com/klauspost/compress/pull/925
  
* Jan 26th, 2024 - [v1.17.5](https://github.com/klauspost/compress/releases/tag/v1.17.5)
	* flate: Fix reset with dictionary on custom window encodes https://github.com/klauspost/compress/pull/912
	* zstd: Add Frame header encoding and stripping https://github.com/klauspost/compress/pull/908
	* zstd: Limit better/best default window to 8MB https://github.com/klauspost/compress/pull/913
	* zstd: Speed improvements by @greatroar in https://github.com/klauspost/compress/pull/896 https://github.com/klauspost/compress/pull/910
	* s2: Fix callbacks for skippable blocks and disallow 0xfe (Padding) by @Jille in https://github.com/klauspost/compress/pull/916 https://github.com/klauspost/compress/pull/917
https://github.com/klauspost/compress/pull/919 https://github.com/klauspost/compress/pull/918

* Dec 1st, 2023 - [v1.17.4](https://github.com/klauspost/compress/releases/tag/v1.17.4)
	* huff0: Speed up symbol counting by @greatroar in https://github.com/klauspost/compress/pull/887
	* huff0: Remove byteReader by @greatroar in https://github.com/klauspost/compress/pull/886
	* gzhttp: Allow overriding decompression on transport https://github.com/klauspost/compress/pull/892
	* gzhttp: Clamp compression level https://github.com/klauspost/compress/pull/890
	* gzip: Error out if reserved bits are set https://github.com/klauspost/compress/pull/891

* Nov 15th, 2023 - [v1.17.3](https://github.com/klauspost/compress/releases/tag/v1.17.3)
	* fse: Fix max header size https://github.com/klauspost/compress/pull/881
	* zstd: Improve better/best compression https://github.com/klauspost/compress/pull/877
	* gzhttp: Fix missing content type on Close https://github.com/klauspost/compress/pull/883

* Oct 22nd, 2023 - [v1.17.2](https://github.com/klauspost/compress/releases/tag/v1.17.2)
	* zstd: Fix rare *CORRUPTION* output in "best" mode. See https://github.com/klauspost/compress/pull/876

* Oct 14th, 2023 - [v1.17.1](https://github.com/klauspost/compress/releases/tag/v1.17.1)
	* s2: Fix S2 "best" dictionary wrong encoding https://github.com/klauspost/compress/pull/871
	* flate: Reduce allocations in decompressor and minor code improvements by @fakefloordiv in https://github.com/klauspost/compress/pull/869
	* s2: Fix EstimateBlockSize on 6&7 length input https://github.com/klauspost/compress/pull/867

* Sept 19th, 2023 - [v1.17.0](https://github.com/klauspost/compress/releases/tag/v1.17.0)
	* Add experimental dictionary builder  https://github.com/klauspost/compress/pull/853
	* Add xerial snappy read/writer https://github.com/klauspost/compress/pull/838
	* flate: Add limited window compression https://github.com/klauspost/compress/pull/843
	* s2: Do 2 overlapping match checks https://github.com/klauspost/compress/pull/839
	* flate: Add amd64 assembly matchlen https://github.com/klauspost/compress/pull/837
	* gzip: Copy bufio.Reader on Reset by @thatguystone in https://github.com/klauspost/compress/pull/860
   
</details>
<details>
	<summary>See changes to v1.16.x</summary>

   
* July 1st, 2023 - [v1.16.7](https://github.com/klauspost/compress/releases/tag/v1.16.7)
	* zstd: Fix default level first dictionary encode https://github.com/klauspost/compress/pull/829
	* s2: add GetBufferCapacity() method by @GiedriusS in https://github.com/klauspost/compress/pull/832

* June 13, 2023 - [v1.16.6](https://github.com/klauspost/compress/releases/tag/v1.16.6)
	* zstd: correctly ignore WithEncoderPadding(1) by @ianlancetaylor in https://github.com/klauspost/compress/pull/806
	* zstd: Add amd64 match length assembly https://github.com/klauspost/compress/pull/824
	* gzhttp: Handle informational headers by @rtribotte in https://github.com/klauspost/compress/pull/815
	* s2: Improve Better compression slightly https://github.com/klauspost/compress/pull/663

* Apr 16, 2023 - [v1.16.5](https://github.com/klauspost/compress/releases/tag/v1.16.5)
	* zstd: readByte needs to use io.ReadFull by @jnoxon in https://github.com/klauspost/compress/pull/802
	* gzip: Fix WriterTo after initial read https://github.com/klauspost/compress/pull/804

* Apr 5, 2023 - [v1.16.4](https://github.com/klauspost/compress/releases/tag/v1.16.4)
	* zstd: Improve zstd best efficiency by @greatroar and @klauspost in https://github.com/klauspost/compress/pull/784
	* zstd: Respect WithAllLitEntropyCompression https://github.com/klauspost/compress/pull/792
	* zstd: Fix amd64 not always detecting corrupt data https://github.com/klauspost/compress/pull/785
	* zstd: Various minor improvements by @greatroar in https://github.com/klauspost/compress/pull/788 https://github.com/klauspost/compress/pull/794 https://github.com/klauspost/compress/pull/795
	* s2: Fix huge block overflow https://github.com/klauspost/compress/pull/779
	* s2: Allow CustomEncoder fallback https://github.com/klauspost/compress/pull/780
	* gzhttp: Support ResponseWriter Unwrap() in gzhttp handler by @jgimenez in https://github.com/klauspost/compress/pull/799

* Mar 13, 2023 - [v1.16.1](https://github.com/klauspost/compress/releases/tag/v1.16.1)
	* zstd: Speed up + improve best encoder by @greatroar in https://github.com/klauspost/compress/pull/776
	* gzhttp: Add optional [BREACH mitigation](https://github.com/klauspost/compress/tree/master/gzhttp#breach-mitigation). https://github.com/klauspost/compress/pull/762 https://github.com/klauspost/compress/pull/768 https://github.com/klauspost/compress/pull/769 https://github.com/klauspost/compress/pull/770 https://github.com/klauspost/compress/pull/767
	* s2: Add Intel LZ4s converter https://github.com/klauspost/compress/pull/766
	* zstd: Minor bug fixes https://github.com/klauspost/compress/pull/771 https://github.com/klauspost/compress/pull/772 https://github.com/klauspost/compress/pull/773
	* huff0: Speed up compress1xDo by @greatroar in https://github.com/klauspost/compress/pull/774

* Feb 26, 2023 - [v1.16.0](https://github.com/klauspost/compress/releases/tag/v1.16.0)
	* s2: Add [Dictionary](https://github.com/klauspost/compress/tree/master/s2#dictionaries) support.  https://github.com/klauspost/compress/pull/685
	* s2: Add Compression Size Estimate.  https://github.com/klauspost/compress/pull/752
	* s2: Add support for custom stream encoder. https://github.com/klauspost/compress/pull/755
	* s2: Add LZ4 block converter. https://github.com/klauspost/compress/pull/748
	* s2: Support io.ReaderAt in ReadSeeker. https://github.com/klauspost/compress/pull/747
	* s2c/s2sx: Use concurrent decoding. https://github.com/klauspost/compress/pull/746
</details>

<details>
	<summary>See changes to v1.15.x</summary>
	
* Jan 21st, 2023 (v1.15.15)
	* deflate: Improve level 7-9 https://github.com/klauspost/compress/pull/739
	* zstd: Add delta encoding support by @greatroar in https://github.com/klauspost/compress/pull/728
	* zstd: Various speed improvements by @greatroar https://github.com/klauspost/compress/pull/741 https://github.com/klauspost/compress/pull/734 https://github.com/klauspost/compress/pull/736 https://github.com/klauspost/compress/pull/744 https://github.com/klauspost/compress/pull/743 https://github.com/klauspost/compress/pull/745
	* gzhttp: Add SuffixETag() and DropETag() options to prevent ETag collisions on compressed responses by @willbicks in https://github.com/klauspost/compress/pull/740

* Jan 3rd, 2023 (v1.15.14)

	* flate: Improve speed in big stateless blocks https://github.com/klauspost/compress/pull/718
	* zstd: Minor speed tweaks by @greatroar in https://github.com/klauspost/compress/pull/716 https://github.com/klauspost/compress/pull/720
	* export NoGzipResponseWriter for custom ResponseWriter wrappers by @harshavardhana in https://github.com/klauspost/compress/pull/722
	* s2: Add example for indexing and existing stream https://github.com/klauspost/compress/pull/723

* Dec 11, 2022 (v1.15.13)
	* zstd: Add [MaxEncodedSize](https://pkg.go.dev/github.com/klauspost/compress@v1.15.13/zstd#Encoder.MaxEncodedSize) to encoder  https://github.com/klauspost/compress/pull/691
	* zstd: Various tweaks and improvements https://github.com/klauspost/compress/pull/693 https://github.com/klauspost/compress/pull/695 https://github.com/klauspost/compress/pull/696 https://github.com/klauspost/compress/pull/701 https://github.com/klauspost/compress/pull/702 https://github.com/klauspost/compress/pull/703 https://github.com/klauspost/compress/pull/704 https://github.com/klauspost/compress/pull/705 https://github.com/klauspost/compress/pull/706 https://github.com/klauspost/compress/pull/707 https://github.com/klauspost/compress/pull/708

* Oct 26, 2022 (v1.15.12)

	* zstd: Tweak decoder allocs. https://github.com/klauspost/compress/pull/680
	* gzhttp: Always delete `HeaderNoCompression` https://github.com/klauspost/compress/pull/683

* Sept 26, 2022 (v1.15.11)

	* flate: Improve level 1-3 compression  https://github.com/klauspost/compress/pull/678
	* zstd: Improve "best" compression by @nightwolfz in https://github.com/klauspost/compress/pull/677
	* zstd: Fix+reduce decompression allocations https://github.com/klauspost/compress/pull/668
	* zstd: Fix non-effective noescape tag https://github.com/klauspost/compress/pull/667

* Sept 16, 2022 (v1.15.10)

	* zstd: Add [WithDecodeAllCapLimit](https://pkg.go.dev/github.com/klauspost/compress@v1.15.10/zstd#WithDecodeAllCapLimit) https://github.com/klauspost/compress/pull/649
	* Add Go 1.19 - deprecate Go 1.16  https://github.com/klauspost/compress/pull/651
	* flate: Improve level 5+6 compression https://github.com/klauspost/compress/pull/656
	* zstd: Improve "better" compression  https://github.com/klauspost/compress/pull/657
	* s2: Improve "best" compression https://github.com/klauspost/compress/pull/658
	* s2: Improve "better" compression. https://github.com/klauspost/compress/pull/635
	* s2: Slightly faster non-assembly decompression https://github.com/klauspost/compress/pull/646
	* Use arrays for constant size copies https://github.com/klauspost/compress/pull/659

* July 21, 2022 (v1.15.9)

	* zstd: Fix decoder crash on amd64 (no BMI) on invalid input https://github.com/klauspost/compress/pull/645
	* zstd: Disable decoder extended memory copies (amd64) due to possible crashes https://github.com/klauspost/compress/pull/644
	* zstd: Allow single segments up to "max decoded size" https://github.com/klauspost/compress/pull/643

* July 13, 2022 (v1.15.8)

	* gzip: fix stack exhaustion bug in Reader.Read https://github.com/klauspost/compress/pull/641
	* s2: Add Index header trim/restore https://github.com/klauspost/compress/pull/638
	* zstd: Optimize seqdeq amd64 asm by @greatroar in https://github.com/klauspost/compress/pull/636
	* zstd: Improve decoder memcopy https://github.com/klauspost/compress/pull/637
	* huff0: Pass a single bitReader pointer to asm by @greatroar in https://github.com/klauspost/compress/pull/634
	* zstd: Branchless getBits for amd64 w/o BMI2 by @greatroar in https://github.com/klauspost/compress/pull/640
	* gzhttp: Remove header before writing https://github.com/klauspost/compress/pull/639

* June 29, 2022 (v1.15.7)

	* s2: Fix absolute forward seeks  https://github.com/klauspost/compress/pull/633
	* zip: Merge upstream  https://github.com/klauspost/compress/pull/631
	* zip: Re-add zip64 fix https://github.com/klauspost/compress/pull/624
	* zstd: translate fseDecoder.buildDtable into asm by @WojciechMula in https://github.com/klauspost/compress/pull/598
	* flate: Faster histograms  https://github.com/klauspost/compress/pull/620
	* deflate: Use compound hcode  https://github.com/klauspost/compress/pull/622

* June 3, 2022 (v1.15.6)
	* s2: Improve coding for long, close matches https://github.com/klauspost/compress/pull/613
	* s2c: Add Snappy/S2 stream recompression https://github.com/klauspost/compress/pull/611
	* zstd: Always use configured block size https://github.com/klauspost/compress/pull/605
	* zstd: Fix incorrect hash table placement for dict encoding in default https://github.com/klauspost/compress/pull/606
	* zstd: Apply default config to ZipDecompressor without options https://github.com/klauspost/compress/pull/608
	* gzhttp: Exclude more common archive formats https://github.com/klauspost/compress/pull/612
	* s2: Add ReaderIgnoreCRC https://github.com/klauspost/compress/pull/609
	* s2: Remove sanity load on index creation https://github.com/klauspost/compress/pull/607
	* snappy: Use dedicated function for scoring https://github.com/klauspost/compress/pull/614
	* s2c+s2d: Use official snappy framed extension https://github.com/klauspost/compress/pull/610

* May 25, 2022 (v1.15.5)
	* s2: Add concurrent stream decompression https://github.com/klauspost/compress/pull/602
	* s2: Fix final emit oob read crash on amd64 https://github.com/klauspost/compress/pull/601
	* huff0: asm implementation of Decompress1X by @WojciechMula https://github.com/klauspost/compress/pull/596
	* zstd: Use 1 less goroutine for stream decoding https://github.com/klauspost/compress/pull/588
	* zstd: Copy literal in 16 byte blocks when possible https://github.com/klauspost/compress/pull/592
	* zstd: Speed up when WithDecoderLowmem(false) https://github.com/klauspost/compress/pull/599
	* zstd: faster next state update in BMI2 version of decode by @WojciechMula in https://github.com/klauspost/compress/pull/593
	* huff0: Do not check max size when reading table. https://github.com/klauspost/compress/pull/586
	* flate: Inplace hashing for level 7-9 https://github.com/klauspost/compress/pull/590


* May 11, 2022 (v1.15.4)
	* huff0: decompress directly into output by @WojciechMula in [#577](https://github.com/klauspost/compress/pull/577)
	* inflate: Keep dict on stack [#581](https://github.com/klauspost/compress/pull/581)
	* zstd: Faster decoding memcopy in asm [#583](https://github.com/klauspost/compress/pull/583)
	* zstd: Fix ignored crc [#580](https://github.com/klauspost/compress/pull/580)

* May 5, 2022 (v1.15.3)
	* zstd: Allow to ignore checksum checking by @WojciechMula [#572](https://github.com/klauspost/compress/pull/572)
	* s2: Fix incorrect seek for io.SeekEnd in [#575](https://github.com/klauspost/compress/pull/575)

* Apr 26, 2022 (v1.15.2)
	* zstd: Add x86-64 assembly for decompression on streams and blocks. Contributed by [@WojciechMula](https://github.com/WojciechMula). Typically 2x faster.  [#528](https://github.com/klauspost/compress/pull/528) [#531](https://github.com/klauspost/compress/pull/531) [#545](https://github.com/klauspost/compress/pull/545) [#537](https://github.com/klauspost/compress/pull/537)
	* zstd: Add options to ZipDecompressor and fixes [#539](https://github.com/klauspost/compress/pull/539)
	* s2: Use sorted search for index [#555](https://github.com/klauspost/compress/pull/555)
	* Minimum version is Go 1.16, added CI test on 1.18.

* Mar 11, 2022 (v1.15.1)
	* huff0: Add x86 assembly of Decode4X by @WojciechMula in [#512](https://github.com/klauspost/compress/pull/512)
	* zstd: Reuse zip decoders in [#514](https://github.com/klauspost/compress/pull/514)
	* zstd: Detect extra block data and report as corrupted in [#520](https://github.com/klauspost/compress/pull/520)
	* zstd: Handle zero sized frame content size stricter in [#521](https://github.com/klauspost/compress/pull/521)
	* zstd: Add stricter block size checks in [#523](https://github.com/klauspost/compress/pull/523)

* Mar 3, 2022 (v1.15.0)
	* zstd: Refactor decoder [#498](https://github.com/klauspost/compress/pull/498)
	* zstd: Add stream encoding without goroutines [#505](https://github.com/klauspost/compress/pull/505)
	* huff0: Prevent single blocks exceeding 16 bits by @klauspost in[#507](https://github.com/klauspost/compress/pull/507)
	* flate: Inline literal emission [#509](https://github.com/klauspost/compress/pull/509)
	* gzhttp: Add zstd to transport [#400](https://github.com/klauspost/compress/pull/400)
	* gzhttp: Make content-type optional [#510](https://github.com/klauspost/compress/pull/510)

Both compression and decompression now supports "synchronous" stream operations. This means that whenever "concurrency" is set to 1, they will operate without spawning goroutines.

Stream decompression is now faster on asynchronous, since the goroutine allocation much more effectively splits the workload. On typical streams this will typically use 2 cores fully for decompression. When a stream has finished decoding no goroutines will be left over, so decoders can now safely be pooled and still be garbage collected.

While the release has been extensively tested, it is recommended to testing when upgrading.

</details>

<details>
	<summary>See changes to v1.14.x</summary>
	
* Feb 22, 2022 (v1.14.4)
	* flate: Fix rare huffman only (-2) corruption. [#503](https://github.com/klauspost/compress/pull/503)
	* zip: Update deprecated CreateHeaderRaw to correctly call CreateRaw by @saracen in [#502](https://github.com/klauspost/compress/pull/502)
	* zip: don't read data descriptor early by @saracen in [#501](https://github.com/klauspost/compress/pull/501)  #501
	* huff0: Use static decompression buffer up to 30% faster [#499](https://github.com/klauspost/compress/pull/499) [#500](https://github.com/klauspost/compress/pull/500)

* Feb 17, 2022 (v1.14.3)
	* flate: Improve fastest levels compression speed ~10% more throughput. [#482](https://github.com/klauspost/compress/pull/482) [#489](https://github.com/klauspost/compress/pull/489) [#490](https://github.com/klauspost/compress/pull/490) [#491](https://github.com/klauspost/compress/pull/491) [#494](https://github.com/klauspost/compress/pull/494)  [#478](https://github.com/klauspost/compress/pull/478)
	* flate: Faster decompression speed, ~5-10%. [#483](https://github.com/klauspost/compress/pull/483)
	* s2: Faster compression with Go v1.18 and amd64 microarch level 3+. [#484](https://github.com/klauspost/compress/pull/484) [#486](https://github.com/klauspost/compress/pull/486)

* Jan 25, 2022 (v1.14.2)
	* zstd: improve header decoder by @dsnet  [#476](https://github.com/klauspost/compress/pull/476)
	* zstd: Add bigger default blocks  [#469](https://github.com/klauspost/compress/pull/469)
	* zstd: Remove unused decompression buffer [#470](https://github.com/klauspost/compress/pull/470)
	* zstd: Fix logically dead code by @ningmingxiao [#472](https://github.com/klauspost/compress/pull/472)
	* flate: Improve level 7-9 [#471](https://github.com/klauspost/compress/pull/471) [#473](https://github.com/klauspost/compress/pull/473)
	* zstd: Add noasm tag for xxhash [#475](https://github.com/klauspost/compress/pull/475)

* Jan 11, 2022 (v1.14.1)
	* s2: Add stream index in [#462](https://github.com/klauspost/compress/pull/462)
	* flate: Speed and efficiency improvements in [#439](https://github.com/klauspost/compress/pull/439) [#461](https://github.com/klauspost/compress/pull/461) [#455](https://github.com/klauspost/compress/pull/455) [#452](https://github.com/klauspost/compress/pull/452) [#458](https://github.com/klauspost/compress/pull/458)
	* zstd: Performance improvement in [#420]( https://github.com/klauspost/compress/pull/420) [#456](https://github.com/klauspost/compress/pull/456) [#437](https://github.com/klauspost/compress/pull/437) [#467](https://github.com/klauspost/compress/pull/467) [#468](https://github.com/klauspost/compress/pull/468)
	* zstd: add arm64 xxhash assembly in [#464](https://github.com/klauspost/compress/pull/464)
	* Add garbled for binaries for s2 in [#445](https://github.com/klauspost/compress/pull/445)
</details>

<details>
	<summary>See changes to v1.13.x</summary>
	
* Aug 30, 2021 (v1.13.5)
	* gz/zlib/flate: Alias stdlib errors [#425](https://github.com/klauspost/compress/pull/425)
	* s2: Add block support to commandline tools [#413](https://github.com/klauspost/compress/pull/413)
	* zstd: pooledZipWriter should return Writers to the same pool [#426](https://github.com/klauspost/compress/pull/426)
	* Removed golang/snappy as external dependency for tests [#421](https://github.com/klauspost/compress/pull/421)

* Aug 12, 2021 (v1.13.4)
	* Add [snappy replacement package](https://github.com/klauspost/compress/tree/master/snappy).
	* zstd: Fix incorrect encoding in "best" mode [#415](https://github.com/klauspost/compress/pull/415)

* Aug 3, 2021 (v1.13.3) 
	* zstd: Improve Best compression [#404](https://github.com/klauspost/compress/pull/404)
	* zstd: Fix WriteTo error forwarding [#411](https://github.com/klauspost/compress/pull/411)
	* gzhttp: Return http.HandlerFunc instead of http.Handler. Unlikely breaking change. [#406](https://github.com/klauspost/compress/pull/406)
	* s2sx: Fix max size error [#399](https://github.com/klauspost/compress/pull/399)
	* zstd: Add optional stream content size on reset [#401](https://github.com/klauspost/compress/pull/401)
	* zstd: use SpeedBestCompression for level >= 10 [#410](https://github.com/klauspost/compress/pull/410)

* Jun 14, 2021 (v1.13.1)
	* s2: Add full Snappy output support  [#396](https://github.com/klauspost/compress/pull/396)
	* zstd: Add configurable [Decoder window](https://pkg.go.dev/github.com/klauspost/compress/zstd#WithDecoderMaxWindow) size [#394](https://github.com/klauspost/compress/pull/394)
	* gzhttp: Add header to skip compression  [#389](https://github.com/klauspost/compress/pull/389)
	* s2: Improve speed with bigger output margin  [#395](https://github.com/klauspost/compress/pull/395)

* Jun 3, 2021 (v1.13.0)
	* Added [gzhttp](https://github.com/klauspost/compress/tree/master/gzhttp#gzip-handler) which allows wrapping HTTP servers and clients with GZIP compressors.
	* zstd: Detect short invalid signatures [#382](https://github.com/klauspost/compress/pull/382)
	* zstd: Spawn decoder goroutine only if needed. [#380](https://github.com/klauspost/compress/pull/380)
</details>


<details>
	<summary>See changes to v1.12.x</summary>
	
* May 25, 2021 (v1.12.3)
	* deflate: Better/faster Huffman encoding [#374](https://github.com/klauspost/compress/pull/374)
	* deflate: Allocate less for history. [#375](https://github.com/klauspost/compress/pull/375)
	* zstd: Forward read errors [#373](https://github.com/klauspost/compress/pull/373) 

* Apr 27, 2021 (v1.12.2)
	* zstd: Improve better/best compression [#360](https://github.com/klauspost/compress/pull/360) [#364](https://github.com/klauspost/compress/pull/364) [#365](https://github.com/klauspost/compress/pull/365)
	* zstd: Add helpers to compress/decompress zstd inside zip files [#363](https://github.com/klauspost/compress/pull/363)
	* deflate: Improve level 5+6 compression [#367](https://github.com/klauspost/compress/pull/367)
	* s2: Improve better/best compression [#358](https://github.com/klauspost/compress/pull/358) [#359](https://github.com/klauspost/compress/pull/358)
	* s2: Load after checking src limit on amd64. [#362](https://github.com/klauspost/compress/pull/362)
	* s2sx: Limit max executable size [#368](https://github.com/klauspost/compress/pull/368) 

* Apr 14, 2021 (v1.12.1)
	* snappy package removed. Upstream added as dependency.
	* s2: Better compression in "best" mode [#353](https://github.com/klauspost/compress/pull/353)
	* s2sx: Add stdin input and detect pre-compressed from signature [#352](https://github.com/klauspost/compress/pull/352)
	* s2c/s2d: Add http as possible input [#348](https://github.com/klauspost/compress/pull/348)
	* s2c/s2d/s2sx: Always truncate when writing files [#352](https://github.com/klauspost/compress/pull/352)
	* zstd: Reduce memory usage further when using [WithLowerEncoderMem](https://pkg.go.dev/github.com/klauspost/compress/zstd#WithLowerEncoderMem) [#346](https://github.com/klauspost/compress/pull/346)
	* s2: Fix potential problem with amd64 assembly and profilers [#349](https://github.com/klauspost/compress/pull/349)
</details>

<details>
	<summary>See changes to v1.11.x</summary>
	
* Mar 26, 2021 (v1.11.13)
	* zstd: Big speedup on small dictionary encodes [#344](https://github.com/klauspost/compress/pull/344) [#345](https://github.com/klauspost/compress/pull/345)
	* zstd: Add [WithLowerEncoderMem](https://pkg.go.dev/github.com/klauspost/compress/zstd#WithLowerEncoderMem) encoder option [#336](https://github.com/klauspost/compress/pull/336)
	* deflate: Improve entropy compression [#338](https://github.com/klauspost/compress/pull/338)
	* s2: Clean up and minor performance improvement in best [#341](https://github.com/klauspost/compress/pull/341)

* Mar 5, 2021 (v1.11.12)
	* s2: Add `s2sx` binary that creates [self extracting archives](https://github.com/klauspost/compress/tree/master/s2#s2sx-self-extracting-archives).
	* s2: Speed up decompression on non-assembly platforms [#328](https://github.com/klauspost/compress/pull/328)

* Mar 1, 2021 (v1.11.9)
	* s2: Add ARM64 decompression assembly. Around 2x output speed. [#324](https://github.com/klauspost/compress/pull/324)
	* s2: Improve "better" speed and efficiency. [#325](https://github.com/klauspost/compress/pull/325)
	* s2: Fix binaries.

* Feb 25, 2021 (v1.11.8)
	* s2: Fixed occasional out-of-bounds write on amd64. Upgrade recommended.
	* s2: Add AMD64 assembly for better mode. 25-50% faster. [#315](https://github.com/klauspost/compress/pull/315)
	* s2: Less upfront decoder allocation. [#322](https://github.com/klauspost/compress/pull/322)
	* zstd: Faster "compression" of incompressible data. [#314](https://github.com/klauspost/compress/pull/314)
	* zip: Fix zip64 headers. [#313](https://github.com/klauspost/compress/pull/313)
  
* Jan 14, 2021 (v1.11.7)
	* Use Bytes() interface to get bytes across packages. [#309](https://github.com/klauspost/compress/pull/309)
	* s2: Add 'best' compression option.  [#310](https://github.com/klauspost/compress/pull/310)
	* s2: Add ReaderMaxBlockSize, changes `s2.NewReader` signature to include varargs. [#311](https://github.com/klauspost/compress/pull/311)
	* s2: Fix crash on small better buffers. [#308](https://github.com/klauspost/compress/pull/308)
	* s2: Clean up decoder. [#312](https://github.com/klauspost/compress/pull/312)

* Jan 7, 2021 (v1.11.6)
	* zstd: Make decoder allocations smaller [#306](https://github.com/klauspost/compress/pull/306)
	* zstd: Free Decoder resources when Reset is called with a nil io.Reader  [#305](https://github.com/klauspost/compress/pull/305)

* Dec 20, 2020 (v1.11.4)
	* zstd: Add Best compression mode [#304](https://github.com/klauspost/compress/pull/304)
	* Add header decoder [#299](https://github.com/klauspost/compress/pull/299)
	* s2: Add uncompressed stream option [#297](https://github.com/klauspost/compress/pull/297)
	* Simplify/speed up small blocks with known max size. [#300](https://github.com/klauspost/compress/pull/300)
	* zstd: Always reset literal dict encoder [#303](https://github.com/klauspost/compress/pull/303)

* Nov 15, 2020 (v1.11.3)
	* inflate: 10-15% faster decompression  [#293](https://github.com/klauspost/compress/pull/293)
	* zstd: Tweak DecodeAll default allocation [#295](https://github.com/klauspost/compress/pull/295)

* Oct 11, 2020 (v1.11.2)
	* s2: Fix out of bounds read in "better" block compression [#291](https://github.com/klauspost/compress/pull/291)

* Oct 1, 2020 (v1.11.1)
	* zstd: Set allLitEntropy true in default configuration [#286](https://github.com/klauspost/compress/pull/286)

* Sept 8, 2020 (v1.11.0)
	* zstd: Add experimental compression [dictionaries](https://github.com/klauspost/compress/tree/master/zstd#dictionaries) [#281](https://github.com/klauspost/compress/pull/281)
	* zstd: Fix mixed Write and ReadFrom calls [#282](https://github.com/klauspost/compress/pull/282)
	* inflate/gz: Limit variable shifts, ~5% faster decompression [#274](https://github.com/klauspost/compress/pull/274)
</details>

<details>
	<summary>See changes to v1.10.x</summary>
 
* July 8, 2020 (v1.10.11) 
	* zstd: Fix extra block when compressing with ReadFrom. [#278](https://github.com/klauspost/compress/pull/278)
	* huff0: Also populate compression table when reading decoding table. [#275](https://github.com/klauspost/compress/pull/275)
	
* June 23, 2020 (v1.10.10) 
	* zstd: Skip entropy compression in fastest mode when no matches. [#270](https://github.com/klauspost/compress/pull/270)
	
* June 16, 2020 (v1.10.9): 
	* zstd: API change for specifying dictionaries. See [#268](https://github.com/klauspost/compress/pull/268)
	* zip: update CreateHeaderRaw to handle zip64 fields. [#266](https://github.com/klauspost/compress/pull/266)
	* Fuzzit tests removed. The service has been purchased and is no longer available.
	
* June 5, 2020 (v1.10.8): 
	* 1.15x faster zstd block decompression. [#265](https://github.com/klauspost/compress/pull/265)
	
* June 1, 2020 (v1.10.7): 
	* Added zstd decompression [dictionary support](https://github.com/klauspost/compress/tree/master/zstd#dictionaries)
	* Increase zstd decompression speed up to 1.19x.  [#259](https://github.com/klauspost/compress/pull/259)
	* Remove internal reset call in zstd compression and reduce allocations. [#263](https://github.com/klauspost/compress/pull/263)
	
* May 21, 2020: (v1.10.6) 
	* zstd: Reduce allocations while decoding. [#258](https://github.com/klauspost/compress/pull/258), [#252](https://github.com/klauspost/compress/pull/252)
	* zstd: Stricter decompression checks.
	
* April 12, 2020: (v1.10.5)
	* s2-commands: Flush output when receiving SIGINT. [#239](https://github.com/klauspost/compress/pull/239)
	
* Apr 8, 2020: (v1.10.4) 
	* zstd: Minor/special case optimizations. [#251](https://github.com/klauspost/compress/pull/251),  [#250](https://github.com/klauspost/compress/pull/250),  [#249](https://github.com/klauspost/compress/pull/249),  [#247](https://github.com/klauspost/compress/pull/247)
* Mar 11, 2020: (v1.10.3) 
	* s2: Use S2 encoder in pure Go mode for Snappy output as well. [#245](https://github.com/klauspost/compress/pull/245)
	* s2: Fix pure Go block encoder. [#244](https://github.com/klauspost/compress/pull/244)
	* zstd: Added "better compression" mode. [#240](https://github.com/klauspost/compress/pull/240)
	* zstd: Improve speed of fastest compression mode by 5-10% [#241](https://github.com/klauspost/compress/pull/241)
	* zstd: Skip creating encoders when not needed. [#238](https://github.com/klauspost/compress/pull/238)
	
* Feb 27, 2020: (v1.10.2) 
	* Close to 50% speedup in inflate (gzip/zip decompression). [#236](https://github.com/klauspost/compress/pull/236) [#234](https://github.com/klauspost/compress/pull/234) [#232](https://github.com/klauspost/compress/pull/232)
	* Reduce deflate level 1-6 memory usage up to 59%. [#227](https://github.com/klauspost/compress/pull/227)
	
* Feb 18, 2020: (v1.10.1)
	* Fix zstd crash when resetting multiple times without sending data. [#226](https://github.com/klauspost/compress/pull/226)
	* deflate: Fix dictionary use on level 1-6. [#224](https://github.com/klauspost/compress/pull/224)
	* Remove deflate writer reference when closing. [#224](https://github.com/klauspost/compress/pull/224)
	
* Feb 4, 2020: (v1.10.0) 
	* Add optional dictionary to [stateless deflate](https://pkg.go.dev/github.com/klauspost/compress/flate?tab=doc#StatelessDeflate). Breaking change, send `nil` for previous behaviour. [#216](https://github.com/klauspost/compress/pull/216)
	* Fix buffer overflow on repeated small block deflate.  [#218](https://github.com/klauspost/compress/pull/218)
	* Allow copying content from an existing ZIP file without decompressing+compressing. [#214](https://github.com/klauspost/compress/pull/214)
	* Added [S2](https://github.com/klauspost/compress/tree/master/s2#s2-compression) AMD64 assembler and various optimizations. Stream speed >10GB/s.  [#186](https://github.com/klauspost/compress/pull/186)

</details>

<details>
	<summary>See changes prior to v1.10.0</summary>

* Jan 20,2020 (v1.9.8) Optimize gzip/deflate with better size estimates and faster table generation. [#207](https://github.com/klauspost/compress/pull/207) by [luyu6056](https://github.com/luyu6056),  [#206](https://github.com/klauspost/compress/pull/206).
* Jan 11, 2020: S2 Encode/Decode will use provided buffer if capacity is big enough. [#204](https://github.com/klauspost/compress/pull/204) 
* Jan 5, 2020: (v1.9.7) Fix another zstd regression in v1.9.5 - v1.9.6 removed.
* Jan 4, 2020: (v1.9.6) Regression in v1.9.5 fixed causing corrupt zstd encodes in rare cases.
* Jan 4, 2020: Faster IO in [s2c + s2d commandline tools](https://github.com/klauspost/compress/tree/master/s2#commandline-tools) compression/decompression. [#192](https://github.com/klauspost/compress/pull/192)
* Dec 29, 2019: Removed v1.9.5 since fuzz tests showed a compatibility problem with the reference zstandard decoder.
* Dec 29, 2019: (v1.9.5) zstd: 10-20% faster block compression. [#199](https://github.com/klauspost/compress/pull/199)
* Dec 29, 2019: [zip](https://godoc.org/github.com/klauspost/compress/zip) package updated with latest Go features
* Dec 29, 2019: zstd: Single segment flag condintions tweaked. [#197](https://github.com/klauspost/compress/pull/197)
* Dec 18, 2019: s2: Faster compression when ReadFrom is used. [#198](https://github.com/klauspost/compress/pull/198)
* Dec 10, 2019: s2: Fix repeat length output when just above at 16MB limit.
* Dec 10, 2019: zstd: Add function to get decoder as io.ReadCloser. [#191](https://github.com/klauspost/compress/pull/191)
* Dec 3, 2019: (v1.9.4) S2: limit max repeat length. [#188](https://github.com/klauspost/compress/pull/188)
* Dec 3, 2019: Add [WithNoEntropyCompression](https://godoc.org/github.com/klauspost/compress/zstd#WithNoEntropyCompression) to zstd [#187](https://github.com/klauspost/compress/pull/187)
* Dec 3, 2019: Reduce memory use for tests. Check for leaked goroutines.
* Nov 28, 2019 (v1.9.3) Less allocations in stateless deflate.
* Nov 28, 2019: 5-20% Faster huff0 decode. Impacts zstd as well. [#184](https://github.com/klauspost/compress/pull/184)
* Nov 12, 2019 (v1.9.2) Added [Stateless Compression](#stateless-compression) for gzip/deflate.
* Nov 12, 2019: Fixed zstd decompression of large single blocks. [#180](https://github.com/klauspost/compress/pull/180)
* Nov 11, 2019: Set default  [s2c](https://github.com/klauspost/compress/tree/master/s2#commandline-tools) block size to 4MB.
* Nov 11, 2019: Reduce inflate memory use by 1KB.
* Nov 10, 2019: Less allocations in deflate bit writer.
* Nov 10, 2019: Fix inconsistent error returned by zstd decoder.
* Oct 28, 2019 (v1.9.1) ztsd: Fix crash when compressing blocks. [#174](https://github.com/klauspost/compress/pull/174)
* Oct 24, 2019 (v1.9.0) zstd: Fix rare data corruption [#173](https://github.com/klauspost/compress/pull/173)
* Oct 24, 2019 zstd: Fix huff0 out of buffer write [#171](https://github.com/klauspost/compress/pull/171) and always return errors [#172](https://github.com/klauspost/compress/pull/172) 
* Oct 10, 2019: Big deflate rewrite, 30-40% faster with better compression [#105](https://github.com/klauspost/compress/pull/105)

</details>

<details>
	<summary>See changes prior to v1.9.0</summary>

* Oct 10, 2019: (v1.8.6) zstd: Allow partial reads to get flushed data. [#169](https://github.com/klauspost/compress/pull/169)
* Oct 3, 2019: Fix inconsistent results on broken zstd streams.
* Sep 25, 2019: Added `-rm` (remove source files) and `-q` (no output except errors) to `s2c` and `s2d` [commands](https://github.com/klauspost/compress/tree/master/s2#commandline-tools)
* Sep 16, 2019: (v1.8.4) Add `s2c` and `s2d` [commandline tools](https://github.com/klauspost/compress/tree/master/s2#commandline-tools).
* Sep 10, 2019: (v1.8.3) Fix s2 decoder [Skip](https://godoc.org/github.com/klauspost/compress/s2#Reader.Skip).
* Sep 7, 2019: zstd: Added [WithWindowSize](https://godoc.org/github.com/klauspost/compress/zstd#WithWindowSize), contributed by [ianwilkes](https://github.com/ianwilkes).
* Sep 5, 2019: (v1.8.2) Add [WithZeroFrames](https://godoc.org/github.com/klauspost/compress/zstd#WithZeroFrames) which adds full zero payload block encoding option.
* Sep 5, 2019: Lazy initialization of zstandard predefined en/decoder tables.
* Aug 26, 2019: (v1.8.1) S2: 1-2% compression increase in "better" compression mode.
* Aug 26, 2019: zstd: Check maximum size of Huffman 1X compressed literals while decoding.
* Aug 24, 2019: (v1.8.0) Added [S2 compression](https://github.com/klauspost/compress/tree/master/s2#s2-compression), a high performance replacement for Snappy. 
* Aug 21, 2019: (v1.7.6) Fixed minor issues found by fuzzer. One could lead to zstd not decompressing.
* Aug 18, 2019: Add [fuzzit](https://fuzzit.dev/) continuous fuzzing.
* Aug 14, 2019: zstd: Skip incompressible data 2x faster.  [#147](https://github.com/klauspost/compress/pull/147)
* Aug 4, 2019 (v1.7.5): Better literal compression. [#146](https://github.com/klauspost/compress/pull/146)
* Aug 4, 2019: Faster zstd compression. [#143](https://github.com/klauspost/compress/pull/143) [#144](https://github.com/klauspost/compress/pull/144)
* Aug 4, 2019: Faster zstd decompression. [#145](https://github.com/klauspost/compress/pull/145) [#143](https://github.com/klauspost/compress/pull/143) [#142](https://github.com/klauspost/compress/pull/142)
* July 15, 2019 (v1.7.4): Fix double EOF block in rare cases on zstd encoder.
* July 15, 2019 (v1.7.3): Minor speedup/compression increase in default zstd encoder.
* July 14, 2019: zstd decoder: Fix decompression error on multiple uses with mixed content.
* July 7, 2019 (v1.7.2): Snappy update, zstd decoder potential race fix.
* June 17, 2019: zstd decompression bugfix.
* June 17, 2019: fix 32 bit builds.
* June 17, 2019: Easier use in modules (less dependencies).
* June 9, 2019: New stronger "default" [zstd](https://github.com/klauspost/compress/tree/master/zstd#zstd) compression mode. Matches zstd default compression ratio.
* June 5, 2019: 20-40% throughput in [zstandard](https://github.com/klauspost/compress/tree/master/zstd#zstd) compression and better compression.
* June 5, 2019: deflate/gzip compression: Reduce memory usage of lower compression levels.
* June 2, 2019: Added [zstandard](https://github.com/klauspost/compress/tree/master/zstd#zstd) compression!
* May 25, 2019: deflate/gzip: 10% faster bit writer, mostly visible in lower levels.
* Apr 22, 2019: [zstd](https://github.com/klauspost/compress/tree/master/zstd#zstd) decompression added.
* Aug 1, 2018: Added [huff0 README](https://github.com/klauspost/compress/tree/master/huff0#huff0-entropy-compression).
* Jul 8, 2018: Added [Performance Update 2018](#performance-update-2018) below.
* Jun 23, 2018: Merged [Go 1.11 inflate optimizations](https://go-review.googlesource.com/c/go/+/102235). Go 1.9 is now required. Backwards compatible version tagged with [v1.3.0](https://github.com/klauspost/compress/releases/tag/v1.3.0).
* Apr 2, 2018: Added [huff0](https://godoc.org/github.com/klauspost/compress/huff0) en/decoder. Experimental for now, API may change.
* Mar 4, 2018: Added [FSE Entropy](https://godoc.org/github.com/klauspost/compress/fse) en/decoder. Experimental for now, API may change.
* Nov 3, 2017: Add compression [Estimate](https://godoc.org/github.com/klauspost/compress#Estimate) function.
* May 28, 2017: Reduce allocations when resetting decoder.
* Apr 02, 2017: Change back to official crc32, since changes were merged in Go 1.7.
* Jan 14, 2017: Reduce stack pressure due to array copies. See [Issue #18625](https://github.com/golang/go/issues/18625).
* Oct 25, 2016: Level 2-4 have been rewritten and now offers significantly better performance than before.
* Oct 20, 2016: Port zlib changes from Go 1.7 to fix zlib writer issue. Please update.
* Oct 16, 2016: Go 1.7 changes merged. Apples to apples this package is a few percent faster, but has a significantly better balance between speed and compression per level. 
* Mar 24, 2016: Always attempt Huffman encoding on level 4-7. This improves base 64 encoded data compression.
* Mar 24, 2016: Small speedup for level 1-3.
* Feb 19, 2016: Faster bit writer, level -2 is 15% faster, level 1 is 4% faster.
* Feb 19, 2016: Handle small payloads faster in level 1-3.
* Feb 19, 2016: Added faster level 2 + 3 compression modes.
* Feb 19, 2016: [Rebalanced compression levels](https://blog.klauspost.com/rebalancing-deflate-compression-levels/), so there is a more even progression in terms of compression. New default level is 5.
* Feb 14, 2016: Snappy: Merge upstream changes. 
* Feb 14, 2016: Snappy: Fix aggressive skipping.
* Feb 14, 2016: Snappy: Update benchmark.
* Feb 13, 2016: Deflate: Fixed assembler problem that could lead to sub-optimal compression.
* Feb 12, 2016: Snappy: Added AMD64 SSE 4.2 optimizations to matching, which makes easy to compress material run faster. Typical speedup is around 25%.
* Feb 9, 2016: Added Snappy package fork. This version is 5-7% faster, much more on hard to compress content.
* Jan 30, 2016: Optimize level 1 to 3 by not considering static dictionary or storing uncompressed. ~4-5% speedup.
* Jan 16, 2016: Optimization on deflate level 1,2,3 compression.
* Jan 8 2016: Merge [CL 18317](https://go-review.googlesource.com/#/c/18317): fix reading, writing of zip64 archives.
* Dec 8 2015: Make level 1 and -2 deterministic even if write size differs.
* Dec 8 2015: Split encoding functions, so hashing and matching can potentially be inlined. 1-3% faster on AMD64. 5% faster on other platforms.
* Dec 8 2015: Fixed rare [one byte out-of bounds read](https://github.com/klauspost/compress/issues/20). Please update!
* Nov 23 2015: Optimization on token writer. ~2-4% faster. Contributed by [@dsnet](https://github.com/dsnet).
* Nov 20 2015: Small optimization to bit writer on 64 bit systems.
* Nov 17 2015: Fixed out-of-bound errors if the underlying Writer returned an error. See [#15](https://github.com/klauspost/compress/issues/15).
* Nov 12 2015: Added [io.WriterTo](https://golang.org/pkg/io/#WriterTo) support to gzip/inflate.
* Nov 11 2015: Merged [CL 16669](https://go-review.googlesource.com/#/c/16669/4): archive/zip: enable overriding (de)compressors per file
* Oct 15 2015: Added skipping on uncompressible data. Random data speed up >5x.

</details>

# deflate usage

The packages are drop-in replacements for standard library [deflate](https://godoc.org/github.com/klauspost/compress/flate), [gzip](https://godoc.org/github.com/klauspost/compress/gzip), [zip](https://godoc.org/github.com/klauspost/compress/zip), and [zlib](https://godoc.org/github.com/klauspost/compress/zlib). Simply replace the import path to use them:

Typical speed is about 2x of the standard library packages.

| old import       | new import                            | Documentation                                                           |
|------------------|---------------------------------------|-------------------------------------------------------------------------|
| `compress/gzip`  | `github.com/klauspost/compress/gzip`  | [gzip](https://pkg.go.dev/github.com/klauspost/compress/gzip?tab=doc)   |
| `compress/zlib`  | `github.com/klauspost/compress/zlib`  | [zlib](https://pkg.go.dev/github.com/klauspost/compress/zlib?tab=doc)   |
| `archive/zip`    | `github.com/klauspost/compress/zip`   | [zip](https://pkg.go.dev/github.com/klauspost/compress/zip?tab=doc)     |
| `compress/flate` | `github.com/klauspost/compress/flate` | [flate](https://pkg.go.dev/github.com/klauspost/compress/flate?tab=doc) |

You may also be interested in [pgzip](https://github.com/klauspost/pgzip), which is a drop-in replacement for gzip, which support multithreaded compression on big files and the optimized [crc32](https://github.com/klauspost/crc32) package used by these packages.

The packages implement the same API as the standard library, so you can use the original godoc documentation: [gzip](http://golang.org/pkg/compress/gzip/), [zip](http://golang.org/pkg/archive/zip/), [zlib](http://golang.org/pkg/compress/zlib/), [flate](http://golang.org/pkg/compress/flate/).

Currently there is only minor speedup on decompression (mostly CRC32 calculation).

Memory usage is typically 1MB for a Writer. stdlib is in the same range. 
If you expect to have a lot of concurrently allocated Writers consider using 
the stateless compression described below.

For compression performance, see: [this spreadsheet](https://docs.google.com/spreadsheets/d/1nuNE2nPfuINCZJRMt6wFWhKpToF95I47XjSsc-1rbPQ/edit?usp=sharing).

To disable all assembly add `-tags=noasm`. This works across all packages.

# Stateless compression

This package offers stateless compression as a special option for gzip/deflate. 
It will do compression but without maintaining any state between Write calls.

This means there will be no memory kept between Write calls, but compression and speed will be suboptimal.

This is only relevant in cases where you expect to run many thousands of compressors concurrently, 
but with very little activity. This is *not* intended for regular web servers serving individual requests.  

Because of this, the size of actual Write calls will affect output size.

In gzip, specify level `-3` / `gzip.StatelessCompression` to enable.

For direct deflate use, NewStatelessWriter and StatelessDeflate are available. See [documentation](https://godoc.org/github.com/klauspost/compress/flate#NewStatelessWriter)

A `bufio.Writer` can of course be used to control write sizes. For example, to use a 4KB buffer:

```go
	// replace 'ioutil.Discard' with your output.
	gzw, err := gzip.NewWriterLevel(ioutil.Discard, gzip.StatelessCompression)
	if err != nil {
		return err
	}
	defer gzw.Close()

	w := bufio.NewWriterSize(gzw, 4096)
	defer w.Flush()
	
	// Write to 'w' 
```

This will only use up to 4KB in memory when the writer is idle. 

Compression is almost always worse than the fastest compression level 
and each write will allocate (a little) memory. 


# Other packages

Here are other packages of good quality and pure Go (no cgo wrappers or autoconverted code):

* [github.com/pierrec/lz4](https://github.com/pierrec/lz4) - strong multithreaded LZ4 compression.
* [github.com/cosnicolaou/pbzip2](https://github.com/cosnicolaou/pbzip2) - multithreaded bzip2 decompression.
* [github.com/dsnet/compress](https://github.com/dsnet/compress) - brotli decompression, bzip2 writer.
* [github.com/ronanh/intcomp](https://github.com/ronanh/intcomp) - Integer compression.
* [github.com/spenczar/fpc](https://github.com/spenczar/fpc) - Float compression.
* [github.com/minio/zipindex](https://github.com/minio/zipindex) - External ZIP directory index.
* [github.com/ybirader/pzip](https://github.com/ybirader/pzip) - Fast concurrent zip archiver and extractor.

# license

This code is licensed under the same conditions as the original Go code. See LICENSE file.

---

### Overview (`vendor/github.com/klauspost/pgzip/README.md`)

pgzip
=====

Go parallel gzip compression/decompression. This is a fully gzip compatible drop in replacement for "compress/gzip".

This will split compression into blocks that are compressed in parallel. 
This can be useful for compressing big amounts of data. The output is a standard gzip file.

The gzip decompression is modified so it decompresses ahead of the current reader. 
This means that reads will be non-blocking if the decompressor can keep ahead of your code reading from it. 
CRC calculation also takes place in a separate goroutine.

You should only use this if you are (de)compressing big amounts of data, 
say **more than 1MB** at the time, otherwise you will not see any benefit, 
and it will likely be faster to use the internal gzip library 
or [this package](https://github.com/klauspost/compress).

It is important to note that this library creates and reads *standard gzip files*. 
You do not have to match the compressor/decompressor to get the described speedups, 
and the gzip files are fully compatible with other gzip readers/writers.

A golang variant of this is [bgzf](https://godoc.org/github.com/biogo/hts/bgzf), 
which has the same feature, as well as seeking in the resulting file. 
The only drawback is a slightly bigger overhead compared to this and pure gzip. 
See a comparison below.

[![GoDoc][1]][2] ![Build Status][3]

[1]: https://godoc.org/github.com/klauspost/pgzip?status.svg
[2]: https://godoc.org/github.com/klauspost/pgzip
[3]: https://github.com/klauspost/pgzip/actions/workflows/go.yml/badge.svg

Installation
====
```go get github.com/klauspost/pgzip/...```

You might need to get/update the dependencies:

```
go get -u github.com/klauspost/compress
```

Usage
====
[Godoc Doumentation](https://godoc.org/github.com/klauspost/pgzip)

To use as a replacement for gzip, exchange 

```import "compress/gzip"``` 
with 
```import gzip "github.com/klauspost/pgzip"```.

# Changes

* Oct 6, 2016: Fixed an issue if the destination writer returned an error.
* Oct 6, 2016: Better buffer reuse, should now generate less garbage.
* Oct 6, 2016: Output does not change based on write sizes.
* Dec 8, 2015: Decoder now supports the io.WriterTo interface, giving a speedup and less GC pressure.
* Oct 9, 2015: Reduced allocations by ~35 by using sync.Pool. ~15% overall speedup.

Changes in [github.com/klauspost/compress](https://github.com/klauspost/compress#changelog) are also carried over, so see that for more changes.

## Compression
The simplest way to use this is to simply do the same as you would when using [compress/gzip](http://golang.org/pkg/compress/gzip). 

To change the block size, use the added (*pgzip.Writer).SetConcurrency(blockSize, blocks int) function. With this you can control the approximate size of your blocks, as well as how many you want to be processing in parallel. Default values for this is SetConcurrency(1MB, runtime.GOMAXPROCS(0)), meaning blocks are split at 1 MB and up to the number of CPU threads blocks can be processing at once before the writer blocks.


Example:
```
var b bytes.Buffer
w := gzip.NewWriter(&b)
w.SetConcurrency(100000, 10)
w.Write([]byte("hello, world\n"))
w.Close()
```

To get any performance gains, you should at least be compressing more than 1 megabyte of data at the time.

You should at least have a block size of 100k and at least a number of blocks that match the number of cores your would like to utilize, but about twice the number of blocks would be the best.

Another side effect of this is, that it is likely to speed up your other code, since writes to the compressor only blocks if the compressor is already compressing the number of blocks you have specified. This also means you don't have worry about buffering input to the compressor.

## Decompression

Decompression works similar to compression. That means that you simply call pgzip the same way as you would call [compress/gzip](http://golang.org/pkg/compress/gzip). 

The only difference is that if you want to specify your own readahead, you have to use `pgzip.NewReaderN(r io.Reader, blockSize, blocks int)` to get a reader with your custom blocksizes. The `blockSize` is the size of each block decoded, and `blocks` is the maximum number of blocks that is decoded ahead.

See [Example on playground](http://play.golang.org/p/uHv1B5NbDh)

Performance
====
## Compression

See my blog post in [Benchmarks of Golang Gzip](https://blog.klauspost.com/go-gzipdeflate-benchmarks/).

Compression cost is usually about 0.2% with default settings with a block size of 250k.

Example with GOMAXPROC set to 32 (16 core CPU)

Content is [Matt Mahoneys 10GB corpus](http://mattmahoney.net/dc/10gb.html). Compression level 6.

Compressor  | MB/sec   | speedup | size | size overhead (lower=better)
------------|----------|---------|------|---------
[gzip](http://golang.org/pkg/compress/gzip) (golang) | 16.91MB/s (1 thread) | 1.0x | 4781329307 | 0%
[gzip](http://github.com/klauspost/compress/gzip) (klauspost) | 127.10MB/s (1 thread) | 7.52x | 4885366806 | +2.17%
[pgzip](https://github.com/klauspost/pgzip) (klauspost) | 2085.35MB/s|  123.34x | 4886132566 | +2.19%
[pargzip](https://godoc.org/github.com/golang/build/pargzip) (builder) | 334.04MB/s | 19.76x | 4786890417 | +0.12%

pgzip also contains a [huffman only compression](https://github.com/klauspost/compress#linear-time-compression-huffman-only) mode, that will allow compression at ~450MB per core per second, largely independent of the content.

See the [complete sheet](https://docs.google.com/spreadsheets/d/1nuNE2nPfuINCZJRMt6wFWhKpToF95I47XjSsc-1rbPQ/edit?usp=sharing) for different content types and compression settings.

## Decompression

The decompression speedup is there because it allows you to do other work while the decompression is taking place.

In the example above, the numbers are as follows on a 4 CPU machine:

Decompressor | Time | Speedup
-------------|------|--------
[gzip](http://golang.org/pkg/compress/gzip) (golang) | 1m28.85s | 0%
[pgzip](https://github.com/klauspost/pgzip) (klauspost) | 43.48s | 104%

But wait, since gzip decompression is inherently singlethreaded (aside from CRC calculation) how can it be more than 100% faster?  Because pgzip due to its design also acts as a buffer. When using unbuffered gzip, you are also waiting for io when you are decompressing. If the gzip decoder can keep up, it will always have data ready for your reader, and you will not be waiting for input to the gzip decompressor to complete.

This is pretty much an optimal situation for pgzip, but it reflects most common usecases for CPU intensive gzip usage.

I haven't included [bgzf](https://godoc.org/github.com/biogo/hts/bgzf) in this comparison, since it only can decompress files created by a compatible encoder, and therefore cannot be considered a generic gzip decompressor. But if you are able to compress your files with a bgzf compatible program, you can expect it to scale beyond 100%.

# License
This contains large portions of code from the go repository - see GO_LICENSE for more information. The changes are released under MIT License. See LICENSE for more information.

---

### Overview (`vendor/github.com/mattn/go-runewidth/README.md`)

go-runewidth
============

[](https://github.com/mattn/go-runewidth/actions?query=workflow%3Atest)
[](https://codecov.io/gh/mattn/go-runewidth)
[](http://godoc.org/github.com/mattn/go-runewidth)
[](https://goreportcard.com/report/github.com/mattn/go-runewidth)

Provides functions to get fixed width of the character or string.

Usage
-----

```go
runewidth.StringWidth("つのだ☆HIRO") == 12
```

NOTE: Latin letters that Unicode gives ambiguous East Asian width, such as
`ü`, `é` and `ß`, are measured as one cell even when `EastAsianWidth` is
set, as terminals draw them in CJK locales too. Other ambiguous characters
such as `±`, `×` and `○` still take two cells there.


Author
------

Yasuhiro Matsumoto

License
-------

under the MIT License: http://mattn.mit-license.org/2013

---

### Overview (`vendor/github.com/mattn/go-sqlite3/README.md`)

go-sqlite3
==========

[](https://pkg.go.dev/github.com/mattn/go-sqlite3)
[](https://github.com/mattn/go-sqlite3/actions?query=workflow%3AGo)
[](https://opencollective.com/mattn-go-sqlite3) 
[](https://codecov.io/gh/mattn/go-sqlite3)
[](https://goreportcard.com/report/github.com/mattn/go-sqlite3)

## Sponsors

This project is proudly sponsored by:

<a href="https://coderabbit.link/mattn">
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="https://victorious-bubble-f69a016683.media.strapiapp.com/White_Typemark_79b9189d19.svg">
    <img src="https://victorious-bubble-f69a016683.media.strapiapp.com/Orange_Typemark_43bf516c9d.svg" alt="CodeRabbit" width="320">
  </picture>
</a>

Latest stable version is v1.14 or later, not v2.

# Description

A sqlite3 driver that conforms to the built-in database/sql interface.

Supported Golang version: See [.github/workflows/go.yaml](./.github/workflows/go.yaml).

This package follows the official [Golang Release Policy](https://golang.org/doc/devel/release.html#policy).

### Overview

- [go-sqlite3](#go-sqlite3)
- [Description](#description)
    - [Overview](#overview)
- [Installation](#installation)
- [API Reference](#api-reference)
- [Connection String](#connection-string)
  - [DSN Examples](#dsn-examples)
- [Features](#features)
    - [Usage](#usage)
    - [Feature / Extension List](#feature--extension-list)
- [Compilation](#compilation)
  - [Android](#android)
- [ARM](#arm)
- [Cross Compile](#cross-compile)
- [Compiling](#compiling)
  - [Linux](#linux)
    - [Alpine](#alpine)
    - [Fedora](#fedora)
    - [Ubuntu](#ubuntu)
  - [macOS](#mac-osx)
  - [Windows](#windows)
  - [Errors](#errors)
- [User Authentication](#user-authentication)
  - [Compile](#compile)
  - [Usage](#usage-1)
    - [Create protected database](#create-protected-database)
    - [Password Encoding](#password-encoding)
      - [Available Encoders](#available-encoders)
    - [Restrictions](#restrictions)
    - [Support](#support)
    - [User Management](#user-management)
      - [SQL](#sql)
        - [Examples](#examples)
      - [*SQLiteConn](#sqliteconn)
    - [Attached database](#attached-database)
- [Extensions](#extensions)
  - [Spatialite](#spatialite)
- [FAQ](#faq)
- [License](#license)
- [Author](#author)

# Installation

This package can be installed with the `go get` command:

    go get github.com/mattn/go-sqlite3

_go-sqlite3_ is *cgo* package.
If you want to build your app using go-sqlite3, you need gcc.

***Important: because this is a `CGO` enabled package, you are required to set the environment variable `CGO_ENABLED=1` and have a `gcc` compiler present within your path.***

# API Reference

API documentation can be found [here](http://godoc.org/github.com/mattn/go-sqlite3).

Examples can be found under the [examples](./_example) directory.

# Connection String

When creating a new SQLite database or connection to an existing one, with the file name additional options can be given.
This is also known as a DSN (Data Source Name) string.

Options are append after the filename of the SQLite database.
The database filename and options are separated by an `?` (Question Mark).
Options should be URL-encoded (see [url.QueryEscape](https://golang.org/pkg/net/url/#QueryEscape)).

This also applies when using an in-memory database instead of a file.

Options can be given using the following format: `KEYWORD=VALUE` and multiple options can be combined with the `&` ampersand.

This library supports DSN options of SQLite itself and provides additional options.

Boolean values can be one of:
* `0` `no` `false` `off`
* `1` `yes` `true` `on`

| Name | Key | Value(s) | Description |
|------|-----|----------|-------------|
| UA - Create | `_auth` | - | Create User Authentication, for more information see [User Authentication](#user-authentication) |
| UA - Username | `_auth_user` | `string` | Username for User Authentication, for more information see [User Authentication](#user-authentication) |
| UA - Password | `_auth_pass` | `string` | Password for User Authentication, for more information see [User Authentication](#user-authentication) |
| UA - Crypt | `_auth_crypt` | <ul><li>SHA1</li><li>SSHA1</li><li>SHA256</li><li>SSHA256</li><li>SHA384</li><li>SSHA384</li><li>SHA512</li><li>SSHA512</li></ul> | Password encoder to use for User Authentication, for more information see [User Authentication](#user-authentication) |
| UA - Salt | `_auth_salt` | `string` | Salt to use if the configure password encoder requires a salt, for User Authentication, for more information see [User Authentication](#user-authentication) |
| Auto Vacuum | `_auto_vacuum` \| `_vacuum` | <ul><li>`0` \| `none`</li><li>`1` \| `full`</li><li>`2` \| `incremental`</li></ul> | For more information see [PRAGMA auto_vacuum](https://www.sqlite.org/pragma.html#pragma_auto_vacuum) |
| Busy Timeout | `_busy_timeout` \| `_timeout` | `int` | Specify value for sqlite3_busy_timeout. For more information see [PRAGMA busy_timeout](https://www.sqlite.org/pragma.html#pragma_busy_timeout) |
| Case Sensitive LIKE | `_case_sensitive_like` \| `_cslike` | `boolean` | For more information see [PRAGMA case_sensitive_like](https://www.sqlite.org/pragma.html#pragma_case_sensitive_like) |
| Defer Foreign Keys | `_defer_foreign_keys` \| `_defer_fk` | `boolean` | For more information see [PRAGMA defer_foreign_keys](https://www.sqlite.org/pragma.html#pragma_defer_foreign_keys) |
| Foreign Keys | `_foreign_keys` \| `_fk` | `boolean` | For more information see [PRAGMA foreign_keys](https://www.sqlite.org/pragma.html#pragma_foreign_keys) |
| Ignore CHECK Constraints | `_ignore_check_constraints` | `boolean` | For more information see [PRAGMA ignore_check_constraints](https://www.sqlite.org/pragma.html#pragma_ignore_check_constraints) |
| Immutable | `immutable` | `boolean` | For more information see [Immutable](https://www.sqlite.org/c3ref/open.html) |
| Journal Mode | `_journal_mode` \| `_journal` | <ul><li>DELETE</li><li>TRUNCATE</li><li>PERSIST</li><li>MEMORY</li><li>WAL</li><li>OFF</li></ul> | For more information see [PRAGMA journal_mode](https://www.sqlite.org/pragma.html#pragma_journal_mode) |
| Locking Mode | `_locking_mode` \| `_locking` | <ul><li>NORMAL</li><li>EXCLUSIVE</li></ul> | For more information see [PRAGMA locking_mode](https://www.sqlite.org/pragma.html#pragma_locking_mode) |
| Mode | `mode` | <ul><li>ro</li><li>rw</li><li>rwc</li><li>memory</li></ul> | Access Mode of the database. For more information see [SQLite Open](https://www.sqlite.org/c3ref/open.html) |
| Mutex Locking | `_mutex` | <ul><li>no</li><li>full</li></ul> | Specify mutex mode. |
| Query Only | `_query_only` | `boolean` | For more information see [PRAGMA query_only](https://www.sqlite.org/pragma.html#pragma_query_only) |
| Recursive Triggers | `_recursive_triggers` \| `_rt` | `boolean` | For more information see [PRAGMA recursive_triggers](https://www.sqlite.org/pragma.html#pragma_recursive_triggers) |
| Secure Delete | `_secure_delete` | `boolean` \| `FAST` | For more information see [PRAGMA secure_delete](https://www.sqlite.org/pragma.html#pragma_secure_delete) |
| Shared-Cache Mode | `cache` | <ul><li>shared</li><li>private</li></ul> | Set cache mode for more information see [sqlite.org](https://www.sqlite.org/sharedcache.html) |
| Synchronous | `_synchronous` \| `_sync` | <ul><li>0 \| OFF</li><li>1 \| NORMAL</li><li>2 \| FULL</li><li>3 \| EXTRA</li></ul> | For more information see [PRAGMA synchronous](https://www.sqlite.org/pragma.html#pragma_synchronous) |
| Time Zone Location | `_loc` | auto | Specify location of time format. |
| Transaction Lock | `_txlock` | <ul><li>immediate</li><li>deferred</li><li>exclusive</li></ul> | Specify locking behavior for transactions. |
| Writable Schema | `_writable_schema` | `Boolean` | When this pragma is on, the SQLITE_MASTER tables in which database can be changed using ordinary UPDATE, INSERT, and DELETE statements. Warning: misuse of this pragma can easily result in a corrupt database file. |
| Cache Size | `_cache_size` | `int` | Maximum cache size; default is 2000K (2M). See [PRAGMA cache_size](https://sqlite.org/pragma.html#pragma_cache_size) |
| Statement Cache Size | `_stmt_cache_size` | `int` | Maximum number of prepared statements cached per connection; default is 0 (disabled). Note that `sql.DB` is a connection pool, so each connection maintains its own independent cache. |


## DSN Examples

```
file:test.db?cache=shared&mode=memory
```

# Features

This package allows additional configuration of features available within SQLite3 to be enabled or disabled by golang build constraints also known as build `tags`.

Click [here](https://golang.org/pkg/go/build/#hdr-Build_Constraints) for more information about build tags / constraints.

### Usage

If you wish to build this library with additional extensions / features, use the following command:

```bash
go build -tags "<FEATURE>"
```

For available features, see the extension list.
When using multiple build tags, all the different tags should be space delimited.

Example:

```bash
go build -tags "icu json1 fts5 secure_delete"
```

### Feature / Extension List

| Extension | Build Tag | Description |
|-----------|-----------|-------------|
| Additional Statistics | sqlite_stat4 | This option adds additional logic to the ANALYZE command and to the query planner that can help SQLite to chose a better query plan under certain situations. The ANALYZE command is enhanced to collect histogram data from all columns of every index and store that data in the sqlite_stat4 table.<br><br>The query planner will then use the histogram data to help it make better index choices. The downside of this compile-time option is that it violates the query planner stability guarantee making it more difficult to ensure consistent performance in mass-produced applications.<br><br>SQLITE_ENABLE_STAT4 is an enhancement of SQLITE_ENABLE_STAT3. STAT3 only recorded histogram data for the left-most column of each index whereas the STAT4 enhancement records histogram data from all columns of each index.<br><br>The SQLITE_ENABLE_STAT3 compile-time option is a no-op and is ignored if the SQLITE_ENABLE_STAT4 compile-time option is used |
| Allow URI Authority | sqlite_allow_uri_authority | URI filenames normally throws an error if the authority section is not either empty or "localhost".<br><br>However, if SQLite is compiled with the SQLITE_ALLOW_URI_AUTHORITY compile-time option, then the URI is converted into a Uniform Naming Convention (UNC) filename and passed down to the underlying operating system that way |
| App Armor | sqlite_app_armor | When defined, this C-preprocessor macro activates extra code that attempts to detect misuse of the SQLite API, such as passing in NULL pointers to required parameters or using objects after they have been destroyed. <br><br>App Armor is not available under `Windows`. |
| Disable Load Extensions | sqlite_omit_load_extension | Loading of external extensions is enabled by default.<br><br>To disable extension loading add the build tag `sqlite_omit_load_extension`. |
| Enable Serialization with `libsqlite3` | sqlite_serialize | Serialization and deserialization of a SQLite database is available by default, unless the build tag `libsqlite3` is set.<br><br>To enable this functionality even if `libsqlite3` is set, add the build tag `sqlite_serialize`. |
| Foreign Keys | sqlite_foreign_keys | This macro determines whether enforcement of foreign key constraints is enabled or disabled by default for new database connections.<br><br>Each database connection can always turn enforcement of foreign key constraints on and off and run-time using the foreign_keys pragma.<br><br>Enforcement of foreign key constraints is normally off by default, but if this compile-time parameter is set to 1, enforcement of foreign key constraints will be on by default | 
| Full Auto Vacuum | sqlite_vacuum_full | Set the default auto vacuum to full |
| Incremental Auto Vacuum | sqlite_vacuum_incr | Set the default auto vacuum to incremental |
| Full Text Search Engine | sqlite_fts5 | When this option is defined in the amalgamation, versions 5 of the full-text search engine (fts5) is added to the build automatically |
|  International Components for Unicode | sqlite_icu | This option causes the International Components for Unicode or "ICU" extension to SQLite to be added to the build |
| Introspect PRAGMAS | sqlite_introspect | This option adds some extra PRAGMA statements. <ul><li>PRAGMA function_list</li><li>PRAGMA module_list</li><li>PRAGMA pragma_list</li></ul> |
| JSON SQL Functions | sqlite_json | When this option is defined in the amalgamation, the JSON SQL functions are added to the build automatically |
| Math Functions | sqlite_math_functions | This compile-time option enables built-in scalar math functions. For more information see [Built-In Mathematical SQL Functions](https://www.sqlite.org/lang_mathfunc.html) |
| OS Trace | sqlite_os_trace | This option enables OSTRACE() debug logging. This can be verbose and should not be used in production. |
| Percentile | sqlite_percentile | This option enables [The Percentile Extension](sqlite.org/percentile.html). |
| Pre Update Hook | sqlite_preupdate_hook | Registers a callback function that is invoked prior to each INSERT, UPDATE, and DELETE operation on a database table. |
| Secure Delete | sqlite_secure_delete | This compile-time option changes the default setting of the secure_delete pragma.<br><br>When this option is not used, secure_delete defaults to off. When this option is present, secure_delete defaults to on.<br><br>The secure_delete setting causes deleted content to be overwritten with zeros. There is a small performance penalty since additional I/O must occur.<br><br>On the other hand, secure_delete can prevent fragments of sensitive information from lingering in unused parts of the database file after it has been deleted. See the documentation on the secure_delete pragma for additional information |
| Secure Delete (FAST) | sqlite_secure_delete_fast | For more information see [PRAGMA secure_delete](https://www.sqlite.org/pragma.html#pragma_secure_delete) |
| Tracing / Debug | sqlite_trace | Activate trace functions |
| User Authentication | sqlite_userauth | SQLite User Authentication see [User Authentication](#user-authentication) for more information. |
| Virtual Tables | sqlite_vtable | SQLite Virtual Tables see [SQLite Official VTABLE Documentation](https://www.sqlite.org/vtab.html) for more information, and a [full example here](https://github.com/mattn/go-sqlite3/tree/master/_example/vtable) |
| The DBSTAT Virtual Table | sqlite_dbstat | The DBSTAT virtual table is a read-only virtual table that returns information about the amount of disk space used to store the content of an SQLite database. See [SQLite Official Documentation](https://www.sqlite.org/dbstat.html) for more information. |

# Compilation

This package requires the `CGO_ENABLED=1` environment variable if not set by default, and the presence of the `gcc` compiler.

If you need to add additional CFLAGS or LDFLAGS to the build command, and do not want to modify this package, then this can be achieved by using the `CGO_CFLAGS` and `CGO_LDFLAGS` environment variables.

## Android

This package can be compiled for android.
Compile with:

```bash
go build -tags "android"
```

For more information see [#201](https://github.com/mattn/go-sqlite3/issues/201)

# ARM

To compile for `ARM` use the following environment:

```bash
env CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ \
    CGO_ENABLED=1 GOOS=linux GOARCH=arm GOARM=7 \
    go build -v 
```

Additional information:
- [#242](https://github.com/mattn/go-sqlite3/issues/242)
- [#504](https://github.com/mattn/go-sqlite3/issues/504)

# Cross Compile

This library can be cross-compiled.

In some cases you are required to the `CC` environment variable with the cross compiler.

## Cross Compiling from macOS
The simplest way to cross compile from macOS is to use [xgo](https://github.com/karalabe/xgo).

Steps:
- Install [musl-cross](https://github.com/FiloSottile/homebrew-musl-cross) (`brew install FiloSottile/musl-cross/musl-cross`).
- Run `CC=x86_64-linux-musl-gcc CXX=x86_64-linux-musl-g++ GOARCH=amd64 GOOS=linux CGO_ENABLED=1 go build -ldflags "-linkmode external -extldflags -static"`.

Please refer to the project's [README](https://github.com/FiloSottile/homebrew-musl-cross#readme) for further information.

# Compiling

## Linux

To compile this package on Linux, you must install the development tools for your linux distribution.

To compile under linux use the build tag `linux`.

```bash
go build -tags "linux"
```

If you wish to link directly to libsqlite3 then you can use the `libsqlite3` build tag.

```
go build -tags "libsqlite3 linux"
```

### Alpine

When building in an `alpine` container  run the following command before building:

```
apk add --update gcc musl-dev
```

### Fedora

```bash
sudo yum groupinstall "Development Tools" "Development Libraries"
```

### Ubuntu

```bash
sudo apt-get install build-essential
```

## macOS

macOS should have all the tools present to compile this package. If not, install XCode to add all the developers tools.

Required dependency:

```bash
brew install sqlite3
```

For macOS, there is an additional package to install which is required if you wish to build the `icu` extension.

This additional package can be installed with `homebrew`:

```bash
brew upgrade icu4c
```

To compile for macOS on x86:

```bash
go build -tags "darwin amd64"
```

To compile for macOS on ARM chips:

```bash
go build -tags "darwin arm64"
```

If you wish to link directly to libsqlite3, use the `libsqlite3` build tag:

```
# x86 
go build -tags "libsqlite3 darwin amd64"
# ARM
go build -tags "libsqlite3 darwin arm64"
```

Additional information:
- [#206](https://github.com/mattn/go-sqlite3/issues/206)
- [#404](https://github.com/mattn/go-sqlite3/issues/404)

## Windows

To compile this package on Windows, you must have the `gcc` compiler installed.

1) Install a Windows `gcc` toolchain.
2) Add the `bin` folder to the Windows path, if the installer did not do this by default.
3) Open a terminal for the TDM-GCC toolchain, which can be found in the Windows Start menu.
4) Navigate to your project folder and run the `go build ...` command for this package.

For example the TDM-GCC Toolchain can be found [here](https://jmeubank.github.io/tdm-gcc/).

## Errors

- Compile error: `can not be used when making a shared object; recompile with -fPIC`

    When receiving a compile time error referencing recompile with `-FPIC` then you
    are probably using a hardend system.

    You can compile the library on a hardend system with the following command.

    ```bash
    go build -ldflags '-extldflags=-fno-PIC'
    ```

    More details see [#120](https://github.com/mattn/go-sqlite3/issues/120)

- Can't build go-sqlite3 on windows 64bit.

    > Probably, you are using go 1.0, go1.0 has a problem when it comes to compiling/linking on windows 64bit.
    > See: [#27](https://github.com/mattn/go-sqlite3/issues/27)

- `go get github.com/mattn/go-sqlite3` throws compilation error.

    `gcc` throws: `internal compiler error`

    Remove the download repository from your disk and try re-install with:

    ```bash
    go install github.com/mattn/go-sqlite3
    ```

# User Authentication

***This is deprecated***

This package supports the SQLite User Authentication module.

## Compile

To use the User authentication module, the package has to be compiled with the tag `sqlite_userauth`. See [Features](#features).

## Usage

### Create protected database

To create a database protected by user authentication, provide the following argument to the connection string `_auth`.
This will enable user authentication within the database. This option however requires two additional arguments:

- `_auth_user`
- `_auth_pass`

When `_auth` is present in the connection string user authentication will be enabled and the provided user will be created
as an `admin` user. After initial creation, the parameter `_auth` has no effect anymore and can be omitted from the connection string.

Example connection strings:

Create an user authentication database with user `admin` and password `admin`:

`file:test.s3db?_auth&_auth_user=admin&_auth_pass=admin`

Create an user authentication database with user `admin` and password `admin` and use `SHA1` for the password encoding:

`file:test.s3db?_auth&_auth_user=admin&_auth_pass=admin&_auth_crypt=sha1`

### Password Encoding

The passwords within the user authentication module of SQLite are encoded with the SQLite function `sqlite_cryp`.
This function uses a ceasar-cypher which is quite insecure.
This library provides several additional password encoders which can be configured through the connection string.

The password cypher can be configured with the key `_auth_crypt`. And if the configured password encoder also requires an
salt this can be configured with `_auth_salt`.

#### Available Encoders

- SHA1
- SSHA1 (Salted SHA1)
- SHA256
- SSHA256 (salted SHA256)
- SHA384
- SSHA384 (salted SHA384)
- SHA512
- SSHA512 (salted SHA512)

### Restrictions

Operations on the database regarding user management can only be preformed by an administrator user.

### Support

The user authentication supports two kinds of users:

- administrators
- regular users

### User Management

User management can be done by directly using the `*SQLiteConn` or by SQL.

#### SQL

The following sql functions are available for user management:

| Function | Arguments | Description |
|----------|-----------|-------------|
| `authenticate` | username `string`, password `string` | Will authenticate an user, this is done by the connection; and should not be used manually. |
| `auth_user_add` | username `string`, password `string`, admin `int` | This function will add an user to the database.<br>if the database is not protected by user authentication it will enable it. Argument `admin` is an integer identifying if the added user should be an administrator. Only Administrators can add administrators. |
| `auth_user_change` | username `string`, password `string`, admin `int` | Function to modify an user. Users can change their own password, but only an administrator can change the administrator flag. |
| `authUserDelete` | username `string` | Delete an user from the database. Can only be used by an administrator. The current logged in administrator cannot be deleted. This is to make sure their is always an administrator remaining. |

These functions will return an integer:

- 0 (SQLITE_OK)
- 23 (SQLITE_AUTH) Failed to perform due to authentication or insufficient privileges

##### Examples

```sql
// Autheticate user
// Create Admin User
SELECT auth_user_add('admin2', 'admin2', 1);

// Change password for user
SELECT auth_user_change('user', 'userpassword', 0);

// Delete user
SELECT user_delete('user');
```

#### *SQLiteConn

The following functions are available for User authentication from the `*SQLiteConn`:

| Function | Description |
|----------|-------------|
| `Authenticate(username, password string) error` | Authenticate user |
| `AuthUserAdd(username, password string, admin bool) error` | Add user |
| `AuthUserChange(username, password string, admin bool) error` | Modify user |
| `AuthUserDelete(username string) error` | Delete user |

### Attached database

When using attached databases, SQLite will use the authentication from the `main` database for the attached database(s).

# Extensions

If you want your own extension to be listed here, or you want to add a reference to an extension; please submit an Issue for this.

## Spatialite

Spatialite is available as an extension to SQLite, and can be used in combination with this repository.
For an example, see [shaxbee/go-spatialite](https://github.com/shaxbee/go-spatialite).

## extension-functions.c from SQLite3 Contrib

extension-functions.c is available as an extension to SQLite, and provides the following functions:

- Math: acos, asin, atan, atn2, atan2, acosh, asinh, atanh, difference, degrees, radians, cos, sin, tan, cot, cosh, sinh, tanh, coth, exp, log, log10, power, sign, sqrt, square, ceil, floor, pi.
- String: replicate, charindex, leftstr, rightstr, ltrim, rtrim, trim, replace, reverse, proper, padl, padr, padc, strfilter.
- Aggregate: stdev, variance, mode, median, lower_quartile, upper_quartile

For an example, see [dinedal/go-sqlite3-extension-functions](https://github.com/dinedal/go-sqlite3-extension-functions).

# FAQ

- Getting insert error while query is opened.

    > You can pass some arguments into the connection string, for example, a URI.
    > See: [#39](https://github.com/mattn/go-sqlite3/issues/39)

- Do you want to cross compile? mingw on Linux or Mac?

    > See: [#106](https://github.com/mattn/go-sqlite3/issues/106)
    > See also: http://www.limitlessfx.com/cross-compile-golang-app-for-windows-from-linux.html

- Want to get time.Time with current locale

    Use `_loc=auto` in SQLite3 filename schema like `file:foo.db?_loc=auto`.

- Can I use this in multiple routines concurrently?

    Yes for readonly. But not for writable. See [#50](https://github.com/mattn/go-sqlite3/issues/50), [#51](https://github.com/mattn/go-sqlite3/issues/51), [#209](https://github.com/mattn/go-sqlite3/issues/209), [#274](https://github.com/mattn/go-sqlite3/issues/274).

- Why I'm getting `no such table` error?

    Why is it racy if I use a `sql.Open("sqlite3", ":memory:")` database?

    Each connection to `":memory:"` opens a brand new in-memory sql database, so if
    the stdlib's sql engine happens to open another connection and you've only
    specified `":memory:"`, that connection will see a brand new database. A
    workaround is to use `"file::memory:?cache=shared"` (or `"file:foobar?mode=memory&cache=shared"`). Every
    connection to this string will point to the same in-memory database.
    
    Note that if the last database connection in the pool closes, the in-memory database is deleted. Make sure the [max idle connection limit](https://golang.org/pkg/database/sql/#DB.SetMaxIdleConns) is > 0, and the [connection lifetime](https://golang.org/pkg/database/sql/#DB.SetConnMaxLifetime) is infinite.
    
    For more information see:
    * [#204](https://github.com/mattn/go-sqlite3/issues/204)
    * [#511](https://github.com/mattn/go-sqlite3/issues/511)
    * https://www.sqlite.org/sharedcache.html#shared_cache_and_in_memory_databases
    * https://www.sqlite.org/inmemorydb.html#sharedmemdb

- Reading from database with large amount of goroutines fails on OSX.

    OS X limits OS-wide to not have more than 1000 files open simultaneously by default.

    For more information, see [#289](https://github.com/mattn/go-sqlite3/issues/289)

- Trying to execute a `.` (dot) command throws an error.

    Error: `Error: near ".": syntax error`
    Dot command are part of SQLite3 CLI, not of this library.

    You need to implement the feature or call the sqlite3 cli.

    More information see [#305](https://github.com/mattn/go-sqlite3/issues/305).

- Error: `database is locked`

    When you get a database is locked, please use the following options.

    Add to DSN: `cache=shared`

    Example:
    ```go
    db, err := sql.Open("sqlite3", "file:locked.sqlite?cache=shared")
    ```

    Next, please set the database connections of the SQL package to 1:
    
    ```go
    db.SetMaxOpenConns(1)
    ```

    For more information, see [#209](https://github.com/mattn/go-sqlite3/issues/209).

## Contributors

### Code Contributors

This project exists thanks to all the people who [[contribute](CONTRIBUTING.md)].
<a href="https://github.com/mattn/go-sqlite3/graphs/contributors"><img src="https://opencollective.com/mattn-go-sqlite3/contributors.svg?width=890&button=false" /></a>

### Financial Contributors

Become a financial contributor and help us sustain our community. [[Contribute here](https://opencollective.com/mattn-go-sqlite3/contribute)].

#### Individuals

<a href="https://opencollective.com/mattn-go-sqlite3"><img src="https://opencollective.com/mattn-go-sqlite3/individuals.svg?width=890"></a>

#### Organizations

Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/mattn-go-sqlite3/contribute)]

<a href="https://opencollective.com/mattn-go-sqlite3/organization/0/website"><img src="https://opencollective.com/mattn-go-sqlite3/organization/0/avatar.svg"></a>
<a href="https://opencollective.com/mattn-go-sqlite3/organization/1/website"><img src="https://opencollective.com/mattn-go-sqlite3/organization/1/avatar.svg"></a>
<a href="https://opencollective.com/mattn-go-sqlite3/organization/2/website"><img src="https://opencollective.com/mattn-go-sqlite3/organization/2/avatar.svg"></a>
<a href="https://opencollective.com/mattn-go-sqlite3/organization/3/website"><img src="https://opencollective.com/mattn-go-sqlite3/organization/3/avatar.svg"></a>
<a href="https://opencollective.com/mattn-go-sqlite3/organization/4/website"><img src="https://opencollective.com/mattn-go-sqlite3/organization/4/avatar.svg"></a>
<a href="https://opencollective.com/mattn-go-sqlite3/organization/5/website"><img src="https://opencollective.com/mattn-go-sqlite3/organization/5/avatar.svg"></a>
<a href="https://opencollective.com/mattn-go-sqlite3/organization/6/website"><img src="https://opencollective.com/mattn-go-sqlite3/organization/6/avatar.svg"></a>
<a href="https://opencollective.com/mattn-go-sqlite3/organization/7/website"><img src="https://opencollective.com/mattn-go-sqlite3/organization/7/avatar.svg"></a>
<a href="https://opencollective.com/mattn-go-sqlite3/organization/8/website"><img src="https://opencollective.com/mattn-go-sqlite3/organization/8/avatar.svg"></a>
<a href="https://opencollective.com/mattn-go-sqlite3/organization/9/website"><img src="https://opencollective.com/mattn-go-sqlite3/organization/9/avatar.svg"></a>

# License

MIT: http://mattn.mit-license.org/2018

sqlite3-binding.c, sqlite3-binding.h, sqlite3ext.h

The -binding suffix was added to avoid build failures under gccgo.

In this repository, those files are an amalgamation of code that was copied from SQLite3. The license of that code is the same as the license of SQLite3.

# Author

Yasuhiro Matsumoto (a.k.a mattn)

G.J.R. Timmer

---

### Overview (`vendor/github.com/miekg/pkcs11/README.md`)

# PKCS#11

This is a Go implementation of the PKCS#11 API. It wraps the library closely, but uses Go idiom where
it makes sense. It has been tested with SoftHSM.

## SoftHSM

 *  Make it use a custom configuration file `export SOFTHSM_CONF=$PWD/softhsm.conf`

 *  Then use `softhsm` to init it

    ~~~
    softhsm --init-token --slot 0 --label test --pin 1234
    ~~~

 *  Then use `libsofthsm2.so` as the pkcs11 module:

    ~~~ go
    p := pkcs11.New("/usr/lib/softhsm/libsofthsm2.so")
    ~~~

## Examples

A skeleton program would look somewhat like this (yes, pkcs#11 is verbose):

~~~ go
p := pkcs11.New("/usr/lib/softhsm/libsofthsm2.so")
err := p.Initialize()
if err != nil {
    panic(err)
}

defer p.Destroy()
defer p.Finalize()

slots, err := p.GetSlotList(true)
if err != nil {
    panic(err)
}

session, err := p.OpenSession(slots[0], pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION)
if err != nil {
    panic(err)
}
defer p.CloseSession(session)

err = p.Login(session, pkcs11.CKU_USER, "1234")
if err != nil {
    panic(err)
}
defer p.Logout(session)

p.DigestInit(session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_SHA_1, nil)})
hash, err := p.Digest(session, []byte("this is a string"))
if err != nil {
    panic(err)
}

for _, d := range hash {
        fmt.Printf("%x", d)
}
fmt.Println()
~~~

Further examples are included in the tests.

To expose PKCS#11 keys using the [crypto.Signer interface](https://golang.org/pkg/crypto/#Signer),
please see [github.com/thalesignite/crypto11](https://github.com/thalesignite/crypto11).

---

### Overview (`vendor/github.com/modern-go/concurrent/README.md`)

# concurrent

[](https://sourcegraph.com/github.com/modern-go/concurrent?badge)
[](http://godoc.org/github.com/modern-go/concurrent)
[](https://travis-ci.org/modern-go/concurrent)
[](https://codecov.io/gh/modern-go/concurrent)
[](https://goreportcard.com/report/github.com/modern-go/concurrent)
[](https://raw.githubusercontent.com/modern-go/concurrent/master/LICENSE)

* concurrent.Map: backport sync.Map for go below 1.9
* concurrent.Executor: goroutine with explicit ownership and cancellable

# concurrent.Map

because sync.Map is only available in go 1.9, we can use concurrent.Map to make code portable

```go
m := concurrent.NewMap()
m.Store("hello", "world")
elem, found := m.Load("hello")
// elem will be "world"
// found will be true
```

# concurrent.Executor

```go
executor := concurrent.NewUnboundedExecutor()
executor.Go(func(ctx context.Context) {
    everyMillisecond := time.NewTicker(time.Millisecond)
    for {
        select {
        case <-ctx.Done():
            fmt.Println("goroutine exited")
            return
        case <-everyMillisecond.C:
            // do something
        }
    }
})
time.Sleep(time.Second)
executor.StopAndWaitForever()
fmt.Println("executor stopped")
```

attach goroutine to executor instance, so that we can

* cancel it by stop the executor with Stop/StopAndWait/StopAndWaitForever
* handle panic by callback: the default behavior will no longer crash your application

---

### Overview (`vendor/github.com/modern-go/reflect2/README.md`)

# reflect2

[](https://sourcegraph.com/github.com/modern-go/reflect2?badge)
[](http://godoc.org/github.com/modern-go/reflect2)
[](https://travis-ci.org/modern-go/reflect2)
[](https://codecov.io/gh/modern-go/reflect2)
[](https://goreportcard.com/report/github.com/modern-go/reflect2)
[](https://raw.githubusercontent.com/modern-go/reflect2/master/LICENSE)

reflect api that avoids runtime reflect.Value cost

* reflect get/set interface{}, with type checking
* reflect get/set unsafe.Pointer, without type checking
* `reflect2.TypeByName` works like `Class.forName` found in java

[json-iterator](https://github.com/json-iterator/go) use this package to save runtime dispatching cost.
This package is designed for low level libraries to optimize reflection performance.
General application should still use reflect standard library.

# reflect2.TypeByName

```go
// given package is github.com/your/awesome-package
type MyStruct struct {
	// ...
}

// will return the type
reflect2.TypeByName("awesome-package.MyStruct")
// however, if the type has not been used
// it will be eliminated by compiler, so we can not get it in runtime
```

# reflect2 get/set interface{}

```go
valType := reflect2.TypeOf(1)
i := 1
j := 10
valType.Set(&i, &j)
// i will be 10
```

to get set `type`, always use its pointer `*type`

# reflect2 get/set unsafe.Pointer

```go
valType := reflect2.TypeOf(1)
i := 1
j := 10
valType.UnsafeSet(unsafe.Pointer(&i), unsafe.Pointer(&j))
// i will be 10
```

to get set `type`, always use its pointer `*type`

# benchmark

Benchmark is not necessary for this package. It does nothing actually.
As it is just a thin wrapper to make go runtime public. 
Both `reflect2` and `reflect` call same function 
provided by `runtime` package exposed by go language.

# unsafe safety

Instead of casting `[]byte` to `sliceHeader` in your application using unsafe.
We can use reflect2 instead. This way, if `sliceHeader` changes in the future,
only reflect2 need to be upgraded.

reflect2 tries its best to keep the implementation same as reflect (by testing).

---

### Overview (`vendor/github.com/opencontainers/go-digest/README.md`)

# go-digest

[](https://godoc.org/github.com/opencontainers/go-digest) [](https://goreportcard.com/report/github.com/opencontainers/go-digest) [](https://travis-ci.org/opencontainers/go-digest)

Common digest package used across the container ecosystem.

Please see the [godoc](https://godoc.org/github.com/opencontainers/go-digest) for more information.

# What is a digest?

A digest is just a [hash](https://en.wikipedia.org/wiki/Hash_function).

The most common use case for a digest is to create a content identifier for use in [Content Addressable Storage](https://en.wikipedia.org/wiki/Content-addressable_storage) systems:

```go
id := digest.FromBytes([]byte("my content"))
```

In the example above, the id can be used to uniquely identify the byte slice "my content".
This allows two disparate applications to agree on a verifiable identifier without having to trust one another.

An identifying digest can be verified, as follows:

```go
if id != digest.FromBytes([]byte("my content")) {
  return errors.New("the content has changed!")
}
```

A `Verifier` type can be used to handle cases where an `io.Reader` makes more sense:

```go
rd := getContent()
verifier := id.Verifier()
io.Copy(verifier, rd)

if !verifier.Verified() {
  return errors.New("the content has changed!")
}
```

Using [Merkle DAGs](https://en.wikipedia.org/wiki/Merkle_tree), this can power a rich, safe, content distribution system.

# Usage

While the [godoc](https://godoc.org/github.com/opencontainers/go-digest) is considered the best resource, a few important items need to be called out when using this package.

1. Make sure to import the hash implementations into your application or the package will panic.
    You should have something like the following in the main (or other entrypoint) of your application:
   
    ```go
    import (
        _ "crypto/sha256"
        _ "crypto/sha512"
    )
    ```
    This may seem inconvenient but it allows you replace the hash 
    implementations with others, such as https://github.com/stevvooe/resumable.
 
2. Even though `digest.Digest` may be assemblable as a string, _always_ verify your input with `digest.Parse` or use `Digest.Validate` when accepting untrusted input.
    While there are measures to avoid common problems, this will ensure you have valid digests in the rest of your application.

3. While alternative encodings of hash values (digests) are possible (for example, base64), this package deals exclusively with hex-encoded digests.

# Stability

The Go API, at this stage, is considered stable, unless otherwise noted.

As always, before using a package export, read the [godoc](https://godoc.org/github.com/opencontainers/go-digest).

# Contributing

This package is considered fairly complete.
It has been in production in thousands (millions?) of deployments and is fairly battle-hardened.
New additions will be met with skepticism.
If you think there is a missing feature, please file a bug clearly describing the problem and the alternatives you tried before submitting a PR.

## Code of Conduct

Participation in the OpenContainers community is governed by [OpenContainer's Code of Conduct][code-of-conduct].

## Security

If you find an issue, please follow the [security][security] protocol to report it.

# Copyright and license

Copyright © 2019, 2020 OCI Contributors
Copyright © 2016 Docker, Inc.
All rights reserved, except as follows.
Code is released under the [Apache 2.0 license](LICENSE).
This `README.md` file and the [`CONTRIBUTING.md`](CONTRIBUTING.md) file are licensed under the Creative Commons Attribution 4.0 International License under the terms and conditions set forth in the file [`LICENSE.docs`](LICENSE.docs).
You may obtain a duplicate copy of the same license, titled CC BY-SA 4.0, at http://creativecommons.org/licenses/by-sa/4.0/.

[security]: https://github.com/opencontainers/org/blob/master/security
[code-of-conduct]: https://github.com/opencontainers/org/blob/master/CODE_OF_CONDUCT.md

---

### Overview (`vendor/github.com/pkg/browser/README.md`)

# browser
    import "github.com/pkg/browser"

Package browser provides helpers to open files, readers, and urls in a browser window.

The choice of which browser is started is entirely client dependant.





## Variables
``` go
var Stderr io.Writer = os.Stderr
```
Stderr is the io.Writer to which executed commands write standard error.

``` go
var Stdout io.Writer = os.Stdout
```
Stdout is the io.Writer to which executed commands write standard output.


## func OpenFile
``` go
func OpenFile(path string) error
```
OpenFile opens new browser window for the file path.


## func OpenReader
``` go
func OpenReader(r io.Reader) error
```
OpenReader consumes the contents of r and presents the
results in a new browser window.


## func OpenURL
``` go
func OpenURL(url string) error
```
OpenURL opens a new browser window pointing to url.









- - -
Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md)

---

### Overview (`vendor/github.com/pkg/errors/README.md`)

# errors [](https://travis-ci.org/pkg/errors) [](https://ci.appveyor.com/project/davecheney/errors/branch/master) [](http://godoc.org/github.com/pkg/errors) [](https://goreportcard.com/report/github.com/pkg/errors) [](https://sourcegraph.com/github.com/pkg/errors?badge)

Package errors provides simple error handling primitives.

`go get github.com/pkg/errors`

The traditional error handling idiom in Go is roughly akin to
```go
if err != nil {
        return err
}
```
which applied recursively up the call stack results in error reports without context or debugging information. The errors package allows programmers to add context to the failure path in their code in a way that does not destroy the original value of the error.

## Adding context to an error

The errors.Wrap function returns a new error that adds context to the original error. For example
```go
_, err := ioutil.ReadAll(r)
if err != nil {
        return errors.Wrap(err, "read failed")
}
```
## Retrieving the cause of an error

Using `errors.Wrap` constructs a stack of errors, adding context to the preceding error. Depending on the nature of the error it may be necessary to reverse the operation of errors.Wrap to retrieve the original error for inspection. Any error value which implements this interface can be inspected by `errors.Cause`.
```go
type causer interface {
        Cause() error
}
```
`errors.Cause` will recursively retrieve the topmost error which does not implement `causer`, which is assumed to be the original cause. For example:
```go
switch err := errors.Cause(err).(type) {
case *MyError:
        // handle specifically
default:
        // unknown error
}
```

[Read the package documentation for more information](https://godoc.org/github.com/pkg/errors).

## Roadmap

With the upcoming [Go2 error proposals](https://go.googlesource.com/proposal/+/master/design/go2draft.md) this package is moving into maintenance mode. The roadmap for a 1.0 release is as follows:

- 0.9. Remove pre Go 1.9 and Go 1.10 support, address outstanding pull requests (if possible)
- 1.0. Final release.

## Contributing

Because of the Go2 errors changes, this package is not accepting proposals for new functionality. With that said, we welcome pull requests, bug fixes and issue reports. 

Before sending a PR, please discuss your change by raising an issue.

## License

BSD-2-Clause

---

### Overview (`vendor/github.com/proglottis/gpgme/README.md`)

# GPGME (golang)

Go wrapper for the GPGME library.

This library is intended for use with desktop applications. If you are looking to add OpenPGP support to a server application I suggest you first look at [golang.org/x/crypto/openpgp](https://godoc.org/golang.org/x/crypto/openpgp).

## Installation

    go get -u github.com/proglottis/gpgme

## Documentation

* [godoc](https://godoc.org/github.com/proglottis/gpgme)

---

### Overview (`vendor/github.com/sirupsen/logrus/README.md`)

# Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/> [](https://github.com/sirupsen/logrus/actions?query=workflow%3ACI) [](https://pkg.go.dev/github.com/sirupsen/logrus)

Logrus is a structured logger for Go (golang), completely API compatible with
the standard library logger.

**Logrus is in maintenance mode.** The project focuses on security, bug fixes,
and performance improvements. New features are not planned, aside from changes
required to provide interoperability with other logging ecosystems (e.g., Go's
[log/slog](https://pkg.go.dev/log/slog)).

I believe Logrus' biggest contribution is to have played a part in today's
widespread use of structured logging in Golang. There doesn't seem to be a
reason to do a major, breaking iteration into Logrus V2, since the fantastic Go
community has built those independently. Many fantastic alternatives have sprung
up. Logrus would look like those, had it been re-designed with what we know
about structured logging in Go today. Check out, for example,
[Zerolog][zerolog], [Zap][zap], and [Apex][apex].

[zerolog]: https://github.com/rs/zerolog
[zap]: https://github.com/uber-go/zap
[apex]: https://github.com/apex/log

Nicely color-coded in development (when a TTY is attached, otherwise just
plain text):



With `logrus.SetFormatter(&logrus.JSONFormatter{})`, for easy parsing by logstash
or Splunk:

```json lines
{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"}
{"level":"warning","msg":"The group's number increased tremendously!","number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"}
{"animal":"walrus","level":"info","msg":"A giant walrus appears!","size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"}
{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.","size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"}
{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true,"time":"2014-03-10 19:57:38.562543128 -0400 EDT"}
```

With the default `logrus.SetFormatter(&logrus.TextFormatter{})` when a TTY is not
attached, the output is compatible with the
[logfmt](https://pkg.go.dev/github.com/kr/logfmt) format:

```bash
time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8
time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10
time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true
time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4
time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009
time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" animal=orca err="It's over 9000!" number=100 omg=true size=9009
```

To ensure this behaviour even if a TTY is attached, set your formatter as follows:

```go
logrus.SetFormatter(&logrus.TextFormatter{
    DisableColors: true,
    FullTimestamp: true,
})
```

#### Logging Method Name

If you wish to add the calling method as a field, instruct the logger via:

```go
logrus.SetReportCaller(true)
```

This adds the caller as 'method' like so:

```json
{"animal":"penguin","level":"fatal","method":"github.com/sirupsen/arcticcreatures.migrate","msg":"a penguin swims by","time":"2014-03-10 19:57:38.562543129 -0400 EDT"}
```

```bash
time="2015-03-26T01:27:38-04:00" level=fatal method=github.com/sirupsen/arcticcreatures.migrate msg="a penguin swims by" animal=penguin
```

Note that this does add measurable overhead - the cost will depend on the version of Go, but is
between 20 and 40% in recent tests with 1.6 and 1.7.  You can validate this in your
environment via benchmarks:

```bash
go test -bench=ReportCaller
```

#### Case-sensitivity

The organization's name was [changed to lower-case][1]. If you are getting import
conflicts due to case sensitivity, please use the lower-case import:
`github.com/sirupsen/logrus`.

[1]: https://github.com/sirupsen/logrus/issues/570#issuecomment-313933276

#### Example

The simplest way to use Logrus is simply the package-level exported logger:

```go
package main

import "github.com/sirupsen/logrus"

func main() {
  logrus.WithFields(logrus.Fields{
    "animal": "walrus",
  }).Info("A walrus appears")
}
```

Note that it's completely api-compatible with the stdlib logger, so you can
replace your `log` imports everywhere with `log "github.com/sirupsen/logrus"`
and you'll now have the flexibility of Logrus. You can customize it all you
want:

```go
package main

import (
  "os"

  log "github.com/sirupsen/logrus"
)

func init() {
  // Log as JSON instead of the default ASCII formatter.
  log.SetFormatter(&log.JSONFormatter{})

  // Output to stdout instead of the default stderr
  // Can be any io.Writer, see below for File example
  log.SetOutput(os.Stdout)

  // Only log the warning severity or above.
  log.SetLevel(log.WarnLevel)
}

func main() {
  log.WithFields(log.Fields{
    "animal": "walrus",
    "size":   10,
  }).Info("A group of walrus emerges from the ocean")

  log.WithFields(log.Fields{
    "omg":    true,
    "number": 122,
  }).Warn("The group's number increased tremendously!")

  log.WithFields(log.Fields{
    "omg":    true,
    "number": 100,
  }).Fatal("The ice breaks!")

  // A common pattern is to re-use fields between logging statements by re-using
  // the logrus.Entry returned from WithFields()
  contextLogger := log.WithFields(log.Fields{
    "common": "this is a common field",
    "other": "I also should be logged always",
  })

  contextLogger.Info("I'll be logged with common and other field")
  contextLogger.Info("Me too")
}
```

For more advanced usage such as logging to multiple locations from the same
application, you can also create an instance of the `logrus` Logger:

```go
package main

import (
  "os"

  "github.com/sirupsen/logrus"
)

// Create a new instance of the logger. You can have any number of instances.
var logger = logrus.New()

func main() {
  // The API for setting attributes is a little different than the package level
  // exported logger. See Godoc. 
  logger.Out = os.Stdout

  // You could set this to any `io.Writer` such as a file
  // file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
  // if err == nil {
  //  logger.Out = file
  // } else {
  //  logger.Info("Failed to log to file, using default stderr")
  // }

  logger.WithFields(logrus.Fields{
    "animal": "walrus",
    "size":   10,
  }).Info("A group of walrus emerges from the ocean")
}
```

#### Fields

Logrus encourages careful, structured logging through logging fields instead of
long, unparseable error messages. For example, instead of: `logrus.Fatalf("Failed
to send event %s to topic %s with key %d")`, you should log the much more
discoverable:

```go
logrus.WithFields(logrus.Fields{
  "event": event,
  "topic": topic,
  "key": key,
}).Fatal("Failed to send event")
```

We've found this API forces you to think about logging in a way that produces
much more useful logging messages. We've been in countless situations where just
a single added field to a log statement that was already there would've saved us
hours. The `WithFields` call is optional.

In general, with Logrus using any of the `printf`-family functions should be
seen as a hint you should add a field, however, you can still use the
`printf`-family functions with Logrus.

#### Default Fields

Often it's helpful to have fields _always_ attached to log statements in an
application or parts of one. For example, you may want to always log the
`request_id` and `user_ip` in the context of a request. Instead of writing
`logger.WithFields(logrus.Fields{"request_id": request_id, "user_ip": user_ip})` on
every line, you can create a `logrus.Entry` to pass around instead:

```go
requestLogger := logger.WithFields(logrus.Fields{"request_id": request_id, "user_ip": user_ip})
requestLogger.Info("something happened on that request") // will log request_id and user_ip
requestLogger.Warn("something not great happened")
```

#### Hooks

You can add hooks for logging levels. For example to send errors to an exception
tracking service on `Error`, `Fatal` and `Panic`, info to StatsD or log to
multiple places simultaneously, e.g. syslog.

Logrus comes with [built-in hooks](hooks/). Add those, or your custom hook, in
`init`:

```go
package main

import (
  "log/syslog"

  "github.com/sirupsen/logrus"
  airbrake "gopkg.in/gemnasium/logrus-airbrake-hook.v2"
  logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
)

func init() {

  // Use the Airbrake hook to report errors that have Error severity or above to
  // an exception tracker. You can create custom hooks, see the Hooks section.
  logrus.AddHook(airbrake.NewHook(123, "xyz", "production"))

  hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
  if err != nil {
    logrus.Error("Unable to connect to local syslog daemon")
  } else {
    logrus.AddHook(hook)
  }
}
```

Note: Syslog hooks also support connecting to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). For the detail, please check the [syslog hook README](hooks/syslog/README.md).

A list of currently known service hooks can be found in this wiki [page](https://github.com/sirupsen/logrus/wiki/Hooks)


#### Level logging

Logrus has seven logging levels: Trace, Debug, Info, Warning, Error, Fatal and Panic.

```go
logrus.Trace("Something very low level.")
logrus.Debug("Useful debugging information.")
logrus.Info("Something noteworthy happened!")
logrus.Warn("You should probably take a look at this.")
logrus.Error("Something failed but I'm not quitting.")
// Calls os.Exit(1) after logging
logrus.Fatal("Bye.")
// Calls panic() after logging
logrus.Panic("I'm bailing.")
```

You can set the logging level on a `Logger`, then it will only log entries with
that severity or anything above it:

```go
// Will log anything that is info or above (warn, error, fatal, panic). Default.
logrus.SetLevel(logrus.InfoLevel)
```

It may be useful to set `logrus.Level = logrus.DebugLevel` in a debug or verbose
environment if your application has that.

Note: If you want different log levels for global (`logrus.SetLevel(...)`) and syslog logging, please check the [syslog hook README](hooks/syslog/README.md#different-log-levels-for-local-and-remote-logging).

#### Entries

Besides the fields added with `WithField` or `WithFields` some fields are
automatically added to all logging events:

1. `time`. The timestamp when the entry was created.
2. `msg`. The logging message passed to `{Info,Warn,Error,Fatal,Panic}` after
   the `AddFields` call. E.g. `Failed to send event.`
3. `level`. The logging level. E.g. `info`.

#### Environments

Logrus has no notion of environment.

If you wish for hooks and formatters to only be used in specific environments,
you should handle that yourself. For example, if your application has a global
variable `Environment`, which is a string representation of the environment you
could do:

```go
import (
  "github.com/sirupsen/logrus"
)

func init() {
  // do something here to set environment depending on an environment variable
  // or command-line flag
  if Environment == "production" {
    logrus.SetFormatter(&logrus.JSONFormatter{})
  } else {
    // The TextFormatter is default, you don't actually have to do this.
    logrus.SetFormatter(&logrus.TextFormatter{})
  }
}
```

This configuration is how `logrus` was intended to be used, but JSON in
production is mostly only useful if you do log aggregation with tools like
Splunk or Logstash.

#### Formatters

The built-in logging formatters are:

* [`logrus.TextFormatter`](https://pkg.go.dev/github.com/sirupsen/logrus#TextFormatter)
  logs the event in colors if the logger output is a TTY, otherwise without colors.
  * To force colored output when there is no TTY, set the `ForceColors`
    field to `true`.  To force no colored output even if there is a TTY  set the
    `DisableColors` field to `true`.
  * On modern Windows terminals with ANSI (Virtual Terminal) support, TextFormatter
    automatically enables colored output.
  * If your environment does not support ANSI escape sequences, wrap the logger output
    using [github.com/mattn/go-colorable](https://github.com/mattn/go-colorable)
    and set `ForceColors` (or `CLICOLOR_FORCE=1`) to enable colors through the wrapper.
  * When colors are enabled, levels are truncated to 4 characters by default. To disable
    truncation set the `DisableLevelTruncation` field to `true`.
  * When outputting to a TTY, it's often helpful to visually scan down a column where all the levels are the same width. Setting the `PadLevelText` field to `true` enables this behavior, by adding padding to the level text.
* [`logrus.JSONFormatter`](https://pkg.go.dev/github.com/sirupsen/logrus#JSONFormatter)
  logs fields as JSON.

Third-party logging formatters:

* [`FluentdFormatter`](https://github.com/joonix/log). Formats entries that can be parsed by Kubernetes and Google Container Engine.
* [`GELF`](https://github.com/fabienm/go-logrus-formatters). Formats entries so they comply to Graylog's [GELF 1.1 specification](http://docs.graylog.org/en/2.4/pages/gelf.html).
* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events.
* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout.
* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the Power of Zalgo.
* [`nested-logrus-formatter`](https://github.com/antonfisher/nested-logrus-formatter). Converts logrus fields to a nested structure.
* [`powerful-logrus-formatter`](https://github.com/zput/zxcTool). get fileName, log's line number and the latest function's name when print log; Save log to files.
* [`caption-json-formatter`](https://github.com/nolleh/caption_json_formatter). logrus's message json formatter with human-readable caption added.
* [`easy-logrus-formatter`](https://github.com/WeiZhixiong/easy-logrus-formatter). Provide a user-friendly formatter for logrus.
* [`redactrus`](https://github.com/ibreakthecloud/redactrus). Redacts sensitive information like password, apikeys, email, etc. from logs.

You can define your formatter by implementing the `Formatter` interface,
requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a
`Fields` type (`map[string]any`) with all your fields as well as the
default ones (see Entries section above):

```go
type MyJSONFormatter struct{}

logrus.SetFormatter(new(MyJSONFormatter))

func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) {
  // Note this doesn't include Time, Level and Message which are available on
  // the Entry. Consult `godoc` on information about those fields or read the
  // source of the official loggers.
  serialized, err := json.Marshal(entry.Data)
    if err != nil {
      return nil, fmt.Errorf("Failed to marshal fields to JSON, %w", err)
    }
  return append(serialized, '\n'), nil
}
```

#### Logger as an `io.Writer`

Logrus can be transformed into an `io.Writer`. That writer is the end of an `io.Pipe` and it is your responsibility to close it.

```go
w := logger.Writer()
defer w.Close()

srv := http.Server{
    // create a stdlib log.Logger that writes to
    // logrus.Logger.
    ErrorLog: log.New(w, "", 0),
}
```

Each line written to that writer will be printed the usual way, using formatters
and hooks. The level for those entries is `info`.

This means that we can override the standard library logger easily:

```go
logger := logrus.New()
logger.Formatter = &logrus.JSONFormatter{}

// Use logrus for standard log output
// Note that `log` here references stdlib's log
// Not logrus imported under the name `log`.
log.SetOutput(logger.Writer())
```

#### Rotation

Log rotation is not provided with Logrus. Log rotation should be done by an
external program (like `logrotate(8)`) that can compress and delete old log
entries. It should not be a feature of the application-level logger.

#### Tools

| Tool | Description |
| ---- | ----------- |
|[Logrus Mate](https://github.com/gogap/logrus_mate)|Logrus mate is a tool for Logrus to manage loggers, you can initial logger's level, hook and formatter by config file, the logger will be generated with different configs in different environments.|
|[Logrus Viper Helper](https://github.com/heirko/go-contrib/tree/master/logrusHelper)|An Helper around Logrus to wrap with spf13/Viper to load configuration with fangs! And to simplify Logrus configuration use some behavior of [Logrus Mate](https://github.com/gogap/logrus_mate). [sample](https://github.com/heirko/iris-contrib/blob/master/middleware/logrus-logger/example) |

#### Testing

Logrus has a built-in facility for asserting the presence of log messages. This is implemented through the `test` hook and provides:

* decorators for existing logger (`test.NewLocal` and `test.NewGlobal`) which basically just adds the `test` hook
* a test logger (`test.NewNullLogger`) that just records log messages (and does not output any):

```go
import(
  "testing"

  "github.com/sirupsen/logrus"
  "github.com/sirupsen/logrus/hooks/test"
  "github.com/stretchr/testify/assert"
)

func TestSomething(t*testing.T){
  logger, hook := test.NewNullLogger()
  logger.Error("Helloerror")

  assert.Equal(t, 1, len(hook.Entries))
  assert.Equal(t, logrus.ErrorLevel, hook.LastEntry().Level)
  assert.Equal(t, "Helloerror", hook.LastEntry().Message)

  hook.Reset()
  assert.Nil(t, hook.LastEntry())
}
```

#### Fatal handlers

Logrus can register one or more functions that will be called when any `fatal`
level message is logged. The registered handlers will be executed before
logrus performs an `os.Exit(1)`. This behavior may be helpful if callers need
to gracefully shut down. Unlike a `panic("Something went wrong...")` call which can be intercepted with a deferred `recover` a call to `os.Exit(1)` can not be intercepted.

```go
// ...
handler := func() {
  // gracefully shut down something...
}
logrus.RegisterExitHandler(handler)
// ...
```

#### Thread safety

By default, Logger is protected by a mutex for concurrent writes. The mutex is held when calling hooks and writing logs.
If you are sure such locking is not needed, you can call logger.SetNoLock() to disable the locking.

Situations when locking is not needed include:

* You have no hooks registered, or hooks calling is already thread-safe.

* Writing to logger.Out is already thread-safe, for example:

  1) logger.Out is protected by locks.

  2) logger.Out is an os.File handler opened with `O_APPEND` flag, and every write is smaller than 4k. (This allows multi-thread/multi-process writing)

     (Refer to <http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/>)

---

### Overview (`vendor/github.com/smallstep/pkcs7/README.md`)

# pkcs7

[](https://pkg.go.dev/github.com/smallstep/pkcs7)
[](https://github.com/smallstep/pkcs7/actions/workflows/ci.yml?query=branch%3Amain+event%3Apush)

pkcs7 implements parsing and creating signed and enveloped messages.

```go
package main

import (
	"bytes"
	"crypto/rsa"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"os"

    "github.com/smallstep/pkcs7"
)

func SignAndDetach(content []byte, cert *x509.Certificate, privkey *rsa.PrivateKey) (signed []byte, err error) {
	toBeSigned, err := NewSignedData(content)
	if err != nil {
		return fmt.Errorf("Cannot initialize signed data: %w", err)
	}
	if err = toBeSigned.AddSigner(cert, privkey, SignerInfoConfig{}); err != nil {
		return fmt.Errorf("Cannot add signer: %w", err)
	}

	// Detach signature, omit if you want an embedded signature
	toBeSigned.Detach()

	signed, err = toBeSigned.Finish()
	if err != nil {
		return fmt.Errorf("Cannot finish signing data: %w", err)
	}

	// Verify the signature
	pem.Encode(os.Stdout, &pem.Block{Type: "PKCS7", Bytes: signed})
	p7, err := pkcs7.Parse(signed)
	if err != nil {
		return fmt.Errorf("Cannot parse our signed data: %w", err)
	}

	// since the signature was detached, reattach the content here
	p7.Content = content

	if bytes.Compare(content, p7.Content) != 0 {
		return fmt.Errorf("Our content was not in the parsed data:\n\tExpected: %s\n\tActual: %s", content, p7.Content)
	}
	if err = p7.Verify(); err != nil {
		return fmt.Errorf("Cannot verify our signed data: %w", err)
	}

	return signed, nil
}
```


## Credits

This is a fork of [mozilla-services/pkcs7](https://github.com/mozilla-services/pkcs7) which, itself, was a fork of [fullsailor/pkcs7](https://github.com/fullsailor/pkcs7).

---

### Overview (`vendor/github.com/spf13/cobra/README.md`)

<div align="center">
<a href="https://cobra.dev">
<img width="512" height="535" alt="cobra-logo" src="https://github.com/user-attachments/assets/c8bf9aad-b5ae-41d3-8899-d83baec10af8" />
</a>
</div>

Cobra is a library for creating powerful modern CLI applications.

<a href="https://cobra.dev">Visit Cobra.dev for extensive documentation</a> 


Cobra is used in many Go projects such as [Kubernetes](https://kubernetes.io/),
[Hugo](https://gohugo.io), and [GitHub CLI](https://github.com/cli/cli) to
name a few. [This list](site/content/projects_using_cobra.md) contains a more extensive list of projects using Cobra.

[](https://github.com/spf13/cobra/actions?query=workflow%3ATest)
[](https://pkg.go.dev/github.com/spf13/cobra)
[](https://goreportcard.com/report/github.com/spf13/cobra)
[](https://gophers.slack.com/archives/CD3LP1199)
<hr>
<div align="center" markdown="1">
   <sup>Supported by:</sup>
   <br>
   <br>
   <a href="https://www.warp.dev/cobra">
      <img alt="Warp sponsorship" width="400" src="https://github.com/user-attachments/assets/ab8dd143-b0fd-4904-bdc5-dd7ecac94eae">
   </a>

### [Warp, the AI terminal for devs](https://www.warp.dev/cobra)
[Try Cobra in Warp today](https://www.warp.dev/cobra)<br>

</div>
<hr>

# Overview

Cobra is a library providing a simple interface to create powerful modern CLI
interfaces similar to git & go tools.

Cobra provides:
* Easy subcommand-based CLIs: `app server`, `app fetch`, etc.
* Fully POSIX-compliant flags (including short & long versions)
* Nested subcommands
* Global, local and cascading flags
* Intelligent suggestions (`app srver`... did you mean `app server`?)
* Automatic help generation for commands and flags
* Grouping help for subcommands
* Automatic help flag recognition of `-h`, `--help`, etc.
* Automatically generated shell autocomplete for your application (bash, zsh, fish, powershell)
* Automatically generated man pages for your application
* Command aliases so you can change things without breaking them
* The flexibility to define your own help, usage, etc.
* Optional seamless integration with [viper](https://github.com/spf13/viper) for 12-factor apps

# Concepts

Cobra is built on a structure of commands, arguments & flags.

**Commands** represent actions, **Args** are things and **Flags** are modifiers for those actions.

The best applications read like sentences when used, and as a result, users
intuitively know how to interact with them.

The pattern to follow is
`APPNAME VERB NOUN --ADJECTIVE`
    or
`APPNAME COMMAND ARG --FLAG`.

A few good real world examples may better illustrate this point.

In the following example, 'server' is a command, and 'port' is a flag:

    hugo server --port=1313

In this command we are telling Git to clone the url bare.

    git clone URL --bare

## Commands

Command is the central point of the application. Each interaction that
the application supports will be contained in a Command. A command can
have children commands and optionally run an action.

In the example above, 'server' is the command.

[More about cobra.Command](https://pkg.go.dev/github.com/spf13/cobra#Command)

## Flags

A flag is a way to modify the behavior of a command. Cobra supports
fully POSIX-compliant flags as well as the Go [flag package](https://golang.org/pkg/flag/).
A Cobra command can define flags that persist through to children commands
and flags that are only available to that command.

In the example above, 'port' is the flag.

Flag functionality is provided by the [pflag
library](https://github.com/spf13/pflag), a fork of the flag standard library
which maintains the same interface while adding POSIX compliance.

# Installing
Using Cobra is easy. First, use `go get` to install the latest version
of the library.

```
go get -u github.com/spf13/cobra@latest
```

Next, include Cobra in your application:

```go
import "github.com/spf13/cobra"
```

# Usage
`cobra-cli` is a command line program to generate cobra applications and command files.
It will bootstrap your application scaffolding to rapidly
develop a Cobra-based application. It is the easiest way to incorporate Cobra into your application.

It can be installed by running:

```
go install github.com/spf13/cobra-cli@latest
```

For complete details on using the Cobra-CLI generator, please read [The Cobra Generator README](https://github.com/spf13/cobra-cli/blob/main/README.md)

For complete details on using the Cobra library, please read [The Cobra User Guide](site/content/user_guide.md).

# License

Cobra is released under the Apache 2.0 license. See [LICENSE.txt](LICENSE.txt)

---

### Overview (`vendor/github.com/spf13/pflag/README.md`)

[](https://travis-ci.org/spf13/pflag)
[](https://goreportcard.com/report/github.com/spf13/pflag)
[](https://godoc.org/github.com/spf13/pflag)

## Description

pflag is a drop-in replacement for Go's flag package, implementing
POSIX/GNU-style --flags.

pflag is compatible with the [GNU extensions to the POSIX recommendations
for command-line options][1]. For a more precise description, see the
"Command-line flag syntax" section below.

[1]: http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html

pflag is available under the same style of BSD license as the Go language,
which can be found in the LICENSE file.

## Installation

pflag is available using the standard `go get` command.

Install by running:

    go get github.com/spf13/pflag

Run tests by running:

    go test github.com/spf13/pflag

## Usage

pflag is a drop-in replacement of Go's native flag package. If you import
pflag under the name "flag" then all code should continue to function
with no changes.

``` go
import flag "github.com/spf13/pflag"
```

There is one exception to this: if you directly instantiate the Flag struct
there is one more field "Shorthand" that you will need to set.
Most code never instantiates this struct directly, and instead uses
functions such as String(), BoolVar(), and Var(), and is therefore
unaffected.

Define flags using flag.String(), Bool(), Int(), etc.

This declares an integer flag, -flagname, stored in the pointer ip, with type *int.

``` go
var ip *int = flag.Int("flagname", 1234, "help message for flagname")
```

If you like, you can bind the flag to a variable using the Var() functions.

``` go
var flagvar int
func init() {
    flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
}
```

Or you can create custom flags that satisfy the Value interface (with
pointer receivers) and couple them to flag parsing by

``` go
flag.Var(&flagVal, "name", "help message for flagname")
```

For such flags, the default value is just the initial value of the variable.

After all flags are defined, call

``` go
flag.Parse()
```

to parse the command line into the defined flags.

Flags may then be used directly. If you're using the flags themselves,
they are all pointers; if you bind to variables, they're values.

``` go
fmt.Println("ip has value ", *ip)
fmt.Println("flagvar has value ", flagvar)
```

There are helper functions available to get the value stored in a Flag if you have a FlagSet but find
it difficult to keep up with all of the pointers in your code.
If you have a pflag.FlagSet with a flag called 'flagname' of type int you
can use GetInt() to get the int value. But notice that 'flagname' must exist
and it must be an int. GetString("flagname") will fail.

``` go
i, err := flagset.GetInt("flagname")
```

After parsing, the arguments after the flag are available as the
slice flag.Args() or individually as flag.Arg(i).
The arguments are indexed from 0 through flag.NArg()-1.

The pflag package also defines some new functions that are not in flag,
that give one-letter shorthands for flags. You can use these by appending
'P' to the name of any function that defines a flag.

``` go
var ip = flag.IntP("flagname", "f", 1234, "help message")
var flagvar bool
func init() {
	flag.BoolVarP(&flagvar, "boolname", "b", true, "help message")
}
flag.VarP(&flagVal, "varname", "v", "help message")
```

Shorthand letters can be used with single dashes on the command line.
Boolean shorthand flags can be combined with other shorthand flags.

The default set of command-line flags is controlled by
top-level functions.  The FlagSet type allows one to define
independent sets of flags, such as to implement subcommands
in a command-line interface. The methods of FlagSet are
analogous to the top-level functions for the command-line
flag set.

## Setting no option default values for flags

After you create a flag it is possible to set the pflag.NoOptDefVal for
the given flag. Doing this changes the meaning of the flag slightly. If
a flag has a NoOptDefVal and the flag is set on the command line without
an option the flag will be set to the NoOptDefVal. For example given:

``` go
var ip = flag.IntP("flagname", "f", 1234, "help message")
flag.Lookup("flagname").NoOptDefVal = "4321"
```

Would result in something like

| Parsed Arguments | Resulting Value |
| -------------    | -------------   |
| --flagname=1357  | ip=1357         |
| --flagname       | ip=4321         |
| [nothing]        | ip=1234         |

## Command line flag syntax

```
--flag    // boolean flags, or flags with no option default values
--flag x  // only on flags without a default value
--flag=x
```

Unlike the flag package, a single dash before an option means something
different than a double dash. Single dashes signify a series of shorthand
letters for flags. All but the last shorthand letter must be boolean flags
or a flag with a default value

```
// boolean or flags where the 'no option default value' is set
-f
-f=true
-abc
but
-b true is INVALID

// non-boolean and flags without a 'no option default value'
-n 1234
-n=1234
-n1234

// mixed
-abcs "hello"
-absd="hello"
-abcs1234
```

Flag parsing stops after the terminator "--". Unlike the flag package,
flags can be interspersed with arguments anywhere on the command line
before this terminator.

Integer flags accept 1234, 0664, 0x1234 and may be negative.
Boolean flags (in their long form) accept 1, 0, t, f, true, false,
TRUE, FALSE, True, False.
Duration flags accept any input valid for time.ParseDuration.

## Mutating or "Normalizing" Flag names

It is possible to set a custom flag name 'normalization function.' It allows flag names to be mutated both when created in the code and when used on the command line to some 'normalized' form. The 'normalized' form is used for comparison. Two examples of using the custom normalization func follow.

**Example #1**: You want -, _, and . in flags to compare the same. aka --my-flag == --my_flag == --my.flag

``` go
func wordSepNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName {
	from := []string{"-", "_"}
	to := "."
	for _, sep := range from {
		name = strings.Replace(name, sep, to, -1)
	}
	return pflag.NormalizedName(name)
}

myFlagSet.SetNormalizeFunc(wordSepNormalizeFunc)
```

**Example #2**: You want to alias two flags. aka --old-flag-name == --new-flag-name

``` go
func aliasNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName {
	switch name {
	case "old-flag-name":
		name = "new-flag-name"
		break
	}
	return pflag.NormalizedName(name)
}

myFlagSet.SetNormalizeFunc(aliasNormalizeFunc)
```

## Deprecating a flag or its shorthand
It is possible to deprecate a flag, or just its shorthand. Deprecating a flag/shorthand hides it from help text and prints a usage message when the deprecated flag/shorthand is used.

**Example #1**: You want to deprecate a flag named "badflag" as well as inform the users what flag they should use instead.
```go
// deprecate a flag by specifying its name and a usage message
flags.MarkDeprecated("badflag", "please use --good-flag instead")
```
This hides "badflag" from help text, and prints `Flag --badflag has been deprecated, please use --good-flag instead` when "badflag" is used.

**Example #2**: You want to keep a flag name "noshorthandflag" but deprecate its shortname "n".
```go
// deprecate a flag shorthand by specifying its flag name and a usage message
flags.MarkShorthandDeprecated("noshorthandflag", "please use --noshorthandflag only")
```
This hides the shortname "n" from help text, and prints `Flag shorthand -n has been deprecated, please use --noshorthandflag only` when the shorthand "n" is used.

Note that usage message is essential here, and it should not be empty.

## Hidden flags
It is possible to mark a flag as hidden, meaning it will still function as normal, however will not show up in usage/help text.

**Example**: You have a flag named "secretFlag" that you need for internal use only and don't want it showing up in help text, or for its usage text to be available.
```go
// hide a flag by specifying its name
flags.MarkHidden("secretFlag")
```

## Disable sorting of flags
`pflag` allows you to disable sorting of flags for help and usage message.

**Example**:
```go
flags.BoolP("verbose", "v", false, "verbose output")
flags.String("coolflag", "yeaah", "it's really cool flag")
flags.Int("usefulflag", 777, "sometimes it's very useful")
flags.SortFlags = false
flags.PrintDefaults()
```
**Output**:
```
  -v, --verbose           verbose output
      --coolflag string   it's really cool flag (default "yeaah")
      --usefulflag int    sometimes it's very useful (default 777)
```


## Supporting Go flags when using pflag
In order to support flags defined using Go's `flag` package, they must be added to the `pflag` flagset. This is usually necessary
to support flags defined by third-party dependencies (e.g. `golang/glog`).

**Example**: You want to add the Go flags to the `CommandLine` flagset
```go
import (
	goflag "flag"
	flag "github.com/spf13/pflag"
)

var ip *int = flag.Int("flagname", 1234, "help message for flagname")

func main() {
	flag.CommandLine.AddGoFlagSet(goflag.CommandLine)
	flag.Parse()
}
```

### Using pflag with go test
`pflag` does not parse the shorthand versions of go test's built-in flags (i.e., those starting with `-test.`).
For more context, see issues [#63](https://github.com/spf13/pflag/issues/63) and [#238](https://github.com/spf13/pflag/issues/238) for more details.

For example, if you use pflag in your `TestMain` function and call `pflag.Parse()` after defining your custom flags, running a test like this:
```bash
go test /your/tests -run ^YourTest -v --your-test-pflags
```
will result in the `-v` flag being ignored. This happens because of the way pflag handles flag parsing, skipping over go test's built-in shorthand flags.
To work around this, you can use the `ParseSkippedFlags` function, which ensures that go test's flags are parsed separately using the standard flag package.

**Example**: You want to parse go test flags that are otherwise ignore by `pflag.Parse()`
```go
import (
	goflag "flag"
	flag "github.com/spf13/pflag"
)

var ip *int = flag.Int("flagname", 1234, "help message for flagname")

func main() {
	flag.CommandLine.AddGoFlagSet(goflag.CommandLine)
    flag.ParseSkippedFlags(os.Args[1:], goflag.CommandLine)
	flag.Parse()
}
```

## More info

You can see the full reference documentation of the pflag package
[at godoc.org][3], or through go's standard documentation system by
running `godoc -http=:6060` and browsing to
[http://localhost:6060/pkg/github.com/spf13/pflag][2] after
installation.

[2]: http://localhost:6060/pkg/github.com/spf13/pflag
[3]: http://godoc.org/github.com/spf13/pflag

---

### Overview (`vendor/github.com/stefanberger/go-pkcs11uri/README.md`)

# go-pkcs11uri

Welcome to the go-pkcs11uri library. The implementation follows [RFC 7512](https://tools.ietf.org/html/rfc7512) and this [errata](https://www.rfc-editor.org/errata/rfc7512).

# Exampe usage:

The following example builds on this library [here](https://github.com/miekg/pkcs11) and are using softhsm2 on Fedora.

## Example

This example program extending the one found [here](https://github.com/miekg/pkcs11/blob/master/README.md#examples):

```
package main

import (
	"fmt"
	"os"
	"strconv"

	"github.com/miekg/pkcs11"
	pkcs11uri "github.com/stefanberger/go-pkcs11uri"
)

func main() {
	if len(os.Args) < 2 {
		panic("Missing pkcs11 URI argument")
	}
	uristr := os.Args[1]

	uri, err := pkcs11uri.New()
	if err != nil {
		panic(err)
	}
	err = uri.Parse(uristr)
	if err != nil {
		panic(err)
	}

	module, err := uri.GetModule()
	if err != nil {
		panic(err)
	}

	slot, ok := uri.GetPathAttribute("slot-id", false)
	if !ok {
		panic("No slot-id in pkcs11 URI")
	}
	slotid, err := strconv.Atoi(slot)
	if err != nil {
		panic(err)
	}

	pin, err := uri.GetPIN()
	if err != nil {
		panic(err)
	}

	p := pkcs11.New(module)
	err = p.Initialize()
	if err != nil {
		panic(err)
	}

	defer p.Destroy()
	defer p.Finalize()

	session, err := p.OpenSession(uint(slotid), pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION)
	if err != nil {
		panic(err)
	}
	defer p.CloseSession(session)

	err = p.Login(session, pkcs11.CKU_USER, pin)
	if err != nil {
		panic(err)
	}
	defer p.Logout(session)

	p.DigestInit(session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_SHA_1, nil)})
	hash, err := p.Digest(session, []byte("this is a string"))
	if err != nil {
		panic(err)
	}

	for _, d := range hash {
		fmt.Printf("%x", d)
	}
	fmt.Println()
}
```

## Exampe Usage

```
$ sudo softhsm2-util --init-token --slot 1 --label test --pin 1234 --so-pin 1234
The token has been initialized and is reassigned to slot 2053753261
$ go build ./...
$ sudo ./pkcs11-example 'pkcs11:slot-id=2053753261?module-path=/usr/lib64/pkcs11/libsofthsm2.so&pin-value=1234'
517592df8fec3ad146a79a9af153db2a4d784ec5
```

---

### Overview (`vendor/github.com/ulikunitz/xz/README.md`)

# Package xz

This Go language package supports the reading and writing of xz
compressed streams. It includes also a gxz command for compressing and
decompressing data. The package is completely written in Go and doesn't
have any dependency on any C code.

The package is currently under development. There might be bugs and APIs
are not considered stable. At this time the package cannot compete with
the xz tool regarding compression speed and size. The algorithms there
have been developed over a long time and are highly optimized. However
there are a number of improvements planned and I'm very optimistic about
parallel compression and decompression. Stay tuned!

## Using the API

The following example program shows how to use the API.

```go
package main

import (
    "bytes"
    "io"
    "log"
    "os"

    "github.com/ulikunitz/xz"
)

func main() {
    const text = "The quick brown fox jumps over the lazy dog.\n"
    var buf bytes.Buffer
    // compress text
    w, err := xz.NewWriter(&buf)
    if err != nil {
        log.Fatalf("xz.NewWriter error %s", err)
    }
    if _, err := io.WriteString(w, text); err != nil {
        log.Fatalf("WriteString error %s", err)
    }
    if err := w.Close(); err != nil {
        log.Fatalf("w.Close error %s", err)
    }
    // decompress buffer and write output to stdout
    r, err := xz.NewReader(&buf)
    if err != nil {
        log.Fatalf("NewReader error %s", err)
    }
    if _, err = io.Copy(os.Stdout, r); err != nil {
        log.Fatalf("io.Copy error %s", err)
    }
}
```

## Documentation

You can find the full documentation at [pkg.go.dev](https://pkg.go.dev/github.com/ulikunitz/xz).

## Using the gxz compression tool

The package includes a gxz command line utility for compression and
decompression.

Use following command for installation:

    $ go get github.com/ulikunitz/xz/cmd/gxz

To test it call the following command.

    $ gxz bigfile

After some time a much smaller file bigfile.xz will replace bigfile.
To decompress it use the following command.

    $ gxz -d bigfile.xz

## Security & Vulnerabilities

The security policy is documented in [SECURITY.md](SECURITY.md). 

The software is not affected by the supply chain attack on the original xz
implementation, [CVE-2024-3094](https://nvd.nist.gov/vuln/detail/CVE-2024-3094).
This implementation doesn't share any files with the original xz implementation
and no patches or pull requests are accepted without a review.

All security advisories for this project are published under
[github.com/ulikunitz/xz/security/advisories](https://github.com/ulikunitz/xz/security/advisories?state=published).

---

### Overview (`vendor/github.com/vbauerster/cupwriter/README.md`)

# cupwriter

[](https://pkg.go.dev/github.com/vbauerster/cupwriter)
[](https://github.com/vbauerster/cupwriter/actions/workflows/test.yml)
[](https://github.com/vbauerster/cupwriter/actions/workflows/golangci-lint.yml)

cupwriter is a cross platform buffered `io.Writer` which abstracts writing multi lines to a fixed position within a terminal.
It's used by [mpb](https://github.com/vbauerster/mpb) under the hood which means it's quite battle tested in spite of `v0.0.x`.

---

### Overview (`vendor/github.com/youmark/pkcs8/README.md`)

pkcs8
===
OpenSSL can generate private keys in both "traditional format" and PKCS#8 format. Newer applications are advised to use more secure PKCS#8 format. Go standard crypto package provides a [function](http://golang.org/pkg/crypto/x509/#ParsePKCS8PrivateKey) to parse private key in PKCS#8 format. There is a limitation to this function. It can only handle unencrypted PKCS#8 private keys. To use this function, the user has to save the private key in file without encryption, which is a bad practice to leave private keys unprotected on file systems. In addition, Go standard package lacks the functions to convert RSA/ECDSA private keys into PKCS#8 format.

pkcs8 package fills the gap here. It implements functions to process private keys in PKCS#8 format, as defined in [RFC5208](https://tools.ietf.org/html/rfc5208) and [RFC5958](https://tools.ietf.org/html/rfc5958). It can handle both unencrypted PKCS#8 PrivateKeyInfo format and EncryptedPrivateKeyInfo format with PKCS#5 (v2.0) algorithms.


[**Godoc**](http://godoc.org/github.com/youmark/pkcs8)

## Installation
Supports Go 1.10+. Release v1.1 is the last release supporting Go 1.9 

```text
go get github.com/youmark/pkcs8
```
## dependency
This package depends on golang.org/x/crypto/pbkdf2 and golang.org/x/crypto/scrypt packages. Use the following command to retrieve them
```text
go get golang.org/x/crypto/pbkdf2
go get golang.org/x/crypto/scrypt
```

---

### Overview (`vendor/go.opentelemetry.io/otel/attribute/README.md`)

# Attribute

[](https://pkg.go.dev/go.opentelemetry.io/otel/attribute)

---

### Overview (`vendor/go.opentelemetry.io/otel/baggage/README.md`)

# Baggage

[](https://pkg.go.dev/go.opentelemetry.io/otel/baggage)

---

### Overview (`vendor/go.opentelemetry.io/otel/codes/README.md`)

# Codes

[](https://pkg.go.dev/go.opentelemetry.io/otel/codes)

---

### Overview (`vendor/go.opentelemetry.io/otel/metric/README.md`)

# Metric API

[](https://pkg.go.dev/go.opentelemetry.io/otel/metric)

---

### Overview (`vendor/go.opentelemetry.io/otel/propagation/README.md`)

# Propagation

[](https://pkg.go.dev/go.opentelemetry.io/otel/propagation)

---

### Overview (`vendor/go.opentelemetry.io/otel/trace/README.md`)

# Trace API

[](https://pkg.go.dev/go.opentelemetry.io/otel/trace)

---

### Overview (`vendor/go.yaml.in/yaml/v3/README.md`)

go.yaml.in/yaml
===============

YAML Support for the Go Language


## Introduction

The `yaml` package enables [Go](https://go.dev/) programs to comfortably encode
and decode [YAML](https://yaml.org/) values.

It was originally developed within [Canonical](https://www.canonical.com) as
part of the [juju](https://juju.ubuntu.com) project, and is based on a pure Go
port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML) C library to
parse and generate YAML data quickly and reliably.


## Project Status

This project started as a fork of the extremely popular [go-yaml](
https://github.com/go-yaml/yaml/)
project, and is being maintained by the official [YAML organization](
https://github.com/yaml/).

The YAML team took over ongoing maintenance and development of the project after
discussion with go-yaml's author, @niemeyer, following his decision to
[label the project repository as "unmaintained"](
https://github.com/go-yaml/yaml/blob/944c86a7d2/README.md) in April 2025.

We have put together a team of dedicated maintainers including representatives
of go-yaml's most important downstream projects.

We will strive to earn the trust of the various go-yaml forks to switch back to
this repository as their upstream.

Please [contact us](https://cloud-native.slack.com/archives/C08PPAT8PS7) if you
would like to contribute or be involved.


## Compatibility

The `yaml` package supports most of YAML 1.2, but preserves some behavior from
1.1 for backwards compatibility.

Specifically, v3 of the `yaml` package:

* Supports YAML 1.1 bools (`yes`/`no`, `on`/`off`) as long as they are being
  decoded into a typed bool value.
  Otherwise they behave as a string.
  Booleans in YAML 1.2 are `true`/`false` only.
* Supports octals encoded and decoded as `0777` per YAML 1.1, rather than
  `0o777` as specified in YAML 1.2, because most parsers still use the old
  format.
  Octals in the `0o777` format are supported though, so new files work.
* Does not support base-60 floats.
  These are gone from YAML 1.2, and were actually never supported by this
  package as it's clearly a poor choice.


## Installation and Usage

The import path for the package is *go.yaml.in/yaml/v3*.

To install it, run:

```bash
go get go.yaml.in/yaml/v3
```


## API Documentation

See: <https://pkg.go.dev/go.yaml.in/yaml/v3>


## API Stability

The package API for yaml v3 will remain stable as described in [gopkg.in](
https://gopkg.in).


## Example

```go
package main

import (
	"fmt"
	"log"

	"go.yaml.in/yaml/v3"
)

var data = `
a: Easy!
b:
  c: 2
  d: [3, 4]
`

// Note: struct fields must be public in order for unmarshal to
// correctly populate the data.
type T struct {
	A string
	B struct {
		RenamedC int   `yaml:"c"`
		D	[]int `yaml:",flow"`
	}
}

func main() {
	t := T{}

	err := yaml.Unmarshal([]byte(data), &t)
	if err != nil {
		log.Fatalf("error: %v", err)
	}
	fmt.Printf("--- t:\n%v\n\n", t)

	d, err := yaml.Marshal(&t)
	if err != nil {
		log.Fatalf("error: %v", err)
	}
	fmt.Printf("--- t dump:\n%s\n\n", string(d))

	m := make(map[interface{}]interface{})

	err = yaml.Unmarshal([]byte(data), &m)
	if err != nil {
		log.Fatalf("error: %v", err)
	}
	fmt.Printf("--- m:\n%v\n\n", m)

	d, err = yaml.Marshal(&m)
	if err != nil {
		log.Fatalf("error: %v", err)
	}
	fmt.Printf("--- m dump:\n%s\n\n", string(d))
}
```

This example will generate the following output:

```
--- t:
{Easy! {2 [3 4]}}

--- t dump:
a: Easy!
b:
  c: 2
  d: [3, 4]


--- m:
map[a:Easy! b:map[c:2 d:[3 4]]]

--- m dump:
a: Easy!
b:
  c: 2
  d:
  - 3
  - 4
```


## License

The yaml package is licensed under the MIT and Apache License 2.0 licenses.
Please see the LICENSE file for details.

---

### Overview (`vendor/golang.org/x/oauth2/README.md`)

# OAuth2 for Go

[](https://pkg.go.dev/golang.org/x/oauth2)
[](https://travis-ci.org/golang/oauth2)

oauth2 package contains a client implementation for OAuth 2.0 spec.

See pkg.go.dev for further documentation and examples.

* [pkg.go.dev/golang.org/x/oauth2](https://pkg.go.dev/golang.org/x/oauth2)
* [pkg.go.dev/golang.org/x/oauth2/google](https://pkg.go.dev/golang.org/x/oauth2/google)

## Policy for new endpoints

We no longer accept new provider-specific packages in this repo if all
they do is add a single endpoint variable. If you just want to add a
single endpoint, add it to the
[pkg.go.dev/golang.org/x/oauth2/endpoints](https://pkg.go.dev/golang.org/x/oauth2/endpoints)
package.

## Report Issues / Send Patches

The main issue tracker for the oauth2 repository is located at
https://github.com/golang/oauth2/issues.

This repository uses Gerrit for code changes. To learn how to submit changes to
this repository, see https://go.dev/doc/contribute.

The git repository is https://go.googlesource.com/oauth2.

Note:

* Excluding trivial changes, all contributions should be connected to an existing issue.
* API changes must go through the [change proposal process](https://go.dev/s/proposal-process) before they can be accepted.
* The code owners are listed at [dev.golang.org/owners](https://dev.golang.org/owners#:~:text=x/oauth2).

---

### Overview (`vendor/golang.org/x/term/README.md`)

# Go terminal/console support

[](https://pkg.go.dev/golang.org/x/term)

This repository provides Go terminal and console support packages.

## Report Issues / Send Patches

This repository uses Gerrit for code changes. To learn how to submit changes to
this repository, see https://go.dev/doc/contribute.

The git repository is https://go.googlesource.com/term.

The main issue tracker for the term repository is located at
https://go.dev/issues. Prefix your issue with "x/term:" in the
subject line, so it is easy to find.

---

### Overview (`vendor/github.com/Masterminds/semver/v3/README.md`)

# SemVer

The `semver` package provides the ability to work with [Semantic Versions](http://semver.org) in Go. Specifically it provides the ability to:

* Parse semantic versions
* Sort semantic versions
* Check if a semantic version fits within a set of constraints
* Optionally work with a `v` prefix

[![Stability:
Active](https://masterminds.github.io/stability/active.svg)](https://masterminds.github.io/stability/active.html)
[](https://github.com/Masterminds/semver/actions)
[](https://pkg.go.dev/github.com/Masterminds/semver/v3)
[](https://goreportcard.com/report/github.com/Masterminds/semver)

## Package Versions

Note, import `github.com/Masterminds/semver/v3` to use the latest version.

There are three major versions fo the `semver` package.

* 3.x.x is the stable and active version. This version is focused on constraint
  compatibility for range handling in other tools from other languages. It has
  a similar API to the v1 releases. The development of this version is on the master
  branch. The documentation for this version is below.
* 2.x was developed primarily for [dep](https://github.com/golang/dep). There are
  no tagged releases and the development was performed by [@sdboyer](https://github.com/sdboyer).
  There are API breaking changes from v1. This version lives on the [2.x branch](https://github.com/Masterminds/semver/tree/2.x).
* 1.x.x is the original release. It is no longer maintained. You should use the
  v3 release instead. You can read the documentation for the 1.x.x release
  [here](https://github.com/Masterminds/semver/blob/release-1/README.md).

## Parsing Semantic Versions

There are two functions that can parse semantic versions. The `StrictNewVersion`
function only parses valid version 2 semantic versions as outlined in the
specification. The `NewVersion` function attempts to coerce a version into a
semantic version and parse it. For example, if there is a leading v or a version
listed without all 3 parts (e.g. `v1.2`) it will attempt to coerce it into a valid
semantic version (e.g., 1.2.0). In both cases a `Version` object is returned
that can be sorted, compared, and used in constraints.

When parsing a version an error is returned if there is an issue parsing the
version. For example,

    v, err := semver.NewVersion("1.2.3-beta.1+build345")

The version object has methods to get the parts of the version, compare it to
other versions, convert the version back into a string, and get the original
string. Getting the original string is useful if the semantic version was coerced
into a valid form.

There are package level variables that affect how `NewVersion` handles parsing.

- `CoerceNewVersion` is `true` by default. When set to `true` it coerces non-compliant
  versions into SemVer. For example, allowing a leading 0 in a major, minor, or patch
  part. This enables the use of CalVer in versions even when not compliant with SemVer.
  When set to `false` less coercion work is done.
- `DetailedNewVersionErrors` provides more detailed errors. It only has an affect when
  `CoerceNewVersion` is set to `false`. When `DetailedNewVersionErrors` is set to `true`
  it can provide some more insight into why a version is invalid. Setting
  `DetailedNewVersionErrors` to `false` is faster on performance but provides less
  detailed error messages if a version fails to parse.

## Sorting Semantic Versions

A set of versions can be sorted using the `sort` package from the standard library.
For example,

```go
raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",}
vs := make([]*semver.Version, len(raw))
for i, r := range raw {
    v, err := semver.NewVersion(r)
    if err != nil {
        t.Errorf("Error parsing version: %s", err)
    }

    vs[i] = v
}

sort.Sort(semver.Collection(vs))
```

## Checking Version Constraints

There are two methods for comparing versions. One uses comparison methods on
`Version` instances and the other uses `Constraints`. There are some important
differences to notes between these two methods of comparison.

1. When two versions are compared using functions such as `Compare`, `LessThan`,
   and others it will follow the specification and always include pre-releases
   within the comparison. It will provide an answer that is valid with the
   comparison section of the spec at https://semver.org/#spec-item-11
2. When constraint checking is used for checks or validation it will follow a
   different set of rules that are common for ranges with tools like npm/js
   and Rust/Cargo. This includes considering pre-releases to be invalid if the
   ranges does not include one. If you want to have it include pre-releases a
   simple solution is to include `-0` in your range.
3. Constraint ranges can have some complex rules including the shorthand use of
   ~ and ^. For more details on those see the options below.

There are differences between the two methods or checking versions because the
comparison methods on `Version` follow the specification while comparison ranges
are not part of the specification. Different packages and tools have taken it
upon themselves to come up with range rules. This has resulted in differences.
For example, npm/js and Cargo/Rust follow similar patterns while PHP has a
different pattern for ^. The comparison features in this package follow the
npm/js and Cargo/Rust lead because applications using it have followed similar
patters with their versions.

Checking a version against version constraints is one of the most featureful
parts of the package.

```go
c, err := semver.NewConstraint(">= 1.2.3")
if err != nil {
    // Handle constraint not being parsable.
}

v, err := semver.NewVersion("1.3")
if err != nil {
    // Handle version not being parsable.
}
// Check if the version meets the constraints. The variable a will be true.
a := c.Check(v)
```

### Basic Comparisons

There are two elements to the comparisons. First, a comparison string is a list
of space or comma separated AND comparisons. These are then separated by || (OR)
comparisons. For example, `">= 1.2 < 3.0.0 || >= 4.2.3"` is looking for a
comparison that's greater than or equal to 1.2 and less than 3.0.0 or is
greater than or equal to 4.2.3.

The basic comparisons are:

* `=`: equal (aliased to no operator)
* `!=`: not equal
* `>`: greater than
* `<`: less than
* `>=`: greater than or equal to
* `<=`: less than or equal to

### Working With Prerelease Versions

Pre-releases, for those not familiar with them, are used for software releases
prior to stable or generally available releases. Examples of pre-releases include
development, alpha, beta, and release candidate releases. A pre-release may be
a version such as `1.2.3-beta.1` while the stable release would be `1.2.3`. In the
order of precedence, pre-releases come before their associated releases. In this
example `1.2.3-beta.1 < 1.2.3`.

According to the Semantic Version specification, pre-releases may not be
API compliant with their release counterpart. It says,

> A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version.

SemVer's comparisons using constraints without a pre-release comparator will skip
pre-release versions. For example, `>=1.2.3` will skip pre-releases when looking
at a list of releases while `>=1.2.3-0` will evaluate and find pre-releases.

The reason for the `0` as a pre-release version in the example comparison is
because pre-releases can only contain ASCII alphanumerics and hyphens (along with
`.` separators), per the spec. Sorting happens in ASCII sort order, again per the
spec. The lowest character is a `0` in ASCII sort order
(see an [ASCII Table](http://www.asciitable.com/))

Understanding ASCII sort ordering is important because A-Z comes before a-z. That
means `>=1.2.3-BETA` will return `1.2.3-alpha`. What you might expect from case
sensitivity doesn't apply here. This is due to ASCII sort ordering which is what
the spec specifies.

The `Constraints` instance returned from `semver.NewConstraint()` has a property
`IncludePrerelease` that, when set to true, will return prerelease versions when calls
to `Check()` and `Validate()` are made.

### Hyphen Range Comparisons

There are multiple methods to handle ranges and the first is hyphens ranges.
These look like:

* `1.2 - 1.4.5` which is equivalent to `>= 1.2 <= 1.4.5`
* `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5`

Note that `1.2-1.4.5` without whitespace is parsed completely differently; it's
parsed as a single constraint `1.2.0` with _prerelease_ `1.4.5`.

### Wildcards In Comparisons

The `x`, `X`, and `*` characters can be used as a wildcard character. This works
for all comparison operators. When used on the `=` operator it falls
back to the patch level comparison (see tilde below). For example,

* `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
* `>= 1.2.x` is equivalent to `>= 1.2.0`
* `<= 2.x` is equivalent to `< 3`
* `*` is equivalent to `>= 0.0.0`

### Tilde Range Comparisons (Patch)

The tilde (`~`) comparison operator is for patch level ranges when a minor
version is specified and major level changes when the minor number is missing.
For example,

* `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0`
* `~1` is equivalent to `>= 1, < 2`
* `~2.3` is equivalent to `>= 2.3, < 2.4`
* `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
* `~1.x` is equivalent to `>= 1, < 2`

### Caret Range Comparisons (Major)

The caret (`^`) comparison operator is for major level changes once a stable
(1.0.0) release has occurred. Prior to a 1.0.0 release the minor versions acts
as the API stability level. This is useful when comparisons of API versions as a
major change is API breaking. For example,

* `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0`
* `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0`
* `^2.3` is equivalent to `>= 2.3, < 3`
* `^2.x` is equivalent to `>= 2.0.0, < 3`
* `^0.2.3` is equivalent to `>=0.2.3 <0.3.0`
* `^0.2` is equivalent to `>=0.2.0 <0.3.0`
* `^0.0.3` is equivalent to `>=0.0.3 <0.0.4`
* `^0.0` is equivalent to `>=0.0.0 <0.1.0`
* `^0` is equivalent to `>=0.0.0 <1.0.0`

## Validation

In addition to testing a version against a constraint, a version can be validated
against a constraint. When validation fails a slice of errors containing why a
version didn't meet the constraint is returned. For example,

```go
c, err := semver.NewConstraint("<= 1.2.3, >= 1.4")
if err != nil {
    // Handle constraint not being parseable.
}

v, err := semver.NewVersion("1.3")
if err != nil {
    // Handle version not being parseable.
}

// Validate a version against a constraint.
a, msgs := c.Validate(v)
// a is false
for _, m := range msgs {
    fmt.Println(m)

    // Loops over the errors which would read
    // "1.3 is greater than 1.2.3"
    // "1.3 is less than 1.4"
}
```

## Contribute

If you find an issue or want to contribute please file an [issue](https://github.com/Masterminds/semver/issues)
or [create a pull request](https://github.com/Masterminds/semver/pulls).

## Security

Security is an important consideration for this project. The project currently
uses the following tools to help discover security issues:

* [CodeQL](https://codeql.github.com)
* [gosec](https://github.com/securego/gosec)
* Daily Fuzz testing

If you believe you have found a security vulnerability you can privately disclose
it through the [GitHub security page](https://github.com/Masterminds/semver/security).

---

### Overview (`vendor/github.com/cespare/xxhash/v2/README.md`)

# xxhash

[](https://pkg.go.dev/github.com/cespare/xxhash/v2)
[](https://github.com/cespare/xxhash/actions/workflows/test.yml)

xxhash is a Go implementation of the 64-bit [xxHash] algorithm, XXH64. This is a
high-quality hashing algorithm that is much faster than anything in the Go
standard library.

This package provides a straightforward API:

```
func Sum64(b []byte) uint64
func Sum64String(s string) uint64
type Digest struct{ ... }
    func New() *Digest
```

The `Digest` type implements hash.Hash64. Its key methods are:

```
func (*Digest) Write([]byte) (int, error)
func (*Digest) WriteString(string) (int, error)
func (*Digest) Sum64() uint64
```

The package is written with optimized pure Go and also contains even faster
assembly implementations for amd64 and arm64. If desired, the `purego` build tag
opts into using the Go code even on those architectures.

[xxHash]: http://cyan4973.github.io/xxHash/

## Compatibility

This package is in a module and the latest code is in version 2 of the module.
You need a version of Go with at least "minimal module compatibility" to use
github.com/cespare/xxhash/v2:

* 1.9.7+ for Go 1.9
* 1.10.3+ for Go 1.10
* Go 1.11 or later

I recommend using the latest release of Go.

## Benchmarks

Here are some quick benchmarks comparing the pure-Go and assembly
implementations of Sum64.

| input size | purego    | asm       |
| ---------- | --------- | --------- |
| 4 B        |  1.3 GB/s |  1.2 GB/s |
| 16 B       |  2.9 GB/s |  3.5 GB/s |
| 100 B      |  6.9 GB/s |  8.1 GB/s |
| 4 KB       | 11.7 GB/s | 16.7 GB/s |
| 10 MB      | 12.0 GB/s | 17.3 GB/s |

These numbers were generated on Ubuntu 20.04 with an Intel Xeon Platinum 8252C
CPU using the following commands under Go 1.19.2:

```
benchstat <(go test -tags purego -benchtime 500ms -count 15 -bench 'Sum64$')
benchstat <(go test -benchtime 500ms -count 15 -bench 'Sum64$')
```

## Projects using this package

- [InfluxDB](https://github.com/influxdata/influxdb)
- [Prometheus](https://github.com/prometheus/prometheus)
- [VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics)
- [FreeCache](https://github.com/coocood/freecache)
- [FastCache](https://github.com/VictoriaMetrics/fastcache)
- [Ristretto](https://github.com/dgraph-io/ristretto)
- [Badger](https://github.com/dgraph-io/badger)

---

### Overview (`vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/README.md`)

## `pathrs-lite` ##

`github.com/cyphar/filepath-securejoin/pathrs-lite` provides a minimal **pure
Go** implementation of the core bits of [libpathrs][]. This is not intended to
be a complete replacement for libpathrs, instead it is mainly intended to be
useful as a transition tool for existing Go projects.

`pathrs-lite` also provides a very easy way to switch to `libpathrs` (even for
downstreams where `pathrs-lite` is being used in a third-party package and is
not interested in using CGo). At build time, if you use the `libpathrs` build
tag then `pathrs-lite` will use `libpathrs` directly instead of the pure Go
implementation. The two backends are functionally equivalent (and we have
integration tests to verify this), so this migration should be very easy with
no user-visible impact.

[libpathrs]: https://github.com/cyphar/libpathrs

### License ###

Most of this subpackage is licensed under the Mozilla Public License (version
2.0). For more information, see the top-level [COPYING.md][] and
[LICENSE.MPL-2.0][] files, as well as the individual license headers for each
file.

```
Copyright (C) 2024-2025 Aleksa Sarai <cyphar@cyphar.com>
Copyright (C) 2024-2025 SUSE LLC

This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
```

[COPYING.md]: ../COPYING.md
[LICENSE.MPL-2.0]: ../LICENSE.MPL-2.0

---

### Overview (`vendor/github.com/go-jose/go-jose/v4/README.md`)

# Go JOSE

[](https://pkg.go.dev/github.com/go-jose/go-jose/v4)
[](https://pkg.go.dev/github.com/go-jose/go-jose/v4/jwt)
[](https://raw.githubusercontent.com/go-jose/go-jose/master/LICENSE)

Package jose aims to provide an implementation of the Javascript Object Signing
and Encryption set of standards. This includes support for JSON Web Encryption,
JSON Web Signature, and JSON Web Token standards.

## Overview

The implementation follows the
[JSON Web Encryption](https://dx.doi.org/10.17487/RFC7516) (RFC 7516),
[JSON Web Signature](https://dx.doi.org/10.17487/RFC7515) (RFC 7515), and
[JSON Web Token](https://dx.doi.org/10.17487/RFC7519) (RFC 7519) specifications.
Tables of supported algorithms are shown below. The library supports both
the compact and JWS/JWE JSON Serialization formats, and has optional support for
multiple recipients. It also comes with a small command-line utility
([`jose-util`](https://pkg.go.dev/github.com/go-jose/go-jose/jose-util))
for dealing with JOSE messages in a shell.

**Note**: We use a forked version of the `encoding/json` package from the Go
standard library which uses case-sensitive matching for member names (instead
of [case-insensitive matching](https://www.ietf.org/mail-archive/web/json/current/msg03763.html)).
This is to avoid differences in interpretation of messages between go-jose and
libraries in other languages.

### Versions

The forthcoming Version 5 will be released with several breaking API changes,
and will require Golang's `encoding/json/v2`, which is currently requires 
Go 1.25 built with GOEXPERIMENT=jsonv2.

Version 4 is the current stable version:

    import "github.com/go-jose/go-jose/v4"

It supports at least the current and previous Golang release. Currently it
requires Golang 1.24.

Version 3 is only receiving critical security updates. Migration to Version 4 is recommended.

Versions 1 and 2 are obsolete, but can be found in the old repository, [square/go-jose](https://github.com/square/go-jose).

### Supported algorithms

See below for a table of supported algorithms. Algorithm identifiers match
the names in the [JSON Web Algorithms](https://dx.doi.org/10.17487/RFC7518)
standard where possible. The Godoc reference has a list of constants.

| Key encryption         | Algorithm identifier(s)                        |
|:-----------------------|:-----------------------------------------------|
| RSA-PKCS#1v1.5         | RSA1_5                                         |
| RSA-OAEP               | RSA-OAEP, RSA-OAEP-256                         |
| AES key wrap           | A128KW, A192KW, A256KW                         |
| AES-GCM key wrap       | A128GCMKW, A192GCMKW, A256GCMKW                |
| ECDH-ES + AES key wrap | ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW |
| ECDH-ES (direct)       | ECDH-ES<sup>1</sup>                            |
| Direct encryption      | dir<sup>1</sup>                                |

<sup>1. Not supported in multi-recipient mode</sup>

| Signing / MAC     | Algorithm identifier(s) |
|:------------------|:------------------------|
| RSASSA-PKCS#1v1.5 | RS256, RS384, RS512     |
| RSASSA-PSS        | PS256, PS384, PS512     |
| HMAC              | HS256, HS384, HS512     |
| ECDSA             | ES256, ES384, ES512     |
| Ed25519           | EdDSA<sup>2</sup>       |

<sup>2. Only available in version 2 of the package</sup>

| Content encryption | Algorithm identifier(s)                     |
|:-------------------|:--------------------------------------------|
| AES-CBC+HMAC       | A128CBC-HS256, A192CBC-HS384, A256CBC-HS512 |
| AES-GCM            | A128GCM, A192GCM, A256GCM                   |

| Compression        | Algorithm identifiers(s) |
|:-------------------|--------------------------|
| DEFLATE (RFC 1951) | DEF                      |

### Supported key types

See below for a table of supported key types. These are understood by the
library, and can be passed to corresponding functions such as `NewEncrypter` or
`NewSigner`. Each of these keys can also be wrapped in a JWK if desired, which
allows attaching a key id.

| Algorithm(s)      | Corresponding types                                                                                                                  |
|:------------------|--------------------------------------------------------------------------------------------------------------------------------------|
| RSA               | *[rsa.PublicKey](https://pkg.go.dev/crypto/rsa/#PublicKey), *[rsa.PrivateKey](https://pkg.go.dev/crypto/rsa/#PrivateKey)             |
| ECDH, ECDSA       | *[ecdsa.PublicKey](https://pkg.go.dev/crypto/ecdsa/#PublicKey), *[ecdsa.PrivateKey](https://pkg.go.dev/crypto/ecdsa/#PrivateKey)     |
| EdDSA<sup>1</sup> | [ed25519.PublicKey](https://pkg.go.dev/crypto/ed25519#PublicKey), [ed25519.PrivateKey](https://pkg.go.dev/crypto/ed25519#PrivateKey) |
| AES, HMAC         | []byte                                                                                                                               |

<sup>1. Only available in version 2 or later of the package</sup>

## Examples

[](https://pkg.go.dev/github.com/go-jose/go-jose/v4)
[](https://pkg.go.dev/github.com/go-jose/go-jose/v4/jwt)

Examples can be found in the Godoc
reference for this package. The
[`jose-util`](https://github.com/go-jose/go-jose/tree/main/jose-util)
subdirectory also contains a small command-line utility which might be useful
as an example as well.

---

### Overview (`vendor/github.com/klauspost/compress/fse/README.md`)

# Finite State Entropy

This package provides Finite State Entropy encoding and decoding.
            
Finite State Entropy (also referenced as [tANS](https://en.wikipedia.org/wiki/Asymmetric_numeral_systems#tANS)) 
encoding provides a fast near-optimal symbol encoding/decoding
for byte blocks as implemented in [zstandard](https://github.com/facebook/zstd).

This can be used for compressing input with a lot of similar input values to the smallest number of bytes.
This does not perform any multi-byte [dictionary coding](https://en.wikipedia.org/wiki/Dictionary_coder) as LZ coders,
but it can be used as a secondary step to compressors (like Snappy) that does not do entropy encoding. 

* [Godoc documentation](https://godoc.org/github.com/klauspost/compress/fse)

## News

 * Feb 2018: First implementation released. Consider this beta software for now.

# Usage

This package provides a low level interface that allows to compress single independent blocks. 

Each block is separate, and there is no built in integrity checks. 
This means that the caller should keep track of block sizes and also do checksums if needed.  

Compressing a block is done via the [`Compress`](https://godoc.org/github.com/klauspost/compress/fse#Compress) function.
You must provide input and will receive the output and maybe an error.

These error values can be returned:

| Error               | Description                                                                 |
|---------------------|-----------------------------------------------------------------------------|
| `<nil>`             | Everything ok, output is returned                                           |
| `ErrIncompressible` | Returned when input is judged to be too hard to compress                    |
| `ErrUseRLE`         | Returned from the compressor when the input is a single byte value repeated |
| `(error)`           | An internal error occurred.                                                 |

As can be seen above there are errors that will be returned even under normal operation so it is important to handle these.

To reduce allocations you can provide a [`Scratch`](https://godoc.org/github.com/klauspost/compress/fse#Scratch) object 
that can be re-used for successive calls. Both compression and decompression accepts a `Scratch` object, and the same 
object can be used for both.   

Be aware, that when re-using a `Scratch` object that the *output* buffer is also re-used, so if you are still using this
you must set the `Out` field in the scratch to nil. The same buffer is used for compression and decompression output.

Decompressing is done by calling the [`Decompress`](https://godoc.org/github.com/klauspost/compress/fse#Decompress) function.
You must provide the output from the compression stage, at exactly the size you got back. If you receive an error back
your input was likely corrupted. 

It is important to note that a successful decoding does *not* mean your output matches your original input. 
There are no integrity checks, so relying on errors from the decompressor does not assure your data is valid.

For more detailed usage, see examples in the [godoc documentation](https://godoc.org/github.com/klauspost/compress/fse#pkg-examples).

# Performance

A lot of factors are affecting speed. Block sizes and compressibility of the material are primary factors.  
All compression functions are currently only running on the calling goroutine so only one core will be used per block.  

The compressor is significantly faster if symbols are kept as small as possible. The highest byte value of the input
is used to reduce some of the processing, so if all your input is above byte value 64 for instance, it may be 
beneficial to transpose all your input values down by 64.   

With moderate block sizes around 64k speed are typically 200MB/s per core for compression and 
around 300MB/s decompression speed. 

The same hardware typically does Huffman (deflate) encoding at 125MB/s and decompression at 100MB/s. 

# Plans

At one point, more internals will be exposed to facilitate more "expert" usage of the components. 

A streaming interface is also likely to be implemented. Likely compatible with [FSE stream format](https://github.com/Cyan4973/FiniteStateEntropy/blob/dev/programs/fileio.c#L261).  

# Contributing

Contributions are always welcome. Be aware that adding public functions will require good justification and breaking 
changes will likely not be accepted. If in doubt open an issue before writing the PR.

---

### Overview (`vendor/github.com/klauspost/compress/huff0/README.md`)

# Huff0 entropy compression

This package provides Huff0 encoding and decoding as used in zstd.
            
[Huff0](https://github.com/Cyan4973/FiniteStateEntropy#new-generation-entropy-coders), 
a Huffman codec designed for modern CPU, featuring OoO (Out of Order) operations on multiple ALU 
(Arithmetic Logic Unit), achieving extremely fast compression and decompression speeds.

This can be used for compressing input with a lot of similar input values to the smallest number of bytes.
This does not perform any multi-byte [dictionary coding](https://en.wikipedia.org/wiki/Dictionary_coder) as LZ coders,
but it can be used as a secondary step to compressors (like Snappy) that does not do entropy encoding. 

* [Godoc documentation](https://godoc.org/github.com/klauspost/compress/huff0)

## News

This is used as part of the [zstandard](https://github.com/klauspost/compress/tree/master/zstd#zstd) compression and decompression package.

This ensures that most functionality is well tested.

# Usage

This package provides a low level interface that allows to compress single independent blocks. 

Each block is separate, and there is no built in integrity checks. 
This means that the caller should keep track of block sizes and also do checksums if needed.  

Compressing a block is done via the [`Compress1X`](https://godoc.org/github.com/klauspost/compress/huff0#Compress1X) and 
[`Compress4X`](https://godoc.org/github.com/klauspost/compress/huff0#Compress4X) functions.
You must provide input and will receive the output and maybe an error.

These error values can be returned:

| Error               | Description                                                                 |
|---------------------|-----------------------------------------------------------------------------|
| `<nil>`             | Everything ok, output is returned                                           |
| `ErrIncompressible` | Returned when input is judged to be too hard to compress                    |
| `ErrUseRLE`         | Returned from the compressor when the input is a single byte value repeated |
| `ErrTooBig`         | Returned if the input block exceeds the maximum allowed size (128 Kib)      |
| `(error)`           | An internal error occurred.                                                 |


As can be seen above some of there are errors that will be returned even under normal operation so it is important to handle these.

To reduce allocations you can provide a [`Scratch`](https://godoc.org/github.com/klauspost/compress/huff0#Scratch) object 
that can be re-used for successive calls. Both compression and decompression accepts a `Scratch` object, and the same 
object can be used for both.   

Be aware, that when re-using a `Scratch` object that the *output* buffer is also re-used, so if you are still using this
you must set the `Out` field in the scratch to nil. The same buffer is used for compression and decompression output.

The `Scratch` object will retain state that allows to re-use previous tables for encoding and decoding.  

## Tables and re-use

Huff0 allows for reusing tables from the previous block to save space if that is expected to give better/faster results. 

The Scratch object allows you to set a [`ReusePolicy`](https://godoc.org/github.com/klauspost/compress/huff0#ReusePolicy) 
that controls this behaviour. See the documentation for details. This can be altered between each block.

Do however note that this information is *not* stored in the output block and it is up to the users of the package to
record whether [`ReadTable`](https://godoc.org/github.com/klauspost/compress/huff0#ReadTable) should be called,
based on the boolean reported back from the CompressXX call. 

If you want to store the table separate from the data, you can access them as `OutData` and `OutTable` on the 
[`Scratch`](https://godoc.org/github.com/klauspost/compress/huff0#Scratch) object.

## Decompressing

The first part of decoding is to initialize the decoding table through [`ReadTable`](https://godoc.org/github.com/klauspost/compress/huff0#ReadTable).
This will initialize the decoding tables. 
You can supply the complete block to `ReadTable` and it will return the data part of the block 
which can be given to the decompressor. 

Decompressing is done by calling the [`Decompress1X`](https://godoc.org/github.com/klauspost/compress/huff0#Scratch.Decompress1X) 
or [`Decompress4X`](https://godoc.org/github.com/klauspost/compress/huff0#Scratch.Decompress4X) function.

For concurrently decompressing content with a fixed table a stateless [`Decoder`](https://godoc.org/github.com/klauspost/compress/huff0#Decoder) can be requested which will remain correct as long as the scratch is unchanged. The capacity of the provided slice indicates the expected output size.

You must provide the output from the compression stage, at exactly the size you got back. If you receive an error back
your input was likely corrupted. 

It is important to note that a successful decoding does *not* mean your output matches your original input. 
There are no integrity checks, so relying on errors from the decompressor does not assure your data is valid.

# Contributing

Contributions are always welcome. Be aware that adding public functions will require good justification and breaking 
changes will likely not be accepted. If in doubt open an issue before writing the PR.

---

### Overview (`vendor/github.com/klauspost/compress/zstd/README.md`)

# zstd 

[Zstandard](https://facebook.github.io/zstd/) is a real-time compression algorithm, providing high compression ratios. 
It offers a very wide range of compression / speed trade-off, while being backed by a very fast decoder.
A high performance compression algorithm is implemented. For now focused on speed. 

This package provides [compression](#Compressor) to and [decompression](#Decompressor) of Zstandard content. 

This package is pure Go. Use `noasm` and `nounsafe` to disable relevant features.

The `zstd` package is provided as open source software using a Go standard license.

Currently the package is heavily optimized for 64 bit processors and will be significantly slower on 32 bit processors.

For seekable zstd streams, see [this excellent package](https://github.com/SaveTheRbtz/zstd-seekable-format-go).

## Installation

Install using `go get -u github.com/klauspost/compress`. The package is located in `github.com/klauspost/compress/zstd`.

[](https://pkg.go.dev/github.com/klauspost/compress/zstd)

## Compressor

### Status: 

STABLE - there may always be subtle bugs, a wide variety of content has been tested and the library is actively 
used by several projects. This library is being [fuzz-tested](https://github.com/klauspost/compress-fuzz) for all updates.

There may still be specific combinations of data types/size/settings that could lead to edge cases, 
so as always, testing is recommended.  

For now, a high speed (fastest) and medium-fast (default) compressor has been implemented. 

* The "Fastest" compression ratio is roughly equivalent to zstd level 1. 
* The "Default" compression ratio is roughly equivalent to zstd level 3 (default).
* The "Better" compression ratio is roughly equivalent to zstd level 7.
* The "Best" compression ratio is roughly equivalent to zstd level 11.

In terms of speed, it is typically 2x as fast as the stdlib deflate/gzip in its fastest mode. 
The compression ratio compared to stdlib is around level 3, but usually 3x as fast.

 
### Usage

An Encoder can be used for either compressing a stream via the
`io.WriteCloser` interface supported by the Encoder or as multiple independent
tasks via the `EncodeAll` function.
Smaller encodes are encouraged to use the EncodeAll function.
Use `NewWriter` to create a new instance that can be used for both.

To create a writer with default options, do like this:

```Go
// Compress input to output.
func Compress(in io.Reader, out io.Writer) error {
    enc, err := zstd.NewWriter(out)
    if err != nil {
        return err
    }
    _, err = io.Copy(enc, in)
    if err != nil {
        enc.Close()
        return err
    }
    return enc.Close()
}
```

Now you can encode by writing data to `enc`. The output will be finished writing when `Close()` is called.
Even if your encode fails, you should still call `Close()` to release any resources that may be held up.  

The above is fine for big encodes. However, whenever possible try to *reuse* the writer.

To reuse the encoder, you can use the `Reset(io.Writer)` function to change to another output. 
This will allow the encoder to reuse all resources and avoid wasteful allocations. 

By default, stream encoding has 'light' concurrency, meaning up to 2 goroutines can be working on part
of a stream. This is independent of the `WithEncoderConcurrency(n)`, but that is likely to change
in the future. So if you want to limit concurrency for future updates, specify the concurrency
you would like.

If you would like stream encoding to be done without spawning async goroutines, use `WithEncoderConcurrency(1)`
which will compress input as each block is completed, blocking on writes until each has completed.

#### Parallel Stream Compression

For maximum throughput on large streams, use `WithConcurrentBlocks(true)` together with
`WithEncoderConcurrency(n)` where n is the number of CPU cores you want to use.
This splits the input into large sections (jobs) that are compressed simultaneously by multiple goroutines,
similar to how the C zstd library does multithreaded compression.

```Go
enc, err := zstd.NewWriter(out,
    zstd.WithEncoderLevel(zstd.SpeedDefault),
    zstd.WithEncoderConcurrency(runtime.GOMAXPROCS(0)),
    zstd.WithConcurrentBlocks(true),
)
```

Each non-first job receives an overlap prefix from the previous job for match context,
so compression ratio is only marginally affected. Output is flushed in order,
producing a valid single-frame zstd stream.

Benchmark on 1.8GB GOB stream (AMD Ryzen 9 9950X):

| Level   |  1 thread  |     4 threads      |     16 threads      | 1T ratio | 16T ratio |
|---------|:----------:|:------------------:|:-------------------:|:--------:|:---------:|
| fastest | 783 MB/s   | 2950 MB/s (3.8×)   | 6939 MB/s (8.9×)    | 12.24%   | 12.26%    |
| default | 728 MB/s   | 2533 MB/s (3.5×)   | 5340 MB/s (7.3×)    | 10.67%   | 10.68%    |
| better  | 434 MB/s   | 1105 MB/s (2.5×)   | 2206 MB/s (5.1×)    | 9.14%    | 9.21%     |
| best    | 129 MB/s   | 367 MB/s (2.8×)    | 884 MB/s (6.8×)     | 8.48%    | 8.63%     |

Notes:
* Not compatible with dictionary encoding.
* `Flush()` dispatches the current partial job, so latency-sensitive callers can force output.
* `EncodeAll` is unaffected — it uses its own concurrency via the encoder pool.

You can specify your desired compression level using `WithEncoderLevel()` option. Currently only pre-defined 
compression settings can be specified.

#### Future Compatibility Guarantees

This will be an evolving project. When using this package it is important to note that both the compression efficiency and speed may change.

The goal will be to keep the default efficiency at the default zstd (level 3). 
However the encoding should never be assumed to remain the same, 
and you should not use hashes of compressed output for similarity checks.

The Encoder can be assumed to produce the same output from the exact same code version.
However, the may be modes in the future that break this, 
although they will not be enabled without an explicit option.   

This encoder is not designed to (and will probably never) output the exact same bitstream as the reference encoder.

Also note, that the cgo decompressor currently does not [report all errors on invalid input](https://github.com/DataDog/zstd/issues/59),
[omits error checks](https://github.com/DataDog/zstd/issues/61), [ignores checksums](https://github.com/DataDog/zstd/issues/43) 
and seems to ignore concatenated streams, even though [it is part of the spec](https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#frames).

#### Blocks

For compressing small blocks, the returned encoder has a function called `EncodeAll(src, dst []byte) []byte`.

`EncodeAll` will encode all input in src and append it to dst.
This function can be called concurrently. 
Each call will only run on a same goroutine as the caller.

Encoded blocks can be concatenated and the result will be the combined input stream.
Data compressed with EncodeAll can be decoded with the Decoder, using either a stream or `DecodeAll`.

Especially when encoding blocks you should take special care to reuse the encoder. 
This will effectively make it run without allocations after a warmup period. 
To make it run completely without allocations, supply a destination buffer with space for all content.   

```Go
import "github.com/klauspost/compress/zstd"

// Create a writer that caches compressors.
// For this operation type we supply a nil Reader.
var encoder, _ = zstd.NewWriter(nil)

// Compress a buffer. 
// If you have a destination buffer, the allocation in the call can also be eliminated.
func Compress(src []byte) []byte {
    return encoder.EncodeAll(src, make([]byte, 0, len(src)))
} 
```

You can control the maximum number of concurrent encodes using the `WithEncoderConcurrency(n)` 
option when creating the writer.

Using the Encoder for both a stream and individual blocks concurrently is safe. 

### Performance

I have collected some speed examples to compare speed and compression against other compressors.

* `file` is the input file.
* `out` is the compressor used. `zskp` is this package. `zstd` is the Datadog cgo library. `gzstd/gzkp` is gzip standard and this library.
* `level` is the compression level used. For `zskp` level 1 is "fastest", level 2 is "default"; 3 is "better", 4 is "best".
* `insize`/`outsize` is the input/output size.
* `millis` is the number of milliseconds used for compression.
* `mb/s` is megabytes (2^20 bytes) per second.

```
/* Detailed source-code truncated for AI context efficiency. */
```

## Decompressor

Status: STABLE - there may still be subtle bugs, but a wide variety of content has been tested.

This library is being continuously [fuzz-tested](https://github.com/klauspost/compress-fuzz),
kindly supplied by [fuzzit.dev](https://fuzzit.dev/). 
The main purpose of the fuzz testing is to ensure that it is not possible to crash the decoder, 
or run it past its limits with ANY input provided.  
 
### Usage

The package has been designed for two main usages, big streams of data and smaller in-memory buffers. 
There are two main usages of the package for these. Both of them are accessed by creating a `Decoder`.

For streaming use a simple setup could look like this:

```Go
import "github.com/klauspost/compress/zstd"

func Decompress(in io.Reader, out io.Writer) error {
    d, err := zstd.NewReader(in)
    if err != nil {
        return err
    }
    defer d.Close()
    
    // Copy content...
    _, err = io.Copy(out, d)
    return err
}
```

It is important to use the "Close" function when you no longer need the Reader to stop running goroutines, 
when running with default settings.
Goroutines will exit once an error has been returned, including `io.EOF` at the end of a stream.

Streams are decoded concurrently in 4 asynchronous stages to give the best possible throughput.
However, if you prefer synchronous decompression, use `WithDecoderConcurrency(1)` which will decompress data 
as it is being requested only.

For decoding buffers, it could look something like this:

```Go
import "github.com/klauspost/compress/zstd"

// Create a reader that caches decompressors.
// For this operation type we supply a nil Reader.
var decoder, _ = zstd.NewReader(nil, zstd.WithDecoderConcurrency(0))

// Decompress a buffer. We don't supply a destination buffer,
// so it will be allocated by the decoder.
func Decompress(src []byte) ([]byte, error) {
    return decoder.DecodeAll(src, nil)
} 
```

Both of these cases should provide the functionality needed. 
The decoder can be used for *concurrent* decompression of multiple buffers.
By default 4 decompressors will be created. 

It will only allow a certain number of concurrent operations to run. 
To tweak that yourself use the `WithDecoderConcurrency(n)` option when creating the decoder.
It is possible to use `WithDecoderConcurrency(0)` to create GOMAXPROCS decoders.

### Dictionaries

Data compressed with [dictionaries](https://github.com/facebook/zstd#the-case-for-small-data-compression) can be decompressed.

Dictionaries are added individually to Decoders.
Dictionaries are generated by the `zstd --train` command and contains an initial state for the decoder.
To add a dictionary use the `WithDecoderDicts(dicts ...[]byte)` option with the dictionary data.
Several dictionaries can be added at once.

The dictionary will be used automatically for the data that specifies them.
A re-used Decoder will still contain the dictionaries registered.

When registering multiple dictionaries with the same ID, the last one will be used.

It is possible to use dictionaries when compressing data.

To enable a dictionary use `WithEncoderDict(dict []byte)`. Here only one dictionary will be used 
and it will likely be used even if it doesn't improve compression. 

The used dictionary must be used to decompress the content.

For any real gains, the dictionary should be built with similar data. 
If an unsuitable dictionary is used the output may be slightly larger than using no dictionary.
Use the [zstd commandline tool](https://github.com/facebook/zstd/releases) to build a dictionary from sample data.
For information see [zstd dictionary information](https://github.com/facebook/zstd#the-case-for-small-data-compression). 

For now there is a fixed startup performance penalty for compressing content with dictionaries. 
This will likely be improved over time. Just be aware to test performance when implementing.  

### Allocation-less operation

The decoder has been designed to operate without allocations after a warmup. 

This means that you should *store* the decoder for best performance. 
To re-use a stream decoder, use the `Reset(r io.Reader) error` to switch to another stream.
A decoder can safely be re-used even if the previous stream failed.

To release the resources, you must call the `Close()` function on a decoder.
After this it can *no longer be reused*, but all running goroutines will be stopped.
So you *must* use this if you will no longer need the Reader.

For decompressing smaller buffers a single decoder can be used.
When decoding buffers, you can supply a destination slice with length 0 and your expected capacity.
In this case no unneeded allocations should be made. 

### Concurrency

The buffer decoder does everything on the same goroutine and does nothing concurrently.
It can however decode several buffers concurrently. Use `WithDecoderConcurrency(n)` to limit that.

The stream decoder will create goroutines that:

1) Reads input and splits the input into blocks.
2) Decompression of literals.
3) Decompression of sequences.
4) Reconstruction of output stream.

So effectively this also means the decoder will "read ahead" and prepare data to always be available for output.

The concurrency level will, for streams, determine how many blocks ahead the compression will start.

Since "blocks" are quite dependent on the output of the previous block stream decoding will only have limited concurrency.

In practice this means that concurrency is often limited to utilizing about 3 cores effectively.
  
### Benchmarks

The first two are streaming decodes and the last are smaller inputs. 

Running on AMD Ryzen 9 3950X 16-Core Processor. AMD64 assembly used.

```
/* Detailed source-code truncated for AI context efficiency. */
```

This reflects the performance around May 2022, but this may be out of date.

## Zstd inside ZIP files

It is possible to use zstandard to compress individual files inside zip archives.
While this isn't widely supported it can be useful for internal files.

To support the compression and decompression of these files you must register a compressor and decompressor.

It is highly recommended registering the (de)compressors on individual zip Reader/Writer and NOT
use the global registration functions. The main reason for this is that 2 registrations from 
different packages will result in a panic.

It is a good idea to only have a single compressor and decompressor, since they can be used for multiple zip
files concurrently, and using a single instance will allow reusing some resources.

See [this example](https://pkg.go.dev/github.com/klauspost/compress/zstd#example-ZipCompressor) for 
how to compress and decompress files inside zip archives.

# Contributions

Contributions are always welcome. 
For new features/fixes, remember to add tests and for performance enhancements include benchmarks.

For general feedback and experience reports, feel free to open an issue or write me on [Twitter](https://twitter.com/sh0dan).

This package includes the excellent [`github.com/cespare/xxhash`](https://github.com/cespare/xxhash) package Copyright (c) 2016 Caleb Spare.

---

### Overview (`vendor/github.com/mistifyio/go-zfs/v4/README.md`)

# Go Wrapper for ZFS

Simple wrappers for ZFS command line tools.

[](https://godoc.org/github.com/mistifyio/go-zfs)

## Requirements

You need a working ZFS setup. To use on Ubuntu 14.04, setup ZFS:

    sudo apt-get install python-software-properties
    sudo apt-add-repository ppa:zfs-native/stable
    sudo apt-get update
    sudo apt-get install ubuntu-zfs libzfs-dev

Developed using Go 1.3, but currently there isn't anything 1.3 specific. Don't use Ubuntu packages for Go, use http://golang.org/doc/install

Generally you need root privileges to use anything zfs related.

## Status

This has been only been tested on Ubuntu 14.04

In the future, we hope to work directly with libzfs.

# Hacking

The tests have decent examples for most functions.

```go
//assuming a zpool named test
//error handling omitted


f, err := zfs.CreateFilesystem("test/snapshot-test", nil)
ok(t, err)

s, err := f.Snapshot("test", nil)
ok(t, err)

// snapshot is named "test/snapshot-test@test"

c, err := s.Clone("test/clone-test", nil)

err := c.Destroy()
err := s.Destroy()
err := f.Destroy()

```

# Contributing

See the [contributing guidelines](./CONTRIBUTING.md)

---

### Overview (`vendor/github.com/moby/moby/client/README.md`)

# Go client for the Docker Engine API

[](https://pkg.go.dev/github.com/moby/moby/client)

[](https://scorecard.dev/viewer/?uri=github.com/moby/moby)
[](https://www.bestpractices.dev/projects/10989)

The `docker` command uses this package to communicate with the daemon. It can
also be used by your own Go applications to do anything the command-line
interface does; running containers, pulling or pushing images, etc.

For example, to list all containers (the equivalent of `docker ps --all`):

```go
package main

import (
	"context"
	"fmt"

	"github.com/moby/moby/client"
)

func main() {
	// Create a new client with "client.FromEnv" (configuring the client
	// from commonly used environment variables such as DOCKER_HOST and
	// DOCKER_API_VERSION) and set a custom User-Agent.
	//
	// API-version negotiation is enabled by default to allow downgrading
	// the API version when connecting with an older daemon version.
	apiClient, err := client.New(
		client.FromEnv,
		client.WithUserAgent("my-application/1.0.0"),
	)
	if err != nil {
		panic(err)
	}
	defer apiClient.Close()

	// List all containers (both stopped and running).
	result, err := apiClient.ContainerList(context.Background(), client.ContainerListOptions{
		All: true,
	})
	if err != nil {
		panic(err)
	}

	// Print each container's ID, status and the image it was created from.
	fmt.Printf("%s  %-22s  %s\n", "ID", "STATUS", "IMAGE")
	for _, ctr := range result.Items {
		fmt.Printf("%s  %-22s  %s\n", ctr.ID, ctr.Status, ctr.Image)
	}
}
```

Full documentation is available on [pkg.go.dev](https://pkg.go.dev/github.com/moby/moby/client).

---

### Overview (`vendor/github.com/moby/sys/capability/README.md`)

This is a fork of (apparently no longer maintained)
https://github.com/syndtr/gocapability package. It provides basic primitives to
work with [Linux capabilities][capabilities(7)].

For changes, see [CHANGELOG.md](./CHANGELOG.md).

[](https://pkg.go.dev/github.com/moby/sys/capability)

## Alternatives

 * https://pkg.go.dev/kernel.org/pub/linux/libs/security/libcap/cap

[capabilities(7)]: https://man7.org/linux/man-pages/man7/capabilities.7.html

---

### Overview (`vendor/github.com/santhosh-tekuri/jsonschema/v6/README.md`)

# jsonschema v6.0.2

[](https://opensource.org/licenses/Apache-2.0)
[](https://pkg.go.dev/github.com/santhosh-tekuri/jsonschema/v6)
[](https://goreportcard.com/report/github.com/santhosh-tekuri/jsonschema/v6)
[](https://github.com/santhosh-tekuri/jsonschema/actions/workflows/go.yaml)
[](https://codecov.io/gh/santhosh-tekuri/jsonschema/tree/boon)

see [godoc](https://pkg.go.dev/github.com/santhosh-tekuri/jsonschema/v6) for examples

## Library Features

- [x] pass [JSON-Schema-Test-Suite](https://github.com/json-schema-org/JSON-Schema-Test-Suite) excluding optional(compare with other impls at [bowtie](https://bowtie-json-schema.github.io/bowtie/#))
  - [x] [](https://bowtie.report/#/dialects/draft4)
  - [x] [](https://bowtie.report/#/dialects/draft6)
  - [x] [](https://bowtie.report/#/dialects/draft7)
  - [x] [](https://bowtie.report/#/dialects/draft2019-09)
  - [x] [](https://bowtie.report/#/dialects/draft2020-12)
- [x] detect infinite loop traps
  - [x] `$schema` cycle
  - [x] validation cycle
- [x] custom `$schema` url
- [x] vocabulary based validation
- [x] custom regex engine
- [x] format assertions
  - [x] flag to enable in draft >= 2019-09
  - [x] custom format registration
  - [x] built-in formats
    - [x] regex, uuid
    - [x] ipv4, ipv6
    - [x] hostname, email
    - [x] date, time, date-time, duration
    - [x] json-pointer, relative-json-pointer
    - [x] uri, uri-reference, uri-template
    - [x] iri, iri-reference
    - [x] period, semver
- [x] content assertions
  - [x] flag to enable in draft >= 7
  - [x] contentEncoding
    - [x] base64
    - [x] custom
  - [x] contentMediaType
    - [x] application/json
    - [x] custom
  - [x] contentSchema
- [x] errors
  - [x] introspectable
  - [x] hierarchy
    - [x] alternative display with `#`
  - [x] output
    - [x] flag
    - [x] basic
    - [x] detailed
- [x] custom vocabulary
    - enable via `$vocabulary` for draft >=2019-19
    - enable via flag for draft <= 7
- [x] mixed dialect support

## CLI v0.7.0

to install: `go install github.com/santhosh-tekuri/jsonschema/cmd/jv@latest`

Note that the cli is versioned independently. you can see it in git tags `cmd/jv/v0.7.0`

```
Usage: jv [OPTIONS] SCHEMA [INSTANCE...]

Options:
  -c, --assert-content    Enable content assertions with draft >= 7
  -f, --assert-format     Enable format assertions with draft >= 2019
      --cacert pem-file   Use the specified pem-file to verify the peer. The file may contain multiple CA certificates
  -d, --draft version     Draft version used when '$schema' is missing. Valid values 4, 6, 7, 2019, 2020 (default 2020)
  -h, --help              Print help information
  -k, --insecure          Use insecure TLS connection
  -o, --output format     Output format. Valid values simple, alt, flag, basic, detailed (default "simple")
  -q, --quiet             Do not print errors
  -v, --version           Print build information
```

- [x] exit code `1` for validation errors, `2` for usage errors
- [x] validate both schema and multiple instances
- [x] support both json and yaml files
- [x] support standard input, use `-`
- [x] quite mode with parsable output
- [x] http(s) url support
  - [x] custom certs for validation, use `--cacert`
  - [x] flag to skip certificate verification, use `--insecure`

---

### Overview (`vendor/github.com/vbauerster/mpb/v8/README.md`)

# Multi Progress Bar

[](https://pkg.go.dev/github.com/vbauerster/mpb/v8)
[](https://github.com/vbauerster/mpb/actions/workflows/test.yml)
[](https://github.com/vbauerster/mpb/actions/workflows/golangci-lint.yml)

**mpb** is a Go lib for rendering progress bars in terminal applications.

## Features

- **Multiple Bars**: Multiple progress bars are supported
- **Dynamic Total**: Set total while bar is running
- **Dynamic Add/Remove**: Dynamically add or remove bars
- **Cancellation**: Cancel whole rendering process
- **Predefined Decorators**: Elapsed time, [ewma](https://github.com/VividCortex/ewma) based ETA, Percentage, Bytes counter
- **Decorator's width sync**: Synchronized decorator's width among multiple bars

## Usage

#### [Rendering single bar](_examples/singleBar/main.go)

```go
package main

import (
    "math/rand"
    "time"

    "github.com/vbauerster/mpb/v8"
    "github.com/vbauerster/mpb/v8/decor"
)

func main() {
    // initialize progress container, with custom width
    p := mpb.New(mpb.WithWidth(64))

    total := 100
    name := "Single Bar:"
    // create a single bar, which will inherit container's width
    bar := p.New(int64(total),
        // BarFillerBuilder with custom style
        mpb.BarStyle().Lbound("╢").Filler("▌").Tip("▌").Padding("░").Rbound("╟"),
        mpb.PrependDecorators(
            // display our name with one space on the right
            decor.Name(name, decor.WC{C: decor.DindentRight | decor.DextraSpace}),
            // replace ETA decorator with "done" message, OnComplete event
            decor.OnComplete(decor.AverageETA(decor.ET_STYLE_GO), "done"),
        ),
        mpb.AppendDecorators(decor.Percentage()),
    )
    // simulating some work
    max := 100 * time.Millisecond
    for range total {
        time.Sleep(time.Duration(rand.Intn(10)+1) * max / 10)
        bar.Increment()
    }
    // wait for our bar to complete and flush
    p.Wait()
}
```

#### [Rendering multiple bars](_examples/multiBars/main.go)

```
/* Detailed source-code truncated for AI context efficiency. */
```

#### [dynTotal example](_examples/dynTotal/main.go)



#### [queueBar example](_examples/queueBar/main.go)



#### [io example](_examples/io/main.go)

---

### Overview (`vendor/go.opentelemetry.io/otel/metric/embedded/README.md`)

# Metric Embedded

[](https://pkg.go.dev/go.opentelemetry.io/otel/metric/embedded)

---

### Overview (`vendor/go.opentelemetry.io/otel/metric/noop/README.md`)

# Metric Noop

[](https://pkg.go.dev/go.opentelemetry.io/otel/metric/noop)

---

### Overview (`vendor/go.opentelemetry.io/otel/semconv/v1.37.0/README.md`)

# Semconv v1.37.0

[](https://pkg.go.dev/go.opentelemetry.io/otel/semconv/v1.37.0)

---

### Overview (`vendor/go.opentelemetry.io/otel/semconv/v1.43.0/README.md`)

# Semconv v1.43.0

[](https://pkg.go.dev/go.opentelemetry.io/otel/semconv/v1.43.0)

---

### Overview (`vendor/go.opentelemetry.io/otel/trace/embedded/README.md`)

# Trace Embedded

[](https://pkg.go.dev/go.opentelemetry.io/otel/trace/embedded)

---

### Overview (`vendor/go.opentelemetry.io/otel/trace/noop/README.md`)

# Trace Noop

[](https://pkg.go.dev/go.opentelemetry.io/otel/trace/noop)

---

### Overview (`vendor/go.podman.io/storage/pkg/archive/README.md`)

This code provides helper functions for dealing with archive files.

---

### Overview (`vendor/go.podman.io/storage/pkg/reexec/README.md`)

# reexec

The `reexec` package facilitates the busybox style reexec of the docker binary that we require because 
of the forking limitations of using Go.  Handlers can be registered with a name and the argv 0 of 
the exec of the binary will be used to find and execute custom init paths.

---

### Overview (`vendor/go.podman.io/storage/pkg/stringid/README.md`)

This package provides helper functions for dealing with string identifiers

---

### Overview (`vendor/go.podman.io/storage/pkg/stringutils/README.md`)

This package provides helper functions for dealing with strings

---

### Overview (`vendor/golang.org/x/net/http2/README.md`)

This package (golang.org/x/net/http2) is the original source of truth
of the Go HTTP/2 implementation.

As of Go 1.27, the source of truth has moved to the standard library
package net/http/internal/http2.
All new feature development should happen in that package.
Only critical bug fixes and security fixes will be backported to x/net.

The x/net package contains two implementations of the HTTP/2 transport and server:

The original implementation (no longer the source of truth).

A reimplementation of the x/net/http2 APIs in terms of net/http.
This is called "the wrapping implementation", since it wraps net/http.

The original implementation is used when the Go version is less than 1.27.

The wrapping implementation is used when the Go version is at least 1.27.
The build tag "http2legacy" may be set to use the original implementation.

---

### Overview (`vendor/golang.org/x/sys/unix/README.md`)

# Building `sys/unix`

The sys/unix package provides access to the raw system call interface of the
underlying operating system. See: https://godoc.org/golang.org/x/sys/unix

Porting Go to a new architecture/OS combination or adding syscalls, types, or
constants to an existing architecture/OS pair requires some manual effort;
however, there are tools that automate much of the process.

## Build Systems

There are currently two ways we generate the necessary files. We are currently
migrating the build system to use containers so the builds are reproducible.
This is being done on an OS-by-OS basis. Please update this documentation as
components of the build system change.

### Old Build System (currently for `GOOS != "linux"`)

The old build system generates the Go files based on the C header files
present on your system. This means that files
for a given GOOS/GOARCH pair must be generated on a system with that OS and
architecture. This also means that the generated code can differ from system
to system, based on differences in the header files.

To avoid this, if you are using the old build system, only generate the Go
files on an installation with unmodified header files. It is also important to
keep track of which version of the OS the files were generated from (ex.
Darwin 14 vs Darwin 15). This makes it easier to track the progress of changes
and have each OS upgrade correspond to a single change.

To build the files for your current OS and architecture, make sure GOOS and
GOARCH are set correctly and run `mkall.sh`. This will generate the files for
your specific system. Running `mkall.sh -n` shows the commands that will be run.

Requirements: bash, go

### New Build System (currently for `GOOS == "linux"`)

The new build system uses a Docker container to generate the go files directly
from source checkouts of the kernel and various system libraries. This means
that on any platform that supports Docker, all the files using the new build
system can be generated at once, and generated files will not change based on
what the person running the scripts has installed on their computer.

The OS specific files for the new build system are located in the `${GOOS}`
directory, and the build is coordinated by the `${GOOS}/mkall.go` program. When
the kernel or system library updates, modify the Dockerfile at
`${GOOS}/Dockerfile` to checkout the new release of the source.

To build all the files under the new build system, you must be on an amd64/Linux
system and have your GOOS and GOARCH set accordingly. Running `mkall.sh` will
then generate all of the files for all of the GOOS/GOARCH pairs in the new build
system. Running `mkall.sh -n` shows the commands that will be run.

Requirements: bash, go, docker

## Component files

This section describes the various files used in the code generation process.
It also contains instructions on how to modify these files to add a new
architecture/OS or to add additional syscalls, types, or constants. Note that
if you are using the new build system, the scripts/programs cannot be called normally.
They must be called from within the docker container.

### asm files

The hand-written assembly file at `asm_${GOOS}_${GOARCH}.s` implements system
call dispatch. There are three entry points:
```
  func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
  func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
  func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
```
The first and second are the standard ones; they differ only in how many
arguments can be passed to the kernel. The third is for low-level use by the
ForkExec wrapper. Unlike the first two, it does not call into the scheduler to
let it know that a system call is running.

When porting Go to a new architecture/OS, this file must be implemented for
each GOOS/GOARCH pair.

### mksysnum

Mksysnum is a Go program located at `${GOOS}/mksysnum.go` (or `mksysnum_${GOOS}.go`
for the old system). This program takes in a list of header files containing the
syscall number declarations and parses them to produce the corresponding list of
Go numeric constants. See `zsysnum_${GOOS}_${GOARCH}.go` for the generated
constants.

Adding new syscall numbers is mostly done by running the build on a sufficiently
new installation of the target OS (or updating the source checkouts for the
new build system). However, depending on the OS, you may need to update the
parsing in mksysnum.

### mksyscall.go

The `syscall.go`, `syscall_${GOOS}.go`, `syscall_${GOOS}_${GOARCH}.go` are
hand-written Go files which implement system calls (for unix, the specific OS,
or the specific OS/Architecture pair respectively) that need special handling
and list `//sys` comments giving prototypes for ones that can be generated.

The mksyscall.go program takes the `//sys` and `//sysnb` comments and converts
them into syscalls. This requires the name of the prototype in the comment to
match a syscall number in the `zsysnum_${GOOS}_${GOARCH}.go` file. The function
prototype can be exported (capitalized) or not.

Adding a new syscall often just requires adding a new `//sys` function prototype
with the desired arguments and a capitalized name so it is exported. However, if
you want the interface to the syscall to be different, often one will make an
unexported `//sys` prototype, and then write a custom wrapper in
`syscall_${GOOS}.go`.

### types files

For each OS, there is a hand-written Go file at `${GOOS}/types.go` (or
`types_${GOOS}.go` on the old system). This file includes standard C headers and
creates Go type aliases to the corresponding C types. The file is then fed
through godef to get the Go compatible definitions. Finally, the generated code
is fed though mkpost.go to format the code correctly and remove any hidden or
private identifiers. This cleaned-up code is written to
`ztypes_${GOOS}_${GOARCH}.go`.

The hardest part about preparing this file is figuring out which headers to
include and which symbols need to be `#define`d to get the actual data
structures that pass through to the kernel system calls. Some C libraries
preset alternate versions for binary compatibility and translate them on the
way in and out of system calls, but there is almost always a `#define` that can
get the real ones.
See `types_darwin.go` and `linux/types.go` for examples.

To add a new type, add in the necessary include statement at the top of the
file (if it is not already there) and add in a type alias line. Note that if
your type is significantly different on different architectures, you may need
some `#if/#elif` macros in your include statements.

### mkerrors.sh

This script is used to generate the system's various constants. This doesn't
just include the error numbers and error strings, but also the signal numbers
and a wide variety of miscellaneous constants. The constants come from the list
of include files in the `includes_${uname}` variable. A regex then picks out
the desired `#define` statements, and generates the corresponding Go constants.
The error numbers and strings are generated from `#include <errno.h>`, and the
signal numbers and strings are generated from `#include <signal.h>`. All of
these constants are written to `zerrors_${GOOS}_${GOARCH}.go` via a C program,
`_errors.c`, which prints out all the constants.

To add a constant, add the header that includes it to the appropriate variable.
Then, edit the regex (if necessary) to match the desired constant. Avoid making
the regex too broad to avoid matching unintended constants.

### internal/mkmerge

This program is used to extract duplicate const, func, and type declarations
from the generated architecture-specific files listed below, and merge these
into a common file for each OS.

The merge is performed in the following steps:
1. Construct the set of common code that is identical in all architecture-specific files.
2. Write this common code to the merged file.
3. Remove the common code from all architecture-specific files.


## Generated files

### `zerrors_${GOOS}_${GOARCH}.go`

A file containing all of the system's generated error numbers, error strings,
signal numbers, and constants. Generated by `mkerrors.sh` (see above).

### `zsyscall_${GOOS}_${GOARCH}.go`

A file containing all the generated syscalls for a specific GOOS and GOARCH.
Generated by `mksyscall.go` (see above).

### `zsysnum_${GOOS}_${GOARCH}.go`

A list of numeric constants for all the syscall number of the specific GOOS
and GOARCH. Generated by mksysnum (see above).

### `ztypes_${GOOS}_${GOARCH}.go`

A file containing Go types for passing into (or returning from) syscalls.
Generated by godefs and the types file (see above).

---

### Overview (`vendor/github.com/clipperhouse/uax29/v2/graphemes/README.md`)

An implementation of grapheme cluster boundaries from [Unicode text segmentation](https://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries) (UAX 29), for Unicode 17.

[](https://pkg.go.dev/github.com/clipperhouse/uax29/v2/graphemes)



## Quick start

```
go get github.com/clipperhouse/uax29/v2/graphemes
```

```go
import "github.com/clipperhouse/uax29/v2/graphemes"

text := "Hello, 世界. Nice dog! 👍🐶"
g := graphemes.FromString(text)

for g.Next() {                     // Next() returns true until end of data
	fmt.Println(g.Value())         // Do something with the current grapheme
}
```

_A grapheme is a “single visible character”, which might be a simple as a single letter, or a complex emoji that consists of several Unicode code points._

## Conformance

We use the Unicode [test suite](https://unicode.org/reports/tr41/tr41-36.html#Tests29).




## APIs

### If you have a `string`

```go
text := "Hello, 世界. Nice dog! 👍🐶"
g := graphemes.FromString(text)

for g.Next() {                     // Next() returns true until end of data
	fmt.Println(g.Value())         // Do something with the current grapheme
}
```

### If you have an `io.Reader`

`FromReader` embeds a [`bufio.Scanner`](https://pkg.go.dev/bufio#Scanner), so just use those methods.

```go
r := getYourReader()                    // from a file or network maybe
g := graphemes.FromReader(r)

for g.Scan() {                         // Scan() returns true until error or EOF
	fmt.Println(g.Text())              // Do something with the current grapheme
}

if g.Err() != nil {                    // Check the error
	log.Fatal(g.Err())
}
```

### If you have a `[]byte`

```go
b := []byte("Hello, 世界. Nice dog! 👍🐶")

g := graphemes.FromBytes(b)

for g.Next() {                     // Next() returns true until end of data
	fmt.Println(g.Value())         // Do something with the current grapheme
}
```

### ANSI escape sequences

By the UAX 29 specification, ANSI escape sequences are not grapheme clusters. To treat 7-bit ANSI escape sequences as a single cluster, set `AnsiEscapeSequences` to true.

```go
text := "Hello, \x1b[31mworld\x1b[0m!"
g := graphemes.FromString(text)
g.AnsiEscapeSequences = true

for g.Next() {
	fmt.Println(g.Value())
}
```

To also parse 8-bit C1 controls (non-UTF-8 bytes), set `AnsiEscapeSequences8Bit` to true.

```go
g.AnsiEscapeSequences = true     // 7-bit forms (ESC ...)
g.AnsiEscapeSequences8Bit = true // 8-bit C1 forms (0x80-0x9F), not valid UTF-8
```

For ESC-initiated (7-bit) control strings, only 7-bit terminators are recognized.
For C1-initiated (8-bit) control strings, only C1 ST (`0x9C`) is recognized as ST.

We implement [ECMA-48](https://ecma-international.org/publications-and-standards/standards/ecma-48/) control codes in both 7-bit and 8-bit representations. 8-bit control codes are not UTF-8 encoded and are not valid UTF-8, caveat emptor.

### Benchmarks

```
goos: darwin
goarch: arm64
pkg: github.com/clipperhouse/uax29/graphemes/comparative
cpu: Apple M2

BenchmarkGraphemesMixed/clipperhouse/uax29-8  	    142635 ns/op	 245.12 MB/s    0 B/op	   0 allocs/op
BenchmarkGraphemesMixed/rivo/uniseg-8         	   2018284 ns/op	  17.32 MB/s    0 B/op	   0 allocs/op

BenchmarkGraphemesASCII/clipperhouse/uax29-8  	      8846 ns/op	 508.73 MB/s    0 B/op	   0 allocs/op
BenchmarkGraphemesASCII/rivo/uniseg-8         	    366760 ns/op	  12.27 MB/s    0 B/op	   0 allocs/op
```

### Invalid inputs

Invalid UTF-8 input is considered undefined behavior. We test to ensure that bad inputs will not cause pathological outcomes, such as a panic or infinite loop. Callers should expect “garbage-in, garbage-out”.

Your pipeline should probably include a call to [`utf8.Valid()`](https://pkg.go.dev/unicode/utf8#Valid).

---

### Overview (`vendor/github.com/go-jose/go-jose/v4/json/README.md`)

# Safe JSON

This repository contains a fork of the `encoding/json` package from Go 1.6.

The following changes were made:

* Object deserialization uses case-sensitive member name matching instead of
  [case-insensitive matching](https://www.ietf.org/mail-archive/web/json/current/msg03763.html).
  This is to avoid differences in the interpretation of JOSE messages between
  go-jose and libraries written in other languages.
* When deserializing a JSON object, we check for duplicate keys and reject the
  input whenever we detect a duplicate. Rather than trying to work with malformed
  data, we prefer to reject it right away.

---

### Overview (`vendor/github.com/google/go-containerregistry/pkg/name/README.md`)

# `name`

[](https://godoc.org/github.com/google/go-containerregistry/pkg/name)

---

### Overview (`vendor/github.com/opencontainers/selinux/pkg/pwalkdir/README.md`)

## pwalkdir: parallel implementation of filepath.WalkDir

This is a wrapper for [filepath.WalkDir](https://pkg.go.dev/path/filepath#WalkDir)
which may speed it up by calling multiple callback functions (WalkDirFunc)
in parallel, utilizing goroutines.

By default, it utilizes 2\*runtime.NumCPU() goroutines for callbacks.
This can be changed by using WalkN function which has the additional
parameter, specifying the number of goroutines (concurrency).

### pwalk vs pwalkdir

This package is very similar to
[pwalk](https://pkg.go.dev/github.com/opencontainers/selinux/pkg/pwalkdir),
but utilizes `filepath.WalkDir` (added to Go 1.16), which does not call stat(2)
on every entry and is therefore faster (up to 3x, depending on usage scenario).

Users who are OK with requiring Go 1.16+ should switch to this
implementation.

### Caveats

Please note the following limitations of this code:

* Unlike filepath.WalkDir, the order of calls is non-deterministic;

* Only primitive error handling is supported:

  * fs.SkipDir is not supported;

  * ErrNotExist errors from filepath.WalkDir are silently ignored for any path
    except the top directory (WalkDir argument); any other error is returned to
    the caller of WalkDir;

  * once any error is returned from any walkDirFunc instance, no more calls
    to WalkDirFunc are made, and the error is returned to the caller of WalkDir;

  * if more than one WalkDirFunc instance will return an error, only one
    of such errors will be propagated to and returned by WalkDir, others
    will be silently discarded.

### Documentation

For the official documentation, see
https://pkg.go.dev/github.com/opencontainers/selinux/pkg/pwalkdir

### Benchmarks

For a WalkDirFunc that consists solely of the return statement, this
implementation is about 15% slower than the standard library's
filepath.WalkDir.

Otherwise (if a WalkDirFunc is actually doing something) this is usually
faster, except when the WalkDirN(..., 1) is used. Run `go test -bench .`
to see how different operations can benefit from it, as well as how the
level of parallelism affects the speed.

---

### Overview (`vendor/github.com/stretchr/testify/internal/spew/README.md`)

go-spew
=======

[](http://copyfree.org)

Go-spew implements a deep pretty printer for Go data structures to aid in
debugging.  A comprehensive suite of tests with 100% test coverage is provided
to ensure proper functionality.

## License

Go-spew is licensed under the [copyfree](http://copyfree.org) ISC License.

---

### Overview (`vendor/github.com/vbatts/tar-split/tar/asm/README.md`)

asm
===

This library for assembly and disassembly of tar archives, facilitated by
`github.com/vbatts/tar-split/tar/storage`.


Concerns
--------

For completely safe assembly/disassembly, there will need to be a Content
Addressable Storage (CAS) directory, that maps to a checksum in the
`storage.Entity` of `storage.FileType`.

This is due to the fact that tar archives _can_ allow multiple records for the
same path, but the last one effectively wins. Even if the prior records had a
different payload. 

In this way, when assembling an archive from relative paths, if the archive has
multiple entries for the same path, then all payloads read in from a relative
path would be identical.


Thoughts
--------

Have a look-aside directory or storage. This way when a clobbering record is
encountered from the tar stream, then the payload of the prior/existing file is
stored to the CAS. This way the clobbering record's file payload can be
extracted, but we'll have preserved the payload needed to reassemble a precise
tar archive.

clobbered/path/to/file.[0-N]

*alternatively*

We could just _not_ support tar streams that have clobbering file paths.
Appending records to the archive is not incredibly common, and doesn't happen
by default for most implementations.  Not supporting them wouldn't be a
security concern either, as if it did occur, we would reassemble an archive
that doesn't validate signature/checksum, so it shouldn't be trusted anyway.

Otherwise, this will allow us to defer support for appended files as a FUTURE FEATURE.

---

### Overview (`vendor/go.podman.io/common/pkg/report/camelcase/README.md`)

# CamelCase [](http://godoc.org/github.com/fatih/camelcase) [](https://travis-ci.org/fatih/camelcase)

CamelCase is a Golang (Go) package to split the words of a camelcase type
string into a slice of words. It can be used to convert a camelcase word (lower
or upper case) into any type of word.

## Splitting rules:

1. If string is not valid UTF-8, return it without splitting as
   single item array.
2. Assign all unicode characters into one of 4 sets: lower case
   letters, upper case letters, numbers, and all other characters.
3. Iterate through characters of string, introducing splits
   between adjacent characters that belong to different sets.
4. Iterate through array of split strings, and if a given string
   is upper case:
   * if subsequent string is lower case:
     * move last character of upper case string to beginning of
       lower case string

## Install

```bash
go get github.com/fatih/camelcase
```

## Usage and examples

```go
split := camelcase.Split("GolangPackage")

fmt.Println(split[0], split[1]) // prints: "Golang", "Package"
```

Both lower camel case and upper camel case are supported. For more info please
check: [http://en.wikipedia.org/wiki/CamelCase](http://en.wikipedia.org/wiki/CamelCase)

Below are some example cases:

```
"" =>                     []
"lowercase" =>            ["lowercase"]
"Class" =>                ["Class"]
"MyClass" =>              ["My", "Class"]
"MyC" =>                  ["My", "C"]
"HTML" =>                 ["HTML"]
"PDFLoader" =>            ["PDF", "Loader"]
"AString" =>              ["A", "String"]
"SimpleXMLParser" =>      ["Simple", "XML", "Parser"]
"vimRPCPlugin" =>         ["vim", "RPC", "Plugin"]
"GL11Version" =>          ["GL", "11", "Version"]
"99Bottles" =>            ["99", "Bottles"]
"May5" =>                 ["May", "5"]
"BFG9000" =>              ["BFG", "9000"]
"BöseÜberraschung" =>     ["Böse", "Überraschung"]
"Two  spaces" =>          ["Two", "  ", "spaces"]
"BadUTF8\xe2\xe2\xa1" =>  ["BadUTF8\xe2\xe2\xa1"]
```

---

### Overview (`vendor/go.podman.io/image/v5/docker/reference/README.md`)

This is a copy of github.com/docker/distribution/reference as of commit 3226863cbcba6dbc2f6c83a37b28126c934af3f8,
except that ParseAnyReferenceWithSet has been removed to drop the dependency on github.com/docker/distribution/digestset.

---

### Overview (`vendor/go.podman.io/image/v5/pkg/strslice/README.md`)

This package was replicated from [github.com/docker/docker v17.04.0-ce](https://github.com/docker/docker/tree/v17.04.0-ce/api/types/strslice).

---

### Overview (`vendor/golang.org/x/net/internal/httpcommon/README.md`)

These two packages are identical:

- net/http/internal/httpcommon
- golang.org/x/net/internal/httpcommon

The two are kept in sync manually.
Any change to one should be made in the other.

---

### Overview (`vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/README.md`)

## gocompat ##

This directory contains backports of stdlib functions from later Go versions so
the filepath-securejoin can continue to be used by projects that are stuck with
Go 1.18 support. Note that often filepath-securejoin is added in security
patches for old releases, so avoiding the need to bump Go compiler requirements
is a huge plus to downstreams.

The source code is licensed under the same license as the Go stdlib. See the
source files for the precise license information.

---

### Overview (`vendor/github.com/klauspost/compress/zstd/internal/xxhash/README.md`)

# xxhash

VENDORED: Go to [github.com/cespare/xxhash](https://github.com/cespare/xxhash) for original package.

xxhash is a Go implementation of the 64-bit [xxHash] algorithm, XXH64. This is a
high-quality hashing algorithm that is much faster than anything in the Go
standard library.

This package provides a straightforward API:

```
func Sum64(b []byte) uint64
func Sum64String(s string) uint64
type Digest struct{ ... }
    func New() *Digest
```

The `Digest` type implements hash.Hash64. Its key methods are:

```
func (*Digest) Write([]byte) (int, error)
func (*Digest) WriteString(string) (int, error)
func (*Digest) Sum64() uint64
```

The package is written with optimized pure Go and also contains even faster
assembly implementations for amd64 and arm64. If desired, the `purego` build tag
opts into using the Go code even on those architectures.

[xxHash]: http://cyan4973.github.io/xxHash/

## Compatibility

This package is in a module and the latest code is in version 2 of the module.
You need a version of Go with at least "minimal module compatibility" to use
github.com/cespare/xxhash/v2:

* 1.9.7+ for Go 1.9
* 1.10.3+ for Go 1.10
* Go 1.11 or later

I recommend using the latest release of Go.

## Benchmarks

Here are some quick benchmarks comparing the pure-Go and assembly
implementations of Sum64.

| input size | purego    | asm       |
| ---------- | --------- | --------- |
| 4 B        |  1.3 GB/s |  1.2 GB/s |
| 16 B       |  2.9 GB/s |  3.5 GB/s |
| 100 B      |  6.9 GB/s |  8.1 GB/s |
| 4 KB       | 11.7 GB/s | 16.7 GB/s |
| 10 MB      | 12.0 GB/s | 17.3 GB/s |

These numbers were generated on Ubuntu 20.04 with an Intel Xeon Platinum 8252C
CPU using the following commands under Go 1.19.2:

```
benchstat <(go test -tags purego -benchtime 500ms -count 15 -bench 'Sum64$')
benchstat <(go test -benchtime 500ms -count 15 -bench 'Sum64$')
```

## Projects using this package

- [InfluxDB](https://github.com/influxdata/influxdb)
- [Prometheus](https://github.com/prometheus/prometheus)
- [VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics)
- [FreeCache](https://github.com/coocood/freecache)
- [FastCache](https://github.com/VictoriaMetrics/fastcache)

---

### Skopeo Copy.1 (`docs/skopeo-copy.1.md`)

% skopeo-copy(1)

## NAME
skopeo\-copy - Copy an image (manifest, filesystem layers, signatures) from one location to another.

## SYNOPSIS
**skopeo copy** [*options*] _source-image_ _destination-image_

## DESCRIPTION
Copy an image (manifest, filesystem layers, signatures) from one location to another.

Uses the system's trust policy to validate images, rejects images not trusted by the policy.

  _source-image_ use the "image name" format described above

  _destination-image_ use the "image name" format described above

_source-image_ and _destination-image_ are interpreted completely independently; e.g. the destination name does not
automatically inherit any parts of the source name.

## OPTIONS

See also [skopeo(1)](skopeo.1.md) for options placed before the subcommand name.

**--additional-tag**=_strings_

Additional tags (supports docker-archive).

**--all**, **-a**

If _source-image_ refers to a list of images, instead of copying just the image which matches the current OS and
architecture (subject to the use of the global --override-os, --override-arch and --override-variant options), attempt to copy all of
the images in the list, and the list itself.

**--authfile** _path_

Path of the primary registry credentials file. On Linux, the default is ${XDG\_RUNTIME\_DIR}/containers/auth.json.
See **containers-auth.json**(5) for more details about the credential search mechanism and defaults on other platforms.

Use `skopeo login` to manage the credentials.

The default value of this option is read from the `REGISTRY\_AUTH\_FILE` environment variable.

**--src-authfile** _path_

Path of the primary registry credentials file for the source registry. Uses path given by `--authfile`, if not provided.

**--dest-authfile** _path_

Path of the primary registry credentials file for the destination registry. Uses path given by `--authfile`, if not provided.

**--dest-shared-blob-dir** _directory_

Directory to use to share blobs across OCI repositories.

**--digestfile** _path_

After copying the image, write the digest of the resulting image to the file.

**--preserve-digests**

Preserve the digests during copying. Fail if the digest cannot be preserved.

This option does not change what will be copied; consider using `--all` at the same time.

**--download-foreign-layers**

Copy the contents of nondistributable ("foreign") layers, such as Windows base layers, to the destination. This overrides the normal behavior for destinations that support foreign-layer URL references. Other destinations copy the contents regardless of the flag.

This flag does not change the foreign layer's media type or `urls` field. Other manifest conversions may still occur.

**--encrypt-layer** _ints_

*Experimental* the 0-indexed layer indices, with support for negative indexing (e.g. 0 is the first layer, -1 is the last layer)

**--format**, **-f** _manifest-type_

MANIFEST TYPE (oci, v2s1, or v2s2) to use in the destination (default is manifest type of source, with fallbacks)

**--help**, **-h**

Print usage statement

**--multi-arch** _option_

Control what is copied if _source-image_ refers to a multi-architecture image. Default is system.

Options:
- system: Copy only the image that matches the system architecture
- all: Copy the full multi-architecture image
- index-only: Copy only the index
- _platform-list_: Copy only specific platforms (comma-separated list of OS/Architecture pairs, e.g., `linux/amd64,linux/arm64`)

The index-only option and platform-list both create sparse manifest lists, which usually fail unless the referenced per-architecture images are already present in the destination, or the target registry supports sparse indexes.
To keep only the remaining platforms in the manifest when a platform-list is given use **--strip-removed-platforms** in addition.

When specifying a platform list, all compression variants and other variations for each platform are copied.

**--quiet**, **-q**

Suppress output information when copying images.

**--remove-signatures**

Do not copy signatures, if any, from _source-image_. Necessary when copying a signed image to a destination which does not support signatures.

**--remove-list-signatures**

Do not copy the manifest list signature while preserving per-instance signatures. This provides more granular control than **--remove-signatures**, which removes all signatures.

**--strip-removed-platforms**

When copying only a subset of platforms from a multi-architecture image (using **--multi-arch** with a platform list), write a manifest list containing only the copied platforms, instead of leaving entries that refer to per-platform images not present in the destination. This is useful for registries that reject manifest lists containing references to missing images.

Note: This option requires signatures to be removed using either **--remove-signatures** or **--remove-list-signatures**, as stripping instances invalidates the manifest list signature and changes the manifest list digest. The operation will fail if signatures are present and not explicitly removed.

**--sign-by** _key-id_

Add a “simple signing” signature using that key ID for an image name corresponding to _destination-image_

**--sign-by-sigstore** _param-file_

Add a sigstore signature based on the options in the specified containers sigstore signing parameter file, _param-file_.
See containers-sigstore-signing-params.yaml(5) for details about the file format.

**--sign-by-sigstore-private-key** _path_

Add a sigstore signature using a private key at _path_ for an image name corresponding to _destination-image_

**--sign-by-sq-fingerprint** _fingerprint_

Add a “simple signing” signature using a Sequoia-PGP key with the specified _fingerprint_.

**--sign-passphrase-file** _path_

The passphrase to use when signing with `--sign-by`, `--sign-by-sigstore-private-key` or `--sign-by-sq-fingerprint`.
Only the first line will be read. A passphrase stored in a file is of questionable security if other users can read this file. Do not use this option if at all avoidable.

**--sign-identity** _reference_

The identity to use when signing the image. The identity must be a fully specified docker reference. If the identity is not specified, the target docker reference will be used.

**--src-shared-blob-dir** _directory_

Directory to use to share blobs across OCI repositories.

**--encryption-key** _protocol:keyfile_

Specifies the encryption protocol, which can be JWE (RFC7516), PGP (RFC4880), and PKCS7 (RFC2315) and the key material required for image encryption. For instance, jwe:/path/to/key.pem or pgp:admin@example.com or pkcs7:/path/to/x509-file.

**--decryption-key** _key[:passphrase]_

Key to be used for decryption of images. Key can point to keys and/or certificates. Decryption will be tried with all keys. If the key is protected by a passphrase, it is required to be passed in the argument and omitted otherwise.

**--src-creds** _username[:password]_

Credentials for accessing the source registry.

**--dest-compress**

Compress tarball image layers when saving to directory using the 'dir' transport. (default is same compression type as source).

**--dest-decompress**

Decompress tarball image layers when saving to directory using the 'dir' transport. (default is same compression type as source).

**--dest-oci-accept-uncompressed-layers**

Allow uncompressed image layers when saving to an OCI image using the 'oci' transport. (default is to compress things that aren't compressed).

**--dest-creds** _username[:password]_

Credentials for accessing the destination registry.

**--src-cert-dir** _path_

Use certificates at _path_ (*.crt, *.cert, *.key) to connect to the source registry or daemon.

**--src-no-creds**

Access the registry anonymously.

**--src-tls-verify**=_bool_

Require HTTPS and verify certificates when talking to container source registry or daemon. Default to source registry setting.

**--dest-cert-dir** _path_

Use certificates at _path_ (*.crt, *.cert, *.key) to connect to the destination registry or daemon.

**--dest-no-creds**

Access the registry anonymously.

**--dest-tls-verify**=_bool_

Require HTTPS and verify certificates when talking to container destination registry or daemon. Default to destination registry setting.

**--src-daemon-host** _host_

Copy from docker daemon at _host_. If _host_ starts with `tcp://`, HTTPS is enabled by default. To use plain HTTP, use the form `http://` (default is `unix:///var/run/docker.sock`).

**--dest-daemon-host** _host_

Copy to docker daemon at _host_. If _host_ starts with `tcp://`, HTTPS is enabled by default. To use plain HTTP, use the form `http://` (default is `unix:///var/run/docker.sock`).

**--dest-compress-format** _format_

Specifies the compression format to use.  Supported values are: `gzip`, `zstd` and `zstd:chunked`.
`zstd:chunked` is incompatible with encrypting images,
and will be treated as `zstd` with a warning in that case.

**--dest-compress-level** _format_

Specifies the compression level to use.  The value is specific to the compression algorithm used, e.g. for zstd the accepted values are in the range 1-20 (inclusive), while for gzip it is 1-9 (inclusive).

**--dest-force-compress-format**

Ensures that the compression algorithm set in --dest-compress-format is used exclusively.

**--src-registry-token** _token_

Bearer token for accessing the source registry.

**--dest-registry-token** _token_

Bearer token for accessing the destination registry.

**--dest-precompute-digests**

Precompute digests to ensure layers are not uploaded that already exist on the destination registry. Layers with initially unknown digests (ex. compressing "on the fly") will be temporarily streamed to disk.

**--retry-times**

The number of times to retry. By default, no retries are attempted.

**--retry-delay**

Fixed delay between retries. If not set (or set to 0s), retry wait time will be exponentially increased based on the number of failed attempts.

**--src-username**

The username to access the source registry.

**--src-password**

The password to access the source registry.

**--dest-username**

The username to access the destination registry.

**--dest-password**

The password to access the destination registry.

**--image-parallel-copies** _n_

Maximum number of image layers to be copied (pulled/pushed) simultaneously. Not setting this field will fall back to containers/image defaults.

## EXAMPLES

To just copy an image from one registry to another:
```console
$ skopeo copy docker://quay.io/skopeo/stable:latest docker://registry.example.com/skopeo:latest
```

To copy the layers of the docker.io busybox image to a local directory:
```console
$ mkdir -p /var/lib/images/busybox
$ skopeo copy docker://busybox:latest dir:/var/lib/images/busybox
$ ls /var/lib/images/busybox/*
  /tmp/busybox/2b8fd9751c4c0f5dd266fcae00707e67a2545ef34f9a29354585f93dac906749.tar
  /tmp/busybox/manifest.json
  /tmp/busybox/8ddc19f16526912237dd8af81971d5e4dd0587907234be2b83e249518d5b673f.tar
```

To create an archive consumable by `docker load` (but note that using a registry is almost always more efficient):
```console
$ skopeo copy docker://busybox:latest docker-archive:archive-file.tar:busybox:latest
```

To copy and sign an image:
```console
$ skopeo copy --sign-by dev@example.com containers-storage:example/busybox:streaming docker://example/busybox:gold
```

To copy only specific platforms from a multi-architecture image (creates a sparse manifest list):
```console
$ skopeo copy --multi-arch=linux/amd64,linux/arm64 docker://quay.io/skopeo/stable:latest docker://registry.example.com/skopeo:latest
```

To copy specific platforms and strip the sparse manifest list (for registries that don't support sparse lists or in case the additional platforms are not wanted in the final registry manifest):
```console
$ skopeo copy --multi-arch=linux/amd64,linux/arm64 --strip-removed-platforms --remove-list-signatures docker://quay.io/skopeo/stable:latest docker://registry.example.com/skopeo:latest
```

To encrypt an image:
```console
$ skopeo copy docker://docker.io/library/nginx:1.17.8 oci:local_nginx:1.17.8

$ openssl genrsa -out private.key 1024
$ openssl rsa -in private.key -pubout > public.key

$ skopeo copy --encryption-key jwe:./public.key oci:local_nginx:1.17.8 oci:try-encrypt:encrypted
```

To decrypt an image:
```console
$ skopeo copy --decryption-key ./private.key oci:try-encrypt:encrypted oci:try-decrypt:decrypted
```

To copy encrypted image without decryption:
```console
$ skopeo copy oci:try-encrypt:encrypted oci:try-encrypt-copy:encrypted
```

To decrypt an image that requires more than one key:
```console
$ skopeo copy --decryption-key ./private1.key --decryption-key ./private2.key --decryption-key ./private3.key oci:try-encrypt:encrypted oci:try-decrypt:decrypted
```

Container images can also be partially encrypted by specifying the index of the layer. Layers are 0-indexed indices, with support for negative indexing. i.e. 0 is the first layer, -1 is the last layer.

Let's say out of 3 layers that the image `docker.io/library/nginx:1.17.8` is made up of, we only want to encrypt the 2nd layer,
```console
$ skopeo copy --encryption-key jwe:./public.key --encrypt-layer 1 oci:local_nginx:1.17.8 oci:try-encrypt:encrypted
```

## SEE ALSO
skopeo(1), skopeo-login(1), docker-login(1), containers-auth.json(5), containers-policy.json(5), containers-transports(5), containers-signature(5)

## AUTHORS

Antonio Murdaca <runcom@redhat.com>, Miloslav Trmac <mitr@redhat.com>, Jhon Honce <jhonce@redhat.com>

---

### Skopeo Delete.1 (`docs/skopeo-delete.1.md`)

% skopeo-delete(1)

## NAME
skopeo\-delete - Mark the _image-name_ for later deletion by the registry's garbage collector.

## SYNOPSIS
**skopeo delete** [*options*] _image-name_

## DESCRIPTION

Mark _image-name_ for deletion.
The effect of this is registry-specific; many registries don’t support this operation, or don’t allow it in some circumstances / configurations.

**WARNING**: If _image-name_ contains a digest, this affects the referenced manifest, and may delete all tags (within the current repository?) pointing to that manifest.

**WARNING**: If _image-name_ contains a tag (but not a digest), in the current version of Skopeo this resolves the tag into a digest, and then deletes the manifest by digest, as described above (possibly deleting all tags pointing to that manifest, not just the provided tag). This behavior may change in the future.


When using the github.com/distribution/distribution registry server:
To release the allocated disk space, you must login to the container registry server and execute the container registry garbage collector. E.g.,

```
/usr/bin/registry garbage-collect /etc/docker-distribution/registry/config.yml
```
Note: sometimes the config.yml is stored in /etc/docker/registry/config.yml

If you are running the container registry inside of a container you would execute something like:
```
$ docker exec -it registry /usr/bin/registry garbage-collect /etc/docker-distribution/registry/config.yml
```

## OPTIONS

See also [skopeo(1)](skopeo.1.md) for options placed before the subcommand name.

**--authfile** _path_

Path of the primary registry credentials file. On Linux, the default is ${XDG\_RUNTIME\_DIR}/containers/auth.json.
See **containers-auth.json**(5) for more details about the credential search mechanism and defaults on other platforms.

Use `skopeo login` to manage the credentials.

The default value of this option is read from the `REGISTRY\_AUTH\_FILE` environment variable.

**--creds** _username[:password]_

Credentials for accessing the registry.

**--cert-dir** _path_

Use certificates at _path_ (*.crt, *.cert, *.key) to connect to the registry.

**--daemon-host** _host_

Use docker daemon host at _host_ (`docker-daemon:` transport only)

**--help**, **-h**

Print usage statement

**--no-creds**

Access the registry anonymously.

Additionally, the registry must allow deletions by setting `REGISTRY_STORAGE_DELETE_ENABLED=true` for the registry daemon.

**--registry-token** _token_

Bearer token for accessing the registry.

**--retry-times**

The number of times to retry. By default, no retries are attempted.

**--retry-delay**

Fixed delay between retries. If not set (or set to 0s), retry wait time will be exponentially increased based on the number of failed attempts.

**--shared-blob-dir** _directory_

Directory to use to share blobs across OCI repositories.

**--tls-verify**=_bool_

Require HTTPS and verify certificates when talking to the container registry or daemon. Default to registry.conf setting.

**--username**

The username to access the registry.

**--password**

The password to access the registry.

## EXAMPLES

Mark image example/pause for deletion from the registry.example.com registry:
```console
$ skopeo delete docker://registry.example.com/example/pause:latest
```
See above for additional details on using the command **delete**.


## SEE ALSO
skopeo(1), skopeo-login(1), docker-login(1), containers-auth.json(5)

## AUTHORS

Antonio Murdaca <runcom@redhat.com>, Miloslav Trmac <mitr@redhat.com>, Jhon Honce <jhonce@redhat.com>

---

### Skopeo Generate Sigstore Key.1 (`docs/skopeo-generate-sigstore-key.1.md`)

% skopeo-generate-sigstore-key(1)

## NAME
skopeo\-generate-sigstore-key - Generate a sigstore public/private key pair.

## SYNOPSIS
**skopeo generate-sigstore-key** [*options*] **--output-prefix** _prefix_

## DESCRIPTION

Generates a public/private key pair suitable for creating sigstore image signatures.
The private key is encrypted with a passphrase;
if one is not provided using an option, this command prompts for it interactively.

The private key is written to _prefix_**.private** .
The public key is written to _prefix_**.pub** .

## OPTIONS

See also [skopeo(1)](skopeo.1.md) for options placed before the subcommand name.

**--help**, **-h**

Print usage statement

**--output-prefix** _prefix_

Mandatory.
Path prefix for the output keys (_prefix_**.private** and _prefix_**.pub**).

**--passphrase-file** _path_

The passphare to use to encrypt the private key.
Only the first line will be read.
A passphrase stored in a file is of questionable security if other users can read this file.
Do not use this option if at all avoidable.

## EXAMPLES

```console
$ skopeo generate-sigstore-key --output-prefix mykey
```

## SEE ALSO
skopeo(1), skopeo-copy(1), containers-policy.json(5)

## AUTHORS

Miloslav Trmač <mitr@redhat.com>

---

### Skopeo Inspect.1 (`docs/skopeo-inspect.1.md`)

% skopeo-inspect(1)

## NAME
skopeo\-inspect - Return low-level information about _image-name_ in a registry.

## SYNOPSIS
**skopeo inspect** [*options*] _image-name_

## DESCRIPTION

Return low-level information about _image-name_ in a registry.
See [skopeo(1)](skopeo.1.md) for the format of _image-name_.

The default output includes data from various sources: user input (**Name**), the remote repository, if any (**RepoTags**), the top-level manifest (**Digest**),
and a per-architecture/OS image matching the current run-time environment (most other values).
To see values for a different architecture/OS, use the **--override-os** / **--override-arch** options documented in [skopeo(1)](skopeo.1.md).

## OPTIONS

See also [skopeo(1)](skopeo.1.md) for options placed before the subcommand name.

**--authfile** _path_

Path of the primary registry credentials file. On Linux, the default is ${XDG\_RUNTIME\_DIR}/containers/auth.json.
See **containers-auth.json**(5) for more details about the credential search mechanism and defaults on other platforms.

Use `skopeo login` to manage the credentials.

The default value of this option is read from the `REGISTRY\_AUTH\_FILE` environment variable.

**--cert-dir** _path_

Use certificates at _path_ (\*.crt, \*.cert, \*.key) to connect to the registry.

**--config**

Output configuration in OCI format, default is to format in JSON format.

**--creds** _username[:password]_

Username and password for accessing the registry.

**--daemon-host** _host_

Use docker daemon host at _host_ (`docker-daemon:` transport only)

**--format**, **-f**=*format*

Format the output using the given Go template.
The keys of the returned JSON can be used as the values for the --format flag (see examples below).
Supports the Go templating functions available at https://pkg.go.dev/github.com/containers/common/pkg/report#hdr-Template_Functions

**--help**, **-h**

Print usage statement

**--no-creds**

Access the registry anonymously.

**--raw**

Output raw manifest or config data depending on --config option.
The --format option is not supported with --raw option.

**--registry-token** _Bearer token_

Registry token for accessing the registry.

**--retry-times**

The number of times to retry. By default, no retries are attempted.

**--retry-delay**

Fixed delay between retries. If not set (or set to 0s), retry wait time will be exponentially increased based on the number of failed attempts.

**--shared-blob-dir** _directory_

Directory to use to share blobs across OCI repositories.

**--tls-verify**=_bool_

Require HTTPS and verify certificates when talking to the container registry or daemon. Default to registry.conf setting.

**--username**

The username to access the registry.

**--password**

The password to access the registry.

**--no-tags**, **-n**

Do not list the available tags from the repository in the output. When `true`, the `RepoTags` array will be empty.  Defaults to `false`, which includes all available tags.

**--manifest-digest**=_algorithm_ **EXPERIMENTAL**

Algorithm to use for computing manifest digest (sha256, sha512); defaults to algorithm used in config digest.

**Note:** This flag is experimental and its behavior may change in future releases.

## EXAMPLES

To review information for the image fedora from the docker.io registry:
```console
$ skopeo inspect docker://docker.io/fedora

{
    "Name": "docker.io/library/fedora",
    "Digest": "sha256:f99efcddc4dd6736d8a88cc1ab6722098ec1d77dbf7aed9a7a514fc997ca08e0",
    "RepoTags": [
        "20",
        "21",
        "..."
    ],
    "Created": "2022-11-16T07:26:42.618327645Z",
    "DockerVersion": "20.10.12",
    "Labels": {
        "maintainer": "Clement Verna \u003ccverna@fedoraproject.org\u003e"
    },
    "Architecture": "amd64",
    "Os": "linux",
    "Layers": [
        "sha256:cb8b1ed77979b894115a983f391465651aa7eb3edd036be4b508eea47271eb93"
    ],
    "LayersData": [
        {
            "MIMEType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
            "Digest": "sha256:cb8b1ed77979b894115a983f391465651aa7eb3edd036be4b508eea47271eb93",
            "Size": 65990920,
            "Annotations": null
        }
    ],
    "Env": [
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "DISTTAG=f37container",
        "FGC=f37",
        "FBR=f37"
    ]
}
```

To inspect python from the docker.io registry and not show the available tags:
```console
$ skopeo inspect --no-tags docker://docker.io/library/python
{
    "Name": "docker.io/library/python",
    "Digest": "sha256:10fc14aa6ae69f69e4c953cffd9b0964843d8c163950491d2138af891377bc1d",
    "RepoTags": [],
    "Created": "2022-11-16T06:55:28.566254104Z",
    "DockerVersion": "20.10.12",
    "Labels": null,
    "Architecture": "amd64",
    "Os": "linux",
    "Layers": [
        "sha256:a8ca11554fce00d9177da2d76307bdc06df7faeb84529755c648ac4886192ed1",
        "sha256:e4e46864aba2e62ba7c75965e4aa33ec856ee1b1074dda6b478101c577b63abd",
        "..."
    ],
    "LayersData": [
        {
            "MIMEType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
            "Digest": "sha256:a8ca11554fce00d9177da2d76307bdc06df7faeb84529755c648ac4886192ed1",
            "Size": 55038615,
            "Annotations": null
        },
        {
            "MIMEType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
            "Digest": "sha256:e4e46864aba2e62ba7c75965e4aa33ec856ee1b1074dda6b478101c577b63abd",
            "Size": 5164893,
            "Annotations": null
        },
        "..."
    ],
    "Env": [
        "PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "LANG=C.UTF-8",
        "...",
    ]
}
```

```console
$ /bin/skopeo inspect --config docker://registry.fedoraproject.org/fedora --format "{{ .Architecture }}"
amd64
```

```console
$ /bin/skopeo inspect --format '{{ .Env }}' docker://registry.access.redhat.com/ubi8
[PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin container=oci]
```

To get the digest using a specific algorithm:
```console
$ skopeo inspect --manifest-digest=sha512 docker://docker.io/library/alpine:latest --format "Digest: {{.Digest}}"
Digest: sha512:5acb33fb56a7791bf0c69d5b19a1c70272148e4107be5261d57305d14e9509792bbca53e5277c456181ecfa1c20ad8427f9b8ba46868020584a819de1128dbd2
```

## SEE ALSO
skopeo(1), skopeo-login(1), docker-login(1), containers-auth.json(5)

## AUTHORS

Antonio Murdaca <runcom@redhat.com>, Miloslav Trmac <mitr@redhat.com>, Jhon Honce <jhonce@redhat.com>

---

### Skopeo List Tags.1 (`docs/skopeo-list-tags.1.md`)

% skopeo-list-tags(1)

## NAME
skopeo\-list\-tags - List image names in a transport-specific collection of images.

## SYNOPSIS
**skopeo list-tags** [*options*] _source-image_

Return a list of tags from _source-image_ in a registry or a local docker-archive file.

  _source-image_ name of the repository to retrieve a tag listing from or a local docker-archive file.

## OPTIONS

See also [skopeo(1)](skopeo.1.md) for options placed before the subcommand name.

**--authfile** _path_

Path of the updated registry credentials file. On Linux, the default is ${XDG\_RUNTIME\_DIR}/containers/auth.json.
See **containers-auth.json**(5) for more details about the credential search mechanism and defaults on other platforms.

Use `skopeo login` to manage the credentials.

The default value of this option is read from the `REGISTRY\_AUTH\_FILE` environment variable.

**--creds** _username[:password]_ for accessing the registry.

**--cert-dir** _path_

Use certificates at _path_ (\*.crt, \*.cert, \*.key) to connect to the registry.

**--help**, **-h**

Print usage statement

**--no-creds**

Access the registry anonymously.

**--registry-token** _Bearer token_

Bearer token for accessing the registry.

**--retry-times**

The number of times to retry. By default, no retries are attempted.

**--retry-delay**

Fixed delay between retries. If not set (or set to 0s), retry wait time will be exponentially increased based on the number of failed attempts.

**--tls-verify**=_bool_

Require HTTPS and verify certificates when talking to the container registry or daemon. Default to registry.conf setting.

**--username**

The username to access the registry.

**--password**

The password to access the registry.

## REPOSITORY NAMES

Repository names are transport-specific references as each transport may have its own concept of a "repository" and "tags".

This commands refers to repositories using a _transport_`:`_details_ format. The following formats are supported:

  **docker://**_docker-repository-reference_
  A repository in a registry implementing the "Docker Registry HTTP API V2".
  A _docker-repository-reference_ is of the form: **registryhost:port/repositoryname** which is similar to an _image-reference_ but with no tag or digest allowed as the last component (e.g no `:latest` or `@sha256:xyz`)

      Examples of valid docker-repository-references:
        "docker.io/myuser/myrepo"
        "docker.io/nginx"
        "docker.io/library/fedora"
        "localhost:5000/myrepository"

      Examples of invalid references:
        "docker.io/nginx:latest"
        "docker.io/myuser/myimage:v1.0"
        "docker.io/myuser/myimage@sha256:f48c4cc192f4c3c6a069cb5cca6d0a9e34d6076ba7c214fd0cc3ca60e0af76bb"

  **docker-archive:**_path_[**:**_docker-reference_]
  Images stored in a `docker save`-formatted file

## EXAMPLES

### Docker Transport
To get the list of tags in the "fedora" repository from the docker.io registry (the repository name expands to "library/fedora" per docker transport canonical form):
```console
$ skopeo list-tags docker://docker.io/fedora
{
    "Repository": "docker.io/library/fedora",
    "Tags": [
        "20",
        "21",
        "22",
        "23",
        "24",
        "25",
        "26-modular",
        "26",
        "27",
        "28",
        "29",
        "30",
        "31",
        "32",
        "branched",
        "heisenbug",
        "latest",
        "modular",
        "rawhide"
    ]
}

```

To list the tags in a local host docker/distribution registry on port 5000, in this case for the "fedora" repository:

```console
$ skopeo list-tags docker://localhost:5000/fedora
{
    "Repository": "localhost:5000/fedora",
    "Tags": [
        "latest",
        "30",
        "31"
    ]
}

```

### Docker-archive Transport

To list the tags in a local docker-archive file:

```console
$ skopeo list-tags docker-archive:/tmp/busybox.tar.gz
{
    "Tags": [
        "busybox:1.28.3"
    ]
}
```

Also supports more than one tags in an archive:

```console
$ skopeo list-tags docker-archive:/tmp/docker-two-images.tar.gz
{
    "Tags": [
        "example.com/empty:latest",
        "example.com/empty/but:different"
    ]
}
```

Will include a source-index entry for each untagged image:

```console
$ skopeo list-tags docker-archive:/tmp/four-tags-with-an-untag.tar
{
    "Tags": [
        "image1:tag1",
        "image2:tag2",
        "@2",
        "image4:tag4"
    ]
}
```


## SEE ALSO
skopeo(1), skopeo-login(1), docker-login(1), containers-auth.json(5), containers-transports(1)

## AUTHORS

Zach Hill <zach@anchore.com>

---

### Skopeo Login.1 (`docs/skopeo-login.1.md`)

% skopeo-login(1)

## NAME
skopeo\-login - Login to a container registry.

## SYNOPSIS
**skopeo login** [*options*] _registry_

## DESCRIPTION
**skopeo login** logs into a specified registry server with the correct username
and password. **skopeo login** reads in the username and password from STDIN.
The username and password can also be set using the **username** and **password** flags.
The path of the credentials file can be specified by the user by setting the **authfile**
flag.

## OPTIONS

See also [skopeo(1)](skopeo.1.md) for options placed before the subcommand name.

**--password**, **-p**=*password*

Password for registry

**--password-stdin**

Take the password from stdin

**--username**, **-u**=*username*

Username for registry

**--authfile**=*path*

Path of the managed registry credentials file. On Linux, the default is ${XDG\_RUNTIME\_DIR}/containers/auth.json.
See **containers-auth.json**(5) for more details about the default on other platforms.

The default value of this option is read from the `REGISTRY\_AUTH\_FILE` environment variable.

**--compat-auth-file**=*path*

Instead of updating the default credentials file, update the one at *path*, and use a Docker-compatible format.

**--get-login**

Return the logged-in user for the registry. Return error if no login is found.

**--cert-dir**=*path*

Use certificates at *path* (\*.crt, \*.cert, \*.key) to connect to the registry.
Default certificates directory is _/etc/containers/certs.d_.

**--help**, **-h**

Print usage statement

**--tls-verify**=_bool_

Require HTTPS and verify certificates when talking to the container registry or daemon. Default to registry.conf setting.

**--verbose**, **-v**

Write more detailed information to stdout

## EXAMPLES

```console
$ skopeo login docker.io
Username: testuser
Password:
Login Succeeded!
```

```console
$ skopeo login -u testuser -p testpassword localhost:5000
Login Succeeded!
```

```console
$ skopeo login --authfile authdir/myauths.json docker.io
Username: testuser
Password:
Login Succeeded!
```

```console
$ skopeo login --tls-verify=false -u test -p test localhost:5000
Login Succeeded!
```

```console
$ skopeo login --cert-dir /etc/containers/certs.d/ -u foo -p bar localhost:5000
Login Succeeded!
```

```console
$ skopeo login -u testuser  --password-stdin < testpassword.txt docker.io
Login Succeeded!
```

```console
$ echo $testpassword | skopeo login -u testuser --password-stdin docker.io
Login Succeeded!
```

## SEE ALSO
skopeo(1), skopeo-logout(1), containers-auth.json(5), containers-registries.conf(5), containers-certs.d.5.md

## HISTORY
May 2020, Originally compiled by Qi Wang <qiwan@redhat.com>

---

### Skopeo Logout.1 (`docs/skopeo-logout.1.md`)

% skopeo-logout(1)

## NAME
skopeo\-logout - Logout of a container registry.

## SYNOPSIS
**skopeo logout** [*options*] _registry_

## DESCRIPTION
**skopeo logout** logs out of a specified registry server by deleting the cached credentials
stored in the **auth.json** file. The path of the credentials file can be overridden by the user by setting the **authfile** flag.
All the cached credentials can be removed by setting the **all** flag.

## OPTIONS

See also [skopeo(1)](skopeo.1.md) for options placed before the subcommand name.

**--authfile**=*path*

Path of the managed registry credentials file. On Linux, the default is ${XDG\_RUNTIME\_DIR}/containers/auth.json.
See **containers-auth.json**(5) for more details about the default on other platforms.

The default value of this option is read from the `REGISTRY\_AUTH\_FILE` environment variable.

**--compat-auth-file**=*path*

Instead of updating the default credentials file, update the one at *path*, and use a Docker-compatible format.

**--all**, **-a**

Remove the cached credentials for all registries in the auth file

**--help**, **-h**

Print usage statement

**--tls-verify**=_bool_

Require HTTPS and verify certificates when talking to the container registry or daemon. Default to registry.conf setting.

## EXAMPLES

```console
$ skopeo logout docker.io
Remove login credentials for docker.io
```

```console
$ skopeo logout --authfile authdir/myauths.json docker.io
Remove login credentials for docker.io
```

```console
$ skopeo logout --all
Remove login credentials for all registries
```

## SEE ALSO
skopeo(1), skopeo-login(1), containers-auth.json(5)

## HISTORY
May 2020, Originally compiled by Qi Wang <qiwan@redhat.com>

---

### Skopeo Manifest Digest.1 (`docs/skopeo-manifest-digest.1.md`)

% skopeo-manifest-digest(1)

## NAME
skopeo\-manifest\-digest - Compute a manifest digest for a manifest-file and write it to standard output.

## SYNOPSIS
**skopeo manifest-digest** _manifest-file_

## DESCRIPTION

Compute a manifest digest of _manifest-file_ and write it to standard output.

## OPTIONS

**--help**, **-h**

Print usage statement

## EXAMPLES

```console
$ skopeo manifest-digest manifest.json
sha256:a59906e33509d14c036c8678d687bd4eec81ed7c4b8ce907b888c607f6a1e0e6
```

## SEE ALSO
skopeo(1)

## AUTHORS

Antonio Murdaca <runcom@redhat.com>, Miloslav Trmac <mitr@redhat.com>, Jhon Honce <jhonce@redhat.com>

---

### Skopeo Standalone Sign.1 (`docs/skopeo-standalone-sign.1.md`)

% skopeo-standalone-sign(1)

## NAME
skopeo\-standalone-sign - Debugging tool - Sign an image locally without uploading.

## SYNOPSIS
**skopeo standalone-sign** [*options*] _manifest_ _docker-reference_ _key-fingerprint_ **--output**|**-o** _signature_

## DESCRIPTION
This is primarily a debugging tool, useful for special cases, and usually should not be a part of your normal operational workflow; use `skopeo copy --sign-by` instead to publish and sign an image in one step.

  _manifest_ Path to a file containing the image manifest

  _docker-reference_ A docker reference to identify the image with

  _key-fingerprint_ Key identity to use for signing

## OPTIONS

See also [skopeo(1)](skopeo.1.md) for options placed before the subcommand name.

**--help**, **-h**

Print usage statement

**--output**, **-o** _output file_

Write signature to _output file_.

**--passphrase-file**=_path_

The passphare to use when signing with the key ID from `--sign-by`. Only the first line will be read. A passphrase stored in a file is of questionable security if other users can read this file. Do not use this option if at all avoidable.

## EXAMPLES

```console
$ skopeo standalone-sign busybox-manifest.json registry.example.com/example/busybox 1D8230F6CDB6A06716E414C1DB72F2188BB46CC8 --output busybox.signature
$
```

## NOTES

This command is intended for use with local signatures e.g. OpenPGP ( other signature formats may be added in the future ), as per containers-signature(5). Furthermore, this command does **not** interact with the artifacts generated by Docker Content Trust (DCT). For more information, please see [containers-signature(5)](https://github.com/containers/image/blob/main/docs/containers-signature.5.md).

## SEE ALSO
skopeo(1), skopeo-copy(1), containers-signature(5)

## AUTHORS

Antonio Murdaca <runcom@redhat.com>, Miloslav Trmac <mitr@redhat.com>, Jhon Honce <jhonce@redhat.com>

---

### Skopeo Standalone Verify.1 (`docs/skopeo-standalone-verify.1.md`)

% skopeo-standalone-verify(1)

## NAME
skopeo\-standalone\-verify - Debugging tool - Verify an image signature from local files.

## SYNOPSIS
**skopeo standalone-verify** _manifest_ _docker-reference_ _key-fingerprints_ _signature_

## DESCRIPTION

Verify a signature using local files; the digest will be printed on success. This is primarily a debugging tool, useful for special cases,
and usually should not be a part of your normal operational workflow. Additionally, consider configuring a signature verification policy file,
as per containers-policy.json(5).

  _manifest_ Path to a file containing the image manifest

  _docker-reference_ A docker reference expected to identify the image in the signature

  _key-fingerprints_ Identities of trusted signing keys (comma separated), or "any" to trust any known key when using a public key file

  _signature_ Path to signature file

**Note:** If you do use this, make sure that the image can not be changed at the source location between the times of its verification and use.

## OPTIONS

See also [skopeo(1)](skopeo.1.md) for options placed before the subcommand name.

**--help**, **-h**

Print usage statement

**--public-key-file** _public key file_

File containing the public keys to use when verifying signatures. If this is not specified, keys from the GPG homedir are used.

## EXAMPLES

```console
$ skopeo standalone-verify busybox-manifest.json registry.example.com/example/busybox 1D8230F6CDB6A06716E414C1DB72F2188BB46CC8  busybox.signature
Signature verified, digest sha256:20bf21ed457b390829cdbeec8795a7bea1626991fda603e0d01b4e7f60427e55
```

## NOTES

This command is intended for use with local signatures e.g. OpenPGP ( other signature formats may be added in the future ), as per containers-signature(5). Furthermore, this command does **not** interact with the artifacts generated by Docker Content Trust (DCT). For more information, please see [containers-signature(5)](https://github.com/containers/image/blob/main/docs/containers-signature.5.md).

## SEE ALSO
skopeo(1), containers-signature(5), containers-policy.json(5)

## AUTHORS

Antonio Murdaca <runcom@redhat.com>, Miloslav Trmac <mitr@redhat.com>, Jhon Honce <jhonce@redhat.com>

---

### Skopeo Sync.1 (`docs/skopeo-sync.1.md`)

% skopeo-sync(1)

## NAME
skopeo\-sync - Synchronize images between registry repositories and local directories.


## SYNOPSIS
**skopeo sync** [*options*] --src _transport_ --dest _transport_ _source_ _destination_

## DESCRIPTION
Synchronize images between registry repositories and local directories. Synchronization is achieved by copying all the images found at _source_ to _destination_ - useful when synchronizing a local container registry mirror or for populating registries running inside of air-gapped environments.

Differently from other skopeo commands, skopeo sync requires both source and destination transports to be specified separately from _source_ and _destination_.
One of the problems of prefixing a destination with its transport is that, the registry `docker://hostname:port` would be wrongly interpreted as an image reference at a non-fully qualified registry, with `hostname` and `port` the image name and tag.

Available _source_ transports:
 - _docker_ (i.e. `--src docker`): _source_ is a repository hosted on a container registry (e.g.: `registry.example.com/busybox`).
 If no image tag is specified, skopeo sync copies all the tags found in that repository.
 - _dir_ (i.e. `--src dir`): _source_ is a local directory path (e.g.: `/media/usb/`). Refer to skopeo(1) **dir:**_path_ for the local image format.
 - _yaml_ (i.e. `--src yaml`): _source_ is local YAML file path.
 The YAML file should specify the list of images copied from different container registries (local directories are not supported). Refer to EXAMPLES for the file format.

Available _destination_ transports:
 - _docker_ (i.e. `--dest docker`): _destination_ is a container registry (e.g.: `my-registry.local.lan`).
 - _dir_ (i.e. `--dest dir`): _destination_ is a local directory path (e.g.: `/media/usb/`).
 One directory per source 'image:tag' is created for each copied image.

When the `--scoped` option is specified, images are prefixed with the source image path so that multiple images with the same
name can be stored at _destination_.

## OPTIONS

See also [skopeo(1)](skopeo.1.md) for options placed before the subcommand name.

**--all**, **-a**
If one of the images in __src__ refers to a list of images, instead of copying just the image which matches the current OS and
architecture (subject to the use of the global --override-os, --override-arch and --override-variant options), attempt to copy all of
the images in the list, and the list itself.

**--authfile** _path_

Path of the primary registry credentials file. On Linux, the default is ${XDG\_RUNTIME\_DIR}/containers/auth.json.
See **containers-auth.json**(5) for more details about the credential search mechanism and defaults on other platforms.

Use `skopeo login` to manage the credentials.

The default value of this option is read from the `REGISTRY\_AUTH\_FILE` environment variable.

**--src-authfile** _path_

Path of the primary registry credentials file for the source registry. Uses path given by `--authfile`, if not provided.

**--dest-authfile** _path_

Path of the primary registry credentials file for the destination registry. Uses path given by `--authfile`, if not provided.

**--dry-run**

Run the sync without actually copying data to the destination.

**--src**, **-s** _transport_ Transport for the source repository.

**--dest**, **-d** _transport_ Destination transport.

**--format**, **-f** _manifest-type_ Manifest Type (oci, v2s1, or v2s2) to use when syncing image(s) to a destination (default is manifest type of source, with fallbacks).

**--help**, **-h**

Print usage statement

**--scoped** Prefix images with the source image path, so that multiple images with the same name can be stored at _destination_.

**--append-suffix** _tag-suffix_ String to append to destination tags.

**--digestfile** _path_

After copying the images from source, write the digest of the resulting images along with Image Reference.

```
sha256:bf91f90823248017a4f920fb541727fa8368dc6cf377a7debbd271cf6a31c8a7 docker://myhost.com/alpine:edge
sha256:31603596830fc7e56753139f9c2c6bd3759e48a850659506ebfb885d1cf3aef5 docker://myhost.com/postgres:14.3

```

**--preserve-digests**

Preserve the digests during copying. Fail if the digest cannot be preserved.

This option does not change what will be copied; consider using `--all` at the same time.

**--download-foreign-layers**

Copy the contents of nondistributable ("foreign") layers, such as Windows base layers, to the destination. This overrides the normal behavior for destinations that support foreign-layer URL references. Other destinations copy the contents regardless of the flag.

This flag does not change the foreign layer's media type or `urls` field. Other manifest conversions may still occur.

**--remove-signatures** Do not copy signatures, if any, from _source-image_. This is necessary when copying a signed image to a destination which does not support signatures.

**--remove-list-signatures**

Do not copy the manifest list signature while preserving per-instance signatures. This provides more granular control than **--remove-signatures**, which removes all signatures.

**--sign-by** _key-id_

Add a “simple signing” signature using that key ID for an image name corresponding to _destination-image_

**--sign-by-sigstore** _param-file_

Add a sigstore signature based on the options in the specified containers sigstore signing parameter file, _param-file_.
See containers-sigstore-signing-params.yaml(5) for details about the file format.

**--sign-by-sigstore-private-key** _path_

Add a sigstore signature using a private key at _path_ for an image name corresponding to _destination-image_

**--sign-by-sq-fingerprint** _fingerprint_

Add a “simple signing” signature using a Sequoia-PGP key with the specified _fingerprint_.

**--sign-passphrase-file** _path_

The passphrase to use when signing with `--sign-by`, `--sign-by-sigstore-private-key` or `--sign-by-sq-fingerprint`.
Only the first line will be read. A passphrase stored in a file is of questionable security if other users can read this file. Do not use this option if at all avoidable.

**--src-creds** _username[:password]_ for accessing the source registry.

**--dest-creds** _username[:password]_ for accessing the destination registry.

**--src-cert-dir** _path_ Use certificates (*.crt, *.cert, *.key) at _path_ to connect to the source registry or daemon.

**--src-no-creds** Access the registry anonymously.

**--src-tls-verify**=_bool_ Require HTTPS and verify certificates when talking to a container source registry or daemon. Default to source registry entry in registry.conf setting.

**--dest-cert-dir** _path_ Use certificates (*.crt, *.cert, *.key) at _path_ to connect to the destination registry or daemon.

**--dest-no-creds** Access the registry anonymously.

**--dest-tls-verify**=_bool_ Require HTTPS and verify certificates when talking to a container destination registry or daemon. Default to destination registry entry in registry.conf setting.

**--src-registry-token** _Bearer token_ for accessing the source registry.

**--dest-registry-token** _Bearer token_ for accessing the destination registry.

**--retry-times**

The number of times to retry. By default, no retries are attempted.

**--retry-delay**

Fixed delay between retries. If not set (or set to 0s), retry wait time will be exponentially increased based on the number of failed attempts.

**--keep-going**
If any errors occur during copying of images, those errors are logged and the process continues syncing rest of the images and finally fails at the end.

**--src-username**

The username to access the source registry.

**--src-password**

The password to access the source registry.

**--dest-username**

The username to access the destination registry.

**--dest-password**

The password to access the destination registry.

## EXAMPLES

### Synchronizing to a local directory
```console
$ skopeo sync --src docker --dest dir registry.example.com/busybox /media/usb
```
Images are located at:
```
/media/usb/busybox:1-glibc
/media/usb/busybox:1-musl
/media/usb/busybox:1-ubuntu
...
/media/usb/busybox:latest
```

### Synchronizing to a container registry from local
Images are located at:
```
/media/usb/busybox:1-glibc
```
Sync run
```console
$ skopeo sync --src dir --dest docker /media/usb/busybox:1-glibc my-registry.local.lan/test/
```
Destination registry content:
```
REPO                                 TAGS
my-registry.local.lan/test/busybox   1-glibc
```

### Synchronizing to a local directory, scoped
```console
$ skopeo sync --src docker --dest dir --scoped registry.example.com/busybox /media/usb
```
Images are located at:
```
/media/usb/registry.example.com/busybox:1-glibc
/media/usb/registry.example.com/busybox:1-musl
/media/usb/registry.example.com/busybox:1-ubuntu
...
/media/usb/registry.example.com/busybox:latest
```

### Synchronizing to a container registry
```console
$ skopeo sync --src docker --dest docker registry.example.com/busybox my-registry.local.lan
```
Destination registry content:
```
REPO                         TAGS
registry.local.lan/busybox   1-glibc, 1-musl, 1-ubuntu, ..., latest
```

### Synchronizing to a container registry keeping the repository
```console
$ skopeo sync --src docker --dest docker registry.example.com/repo/busybox my-registry.local.lan/repo
```
Destination registry content:
```
REPO                              TAGS
registry.local.lan/repo/busybox   1-glibc, 1-musl, 1-ubuntu, ..., latest
```

### Synchronizing to a container registry with tag suffix
```console
$ skopeo sync --src docker --dest docker --append-suffix '-mirror' registry.example.com/busybox my-registry.local.lan
```
Destination registry content:
```
REPO                         TAGS
registry.local.lan/busybox   1-glibc-mirror, 1-musl-mirror, 1-ubuntu-mirror, ..., latest-mirror
```

### YAML file content (used _source_ for `**--src yaml**`)

```yaml
registry.example.com:
    images:
        busybox: []
        redis:
            - "1.0"
            - "2.0"
            - "sha256:0000000000000000000000000000000011111111111111111111111111111111"
    images-by-tag-regex:
        nginx: ^1\.13\.[12]-alpine-perl$
    images-by-semver:
        alpine: ">= 3.12.0"
    credentials:
        username: john
        password: this is a secret
    tls-verify: true
    cert-dir: /home/john/certs
quay.io:
    tls-verify: false
    images:
        coreos/etcd:
            - latest
```
If the yaml filename is `sync.yml`, sync run:
```console
$ skopeo sync --src yaml --dest docker sync.yml my-registry.local.lan/repo/
```
This will copy the following images:
- Repository `registry.example.com/busybox`: all images, as no tags are specified.
- Repository `registry.example.com/redis`: images tagged "1.0" and "2.0" along with image with digest "sha256:0000000000000000000000000000000011111111111111111111111111111111".
- Repository `registry.example.com/nginx`: images tagged "1.13.1-alpine-perl" and "1.13.2-alpine-perl".
- Repository `quay.io/coreos/etcd`: images tagged "latest".
- Repository `registry.example.com/alpine`: all images with tags match the semantic version constraint ">= 3.12.0" ("3.12.0, "3.12.1", ... ,"4.0.0", ...)

The full list of possible semantic version comparisons can be found in the
upstream library's documentation:
https://github.com/Masterminds/semver/tree/v3.2.0#basic-comparisons.

Version ordering and precedence is understood as defined here:
https://semver.org/#spec-item-11.

For the registry `registry.example.com`, the "john"/"this is a secret" credentials are used, with server TLS certificates located at `/home/john/certs`.

TLS verification is normally enabled, and it can be disabled setting `tls-verify` to `false`.
In the above example, TLS verification is enabled for `registry.example.com`, while is
disabled for `quay.io`.

## SEE ALSO
skopeo(1), skopeo-login(1), docker-login(1), containers-auth.json(5), containers-policy.json(5), containers-transports(5)

## AUTHORS

Flavio Castelli <fcastelli@suse.com>, Marco Vedovati <mvedovati@suse.com>

---

### Skopeo.1 (`docs/skopeo.1.md`)

% SKOPEO(1) Skopeo Man Pages
% Jhon Honce
% August 2016
## NAME
skopeo -- Command line utility used to interact with local and remote container images and container image registries

## SYNOPSIS
**skopeo** [_global options_] _command_ [_command options_]

## DESCRIPTION
`skopeo` is a command line utility providing various operations with container images and container image registries.

`skopeo` can copy container images between various containers image stores, converting them as necessary.  For example you can use `skopeo` to copy container images from one container registry to another.

`skopeo` can convert a Docker schema 2 or schema 1 container image to an OCI image.

`skopeo` can inspect a repository on a container registry without needlessly pulling the image. Pulling an image from a repository, especially a remote repository, is an expensive network and storage operation. Skopeo fetches the repository's manifest and displays a `docker inspect`-like json output about the repository or a tag. `skopeo`, in contrast to `docker inspect`, helps you gather useful information about a repository or a tag without requiring you to run `docker pull` - e.g. - Which tags are available for the given repository? Which labels does the image have?

`skopeo` can sign and verify container images.

`skopeo` can delete container images from a remote container registry.

Note: `skopeo` does not require any container runtimes to be running to do most of
its functionality.  It also does not require root, unless you are copying images into a container runtime storage backend, like the docker daemon or github.com/containers/storage.

## IMAGE NAMES
Most commands refer to container images, using a _transport_`:`_details_ format. The following formats are supported:

  **containers-storage:**_docker-reference_
  An image located in a local containers/storage image store.  Both the location and image store are specified in /etc/containers/storage.conf. (Backend for Podman, CRI-O, Buildah and friends)

  **dir:**_path_
  An existing local directory _path_ storing the manifest, layer tarballs and signatures as individual files. This is a non-standardized format, primarily useful for debugging or noninvasive container inspection.

  **docker://**_docker-reference_
  An image in a registry implementing the "Docker Registry HTTP API V2".
  Credentials are typically managed using `(skopeo login)`;
  see **containers-auth.json**(5) for more details about the credential search mechanism.

  **docker-archive:**_path_[**:**_docker-reference_]
  An image is stored in the `docker save` formatted file.  _docker-reference_ is only used when creating such a file, and it must not contain a digest.

  **docker-daemon:**_docker-reference_
  An image _docker-reference_ stored in the docker daemon internal storage.  _docker-reference_ must contain either a tag or a digest.  Alternatively, when reading images, the format can be docker-daemon:algo:digest (an image ID).

  **oci:**_path_**:**_tag_
  An image _tag_ in a directory compliant with "Open Container Image Layout Specification" at _path_.

  **oci-archive:**_path_**:**_tag_
  An image _tag_ in a tar archive compliant with "Open Container Image Layout Specification" at _path_.

See [containers-transports(5)](https://github.com/containers/image/blob/main/docs/containers-transports.5.md) for details.

## OPTIONS

These options should be placed before the subcommand name.
Individual subcommands have their own options.

**--command-timeout** _duration_

Timeout for the command execution (e.g. 30s, 10m).

**--debug**

enable debug output

**--help**, **-h**

Show help

**--insecure-policy**

Adopt an insecure, permissive policy that allows anything. This obviates the need for a policy file.

**--override-arch** _arch_

Use _arch_ instead of the architecture of the machine for choosing images.

**--override-os** _os_

Use _OS_ instead of the running OS for choosing images.

**--override-variant** _variant_

Use _variant_ instead of the running architecture variant for choosing images.

**--policy** _path-to-policy_

Path to a policy.json file to use for verifying signatures and deciding whether an image is trusted, overriding the default trust policy file.

**--registries.d** _dir_

Use registry configuration files in _dir_ (e.g. for container signature storage), overriding the default path.

**--require-signed**

Require that any pulled image must be signed regardless of what the default or provided trust policy file says.

**--tls-details** _path_

Path to a containers-tls-details(5) file, affecting TLS behavior throughout the program.

If not set, defaults to a reasonable default that may change over time (depending on system’s global policy,
version of the program, version of the Go language, and the like).

Users should generally not use this option unless they have a process to ensure that the configuration will be kept up to date.

**--tmpdir** _dir_

Directory used to store temporary files. Defaults to /var/tmp.

**--user-agent-prefix** _prefix_

Prefix to add to the user agent string. The resulting user agent will be in the format "_prefix_ skopeo/_version_".

**--version**, **-v**

Print the version number

## COMMANDS

| Command                                   | Description                                                                    |
| ----------------------------------------- | ------------------------------------------------------------------------------ |
| [skopeo-copy(1)](skopeo-copy.1.md)        | Copy an image (manifest, filesystem layers, signatures) from one location to another. |
| [skopeo-delete(1)](skopeo-delete.1.md)    | Mark the _image-name_ for later deletion by the registry's garbage collector.  |
| [skopeo-generate-sigstore-key(1)](skopeo-generate-sigstore-key.1.md)    | Generate a sigstore public/private key pair.  |
| [skopeo-inspect(1)](skopeo-inspect.1.md)  | Return low-level information about _image-name_ in a registry.                 |
| [skopeo-list-tags(1)](skopeo-list-tags.1.md)  | List image names in a transport-specific collection of images.|
| [skopeo-login(1)](skopeo-login.1.md)  | Login to a container registry. |
| [skopeo-logout(1)](skopeo-logout.1.md)  | Logout of a container registry. |
| [skopeo-manifest-digest(1)](skopeo-manifest-digest.1.md)    | Compute a manifest digest for a manifest-file and write it to standard output. |
| [skopeo-standalone-sign(1)](skopeo-standalone-sign.1.md)    | Debugging tool - Sign an image locally without uploading.    |
| [skopeo-standalone-verify(1)](skopeo-standalone-verify.1.md)| Debugging tool - Verify an image signature from local files. |
| [skopeo-sync(1)](skopeo-sync.1.md)| Synchronize images between registry repositories and local directories.                |

## EXIT STATUS
`skopeo` exits with status 0 on success, non-zero on error.

Details about the exit statuses:

**1** Generic error, details can be found in the error message.

**2** The input image cannot be found. Note that this is best effort and for remote registries the status often cannot be reliably reported.

## FILES
  **/etc/containers/policy.json**
  Default trust policy file, if **--policy** is not specified.
  The policy format is documented in [containers-policy.json(5)](https://github.com/containers/image/blob/main/docs/containers-policy.json.5.md) .

  **/etc/containers/registries.d**
  Default directory containing registry configuration, if **--registries.d** is not specified.
  The contents of this directory are documented in [containers-registries.d(5)](https://github.com/containers/image/blob/main/docs/containers-registries.d.5.md).

## SEE ALSO
skopeo-login(1), docker-login(1), containers-auth.json(5), containers-storage.conf(5), containers-policy.json(5), containers-transports(5)

## AUTHORS

Antonio Murdaca <runcom@redhat.com>, Miloslav Trmac <mitr@redhat.com>, Jhon Honce <jhonce@redhat.com>

---

--- METRICS ---
- Files Extracted: 102
- Estimated Token Budget: ~105554 tokens
- Canonical Reference: https://codewiki.google/github.com/containers/skopeo
