diff options
Diffstat (limited to 'vendor/github.com')
49 files changed, 241 insertions, 3387 deletions
diff --git a/vendor/github.com/containers/image/v5/docker/docker_image_dest.go b/vendor/github.com/containers/image/v5/docker/docker_image_dest.go index 7111c5612..56c39c141 100644 --- a/vendor/github.com/containers/image/v5/docker/docker_image_dest.go +++ b/vendor/github.com/containers/image/v5/docker/docker_image_dest.go @@ -17,9 +17,9 @@ import ( "github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/internal/blobinfocache" "github.com/containers/image/v5/internal/putblobdigest" + "github.com/containers/image/v5/internal/streamdigest" "github.com/containers/image/v5/internal/uploadreader" "github.com/containers/image/v5/manifest" - "github.com/containers/image/v5/pkg/blobinfocache/none" "github.com/containers/image/v5/types" "github.com/docker/distribution/registry/api/errcode" v2 "github.com/docker/distribution/registry/api/v2" @@ -131,11 +131,23 @@ func (d *dockerImageDestination) HasThreadSafePutBlob() bool { // to any other readers for download using the supplied digest. // If stream.Read() at any time, ESPECIALLY at end of input, returns an error, PutBlob MUST 1) fail, and 2) delete any data stored so far. func (d *dockerImageDestination) PutBlob(ctx context.Context, stream io.Reader, inputInfo types.BlobInfo, cache types.BlobInfoCache, isConfig bool) (types.BlobInfo, error) { + // If requested, precompute the blob digest to prevent uploading layers that already exist on the registry. + // This functionality is particularly useful when BlobInfoCache has not been populated with compressed digests, + // the source blob is uncompressed, and the destination blob is being compressed "on the fly". + if inputInfo.Digest == "" && d.c.sys.DockerRegistryPushPrecomputeDigests { + logrus.Debugf("Precomputing digest layer for %s", reference.Path(d.ref.ref)) + streamCopy, cleanup, err := streamdigest.ComputeBlobInfo(d.c.sys, stream, &inputInfo) + if err != nil { + return types.BlobInfo{}, err + } + defer cleanup() + stream = streamCopy + } + if inputInfo.Digest != "" { // This should not really be necessary, at least the copy code calls TryReusingBlob automatically. // Still, we need to check, if only because the "initiate upload" endpoint does not have a documented "blob already exists" return value. - // But we do that with NoCache, so that it _only_ checks the primary destination, instead of trying all mount candidates _again_. - haveBlob, reusedInfo, err := d.TryReusingBlob(ctx, inputInfo, none.NoCache, false) + haveBlob, reusedInfo, err := d.tryReusingExactBlob(ctx, inputInfo, cache) if err != nil { return types.BlobInfo{}, err } @@ -282,6 +294,21 @@ func (d *dockerImageDestination) mountBlob(ctx context.Context, srcRepo referenc } } +// tryReusingExactBlob is a subset of TryReusingBlob which _only_ looks for exactly the specified +// blob in the current repository, with no cross-repo reuse or mounting; cache may be updated, it is not read. +// The caller must ensure info.Digest is set. +func (d *dockerImageDestination) tryReusingExactBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache) (bool, types.BlobInfo, error) { + exists, size, err := d.blobExists(ctx, d.ref.ref, info.Digest, nil) + if err != nil { + return false, types.BlobInfo{}, err + } + if exists { + cache.RecordKnownLocation(d.ref.Transport(), bicTransportScope(d.ref), info.Digest, newBICLocationReference(d.ref)) + return true, types.BlobInfo{Digest: info.Digest, MediaType: info.MediaType, Size: size}, nil + } + return false, types.BlobInfo{}, nil +} + // TryReusingBlob checks whether the transport already contains, or can efficiently reuse, a blob, and if so, applies it to the current destination // (e.g. if the blob is a filesystem layer, this signifies that the changes it describes need to be applied again when composing a filesystem tree). // info.Digest must not be empty. @@ -297,13 +324,12 @@ func (d *dockerImageDestination) TryReusingBlob(ctx context.Context, info types. } // First, check whether the blob happens to already exist at the destination. - exists, size, err := d.blobExists(ctx, d.ref.ref, info.Digest, nil) + haveBlob, reusedInfo, err := d.tryReusingExactBlob(ctx, info, cache) if err != nil { return false, types.BlobInfo{}, err } - if exists { - cache.RecordKnownLocation(d.ref.Transport(), bicTransportScope(d.ref), info.Digest, newBICLocationReference(d.ref)) - return true, types.BlobInfo{Digest: info.Digest, MediaType: info.MediaType, Size: size}, nil + if haveBlob { + return true, reusedInfo, nil } // Then try reusing blobs from other locations. diff --git a/vendor/github.com/containers/image/v5/docker/docker_image_src.go b/vendor/github.com/containers/image/v5/docker/docker_image_src.go index f2e9eb17b..314e9b394 100644 --- a/vendor/github.com/containers/image/v5/docker/docker_image_src.go +++ b/vendor/github.com/containers/image/v5/docker/docker_image_src.go @@ -236,6 +236,9 @@ func (s *dockerImageSource) ensureManifestIsLoaded(ctx context.Context) error { return nil } +// getExternalBlob returns the reader of the first available blob URL from urls, which must not be empty. +// This function can return nil reader when no url is supported by this function. In this case, the caller +// should fallback to fetch the non-external blob (i.e. pull from the registry). func (s *dockerImageSource) getExternalBlob(ctx context.Context, urls []string) (io.ReadCloser, int64, error) { var ( resp *http.Response @@ -244,14 +247,17 @@ func (s *dockerImageSource) getExternalBlob(ctx context.Context, urls []string) if len(urls) == 0 { return nil, 0, errors.New("internal error: getExternalBlob called with no URLs") } - for _, url := range urls { + for _, u := range urls { + if u, err := url.Parse(u); err != nil || (u.Scheme != "http" && u.Scheme != "https") { + continue // unsupported url. skip this url. + } // NOTE: we must not authenticate on additional URLs as those // can be abused to leak credentials or tokens. Please // refer to CVE-2020-15157 for more information. - resp, err = s.c.makeRequestToResolvedURL(ctx, http.MethodGet, url, nil, nil, -1, noAuth, nil) + resp, err = s.c.makeRequestToResolvedURL(ctx, http.MethodGet, u, nil, nil, -1, noAuth, nil) if err == nil { if resp.StatusCode != http.StatusOK { - err = errors.Errorf("error fetching external blob from %q: %d (%s)", url, resp.StatusCode, http.StatusText(resp.StatusCode)) + err = errors.Errorf("error fetching external blob from %q: %d (%s)", u, resp.StatusCode, http.StatusText(resp.StatusCode)) logrus.Debug(err) resp.Body.Close() continue @@ -259,6 +265,9 @@ func (s *dockerImageSource) getExternalBlob(ctx context.Context, urls []string) break } } + if resp == nil && err == nil { + return nil, 0, nil // fallback to non-external blob + } if err != nil { return nil, 0, err } @@ -408,7 +417,12 @@ func (s *dockerImageSource) GetBlobAt(ctx context.Context, info types.BlobInfo, // May update BlobInfoCache, preferably after it knows for certain that a blob truly exists at a specific location. func (s *dockerImageSource) GetBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache) (io.ReadCloser, int64, error) { if len(info.URLs) != 0 { - return s.getExternalBlob(ctx, info.URLs) + r, s, err := s.getExternalBlob(ctx, info.URLs) + if err != nil { + return nil, 0, err + } else if r != nil { + return r, s, nil + } } path := fmt.Sprintf(blobsPath, reference.Path(s.physicalRef.ref), info.Digest.String()) diff --git a/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go b/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go index 44b0af110..7e1580990 100644 --- a/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go +++ b/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go @@ -5,13 +5,10 @@ import ( "context" "encoding/json" "io" - "io/ioutil" - "os" "github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/internal/iolimits" - "github.com/containers/image/v5/internal/putblobdigest" - "github.com/containers/image/v5/internal/tmpdir" + "github.com/containers/image/v5/internal/streamdigest" "github.com/containers/image/v5/manifest" "github.com/containers/image/v5/types" "github.com/opencontainers/go-digest" @@ -98,25 +95,11 @@ func (d *Destination) PutBlob(ctx context.Context, stream io.Reader, inputInfo t // When the layer is decompressed, we also have to generate the digest on uncompressed data. if inputInfo.Size == -1 || inputInfo.Digest == "" { logrus.Debugf("docker tarfile: input with unknown size, streaming to disk first ...") - streamCopy, err := ioutil.TempFile(tmpdir.TemporaryDirectoryForBigFiles(d.sysCtx), "docker-tarfile-blob") + streamCopy, cleanup, err := streamdigest.ComputeBlobInfo(d.sysCtx, stream, &inputInfo) if err != nil { return types.BlobInfo{}, err } - defer os.Remove(streamCopy.Name()) - defer streamCopy.Close() - - digester, stream2 := putblobdigest.DigestIfUnknown(stream, inputInfo) - // TODO: This can take quite some time, and should ideally be cancellable using ctx.Done(). - size, err := io.Copy(streamCopy, stream2) - if err != nil { - return types.BlobInfo{}, err - } - _, err = streamCopy.Seek(0, io.SeekStart) - if err != nil { - return types.BlobInfo{}, err - } - inputInfo.Size = size // inputInfo is a struct, so we are only modifying our copy. - inputInfo.Digest = digester.Digest() + defer cleanup() stream = streamCopy logrus.Debugf("... streaming done") } diff --git a/vendor/github.com/containers/image/v5/internal/streamdigest/stream_digest.go b/vendor/github.com/containers/image/v5/internal/streamdigest/stream_digest.go new file mode 100644 index 000000000..306220585 --- /dev/null +++ b/vendor/github.com/containers/image/v5/internal/streamdigest/stream_digest.go @@ -0,0 +1,41 @@ +package streamdigest + +import ( + "fmt" + "io" + "io/ioutil" + "os" + + "github.com/containers/image/v5/internal/putblobdigest" + "github.com/containers/image/v5/internal/tmpdir" + "github.com/containers/image/v5/types" +) + +// ComputeBlobInfo streams a blob to a temporary file and populates Digest and Size in inputInfo. +// The temporary file is returned as an io.Reader along with a cleanup function. +// It is the caller's responsibility to call the cleanup function, which closes and removes the temporary file. +// If an error occurs, inputInfo is not modified. +func ComputeBlobInfo(sys *types.SystemContext, stream io.Reader, inputInfo *types.BlobInfo) (io.Reader, func(), error) { + diskBlob, err := ioutil.TempFile(tmpdir.TemporaryDirectoryForBigFiles(sys), "stream-blob") + if err != nil { + return nil, nil, fmt.Errorf("creating temporary on-disk layer: %w", err) + } + cleanup := func() { + diskBlob.Close() + os.Remove(diskBlob.Name()) + } + digester, stream := putblobdigest.DigestIfCanonicalUnknown(stream, *inputInfo) + written, err := io.Copy(diskBlob, stream) + if err != nil { + cleanup() + return nil, nil, fmt.Errorf("writing to temporary on-disk layer: %w", err) + } + _, err = diskBlob.Seek(0, io.SeekStart) + if err != nil { + cleanup() + return nil, nil, fmt.Errorf("rewinding temporary on-disk layer: %w", err) + } + inputInfo.Digest = digester.Digest() + inputInfo.Size = written + return diskBlob, cleanup, nil +} diff --git a/vendor/github.com/containers/image/v5/manifest/common.go b/vendor/github.com/containers/image/v5/manifest/common.go index 4692211c0..511cdcc37 100644 --- a/vendor/github.com/containers/image/v5/manifest/common.go +++ b/vendor/github.com/containers/image/v5/manifest/common.go @@ -1,6 +1,7 @@ package manifest import ( + "encoding/json" "fmt" compressiontypes "github.com/containers/image/v5/pkg/compression/types" @@ -32,6 +33,72 @@ func dupStringStringMap(m map[string]string) map[string]string { return result } +// allowedManifestFields is a bit mask of “essential” manifest fields that validateUnambiguousManifestFormat +// can expect to be present. +type allowedManifestFields int + +const ( + allowedFieldConfig allowedManifestFields = 1 << iota + allowedFieldFSLayers + allowedFieldHistory + allowedFieldLayers + allowedFieldManifests + allowedFieldFirstUnusedBit // Keep this at the end! +) + +// validateUnambiguousManifestFormat rejects manifests (incl. multi-arch) that look like more than +// one kind we currently recognize, i.e. if they contain any of the known “essential” format fields +// other than the ones the caller specifically allows. +// expectedMIMEType is used only for diagnostics. +// NOTE: The caller should do the non-heuristic validations (e.g. check for any specified format +// identification/version, or other “magic numbers”) before calling this, to cleanly reject unambigous +// data that just isn’t what was expected, as opposed to actually ambiguous data. +func validateUnambiguousManifestFormat(manifest []byte, expectedMIMEType string, + allowed allowedManifestFields) error { + if allowed >= allowedFieldFirstUnusedBit { + return fmt.Errorf("internal error: invalid allowedManifestFields value %#v", allowed) + } + // Use a private type to decode, not just a map[string]interface{}, because we want + // to also reject case-insensitive matches (which would be used by Go when really decoding + // the manifest). + // (It is expected that as manifest formats are added or extended over time, more fields will be added + // here.) + detectedFields := struct { + Config interface{} `json:"config"` + FSLayers interface{} `json:"fsLayers"` + History interface{} `json:"history"` + Layers interface{} `json:"layers"` + Manifests interface{} `json:"manifests"` + }{} + if err := json.Unmarshal(manifest, &detectedFields); err != nil { + // The caller was supposed to already validate version numbers, so this shold not happen; + // let’s not bother with making this error “nice”. + return err + } + unexpected := []string{} + // Sadly this isn’t easy to automate in Go, without reflection. So, copy&paste. + if detectedFields.Config != nil && (allowed&allowedFieldConfig) == 0 { + unexpected = append(unexpected, "config") + } + if detectedFields.FSLayers != nil && (allowed&allowedFieldFSLayers) == 0 { + unexpected = append(unexpected, "fsLayers") + } + if detectedFields.History != nil && (allowed&allowedFieldHistory) == 0 { + unexpected = append(unexpected, "history") + } + if detectedFields.Layers != nil && (allowed&allowedFieldLayers) == 0 { + unexpected = append(unexpected, "layers") + } + if detectedFields.Manifests != nil && (allowed&allowedFieldManifests) == 0 { + unexpected = append(unexpected, "manifests") + } + if len(unexpected) != 0 { + return fmt.Errorf(`rejecting ambiguous manifest, unexpected fields %#v in supposedly %s`, + unexpected, expectedMIMEType) + } + return nil +} + // layerInfosToStrings converts a list of layer infos, presumably obtained from a Manifest.LayerInfos() // method call, into a format suitable for inclusion in a types.ImageInspectInfo structure. func layerInfosToStrings(infos []LayerInfo) []string { diff --git a/vendor/github.com/containers/image/v5/manifest/docker_schema1.go b/vendor/github.com/containers/image/v5/manifest/docker_schema1.go index 8679cad11..6d12c4cec 100644 --- a/vendor/github.com/containers/image/v5/manifest/docker_schema1.go +++ b/vendor/github.com/containers/image/v5/manifest/docker_schema1.go @@ -60,6 +60,10 @@ func Schema1FromManifest(manifest []byte) (*Schema1, error) { if s1.SchemaVersion != 1 { return nil, errors.Errorf("unsupported schema version %d", s1.SchemaVersion) } + if err := validateUnambiguousManifestFormat(manifest, DockerV2Schema1SignedMediaType, + allowedFieldFSLayers|allowedFieldHistory); err != nil { + return nil, err + } if err := s1.initialize(); err != nil { return nil, err } diff --git a/vendor/github.com/containers/image/v5/manifest/docker_schema2.go b/vendor/github.com/containers/image/v5/manifest/docker_schema2.go index 2711ca5eb..1f4db54ee 100644 --- a/vendor/github.com/containers/image/v5/manifest/docker_schema2.go +++ b/vendor/github.com/containers/image/v5/manifest/docker_schema2.go @@ -165,6 +165,10 @@ func Schema2FromManifest(manifest []byte) (*Schema2, error) { if err := json.Unmarshal(manifest, &s2); err != nil { return nil, err } + if err := validateUnambiguousManifestFormat(manifest, DockerV2Schema2MediaType, + allowedFieldConfig|allowedFieldLayers); err != nil { + return nil, err + } // Check manifest's and layers' media types. if err := SupportedSchema2MediaType(s2.MediaType); err != nil { return nil, err diff --git a/vendor/github.com/containers/image/v5/manifest/docker_schema2_list.go b/vendor/github.com/containers/image/v5/manifest/docker_schema2_list.go index 9ebb8d6b9..e97dfbd88 100644 --- a/vendor/github.com/containers/image/v5/manifest/docker_schema2_list.go +++ b/vendor/github.com/containers/image/v5/manifest/docker_schema2_list.go @@ -192,6 +192,10 @@ func Schema2ListFromManifest(manifest []byte) (*Schema2List, error) { if err := json.Unmarshal(manifest, &list); err != nil { return nil, errors.Wrapf(err, "unmarshaling Schema2List %q", string(manifest)) } + if err := validateUnambiguousManifestFormat(manifest, DockerV2ListMediaType, + allowedFieldManifests); err != nil { + return nil, err + } return &list, nil } diff --git a/vendor/github.com/containers/image/v5/manifest/oci.go b/vendor/github.com/containers/image/v5/manifest/oci.go index 29a479c94..c4616b965 100644 --- a/vendor/github.com/containers/image/v5/manifest/oci.go +++ b/vendor/github.com/containers/image/v5/manifest/oci.go @@ -54,6 +54,10 @@ func OCI1FromManifest(manifest []byte) (*OCI1, error) { if err := json.Unmarshal(manifest, &oci1); err != nil { return nil, err } + if err := validateUnambiguousManifestFormat(manifest, imgspecv1.MediaTypeImageIndex, + allowedFieldConfig|allowedFieldLayers); err != nil { + return nil, err + } return &oci1, nil } diff --git a/vendor/github.com/containers/image/v5/manifest/oci_index.go b/vendor/github.com/containers/image/v5/manifest/oci_index.go index 5b4111e4e..5bec43ff9 100644 --- a/vendor/github.com/containers/image/v5/manifest/oci_index.go +++ b/vendor/github.com/containers/image/v5/manifest/oci_index.go @@ -202,6 +202,10 @@ func OCI1IndexFromManifest(manifest []byte) (*OCI1Index, error) { if err := json.Unmarshal(manifest, &index); err != nil { return nil, errors.Wrapf(err, "unmarshaling OCI1Index %q", string(manifest)) } + if err := validateUnambiguousManifestFormat(manifest, imgspecv1.MediaTypeImageIndex, + allowedFieldManifests); err != nil { + return nil, err + } return &index, nil } diff --git a/vendor/github.com/containers/image/v5/oci/layout/oci_src.go b/vendor/github.com/containers/image/v5/oci/layout/oci_src.go index 55d3f637a..9d8ab689b 100644 --- a/vendor/github.com/containers/image/v5/oci/layout/oci_src.go +++ b/vendor/github.com/containers/image/v5/oci/layout/oci_src.go @@ -5,6 +5,7 @@ import ( "io" "io/ioutil" "net/http" + "net/url" "os" "strconv" @@ -113,7 +114,12 @@ func (s *ociImageSource) HasThreadSafeGetBlob() bool { // May update BlobInfoCache, preferably after it knows for certain that a blob truly exists at a specific location. func (s *ociImageSource) GetBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache) (io.ReadCloser, int64, error) { if len(info.URLs) != 0 { - return s.getExternalBlob(ctx, info.URLs) + r, s, err := s.getExternalBlob(ctx, info.URLs) + if err != nil { + return nil, 0, err + } else if r != nil { + return r, s, nil + } } path, err := s.ref.blobPath(info.Digest, s.sharedBlobDir) @@ -140,34 +146,44 @@ func (s *ociImageSource) GetSignatures(ctx context.Context, instanceDigest *dige return [][]byte{}, nil } +// getExternalBlob returns the reader of the first available blob URL from urls, which must not be empty. +// This function can return nil reader when no url is supported by this function. In this case, the caller +// should fallback to fetch the non-external blob (i.e. pull from the registry). func (s *ociImageSource) getExternalBlob(ctx context.Context, urls []string) (io.ReadCloser, int64, error) { if len(urls) == 0 { return nil, 0, errors.New("internal error: getExternalBlob called with no URLs") } errWrap := errors.New("failed fetching external blob from all urls") - for _, url := range urls { - - req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + hasSupportedURL := false + for _, u := range urls { + if u, err := url.Parse(u); err != nil || (u.Scheme != "http" && u.Scheme != "https") { + continue // unsupported url. skip this url. + } + hasSupportedURL = true + req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil) if err != nil { - errWrap = errors.Wrapf(errWrap, "fetching %s failed %s", url, err.Error()) + errWrap = errors.Wrapf(errWrap, "fetching %s failed %s", u, err.Error()) continue } resp, err := s.client.Do(req) if err != nil { - errWrap = errors.Wrapf(errWrap, "fetching %s failed %s", url, err.Error()) + errWrap = errors.Wrapf(errWrap, "fetching %s failed %s", u, err.Error()) continue } if resp.StatusCode != http.StatusOK { resp.Body.Close() - errWrap = errors.Wrapf(errWrap, "fetching %s failed, response code not 200", url) + errWrap = errors.Wrapf(errWrap, "fetching %s failed, response code not 200", u) continue } return resp.Body, getBlobSize(resp), nil } + if !hasSupportedURL { + return nil, 0, nil // fallback to non-external blob + } return nil, 0, errWrap } diff --git a/vendor/github.com/containers/image/v5/pkg/docker/config/config.go b/vendor/github.com/containers/image/v5/pkg/docker/config/config.go index e37f4c19e..63f5bd53e 100644 --- a/vendor/github.com/containers/image/v5/pkg/docker/config/config.go +++ b/vendor/github.com/containers/image/v5/pkg/docker/config/config.go @@ -268,18 +268,18 @@ func getCredentialsWithHomeDir(sys *types.SystemContext, ref reference.Named, re } // Anonymous function to query credentials from auth files. - getCredentialsFromAuthFiles := func() (types.DockerAuthConfig, error) { + getCredentialsFromAuthFiles := func() (types.DockerAuthConfig, string, error) { for _, path := range getAuthFilePaths(sys, homeDir) { authConfig, err := findAuthentication(ref, registry, path.path, path.legacyFormat) if err != nil { - return types.DockerAuthConfig{}, err + return types.DockerAuthConfig{}, "", err } if (authConfig.Username != "" && authConfig.Password != "") || authConfig.IdentityToken != "" { - return authConfig, nil + return authConfig, path.path, nil } } - return types.DockerAuthConfig{}, nil + return types.DockerAuthConfig{}, "", nil } helpers, err := sysregistriesv2.CredentialHelpers(sys) @@ -289,12 +289,15 @@ func getCredentialsWithHomeDir(sys *types.SystemContext, ref reference.Named, re var multiErr error for _, helper := range helpers { - var creds types.DockerAuthConfig - var err error + var ( + creds types.DockerAuthConfig + credHelperPath string + err error + ) switch helper { // Special-case the built-in helper for auth files. case sysregistriesv2.AuthenticationFileHelper: - creds, err = getCredentialsFromAuthFiles() + creds, credHelperPath, err = getCredentialsFromAuthFiles() // External helpers. default: creds, err = getAuthFromCredHelper(helper, registry) @@ -307,7 +310,11 @@ func getCredentialsWithHomeDir(sys *types.SystemContext, ref reference.Named, re if len(creds.Username)+len(creds.Password)+len(creds.IdentityToken) == 0 { continue } - logrus.Debugf("Found credentials for %s in credential helper %s", registry, helper) + msg := fmt.Sprintf("Found credentials for %s in credential helper %s", registry, helper) + if credHelperPath != "" { + msg = fmt.Sprintf("%s in file %s", msg, credHelperPath) + } + logrus.Debug(msg) return creds, nil } if multiErr != nil { diff --git a/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go b/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go index 4c1629f56..c8a603c4e 100644 --- a/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go +++ b/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go @@ -80,7 +80,7 @@ func (e *Endpoint) rewriteReference(ref reference.Named, prefix string) (referen // be dropped. // https://github.com/containers/image/pull/1191#discussion_r610621608 if e.Location == "" { - if prefix[:2] != "*." { + if !strings.HasPrefix(prefix, "*.") { return nil, fmt.Errorf("invalid prefix '%v' for empty location, should be in the format: *.example.com", prefix) } return ref, nil @@ -369,7 +369,7 @@ func (config *V2RegistriesConf) postProcessRegistries() error { } // FIXME: allow config authors to always use Prefix. // https://github.com/containers/image/pull/1191#discussion_r610622495 - if reg.Prefix[:2] != "*." && reg.Location == "" { + if !strings.HasPrefix(reg.Prefix, "*.") && reg.Location == "" { return &InvalidRegistries{s: "invalid condition: location is unset and prefix is not in the format: *.example.com"} } } @@ -804,7 +804,7 @@ func refMatchingSubdomainPrefix(ref, prefix string) int { // (This is split from the caller primarily to make testing easier.) func refMatchingPrefix(ref, prefix string) int { switch { - case prefix[0:2] == "*.": + case strings.HasPrefix(prefix, "*."): return refMatchingSubdomainPrefix(ref, prefix) case len(ref) < len(prefix): return -1 @@ -924,7 +924,7 @@ func loadConfigFile(path string, forceV2 bool) (*parsedConfig, error) { // https://github.com/containers/image/pull/1191#discussion_r610623829 for i := range res.partialV2.Registries { prefix := res.partialV2.Registries[i].Prefix - if prefix[:2] == "*." && strings.ContainsAny(prefix, "/@:") { + if strings.HasPrefix(prefix, "*.") && strings.ContainsAny(prefix, "/@:") { msg := fmt.Sprintf("Wildcarded prefix should be in the format: *.example.com. Current prefix %q is incorrectly formatted", prefix) return nil, &InvalidRegistries{s: msg} } diff --git a/vendor/github.com/containers/image/v5/storage/storage_transport.go b/vendor/github.com/containers/image/v5/storage/storage_transport.go index ab59c8a29..07393ee74 100644 --- a/vendor/github.com/containers/image/v5/storage/storage_transport.go +++ b/vendor/github.com/containers/image/v5/storage/storage_transport.go @@ -225,7 +225,7 @@ func (s *storageTransport) ParseReference(reference string) (types.ImageReferenc // needs to match a store that was previously initialized using // storage.GetStore(), or be enough to let the storage library fill out // the rest using knowledge that it has from elsewhere. - if reference[0] == '[' { + if len(reference) > 0 && reference[0] == '[' { closeIndex := strings.IndexRune(reference, ']') if closeIndex < 1 { return nil, ErrInvalidReference diff --git a/vendor/github.com/containers/image/v5/types/types.go b/vendor/github.com/containers/image/v5/types/types.go index 354b3f663..c98a6c6fd 100644 --- a/vendor/github.com/containers/image/v5/types/types.go +++ b/vendor/github.com/containers/image/v5/types/types.go @@ -622,6 +622,10 @@ type SystemContext struct { DockerLogMirrorChoice bool // Directory to use for OSTree temporary files OSTreeTmpDirPath string + // If true, all blobs will have precomputed digests to ensure layers are not uploaded that already exist on the registry. + // Note that this requires writing blobs to temporary files, and takes more time than the default behavior, + // when the digest for a blob is unknown. + DockerRegistryPushPrecomputeDigests bool // === docker/daemon.Transport overrides === // A directory containing a CA certificate (ending with ".crt"), diff --git a/vendor/github.com/containers/image/v5/version/version.go b/vendor/github.com/containers/image/v5/version/version.go index 7f68c7cd0..ffb2a4ce2 100644 --- a/vendor/github.com/containers/image/v5/version/version.go +++ b/vendor/github.com/containers/image/v5/version/version.go @@ -6,9 +6,9 @@ const ( // VersionMajor is for an API incompatible changes VersionMajor = 5 // VersionMinor is for functionality in a backwards-compatible manner - VersionMinor = 16 + VersionMinor = 17 // VersionPatch is for backwards-compatible bug fixes - VersionPatch = 1 + VersionPatch = 0 // VersionDev indicates development branch. Releases will be empty string. VersionDev = "" diff --git a/vendor/github.com/juju/ansiterm/LICENSE b/vendor/github.com/juju/ansiterm/LICENSE deleted file mode 100644 index ade9307b3..000000000 --- a/vendor/github.com/juju/ansiterm/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ -All files in this repository are licensed as follows. If you contribute -to this repository, it is assumed that you license your contribution -under the same license unless you state otherwise. - -All files Copyright (C) 2015 Canonical Ltd. unless otherwise specified in the file. - -This software is licensed under the LGPLv3, included below. - -As a special exception to the GNU Lesser General Public License version 3 -("LGPL3"), the copyright holders of this Library give you permission to -convey to a third party a Combined Work that links statically or dynamically -to this Library without providing any Minimal Corresponding Source or -Minimal Application Code as set out in 4d or providing the installation -information set out in section 4e, provided that you comply with the other -provisions of LGPL3 and provided that you meet, for the Application the -terms and conditions of the license(s) which apply to the Application. - -Except as stated in this special exception, the provisions of LGPL3 will -continue to comply in full to this Library. If you modify this Library, you -may apply this exception to your version of this Library, but you are not -obliged to do so. If you do not wish to do so, delete this exception -statement from your version. This exception does not (and cannot) modify any -license terms which apply to the Application, with which you must still -comply. - - - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/vendor/github.com/juju/ansiterm/Makefile b/vendor/github.com/juju/ansiterm/Makefile deleted file mode 100644 index 212fdcbe5..000000000 --- a/vendor/github.com/juju/ansiterm/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright 2016 Canonical Ltd. -# Licensed under the LGPLv3, see LICENCE file for details. - -default: check - -check: - go test - -docs: - godoc2md github.com/juju/ansiterm > README.md - sed -i 's|\[godoc-link-here\]|[![GoDoc](https://godoc.org/github.com/juju/ansiterm?status.svg)](https://godoc.org/github.com/juju/ansiterm)|' README.md - - -.PHONY: default check docs diff --git a/vendor/github.com/juju/ansiterm/README.md b/vendor/github.com/juju/ansiterm/README.md deleted file mode 100644 index 567438721..000000000 --- a/vendor/github.com/juju/ansiterm/README.md +++ /dev/null @@ -1,323 +0,0 @@ - -# ansiterm - import "github.com/juju/ansiterm" - -Package ansiterm provides a Writer that writes out the ANSI escape -codes for color and styles. - - - - - - - -## type Color -``` go -type Color int -``` -Color represents one of the standard 16 ANSI colors. - - - -``` go -const ( - Default Color - Black - Red - Green - Yellow - Blue - Magenta - Cyan - Gray - DarkGray - BrightRed - BrightGreen - BrightYellow - BrightBlue - BrightMagenta - BrightCyan - White -) -``` - - - - - - - - -### func (Color) String -``` go -func (c Color) String() string -``` -String returns the name of the color. - - - -## type Context -``` go -type Context struct { - Foreground Color - Background Color - Styles []Style -} -``` -Context provides a way to specify both foreground and background colors -along with other styles and write text to a Writer with those colors and -styles. - - - - - - - - - -### func Background -``` go -func Background(color Color) *Context -``` -Background is a convenience function that creates a Context with the -specified color as the background color. - - -### func Foreground -``` go -func Foreground(color Color) *Context -``` -Foreground is a convenience function that creates a Context with the -specified color as the foreground color. - - -### func Styles -``` go -func Styles(styles ...Style) *Context -``` -Styles is a convenience function that creates a Context with the -specified styles set. - - - - -### func (\*Context) Fprint -``` go -func (c *Context) Fprint(w sgrWriter, args ...interface{}) -``` -Fprint will set the sgr values of the writer to the specified foreground, -background and styles, then formats using the default formats for its -operands and writes to w. Spaces are added between operands when neither is -a string. It returns the number of bytes written and any write error -encountered. - - - -### func (\*Context) Fprintf -``` go -func (c *Context) Fprintf(w sgrWriter, format string, args ...interface{}) -``` -Fprintf will set the sgr values of the writer to the specified -foreground, background and styles, then write the formatted string, -then reset the writer. - - - -### func (\*Context) SetBackground -``` go -func (c *Context) SetBackground(color Color) *Context -``` -SetBackground sets the background to the specified color. - - - -### func (\*Context) SetForeground -``` go -func (c *Context) SetForeground(color Color) *Context -``` -SetForeground sets the foreground to the specified color. - - - -### func (\*Context) SetStyle -``` go -func (c *Context) SetStyle(styles ...Style) *Context -``` -SetStyle replaces the styles with the new values. - - - -## type Style -``` go -type Style int -``` - - -``` go -const ( - Bold Style - Faint - Italic - Underline - Blink - Reverse - Strikethrough - Conceal -) -``` - - - - - - - - -### func (Style) String -``` go -func (s Style) String() string -``` - - -## type TabWriter -``` go -type TabWriter struct { - Writer - // contains filtered or unexported fields -} -``` -TabWriter is a filter that inserts padding around tab-delimited -columns in its input to align them in the output. - -It also setting of colors and styles over and above the standard -tabwriter package. - - - - - - - - - -### func NewTabWriter -``` go -func NewTabWriter(output io.Writer, minwidth, tabwidth, padding int, padchar byte, flags uint) *TabWriter -``` -NewTabWriter returns a writer that is able to set colors and styels. -The ansi escape codes are stripped for width calculations. - - - - -### func (\*TabWriter) Flush -``` go -func (t *TabWriter) Flush() error -``` -Flush should be called after the last call to Write to ensure -that any data buffered in the Writer is written to output. Any -incomplete escape sequence at the end is considered -complete for formatting purposes. - - - -### func (\*TabWriter) Init -``` go -func (t *TabWriter) Init(output io.Writer, minwidth, tabwidth, padding int, padchar byte, flags uint) *TabWriter -``` -A Writer must be initialized with a call to Init. The first parameter (output) -specifies the filter output. The remaining parameters control the formatting: - - - minwidth minimal cell width including any padding - tabwidth width of tab characters (equivalent number of spaces) - padding padding added to a cell before computing its width - padchar ASCII char used for padding - if padchar == '\t', the Writer will assume that the - width of a '\t' in the formatted output is tabwidth, - and cells are left-aligned independent of align_left - (for correct-looking results, tabwidth must correspond - to the tab width in the viewer displaying the result) - flags formatting control - - - -## type Writer -``` go -type Writer struct { - io.Writer - // contains filtered or unexported fields -} -``` -Writer allows colors and styles to be specified. If the io.Writer -is not a terminal capable of color, all attempts to set colors or -styles are no-ops. - - - - - - - - - -### func NewWriter -``` go -func NewWriter(w io.Writer) *Writer -``` -NewWriter returns a Writer that allows the caller to specify colors and -styles. If the io.Writer is not a terminal capable of color, all attempts -to set colors or styles are no-ops. - - - - -### func (\*Writer) ClearStyle -``` go -func (w *Writer) ClearStyle(s Style) -``` -ClearStyle clears the text style. - - - -### func (\*Writer) Reset -``` go -func (w *Writer) Reset() -``` -Reset returns the default foreground and background colors with no styles. - - - -### func (\*Writer) SetBackground -``` go -func (w *Writer) SetBackground(c Color) -``` -SetBackground sets the background color. - - - -### func (\*Writer) SetForeground -``` go -func (w *Writer) SetForeground(c Color) -``` -SetForeground sets the foreground color. - - - -### func (\*Writer) SetStyle -``` go -func (w *Writer) SetStyle(s Style) -``` -SetStyle sets the text style. - - - - - - - - - -- - - -Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md)
\ No newline at end of file diff --git a/vendor/github.com/juju/ansiterm/attribute.go b/vendor/github.com/juju/ansiterm/attribute.go deleted file mode 100644 index f2daa4813..000000000 --- a/vendor/github.com/juju/ansiterm/attribute.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2016 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -package ansiterm - -import ( - "fmt" - "sort" - "strings" -) - -type attribute int - -const ( - unknownAttribute attribute = -1 - reset attribute = 0 -) - -// sgr returns the escape sequence for the Select Graphic Rendition -// for the attribute. -func (a attribute) sgr() string { - if a < 0 { - return "" - } - return fmt.Sprintf("\x1b[%dm", a) -} - -type attributes []attribute - -func (a attributes) Len() int { return len(a) } -func (a attributes) Less(i, j int) bool { return a[i] < a[j] } -func (a attributes) Swap(i, j int) { a[i], a[j] = a[j], a[i] } - -// sgr returns the combined escape sequence for the Select Graphic Rendition -// for the sequence of attributes. -func (a attributes) sgr() string { - switch len(a) { - case 0: - return "" - case 1: - return a[0].sgr() - default: - sort.Sort(a) - var values []string - for _, attr := range a { - values = append(values, fmt.Sprint(attr)) - } - return fmt.Sprintf("\x1b[%sm", strings.Join(values, ";")) - } -} diff --git a/vendor/github.com/juju/ansiterm/color.go b/vendor/github.com/juju/ansiterm/color.go deleted file mode 100644 index 0a97de31e..000000000 --- a/vendor/github.com/juju/ansiterm/color.go +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2016 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -package ansiterm - -const ( - _ Color = iota - Default - Black - Red - Green - Yellow - Blue - Magenta - Cyan - Gray - DarkGray - BrightRed - BrightGreen - BrightYellow - BrightBlue - BrightMagenta - BrightCyan - White -) - -// Color represents one of the standard 16 ANSI colors. -type Color int - -// String returns the name of the color. -func (c Color) String() string { - switch c { - case Default: - return "default" - case Black: - return "black" - case Red: - return "red" - case Green: - return "green" - case Yellow: - return "yellow" - case Blue: - return "blue" - case Magenta: - return "magenta" - case Cyan: - return "cyan" - case Gray: - return "gray" - case DarkGray: - return "darkgray" - case BrightRed: - return "brightred" - case BrightGreen: - return "brightgreen" - case BrightYellow: - return "brightyellow" - case BrightBlue: - return "brightblue" - case BrightMagenta: - return "brightmagenta" - case BrightCyan: - return "brightcyan" - case White: - return "white" - default: - return "" - } -} - -func (c Color) foreground() attribute { - switch c { - case Default: - return 39 - case Black: - return 30 - case Red: - return 31 - case Green: - return 32 - case Yellow: - return 33 - case Blue: - return 34 - case Magenta: - return 35 - case Cyan: - return 36 - case Gray: - return 37 - case DarkGray: - return 90 - case BrightRed: - return 91 - case BrightGreen: - return 92 - case BrightYellow: - return 93 - case BrightBlue: - return 94 - case BrightMagenta: - return 95 - case BrightCyan: - return 96 - case White: - return 97 - default: - return unknownAttribute - } -} - -func (c Color) background() attribute { - value := c.foreground() - if value != unknownAttribute { - return value + 10 - } - return value -} diff --git a/vendor/github.com/juju/ansiterm/context.go b/vendor/github.com/juju/ansiterm/context.go deleted file mode 100644 index e61a867ff..000000000 --- a/vendor/github.com/juju/ansiterm/context.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2016 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -package ansiterm - -import ( - "fmt" - "io" -) - -// Context provides a way to specify both foreground and background colors -// along with other styles and write text to a Writer with those colors and -// styles. -type Context struct { - Foreground Color - Background Color - Styles []Style -} - -// Foreground is a convenience function that creates a Context with the -// specified color as the foreground color. -func Foreground(color Color) *Context { - return &Context{Foreground: color} -} - -// Background is a convenience function that creates a Context with the -// specified color as the background color. -func Background(color Color) *Context { - return &Context{Background: color} -} - -// Styles is a convenience function that creates a Context with the -// specified styles set. -func Styles(styles ...Style) *Context { - return &Context{Styles: styles} -} - -// SetForeground sets the foreground to the specified color. -func (c *Context) SetForeground(color Color) *Context { - c.Foreground = color - return c -} - -// SetBackground sets the background to the specified color. -func (c *Context) SetBackground(color Color) *Context { - c.Background = color - return c -} - -// SetStyle replaces the styles with the new values. -func (c *Context) SetStyle(styles ...Style) *Context { - c.Styles = styles - return c -} - -type sgrWriter interface { - io.Writer - writeSGR(value sgr) -} - -// Fprintf will set the sgr values of the writer to the specified -// foreground, background and styles, then write the formatted string, -// then reset the writer. -func (c *Context) Fprintf(w sgrWriter, format string, args ...interface{}) { - w.writeSGR(c) - fmt.Fprintf(w, format, args...) - w.writeSGR(reset) -} - -// Fprint will set the sgr values of the writer to the specified foreground, -// background and styles, then formats using the default formats for its -// operands and writes to w. Spaces are added between operands when neither is -// a string. It returns the number of bytes written and any write error -// encountered. -func (c *Context) Fprint(w sgrWriter, args ...interface{}) { - w.writeSGR(c) - fmt.Fprint(w, args...) - w.writeSGR(reset) -} - -func (c *Context) sgr() string { - var values attributes - if foreground := c.Foreground.foreground(); foreground != unknownAttribute { - values = append(values, foreground) - } - if background := c.Background.background(); background != unknownAttribute { - values = append(values, background) - } - for _, style := range c.Styles { - if value := style.enable(); value != unknownAttribute { - values = append(values, value) - } - } - return values.sgr() -} diff --git a/vendor/github.com/juju/ansiterm/doc.go b/vendor/github.com/juju/ansiterm/doc.go deleted file mode 100644 index 782700779..000000000 --- a/vendor/github.com/juju/ansiterm/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2016 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -// Package ansiterm provides a Writer that writes out the ANSI escape -// codes for color and styles. -package ansiterm diff --git a/vendor/github.com/juju/ansiterm/style.go b/vendor/github.com/juju/ansiterm/style.go deleted file mode 100644 index 0be42da56..000000000 --- a/vendor/github.com/juju/ansiterm/style.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2016 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -package ansiterm - -const ( - _ Style = iota - Bold - Faint - Italic - Underline - Blink - Reverse - Strikethrough - Conceal -) - -type Style int - -func (s Style) String() string { - switch s { - case Bold: - return "bold" - case Faint: - return "faint" - case Italic: - return "italic" - case Underline: - return "underline" - case Blink: - return "blink" - case Reverse: - return "reverse" - case Strikethrough: - return "strikethrough" - case Conceal: - return "conceal" - default: - return "" - } -} - -func (s Style) enable() attribute { - switch s { - case Bold: - return 1 - case Faint: - return 2 - case Italic: - return 3 - case Underline: - return 4 - case Blink: - return 5 - case Reverse: - return 7 - case Conceal: - return 8 - case Strikethrough: - return 9 - default: - return unknownAttribute - } -} - -func (s Style) disable() attribute { - value := s.enable() - if value != unknownAttribute { - return value + 20 - } - return value -} diff --git a/vendor/github.com/juju/ansiterm/tabwriter.go b/vendor/github.com/juju/ansiterm/tabwriter.go deleted file mode 100644 index 1ff6faaaf..000000000 --- a/vendor/github.com/juju/ansiterm/tabwriter.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2016 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -package ansiterm - -import ( - "io" - - "github.com/juju/ansiterm/tabwriter" -) - -// NewTabWriter returns a writer that is able to set colors and styels. -// The ansi escape codes are stripped for width calculations. -func NewTabWriter(output io.Writer, minwidth, tabwidth, padding int, padchar byte, flags uint) *TabWriter { - return new(TabWriter).Init(output, minwidth, tabwidth, padding, padchar, flags) -} - -// TabWriter is a filter that inserts padding around tab-delimited -// columns in its input to align them in the output. -// -// It also setting of colors and styles over and above the standard -// tabwriter package. -type TabWriter struct { - Writer - tw tabwriter.Writer -} - -// Flush should be called after the last call to Write to ensure -// that any data buffered in the Writer is written to output. Any -// incomplete escape sequence at the end is considered -// complete for formatting purposes. -// -func (t *TabWriter) Flush() error { - return t.tw.Flush() -} - -// SetColumnAlignRight will mark a particular column as align right. -// This is reset on the next flush. -func (t *TabWriter) SetColumnAlignRight(column int) { - t.tw.SetColumnAlignRight(column) -} - -// A Writer must be initialized with a call to Init. The first parameter (output) -// specifies the filter output. The remaining parameters control the formatting: -// -// minwidth minimal cell width including any padding -// tabwidth width of tab characters (equivalent number of spaces) -// padding padding added to a cell before computing its width -// padchar ASCII char used for padding -// if padchar == '\t', the Writer will assume that the -// width of a '\t' in the formatted output is tabwidth, -// and cells are left-aligned independent of align_left -// (for correct-looking results, tabwidth must correspond -// to the tab width in the viewer displaying the result) -// flags formatting control -// -func (t *TabWriter) Init(output io.Writer, minwidth, tabwidth, padding int, padchar byte, flags uint) *TabWriter { - writer, colorCapable := colorEnabledWriter(output) - t.Writer = Writer{ - Writer: t.tw.Init(writer, minwidth, tabwidth, padding, padchar, flags), - noColor: !colorCapable, - } - return t -} diff --git a/vendor/github.com/juju/ansiterm/tabwriter/LICENSE b/vendor/github.com/juju/ansiterm/tabwriter/LICENSE deleted file mode 100644 index 744875676..000000000 --- a/vendor/github.com/juju/ansiterm/tabwriter/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2012 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/juju/ansiterm/tabwriter/tabwriter.go b/vendor/github.com/juju/ansiterm/tabwriter/tabwriter.go deleted file mode 100644 index 98949d036..000000000 --- a/vendor/github.com/juju/ansiterm/tabwriter/tabwriter.go +++ /dev/null @@ -1,587 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file is mostly a copy of the go standard library text/tabwriter. With -// the additional stripping of ansi control characters for width calculations. - -// Package tabwriter implements a write filter (tabwriter.Writer) that -// translates tabbed columns in input into properly aligned text. -// -// The package is using the Elastic Tabstops algorithm described at -// http://nickgravgaard.com/elastictabstops/index.html. -// -package tabwriter - -import ( - "bytes" - "io" - "unicode/utf8" - - "github.com/lunixbochs/vtclean" -) - -// ---------------------------------------------------------------------------- -// Filter implementation - -// A cell represents a segment of text terminated by tabs or line breaks. -// The text itself is stored in a separate buffer; cell only describes the -// segment's size in bytes, its width in runes, and whether it's an htab -// ('\t') terminated cell. -// -type cell struct { - size int // cell size in bytes - width int // cell width in runes - htab bool // true if the cell is terminated by an htab ('\t') -} - -// A Writer is a filter that inserts padding around tab-delimited -// columns in its input to align them in the output. -// -// The Writer treats incoming bytes as UTF-8 encoded text consisting -// of cells terminated by (horizontal or vertical) tabs or line -// breaks (newline or formfeed characters). Cells in adjacent lines -// constitute a column. The Writer inserts padding as needed to -// make all cells in a column have the same width, effectively -// aligning the columns. It assumes that all characters have the -// same width except for tabs for which a tabwidth must be specified. -// Note that cells are tab-terminated, not tab-separated: trailing -// non-tab text at the end of a line does not form a column cell. -// -// The Writer assumes that all Unicode code points have the same width; -// this may not be true in some fonts. -// -// If DiscardEmptyColumns is set, empty columns that are terminated -// entirely by vertical (or "soft") tabs are discarded. Columns -// terminated by horizontal (or "hard") tabs are not affected by -// this flag. -// -// If a Writer is configured to filter HTML, HTML tags and entities -// are passed through. The widths of tags and entities are -// assumed to be zero (tags) and one (entities) for formatting purposes. -// -// A segment of text may be escaped by bracketing it with Escape -// characters. The tabwriter passes escaped text segments through -// unchanged. In particular, it does not interpret any tabs or line -// breaks within the segment. If the StripEscape flag is set, the -// Escape characters are stripped from the output; otherwise they -// are passed through as well. For the purpose of formatting, the -// width of the escaped text is always computed excluding the Escape -// characters. -// -// The formfeed character ('\f') acts like a newline but it also -// terminates all columns in the current line (effectively calling -// Flush). Cells in the next line start new columns. Unless found -// inside an HTML tag or inside an escaped text segment, formfeed -// characters appear as newlines in the output. -// -// The Writer must buffer input internally, because proper spacing -// of one line may depend on the cells in future lines. Clients must -// call Flush when done calling Write. -// -type Writer struct { - // configuration - output io.Writer - minwidth int - tabwidth int - padding int - padbytes [8]byte - flags uint - - // current state - buf bytes.Buffer // collected text excluding tabs or line breaks - pos int // buffer position up to which cell.width of incomplete cell has been computed - cell cell // current incomplete cell; cell.width is up to buf[pos] excluding ignored sections - endChar byte // terminating char of escaped sequence (Escape for escapes, '>', ';' for HTML tags/entities, or 0) - lines [][]cell // list of lines; each line is a list of cells - widths []int // list of column widths in runes - re-used during formatting - alignment map[int]uint // column alignment -} - -func (b *Writer) addLine() { b.lines = append(b.lines, []cell{}) } - -// Reset the current state. -func (b *Writer) reset() { - b.buf.Reset() - b.pos = 0 - b.cell = cell{} - b.endChar = 0 - b.lines = b.lines[0:0] - b.widths = b.widths[0:0] - b.alignment = make(map[int]uint) - b.addLine() -} - -// Internal representation (current state): -// -// - all text written is appended to buf; tabs and line breaks are stripped away -// - at any given time there is a (possibly empty) incomplete cell at the end -// (the cell starts after a tab or line break) -// - cell.size is the number of bytes belonging to the cell so far -// - cell.width is text width in runes of that cell from the start of the cell to -// position pos; html tags and entities are excluded from this width if html -// filtering is enabled -// - the sizes and widths of processed text are kept in the lines list -// which contains a list of cells for each line -// - the widths list is a temporary list with current widths used during -// formatting; it is kept in Writer because it's re-used -// -// |<---------- size ---------->| -// | | -// |<- width ->|<- ignored ->| | -// | | | | -// [---processed---tab------------<tag>...</tag>...] -// ^ ^ ^ -// | | | -// buf start of incomplete cell pos - -// Formatting can be controlled with these flags. -const ( - // Ignore html tags and treat entities (starting with '&' - // and ending in ';') as single characters (width = 1). - FilterHTML uint = 1 << iota - - // Strip Escape characters bracketing escaped text segments - // instead of passing them through unchanged with the text. - StripEscape - - // Force right-alignment of cell content. - // Default is left-alignment. - AlignRight - - // Handle empty columns as if they were not present in - // the input in the first place. - DiscardEmptyColumns - - // Always use tabs for indentation columns (i.e., padding of - // leading empty cells on the left) independent of padchar. - TabIndent - - // Print a vertical bar ('|') between columns (after formatting). - // Discarded columns appear as zero-width columns ("||"). - Debug -) - -// A Writer must be initialized with a call to Init. The first parameter (output) -// specifies the filter output. The remaining parameters control the formatting: -// -// minwidth minimal cell width including any padding -// tabwidth width of tab characters (equivalent number of spaces) -// padding padding added to a cell before computing its width -// padchar ASCII char used for padding -// if padchar == '\t', the Writer will assume that the -// width of a '\t' in the formatted output is tabwidth, -// and cells are left-aligned independent of align_left -// (for correct-looking results, tabwidth must correspond -// to the tab width in the viewer displaying the result) -// flags formatting control -// -func (b *Writer) Init(output io.Writer, minwidth, tabwidth, padding int, padchar byte, flags uint) *Writer { - if minwidth < 0 || tabwidth < 0 || padding < 0 { - panic("negative minwidth, tabwidth, or padding") - } - b.output = output - b.minwidth = minwidth - b.tabwidth = tabwidth - b.padding = padding - for i := range b.padbytes { - b.padbytes[i] = padchar - } - if padchar == '\t' { - // tab padding enforces left-alignment - flags &^= AlignRight - } - b.flags = flags - - b.reset() - - return b -} - -// debugging support (keep code around) -func (b *Writer) dump() { - pos := 0 - for i, line := range b.lines { - print("(", i, ") ") - for _, c := range line { - print("[", string(b.buf.Bytes()[pos:pos+c.size]), "]") - pos += c.size - } - print("\n") - } - print("\n") -} - -// local error wrapper so we can distinguish errors we want to return -// as errors from genuine panics (which we don't want to return as errors) -type osError struct { - err error -} - -func (b *Writer) write0(buf []byte) { - n, err := b.output.Write(buf) - if n != len(buf) && err == nil { - err = io.ErrShortWrite - } - if err != nil { - panic(osError{err}) - } -} - -func (b *Writer) writeN(src []byte, n int) { - for n > len(src) { - b.write0(src) - n -= len(src) - } - b.write0(src[0:n]) -} - -var ( - newline = []byte{'\n'} - tabs = []byte("\t\t\t\t\t\t\t\t") -) - -func (b *Writer) writePadding(textw, cellw int, useTabs bool) { - if b.padbytes[0] == '\t' || useTabs { - // padding is done with tabs - if b.tabwidth == 0 { - return // tabs have no width - can't do any padding - } - // make cellw the smallest multiple of b.tabwidth - cellw = (cellw + b.tabwidth - 1) / b.tabwidth * b.tabwidth - n := cellw - textw // amount of padding - if n < 0 { - panic("internal error") - } - b.writeN(tabs, (n+b.tabwidth-1)/b.tabwidth) - return - } - - // padding is done with non-tab characters - b.writeN(b.padbytes[0:], cellw-textw) -} - -var vbar = []byte{'|'} - -func (b *Writer) writeLines(pos0 int, line0, line1 int) (pos int) { - pos = pos0 - for i := line0; i < line1; i++ { - line := b.lines[i] - - // if TabIndent is set, use tabs to pad leading empty cells - useTabs := b.flags&TabIndent != 0 - - for j, c := range line { - if j > 0 && b.flags&Debug != 0 { - // indicate column break - b.write0(vbar) - } - - if c.size == 0 { - // empty cell - if j < len(b.widths) { - b.writePadding(c.width, b.widths[j], useTabs) - } - } else { - // non-empty cell - useTabs = false - alignColumnRight := b.alignment[j] == AlignRight - if (b.flags&AlignRight == 0) && !alignColumnRight { // align left - b.write0(b.buf.Bytes()[pos : pos+c.size]) - pos += c.size - if j < len(b.widths) { - b.writePadding(c.width, b.widths[j], false) - } - } else if alignColumnRight && j < len(b.widths) { - // just this column - internalSize := b.widths[j] - b.padding - if j < len(b.widths) { - b.writePadding(c.width, internalSize, false) - } - b.write0(b.buf.Bytes()[pos : pos+c.size]) - if b.padding > 0 { - b.writePadding(0, b.padding, false) - } - pos += c.size - } else { // align right - if j < len(b.widths) { - b.writePadding(c.width, b.widths[j], false) - } - b.write0(b.buf.Bytes()[pos : pos+c.size]) - pos += c.size - } - } - } - - if i+1 == len(b.lines) { - // last buffered line - we don't have a newline, so just write - // any outstanding buffered data - b.write0(b.buf.Bytes()[pos : pos+b.cell.size]) - pos += b.cell.size - } else { - // not the last line - write newline - b.write0(newline) - } - } - return -} - -// Format the text between line0 and line1 (excluding line1); pos -// is the buffer position corresponding to the beginning of line0. -// Returns the buffer position corresponding to the beginning of -// line1 and an error, if any. -// -func (b *Writer) format(pos0 int, line0, line1 int) (pos int) { - pos = pos0 - column := len(b.widths) - for this := line0; this < line1; this++ { - line := b.lines[this] - - if column < len(line)-1 { - // cell exists in this column => this line - // has more cells than the previous line - // (the last cell per line is ignored because cells are - // tab-terminated; the last cell per line describes the - // text before the newline/formfeed and does not belong - // to a column) - - // print unprinted lines until beginning of block - pos = b.writeLines(pos, line0, this) - line0 = this - - // column block begin - width := b.minwidth // minimal column width - discardable := true // true if all cells in this column are empty and "soft" - for ; this < line1; this++ { - line = b.lines[this] - if column < len(line)-1 { - // cell exists in this column - c := line[column] - // update width - if w := c.width + b.padding; w > width { - width = w - } - // update discardable - if c.width > 0 || c.htab { - discardable = false - } - } else { - break - } - } - // column block end - - // discard empty columns if necessary - if discardable && b.flags&DiscardEmptyColumns != 0 { - width = 0 - } - - // format and print all columns to the right of this column - // (we know the widths of this column and all columns to the left) - b.widths = append(b.widths, width) // push width - pos = b.format(pos, line0, this) - b.widths = b.widths[0 : len(b.widths)-1] // pop width - line0 = this - } - } - - // print unprinted lines until end - return b.writeLines(pos, line0, line1) -} - -// Append text to current cell. -func (b *Writer) append(text []byte) { - b.buf.Write(text) - b.cell.size += len(text) -} - -// Update the cell width. -func (b *Writer) updateWidth() { - // ---- Changes here ----- - newChars := b.buf.Bytes()[b.pos:b.buf.Len()] - cleaned := vtclean.Clean(string(newChars), false) // false to strip colors - b.cell.width += utf8.RuneCount([]byte(cleaned)) - // --- end of changes ---- - b.pos = b.buf.Len() -} - -// To escape a text segment, bracket it with Escape characters. -// For instance, the tab in this string "Ignore this tab: \xff\t\xff" -// does not terminate a cell and constitutes a single character of -// width one for formatting purposes. -// -// The value 0xff was chosen because it cannot appear in a valid UTF-8 sequence. -// -const Escape = '\xff' - -// Start escaped mode. -func (b *Writer) startEscape(ch byte) { - switch ch { - case Escape: - b.endChar = Escape - case '<': - b.endChar = '>' - case '&': - b.endChar = ';' - } -} - -// Terminate escaped mode. If the escaped text was an HTML tag, its width -// is assumed to be zero for formatting purposes; if it was an HTML entity, -// its width is assumed to be one. In all other cases, the width is the -// unicode width of the text. -// -func (b *Writer) endEscape() { - switch b.endChar { - case Escape: - b.updateWidth() - if b.flags&StripEscape == 0 { - b.cell.width -= 2 // don't count the Escape chars - } - case '>': // tag of zero width - case ';': - b.cell.width++ // entity, count as one rune - } - b.pos = b.buf.Len() - b.endChar = 0 -} - -// Terminate the current cell by adding it to the list of cells of the -// current line. Returns the number of cells in that line. -// -func (b *Writer) terminateCell(htab bool) int { - b.cell.htab = htab - line := &b.lines[len(b.lines)-1] - *line = append(*line, b.cell) - b.cell = cell{} - return len(*line) -} - -func handlePanic(err *error, op string) { - if e := recover(); e != nil { - if nerr, ok := e.(osError); ok { - *err = nerr.err - return - } - panic("tabwriter: panic during " + op) - } -} - -// Flush should be called after the last call to Write to ensure -// that any data buffered in the Writer is written to output. Any -// incomplete escape sequence at the end is considered -// complete for formatting purposes. -// -func (b *Writer) Flush() (err error) { - defer b.reset() // even in the presence of errors - defer handlePanic(&err, "Flush") - - // add current cell if not empty - if b.cell.size > 0 { - if b.endChar != 0 { - // inside escape - terminate it even if incomplete - b.endEscape() - } - b.terminateCell(false) - } - - // format contents of buffer - b.format(0, 0, len(b.lines)) - - return -} - -var hbar = []byte("---\n") - -// SetColumnAlignRight will mark a particular column as align right. -// This is reset on the next flush. -func (b *Writer) SetColumnAlignRight(column int) { - b.alignment[column] = AlignRight -} - -// Write writes buf to the writer b. -// The only errors returned are ones encountered -// while writing to the underlying output stream. -// -func (b *Writer) Write(buf []byte) (n int, err error) { - defer handlePanic(&err, "Write") - - // split text into cells - n = 0 - for i, ch := range buf { - if b.endChar == 0 { - // outside escape - switch ch { - case '\t', '\v', '\n', '\f': - // end of cell - b.append(buf[n:i]) - b.updateWidth() - n = i + 1 // ch consumed - ncells := b.terminateCell(ch == '\t') - if ch == '\n' || ch == '\f' { - // terminate line - b.addLine() - if ch == '\f' || ncells == 1 { - // A '\f' always forces a flush. Otherwise, if the previous - // line has only one cell which does not have an impact on - // the formatting of the following lines (the last cell per - // line is ignored by format()), thus we can flush the - // Writer contents. - if err = b.Flush(); err != nil { - return - } - if ch == '\f' && b.flags&Debug != 0 { - // indicate section break - b.write0(hbar) - } - } - } - - case Escape: - // start of escaped sequence - b.append(buf[n:i]) - b.updateWidth() - n = i - if b.flags&StripEscape != 0 { - n++ // strip Escape - } - b.startEscape(Escape) - - case '<', '&': - // possibly an html tag/entity - if b.flags&FilterHTML != 0 { - // begin of tag/entity - b.append(buf[n:i]) - b.updateWidth() - n = i - b.startEscape(ch) - } - } - - } else { - // inside escape - if ch == b.endChar { - // end of tag/entity - j := i + 1 - if ch == Escape && b.flags&StripEscape != 0 { - j = i // strip Escape - } - b.append(buf[n:j]) - n = i + 1 // ch consumed - b.endEscape() - } - } - } - - // append leftover text - b.append(buf[n:]) - n = len(buf) - return -} - -// NewWriter allocates and initializes a new tabwriter.Writer. -// The parameters are the same as for the Init function. -// -func NewWriter(output io.Writer, minwidth, tabwidth, padding int, padchar byte, flags uint) *Writer { - return new(Writer).Init(output, minwidth, tabwidth, padding, padchar, flags) -} diff --git a/vendor/github.com/juju/ansiterm/terminal.go b/vendor/github.com/juju/ansiterm/terminal.go deleted file mode 100644 index 96fd11c51..000000000 --- a/vendor/github.com/juju/ansiterm/terminal.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2016 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -package ansiterm - -import ( - "io" - "os" - - "github.com/mattn/go-colorable" - "github.com/mattn/go-isatty" -) - -// colorEnabledWriter returns a writer that can handle the ansi color codes -// and true if the writer passed in is a terminal capable of color. If the -// TERM environment variable is set to "dumb", the terminal is not considered -// color capable. -func colorEnabledWriter(w io.Writer) (io.Writer, bool) { - f, ok := w.(*os.File) - if !ok { - return w, false - } - // Check the TERM environment variable specifically - // to check for "dumb" terminals. - if os.Getenv("TERM") == "dumb" { - return w, false - } - if !isatty.IsTerminal(f.Fd()) { - return w, false - } - return colorable.NewColorable(f), true -} diff --git a/vendor/github.com/juju/ansiterm/writer.go b/vendor/github.com/juju/ansiterm/writer.go deleted file mode 100644 index 32437bb27..000000000 --- a/vendor/github.com/juju/ansiterm/writer.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2016 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -package ansiterm - -import ( - "fmt" - "io" -) - -// Writer allows colors and styles to be specified. If the io.Writer -// is not a terminal capable of color, all attempts to set colors or -// styles are no-ops. -type Writer struct { - io.Writer - - noColor bool -} - -// NewWriter returns a Writer that allows the caller to specify colors and -// styles. If the io.Writer is not a terminal capable of color, all attempts -// to set colors or styles are no-ops. -func NewWriter(w io.Writer) *Writer { - writer, colorCapable := colorEnabledWriter(w) - return &Writer{ - Writer: writer, - noColor: !colorCapable, - } -} - -// SetColorCapable forces the writer to either write the ANSI escape color -// if capable is true, or to not write them if capable is false. -func (w *Writer) SetColorCapable(capable bool) { - w.noColor = !capable -} - -// SetForeground sets the foreground color. -func (w *Writer) SetForeground(c Color) { - w.writeSGR(c.foreground()) -} - -// SetBackground sets the background color. -func (w *Writer) SetBackground(c Color) { - w.writeSGR(c.background()) -} - -// SetStyle sets the text style. -func (w *Writer) SetStyle(s Style) { - w.writeSGR(s.enable()) -} - -// ClearStyle clears the text style. -func (w *Writer) ClearStyle(s Style) { - w.writeSGR(s.disable()) -} - -// Reset returns the default foreground and background colors with no styles. -func (w *Writer) Reset() { - w.writeSGR(reset) -} - -type sgr interface { - // sgr returns the combined escape sequence for the Select Graphic Rendition. - sgr() string -} - -// writeSGR takes the appropriate integer SGR parameters -// and writes out the ANIS escape code. -func (w *Writer) writeSGR(value sgr) { - if w.noColor { - return - } - fmt.Fprint(w, value.sgr()) -} diff --git a/vendor/github.com/lunixbochs/vtclean/.travis.yml b/vendor/github.com/lunixbochs/vtclean/.travis.yml deleted file mode 100644 index fc0a54325..000000000 --- a/vendor/github.com/lunixbochs/vtclean/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: go -sudo: false - -script: go test -v - -go: - - 1.5 - - 1.6 - - 1.7 diff --git a/vendor/github.com/lunixbochs/vtclean/LICENSE b/vendor/github.com/lunixbochs/vtclean/LICENSE deleted file mode 100644 index 42e82633f..000000000 --- a/vendor/github.com/lunixbochs/vtclean/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2015 Ryan Hileman - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/github.com/lunixbochs/vtclean/README.md b/vendor/github.com/lunixbochs/vtclean/README.md deleted file mode 100644 index 99910a460..000000000 --- a/vendor/github.com/lunixbochs/vtclean/README.md +++ /dev/null @@ -1,46 +0,0 @@ -[![Build Status](https://travis-ci.org/lunixbochs/vtclean.svg?branch=master)](https://travis-ci.org/lunixbochs/vtclean) - -vtclean ----- - -Clean up raw terminal output by stripping escape sequences, optionally preserving color. - -Get it: `go get github.com/lunixbochs/vtclean/vtclean` - -API: - - import "github.com/lunixbochs/vtclean" - vtclean.Clean(line string, color bool) string - -Command line example: - - $ echo -e '\x1b[1;32mcolor example - color forced to stop at end of line - backspace is ba\b\bgood - no beeps!\x07\x07' | ./vtclean -color - - color example - color forced to stop at end of line - backspace is good - no beeps! - -Go example: - - package main - - import ( - "fmt" - "github.com/lunixbochs/vtclean" - ) - - func main() { - line := vtclean.Clean( - "\033[1;32mcolor, " + - "curs\033[Aor, " + - "backspace\b\b\b\b\b\b\b\b\b\b\b\033[K", false) - fmt.Println(line) - } - -Output: - - color, cursor diff --git a/vendor/github.com/lunixbochs/vtclean/io.go b/vendor/github.com/lunixbochs/vtclean/io.go deleted file mode 100644 index 31be0076a..000000000 --- a/vendor/github.com/lunixbochs/vtclean/io.go +++ /dev/null @@ -1,93 +0,0 @@ -package vtclean - -import ( - "bufio" - "bytes" - "io" -) - -type reader struct { - io.Reader - scanner *bufio.Scanner - buf []byte - - color bool -} - -func NewReader(r io.Reader, color bool) io.Reader { - return &reader{Reader: r, color: color} -} - -func (r *reader) scan() bool { - if r.scanner == nil { - r.scanner = bufio.NewScanner(r.Reader) - } - if len(r.buf) > 0 { - return true - } - if r.scanner.Scan() { - r.buf = []byte(Clean(r.scanner.Text(), r.color) + "\n") - return true - } - return false -} - -func (r *reader) fill(p []byte) int { - n := len(r.buf) - copy(p, r.buf) - if len(p) < len(r.buf) { - r.buf = r.buf[len(p):] - n = len(p) - } else { - r.buf = nil - } - return n -} - -func (r *reader) Read(p []byte) (int, error) { - n := r.fill(p) - if n < len(p) { - if !r.scan() { - if n == 0 { - return 0, io.EOF - } - return n, nil - } - n += r.fill(p[n:]) - } - return n, nil -} - -type writer struct { - io.Writer - buf []byte - color bool -} - -func NewWriter(w io.Writer, color bool) io.WriteCloser { - return &writer{Writer: w, color: color} -} - -func (w *writer) Write(p []byte) (int, error) { - buf := append(w.buf, p...) - lines := bytes.Split(buf, []byte("\n")) - if len(lines) > 0 { - last := len(lines) - 1 - w.buf = lines[last] - count := 0 - for _, line := range lines[:last] { - n, err := w.Writer.Write([]byte(Clean(string(line), w.color) + "\n")) - count += n - if err != nil { - return count, err - } - } - } - return len(p), nil -} - -func (w *writer) Close() error { - cl := Clean(string(w.buf), w.color) - _, err := w.Writer.Write([]byte(cl)) - return err -} diff --git a/vendor/github.com/lunixbochs/vtclean/line.go b/vendor/github.com/lunixbochs/vtclean/line.go deleted file mode 100644 index 66ee990be..000000000 --- a/vendor/github.com/lunixbochs/vtclean/line.go +++ /dev/null @@ -1,113 +0,0 @@ -package vtclean - -type char struct { - char byte - vt100 []byte -} - -func chars(p []byte) []char { - tmp := make([]char, len(p)) - for i, v := range p { - tmp[i].char = v - } - return tmp -} - -type lineEdit struct { - buf []char - pos, size int - vt100 []byte -} - -func newLineEdit(length int) *lineEdit { - return &lineEdit{buf: make([]char, length)} -} - -func (l *lineEdit) Vt100(p []byte) { - l.vt100 = p -} - -func (l *lineEdit) Move(x int) { - if x < 0 && l.pos <= -x { - l.pos = 0 - } else if x > 0 && l.pos+x > l.size { - l.pos = l.size - } else { - l.pos += x - } -} - -func (l *lineEdit) MoveAbs(x int) { - if x < l.size { - l.pos = x - } -} - -func (l *lineEdit) Write(p []byte) { - c := chars(p) - if len(c) > 0 { - c[0].vt100 = l.vt100 - l.vt100 = nil - } - if len(l.buf)-l.pos < len(c) { - l.buf = append(l.buf[:l.pos], c...) - } else { - copy(l.buf[l.pos:], c) - } - l.pos += len(c) - if l.pos > l.size { - l.size = l.pos - } -} - -func (l *lineEdit) Insert(p []byte) { - c := chars(p) - if len(c) > 0 { - c[0].vt100 = l.vt100 - l.vt100 = nil - } - l.size += len(c) - c = append(c, l.buf[l.pos:]...) - l.buf = append(l.buf[:l.pos], c...) -} - -func (l *lineEdit) Delete(n int) { - most := l.size - l.pos - if n > most { - n = most - } - copy(l.buf[l.pos:], l.buf[l.pos+n:]) - l.size -= n -} - -func (l *lineEdit) Clear() { - for i := 0; i < len(l.buf); i++ { - l.buf[i].char = ' ' - } -} -func (l *lineEdit) ClearLeft() { - for i := 0; i < l.pos+1; i++ { - l.buf[i].char = ' ' - } -} -func (l *lineEdit) ClearRight() { - l.size = l.pos -} - -func (l *lineEdit) Bytes() []byte { - length := 0 - buf := l.buf[:l.size] - for _, v := range buf { - length += 1 + len(v.vt100) - } - tmp := make([]byte, 0, length) - for _, v := range buf { - tmp = append(tmp, v.vt100...) - tmp = append(tmp, v.char) - } - return tmp -} - -func (l *lineEdit) String() string { - return string(l.Bytes()) -} diff --git a/vendor/github.com/lunixbochs/vtclean/vtclean.go b/vendor/github.com/lunixbochs/vtclean/vtclean.go deleted file mode 100644 index 64fe01fdb..000000000 --- a/vendor/github.com/lunixbochs/vtclean/vtclean.go +++ /dev/null @@ -1,95 +0,0 @@ -package vtclean - -import ( - "bytes" - "regexp" - "strconv" -) - -// regex based on ECMA-48: -// 1. optional: -// one of [ or ] -// any amount of 0x30-0x3f -// any amount of 0x20-0x2f -// 3. exactly one 0x40-0x7e -var vt100re = regexp.MustCompile(`^\033([\[\]]([0-9:;<=>\?]*)([!"#$%&'()*+,\-./]*))?([@A-Z\[\]^_\x60a-z{|}~])`) -var vt100exc = regexp.MustCompile(`^\033(\[[^a-zA-Z0-9@\?]+|[\(\)]).`) - -// this is to handle the RGB escape generated by `tput initc 1 500 500 500` -var vt100long = regexp.MustCompile(`^\033](\d+);([^\033]+)\033\\`) - -func Clean(line string, color bool) string { - var edit = newLineEdit(len(line)) - lineb := []byte(line) - - hadColor := false - for i := 0; i < len(lineb); { - c := lineb[i] - switch c { - case '\r': - edit.MoveAbs(0) - case '\b': - edit.Move(-1) - case '\033': - // set terminal title - if bytes.HasPrefix(lineb[i:], []byte("\x1b]0;")) { - pos := bytes.Index(lineb[i:], []byte("\a")) - if pos != -1 { - i += pos + 1 - continue - } - } - if m := vt100long.Find(lineb[i:]); m != nil { - i += len(m) - } else if m := vt100exc.Find(lineb[i:]); m != nil { - i += len(m) - } else if m := vt100re.FindSubmatch(lineb[i:]); m != nil { - i += len(m[0]) - num := string(m[2]) - n, err := strconv.Atoi(num) - if err != nil || n > 10000 { - n = 1 - } - switch m[4][0] { - case 'm': - if color { - hadColor = true - edit.Vt100(m[0]) - } - case '@': - edit.Insert(bytes.Repeat([]byte{' '}, n)) - case 'G': - edit.MoveAbs(n) - case 'C': - edit.Move(n) - case 'D': - edit.Move(-n) - case 'P': - edit.Delete(n) - case 'K': - switch num { - case "", "0": - edit.ClearRight() - case "1": - edit.ClearLeft() - case "2": - edit.Clear() - } - } - } else { - i += 1 - } - continue - default: - if c == '\n' || c == '\t' || c >= ' ' { - edit.Write([]byte{c}) - } - } - i += 1 - } - out := edit.Bytes() - if hadColor { - out = append(out, []byte("\033[0m")...) - } - return string(out) -} diff --git a/vendor/github.com/manifoldco/promptui/CHANGELOG.md b/vendor/github.com/manifoldco/promptui/CHANGELOG.md index 563e9d00a..ff30afdf0 100644 --- a/vendor/github.com/manifoldco/promptui/CHANGELOG.md +++ b/vendor/github.com/manifoldco/promptui/CHANGELOG.md @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +## [0.9.0] - 2021-10-30 + +### Fixed + +- Resolve license incompatibility in tabwriter + + ## [0.8.0] - 2020-09-28 ### Added diff --git a/vendor/github.com/manifoldco/promptui/go.mod b/vendor/github.com/manifoldco/promptui/go.mod index 760a44deb..a69023954 100644 --- a/vendor/github.com/manifoldco/promptui/go.mod +++ b/vendor/github.com/manifoldco/promptui/go.mod @@ -6,11 +6,5 @@ require ( github.com/chzyer/logex v1.1.10 // indirect github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 // indirect - github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a - github.com/kr/pretty v0.1.0 // indirect - github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a // indirect - github.com/mattn/go-colorable v0.0.9 // indirect - github.com/mattn/go-isatty v0.0.4 // indirect golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b // indirect - gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect ) diff --git a/vendor/github.com/manifoldco/promptui/go.sum b/vendor/github.com/manifoldco/promptui/go.sum index be5f99025..fcb24c854 100644 --- a/vendor/github.com/manifoldco/promptui/go.sum +++ b/vendor/github.com/manifoldco/promptui/go.sum @@ -4,20 +4,5 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5O github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU= -github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a h1:weJVJJRzAJBFRlAiJQROKQs8oC9vOxvm4rZmBBk0ONw= -github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= -github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b h1:MQE+LT/ABUuuvEZ+YQAMSXindAdUh7slEmAkup74op4= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/vendor/github.com/manifoldco/promptui/select.go b/vendor/github.com/manifoldco/promptui/select.go index 19b9e0c2e..b58ed9734 100644 --- a/vendor/github.com/manifoldco/promptui/select.go +++ b/vendor/github.com/manifoldco/promptui/select.go @@ -5,10 +5,10 @@ import ( "fmt" "io" "os" + "text/tabwriter" "text/template" "github.com/chzyer/readline" - "github.com/juju/ansiterm" "github.com/manifoldco/promptui/list" "github.com/manifoldco/promptui/screenbuf" ) @@ -587,7 +587,8 @@ func (s *Select) renderDetails(item interface{}) [][]byte { } var buf bytes.Buffer - w := ansiterm.NewTabWriter(&buf, 0, 0, 8, ' ', 0) + + w := tabwriter.NewWriter(&buf, 0, 0, 8, ' ', 0) err := s.Templates.details.Execute(w, item) if err != nil { diff --git a/vendor/github.com/mattn/go-colorable/.travis.yml b/vendor/github.com/mattn/go-colorable/.travis.yml deleted file mode 100644 index 7942c565c..000000000 --- a/vendor/github.com/mattn/go-colorable/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: go -sudo: false -go: - - 1.13.x - - tip - -before_install: - - go get -t -v ./... - -script: - - ./go.test.sh - -after_success: - - bash <(curl -s https://codecov.io/bash) - diff --git a/vendor/github.com/mattn/go-colorable/LICENSE b/vendor/github.com/mattn/go-colorable/LICENSE deleted file mode 100644 index 91b5cef30..000000000 --- a/vendor/github.com/mattn/go-colorable/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Yasuhiro Matsumoto - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/mattn/go-colorable/README.md b/vendor/github.com/mattn/go-colorable/README.md deleted file mode 100644 index e055952b6..000000000 --- a/vendor/github.com/mattn/go-colorable/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# go-colorable - -[![Build Status](https://travis-ci.org/mattn/go-colorable.svg?branch=master)](https://travis-ci.org/mattn/go-colorable) -[![Codecov](https://codecov.io/gh/mattn/go-colorable/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-colorable) -[![GoDoc](https://godoc.org/github.com/mattn/go-colorable?status.svg)](http://godoc.org/github.com/mattn/go-colorable) -[![Go Report Card](https://goreportcard.com/badge/mattn/go-colorable)](https://goreportcard.com/report/mattn/go-colorable) - -Colorable writer for windows. - -For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.) -This package is possible to handle escape sequence for ansi color on windows. - -## Too Bad! - -![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/bad.png) - - -## So Good! - -![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/good.png) - -## Usage - -```go -logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true}) -logrus.SetOutput(colorable.NewColorableStdout()) - -logrus.Info("succeeded") -logrus.Warn("not correct") -logrus.Error("something error") -logrus.Fatal("panic") -``` - -You can compile above code on non-windows OSs. - -## Installation - -``` -$ go get github.com/mattn/go-colorable -``` - -# License - -MIT - -# Author - -Yasuhiro Matsumoto (a.k.a mattn) diff --git a/vendor/github.com/mattn/go-colorable/colorable_appengine.go b/vendor/github.com/mattn/go-colorable/colorable_appengine.go deleted file mode 100644 index 1f7806fe1..000000000 --- a/vendor/github.com/mattn/go-colorable/colorable_appengine.go +++ /dev/null @@ -1,37 +0,0 @@ -// +build appengine - -package colorable - -import ( - "io" - "os" - - _ "github.com/mattn/go-isatty" -) - -// NewColorable returns new instance of Writer which handles escape sequence. -func NewColorable(file *os.File) io.Writer { - if file == nil { - panic("nil passed instead of *os.File to NewColorable()") - } - - return file -} - -// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout. -func NewColorableStdout() io.Writer { - return os.Stdout -} - -// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr. -func NewColorableStderr() io.Writer { - return os.Stderr -} - -// EnableColorsStdout enable colors if possible. -func EnableColorsStdout(enabled *bool) func() { - if enabled != nil { - *enabled = true - } - return func() {} -} diff --git a/vendor/github.com/mattn/go-colorable/colorable_others.go b/vendor/github.com/mattn/go-colorable/colorable_others.go deleted file mode 100644 index 08cbd1e0f..000000000 --- a/vendor/github.com/mattn/go-colorable/colorable_others.go +++ /dev/null @@ -1,38 +0,0 @@ -// +build !windows -// +build !appengine - -package colorable - -import ( - "io" - "os" - - _ "github.com/mattn/go-isatty" -) - -// NewColorable returns new instance of Writer which handles escape sequence. -func NewColorable(file *os.File) io.Writer { - if file == nil { - panic("nil passed instead of *os.File to NewColorable()") - } - - return file -} - -// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout. -func NewColorableStdout() io.Writer { - return os.Stdout -} - -// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr. -func NewColorableStderr() io.Writer { - return os.Stderr -} - -// EnableColorsStdout enable colors if possible. -func EnableColorsStdout(enabled *bool) func() { - if enabled != nil { - *enabled = true - } - return func() {} -} diff --git a/vendor/github.com/mattn/go-colorable/colorable_windows.go b/vendor/github.com/mattn/go-colorable/colorable_windows.go deleted file mode 100644 index 41215d7fc..000000000 --- a/vendor/github.com/mattn/go-colorable/colorable_windows.go +++ /dev/null @@ -1,1043 +0,0 @@ -// +build windows -// +build !appengine - -package colorable - -import ( - "bytes" - "io" - "math" - "os" - "strconv" - "strings" - "sync" - "syscall" - "unsafe" - - "github.com/mattn/go-isatty" -) - -const ( - foregroundBlue = 0x1 - foregroundGreen = 0x2 - foregroundRed = 0x4 - foregroundIntensity = 0x8 - foregroundMask = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity) - backgroundBlue = 0x10 - backgroundGreen = 0x20 - backgroundRed = 0x40 - backgroundIntensity = 0x80 - backgroundMask = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity) - commonLvbUnderscore = 0x8000 - - cENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x4 -) - -const ( - genericRead = 0x80000000 - genericWrite = 0x40000000 -) - -const ( - consoleTextmodeBuffer = 0x1 -) - -type wchar uint16 -type short int16 -type dword uint32 -type word uint16 - -type coord struct { - x short - y short -} - -type smallRect struct { - left short - top short - right short - bottom short -} - -type consoleScreenBufferInfo struct { - size coord - cursorPosition coord - attributes word - window smallRect - maximumWindowSize coord -} - -type consoleCursorInfo struct { - size dword - visible int32 -} - -var ( - kernel32 = syscall.NewLazyDLL("kernel32.dll") - procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") - procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute") - procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition") - procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW") - procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute") - procGetConsoleCursorInfo = kernel32.NewProc("GetConsoleCursorInfo") - procSetConsoleCursorInfo = kernel32.NewProc("SetConsoleCursorInfo") - procSetConsoleTitle = kernel32.NewProc("SetConsoleTitleW") - procGetConsoleMode = kernel32.NewProc("GetConsoleMode") - procSetConsoleMode = kernel32.NewProc("SetConsoleMode") - procCreateConsoleScreenBuffer = kernel32.NewProc("CreateConsoleScreenBuffer") -) - -// Writer provides colorable Writer to the console -type Writer struct { - out io.Writer - handle syscall.Handle - althandle syscall.Handle - oldattr word - oldpos coord - rest bytes.Buffer - mutex sync.Mutex -} - -// NewColorable returns new instance of Writer which handles escape sequence from File. -func NewColorable(file *os.File) io.Writer { - if file == nil { - panic("nil passed instead of *os.File to NewColorable()") - } - - if isatty.IsTerminal(file.Fd()) { - var mode uint32 - if r, _, _ := procGetConsoleMode.Call(file.Fd(), uintptr(unsafe.Pointer(&mode))); r != 0 && mode&cENABLE_VIRTUAL_TERMINAL_PROCESSING != 0 { - return file - } - var csbi consoleScreenBufferInfo - handle := syscall.Handle(file.Fd()) - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - return &Writer{out: file, handle: handle, oldattr: csbi.attributes, oldpos: coord{0, 0}} - } - return file -} - -// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout. -func NewColorableStdout() io.Writer { - return NewColorable(os.Stdout) -} - -// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr. -func NewColorableStderr() io.Writer { - return NewColorable(os.Stderr) -} - -var color256 = map[int]int{ - 0: 0x000000, - 1: 0x800000, - 2: 0x008000, - 3: 0x808000, - 4: 0x000080, - 5: 0x800080, - 6: 0x008080, - 7: 0xc0c0c0, - 8: 0x808080, - 9: 0xff0000, - 10: 0x00ff00, - 11: 0xffff00, - 12: 0x0000ff, - 13: 0xff00ff, - 14: 0x00ffff, - 15: 0xffffff, - 16: 0x000000, - 17: 0x00005f, - 18: 0x000087, - 19: 0x0000af, - 20: 0x0000d7, - 21: 0x0000ff, - 22: 0x005f00, - 23: 0x005f5f, - 24: 0x005f87, - 25: 0x005faf, - 26: 0x005fd7, - 27: 0x005fff, - 28: 0x008700, - 29: 0x00875f, - 30: 0x008787, - 31: 0x0087af, - 32: 0x0087d7, - 33: 0x0087ff, - 34: 0x00af00, - 35: 0x00af5f, - 36: 0x00af87, - 37: 0x00afaf, - 38: 0x00afd7, - 39: 0x00afff, - 40: 0x00d700, - 41: 0x00d75f, - 42: 0x00d787, - 43: 0x00d7af, - 44: 0x00d7d7, - 45: 0x00d7ff, - 46: 0x00ff00, - 47: 0x00ff5f, - 48: 0x00ff87, - 49: 0x00ffaf, - 50: 0x00ffd7, - 51: 0x00ffff, - 52: 0x5f0000, - 53: 0x5f005f, - 54: 0x5f0087, - 55: 0x5f00af, - 56: 0x5f00d7, - 57: 0x5f00ff, - 58: 0x5f5f00, - 59: 0x5f5f5f, - 60: 0x5f5f87, - 61: 0x5f5faf, - 62: 0x5f5fd7, - 63: 0x5f5fff, - 64: 0x5f8700, - 65: 0x5f875f, - 66: 0x5f8787, - 67: 0x5f87af, - 68: 0x5f87d7, - 69: 0x5f87ff, - 70: 0x5faf00, - 71: 0x5faf5f, - 72: 0x5faf87, - 73: 0x5fafaf, - 74: 0x5fafd7, - 75: 0x5fafff, - 76: 0x5fd700, - 77: 0x5fd75f, - 78: 0x5fd787, - 79: 0x5fd7af, - 80: 0x5fd7d7, - 81: 0x5fd7ff, - 82: 0x5fff00, - 83: 0x5fff5f, - 84: 0x5fff87, - 85: 0x5fffaf, - 86: 0x5fffd7, - 87: 0x5fffff, - 88: 0x870000, - 89: 0x87005f, - 90: 0x870087, - 91: 0x8700af, - 92: 0x8700d7, - 93: 0x8700ff, - 94: 0x875f00, - 95: 0x875f5f, - 96: 0x875f87, - 97: 0x875faf, - 98: 0x875fd7, - 99: 0x875fff, - 100: 0x878700, - 101: 0x87875f, - 102: 0x878787, - 103: 0x8787af, - 104: 0x8787d7, - 105: 0x8787ff, - 106: 0x87af00, - 107: 0x87af5f, - 108: 0x87af87, - 109: 0x87afaf, - 110: 0x87afd7, - 111: 0x87afff, - 112: 0x87d700, - 113: 0x87d75f, - 114: 0x87d787, - 115: 0x87d7af, - 116: 0x87d7d7, - 117: 0x87d7ff, - 118: 0x87ff00, - 119: 0x87ff5f, - 120: 0x87ff87, - 121: 0x87ffaf, - 122: 0x87ffd7, - 123: 0x87ffff, - 124: 0xaf0000, - 125: 0xaf005f, - 126: 0xaf0087, - 127: 0xaf00af, - 128: 0xaf00d7, - 129: 0xaf00ff, - 130: 0xaf5f00, - 131: 0xaf5f5f, - 132: 0xaf5f87, - 133: 0xaf5faf, - 134: 0xaf5fd7, - 135: 0xaf5fff, - 136: 0xaf8700, - 137: 0xaf875f, - 138: 0xaf8787, - 139: 0xaf87af, - 140: 0xaf87d7, - 141: 0xaf87ff, - 142: 0xafaf00, - 143: 0xafaf5f, - 144: 0xafaf87, - 145: 0xafafaf, - 146: 0xafafd7, - 147: 0xafafff, - 148: 0xafd700, - 149: 0xafd75f, - 150: 0xafd787, - 151: 0xafd7af, - 152: 0xafd7d7, - 153: 0xafd7ff, - 154: 0xafff00, - 155: 0xafff5f, - 156: 0xafff87, - 157: 0xafffaf, - 158: 0xafffd7, - 159: 0xafffff, - 160: 0xd70000, - 161: 0xd7005f, - 162: 0xd70087, - 163: 0xd700af, - 164: 0xd700d7, - 165: 0xd700ff, - 166: 0xd75f00, - 167: 0xd75f5f, - 168: 0xd75f87, - 169: 0xd75faf, - 170: 0xd75fd7, - 171: 0xd75fff, - 172: 0xd78700, - 173: 0xd7875f, - 174: 0xd78787, - 175: 0xd787af, - 176: 0xd787d7, - 177: 0xd787ff, - 178: 0xd7af00, - 179: 0xd7af5f, - 180: 0xd7af87, - 181: 0xd7afaf, - 182: 0xd7afd7, - 183: 0xd7afff, - 184: 0xd7d700, - 185: 0xd7d75f, - 186: 0xd7d787, - 187: 0xd7d7af, - 188: 0xd7d7d7, - 189: 0xd7d7ff, - 190: 0xd7ff00, - 191: 0xd7ff5f, - 192: 0xd7ff87, - 193: 0xd7ffaf, - 194: 0xd7ffd7, - 195: 0xd7ffff, - 196: 0xff0000, - 197: 0xff005f, - 198: 0xff0087, - 199: 0xff00af, - 200: 0xff00d7, - 201: 0xff00ff, - 202: 0xff5f00, - 203: 0xff5f5f, - 204: 0xff5f87, - 205: 0xff5faf, - 206: 0xff5fd7, - 207: 0xff5fff, - 208: 0xff8700, - 209: 0xff875f, - 210: 0xff8787, - 211: 0xff87af, - 212: 0xff87d7, - 213: 0xff87ff, - 214: 0xffaf00, - 215: 0xffaf5f, - 216: 0xffaf87, - 217: 0xffafaf, - 218: 0xffafd7, - 219: 0xffafff, - 220: 0xffd700, - 221: 0xffd75f, - 222: 0xffd787, - 223: 0xffd7af, - 224: 0xffd7d7, - 225: 0xffd7ff, - 226: 0xffff00, - 227: 0xffff5f, - 228: 0xffff87, - 229: 0xffffaf, - 230: 0xffffd7, - 231: 0xffffff, - 232: 0x080808, - 233: 0x121212, - 234: 0x1c1c1c, - 235: 0x262626, - 236: 0x303030, - 237: 0x3a3a3a, - 238: 0x444444, - 239: 0x4e4e4e, - 240: 0x585858, - 241: 0x626262, - 242: 0x6c6c6c, - 243: 0x767676, - 244: 0x808080, - 245: 0x8a8a8a, - 246: 0x949494, - 247: 0x9e9e9e, - 248: 0xa8a8a8, - 249: 0xb2b2b2, - 250: 0xbcbcbc, - 251: 0xc6c6c6, - 252: 0xd0d0d0, - 253: 0xdadada, - 254: 0xe4e4e4, - 255: 0xeeeeee, -} - -// `\033]0;TITLESTR\007` -func doTitleSequence(er *bytes.Reader) error { - var c byte - var err error - - c, err = er.ReadByte() - if err != nil { - return err - } - if c != '0' && c != '2' { - return nil - } - c, err = er.ReadByte() - if err != nil { - return err - } - if c != ';' { - return nil - } - title := make([]byte, 0, 80) - for { - c, err = er.ReadByte() - if err != nil { - return err - } - if c == 0x07 || c == '\n' { - break - } - title = append(title, c) - } - if len(title) > 0 { - title8, err := syscall.UTF16PtrFromString(string(title)) - if err == nil { - procSetConsoleTitle.Call(uintptr(unsafe.Pointer(title8))) - } - } - return nil -} - -// returns Atoi(s) unless s == "" in which case it returns def -func atoiWithDefault(s string, def int) (int, error) { - if s == "" { - return def, nil - } - return strconv.Atoi(s) -} - -// Write writes data on console -func (w *Writer) Write(data []byte) (n int, err error) { - w.mutex.Lock() - defer w.mutex.Unlock() - var csbi consoleScreenBufferInfo - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - - handle := w.handle - - var er *bytes.Reader - if w.rest.Len() > 0 { - var rest bytes.Buffer - w.rest.WriteTo(&rest) - w.rest.Reset() - rest.Write(data) - er = bytes.NewReader(rest.Bytes()) - } else { - er = bytes.NewReader(data) - } - var bw [1]byte -loop: - for { - c1, err := er.ReadByte() - if err != nil { - break loop - } - if c1 != 0x1b { - bw[0] = c1 - w.out.Write(bw[:]) - continue - } - c2, err := er.ReadByte() - if err != nil { - break loop - } - - switch c2 { - case '>': - continue - case ']': - w.rest.WriteByte(c1) - w.rest.WriteByte(c2) - er.WriteTo(&w.rest) - if bytes.IndexByte(w.rest.Bytes(), 0x07) == -1 { - break loop - } - er = bytes.NewReader(w.rest.Bytes()[2:]) - err := doTitleSequence(er) - if err != nil { - break loop - } - w.rest.Reset() - continue - // https://github.com/mattn/go-colorable/issues/27 - case '7': - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - w.oldpos = csbi.cursorPosition - continue - case '8': - procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&w.oldpos))) - continue - case 0x5b: - // execute part after switch - default: - continue - } - - w.rest.WriteByte(c1) - w.rest.WriteByte(c2) - er.WriteTo(&w.rest) - - var buf bytes.Buffer - var m byte - for i, c := range w.rest.Bytes()[2:] { - if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { - m = c - er = bytes.NewReader(w.rest.Bytes()[2+i+1:]) - w.rest.Reset() - break - } - buf.Write([]byte(string(c))) - } - if m == 0 { - break loop - } - - switch m { - case 'A': - n, err = atoiWithDefault(buf.String(), 1) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.y -= short(n) - procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'B': - n, err = atoiWithDefault(buf.String(), 1) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.y += short(n) - procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'C': - n, err = atoiWithDefault(buf.String(), 1) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x += short(n) - procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'D': - n, err = atoiWithDefault(buf.String(), 1) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x -= short(n) - if csbi.cursorPosition.x < 0 { - csbi.cursorPosition.x = 0 - } - procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'E': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x = 0 - csbi.cursorPosition.y += short(n) - procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'F': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x = 0 - csbi.cursorPosition.y -= short(n) - procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'G': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - if n < 1 { - n = 1 - } - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x = short(n - 1) - procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'H', 'f': - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - if buf.Len() > 0 { - token := strings.Split(buf.String(), ";") - switch len(token) { - case 1: - n1, err := strconv.Atoi(token[0]) - if err != nil { - continue - } - csbi.cursorPosition.y = short(n1 - 1) - case 2: - n1, err := strconv.Atoi(token[0]) - if err != nil { - continue - } - n2, err := strconv.Atoi(token[1]) - if err != nil { - continue - } - csbi.cursorPosition.x = short(n2 - 1) - csbi.cursorPosition.y = short(n1 - 1) - } - } else { - csbi.cursorPosition.y = 0 - } - procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'J': - n := 0 - if buf.Len() > 0 { - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - } - var count, written dword - var cursor coord - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - switch n { - case 0: - cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} - count = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.size.y-csbi.cursorPosition.y)*dword(csbi.size.x) - case 1: - cursor = coord{x: csbi.window.left, y: csbi.window.top} - count = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.window.top-csbi.cursorPosition.y)*dword(csbi.size.x) - case 2: - cursor = coord{x: csbi.window.left, y: csbi.window.top} - count = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.size.y-csbi.cursorPosition.y)*dword(csbi.size.x) - } - procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - case 'K': - n := 0 - if buf.Len() > 0 { - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - } - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - var cursor coord - var count, written dword - switch n { - case 0: - cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} - count = dword(csbi.size.x - csbi.cursorPosition.x) - case 1: - cursor = coord{x: csbi.window.left, y: csbi.cursorPosition.y} - count = dword(csbi.size.x - csbi.cursorPosition.x) - case 2: - cursor = coord{x: csbi.window.left, y: csbi.cursorPosition.y} - count = dword(csbi.size.x) - } - procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - case 'X': - n := 0 - if buf.Len() > 0 { - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - } - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - var cursor coord - var written dword - cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} - procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(n), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(n), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - case 'm': - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - attr := csbi.attributes - cs := buf.String() - if cs == "" { - procSetConsoleTextAttribute.Call(uintptr(handle), uintptr(w.oldattr)) - continue - } - token := strings.Split(cs, ";") - for i := 0; i < len(token); i++ { - ns := token[i] - if n, err = strconv.Atoi(ns); err == nil { - switch { - case n == 0 || n == 100: - attr = w.oldattr - case n == 4: - attr |= commonLvbUnderscore - case (1 <= n && n <= 3) || n == 5: - attr |= foregroundIntensity - case n == 7 || n == 27: - attr = - (attr &^ (foregroundMask | backgroundMask)) | - ((attr & foregroundMask) << 4) | - ((attr & backgroundMask) >> 4) - case n == 22: - attr &^= foregroundIntensity - case n == 24: - attr &^= commonLvbUnderscore - case 30 <= n && n <= 37: - attr &= backgroundMask - if (n-30)&1 != 0 { - attr |= foregroundRed - } - if (n-30)&2 != 0 { - attr |= foregroundGreen - } - if (n-30)&4 != 0 { - attr |= foregroundBlue - } - case n == 38: // set foreground color. - if i < len(token)-2 && (token[i+1] == "5" || token[i+1] == "05") { - if n256, err := strconv.Atoi(token[i+2]); err == nil { - if n256foreAttr == nil { - n256setup() - } - attr &= backgroundMask - attr |= n256foreAttr[n256%len(n256foreAttr)] - i += 2 - } - } else if len(token) == 5 && token[i+1] == "2" { - var r, g, b int - r, _ = strconv.Atoi(token[i+2]) - g, _ = strconv.Atoi(token[i+3]) - b, _ = strconv.Atoi(token[i+4]) - i += 4 - if r > 127 { - attr |= foregroundRed - } - if g > 127 { - attr |= foregroundGreen - } - if b > 127 { - attr |= foregroundBlue - } - } else { - attr = attr & (w.oldattr & backgroundMask) - } - case n == 39: // reset foreground color. - attr &= backgroundMask - attr |= w.oldattr & foregroundMask - case 40 <= n && n <= 47: - attr &= foregroundMask - if (n-40)&1 != 0 { - attr |= backgroundRed - } - if (n-40)&2 != 0 { - attr |= backgroundGreen - } - if (n-40)&4 != 0 { - attr |= backgroundBlue - } - case n == 48: // set background color. - if i < len(token)-2 && token[i+1] == "5" { - if n256, err := strconv.Atoi(token[i+2]); err == nil { - if n256backAttr == nil { - n256setup() - } - attr &= foregroundMask - attr |= n256backAttr[n256%len(n256backAttr)] - i += 2 - } - } else if len(token) == 5 && token[i+1] == "2" { - var r, g, b int - r, _ = strconv.Atoi(token[i+2]) - g, _ = strconv.Atoi(token[i+3]) - b, _ = strconv.Atoi(token[i+4]) - i += 4 - if r > 127 { - attr |= backgroundRed - } - if g > 127 { - attr |= backgroundGreen - } - if b > 127 { - attr |= backgroundBlue - } - } else { - attr = attr & (w.oldattr & foregroundMask) - } - case n == 49: // reset foreground color. - attr &= foregroundMask - attr |= w.oldattr & backgroundMask - case 90 <= n && n <= 97: - attr = (attr & backgroundMask) - attr |= foregroundIntensity - if (n-90)&1 != 0 { - attr |= foregroundRed - } - if (n-90)&2 != 0 { - attr |= foregroundGreen - } - if (n-90)&4 != 0 { - attr |= foregroundBlue - } - case 100 <= n && n <= 107: - attr = (attr & foregroundMask) - attr |= backgroundIntensity - if (n-100)&1 != 0 { - attr |= backgroundRed - } - if (n-100)&2 != 0 { - attr |= backgroundGreen - } - if (n-100)&4 != 0 { - attr |= backgroundBlue - } - } - procSetConsoleTextAttribute.Call(uintptr(handle), uintptr(attr)) - } - } - case 'h': - var ci consoleCursorInfo - cs := buf.String() - if cs == "5>" { - procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) - ci.visible = 0 - procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) - } else if cs == "?25" { - procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) - ci.visible = 1 - procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) - } else if cs == "?1049" { - if w.althandle == 0 { - h, _, _ := procCreateConsoleScreenBuffer.Call(uintptr(genericRead|genericWrite), 0, 0, uintptr(consoleTextmodeBuffer), 0, 0) - w.althandle = syscall.Handle(h) - if w.althandle != 0 { - handle = w.althandle - } - } - } - case 'l': - var ci consoleCursorInfo - cs := buf.String() - if cs == "5>" { - procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) - ci.visible = 1 - procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) - } else if cs == "?25" { - procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) - ci.visible = 0 - procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) - } else if cs == "?1049" { - if w.althandle != 0 { - syscall.CloseHandle(w.althandle) - w.althandle = 0 - handle = w.handle - } - } - case 's': - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - w.oldpos = csbi.cursorPosition - case 'u': - procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&w.oldpos))) - } - } - - return len(data), nil -} - -type consoleColor struct { - rgb int - red bool - green bool - blue bool - intensity bool -} - -func (c consoleColor) foregroundAttr() (attr word) { - if c.red { - attr |= foregroundRed - } - if c.green { - attr |= foregroundGreen - } - if c.blue { - attr |= foregroundBlue - } - if c.intensity { - attr |= foregroundIntensity - } - return -} - -func (c consoleColor) backgroundAttr() (attr word) { - if c.red { - attr |= backgroundRed - } - if c.green { - attr |= backgroundGreen - } - if c.blue { - attr |= backgroundBlue - } - if c.intensity { - attr |= backgroundIntensity - } - return -} - -var color16 = []consoleColor{ - {0x000000, false, false, false, false}, - {0x000080, false, false, true, false}, - {0x008000, false, true, false, false}, - {0x008080, false, true, true, false}, - {0x800000, true, false, false, false}, - {0x800080, true, false, true, false}, - {0x808000, true, true, false, false}, - {0xc0c0c0, true, true, true, false}, - {0x808080, false, false, false, true}, - {0x0000ff, false, false, true, true}, - {0x00ff00, false, true, false, true}, - {0x00ffff, false, true, true, true}, - {0xff0000, true, false, false, true}, - {0xff00ff, true, false, true, true}, - {0xffff00, true, true, false, true}, - {0xffffff, true, true, true, true}, -} - -type hsv struct { - h, s, v float32 -} - -func (a hsv) dist(b hsv) float32 { - dh := a.h - b.h - switch { - case dh > 0.5: - dh = 1 - dh - case dh < -0.5: - dh = -1 - dh - } - ds := a.s - b.s - dv := a.v - b.v - return float32(math.Sqrt(float64(dh*dh + ds*ds + dv*dv))) -} - -func toHSV(rgb int) hsv { - r, g, b := float32((rgb&0xFF0000)>>16)/256.0, - float32((rgb&0x00FF00)>>8)/256.0, - float32(rgb&0x0000FF)/256.0 - min, max := minmax3f(r, g, b) - h := max - min - if h > 0 { - if max == r { - h = (g - b) / h - if h < 0 { - h += 6 - } - } else if max == g { - h = 2 + (b-r)/h - } else { - h = 4 + (r-g)/h - } - } - h /= 6.0 - s := max - min - if max != 0 { - s /= max - } - v := max - return hsv{h: h, s: s, v: v} -} - -type hsvTable []hsv - -func toHSVTable(rgbTable []consoleColor) hsvTable { - t := make(hsvTable, len(rgbTable)) - for i, c := range rgbTable { - t[i] = toHSV(c.rgb) - } - return t -} - -func (t hsvTable) find(rgb int) consoleColor { - hsv := toHSV(rgb) - n := 7 - l := float32(5.0) - for i, p := range t { - d := hsv.dist(p) - if d < l { - l, n = d, i - } - } - return color16[n] -} - -func minmax3f(a, b, c float32) (min, max float32) { - if a < b { - if b < c { - return a, c - } else if a < c { - return a, b - } else { - return c, b - } - } else { - if a < c { - return b, c - } else if b < c { - return b, a - } else { - return c, a - } - } -} - -var n256foreAttr []word -var n256backAttr []word - -func n256setup() { - n256foreAttr = make([]word, 256) - n256backAttr = make([]word, 256) - t := toHSVTable(color16) - for i, rgb := range color256 { - c := t.find(rgb) - n256foreAttr[i] = c.foregroundAttr() - n256backAttr[i] = c.backgroundAttr() - } -} - -// EnableColorsStdout enable colors if possible. -func EnableColorsStdout(enabled *bool) func() { - var mode uint32 - h := os.Stdout.Fd() - if r, _, _ := procGetConsoleMode.Call(h, uintptr(unsafe.Pointer(&mode))); r != 0 { - if r, _, _ = procSetConsoleMode.Call(h, uintptr(mode|cENABLE_VIRTUAL_TERMINAL_PROCESSING)); r != 0 { - if enabled != nil { - *enabled = true - } - return func() { - procSetConsoleMode.Call(h, uintptr(mode)) - } - } - } - if enabled != nil { - *enabled = true - } - return func() {} -} diff --git a/vendor/github.com/mattn/go-colorable/go.mod b/vendor/github.com/mattn/go-colorable/go.mod deleted file mode 100644 index 1e590b819..000000000 --- a/vendor/github.com/mattn/go-colorable/go.mod +++ /dev/null @@ -1,8 +0,0 @@ -module github.com/mattn/go-colorable - -require ( - github.com/mattn/go-isatty v0.0.12 - golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae // indirect -) - -go 1.13 diff --git a/vendor/github.com/mattn/go-colorable/go.sum b/vendor/github.com/mattn/go-colorable/go.sum deleted file mode 100644 index cf5b95d97..000000000 --- a/vendor/github.com/mattn/go-colorable/go.sum +++ /dev/null @@ -1,5 +0,0 @@ -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/vendor/github.com/mattn/go-colorable/go.test.sh b/vendor/github.com/mattn/go-colorable/go.test.sh deleted file mode 100644 index 012162b07..000000000 --- a/vendor/github.com/mattn/go-colorable/go.test.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -set -e -echo "" > coverage.txt - -for d in $(go list ./... | grep -v vendor); do - go test -race -coverprofile=profile.out -covermode=atomic "$d" - if [ -f profile.out ]; then - cat profile.out >> coverage.txt - rm profile.out - fi -done diff --git a/vendor/github.com/mattn/go-colorable/noncolorable.go b/vendor/github.com/mattn/go-colorable/noncolorable.go deleted file mode 100644 index 95f2c6be2..000000000 --- a/vendor/github.com/mattn/go-colorable/noncolorable.go +++ /dev/null @@ -1,55 +0,0 @@ -package colorable - -import ( - "bytes" - "io" -) - -// NonColorable holds writer but removes escape sequence. -type NonColorable struct { - out io.Writer -} - -// NewNonColorable returns new instance of Writer which removes escape sequence from Writer. -func NewNonColorable(w io.Writer) io.Writer { - return &NonColorable{out: w} -} - -// Write writes data on console -func (w *NonColorable) Write(data []byte) (n int, err error) { - er := bytes.NewReader(data) - var bw [1]byte -loop: - for { - c1, err := er.ReadByte() - if err != nil { - break loop - } - if c1 != 0x1b { - bw[0] = c1 - w.out.Write(bw[:]) - continue - } - c2, err := er.ReadByte() - if err != nil { - break loop - } - if c2 != 0x5b { - continue - } - - var buf bytes.Buffer - for { - c, err := er.ReadByte() - if err != nil { - break loop - } - if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { - break - } - buf.Write([]byte(string(c))) - } - } - - return len(data), nil -} |