diff --git a/Gopkg.lock b/Gopkg.lock index 2832e370dd1..f69177a62d6 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -183,6 +183,21 @@ pruneopts = "NUT" revision = "24818f796faf91cd76ec7bddd72458fbced7a6c1" +[[projects]] + branch = "master" + digest = "1:0d5e3798bfa2642ac268341c96710b8def1f3cbc3bc803c421d90704d72107d8" + name = "github.com/google/licenseclassifier" + packages = [ + ".", + "internal/sets", + "stringclassifier", + "stringclassifier/internal/pq", + "stringclassifier/searchset", + "stringclassifier/searchset/tokenizer", + ] + pruneopts = "NUT" + revision = "e979a0b10eebe748549c702a25e997c556349da6" + [[projects]] digest = "1:1bb197a3b5db4e06e00b7560f8e89836c486627f2a0338332ed37daa003d259e" name = "github.com/google/uuid" @@ -334,10 +349,13 @@ [[projects]] branch = "master" - digest = "1:4d0724515d22c3964ef7bf671c989c45eefb81d71be09c1d8ab74acbdbb2ca94" + digest = "1:a8f096af01ca3ef74546e412d0ffc5ad526bd17ae88495c04e6042200fc7fabc" name = "github.com/knative/test-infra" - packages = ["."] - pruneopts = "T" + packages = [ + "scripts", + "tools/dep-collector", + ] + pruneopts = "UT" revision = "f710a703baf3ac7e5e9005693fb1c8d61c4eccbb" [[projects]] @@ -467,6 +485,14 @@ pruneopts = "NUT" revision = "3113b8401b8a98917cde58f8bbd42a1b1c03b1fd" +[[projects]] + digest = "1:d917313f309bda80d27274d53985bc65651f81a5b66b820749ac7f8ef061fd04" + name = "github.com/sergi/go-diff" + packages = ["diffmatchpatch"] + pruneopts = "NUT" + revision = "1744e2970ca51c86172c8190fadad617561ed6e7" + version = "v1.0.0" + [[projects]] digest = "1:15e5c398fbd9d2c439b635a08ac161b13d04f0c2aa587fe256b65dc0c3efe8b7" name = "github.com/spf13/pflag" @@ -1009,7 +1035,8 @@ "github.com/knative/serving/pkg/apis/serving/v1alpha1", "github.com/knative/serving/pkg/client/clientset/versioned", "github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1", - "github.com/knative/test-infra", + "github.com/knative/test-infra/scripts", + "github.com/knative/test-infra/tools/dep-collector", "github.com/prometheus/client_golang/prometheus/promhttp", "go.opencensus.io/trace", "go.uber.org/atomic", diff --git a/Gopkg.toml b/Gopkg.toml index 12934b0b2ce..c0c91e568a2 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -8,7 +8,8 @@ required = [ "k8s.io/code-generator/cmd/client-gen", "k8s.io/code-generator/cmd/lister-gen", "k8s.io/code-generator/cmd/informer-gen", - "github.com/knative/test-infra", + "github.com/knative/test-infra/scripts", + "github.com/knative/test-infra/tools/dep-collector", ] [prune] @@ -23,7 +24,6 @@ required = [ [[prune.project]] name = "github.com/knative/test-infra" - unused-packages = false non-go = false # Use HEAD (2018-04-21) to pick up: diff --git a/vendor/github.com/google/licenseclassifier/LICENSE b/vendor/github.com/google/licenseclassifier/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/vendor/github.com/google/licenseclassifier/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/google/licenseclassifier/classifier.go b/vendor/github.com/google/licenseclassifier/classifier.go new file mode 100644 index 00000000000..8d39cafbf73 --- /dev/null +++ b/vendor/github.com/google/licenseclassifier/classifier.go @@ -0,0 +1,429 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package licenseclassifier provides methods to identify the open source +// license that most closely matches an unknown license. +package licenseclassifier + +import ( + "archive/tar" + "bytes" + "compress/gzip" + "fmt" + "html" + "io" + "math" + "regexp" + "sort" + "strings" + "sync" + "unicode" + + "github.com/google/licenseclassifier/stringclassifier" + "github.com/google/licenseclassifier/stringclassifier/searchset" +) + +// DefaultConfidenceThreshold is the minimum confidence percentage we're willing to accept in order +// to say that a match is good. +const DefaultConfidenceThreshold = 0.80 + +var ( + // Normalizers is a list of functions that get applied to the strings + // before they are registered with the string classifier. + Normalizers = []stringclassifier.NormalizeFunc{ + html.UnescapeString, + removeShebangLine, + RemoveNonWords, + NormalizeEquivalentWords, + NormalizePunctuation, + strings.ToLower, + removeIgnorableTexts, + stringclassifier.FlattenWhitespace, + strings.TrimSpace, + } + + // commonLicenseWords are words that are common to all known licenses. + // If an unknown text doesn't have at least one of these, then we can + // ignore it. + commonLicenseWords = []*regexp.Regexp{ + regexp.MustCompile(`(?i)\bcode\b`), + regexp.MustCompile(`(?i)\blicense\b`), + regexp.MustCompile(`(?i)\boriginal\b`), + regexp.MustCompile(`(?i)\brights\b`), + regexp.MustCompile(`(?i)\bsoftware\b`), + regexp.MustCompile(`(?i)\bterms\b`), + regexp.MustCompile(`(?i)\bversion\b`), + regexp.MustCompile(`(?i)\bwork\b`), + } +) + +// License is a classifier pre-loaded with known open source licenses. +type License struct { + c *stringclassifier.Classifier + + // Threshold is the lowest confidence percentage acceptable for the + // classifier. + Threshold float64 +} + +// New creates a license classifier and pre-loads it with known open source licenses. +func New(threshold float64) (*License, error) { + classifier := &License{ + c: stringclassifier.New(threshold, Normalizers...), + Threshold: threshold, + } + if err := classifier.registerLicenses(LicenseArchive); err != nil { + return nil, fmt.Errorf("cannot register licenses: %v", err) + } + return classifier, nil +} + +// NewWithForbiddenLicenses creates a license classifier and pre-loads it with +// known open source licenses which are forbidden. +func NewWithForbiddenLicenses(threshold float64) (*License, error) { + classifier := &License{ + c: stringclassifier.New(threshold, Normalizers...), + Threshold: threshold, + } + if err := classifier.registerLicenses(ForbiddenLicenseArchive); err != nil { + return nil, fmt.Errorf("cannot register licenses: %v", err) + } + return classifier, nil +} + +// WithinConfidenceThreshold returns true if the confidence value is above or +// equal to the confidence threshold. +func (c *License) WithinConfidenceThreshold(conf float64) bool { + return conf > c.Threshold || math.Abs(conf-c.Threshold) < math.SmallestNonzeroFloat64 +} + +// NearestMatch returns the "nearest" match to the given set of known licenses. +// Returned are the name of the license, and a confidence percentage indicating +// how confident the classifier is in the result. +func (c *License) NearestMatch(contents string) *stringclassifier.Match { + if !c.hasCommonLicenseWords(contents) { + return nil + } + m := c.c.NearestMatch(contents) + m.Name = strings.TrimSuffix(m.Name, ".header") + return m +} + +// MultipleMatch matches all licenses within an unknown text. +func (c *License) MultipleMatch(contents string, includeHeaders bool) stringclassifier.Matches { + norm := normalizeText(contents) + if !c.hasCommonLicenseWords(norm) { + return nil + } + + m := make(map[stringclassifier.Match]bool) + var matches stringclassifier.Matches + for _, v := range c.c.MultipleMatch(norm) { + if !c.WithinConfidenceThreshold(v.Confidence) { + continue + } + + if !includeHeaders && strings.HasSuffix(v.Name, ".header") { + continue + } + + v.Name = strings.TrimSuffix(v.Name, ".header") + if re, ok := forbiddenRegexps[v.Name]; ok && !re.MatchString(norm) { + continue + } + if _, ok := m[*v]; !ok { + m[*v] = true + matches = append(matches, v) + } + } + sort.Sort(matches) + return matches +} + +func normalizeText(s string) string { + for _, n := range Normalizers { + s = n(s) + } + return s +} + +// hasCommonLicenseWords returns true if the unknown text has at least one word +// that's common to all licenses. +func (c *License) hasCommonLicenseWords(s string) bool { + for _, re := range commonLicenseWords { + if re.MatchString(s) { + return true + } + } + return false +} + +type archivedValue struct { + name string + normalized string + set *searchset.SearchSet +} + +// registerLicenses loads all known licenses and adds them to c as known values +// for comparison. The allocated space after ingesting the 'licenses.db' +// archive is ~167M. +func (c *License) registerLicenses(archive string) error { + contents, err := ReadLicenseFile(archive) + if err != nil { + return err + } + + reader := bytes.NewReader(contents) + gr, err := gzip.NewReader(reader) + if err != nil { + return err + } + defer gr.Close() + + tr := tar.NewReader(gr) + + var muVals sync.Mutex + var vals []archivedValue + for i := 0; ; i++ { + hdr, err := tr.Next() + if err == io.EOF { + break + } + if err != nil { + return err + } + + name := strings.TrimSuffix(hdr.Name, ".txt") + + // Read normalized value. + var b bytes.Buffer + if _, err := io.Copy(&b, tr); err != nil { + return err + } + normalized := b.String() + b.Reset() + + // Read precomputed hashes. + hdr, err = tr.Next() + if err != nil { + return err + } + + if _, err := io.Copy(&b, tr); err != nil { + return err + } + + var set searchset.SearchSet + searchset.Deserialize(&b, &set) + + muVals.Lock() + vals = append(vals, archivedValue{name, normalized, &set}) + muVals.Unlock() + } + + for _, v := range vals { + if err = c.c.AddPrecomputedValue(v.name, v.normalized, v.set); err != nil { + return err + } + } + return nil +} + +// endOfLicenseText is text commonly associated with the end of a license. We +// can remove text that occurs after it. +var endOfLicenseText = []string{ + "END OF TERMS AND CONDITIONS", +} + +// TrimExtraneousTrailingText removes text after an obvious end of the license +// and does not include substantive text of the license. +func TrimExtraneousTrailingText(s string) string { + for _, e := range endOfLicenseText { + if i := strings.LastIndex(s, e); i != -1 { + return s[:i+len(e)] + } + } + return s +} + +var copyrightRE = regexp.MustCompile(`(?m)(?i:Copyright)\s+(?i:©\s+|\(c\)\s+)?(?:\d{2,4})(?:[-,]\s*\d{2,4})*,?\s*(?i:by)?\s*(.*?(?i:\s+Inc\.)?)[.,]?\s*(?i:All rights reserved\.?)?\s*$`) + +// CopyrightHolder finds a copyright notification, if it exists, and returns +// the copyright holder. +func CopyrightHolder(contents string) string { + matches := copyrightRE.FindStringSubmatch(contents) + if len(matches) == 2 { + return matches[1] + } + return "" +} + +var publicDomainRE = regexp.MustCompile("(?i)(this file )?is( in the)? public domain") + +// HasPublicDomainNotice performs a simple regex over the contents to see if a +// public domain notice is in there. As you can imagine, this isn't 100% +// definitive, but can be useful if a license match isn't found. +func (c *License) HasPublicDomainNotice(contents string) bool { + return publicDomainRE.FindString(contents) != "" +} + +// ignorableTexts is a list of lines at the start of the string we can remove +// to get a cleaner match. +var ignorableTexts = []*regexp.Regexp{ + regexp.MustCompile(`(?i)^(?:the )?mit license(?: \(mit\))?$`), + regexp.MustCompile(`(?i)^(?:new )?bsd license$`), + regexp.MustCompile(`(?i)^copyright and permission notice$`), + regexp.MustCompile(`(?i)^copyright (\(c\) )?(\[yyyy\]|\d{4})[,.]? .*$`), + regexp.MustCompile(`(?i)^(all|some) rights reserved\.?$`), + regexp.MustCompile(`(?i)^@license$`), + regexp.MustCompile(`^\s*$`), +} + +// removeIgnorableTexts removes common text, which is not important for +// classification, that shows up before the body of the license. +func removeIgnorableTexts(s string) string { + lines := strings.Split(strings.TrimRight(s, "\n"), "\n") + var start int + for ; start < len(lines); start++ { + line := strings.TrimSpace(lines[start]) + var matches bool + for _, re := range ignorableTexts { + if re.MatchString(line) { + matches = true + break + } + } + if !matches { + break + } + } + end := len(lines) + if start > end { + return "\n" + } + return strings.Join(lines[start:end], "\n") + "\n" +} + +// removeShebangLine removes the '#!...' line if it's the first line in the +// file. Note that if it's the only line in a comment, it won't be removed. +func removeShebangLine(s string) string { + lines := strings.Split(s, "\n") + if len(lines) <= 1 || !strings.HasPrefix(lines[0], "#!") { + return s + } + + return strings.Join(lines[1:], "\n") +} + +// isDecorative returns true if the line is made up purely of non-letter and +// non-digit characters. +func isDecorative(s string) bool { + for _, c := range s { + if unicode.IsLetter(c) || unicode.IsDigit(c) { + return false + } + } + return true +} + +var nonWords = regexp.MustCompile("[[:punct:]]+") + +// RemoveNonWords removes non-words from the string. +func RemoveNonWords(s string) string { + return nonWords.ReplaceAllString(s, " ") +} + +// interchangeablePunctutation is punctuation that can be normalized. +var interchangeablePunctuation = []struct { + interchangeable *regexp.Regexp + substitute string +}{ + // Hyphen, Dash, En Dash, and Em Dash. + {regexp.MustCompile(`[-‒–—]`), "-"}, + // Single, Double, Curly Single, and Curly Double. + {regexp.MustCompile("['\"`‘’“”]"), "'"}, + // Copyright. + {regexp.MustCompile("©"), "(c)"}, + // Hyphen-separated words. + {regexp.MustCompile(`(\S)-\s+(\S)`), "${1}-${2}"}, + // Currency and Section. (Different copies of the CDDL use each marker.) + {regexp.MustCompile("[§¤]"), "(s)"}, + // Middle Dot + {regexp.MustCompile("·"), "*"}, +} + +// NormalizePunctuation takes all hyphens and quotes and normalizes them. +func NormalizePunctuation(s string) string { + for _, iw := range interchangeablePunctuation { + s = iw.interchangeable.ReplaceAllString(s, iw.substitute) + } + return s +} + +// interchangeableWords are words we can substitute for a normalized form +// without changing the meaning of the license. See +// https://spdx.org/spdx-license-list/matching-guidelines for the list. +var interchangeableWords = []struct { + interchangeable *regexp.Regexp + substitute string +}{ + {regexp.MustCompile("(?i)Acknowledgment"), "Acknowledgement"}, + {regexp.MustCompile("(?i)Analogue"), "Analog"}, + {regexp.MustCompile("(?i)Analyse"), "Analyze"}, + {regexp.MustCompile("(?i)Artefact"), "Artifact"}, + {regexp.MustCompile("(?i)Authorisation"), "Authorization"}, + {regexp.MustCompile("(?i)Authorised"), "Authorized"}, + {regexp.MustCompile("(?i)Calibre"), "Caliber"}, + {regexp.MustCompile("(?i)Cancelled"), "Canceled"}, + {regexp.MustCompile("(?i)Capitalisations"), "Capitalizations"}, + {regexp.MustCompile("(?i)Catalogue"), "Catalog"}, + {regexp.MustCompile("(?i)Categorise"), "Categorize"}, + {regexp.MustCompile("(?i)Centre"), "Center"}, + {regexp.MustCompile("(?i)Emphasised"), "Emphasized"}, + {regexp.MustCompile("(?i)Favour"), "Favor"}, + {regexp.MustCompile("(?i)Favourite"), "Favorite"}, + {regexp.MustCompile("(?i)Fulfil"), "Fulfill"}, + {regexp.MustCompile("(?i)Fulfilment"), "Fulfillment"}, + {regexp.MustCompile("(?i)Initialise"), "Initialize"}, + {regexp.MustCompile("(?i)Judgment"), "Judgement"}, + {regexp.MustCompile("(?i)Labelling"), "Labeling"}, + {regexp.MustCompile("(?i)Labour"), "Labor"}, + {regexp.MustCompile("(?i)Licence"), "License"}, + {regexp.MustCompile("(?i)Maximise"), "Maximize"}, + {regexp.MustCompile("(?i)Modelled"), "Modeled"}, + {regexp.MustCompile("(?i)Modelling"), "Modeling"}, + {regexp.MustCompile("(?i)Offence"), "Offense"}, + {regexp.MustCompile("(?i)Optimise"), "Optimize"}, + {regexp.MustCompile("(?i)Organisation"), "Organization"}, + {regexp.MustCompile("(?i)Organise"), "Organize"}, + {regexp.MustCompile("(?i)Practise"), "Practice"}, + {regexp.MustCompile("(?i)Programme"), "Program"}, + {regexp.MustCompile("(?i)Realise"), "Realize"}, + {regexp.MustCompile("(?i)Recognise"), "Recognize"}, + {regexp.MustCompile("(?i)Signalling"), "Signaling"}, + {regexp.MustCompile("(?i)Sub[- ]license"), "Sublicense"}, + {regexp.MustCompile("(?i)Utilisation"), "Utilization"}, + {regexp.MustCompile("(?i)Whilst"), "While"}, + {regexp.MustCompile("(?i)Wilful"), "Wilfull"}, + {regexp.MustCompile("(?i)Non-commercial"), "Noncommercial"}, + {regexp.MustCompile("(?i)Per cent"), "Percent"}, +} + +// NormalizeEquivalentWords normalizes equivalent words that are interchangeable. +func NormalizeEquivalentWords(s string) string { + for _, iw := range interchangeableWords { + s = iw.interchangeable.ReplaceAllString(s, iw.substitute) + } + return s +} diff --git a/vendor/github.com/google/licenseclassifier/file_system_resources.go b/vendor/github.com/google/licenseclassifier/file_system_resources.go new file mode 100644 index 00000000000..0d92e3aec8d --- /dev/null +++ b/vendor/github.com/google/licenseclassifier/file_system_resources.go @@ -0,0 +1,65 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package licenseclassifier + +import ( + "go/build" + "io/ioutil" + "os" + "path/filepath" +) + +const ( + // LicenseDirectory is the directory where the prototype licenses are kept. + LicenseDirectory = "src/github.com/google/licenseclassifier/licenses" + // LicenseArchive is the name of the archive containing preprocessed + // license texts. + LicenseArchive = "licenses.db" + // ForbiddenLicenseArchive is the name of the archive containing preprocessed + // forbidden license texts only. + ForbiddenLicenseArchive = "forbidden_licenses.db" +) + +func findInGOPATH(rel string) (fullPath string, err error) { + for _, path := range filepath.SplitList(build.Default.GOPATH) { + fullPath := filepath.Join(path, rel) + if _, err := os.Stat(fullPath); err != nil { + if os.IsNotExist(err) { + continue + } + return "", err + } + return fullPath, nil + } + return "", nil +} + +// ReadLicenseFile locates and reads the license file. +func ReadLicenseFile(filename string) ([]byte, error) { + archive, err := findInGOPATH(filepath.Join(LicenseDirectory, filename)) + if err != nil || archive == "" { + return nil, err + } + return ioutil.ReadFile(archive) +} + +// ReadLicenseDir reads directory containing the license files. +func ReadLicenseDir() ([]os.FileInfo, error) { + filename, err := findInGOPATH(filepath.Join(LicenseDirectory, LicenseArchive)) + if err != nil || filename == "" { + return nil, err + } + return ioutil.ReadDir(filepath.Dir(filename)) +} diff --git a/vendor/github.com/google/licenseclassifier/forbidden.go b/vendor/github.com/google/licenseclassifier/forbidden.go new file mode 100644 index 00000000000..6c02ee5d6da --- /dev/null +++ b/vendor/github.com/google/licenseclassifier/forbidden.go @@ -0,0 +1,48 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package licenseclassifier + +import "regexp" + +var ( + reCCBYNC = regexp.MustCompile(`(?i).*\bAttribution NonCommercial\b.*`) + reCCBYNCND = regexp.MustCompile(`(?i).*\bAttribution NonCommercial NoDerivs\b.*`) + reCCBYNCSA = regexp.MustCompile(`(?i).*\bAttribution NonCommercial ShareAlike\b.*`) + + // forbiddenRegexps are regular expressions we expect to find in + // forbidden licenses. If we think we have a forbidden license but + // don't find the equivalent phrase, then it's probably just a + // misclassification. + forbiddenRegexps = map[string]*regexp.Regexp{ + AGPL10: regexp.MustCompile(`(?i).*\bAFFERO GENERAL PUBLIC LICENSE\b.*`), + AGPL30: regexp.MustCompile(`(?i).*\bGNU AFFERO GENERAL PUBLIC LICENSE\b.*`), + CCBYNC10: reCCBYNC, + CCBYNC20: reCCBYNC, + CCBYNC25: reCCBYNC, + CCBYNC30: reCCBYNC, + CCBYNC40: reCCBYNC, + CCBYNCND10: regexp.MustCompile(`(?i).*\bAttribution NoDerivs NonCommercial\b.*`), + CCBYNCND20: reCCBYNCND, + CCBYNCND25: reCCBYNCND, + CCBYNCND30: reCCBYNCND, + CCBYNCND40: regexp.MustCompile(`(?i).*\bAttribution NonCommercial NoDerivatives\b.*`), + CCBYNCSA10: reCCBYNCSA, + CCBYNCSA20: reCCBYNCSA, + CCBYNCSA25: reCCBYNCSA, + CCBYNCSA30: reCCBYNCSA, + CCBYNCSA40: reCCBYNCSA, + WTFPL: regexp.MustCompile(`(?i).*\bDO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE\b.*`), + } +) diff --git a/vendor/github.com/google/licenseclassifier/internal/sets/sets.go b/vendor/github.com/google/licenseclassifier/internal/sets/sets.go new file mode 100644 index 00000000000..f34ae5bf862 --- /dev/null +++ b/vendor/github.com/google/licenseclassifier/internal/sets/sets.go @@ -0,0 +1,20 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package sets provides sets for storing collections of unique elements. +package sets + +// present is an empty struct used as the "value" in the map[int], since +// empty structs consume zero bytes (unlike 1 unnecessary byte per bool). +type present struct{} diff --git a/vendor/github.com/google/licenseclassifier/internal/sets/stringset.go b/vendor/github.com/google/licenseclassifier/internal/sets/stringset.go new file mode 100644 index 00000000000..54edbd4bfde --- /dev/null +++ b/vendor/github.com/google/licenseclassifier/internal/sets/stringset.go @@ -0,0 +1,228 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package sets + +import ( + "fmt" + "sort" + "strings" +) + +// StringSet stores a set of unique string elements. +type StringSet struct { + set map[string]present +} + +// NewStringSet creates a StringSet containing the supplied initial string elements. +func NewStringSet(elements ...string) *StringSet { + s := &StringSet{} + s.set = make(map[string]present) + s.Insert(elements...) + return s +} + +// Copy returns a newly allocated copy of the supplied StringSet. +func (s *StringSet) Copy() *StringSet { + c := NewStringSet() + if s != nil { + for e := range s.set { + c.set[e] = present{} + } + } + return c +} + +// Insert zero or more string elements into the StringSet. +// As expected for a Set, elements already present in the StringSet are +// simply ignored. +func (s *StringSet) Insert(elements ...string) { + for _, e := range elements { + s.set[e] = present{} + } +} + +// Delete zero or more string elements from the StringSet. +// Any elements not present in the StringSet are simply ignored. +func (s *StringSet) Delete(elements ...string) { + for _, e := range elements { + delete(s.set, e) + } +} + +// Intersect returns a new StringSet containing the intersection of the +// receiver and argument StringSets. Returns an empty set if the argument is nil. +func (s *StringSet) Intersect(other *StringSet) *StringSet { + if other == nil { + return NewStringSet() + } + + // Point a and b to the maps, setting a to the smaller of the two. + a, b := s.set, other.set + if len(b) < len(a) { + a, b = b, a + } + + // Perform the intersection. + intersect := NewStringSet() + for e := range a { + if _, ok := b[e]; ok { + intersect.set[e] = present{} + } + } + return intersect +} + +// Disjoint returns true if the intersection of the receiver and the argument +// StringSets is the empty set. Returns true if the argument is nil or either +// StringSet is the empty set. +func (s *StringSet) Disjoint(other *StringSet) bool { + if other == nil || len(other.set) == 0 || len(s.set) == 0 { + return true + } + + // Point a and b to the maps, setting a to the smaller of the two. + a, b := s.set, other.set + if len(b) < len(a) { + a, b = b, a + } + + // Check for non-empty intersection. + for e := range a { + if _, ok := b[e]; ok { + return false // Early-exit because intersecting. + } + } + return true +} + +// Difference returns a new StringSet containing the elements in the receiver +// that are not present in the argument StringSet. Returns a copy of the +// receiver if the argument is nil. +func (s *StringSet) Difference(other *StringSet) *StringSet { + if other == nil { + return s.Copy() + } + + // Insert only the elements in the receiver that are not present in the + // argument StringSet. + diff := NewStringSet() + for e := range s.set { + if _, ok := other.set[e]; !ok { + diff.set[e] = present{} + } + } + return diff +} + +// Unique returns a new StringSet containing the elements in the receiver +// that are not present in the argument StringSet *and* the elements in the +// argument StringSet that are not in the receiver (which is the union of two +// disjoint sets). Returns a copy of the +// receiver if the argument is nil. +func (s *StringSet) Unique(other *StringSet) *StringSet { + if other == nil { + return s.Copy() + } + + sNotInOther := s.Difference(other) + otherNotInS := other.Difference(s) + + // Duplicate Union implementation here to avoid extra Copy, since both + // sNotInOther and otherNotInS are already copies. + unique := sNotInOther + for e := range otherNotInS.set { + unique.set[e] = present{} + } + return unique +} + +// Equal returns true if the receiver and the argument StringSet contain +// exactly the same elements. +func (s *StringSet) Equal(other *StringSet) bool { + if s == nil || other == nil { + return s == nil && other == nil + } + + // Two sets of different length cannot have the exact same unique elements. + if len(s.set) != len(other.set) { + return false + } + + // Only one loop is needed. If the two sets are known to be of equal + // length, then the two sets are equal only if exactly all of the elements + // in the first set are found in the second. + for e := range s.set { + if _, ok := other.set[e]; !ok { + return false + } + } + + return true +} + +// Union returns a new StringSet containing the union of the receiver and +// argument StringSets. Returns a copy of the receiver if the argument is nil. +func (s *StringSet) Union(other *StringSet) *StringSet { + union := s.Copy() + if other != nil { + for e := range other.set { + union.set[e] = present{} + } + } + return union +} + +// Contains returns true if element is in the StringSet. +func (s *StringSet) Contains(element string) bool { + _, in := s.set[element] + return in +} + +// Len returns the number of unique elements in the StringSet. +func (s *StringSet) Len() int { + return len(s.set) +} + +// Empty returns true if the receiver is the empty set. +func (s *StringSet) Empty() bool { + return len(s.set) == 0 +} + +// Elements returns a []string of the elements in the StringSet, in no +// particular (or consistent) order. +func (s *StringSet) Elements() []string { + elements := []string{} // Return at least an empty slice rather than nil. + for e := range s.set { + elements = append(elements, e) + } + return elements +} + +// Sorted returns a sorted []string of the elements in the StringSet. +func (s *StringSet) Sorted() []string { + elements := s.Elements() + sort.Strings(elements) + return elements +} + +// String formats the StringSet elements as sorted strings, representing them +// in "array initializer" syntax. +func (s *StringSet) String() string { + elements := s.Sorted() + var quoted []string + for _, e := range elements { + quoted = append(quoted, fmt.Sprintf("%q", e)) + } + return fmt.Sprintf("{%s}", strings.Join(quoted, ", ")) +} diff --git a/vendor/github.com/google/licenseclassifier/license_type.go b/vendor/github.com/google/licenseclassifier/license_type.go new file mode 100644 index 00000000000..431e61a2275 --- /dev/null +++ b/vendor/github.com/google/licenseclassifier/license_type.go @@ -0,0 +1,375 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package licenseclassifier + +// *** NOTE: Update this file when adding a new license. You need to: +// +// 1. Add the canonical name to the list, and +// 2. Categorize the license. + +import "github.com/google/licenseclassifier/internal/sets" + +// Canonical names of the licenses. +const ( + // The names come from the https://spdx.org/licenses website, and are + // also the filenames of the licenses in licenseclassifier/licenses. + AFL11 = "AFL-1.1" + AFL12 = "AFL-1.2" + AFL20 = "AFL-2.0" + AFL21 = "AFL-2.1" + AFL30 = "AFL-3.0" + AGPL10 = "AGPL-1.0" + AGPL30 = "AGPL-3.0" + Apache10 = "Apache-1.0" + Apache11 = "Apache-1.1" + Apache20 = "Apache-2.0" + APSL10 = "APSL-1.0" + APSL11 = "APSL-1.1" + APSL12 = "APSL-1.2" + APSL20 = "APSL-2.0" + Artistic10cl8 = "Artistic-1.0-cl8" + Artistic10Perl = "Artistic-1.0-Perl" + Artistic10 = "Artistic-1.0" + Artistic20 = "Artistic-2.0" + BCL = "BCL" + Beerware = "Beerware" + BSD2ClauseFreeBSD = "BSD-2-Clause-FreeBSD" + BSD2ClauseNetBSD = "BSD-2-Clause-NetBSD" + BSD2Clause = "BSD-2-Clause" + BSD3ClauseAttribution = "BSD-3-Clause-Attribution" + BSD3ClauseClear = "BSD-3-Clause-Clear" + BSD3ClauseLBNL = "BSD-3-Clause-LBNL" + BSD3Clause = "BSD-3-Clause" + BSD4Clause = "BSD-4-Clause" + BSD4ClauseUC = "BSD-4-Clause-UC" + BSDProtection = "BSD-Protection" + BSL10 = "BSL-1.0" + CC010 = "CC0-1.0" + CCBY10 = "CC-BY-1.0" + CCBY20 = "CC-BY-2.0" + CCBY25 = "CC-BY-2.5" + CCBY30 = "CC-BY-3.0" + CCBY40 = "CC-BY-4.0" + CCBYNC10 = "CC-BY-NC-1.0" + CCBYNC20 = "CC-BY-NC-2.0" + CCBYNC25 = "CC-BY-NC-2.5" + CCBYNC30 = "CC-BY-NC-3.0" + CCBYNC40 = "CC-BY-NC-4.0" + CCBYNCND10 = "CC-BY-NC-ND-1.0" + CCBYNCND20 = "CC-BY-NC-ND-2.0" + CCBYNCND25 = "CC-BY-NC-ND-2.5" + CCBYNCND30 = "CC-BY-NC-ND-3.0" + CCBYNCND40 = "CC-BY-NC-ND-4.0" + CCBYNCSA10 = "CC-BY-NC-SA-1.0" + CCBYNCSA20 = "CC-BY-NC-SA-2.0" + CCBYNCSA25 = "CC-BY-NC-SA-2.5" + CCBYNCSA30 = "CC-BY-NC-SA-3.0" + CCBYNCSA40 = "CC-BY-NC-SA-4.0" + CCBYND10 = "CC-BY-ND-1.0" + CCBYND20 = "CC-BY-ND-2.0" + CCBYND25 = "CC-BY-ND-2.5" + CCBYND30 = "CC-BY-ND-3.0" + CCBYND40 = "CC-BY-ND-4.0" + CCBYSA10 = "CC-BY-SA-1.0" + CCBYSA20 = "CC-BY-SA-2.0" + CCBYSA25 = "CC-BY-SA-2.5" + CCBYSA30 = "CC-BY-SA-3.0" + CCBYSA40 = "CC-BY-SA-4.0" + CDDL10 = "CDDL-1.0" + CDDL11 = "CDDL-1.1" + CommonsClause = "Commons-Clause" + CPAL10 = "CPAL-1.0" + CPL10 = "CPL-1.0" + eGenix = "eGenix" + EPL10 = "EPL-1.0" + EUPL10 = "EUPL-1.0" + EUPL11 = "EUPL-1.1" + Facebook2Clause = "Facebook-2-Clause" + Facebook3Clause = "Facebook-3-Clause" + FacebookExamples = "Facebook-Examples" + FreeImage = "FreeImage" + FTL = "FTL" + GPL10 = "GPL-1.0" + GPL20 = "GPL-2.0" + GPL20withautoconfexception = "GPL-2.0-with-autoconf-exception" + GPL20withbisonexception = "GPL-2.0-with-bison-exception" + GPL20withclasspathexception = "GPL-2.0-with-classpath-exception" + GPL20withfontexception = "GPL-2.0-with-font-exception" + GPL20withGCCexception = "GPL-2.0-with-GCC-exception" + GPL30 = "GPL-3.0" + GPL30withautoconfexception = "GPL-3.0-with-autoconf-exception" + GPL30withGCCexception = "GPL-3.0-with-GCC-exception" + GUSTFont = "GUST-Font-License" + ImageMagick = "ImageMagick" + IPL10 = "IPL-1.0" + ISC = "ISC" + LGPL20 = "LGPL-2.0" + LGPL21 = "LGPL-2.1" + LGPL30 = "LGPL-3.0" + LGPLLR = "LGPLLR" + Libpng = "Libpng" + Lil10 = "Lil-1.0" + LPL102 = "LPL-1.02" + LPL10 = "LPL-1.0" + LPPL13c = "LPPL-1.3c" + MIT = "MIT" + MPL10 = "MPL-1.0" + MPL11 = "MPL-1.1" + MPL20 = "MPL-2.0" + MSPL = "MS-PL" + NCSA = "NCSA" + NPL10 = "NPL-1.0" + NPL11 = "NPL-1.1" + OFL = "OFL" + OpenSSL = "OpenSSL" + OSL10 = "OSL-1.0" + OSL11 = "OSL-1.1" + OSL20 = "OSL-2.0" + OSL21 = "OSL-2.1" + OSL30 = "OSL-3.0" + PHP301 = "PHP-3.01" + PHP30 = "PHP-3.0" + PIL = "PIL" + Python20complete = "Python-2.0-complete" + Python20 = "Python-2.0" + QPL10 = "QPL-1.0" + Ruby = "Ruby" + SGIB10 = "SGI-B-1.0" + SGIB11 = "SGI-B-1.1" + SGIB20 = "SGI-B-2.0" + SISSL12 = "SISSL-1.2" + SISSL = "SISSL" + Sleepycat = "Sleepycat" + UnicodeTOU = "Unicode-TOU" + Unlicense = "Unlicense" + W3C19980720 = "W3C-19980720" + W3C = "W3C" + WTFPL = "WTFPL" + X11 = "X11" + Xnet = "Xnet" + Zend20 = "Zend-2.0" + ZlibAcknowledgement = "zlib-acknowledgement" + Zlib = "Zlib" + ZPL11 = "ZPL-1.1" + ZPL20 = "ZPL-2.0" + ZPL21 = "ZPL-2.1" +) + +var ( + // Licenses Categorized by Type + + // restricted - Licenses in this category require mandatory source + // distribution if we ships a product that includes third-party code + // protected by such a license. + restrictedType = sets.NewStringSet( + BCL, + CCBYND10, + CCBYND20, + CCBYND25, + CCBYND30, + CCBYND40, + CCBYSA10, + CCBYSA20, + CCBYSA25, + CCBYSA30, + CCBYSA40, + GPL10, + GPL20, + GPL20withautoconfexception, + GPL20withbisonexception, + GPL20withclasspathexception, + GPL20withfontexception, + GPL20withGCCexception, + GPL30, + GPL30withautoconfexception, + GPL30withGCCexception, + LGPL20, + LGPL21, + LGPL30, + NPL10, + NPL11, + OSL10, + OSL11, + OSL20, + OSL21, + OSL30, + QPL10, + Sleepycat, + ) + + // reciprocal - These licenses allow usage of software made available + // under such licenses freely in *unmodified* form. If the third-party + // source code is modified in any way these modifications to the + // original third-party source code must be made available. + reciprocalType = sets.NewStringSet( + APSL10, + APSL11, + APSL12, + APSL20, + CDDL10, + CDDL11, + CPL10, + EPL10, + FreeImage, + IPL10, + MPL10, + MPL11, + MPL20, + Ruby, + ) + + // notice - These licenses contain few restrictions, allowing original + // or modified third-party software to be shipped in any product + // without endangering or encumbering our source code. All of the + // licenses in this category do, however, have an "original Copyright + // notice" or "advertising clause", wherein any external distributions + // must include the notice or clause specified in the license. + noticeType = sets.NewStringSet( + AFL11, + AFL12, + AFL20, + AFL21, + AFL30, + Apache10, + Apache11, + Apache20, + Artistic10cl8, + Artistic10Perl, + Artistic10, + Artistic20, + BSL10, + BSD2ClauseFreeBSD, + BSD2ClauseNetBSD, + BSD2Clause, + BSD3ClauseAttribution, + BSD3ClauseClear, + BSD3ClauseLBNL, + BSD3Clause, + BSD4Clause, + BSD4ClauseUC, + BSDProtection, + CCBY10, + CCBY20, + CCBY25, + CCBY30, + CCBY40, + FTL, + ISC, + ImageMagick, + Libpng, + Lil10, + LPL102, + LPL10, + MSPL, + MIT, + NCSA, + OpenSSL, + PHP301, + PHP30, + PIL, + Python20, + Python20complete, + SGIB10, + SGIB11, + SGIB20, + UnicodeTOU, + W3C19980720, + W3C, + X11, + Xnet, + Zend20, + ZlibAcknowledgement, + Zlib, + ZPL11, + ZPL20, + ZPL21, + ) + + // permissive - These licenses can be used in (relatively rare) cases + // where third-party software is under a license (not "Public Domain" + // or "free for any use" like 'unencumbered') that is even more lenient + // than a 'notice' license. Use the 'permissive' license type when even + // a copyright notice is not required for license compliance. + permissiveType = sets.NewStringSet() + + // unencumbered - Licenses that basically declare that the code is "free for any use". + unencumberedType = sets.NewStringSet( + CC010, + Unlicense, + ) + + // byexceptiononly - Licenses that are incompatible with all (or most) + // uses in combination with our source code. Commercial third-party + // packages that are purchased and licensed only for a specific use + // fall into this category. + byExceptionOnlyType = sets.NewStringSet( + Beerware, + ) + + // forbidden - Licenses that are forbidden to be used. + forbiddenType = sets.NewStringSet( + AGPL10, + AGPL30, + CCBYNC10, + CCBYNC20, + CCBYNC25, + CCBYNC30, + CCBYNC40, + CCBYNCND10, + CCBYNCND20, + CCBYNCND25, + CCBYNCND30, + CCBYNCND40, + CCBYNCSA10, + CCBYNCSA20, + CCBYNCSA25, + CCBYNCSA30, + CCBYNCSA40, + CommonsClause, + Facebook2Clause, + Facebook3Clause, + FacebookExamples, + WTFPL, + ) + + // LicenseTypes is a set of the types of licenses Google recognizes. + LicenseTypes = sets.NewStringSet( + "restricted", + "reciprocal", + "notice", + "permissive", + "unencumbered", + "by_exception_only", + ) +) + +// LicenseType returns the type the license has. +func LicenseType(name string) string { + switch { + case restrictedType.Contains(name): + return "restricted" + case reciprocalType.Contains(name): + return "reciprocal" + case noticeType.Contains(name): + return "notice" + case permissiveType.Contains(name): + return "permissive" + case unencumberedType.Contains(name): + return "unencumbered" + case forbiddenType.Contains(name): + return "FORBIDDEN" + } + return "" +} diff --git a/vendor/github.com/google/licenseclassifier/licenses/Unlicense.txt b/vendor/github.com/google/licenseclassifier/licenses/Unlicense.txt new file mode 100644 index 00000000000..ac8f5f5f15b --- /dev/null +++ b/vendor/github.com/google/licenseclassifier/licenses/Unlicense.txt @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or distribute +this software, either in source code form or as a compiled binary, for any +purpose, commercial or non-commercial, and by any means. + +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and + +successors. We intend this dedication to be an overt act of relinquishment in +perpetuity of all present and future rights to this software under copyright +law. + +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 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. + +For more information, please refer to + diff --git a/vendor/github.com/google/licenseclassifier/licenses/licenses.db b/vendor/github.com/google/licenseclassifier/licenses/licenses.db new file mode 100644 index 00000000000..dc66125cd98 Binary files /dev/null and b/vendor/github.com/google/licenseclassifier/licenses/licenses.db differ diff --git a/vendor/github.com/google/licenseclassifier/stringclassifier/LICENSE b/vendor/github.com/google/licenseclassifier/stringclassifier/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/vendor/github.com/google/licenseclassifier/stringclassifier/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/google/licenseclassifier/stringclassifier/classifier.go b/vendor/github.com/google/licenseclassifier/stringclassifier/classifier.go new file mode 100644 index 00000000000..1bf01e26388 --- /dev/null +++ b/vendor/github.com/google/licenseclassifier/stringclassifier/classifier.go @@ -0,0 +1,560 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package stringclassifier finds the nearest match between a string and a set of known values. It +// uses the Levenshtein Distance (LD) algorithm to determine this. A match with a large LD is less +// likely to be correct than one with a small LD. A confidence percentage is returned, which +// indicates how confident the algorithm is that the match is correct. The higher the percentage, +// the greater the confidence that the match is correct. +// +// Example Usage: +// +// type Text struct { +// Name string +// Text string +// } +// +// func NewClassifier(knownTexts []Text) (*stringclassifier.Classifier, error) { +// sc := stringclassifier.New(stringclassifier.FlattenWhitespace) +// for _, known := range knownTexts { +// if err := sc.AddValue(known.Name, known.Text); err != nil { +// return nil, err +// } +// } +// return sc, nil +// } +// +// func IdentifyTexts(sc *stringclassifier.Classifier, unknownTexts []*Text) { +// for _, unknown := range unknownTexts { +// m := sc.NearestMatch(unknown.Text) +// log.Printf("The nearest match to %q is %q (confidence: %v)", +// unknown.Name, m.Name, m.Confidence) +// } +// } +package stringclassifier + +import ( + "fmt" + "log" + "math" + "regexp" + "sort" + "sync" + + "github.com/google/licenseclassifier/stringclassifier/internal/pq" + "github.com/google/licenseclassifier/stringclassifier/searchset" + "github.com/sergi/go-diff/diffmatchpatch" +) + +// The diff/match/patch algorithm. +var dmp = diffmatchpatch.New() + +const ( + // DefaultConfidenceThreshold is the minimum ratio threshold between + // the matching range and the full source range that we're willing to + // accept in order to say that the matching range will produce a + // sufficiently good edit distance. I.e., if the matching range is + // below this threshold we won't run the Levenshtein Distance algorithm + // on it. + DefaultConfidenceThreshold float64 = 0.80 + + defaultMinDiffRatio float64 = 0.75 +) + +// A Classifier matches a string to a set of known values. +type Classifier struct { + muValues sync.RWMutex + values map[string]*knownValue + normalizers []NormalizeFunc + threshold float64 + + // MinDiffRatio defines the minimum ratio of the length difference + // allowed to consider a known value a possible match. This is used as + // a performance optimization to eliminate values that are unlikely to + // be a match. + // + // For example, a value of 0.75 means that the shorter string must be + // at least 75% the length of the longer string to consider it a + // possible match. + // + // Setting this to 1.0 will require that strings are identical length. + // Setting this to 0 will consider all known values as possible + // matches. + MinDiffRatio float64 +} + +// NormalizeFunc is a function that is used to normalize a string prior to comparison. +type NormalizeFunc func(string) string + +// New creates a new Classifier with the provided NormalizeFuncs. Each +// NormalizeFunc is applied in order to a string before comparison. +func New(threshold float64, funcs ...NormalizeFunc) *Classifier { + return &Classifier{ + values: make(map[string]*knownValue), + normalizers: append([]NormalizeFunc(nil), funcs...), + threshold: threshold, + MinDiffRatio: defaultMinDiffRatio, + } +} + +// knownValue identifies a value in the corpus to match against. +type knownValue struct { + key string + normalizedValue string + reValue *regexp.Regexp + set *searchset.SearchSet +} + +// AddValue adds a known value to be matched against. If a value already exists +// for key, an error is returned. +func (c *Classifier) AddValue(key, value string) error { + c.muValues.Lock() + defer c.muValues.Unlock() + if _, ok := c.values[key]; ok { + return fmt.Errorf("value already registered with key %q", key) + } + norm := c.normalize(value) + c.values[key] = &knownValue{ + key: key, + normalizedValue: norm, + reValue: regexp.MustCompile(norm), + } + return nil +} + +// AddPrecomputedValue adds a known value to be matched against. The value has +// already been normalized and the SearchSet object deserialized, so no +// processing is necessary. +func (c *Classifier) AddPrecomputedValue(key, value string, set *searchset.SearchSet) error { + c.muValues.Lock() + defer c.muValues.Unlock() + if _, ok := c.values[key]; ok { + return fmt.Errorf("value already registered with key %q", key) + } + set.GenerateNodeList() + c.values[key] = &knownValue{ + key: key, + normalizedValue: value, + reValue: regexp.MustCompile(value), + set: set, + } + return nil +} + +// normalize a string by applying each of the registered NormalizeFuncs. +func (c *Classifier) normalize(s string) string { + for _, fn := range c.normalizers { + s = fn(s) + } + return s +} + +// Match identifies the result of matching a string against a knownValue. +type Match struct { + Name string // Name of knownValue that was matched + Confidence float64 // Confidence percentage + Offset int // The offset into the unknown string the match was made + Extent int // The length from the offset into the unknown string +} + +// Matches is a list of Match-es. This is here mainly so that the list can be +// sorted. +type Matches []*Match + +func (m Matches) Len() int { return len(m) } +func (m Matches) Swap(i, j int) { m[i], m[j] = m[j], m[i] } +func (m Matches) Less(i, j int) bool { + if math.Abs(m[j].Confidence-m[i].Confidence) < math.SmallestNonzeroFloat64 { + if m[i].Name == m[j].Name { + if m[i].Offset > m[j].Offset { + return false + } + if m[i].Offset == m[j].Offset { + return m[i].Extent > m[j].Extent + } + return true + } + return m[i].Name < m[j].Name + } + return m[i].Confidence > m[j].Confidence +} + +// Names returns an unsorted slice of the names of the matched licenses. +func (m Matches) Names() []string { + var names []string + for _, n := range m { + names = append(names, n.Name) + } + return names +} + +// uniquify goes through the matches and removes any that are contained within +// one with a higher confidence. This assumes that Matches is sorted. +func (m Matches) uniquify() Matches { + type matchedRange struct { + offset, extent int + } + + var matched []matchedRange + var matches Matches +OUTER: + for _, match := range m { + for _, mr := range matched { + if match.Offset >= mr.offset && match.Offset <= mr.offset+mr.extent { + continue OUTER + } + } + matched = append(matched, matchedRange{match.Offset, match.Extent}) + matches = append(matches, match) + } + + return matches +} + +// NearestMatch returns the name of the known value that most closely matches +// the unknown string and a confidence percentage is returned indicating how +// confident the classifier is in the result. A percentage of "1.0" indicates +// an exact match, while a percentage of "0.0" indicates a complete mismatch. +// +// If the string is equidistant from multiple known values, it is undefined +// which will be returned. +func (c *Classifier) NearestMatch(s string) *Match { + pq := c.nearestMatch(s) + if pq.Len() == 0 { + return &Match{} + } + return pq.Pop().(*Match) +} + +// MultipleMatch tries to determine which known strings are found within an +// unknown string. This differs from "NearestMatch" in that it looks only at +// those areas within the unknown string that are likely to match. A list of +// potential matches are returned. It's up to the caller to determine which +// ones are acceptable. +func (c *Classifier) MultipleMatch(s string) (matches Matches) { + pq := c.multipleMatch(s) + if pq == nil { + return matches + } + + // A map to remove duplicate entries. + m := make(map[Match]bool) + + for pq.Len() != 0 { + v := pq.Pop().(*Match) + if _, ok := m[*v]; !ok { + m[*v] = true + matches = append(matches, v) + } + } + + sort.Sort(matches) + return matches.uniquify() +} + +// possibleMatch identifies a known value and it's diffRatio to a given string. +type possibleMatch struct { + value *knownValue + diffRatio float64 +} + +// likelyMatches is a slice of possibleMatches that can be sorted by their +// diffRatio to a given string, such that the most likely matches (based on +// length) are at the beginning. +type likelyMatches []possibleMatch + +func (m likelyMatches) Len() int { return len(m) } +func (m likelyMatches) Less(i, j int) bool { return m[i].diffRatio > m[j].diffRatio } +func (m likelyMatches) Swap(i, j int) { m[i], m[j] = m[j], m[i] } + +// nearestMatch returns a Queue of values that the unknown string may be. The +// values are compared via their Levenshtein Distance and ranked with the +// nearest match at the beginning. +func (c *Classifier) nearestMatch(unknown string) *pq.Queue { + var mu sync.Mutex // Protect the priority queue. + pq := pq.NewQueue(func(x, y interface{}) bool { + return x.(*Match).Confidence > y.(*Match).Confidence + }, nil) + + unknown = c.normalize(unknown) + if len(unknown) == 0 { + return pq + } + + c.muValues.RLock() + var likely likelyMatches + for _, v := range c.values { + dr := diffRatio(unknown, v.normalizedValue) + if dr < c.MinDiffRatio { + continue + } + if unknown == v.normalizedValue { + // We found an exact match. + pq.Push(&Match{Name: v.key, Confidence: 1.0, Offset: 0, Extent: len(unknown)}) + c.muValues.RUnlock() + return pq + } + likely = append(likely, possibleMatch{value: v, diffRatio: dr}) + } + c.muValues.RUnlock() + sort.Sort(likely) + + var wg sync.WaitGroup + classifyString := func(name, unknown, known string) { + defer wg.Done() + + diffs := dmp.DiffMain(unknown, known, true) + distance := dmp.DiffLevenshtein(diffs) + confidence := confidencePercentage(len(unknown), len(known), distance) + if confidence > 0.0 { + mu.Lock() + pq.Push(&Match{Name: name, Confidence: confidence, Offset: 0, Extent: len(unknown)}) + mu.Unlock() + } + } + + wg.Add(len(likely)) + for _, known := range likely { + go classifyString(known.value.key, unknown, known.value.normalizedValue) + } + wg.Wait() + return pq +} + +// matcher finds all potential matches of "known" in "unknown". The results are +// placed in "queue". +type matcher struct { + unknown *searchset.SearchSet + normUnknown string + threshold float64 + + mu sync.Mutex + queue *pq.Queue +} + +// newMatcher creates a "matcher" object. +func newMatcher(unknown string, threshold float64) *matcher { + return &matcher{ + unknown: searchset.New(unknown, searchset.DefaultGranularity), + normUnknown: unknown, + threshold: threshold, + queue: pq.NewQueue(func(x, y interface{}) bool { + return x.(*Match).Confidence > y.(*Match).Confidence + }, nil), + } +} + +// findMatches takes a known text and finds all potential instances of it in +// the unknown text. The resulting matches can then filtered to determine which +// are the best matches. +func (m *matcher) findMatches(known *knownValue) { + var mrs []searchset.MatchRanges + if all := known.reValue.FindAllStringIndex(m.normUnknown, -1); all != nil { + // We found exact matches. Just use those! + for _, a := range all { + var start, end int + for i, tok := range m.unknown.Tokens { + if tok.Offset == a[0] { + start = i + } else if tok.Offset >= a[len(a)-1]-len(tok.Text) { + end = i + break + } + } + + mrs = append(mrs, searchset.MatchRanges{{ + SrcStart: 0, + SrcEnd: len(known.set.Tokens), + TargetStart: start, + TargetEnd: end + 1, + }}) + } + } else { + // No exact match. Perform a more thorough match. + mrs = searchset.FindPotentialMatches(known.set, m.unknown) + } + + var wg sync.WaitGroup + for _, mr := range mrs { + if !m.withinConfidenceThreshold(known.set, mr) { + continue + } + + wg.Add(1) + go func(mr searchset.MatchRanges) { + start, end := mr.TargetRange(m.unknown) + conf := levDist(m.normUnknown[start:end], known.normalizedValue) + if conf > 0.0 { + m.mu.Lock() + m.queue.Push(&Match{Name: known.key, Confidence: conf, Offset: start, Extent: end - start}) + m.mu.Unlock() + } + wg.Done() + }(mr) + } + wg.Wait() +} + +// withinConfidenceThreshold returns the Confidence we have in the potential +// match. It does this by calculating the ratio of what's matching to the +// original known text. +func (m *matcher) withinConfidenceThreshold(known *searchset.SearchSet, mr searchset.MatchRanges) bool { + return float64(mr.Size())/float64(len(known.Tokens)) >= m.threshold +} + +// multipleMatch returns a Queue of values that might be within the unknown +// string. The values are compared via their Levenshtein Distance and ranked +// with the nearest match at the beginning. +func (c *Classifier) multipleMatch(unknown string) *pq.Queue { + normUnknown := c.normalize(unknown) + if normUnknown == "" { + return nil + } + + m := newMatcher(normUnknown, c.threshold) + + c.muValues.RLock() + var kvals []*knownValue + for _, known := range c.values { + kvals = append(kvals, known) + } + c.muValues.RUnlock() + + var wg sync.WaitGroup + wg.Add(len(kvals)) + for _, known := range kvals { + go func(known *knownValue) { + if known.set == nil { + k := searchset.New(known.normalizedValue, searchset.DefaultGranularity) + c.muValues.Lock() + c.values[known.key].set = k + c.muValues.Unlock() + } + m.findMatches(known) + wg.Done() + }(known) + } + wg.Wait() + return m.queue +} + +// levDist runs the Levenshtein Distance algorithm on the known and unknown +// texts to measure how well they match. +func levDist(unknown, known string) float64 { + if len(known) == 0 || len(unknown) == 0 { + log.Printf("Zero-sized texts in Levenshtein Distance algorithm: known==%d, unknown==%d", len(known), len(unknown)) + return 0.0 + } + + // Calculate the differences between the potentially matching known + // text and the unknown text. + diffs := dmp.DiffMain(unknown, known, false) + end := diffRangeEnd(known, diffs) + + // Now execute the Levenshtein Distance algorithm to see how much it + // does match. + distance := dmp.DiffLevenshtein(diffs[:end]) + return confidencePercentage(unknownTextLength(unknown, diffs), len(known), distance) +} + +// unknownTextLength returns the length of the unknown text based on the diff range. +func unknownTextLength(unknown string, diffs []diffmatchpatch.Diff) int { + last := len(diffs) - 1 + for ; last >= 0; last-- { + if diffs[last].Type == diffmatchpatch.DiffEqual { + break + } + } + ulen := 0 + for i := 0; i < last+1; i++ { + switch diffs[i].Type { + case diffmatchpatch.DiffEqual, diffmatchpatch.DiffDelete: + ulen += len(diffs[i].Text) + } + } + return ulen +} + +// diffRangeEnd returns the end index for the "Diff" objects that constructs +// (or nearly constructs) the "known" value. +func diffRangeEnd(known string, diffs []diffmatchpatch.Diff) (end int) { + var seen string + for end = 0; end < len(diffs); end++ { + if seen == known { + // Once we've constructed the "known" value, then we've + // reached the point in the diff list where more + // "Diff"s would just make the Levenshtein Distance + // less valid. There shouldn't be further "DiffEqual" + // nodes, because there's nothing further to match in + // the "known" text. + break + } + switch diffs[end].Type { + case diffmatchpatch.DiffEqual, diffmatchpatch.DiffInsert: + seen += diffs[end].Text + } + } + return end +} + +// confidencePercentage calculates how confident we are in the result of the +// match. A percentage of "1.0" means an identical match. A confidence of "0.0" +// means a complete mismatch. +func confidencePercentage(ulen, klen, distance int) float64 { + if ulen == 0 && klen == 0 { + return 1.0 + } + if ulen == 0 || klen == 0 || (distance > ulen && distance > klen) { + return 0.0 + } + return 1.0 - float64(distance)/float64(max(ulen, klen)) +} + +// diffRatio calculates the ratio of the length of s1 and s2, returned as a +// percentage of the length of the longer string. E.g., diffLength("abcd", "e") +// would return 0.25 because "e" is 25% of the size of "abcd". Comparing +// strings of equal length will return 1. +func diffRatio(s1, s2 string) float64 { + x, y := len(s1), len(s2) + if x == 0 && y == 0 { + // Both strings are zero length + return 1.0 + } + if x < y { + return float64(x) / float64(y) + } + return float64(y) / float64(x) +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +// wsRegexp is a regexp used to identify blocks of whitespace. +var wsRegexp = regexp.MustCompile(`\s+`) + +// FlattenWhitespace will flatten contiguous blocks of whitespace down to a single space. +var FlattenWhitespace NormalizeFunc = func(s string) string { + return wsRegexp.ReplaceAllString(s, " ") +} diff --git a/vendor/github.com/google/licenseclassifier/stringclassifier/internal/pq/priority.go b/vendor/github.com/google/licenseclassifier/stringclassifier/internal/pq/priority.go new file mode 100644 index 00000000000..d1797c7aa77 --- /dev/null +++ b/vendor/github.com/google/licenseclassifier/stringclassifier/internal/pq/priority.go @@ -0,0 +1,111 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package pq provides a priority queue. +package pq + +import "container/heap" + +// NewQueue returns an unbounded priority queue that compares elements using +// less; the minimal element is at the top of the queue. +// +// If setIndex is not nil, the queue calls setIndex to inform each element of +// its position in the queue. If an element's priority changes, its position in +// the queue may be incorrect. Call Fix on the element's index to update the +// queue. Call Remove on the element's index to remove it from the queue. +func NewQueue(less func(x, y interface{}) bool, setIndex func(x interface{}, idx int)) *Queue { + return &Queue{ + heap: pqHeap{ + less: less, + setIndex: setIndex, + }, + } +} + +// Queue is a priority queue that supports updating the priority of an element. +// A Queue must be created with NewQueue. +type Queue struct { + heap pqHeap +} + +// Len returns the number of elements in the queue. +func (pq *Queue) Len() int { + return pq.heap.Len() +} + +// Push adds x to the queue. +func (pq *Queue) Push(x interface{}) { + heap.Push(&pq.heap, x) +} + +// Min returns the minimal element. +// Min panics if the queue is empty. +func (pq *Queue) Min() interface{} { + return pq.heap.a[0] +} + +// Pop removes and returns the minimal element. +// Pop panics if the queue is empty. +func (pq *Queue) Pop() interface{} { + return heap.Pop(&pq.heap) +} + +// Fix adjusts the heap to reflect that the element at index has changed priority. +func (pq *Queue) Fix(index int) { + heap.Fix(&pq.heap, index) +} + +// Remove removes the element at index i from the heap. +func (pq *Queue) Remove(index int) { + heap.Remove(&pq.heap, index) +} + +// pqHeap implements heap.Interface. +type pqHeap struct { + a []interface{} + less func(x, y interface{}) bool + setIndex func(x interface{}, idx int) +} + +func (h pqHeap) Len() int { + return len(h.a) +} + +func (h pqHeap) Less(i, j int) bool { + return h.less(h.a[i], h.a[j]) +} + +func (h pqHeap) Swap(i, j int) { + h.a[i], h.a[j] = h.a[j], h.a[i] + if h.setIndex != nil { + h.setIndex(h.a[i], i) + h.setIndex(h.a[j], j) + } +} + +func (h *pqHeap) Push(x interface{}) { + n := len(h.a) + if h.setIndex != nil { + h.setIndex(x, n) + } + h.a = append(h.a, x) +} + +func (h *pqHeap) Pop() interface{} { + old := h.a + n := len(old) + x := old[n-1] + h.a = old[:n-1] + return x +} diff --git a/vendor/github.com/google/licenseclassifier/stringclassifier/searchset/searchset.go b/vendor/github.com/google/licenseclassifier/stringclassifier/searchset/searchset.go new file mode 100644 index 00000000000..2f443e5e101 --- /dev/null +++ b/vendor/github.com/google/licenseclassifier/stringclassifier/searchset/searchset.go @@ -0,0 +1,491 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package searchset generates hashes for all substrings of a text. Potential +// matches between two SearchSet objects can then be determined quickly. +// Generating the hashes can be expensive, so it's best to perform it once. If +// the text is part of a known corpus, then the SearchSet can be serialized and +// kept in an archive. +// +// Matching occurs by "mapping" ranges from the source text into the target +// text but still retaining the source order: +// +// SOURCE: |-----------------------------| +// +// TARGET: |*****************************************| +// +// MAP SOURCE SECTIONS ONTO TARGET IN SOURCE ORDER: +// +// S: |-[--]-----[---]------[----]------| +// / | \ +// |---| |---------| |-------------| +// T: |*****************************************| +// +// Note that a single source range may match many different ranges in the +// target. The matching algorithm untangles these so that all matched ranges +// are in order with respect to the source ranges. This is especially important +// since the source text may occur more than once in the target text. The +// algorithm finds each potential occurrence of S in T and returns all as +// potential matched ranges. +package searchset + +import ( + "encoding/gob" + "fmt" + "io" + "sort" + + "github.com/google/licenseclassifier/stringclassifier/searchset/tokenizer" +) + +// DefaultGranularity is the minimum size (in words) of the hash chunks. +const DefaultGranularity = 3 + +// SearchSet is a set of substrings that have hashes associated with them, +// making it fast to search for potential matches. +type SearchSet struct { + // Tokens is a tokenized list of the original input string. + Tokens tokenizer.Tokens + // Hashes is a map of checksums to a range of tokens. + Hashes tokenizer.Hash + // Checksums is a list of checksums ordered from longest range to + // shortest. + Checksums []uint32 + // ChecksumRanges are the token ranges for the above checksums. + ChecksumRanges tokenizer.TokenRanges + + nodes []*node +} + +// node consists of a range of tokens along with the checksum for those tokens. +type node struct { + checksum uint32 + tokens *tokenizer.TokenRange +} + +func (n *node) String() string { + return fmt.Sprintf("[%d:%d]", n.tokens.Start, n.tokens.End) +} + +// New creates a new SearchSet object. It generates a hash for each substring of "s". +func New(s string, granularity int) *SearchSet { + toks := tokenizer.Tokenize(s) + + // Start generating hash values for all substrings within the text. + h := make(tokenizer.Hash) + checksums, tokenRanges := toks.GenerateHashes(h, func(a, b int) int { + if a < b { + return a + } + return b + }(len(toks), granularity)) + sset := &SearchSet{ + Tokens: toks, + Hashes: h, + Checksums: checksums, + ChecksumRanges: tokenRanges, + } + sset.GenerateNodeList() + return sset +} + +// GenerateNodeList creates a node list out of the search set. +func (s *SearchSet) GenerateNodeList() { + if len(s.Tokens) == 0 { + return + } + + for i := 0; i < len(s.Checksums); i++ { + s.nodes = append(s.nodes, &node{ + checksum: s.Checksums[i], + tokens: s.ChecksumRanges[i], + }) + } +} + +// Serialize emits the SearchSet out so that it can be recreated at a later +// time. +func (s *SearchSet) Serialize(w io.Writer) error { + return gob.NewEncoder(w).Encode(s) +} + +// Deserialize reads a file with a serialized SearchSet in it and reconstructs it. +func Deserialize(r io.Reader, s *SearchSet) error { + if err := gob.NewDecoder(r).Decode(&s); err != nil { + return err + } + s.GenerateNodeList() + return nil +} + +// MatchRange is the range within the source text that is a match to the range +// in the target text. +type MatchRange struct { + // Offsets into the source tokens. + SrcStart, SrcEnd int + // Offsets into the target tokens. + TargetStart, TargetEnd int +} + +// in returns true if the start and end are enclosed in the match range. +func (m *MatchRange) in(start, end int) bool { + return start >= m.TargetStart && end <= m.TargetEnd +} + +func (m *MatchRange) String() string { + return fmt.Sprintf("[%v, %v)->[%v, %v)", m.SrcStart, m.SrcEnd, m.TargetStart, m.TargetEnd) +} + +// MatchRanges is a list of "MatchRange"s. The ranges are monotonically +// increasing in value and indicate a single potential occurrence of the source +// text in the target text. +type MatchRanges []*MatchRange + +func (m MatchRanges) Len() int { return len(m) } +func (m MatchRanges) Swap(i, j int) { m[i], m[j] = m[j], m[i] } +func (m MatchRanges) Less(i, j int) bool { + if m[i].TargetStart < m[j].TargetStart { + return true + } + return m[i].TargetStart == m[j].TargetStart && m[i].SrcStart < m[j].SrcStart +} + +// TargetRange is the start and stop token offsets into the target text. +func (m MatchRanges) TargetRange(target *SearchSet) (start, end int) { + start = target.Tokens[m[0].TargetStart].Offset + end = target.Tokens[m[len(m)-1].TargetEnd-1].Offset + len(target.Tokens[m[len(m)-1].TargetEnd-1].Text) + return start, end +} + +// Size is the number of source tokens that were matched. +func (m MatchRanges) Size() int { + sum := 0 + for _, mr := range m { + sum += mr.SrcEnd - mr.SrcStart + } + return sum +} + +// FindPotentialMatches returns the ranges in the target (unknown) text that +// are best potential matches to the source (known) text. +func FindPotentialMatches(src, target *SearchSet) []MatchRanges { + matchedRanges := getMatchedRanges(src, target) + if len(matchedRanges) == 0 { + return nil + } + + // Cleanup the matching ranges so that we get the longest contiguous ranges. + for i := 0; i < len(matchedRanges); i++ { + matchedRanges[i] = coalesceMatchRanges(matchedRanges[i]) + } + return matchedRanges +} + +// getMatchedRanges finds the ranges in the target text that match the source +// text. There can be multiple occurrences of the source text within the target +// text. Each separate occurrence is an entry in the returned slice. +func getMatchedRanges(src, target *SearchSet) []MatchRanges { + matched := targetMatchedRanges(src, target) + if len(matched) == 0 { + return nil + } + sort.Sort(matched) + matched = untangleSourceRanges(matched) + matchedRanges := splitRanges(matched) + return mergeConsecutiveRanges(matchedRanges) +} + +func extendsAny(tr tokenizer.TokenRanges, mr []MatchRanges) bool { + if len(mr) == 0 { + return false + } + for _, tv := range tr { + for _, mv := range mr { + if tv.Start >= mv[0].TargetStart && tv.Start <= mv[len(mv)-1].TargetEnd { + return true + } + } + } + return false +} + +// targetMatchedRanges finds matching sequences in target and src ordered by target position +func targetMatchedRanges(src, target *SearchSet) MatchRanges { + if src.nodes == nil { + return nil + } + + var matched MatchRanges + var previous *node + var possible []MatchRanges + for _, tgtNode := range target.nodes { + sr, ok := src.Hashes[tgtNode.checksum] + if !ok || (previous != nil && tgtNode.tokens.Start > previous.tokens.End) || !extendsAny(sr, possible) { + for _, r := range possible { + matched = append(matched, r...) + } + possible = possible[:0] + previous = nil + } + if !ok { + // There isn't a match in the source. + continue + } + + // Maps index within `possible` to the slice of ranges extended by a new range + extended := make(map[int]*MatchRanges) + // Go over the set of source ranges growing lists of `possible` match ranges. + tv := tgtNode.tokens + for _, sv := range sr { + r := &MatchRange{ + SrcStart: sv.Start, + SrcEnd: sv.End, + TargetStart: tv.Start, + TargetEnd: tv.End, + } + found := false + // Grow or extend each abutting `possible` match range. + for i, p := range possible { + last := p[len(p)-1] + if sv.Start >= last.SrcStart && sv.Start <= last.SrcEnd && tv.Start >= last.TargetStart && tv.Start <= last.TargetEnd { + found = true + possible[i] = append(possible[i], r) + extended[i] = &possible[i] + } + } + if !found { + // Did not abut any existing ranges, start a new `possible` match range. + mrs := make(MatchRanges, 0, 2) + mrs = append(mrs, r) + possible = append(possible, mrs) + extended[len(possible)-1] = &possible[len(possible)-1] + } + } + if len(extended) < len(possible) { + // Ranges not extended--add to `matched` if not included in other range. + for i := 0; i < len(possible); { + _, updated := extended[i] + if updated { + i++ // Keep in `possible` and advance to next index. + continue + } + p1 := possible[i] + found := false // whether found as subrange of another `possible` match. + for _, p2 := range extended { + if p1[0].SrcStart >= (*p2)[0].SrcStart && p1[0].TargetStart >= (*p2)[0].TargetStart { + found = true + break + } + } + if !found { + matched = append(matched, p1...) + } // else included in other match. + // Finished -- delete from `possible` and continue from same index. + possible = append(possible[:i], possible[i+1:]...) + } + } + previous = tgtNode + } + // At end of file, terminate all `possible` match ranges. + for i := 0; i < len(possible); i++ { + p1 := possible[i] + found := false // whether found as subrange of another `possible` match. + for j := i + 1; j < len(possible); { + p2 := possible[j] + if p1[0].SrcStart <= p2[0].SrcStart && p1[0].TargetStart <= p2[0].TargetStart { + // Delete later sub-ranges included in this range. + possible = append(possible[:j], possible[j+1:]...) + continue + } + // Skip if subrange of a later range + if p1[0].SrcStart >= p2[0].SrcStart && p1[0].TargetStart >= p2[0].TargetStart { + found = true + } + j++ + } + if !found { + matched = append(matched, p1...) + } + } + return matched +} + +// untangleSourceRanges goes through the ranges and removes any whose source +// ranges are "out of order". A source range is "out of order" if the source +// range is out of sequence with the source ranges before and after it. This +// happens when more than one source range maps to the same target range. +// E.g.: +// +// SrcStart: 20, SrcEnd: 30, TargetStart: 127, TargetEnd: 137 +// 1: SrcStart: 12, SrcEnd: 17, TargetStart: 138, TargetEnd: 143 +// 2: SrcStart: 32, SrcEnd: 37, TargetStart: 138, TargetEnd: 143 +// SrcStart: 38, SrcEnd: 40, TargetStart: 144, TargetEnd: 146 +// +// Here (1) is out of order, because the source range [12, 17) is out of +// sequence with the surrounding source sequences, but [32, 37) is. +func untangleSourceRanges(matched MatchRanges) MatchRanges { + mr := MatchRanges{matched[0]} +NEXT: + for i := 1; i < len(matched); i++ { + if mr[len(mr)-1].TargetStart == matched[i].TargetStart && mr[len(mr)-1].TargetEnd == matched[i].TargetEnd { + // The matched range has already been added. + continue + } + + if i+1 < len(matched) && equalTargetRange(matched[i], matched[i+1]) { + // A sequence of ranges match the same target range. + // Find the first one that has a source range greater + // than the currently matched range. Omit all others. + if matched[i].SrcStart > mr[len(mr)-1].SrcStart { + mr = append(mr, matched[i]) + continue + } + + for j := i + 1; j < len(matched) && equalTargetRange(matched[i], matched[j]); j++ { + // Check subsequent ranges to see if we can + // find one that matches in the correct order. + if matched[j].SrcStart > mr[len(mr)-1].SrcStart { + mr = append(mr, matched[j]) + i = j + continue NEXT + } + } + } + + mr = append(mr, matched[i]) + } + return mr +} + +// equalTargetRange returns true if the two MatchRange's cover the same target range. +func equalTargetRange(this, that *MatchRange) bool { + return this.TargetStart == that.TargetStart && this.TargetEnd == that.TargetEnd +} + +// splitRanges splits the matched ranges so that a single match range has a +// monotonically increasing source range (indicating a single, potential +// instance of the source in the target). +func splitRanges(matched MatchRanges) []MatchRanges { + var matchedRanges []MatchRanges + mr := MatchRanges{matched[0]} + for i := 1; i < len(matched); i++ { + if mr[len(mr)-1].SrcStart > matched[i].SrcStart { + matchedRanges = append(matchedRanges, mr) + mr = MatchRanges{matched[i]} + } else { + mr = append(mr, matched[i]) + } + } + matchedRanges = append(matchedRanges, mr) + return matchedRanges +} + +// mergeConsecutiveRanges goes through the matched ranges and merges +// consecutive ranges. Two ranges are consecutive if the end of the previous +// matched range and beginning of the next matched range overlap. "matched" +// should have 1 or more MatchRanges, each with one or more MatchRange objects. +func mergeConsecutiveRanges(matched []MatchRanges) []MatchRanges { + mr := []MatchRanges{matched[0]} + + // Convenience functions. + prevMatchedRange := func() MatchRanges { + return mr[len(mr)-1] + } + prevMatchedRangeLastElem := func() *MatchRange { + return prevMatchedRange()[len(prevMatchedRange())-1] + } + + // This algorithm compares the start of each MatchRanges object to the + // end of the previous MatchRanges object. If they overlap, then it + // tries to combine them. Note that a 0 offset into a MatchRanges + // object (e.g., matched[i][0]) is its first MatchRange, which + // indicates the start of the whole matched range. +NEXT: + for i := 1; i < len(matched); i++ { + if prevMatchedRangeLastElem().TargetEnd > matched[i][0].TargetStart { + // Consecutive matched ranges overlap. Merge them. + if prevMatchedRangeLastElem().TargetStart < matched[i][0].TargetStart { + // The last element of the previous matched + // range overlaps with the first element of the + // current matched range. Concatenate them. + if prevMatchedRangeLastElem().TargetEnd < matched[i][0].TargetEnd { + prevMatchedRangeLastElem().SrcEnd += matched[i][0].TargetEnd - prevMatchedRangeLastElem().TargetEnd + prevMatchedRangeLastElem().TargetEnd = matched[i][0].TargetEnd + } + mr[len(mr)-1] = append(prevMatchedRange(), matched[i][1:]...) + continue + } + + for j := 1; j < len(matched[i]); j++ { + // Find the positions in the ranges where the + // tail end of the previous matched range + // overlaps with the start of the next matched + // range. + for k := len(prevMatchedRange()) - 1; k > 0; k-- { + if prevMatchedRange()[k].SrcStart < matched[i][j].SrcStart && + prevMatchedRange()[k].TargetStart < matched[i][j].TargetStart { + // Append the next range to the previous range. + if prevMatchedRange()[k].TargetEnd < matched[i][j].TargetStart { + // Coalesce the ranges. + prevMatchedRange()[k].SrcEnd += matched[i][j-1].TargetEnd - prevMatchedRange()[k].TargetEnd + prevMatchedRange()[k].TargetEnd = matched[i][j-1].TargetEnd + } + mr[len(mr)-1] = append(prevMatchedRange()[:k+1], matched[i][j:]...) + continue NEXT + } + } + } + } + mr = append(mr, matched[i]) + } + return mr +} + +// coalesceMatchRanges coalesces overlapping match ranges into a single +// contiguous match range. +func coalesceMatchRanges(matchedRanges MatchRanges) MatchRanges { + coalesced := MatchRanges{matchedRanges[0]} + for i := 1; i < len(matchedRanges); i++ { + c := coalesced[len(coalesced)-1] + mr := matchedRanges[i] + + if mr.SrcStart <= c.SrcEnd && mr.SrcStart >= c.SrcStart { + var se, ts, te int + if mr.SrcEnd > c.SrcEnd { + se = mr.SrcEnd + } else { + se = c.SrcEnd + } + if mr.TargetStart < c.TargetStart { + ts = mr.TargetStart + } else { + ts = c.TargetStart + } + if mr.TargetEnd > c.TargetEnd { + te = mr.TargetEnd + } else { + te = c.TargetEnd + } + coalesced[len(coalesced)-1] = &MatchRange{ + SrcStart: c.SrcStart, + SrcEnd: se, + TargetStart: ts, + TargetEnd: te, + } + } else { + coalesced = append(coalesced, mr) + } + } + return coalesced +} diff --git a/vendor/github.com/google/licenseclassifier/stringclassifier/searchset/tokenizer/tokenizer.go b/vendor/github.com/google/licenseclassifier/stringclassifier/searchset/tokenizer/tokenizer.go new file mode 100644 index 00000000000..0f842d866ef --- /dev/null +++ b/vendor/github.com/google/licenseclassifier/stringclassifier/searchset/tokenizer/tokenizer.go @@ -0,0 +1,175 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package tokenizer converts a text into a stream of tokens. +package tokenizer + +import ( + "bytes" + "fmt" + "hash/crc32" + "sort" + "unicode" + "unicode/utf8" +) + +// Token is a non-whitespace sequence (i.e., word or punctuation) in the +// original string. This is not meant for use outside of this package. +type token struct { + Text string + Offset int +} + +// Tokens is a list of Token objects. +type Tokens []*token + +// newToken creates a new token object with an invalid (negative) offset, which +// will be set before the token's used. +func newToken() *token { + return &token{Offset: -1} +} + +// Tokenize converts a string into a stream of tokens. +func Tokenize(s string) (toks Tokens) { + tok := newToken() + for i := 0; i < len(s); { + r, size := utf8.DecodeRuneInString(s[i:]) + switch { + case unicode.IsSpace(r): + if tok.Offset >= 0 { + toks = append(toks, tok) + tok = newToken() + } + case unicode.IsPunct(r): + if tok.Offset >= 0 { + toks = append(toks, tok) + tok = newToken() + } + toks = append(toks, &token{ + Text: string(r), + Offset: i, + }) + default: + if tok.Offset == -1 { + tok.Offset = i + } + tok.Text += string(r) + } + i += size + } + if tok.Offset != -1 { + // Add any remaining token that wasn't yet included in the list. + toks = append(toks, tok) + } + return toks +} + +// GenerateHashes generates hashes for "size" length substrings. The +// "stringifyTokens" call takes a long time to run, so not all substrings have +// hashes, i.e. we skip some of the smaller substrings. +func (t Tokens) GenerateHashes(h Hash, size int) ([]uint32, TokenRanges) { + if size == 0 { + return nil, nil + } + + var css []uint32 + var tr TokenRanges + for offset := 0; offset+size <= len(t); offset += size / 2 { + var b bytes.Buffer + t.stringifyTokens(&b, offset, size) + cs := crc32.ChecksumIEEE(b.Bytes()) + css = append(css, cs) + tr = append(tr, &TokenRange{offset, offset + size}) + h.add(cs, offset, offset+size) + if size <= 1 { + break + } + } + + return css, tr +} + +// stringifyTokens serializes a sublist of tokens into a bytes buffer. +func (t Tokens) stringifyTokens(b *bytes.Buffer, offset, size int) { + for j := offset; j < offset+size; j++ { + if j != offset { + b.WriteRune(' ') + } + b.WriteString(t[j].Text) + } +} + +// TokenRange indicates the range of tokens that map to a particular checksum. +type TokenRange struct { + Start int + End int +} + +func (t *TokenRange) String() string { + return fmt.Sprintf("[%v, %v)", t.Start, t.End) +} + +// TokenRanges is a list of TokenRange objects. The chance that two different +// strings map to the same checksum is very small, but unfortunately isn't +// zero, so we use this instead of making the assumption that they will all be +// unique. +type TokenRanges []*TokenRange + +func (t TokenRanges) Len() int { return len(t) } +func (t TokenRanges) Swap(i, j int) { t[i], t[j] = t[j], t[i] } +func (t TokenRanges) Less(i, j int) bool { return t[i].Start < t[j].Start } + +// CombineUnique returns the combination of both token ranges with no duplicates. +func (t TokenRanges) CombineUnique(other TokenRanges) TokenRanges { + if len(other) == 0 { + return t + } + if len(t) == 0 { + return other + } + + cu := append(t, other...) + sort.Sort(cu) + + if len(cu) == 0 { + return nil + } + + res := TokenRanges{cu[0]} + for prev, i := cu[0], 1; i < len(cu); i++ { + if prev.Start != cu[i].Start || prev.End != cu[i].End { + res = append(res, cu[i]) + prev = cu[i] + } + } + return res +} + +// Hash is a map of the hashes of a section of text to the token range covering that text. +type Hash map[uint32]TokenRanges + +// add associates a token range, [start, end], to a checksum. +func (h Hash) add(checksum uint32, start, end int) { + ntr := &TokenRange{Start: start, End: end} + if r, ok := h[checksum]; ok { + for _, tr := range r { + if tr.Start == ntr.Start && tr.End == ntr.End { + // The token range already exists at this + // checksum. No need to re-add it. + return + } + } + } + h[checksum] = append(h[checksum], ntr) +} diff --git a/vendor/github.com/knative/test-infra/.github/pull-request-template.md b/vendor/github.com/knative/test-infra/.github/pull-request-template.md deleted file mode 100644 index 9b2b7820f61..00000000000 --- a/vendor/github.com/knative/test-infra/.github/pull-request-template.md +++ /dev/null @@ -1,7 +0,0 @@ - - -Fixes # diff --git a/vendor/github.com/knative/test-infra/CONTRIBUTING.md b/vendor/github.com/knative/test-infra/CONTRIBUTING.md deleted file mode 100644 index bcfe857fda4..00000000000 --- a/vendor/github.com/knative/test-infra/CONTRIBUTING.md +++ /dev/null @@ -1,3 +0,0 @@ -# Contribution guidelines - -So you want to hack on Knative Test Infrastructure? Yay! Please refer to Knative's overall [contribution guidelines](https://github.com/knative/docs/blob/master/community/CONTRIBUTING.md) to find out how you can help. diff --git a/vendor/github.com/knative/test-infra/Gopkg.lock b/vendor/github.com/knative/test-infra/Gopkg.lock deleted file mode 100644 index e0347ada5a9..00000000000 --- a/vendor/github.com/knative/test-infra/Gopkg.lock +++ /dev/null @@ -1,28 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - branch = "master" - name = "github.com/google/licenseclassifier" - packages = [ - ".", - "internal/sets", - "stringclassifier", - "stringclassifier/internal/pq", - "stringclassifier/searchset", - "stringclassifier/searchset/tokenizer" - ] - revision = "3c8ad1f0b0644b6646210ee9cf2f34ff907e2e18" - -[[projects]] - name = "github.com/sergi/go-diff" - packages = ["diffmatchpatch"] - revision = "1744e2970ca51c86172c8190fadad617561ed6e7" - version = "v1.0.0" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - inputs-digest = "aea50f9014005bedc3dc202c5fbf9d2d8c7a6f7beac2337fd863b23f411c4125" - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/vendor/github.com/knative/test-infra/Gopkg.toml b/vendor/github.com/knative/test-infra/Gopkg.toml deleted file mode 100644 index 1a03ba55a89..00000000000 --- a/vendor/github.com/knative/test-infra/Gopkg.toml +++ /dev/null @@ -1,14 +0,0 @@ -# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html -# for detailed Gopkg.toml documentation. - -required = [ - "github.com/google/licenseclassifier/licenses", -] - -# TODO(mattmoor): Find a way to bundle the licenseclassifier's -# license database, so folks don't have to go get it. - -[prune] - go-tests = true - unused-packages = true - non-go = true diff --git a/vendor/github.com/knative/test-infra/OWNERS b/vendor/github.com/knative/test-infra/OWNERS deleted file mode 100644 index ed8dd603cf2..00000000000 --- a/vendor/github.com/knative/test-infra/OWNERS +++ /dev/null @@ -1,9 +0,0 @@ -# The OWNERS file is used by prow to automatically merge approved PRs. - -approvers: -- adrcunha -- dushyanthsc -- ericKlawitter -- jessiezcc -- srinivashegde86 -- steuhs diff --git a/vendor/github.com/knative/test-infra/README.md b/vendor/github.com/knative/test-infra/README.md deleted file mode 100644 index 88f40521e11..00000000000 --- a/vendor/github.com/knative/test-infra/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Knative Test Infrastructure - -The `test-infra` repository contains a collection of tools for testing Knative, collecting metrics -and displaying test results. - -## High level architecture - -Knative uses [Prow](https://github.com/kubernetes/test-infra/tree/master/prow) to schedule testing and update issues. - -### Gubernator - -Knative uses [gubernator](https://github.com/kubernetes/test-infra) to provide -a [PR dashboard](https://gubernator.knative.dev/pr) for contributions in the Knative github organization. - -### E2E Testing - -Our E2E testing uses [kubetest](https://github.com/kubernetes/test-infra/blob/master/kubetest) to build/deploy/test Knative clusters. diff --git a/vendor/github.com/knative/test-infra/WORKSPACE b/vendor/github.com/knative/test-infra/WORKSPACE deleted file mode 100644 index 91db673d566..00000000000 --- a/vendor/github.com/knative/test-infra/WORKSPACE +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Required rules for building kubernetes/test-infra -# These all come from http://github.com/kubernetes/test-infra/blob/master/WORKSPACE - -http_archive( - name = "io_bazel_rules_go", - sha256 = "1868ff68d6079e31b2f09b828b58d62e57ca8e9636edff699247c9108518570b", - url = "https://github.com/bazelbuild/rules_go/releases/download/0.11.1/rules_go-0.11.1.tar.gz", -) - -load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains") - -go_rules_dependencies() - -go_register_toolchains( - go_version = "1.10.2", -) - -git_repository( - name = "io_bazel_rules_k8s", - commit = "3756369d4920033c32c12d16207e8ee14fee1b18", - remote = "https://github.com/bazelbuild/rules_k8s.git", -) - -http_archive( - name = "io_bazel_rules_docker", - sha256 = "cef4e7adfc1df999891e086bf42bed9092cfdf374adb902f18de2c1d6e1e0197", - strip_prefix = "rules_docker-198367210c55fba5dded22274adde1a289801dc4", - urls = ["https://github.com/bazelbuild/rules_docker/archive/198367210c55fba5dded22274adde1a289801dc4.tar.gz"], -) - -# External repositories - -git_repository( - name = "k8s", - remote = "http://github.com/kubernetes/test-infra.git", - commit = "dd12621d6178838097847abf5842ad8d08fc9308", # HEAD as of 8/1/2018 -) - diff --git a/vendor/github.com/knative/test-infra/ci/README.md b/vendor/github.com/knative/test-infra/ci/README.md deleted file mode 100644 index 51b28eddac4..00000000000 --- a/vendor/github.com/knative/test-infra/ci/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Continuous Integration / Continuous Deployment system - -This directory contains the configs for all systems related to Knative's CI/CD system. diff --git a/vendor/github.com/knative/test-infra/ci/gubernator/Makefile b/vendor/github.com/knative/test-infra/ci/gubernator/Makefile deleted file mode 100644 index 5307d95d94f..00000000000 --- a/vendor/github.com/knative/test-infra/ci/gubernator/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -SRC := test-infra/gubernator - -deploy: - # Fetch latest source, patch for our instance - rm -fr test-infra - git clone http://github.com/kubernetes/test-infra.git - cp config.yaml $(SRC) - cp redir_github.py $(SRC) - sed -i -e '/^runtime: .*/a service: gubernator' $(SRC)/app.yaml - sed -i -e "/^handlers:/a\- url: /timeline\n script: redir_github.app\n" $(SRC)/app.yaml - sed -i -e 's/user:kubernetes/user:knative/' $(SRC)/view_pr.py - sed -i -e 's/Kubernetes/Knative/' $(SRC)/templates/index.html - sed -i -e 's/k8s-testgrid.appspot.com/testgrid.knative.dev/' $(SRC)/filters.py - sed -i -e 's/k8s-testgrid/knative-testgrid/' $(SRC)/testgrid.py - # Deploy - make -C ../prow get-cluster-credentials - PROJECT=knative-tests make -C $(SRC) deploy - # Cleanup - rm -fr test-infra diff --git a/vendor/github.com/knative/test-infra/ci/gubernator/README.md b/vendor/github.com/knative/test-infra/ci/gubernator/README.md deleted file mode 100644 index 14508c3dfda..00000000000 --- a/vendor/github.com/knative/test-infra/ci/gubernator/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Gubernator config - -This directory contains the config for our [Gubernator](https://github.com/kubernetes/test-infra/tree/master/gubernator) instance, plus a makefile for deploying it. - -* `config.yaml` Gubernator configuration. -* `Makefile` Recipe for deploying a Gubernator instance. -* `redir_github.py` Simple redirection handler to Gubernator's GitHub service. diff --git a/vendor/github.com/knative/test-infra/ci/gubernator/config.yaml b/vendor/github.com/knative/test-infra/ci/gubernator/config.yaml deleted file mode 100644 index 794b4ce2bdd..00000000000 --- a/vendor/github.com/knative/test-infra/ci/gubernator/config.yaml +++ /dev/null @@ -1,71 +0,0 @@ - -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -default_external_services: - gcs_pull_prefix: knative-prow/pr-logs/pull - prow_url: prow.knative.dev -default_org: knative -default_repo: serving -external_services: - knative: - gcs_bucket: knative-prow/ - gcs_pull_prefix: knative-prow/pr-logs/pull - prow_url: prow.knative.dev -jobs: - knative-prow/pr-logs/directory/: - - pull-knative-serving-build-tests - - pull-knative-serving-integration-tests - - pull-knative-serving-unit-tests - - pull-knative-eventing-build-tests - - pull-knative-eventing-integration-tests - - pull-knative-eventing-unit-tests - - pull-knative-eventing-sources-build-tests - - pull-knative-eventing-sources-integration-tests - - pull-knative-eventing-sources-unit-tests - - pull-knative-docs-build-tests - - pull-knative-docs-unit-tests - - pull-knative-docs-integration-tests - - pull-knative-build-templates-unit-tests - - pull-knative-build-templates-build-tests - - pull-knative-build-templates-integration-tests - - pull-knative-build-pipeline-build-tests - - pull-knative-build-pipeline-unit-tests - - pull-knative-build-build-tests - - pull-knative-build-unit-tests - - pull-knative-build-integration-tests - - pull-knative-pkg-build-tests - - pull-knative-pkg-unit-tests - - pull-knative-pkg-integration-tests - - pull-knative-test-infra-build-tests - - pull-knative-test-infra-unit-tests - - pull-knative-test-infra-integration-tests - - pull-knative-caching-build-tests - - pull-knative-caching-unit-tests - - pull-knative-caching-integration-tests - knative-prow/logs/: - - ci-knative-serving-continuous - - ci-knative-serving-release - - ci-knative-serving-playground - - ci-knative-build-continuous - - ci-knative-build-release - - ci-knative-eventing-continuous - - ci-knative-eventing-release - - ci-knative-eventing-sources-continuous - - ci-knative-eventing-sources-release - - ci-knative-build-templates-continuous - - ci-knative-docs-continuous - - ci-knative-pkg-continuous - - ci-knative-caching-continuous -recursive_artifacts: false diff --git a/vendor/github.com/knative/test-infra/ci/gubernator/redir_github.py b/vendor/github.com/knative/test-infra/ci/gubernator/redir_github.py deleted file mode 100644 index e168d6adbc5..00000000000 --- a/vendor/github.com/knative/test-infra/ci/gubernator/redir_github.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python - -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Simple redirection handler to Gubernator's GitHub service.""" - -import webapp2 - -class GitHubRedirect(webapp2.RequestHandler): - def get(self): - self.redirect("https://github-dot-knative-tests.appspot.com" + self.request.path_qs) - -app = webapp2.WSGIApplication([(r'/.*', GitHubRedirect),], debug=True, config={}) diff --git a/vendor/github.com/knative/test-infra/ci/prow/Makefile b/vendor/github.com/knative/test-infra/ci/prow/Makefile deleted file mode 100644 index 9b6fcfbea17..00000000000 --- a/vendor/github.com/knative/test-infra/ci/prow/Makefile +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -CLUSTER ?= prow -PROJECT ?= knative-tests -ZONE ?= us-central1-f -JOB_NAMESPACE ?= test-pods - -PROW_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) - -get-cluster-credentials: - gcloud container clusters get-credentials "$(CLUSTER)" --project="$(PROJECT)" --zone="$(ZONE)" - -update-config: get-cluster-credentials - kubectl create configmap config --from-file=config.yaml=config.yaml --dry-run -o yaml | kubectl replace configmap config -f - - -update-plugins: get-cluster-credentials - kubectl create configmap plugins --from-file=plugins.yaml=plugins.yaml --dry-run -o yaml | kubectl replace configmap plugins -f - - -update-boskos: get-cluster-credentials - kubectl apply -f boskos/config.yaml - -update-boskos-config: get-cluster-credentials - kubectl create configmap resources --from-file=config=boskos/resources.yaml --dry-run -o yaml | kubectl --namespace="$(JOB_NAMESPACE)" replace configmap resources -f - - -update-cluster: get-cluster-credentials - kubectl apply -f cluster.yaml - -test: - bazel run @k8s//prow/cmd/config -- --plugin-config=$(PROW_DIR)/plugins.yaml - bazel run @k8s//prow/cmd/config -- --config-path=$(PROW_DIR)/config.yaml diff --git a/vendor/github.com/knative/test-infra/ci/prow/README.md b/vendor/github.com/knative/test-infra/ci/prow/README.md deleted file mode 100644 index 04fd12e6bb2..00000000000 --- a/vendor/github.com/knative/test-infra/ci/prow/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Prow config - -This directory contains the config for our [Prow](https://github.com/kubernetes/test-infra/tree/master/prow) instance. - -* `boskos` Configuration for the Boskos instance. -* `Makefile` Commands to interact with the Prow instance regarding updates. -* `cluster.yaml` Configuration of the Prow cluster. -* `config.yaml` Configuration of the Prow jobs. -* `config_start.yaml` Initial, empty configuration for Prow. -* `plugins.yaml` Configuration of the Prow plugins. diff --git a/vendor/github.com/knative/test-infra/ci/prow/boskos/README.md b/vendor/github.com/knative/test-infra/ci/prow/boskos/README.md deleted file mode 100644 index 8e6e90ab6b1..00000000000 --- a/vendor/github.com/knative/test-infra/ci/prow/boskos/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Boskos config - -This directory contains the config for our [Boskos](https://github.com/kubernetes/test-infra/tree/master/boskos) instance. - -* `config.yaml` Boskos configuration. -* `resources.yaml` Pool of projects used by Boskos. diff --git a/vendor/github.com/knative/test-infra/ci/prow/boskos/config.yaml b/vendor/github.com/knative/test-infra/ci/prow/boskos/config.yaml deleted file mode 100644 index a444d6cff8b..00000000000 --- a/vendor/github.com/knative/test-infra/ci/prow/boskos/config.yaml +++ /dev/null @@ -1,152 +0,0 @@ -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Boskos deployment for Knative Prow instance ---- -apiVersion: v1 -kind: PersistentVolume -metadata: - labels: - app: boskos - name: boskos-storage - namespace: test-pods -spec: - claimRef: - name: boskos-volume-boskos-0 - namespace: test-pods - capacity: - storage: 1Gi - accessModes: - - ReadWriteOnce - persistentVolumeReclaimPolicy: Retain - gcePersistentDisk: - pdName: boskos-storage - fsType: ext4 ---- -# Start of StatefulSet -apiVersion: apps/v1beta1 -kind: StatefulSet -metadata: - name: boskos - namespace: test-pods -spec: - serviceName: "boskos" - replicas: 1 # one canonical source of resources - template: - metadata: - labels: - app: boskos - namespace: test-pods - spec: - serviceAccountName: "boskos" - terminationGracePeriodSeconds: 30 - containers: - - name: boskos - image: gcr.io/k8s-testimages/boskos:v20180405-12e892d69 - args: - - --storage=/store/boskos.json - - --config=/etc/config/config - - --namespace=test-pods - ports: - - containerPort: 8080 - protocol: TCP - volumeMounts: - - name: boskos-volume - mountPath: /store - - name: boskos-config - mountPath: /etc/config - readOnly: true - volumes: - - name: boskos-config - configMap: - name: resources - volumeClaimTemplates: - - metadata: - name: boskos-volume - spec: - accessModes: [ "ReadWriteOnce" ] - storageClassName: boskos - resources: - requests: - storage: 1Gi ---- -apiVersion: v1 -kind: Service -metadata: - name: boskos - namespace: test-pods -spec: - selector: - app: boskos - ports: - - name: default - protocol: TCP - port: 80 - targetPort: 8080 ---- -# Janitor -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: boskos-janitor - labels: - app: boskos-janitor - namespace: test-pods -spec: - replicas: 3 # 3 distributed janitor instances - template: - metadata: - labels: - app: boskos-janitor - spec: - serviceAccountName: "boskos" - terminationGracePeriodSeconds: 300 - containers: - - name: boskos-janitor - image: gcr.io/k8s-testimages/janitor:v20180619-83c62c891 - args: - - --service-account=/etc/service-account/service-account.json - - --resource-type=gke-project - - --pool-size=10 - volumeMounts: - - mountPath: /etc/service-account - name: service - readOnly: true - volumes: - - name: service - secret: - secretName: service-account ---- -# Reaper -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: boskos-reaper - labels: - app: boskos-reaper - namespace: test-pods -spec: - replicas: 1 # one canonical source of resources - template: - metadata: - labels: - app: boskos-reaper - spec: - serviceAccountName: "boskos" - terminationGracePeriodSeconds: 30 - containers: - - name: boskos-reaper - image: gcr.io/k8s-testimages/reaper:v20180402-43203f868 - args: - - --resource-type=gke-project diff --git a/vendor/github.com/knative/test-infra/ci/prow/boskos/config_start.yaml b/vendor/github.com/knative/test-infra/ci/prow/boskos/config_start.yaml deleted file mode 100644 index dc8d66b6295..00000000000 --- a/vendor/github.com/knative/test-infra/ci/prow/boskos/config_start.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Initial configuration of Boskos - -apiVersion: v1 -kind: ConfigMap -metadata: - name: resources - namespace: test-pods -data: - resources: "" diff --git a/vendor/github.com/knative/test-infra/ci/prow/boskos/resources.yaml b/vendor/github.com/knative/test-infra/ci/prow/boskos/resources.yaml deleted file mode 100644 index 58f734358f6..00000000000 --- a/vendor/github.com/knative/test-infra/ci/prow/boskos/resources.yaml +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -resources: -- names: - - knative-boskos-01 - - knative-boskos-02 - - knative-boskos-03 - - knative-boskos-04 - - knative-boskos-05 - - knative-boskos-06 - - knative-boskos-07 - - knative-boskos-08 - - knative-boskos-09 - - knative-boskos-10 - - knative-boskos-11 - - knative-boskos-12 - - knative-boskos-13 - - knative-boskos-14 - - knative-boskos-15 - - knative-boskos-16 - - knative-boskos-17 - - knative-boskos-18 - - knative-boskos-19 - - knative-boskos-20 - state: dirty - type: gke-project diff --git a/vendor/github.com/knative/test-infra/ci/prow/cluster.yaml b/vendor/github.com/knative/test-infra/ci/prow/cluster.yaml deleted file mode 100644 index 5031611756f..00000000000 --- a/vendor/github.com/knative/test-infra/ci/prow/cluster.yaml +++ /dev/null @@ -1,350 +0,0 @@ -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This file contains Kubernetes YAML files for the most important prow components. ---- -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: prowjobs.prow.k8s.io -spec: - group: prow.k8s.io - version: v1 - names: - kind: ProwJob - singular: prowjob - plural: prowjobs - scope: Namespaced - validation: - openAPIV3Schema: - properties: - spec: - properties: - max_concurrency: - type: integer - minimum: 0 - type: - type: string - enum: - - "presubmit" - - "postsubmit" - - "periodic" - - "batch" - status: - properties: - state: - type: string - enum: - - "triggered" - - "pending" - - "success" - - "failure" - - "aborted" - - "error" - anyOf: - - not: - properties: - state: - type: string - enum: - - "success" - - "failure" - - "error" - - "aborted" - - required: - - completionTime ---- -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: hook - labels: - app: hook -spec: - replicas: 2 - strategy: - type: RollingUpdate - rollingUpdate: - maxSurge: 1 - maxUnavailable: 1 - template: - metadata: - labels: - app: hook - spec: - serviceAccountName: "hook" - terminationGracePeriodSeconds: 180 - containers: - - name: hook - image: gcr.io/k8s-prow/hook:v20181023-ca14137 - imagePullPolicy: Always - args: - - --dry-run=false - ports: - - name: http - containerPort: 8888 - volumeMounts: - - name: hmac - mountPath: /etc/webhook - readOnly: true - - name: oauth - mountPath: /etc/github - readOnly: true - - name: config - mountPath: /etc/config - readOnly: true - - name: plugins - mountPath: /etc/plugins - readOnly: true - volumes: - - name: hmac - secret: - secretName: hmac-token - - name: oauth - secret: - secretName: oauth-token - - name: config - configMap: - name: config - - name: plugins - configMap: - name: plugins ---- -apiVersion: v1 -kind: Service -metadata: - name: hook -spec: - selector: - app: hook - ports: - - port: 8888 - type: NodePort ---- -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: plank - labels: - app: plank -spec: - replicas: 1 # Do not scale up. - template: - metadata: - labels: - app: plank - spec: - serviceAccountName: "plank" - containers: - - name: plank - image: gcr.io/k8s-prow/plank:v20180709-7109caeb1 - args: - - --dry-run=false - volumeMounts: - - name: oauth - mountPath: /etc/github - readOnly: true - - name: config - mountPath: /etc/config - readOnly: true - volumes: - - name: oauth - secret: - secretName: oauth-token - - name: config - configMap: - name: config ---- -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: sinker - labels: - app: sinker -spec: - replicas: 1 - template: - metadata: - labels: - app: sinker - spec: - serviceAccountName: "sinker" - containers: - - name: sinker - image: gcr.io/k8s-prow/sinker:v20180709-7109caeb1 - volumeMounts: - - name: config - mountPath: /etc/config - readOnly: true - volumes: - - name: config - configMap: - name: config ---- -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: deck - labels: - app: deck -spec: - replicas: 2 - strategy: - type: RollingUpdate - rollingUpdate: - maxSurge: 1 - maxUnavailable: 1 - template: - metadata: - labels: - app: deck - spec: - serviceAccountName: "deck" - terminationGracePeriodSeconds: 30 - containers: - - name: deck - image: gcr.io/k8s-prow/deck:v20180709-7109caeb1 - args: - - --hook-url=http://hook:8888/plugin-help - - --tide-url=http://tide/ - ports: - - name: http - containerPort: 8080 - volumeMounts: - - name: config - mountPath: /etc/config - readOnly: true - volumes: - - name: config - configMap: - name: config ---- -apiVersion: v1 -kind: Service -metadata: - name: deck -spec: - selector: - app: deck - ports: - - port: 80 - targetPort: 8080 - type: NodePort ---- -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: horologium - labels: - app: horologium -spec: - replicas: 1 - template: - metadata: - labels: - app: horologium - spec: - serviceAccountName: "horologium" - terminationGracePeriodSeconds: 30 - containers: - - name: horologium - image: gcr.io/k8s-prow/horologium:v20180709-7109caeb1 - volumeMounts: - - name: config - mountPath: /etc/config - readOnly: true - volumes: - - name: config - configMap: - name: config - -# Ingresses - ---- -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: deck-ing - annotations: - kubernetes.io/ingress.class: "gce" - kubernetes.io/ingress.global-static-ip-name: prow-ingress -spec: - tls: - - secretName: tls-secret - hosts: - - prow.knative.dev - rules: - - host: prow.knative.dev - http: - paths: - - path: /* - backend: - serviceName: deck - servicePort: 80 - - path: /hook - backend: - serviceName: hook - servicePort: 8888 - -# Tide - -apiVersion: v1 -kind: Service -metadata: - name: tide -spec: - selector: - app: tide - ports: - - port: 80 - targetPort: 8888 - type: NodePort ---- -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: tide - labels: - app: tide -spec: - replicas: 1 # Do not scale up. - template: - metadata: - labels: - app: tide - spec: - serviceAccountName: "tide" - containers: - - name: tide - image: gcr.io/k8s-prow/tide:v20180808-68cee5a41 - args: - - --dry-run=false - ports: - - name: http - containerPort: 8888 - volumeMounts: - - name: oauth - mountPath: /etc/github - readOnly: true - - name: config - mountPath: /etc/config - readOnly: true - volumes: - - name: oauth - secret: - secretName: oauth-token - - name: config - configMap: - name: config - diff --git a/vendor/github.com/knative/test-infra/ci/prow/config.yaml b/vendor/github.com/knative/test-infra/ci/prow/config.yaml deleted file mode 100644 index c88098662a1..00000000000 --- a/vendor/github.com/knative/test-infra/ci/prow/config.yaml +++ /dev/null @@ -1,2250 +0,0 @@ -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -plank: - job_url_template: 'https://gubernator.knative.dev/build/knative-prow/{{if or (eq .Spec.Type "presubmit") (eq .Spec.Type "batch")}}pr-logs/pull{{with .Spec.Refs}}/{{.Org}}_{{.Repo}}{{end}}{{else}}logs{{end}}{{if eq .Spec.Type "presubmit"}}/{{with index .Spec.Refs.Pulls 0}}{{.Number}}{{end}}{{else if eq .Spec.Type "batch"}}/batch{{end}}/{{.Spec.Job}}/{{.Status.BuildID}}/' - report_template: '[Full PR test history](https://gubernator.knative.dev/pr/{{.Spec.Refs.Org}}_{{.Spec.Refs.Repo}}/{{with index .Spec.Refs.Pulls 0}}{{.Number}}{{end}}). [Your PR dashboard](https://gubernator.knative.dev/pr/{{with index .Spec.Refs.Pulls 0}}{{.Author}}{{end}}).' - pod_pending_timeout: 60m - default_decoration_config: - timeout: 7200000000000 # 2h - grace_period: 15000000000 # 15s - utility_images: - clonerefs: "gcr.io/k8s-prow/clonerefs@sha256:b62ba1f379ac19c5ec9ee7bcab14d3f0b3c31cea9cdd4bc491e98e2c5f346c07" - initupload: "gcr.io/k8s-prow/initupload@sha256:58f89f2aae68f7dc46aaf05c7e8204c4f26b53ec9ce30353d1c27ce44a60d121" - entrypoint: "gcr.io/k8s-prow/entrypoint:v20180512-0255926d1" - sidecar: "gcr.io/k8s-prow/sidecar@sha256:8807b2565f4d2699920542fcf890878824b1ede4198d7ff46bca53feb064ed44" - gcs_configuration: - bucket: "knative-prow" - path_strategy: "explicit" - gcs_credentials_secret: "service-account" - -prowjob_namespace: default -pod_namespace: test-pods -log_level: info - -branch-protection: - orgs: - knative: - # Protect all branches in knative - # This means all prow jobs with "always_run" set are required - # to pass before tide can merge the PR. - # Currently this is manually enabled by the knative org admins, - # but it's stated here for documentation and reference purposes. - protect: true - # Admins can overrule checks - enforce_admins: false - -tide: - queries: - - repos: - - knative/build - - knative/build-pipeline - - knative/build-templates - - knative/serving - - knative/eventing - - knative/eventing-sources - - knative/docs - - knative/test-infra - - knative/pkg - - knative/caching - labels: - - lgtm - - approved - missingLabels: - - do-not-merge/hold - - do-not-merge/work-in-progress - merge_method: - knative: squash - knative/build-pipeline: rebase - target_url: https://prow.knative.dev/tide.html - -presets: -- labels: - preset-service-account: "true" - env: - - name: GOOGLE_APPLICATION_CREDENTIALS - value: /etc/service-account/service-account.json - volumes: - - name: service - secret: - secretName: service-account - volumeMounts: - - name: service - mountPath: /etc/service-account - readOnly: true -# storage / caching presets -- labels: - preset-bazel-scratch-dir: "true" - env: - - name: TEST_TMPDIR - value: /bazel-scratch/.cache/bazel - volumes: - - name: bazel-scratch - emptyDir: {} - volumeMounts: - - name: bazel-scratch - mountPath: /bazel-scratch/.cache -- labels: - preset-bazel-remote-cache-enabled: "false" - env: - - name: BAZEL_REMOTE_CACHE_ENABLED - value: "false" -# docker-in-docker presets -- labels: - preset-dind-enabled: "true" - env: - - name: DOCKER_IN_DOCKER_ENABLED - value: "true" - volumes: - - name: docker-graph - emptyDir: {} - volumeMounts: - - name: docker-graph - mountPath: /docker-graph - -presubmits: - knative/serving: - - name: pull-knative-serving-build-tests - agent: kubernetes - context: pull-knative-serving-build-tests - always_run: true - rerun_command: "/test pull-knative-serving-build-tests" - trigger: "(?m)^/test (all|pull-knative-serving-build-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--build-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-serving-unit-tests - agent: kubernetes - context: pull-knative-serving-unit-tests - always_run: true - rerun_command: "/test pull-knative-serving-unit-tests" - trigger: "(?m)^/test (all|pull-knative-serving-unit-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--unit-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-serving-integration-tests - agent: kubernetes - context: pull-knative-serving-integration-tests - always_run: true - rerun_command: "/test pull-knative-serving-integration-tests" - trigger: "(?m)^/test (all|pull-knative-serving-integration-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--integration-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-serving-go-coverage - labels: - preset-service-account: "true" - agent: kubernetes - context: pull-knative-serving-go-coverage - always_run: true - rerun_command: "/test pull-knative-serving-go-coverage" - trigger: "(?m)^/test (all|pull-knative-serving-go-coverage),?(\\s+|$)" - optional: true - decorate: true - clone_uri: "https://github.com/knative/serving.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--postsubmit-gcs-bucket=knative-prow" - - "--postsubmit-job-name=post-knative-serving-go-coverage" - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=50" - - "--github-token=/etc/github-token/token" - volumeMounts: - - name: github-token - mountPath: /etc/github-token - readOnly: true - volumes: - - name: github-token - secret: - secretName: covbot-token - - - name: pull-knative-serving-go-coverage-dev - labels: - preset-service-account: "true" - agent: kubernetes - context: pull-knative-serving-go-coverage-dev - always_run: false - rerun_command: "/test pull-knative-serving-go-coverage-dev" - trigger: "(?m)^/test (pull-knative-serving-go-coverage-dev),?(\\s+|$)" - optional: true - decorate: true - clone_uri: "https://github.com/knative/serving.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage-dev:latest-dev - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--postsubmit-gcs-bucket=knative-prow" - - "--postsubmit-job-name=post-knative-serving-go-coverage" - - "--profile-name=coverage_profile.txt" - - "--artifacts=$(ARTIFACTS)" - - "--cov-target=." - - "--cov-threshold-percentage=81" - - "--github-token=/etc/github-token/token" - volumeMounts: - - name: github-token - mountPath: /etc/github-token - readOnly: true - volumes: - - name: github-token - secret: - secretName: covbot-token - - knative/build: - - name: pull-knative-build-build-tests - agent: kubernetes - context: pull-knative-build-build-tests - always_run: true - rerun_command: "/test pull-knative-build-build-tests" - trigger: "(?m)^/test (all|pull-knative-build-build-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--build-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-build-unit-tests - agent: kubernetes - context: pull-knative-build-unit-tests - always_run: true - rerun_command: "/test pull-knative-build-unit-tests" - trigger: "(?m)^/test (all|pull-knative-build-unit-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--unit-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-build-integration-tests - agent: kubernetes - context: pull-knative-build-integration-tests - always_run: true - rerun_command: "/test pull-knative-build-integration-tests" - trigger: "(?m)^/test (all|pull-knative-build-integration-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - preset-dind-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--integration-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-build-go-coverage - labels: - preset-service-account: "true" - agent: kubernetes - context: pull-knative-build-go-coverage - always_run: true - rerun_command: "/test pull-knative-build-go-coverage" - trigger: "(?m)^/test (all|pull-knative-build-go-coverage),?(\\s+|$)" - optional: true - decorate: true - clone_uri: "https://github.com/knative/build.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--postsubmit-gcs-bucket=knative-prow" - - "--postsubmit-job-name=post-knative-build-go-coverage" - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=50" - - "--github-token=/etc/github-token/token" - volumeMounts: - - name: github-token - mountPath: /etc/github-token - readOnly: true - volumes: - - name: github-token - secret: - secretName: covbot-token - - knative/build-pipeline: - - name: pull-knative-build-pipeline-build-tests - agent: kubernetes - context: pull-knative-build-pipeline-build-tests - always_run: true - rerun_command: "/test pull-knative-build-pipeline-build-tests" - trigger: "(?m)^/test (all|pull-knative-build-pipeline-build-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--build-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-build-pipeline-unit-tests - agent: kubernetes - context: pull-knative-build-pipeline-unit-tests - always_run: true - rerun_command: "/test pull-knative-build-pipeline-unit-tests" - trigger: "(?m)^/test (all|pull-knative-build-pipeline-unit-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--unit-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-build-pipeline-integration-tests - agent: kubernetes - context: pull-knative-build-pipeline-integration-tests - always_run: true - rerun_command: "/test pull-knative-build-pipeline-integration-tests" - trigger: "(?m)^/test (all|pull-knative-build-pipeline-integration-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--integration-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-build-pipeline-go-coverage - labels: - preset-service-account: "true" - agent: kubernetes - context: pull-knative-build-pipeline-go-coverage - always_run: true - rerun_command: "/test pull-knative-build-pipeline-go-coverage" - trigger: "(?m)^/test (all|pull-knative-build-pipeline-go-coverage),?(\\s+|$)" - optional: true - decorate: true - clone_uri: "https://github.com/knative/build-pipeline.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--postsubmit-gcs-bucket=knative-prow" - - "--postsubmit-job-name=post-knative-build-pipeline-go-coverage" - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=50" - - "--github-token=/etc/github-token/token" - volumeMounts: - - name: github-token - mountPath: /etc/github-token - readOnly: true - volumes: - - name: github-token - secret: - secretName: covbot-token - - knative/eventing: - - name: pull-knative-eventing-build-tests - agent: kubernetes - context: pull-knative-eventing-build-tests - always_run: true - rerun_command: "/test pull-knative-eventing-build-tests" - trigger: "(?m)^/test (all|pull-knative-eventing-build-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--build-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-eventing-unit-tests - agent: kubernetes - context: pull-knative-eventing-unit-tests - always_run: true - rerun_command: "/test pull-knative-eventing-unit-tests" - trigger: "(?m)^/test (all|pull-knative-eventing-unit-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--unit-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-eventing-integration-tests - agent: kubernetes - context: pull-knative-eventing-integration-tests - always_run: true - rerun_command: "/test pull-knative-eventing-integration-tests" - trigger: "(?m)^/test (all|pull-knative-eventing-integration-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--integration-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-eventing-go-coverage - labels: - preset-service-account: "true" - agent: kubernetes - context: pull-knative-eventing-go-coverage - always_run: true - rerun_command: "/test pull-knative-eventing-go-coverage" - trigger: "(?m)^/test (all|pull-knative-eventing-go-coverage),?(\\s+|$)" - optional: true - decorate: true - clone_uri: "https://github.com/knative/eventing.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--postsubmit-gcs-bucket=knative-prow" - - "--postsubmit-job-name=post-knative-eventing-go-coverage" - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=50" - - "--github-token=/etc/github-token/token" - volumeMounts: - - name: github-token - mountPath: /etc/github-token - readOnly: true - volumes: - - name: github-token - secret: - secretName: covbot-token - - knative/eventing-sources: - - name: pull-knative-eventing-sources-build-tests - agent: kubernetes - context: pull-knative-eventing-sources-build-tests - always_run: true - rerun_command: "/test pull-knative-eventing-sources-build-tests" - trigger: "(?m)^/test (all|pull-knative-eventing-sources-build-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--build-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-eventing-sources-unit-tests - agent: kubernetes - context: pull-knative-eventing-sources-unit-tests - always_run: true - rerun_command: "/test pull-knative-eventing-sources-unit-tests" - trigger: "(?m)^/test (all|pull-knative-eventing-sources-unit-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--unit-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-eventing-sources-integration-tests - agent: kubernetes - context: pull-knative-eventing-sources-integration-tests - always_run: true - rerun_command: "/test pull-knative-eventing-sources-integration-tests" - trigger: "(?m)^/test (all|pull-knative-eventing-sources-integration-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--integration-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-eventing-sources-go-coverage - labels: - preset-service-account: "true" - agent: kubernetes - context: pull-knative-eventing-sources-go-coverage - always_run: true - rerun_command: "/test pull-knative-eventing-sources-go-coverage" - trigger: "(?m)^/test (all|pull-knative-eventing-sources-go-coverage),?(\\s+|$)" - optional: true - decorate: true - clone_uri: "https://github.com/knative/eventing-sources.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--postsubmit-gcs-bucket=knative-prow" - - "--postsubmit-job-name=post-knative-eventing-sources-go-coverage" - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=50" - - "--github-token=/etc/github-token/token" - volumeMounts: - - name: github-token - mountPath: /etc/github-token - readOnly: true - volumes: - - name: github-token - secret: - secretName: covbot-token - - knative/docs: - - name: pull-knative-docs-build-tests - agent: kubernetes - context: pull-knative-docs-build-tests - always_run: true - rerun_command: "/test pull-knative-docs-build-tests" - trigger: "(?m)^/test (all|pull-knative-docs-build-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--build-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-docs-unit-tests - agent: kubernetes - context: pull-knative-docs-unit-tests - always_run: true - rerun_command: "/test pull-knative-docs-unit-tests" - trigger: "(?m)^/test (all|pull-knative-docs-unit-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--unit-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-docs-integration-tests - agent: kubernetes - context: pull-knative-docs-integration-tests - always_run: true - rerun_command: "/test pull-knative-docs-integration-tests" - trigger: "(?m)^/test (all|pull-knative-docs-integration-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--integration-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-docs-go-coverage - labels: - preset-service-account: "true" - agent: kubernetes - context: pull-knative-docs-go-coverage - always_run: true - rerun_command: "/test pull-knative-docs-go-coverage" - trigger: "(?m)^/test (all|pull-knative-docs-go-coverage),?(\\s+|$)" - optional: true - decorate: true - clone_uri: "https://github.com/knative/docs.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--postsubmit-gcs-bucket=knative-prow" - - "--postsubmit-job-name=post-knative-docs-go-coverage" - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=50" - - "--github-token=/etc/github-token/token" - volumeMounts: - - name: github-token - mountPath: /etc/github-token - readOnly: true - volumes: - - name: github-token - secret: - secretName: covbot-token - - knative/build-templates: - - name: pull-knative-build-templates-build-tests - agent: kubernetes - context: pull-knative-build-templates-build-tests - always_run: true - rerun_command: "/test pull-knative-build-templates-build-tests" - trigger: "(?m)^/test (all|pull-knative-build-templates-build-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--build-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-build-templates-unit-tests - agent: kubernetes - context: pull-knative-build-templates-unit-tests - always_run: true - rerun_command: "/test pull-knative-build-templates-unit-tests" - trigger: "(?m)^/test (all|pull-knative-build-templates-unit-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--unit-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-build-templates-integration-tests - agent: kubernetes - context: pull-knative-build-templates-integration-tests - always_run: true - rerun_command: "/test pull-knative-build-templates-integration-tests" - trigger: "(?m)^/test (all|pull-knative-build-templates-integration-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--integration-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - knative/pkg: - - name: pull-knative-pkg-build-tests - agent: kubernetes - context: pull-knative-pkg-build-tests - always_run: true - rerun_command: "/test pull-knative-pkg-build-tests" - trigger: "(?m)^/test (all|pull-knative-pkg-build-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--build-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-pkg-unit-tests - agent: kubernetes - context: pull-knative-pkg-unit-tests - always_run: true - rerun_command: "/test pull-knative-pkg-unit-tests" - trigger: "(?m)^/test (all|pull-knative-pkg-unit-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--unit-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-pkg-integration-tests - agent: kubernetes - context: pull-knative-pkg-integration-tests - always_run: true - rerun_command: "/test pull-knative-pkg-integration-tests" - trigger: "(?m)^/test (all|pull-knative-pkg-integration-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--integration-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-pkg-go-coverage - labels: - preset-service-account: "true" - agent: kubernetes - context: pull-knative-pkg-go-coverage - always_run: true - rerun_command: "/test pull-knative-pkg-go-coverage" - trigger: "(?m)^/test (all|pull-knative-pkg-go-coverage),?(\\s+|$)" - optional: true - decorate: true - clone_uri: "https://github.com/knative/pkg.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--postsubmit-gcs-bucket=knative-prow" - - "--postsubmit-job-name=post-knative-pkg-go-coverage" - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=50" - - "--github-token=/etc/github-token/token" - volumeMounts: - - name: github-token - mountPath: /etc/github-token - readOnly: true - volumes: - - name: github-token - secret: - secretName: covbot-token - - knative/test-infra: - - name: pull-knative-test-infra-build-tests - agent: kubernetes - context: pull-knative-test-infra-build-tests - always_run: true - rerun_command: "/test pull-knative-test-infra-build-tests" - trigger: "(?m)^/test (all|pull-knative-test-infra-build-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--build-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-test-infra-unit-tests - agent: kubernetes - context: pull-knative-test-infra-unit-tests - always_run: true - rerun_command: "/test pull-knative-test-infra-unit-tests" - trigger: "(?m)^/test (all|pull-knative-test-infra-unit-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--unit-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-test-infra-integration-tests - agent: kubernetes - context: pull-knative-test-infra-integration-tests - always_run: true - rerun_command: "/test pull-knative-test-infra-integration-tests" - trigger: "(?m)^/test (all|pull-knative-test-infra-integration-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--integration-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - knative/caching: - - name: pull-knative-caching-build-tests - agent: kubernetes - context: pull-knative-caching-build-tests - always_run: true - rerun_command: "/test pull-knative-caching-build-tests" - trigger: "(?m)^/test (all|pull-knative-caching-build-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--build-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-caching-unit-tests - agent: kubernetes - context: pull-knative-caching-unit-tests - always_run: true - rerun_command: "/test pull-knative-caching-unit-tests" - trigger: "(?m)^/test (all|pull-knative-caching-unit-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--unit-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-caching-integration-tests - agent: kubernetes - context: pull-knative-caching-integration-tests - always_run: true - rerun_command: "/test pull-knative-caching-integration-tests" - trigger: "(?m)^/test (all|pull-knative-caching-integration-tests),?(\\s+|$)" - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/$(REPO_OWNER)/$(REPO_NAME)=$(PULL_REFS)" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/pr-logs" - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--integration-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - - - name: pull-knative-caching-go-coverage - labels: - preset-service-account: "true" - agent: kubernetes - context: pull-knative-caching-go-coverage - always_run: true - rerun_command: "/test pull-knative-caching-go-coverage" - trigger: "(?m)^/test (all|pull-knative-caching-go-coverage),?(\\s+|$)" - optional: true - decorate: true - clone_uri: "https://github.com/knative/caching.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--postsubmit-gcs-bucket=knative-prow" - - "--postsubmit-job-name=post-knative-caching-go-coverage" - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=50" - - "--github-token=/etc/github-token/token" - volumeMounts: - - name: github-token - mountPath: /etc/github-token - readOnly: true - volumes: - - name: github-token - secret: - secretName: covbot-token - -periodics: -- cron: "1 * * * *" # Run every hour and one minute - name: ci-knative-serving-continuous - agent: kubernetes - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/knative/serving" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/logs" - - "--timeout=50" # Avoid overrun - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--all-tests" - - "--emit-metrics" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" -- cron: "1 8 * * *" # Run at 01:01PST every day (08:01 UTC) - name: ci-knative-serving-release - agent: kubernetes - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/knative/serving" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/logs" - - "--timeout=90" # 1.5h - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./hack/release.sh" - - "--publish" - - "--tag-release" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" -- cron: "1 9 * * 6" # Run at 02:01PST every Saturday (09:01 UTC) - name: ci-knative-serving-playground - agent: kubernetes - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/knative/serving" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/logs" - - "--timeout=90" # 1.5h - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./hack/deploy.sh" - - "knative-playground" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" -- cron: "5 8 * * *" # Run at 01:05PST every day (08:05 UTC) - name: ci-knative-serving-latency - agent: kubernetes - labels: - preset-service-account: "true" - decorate: true - extra_refs: - - org: knative - repo: serving - base_ref: master - clone_uri: "https://github.com/knative/serving.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/metrics:latest - imagePullPolicy: Always - command: - - "/metrics" - args: - - "--source-directory=ci-knative-serving-continuous" - - "--artifacts-dir=$(ARTIFACTS)" - - "--service-account=/etc/service-account/service-account.json" -- cron: "5 8 * * *" # Run at 01:05PST every day (08:05 UTC) - name: ci-knative-serving-api-coverage - agent: kubernetes - labels: - preset-service-account: "true" - decorate: true - extra_refs: - - org: knative - repo: serving - base_ref: master - clone_uri: "https://github.com/knative/serving.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/apicoverage:latest - imagePullPolicy: Always - command: - - "/apicoverage" - args: - - "--artifacts-dir=$(ARTIFACTS)" - - "--service-account=/etc/service-account/service-account.json" -- cron: "0 1 * * *" # Run at 01:00 every day - name: ci-knative-serving-go-coverage - agent: kubernetes - decorate: true - extra_refs: - - org: knative - repo: serving - base_ref: master - clone_uri: "https://github.com/knative/serving.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=80" -- cron: "0 1 * * *" # Run at 01:00 every day - name: ci-knative-serving-performance - agent: kubernetes - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/knative/serving" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/logs" - - "--timeout=50" # Avoid overrun - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/performance-tests.sh" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - -- cron: "15 * * * *" # Run every hour and 15 minutes - name: ci-knative-build-continuous - agent: kubernetes - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/knative/build" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/logs" - - "--timeout=50" # Avoid overrun - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--all-tests" - - "--emit-metrics" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" -- cron: "31 8 * * *" # Run at 01:31PST every day (08:31 UTC) - name: ci-knative-build-release - agent: kubernetes - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - preset-dind-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/knative/build" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/logs" - - "--timeout=90" # 1.5h - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./hack/release.sh" - - "--publish" - - "--tag-release" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" -- cron: "5 8 * * *" # Run at 01:05PST every day (08:05 UTC) - name: ci-knative-build-latency - agent: kubernetes - labels: - preset-service-account: "true" - decorate: true - extra_refs: - - org: knative - repo: build - base_ref: master - clone_uri: "https://github.com/knative/build.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/metrics:latest - imagePullPolicy: Always - command: - - "/metrics" - args: - - "--source-directory=ci-knative-build-continuous" - - "--artifacts-dir=$(ARTIFACTS)" - - "--service-account=/etc/service-account/service-account.json" -- cron: "0 1 * * *" # Run at 01:00 every day - name: ci-knative-build-go-coverage - agent: kubernetes - decorate: true - extra_refs: - - org: knative - repo: build - base_ref: master - clone_uri: "https://github.com/knative/build.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=80" - -- cron: "0 1 * * *" # Run at 01:00 every day - name: ci-knative-build-pipeline-go-coverage - agent: kubernetes - decorate: true - extra_refs: - - org: knative - repo: build - base_ref: master - clone_uri: "https://github.com/knative/build-pipeline.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=80" - -- cron: "50 * * * *" # Run every hour and 50 minutes - name: ci-knative-docs-continuous - agent: kubernetes - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/knative/docs" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/logs" - - "--timeout=50" # Avoid overrun - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--all-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" -- cron: "0 1 * * *" # Run at 01:00 every day - name: ci-knative-docs-go-coverage - agent: kubernetes - decorate: true - extra_refs: - - org: knative - repo: docs - base_ref: master - clone_uri: "https://github.com/knative/docs.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=80" - -- cron: "30 * * * *" # Run every hour and 30 minutes - name: ci-knative-eventing-continuous - agent: kubernetes - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/knative/eventing" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/logs" - - "--timeout=50" # Avoid overrun - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--all-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" -- cron: "16 9 * * *" # Run at 02:16PST every day (09:16 UTC) - name: ci-knative-eventing-release - agent: kubernetes - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/knative/eventing" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/logs" - - "--timeout=90" # 1.5h - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./hack/release.sh" - - "--publish" - - "--tag-release" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" -- cron: "0 1 * * *" # Run at 01:00 every day - name: ci-knative-eventing-go-coverage - agent: kubernetes - decorate: true - extra_refs: - - org: knative - repo: eventing - base_ref: master - clone_uri: "https://github.com/knative/eventing.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=80" - -- cron: "30 * * * *" # Run every hour and 30 minutes - name: ci-knative-eventing-sources-continuous - agent: kubernetes - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/knative/eventing-sources" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/logs" - - "--timeout=50" # Avoid overrun - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--all-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" -- cron: "16 9 * * *" # Run at 02:16PST every day (09:16 UTC) - name: ci-knative-eventing-sources-release - agent: kubernetes - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/knative/eventing-sources" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/logs" - - "--timeout=90" # 1.5h - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./hack/release.sh" - - "--publish" - - "--tag-release" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" -- cron: "0 1 * * *" # Run at 01:00 every day - name: ci-knative-eventing-sources-go-coverage - agent: kubernetes - decorate: true - extra_refs: - - org: knative - repo: eventing-sources - base_ref: master - clone_uri: "https://github.com/knative/eventing-sources.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=80" - -- cron: "40 * * * *" # Run every hour and 40 minutes - name: ci-knative-build-templates-continuous - agent: kubernetes - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/knative/build-templates" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/logs" - - "--timeout=50" # Avoid overrun - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--all-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" - -- cron: "45 * * * *" # Run every hour and 45 minutes - name: ci-knative-pkg-continuous - agent: kubernetes - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/knative/pkg" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/logs" - - "--timeout=50" # Avoid overrun - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--all-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" -- cron: "0 1 * * *" # Run at 01:00 every day - name: ci-knative-pkg-go-coverage - agent: kubernetes - decorate: true - extra_refs: - - org: knative - repo: pkg - base_ref: master - clone_uri: "https://github.com/knative/pkg.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=80" - -- cron: "30 * * * *" # Run every hour and 30 minutes - name: ci-knative-caching-continuous - agent: kubernetes - labels: - preset-service-account: "true" - preset-bazel-scratch-dir: "true" - preset-bazel-remote-cache-enabled: "true" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/prow-tests:latest - imagePullPolicy: Always - args: - - "--scenario=kubernetes_execute_bazel" - - "--clean" - - "--job=$(JOB_NAME)" - - "--repo=github.com/knative/caching" - - "--root=/go/src" - - "--service-account=/etc/service-account/service-account.json" - - "--upload=gs://knative-prow/logs" - - "--timeout=50" # Avoid overrun - - "--" # end bootstrap args, scenario args below - - "--" # end kubernetes_execute_bazel flags (consider following flags as text) - - "./test/presubmit-tests.sh" - - "--all-tests" - # Bazel needs privileged mode in order to sandbox builds. - securityContext: - privileged: true - resources: - requests: - memory: "1Gi" -- cron: "0 1 * * *" # Run at 01:00 every day - name: ci-knative-caching-go-coverage - agent: kubernetes - decorate: true - extra_refs: - - org: knative - repo: caching - base_ref: master - clone_uri: "https://github.com/knative/caching.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=80" - -postsubmits: - knative/serving: - - name: post-knative-serving-go-coverage - branches: - - master - agent: kubernetes - decorate: true - clone_uri: "https://github.com/knative/serving.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=0" - - name: post-knative-serving-go-coverage-dev - branches: - - master - agent: kubernetes - decorate: true - clone_uri: "https://github.com/knative/serving.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage-dev:latest-dev - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=0" - - knative/build: - - name: post-knative-build-go-coverage - branches: - - master - agent: kubernetes - decorate: true - clone_uri: "https://github.com/knative/build.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=0" - - knative/build-pipeline: - - name: post-knative-build-pipeline-go-coverage - branches: - - master - agent: kubernetes - decorate: true - clone_uri: "https://github.com/knative/build-pipeline.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=0" - - knative/docs: - - name: post-knative-docs-go-coverage - branches: - - master - agent: kubernetes - decorate: true - clone_uri: "https://github.com/knative/docs.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=0" - - knative/eventing: - - name: post-knative-eventing-go-coverage - branches: - - master - agent: kubernetes - decorate: true - clone_uri: "https://github.com/knative/eventing.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=0" - - knative/eventing-sources: - - name: post-knative-eventing-sources-go-coverage - branches: - - master - agent: kubernetes - decorate: true - clone_uri: "https://github.com/knative/eventing-sources.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=0" - - knative/pkg: - - name: post-knative-pkg-go-coverage - branches: - - master - agent: kubernetes - decorate: true - clone_uri: "https://github.com/knative/pkg.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=0" - - knative/caching: - - name: post-knative-caching-go-coverage - branches: - - master - agent: kubernetes - decorate: true - clone_uri: "https://github.com/knative/caching.git" - spec: - containers: - - image: gcr.io/knative-tests/test-infra/coverage:latest - imagePullPolicy: Always - command: - - "/coverage" - args: - - "--artifacts=$(ARTIFACTS)" - - "--profile-name=coverage_profile.txt" - - "--cov-target=." - - "--cov-threshold-percentage=0" diff --git a/vendor/github.com/knative/test-infra/ci/prow/config_start.yaml b/vendor/github.com/knative/test-infra/ci/prow/config_start.yaml deleted file mode 100644 index ada1a3e62fa..00000000000 --- a/vendor/github.com/knative/test-infra/ci/prow/config_start.yaml +++ /dev/null @@ -1,339 +0,0 @@ -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Initial configuration of prow cluster - -# Configs - -apiVersion: v1 -kind: ConfigMap -metadata: - name: plugins -data: - plugins: "" ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: config -data: - config: "" ---- - -# Namespaces - -apiVersion: v1 -kind: Namespace -metadata: - name: prow ---- -apiVersion: v1 -kind: Namespace -metadata: - name: test-pods ---- - -# Service accounts, roles and bindings - -kind: ServiceAccount -apiVersion: v1 -metadata: - name: "boskos" - namespace: test-pods ---- -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: "boskos" - namespace: test-pods -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: boskos -subjects: -- kind: ServiceAccount - name: "boskos" - namespace: test-pods ---- -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: "boskos" - namespace: test-pods -rules: - - apiGroups: - - apiextensions.k8s.io - resources: - - customresourcedefinitions - verbs: - - create - - apiGroups: - - boskos.k8s.io - resources: - - resources - verbs: - - "*" ---- -kind: ServiceAccount -apiVersion: v1 -metadata: - name: "default" - namespace: test-pods ---- -kind: RoleBinding -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: "test-pods-default" - namespace: test-pods -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: "test-pods-default" -subjects: -- kind: ServiceAccount - name: "default" - namespace: test-pods ---- -kind: Role -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: "test-pods-default" - namespace: test-pods -rules: - - apiGroups: - - "" - resources: - - pods - verbs: - - get ---- -kind: ServiceAccount -apiVersion: v1 -metadata: - name: "deck" ---- -kind: RoleBinding -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: "deck" -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: "deck" -subjects: -- kind: ServiceAccount - name: "deck" - namespace: default ---- -kind: Role -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: "deck" -rules: - - apiGroups: - - "" - resources: - - pods/log - verbs: - - get - - apiGroups: - - "prow.k8s.io" - resources: - - prowjobs - verbs: - - get - - list ---- -kind: ServiceAccount -apiVersion: v1 -metadata: - name: "horologium" ---- -kind: Role -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: "horologium" -rules: - - apiGroups: - - "prow.k8s.io" - resources: - - prowjobs - verbs: - - create - - list ---- -kind: RoleBinding -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: "horologium" -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: "horologium" -subjects: -- kind: ServiceAccount - name: "horologium" - namespace: default ---- -kind: ServiceAccount -apiVersion: v1 -metadata: - name: "plank" ---- -kind: Role -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: "plank" -rules: - - apiGroups: - - "" - resources: - - pods - verbs: - - create - - delete - - list - - apiGroups: - - "prow.k8s.io" - resources: - - prowjobs - verbs: - - create - - list - - update ---- -kind: RoleBinding -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: "plank" -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: "plank" -subjects: -- kind: ServiceAccount - name: "plank" - namespace: default ---- -kind: ServiceAccount -apiVersion: v1 -metadata: - name: "sinker" ---- -kind: Role -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: "sinker" -rules: - - apiGroups: - - "" - resources: - - pods - verbs: - - delete - - list - - apiGroups: - - "prow.k8s.io" - resources: - - prowjobs - verbs: - - delete - - list ---- -kind: RoleBinding -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: "sinker" -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: "sinker" -subjects: -- kind: ServiceAccount - name: "sinker" - namespace: default ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: "hook" ---- -kind: Role -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: "hook" -rules: - - apiGroups: - - "prow.k8s.io" - resources: - - prowjobs - verbs: - - create - - get - - apiGroups: - - "" - resources: - - configmaps - verbs: - - update ---- -kind: RoleBinding -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: "hook" -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: "hook" -subjects: -- kind: ServiceAccount - name: "hook" ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: "tide" ---- -kind: Role -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: "tide" -rules: - - apiGroups: - - "prow.k8s.io" - resources: - - prowjobs - verbs: - - create - - get - - list - - apiGroups: - - "" - resources: - - configmaps - verbs: - - update ---- -kind: RoleBinding -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: "tide" -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: "tide" -subjects: -- kind: ServiceAccount - name: "tide" - namespace: default diff --git a/vendor/github.com/knative/test-infra/ci/prow/plugins.yaml b/vendor/github.com/knative/test-infra/ci/prow/plugins.yaml deleted file mode 100644 index 57c8b2f4079..00000000000 --- a/vendor/github.com/knative/test-infra/ci/prow/plugins.yaml +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -approve: -- repos: - - knative - implicit_self_approve: true - review_acts_as_approve: true - -plugins: - knative: - - approve - - assign - - blunderbuss - - buildifier - - cat - - dog - - golint - - heart - - help - - hold - - label - - lgtm - - lifecycle - - shrug - - size - - skip - - trigger - - wip - - yuks diff --git a/vendor/github.com/knative/test-infra/ci/prow/prow_setup.md b/vendor/github.com/knative/test-infra/ci/prow/prow_setup.md deleted file mode 100644 index 3f04729dfb5..00000000000 --- a/vendor/github.com/knative/test-infra/ci/prow/prow_setup.md +++ /dev/null @@ -1,71 +0,0 @@ -# Prow setup - -## Creating the cluster - -1. Create the GKE cluster, the role bindings and the GitHub secrets. You might need to update [Makefile](./Makefile). For details, see https://github.com/kubernetes/test-infra/blob/master/prow/getting_started.md. - -1. Ensure the GCP projects listed in [resources.yaml](./boskos/resources.yaml) are created. - -1. Apply [config_start.yaml](./config_start.yaml) to the cluster. - -1. Apply Boskos [config_start.yaml](./boskos/config_start.yaml) to the cluster. - -1. Run `make update-cluster`, `make update-boskos`, `make update-config`, `make update-plugins` and `make update-boskos-config`. - -1. If SSL needs to be reconfigured, promote your ingress IP to static in Cloud Console, and [create the TLS secret](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls). - -## Expanding Boskos pool - -1. Create a new GCP project and add it to [resources.yaml](./boskos/resources.yaml). - -1. Make `knative-tests@appspot.gserviceaccount.com` an editor of the project. - -1. Enable the Compute Engine API for the project (e.g., by visiting https://console.developers.google.com/apis/api/compute.googleapis.com/overview?project=XXXXXXXX). - -1. Enable the Kubernetes Engine API for the project (e.g., by visiting https://console.cloud.google.com/apis/api/container.googleapis.com/overview?project=XXXXXXXX). - -1. Run `make update-boskos-config`. - -## Setting up Prow for a new repo - -1. Create the appropriate `OWNERS` files (at least one for the root dir). - -1. Make sure that *Knative Robots* is an Admin of the repo. - -1. Update the tide section in the Prow config file and run `make update-config` (ask one of the owners of knative/test-infra). - -1. Wait a few minutes, check that Prow is working by entering `/woof` as a comment in any PR in the new repo. - -1. Set **tide** as a required status check for the master branch. - -### Setting up jobs for a new repo - -1. Have the test infrastructure in place (usually this means having at least `//test/presubmit-tests.sh` working, and optionally `//hack/release.sh` working for automated nightly releases). - -1. Merge a pull request (e.g., https://github.com/knative/test-infra/pull/203) that: - - 1. Updates the Prow config file (usually, copy and update existing jobs from another repository). - - 1. For the presubmit tests, setup the *pull-knative-**repo**-**(build|unit|integration)**-tests* jobs. - - 1. For go test coverage, setup the ***(pull|post|ci)**-knative-**repo**-go-coverage* jobs. - - 1. For the continuous integration tests, setup the *ci-knative-**repo**-continuous* job. - - 1. For automated nightly releases, setup the *ci-knative-**repo**-release* job. - - 1. Updates the Gubernator config with the new log dirs. - - 1. Updates the Testgrid config with the new buckets, tabs and dashboard. - -1. Ask one of the owners of *knative/test-infra* to: - - 1. Run `make update-config` in `ci/prow`. - - 1. Run `make deploy` in `ci/gubernator`. - - 1. Run `make update-config` in `ci/testgrid`. - -1. Wait a few minutes, enter `/retest` as a comment in any PR in the repo and ensure the test jobs are executed. - -1. Set the new test jobs as required status checks for the master branch. diff --git a/vendor/github.com/knative/test-infra/ci/testgrid/Makefile b/vendor/github.com/knative/test-infra/ci/testgrid/Makefile deleted file mode 100644 index 5cf42d995b9..00000000000 --- a/vendor/github.com/knative/test-infra/ci/testgrid/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -TESTGRID_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) - -test: - bazel run @k8s//testgrid/cmd/configurator -- \ - --yaml=$(TESTGRID_DIR)/config.yaml \ - --validate-config-file - -update-config: -ifndef GOOGLE_APPLICATION_CREDENTIALS - $(error GOOGLE_APPLICATION_CREDENTIALS not set) -endif - bazel run @k8s//testgrid/cmd/configurator -- \ - --yaml=$(TESTGRID_DIR)/config.yaml \ - --output=gs://knative-testgrid/config \ - --oneshot diff --git a/vendor/github.com/knative/test-infra/ci/testgrid/README.md b/vendor/github.com/knative/test-infra/ci/testgrid/README.md deleted file mode 100644 index 7b028e040f3..00000000000 --- a/vendor/github.com/knative/test-infra/ci/testgrid/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Testgrid config - -This directory contains the config for our [Testgrid](https://github.com/kubernetes/test-infra/tree/master/testgrid) instance. - -* `Makefile` Commands to interact with the Testgrid instance regarding updates. -* `config.yaml` Testgrid configuration. diff --git a/vendor/github.com/knative/test-infra/ci/testgrid/config.yaml b/vendor/github.com/knative/test-infra/ci/testgrid/config.yaml deleted file mode 100644 index 9af7ce15425..00000000000 --- a/vendor/github.com/knative/test-infra/ci/testgrid/config.yaml +++ /dev/null @@ -1,216 +0,0 @@ -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Default testgroup and dashboardtab, please do not change them -default_test_group: - days_of_results: 14 # Number of days of test results to gather and serve - tests_name_policy: 2 # Replace the name of the test - ignore_pending: false # Show in-progress tests - column_header: - - configuration_value: Commit # Shows the commit number on column header - - configuration_value: infra-commit - num_columns_recent: 10 # The number of columns to consider "recent" for a variety of purposes - use_kubernetes_client: true # ** This field is deprecated and should always be true ** - is_external: true # ** This field is deprecated and should always be true ** - alert_stale_results_hours: 0 # Don't alert for staleness by default - num_failures_to_alert: 3 # Consider a test failed if it has 3 or more consecutive failures - num_passes_to_disable_alert: 1 # Consider a failing test passing if it has 1 or more consecutive passes - -default_dashboard_tab: - open_test_template: # The URL template to visit after clicking on a cell - url: https://gubernator.knative.dev/build// - file_bug_template: # The URL template to visit when filing a bug - url: https://github.com/knative/serving/issues/new - options: - - key: title - value: 'Test "" failed' - - key: body - value: - attach_bug_template: # The URL template to visit when attaching a bug - url: # Empty - options: # Empty - # Text to show in the about menu as a link to another view of the results - results_text: See these results in Gubernator - results_url_template: # The URL template to visit after clicking - url: https://gubernator.knative.dev/builds/ - # URL for regression search links. - code_search_path: github.com/knative/serving/search - num_columns_recent: 10 - code_search_url_template: # The URL template to visit when searching for changelists - url: https://github.com/knative/serving/compare/... - -# Test groups - -test_groups: -- name: ci-knative-serving-continuous - gcs_prefix: knative-prow/logs/ci-knative-serving-continuous -- name: ci-knative-serving-release - gcs_prefix: knative-prow/logs/ci-knative-serving-release -- name: ci-knative-serving-playground - gcs_prefix: knative-prow/logs/ci-knative-serving-playground -- name: pull-knative-serving-test-coverage - gcs_prefix: knative-prow/logs/ci-knative-serving-go-coverage - short_text_metric: coverage -- name: ci-knative-serving-latency - gcs_prefix: knative-prow/logs/ci-knative-serving-latency - short_text_metric: latency -- name: ci-knative-serving-api-coverage - gcs_prefix: knative-prow/logs/ci-knative-serving-api-coverage - short_text_metric: api_coverage -- name: ci-knative-build-continuous - gcs_prefix: knative-prow/logs/ci-knative-build-continuous -- name: ci-knative-build-release - gcs_prefix: knative-prow/logs/ci-knative-build-release -- name: pull-knative-build-test-coverage - gcs_prefix: knative-prow/logs/ci-knative-build-go-coverage - short_text_metric: coverage -- name: ci-knative-build-latency - gcs_prefix: knative-prow/logs/ci-knative-build-latency - short_text_metric: latency -- name: ci-knative-build-templates-continuous - gcs_prefix: knative-prow/logs/ci-knative-build-templates-continuous -- name: pull-knative-build-pipeline-test-coverage - gcs_prefix: knative-prow/logs/ci-knative-build-pipeline-go-coverage - short_text_metric: coverage -- name: ci-knative-eventing-continuous - gcs_prefix: knative-prow/logs/ci-knative-eventing-continuous -- name: ci-knative-eventing-release - gcs_prefix: knative-prow/logs/ci-knative-eventing-release -- name: pull-knative-eventing-test-coverage - gcs_prefix: knative-prow/logs/ci-knative-eventing-go-coverage - short_text_metric: coverage -- name: ci-knative-eventing-sources-continuous - gcs_prefix: knative-prow/logs/ci-knative-eventing-sources-continuous -- name: ci-knative-eventing-sources-release - gcs_prefix: knative-prow/logs/ci-knative-eventing-sources-release -- name: pull-knative-eventing-sources-test-coverage - gcs_prefix: knative-prow/logs/ci-knative-eventing-sources-go-coverage - short_text_metric: coverage -- name: ci-knative-docs-continuous - gcs_prefix: knative-prow/logs/ci-knative-docs-continuous -- name: pull-knative-docs-test-coverage - gcs_prefix: knative-prow/logs/ci-knative-docs-go-coverage - short_text_metric: coverage -- name: ci-knative-pkg-continuous - gcs_prefix: knative-prow/logs/ci-knative-pkg-continuous -- name: pull-knative-pkg-test-coverage - gcs_prefix: knative-prow/logs/ci-knative-pkg-go-coverage - short_text_metric: coverage -- name: ci-knative-caching-continuous - gcs_prefix: knative-prow/logs/ci-knative-caching-continuous -- name: pull-knative-caching-test-coverage - gcs_prefix: knative-prow/logs/ci-knative-caching-go-coverage - short_text_metric: coverage - -# Dashboards - -dashboards: -- name: knative-serving - dashboard_tab: - - name: continuous - test_group_name: ci-knative-serving-continuous - - name: release - test_group_name: ci-knative-serving-release - - name: playground - test_group_name: ci-knative-serving-playground - - name: coverage - test_group_name: pull-knative-serving-test-coverage - base_options: 'exclude-filter-by-regex=Overall&group-by-directory=&expand-groups=&sort-by-name=' - - name: latency - test_group_name: ci-knative-serving-latency - description: '95% latency in ms' - base_options: 'exclude-filter-by-regex=Overall&group-by-directory=&expand-groups=&sort-by-name=' - - name: api-coverage - test_group_name: ci-knative-serving-api-coverage - description: 'Conformance tests API coverage.' - base_options: 'exclude-filter-by-regex=Overall$&group-by-directory=&expand-groups=&sort-by-name=' - - name: conformance-tests - test_group_name: ci-knative-serving-continuous - base_options: 'include-filter-by-regex=//knative/serving/test/conformance:&sort-by-name=' -- name: knative-build - dashboard_tab: - - name: continuous - test_group_name: ci-knative-build-continuous - - name: release - test_group_name: ci-knative-build-release - - name: coverage - test_group_name: pull-knative-build-test-coverage - base_options: 'exclude-filter-by-regex=Overall&group-by-directory=&expand-groups=&sort-by-name=' - - name: latency - test_group_name: ci-knative-build-latency - description: '95% latency in ms' - base_options: 'exclude-filter-by-regex=Overall&group-by-directory=&expand-groups=&sort-by-name=' -- name: knative-build-templates - dashboard_tab: - - name: continuous - test_group_name: ci-knative-build-templates-continuous -- name: knative-build-pipeline - dashboard_tab: - - name: coverage - test_group_name: pull-knative-build-pipeline-test-coverage - base_options: 'exclude-filter-by-regex=Overall&group-by-directory=&expand-groups=&sort-by-name=' -- name: knative-eventing - dashboard_tab: - - name: continuous - test_group_name: ci-knative-eventing-continuous - - name: release - test_group_name: ci-knative-eventing-release - - name: coverage - test_group_name: pull-knative-eventing-test-coverage - base_options: 'exclude-filter-by-regex=Overall&group-by-directory=&expand-groups=&sort-by-name=' -- name: knative-eventing-sources - dashboard_tab: - - name: continuous - test_group_name: ci-knative-eventing-sources-continuous - - name: release - test_group_name: ci-knative-eventing-sources-release - - name: coverage - test_group_name: pull-knative-eventing-sources-test-coverage - base_options: 'exclude-filter-by-regex=Overall&group-by-directory=&expand-groups=&sort-by-name=' -- name: knative-docs - dashboard_tab: - - name: continuous - test_group_name: ci-knative-docs-continuous - - name: coverage - test_group_name: pull-knative-docs-test-coverage - base_options: 'exclude-filter-by-regex=Overall&group-by-directory=&expand-groups=&sort-by-name=' -- name: knative-pkg - dashboard_tab: - - name: continuous - test_group_name: ci-knative-pkg-continuous - - name: coverage - test_group_name: pull-knative-pkg-test-coverage - base_options: 'exclude-filter-by-regex=Overall&group-by-directory=&expand-groups=&sort-by-name=' -- name: knative-caching - dashboard_tab: - - name: continuous - test_group_name: ci-knative-caching-continuous - - name: coverage - test_group_name: pull-knative-caching-test-coverage - base_options: 'exclude-filter-by-regex=Overall&group-by-directory=&expand-groups=&sort-by-name=' - -# Dashboard groups - -dashboard_groups: -- name: knative - dashboard_names: - - knative-serving - - knative-build - - knative-build-templates - - knative-build-pipeline - - knative-eventing - - knative-eventing-sources - - knative-docs - - knative-pkg - - knative-caching diff --git a/vendor/github.com/knative/test-infra/dummy.go b/vendor/github.com/knative/test-infra/dummy.go deleted file mode 100644 index 40028c14ec7..00000000000 --- a/vendor/github.com/knative/test-infra/dummy.go +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 2018 The Knative Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package main - -import ( - "fmt" -) - -func main() { - fmt.Println("This is a dummy go file so `go dep` can be used with knative/test-infra repo") - fmt.Println("This file can be removed once the repo contains real, useful go code in the root dir") -} - diff --git a/vendor/github.com/knative/test-infra/images/README.md b/vendor/github.com/knative/test-infra/images/README.md deleted file mode 100644 index 22b9b16edd0..00000000000 --- a/vendor/github.com/knative/test-infra/images/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Prow Job Images - -This directory contains custom Docker images used by our Prow jobs. diff --git a/vendor/github.com/knative/test-infra/images/apicoverage/Dockerfile b/vendor/github.com/knative/test-infra/images/apicoverage/Dockerfile deleted file mode 100644 index 897ec7d82ef..00000000000 --- a/vendor/github.com/knative/test-infra/images/apicoverage/Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -FROM golang:1.10.2 -LABEL maintainer "Srinivas Hegde " -RUN apt-get update && apt-get install -y --no-install-recommends - -COPY apicoverage /apicoverage -ENTRYPOINT ["/apicoverage"] diff --git a/vendor/github.com/knative/test-infra/images/apicoverage/Makefile b/vendor/github.com/knative/test-infra/images/apicoverage/Makefile deleted file mode 100644 index b5a87ca546c..00000000000 --- a/vendor/github.com/knative/test-infra/images/apicoverage/Makefile +++ /dev/null @@ -1,23 +0,0 @@ - -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -REGISTRY ?= gcr.io -PROJECT ?= knative-tests/test-infra -PUSH ?= docker push - -apicoverage-image: - CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build ../../tools/apicoverage - docker build -t "$(REGISTRY)/$(PROJECT)/apicoverage:latest" . - $(PUSH) "$(REGISTRY)/$(PROJECT)/apicoverage:latest" diff --git a/vendor/github.com/knative/test-infra/images/apicoverage/README.md b/vendor/github.com/knative/test-infra/images/apicoverage/README.md deleted file mode 100644 index b855777358b..00000000000 --- a/vendor/github.com/knative/test-infra/images/apicoverage/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# API coverage tool Image - -This directory contains the custom docker image used for calculating the API coverage by the conformance tests. diff --git a/vendor/github.com/knative/test-infra/images/prow-tests/Dockerfile b/vendor/github.com/knative/test-infra/images/prow-tests/Dockerfile deleted file mode 100644 index 7baf483481e..00000000000 --- a/vendor/github.com/knative/test-infra/images/prow-tests/Dockerfile +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -FROM gcr.io/k8s-testimages/kubekins-e2e:v20181001-df2f5324a-master -LABEL maintainer "Adriano Cunha " - -# Install extras on top of base image - -ENV DEBIAN_FRONTEND noninteractive -RUN apt-get update -RUN gcloud components update - -# Docker -RUN gcloud components install docker-credential-gcr -RUN docker-credential-gcr configure-docker - -# Extra tools through apt-get -RUN apt-get install -y uuid-runtime # for uuidgen -RUN apt-get install -y npm # for markdown-link-check -RUN apt-get install -y rubygems # for mdl -RUN apt-get install -y build-essential libssl-dev # for wrk -RUN apt-get install -y netbase # sets up /etc/services needed for wrk - -# Extra tools through go get -RUN go get -u github.com/google/go-containerregistry/cmd/ko -RUN go get -u github.com/golang/dep/cmd/dep -RUN go get -u github.com/google/licenseclassifier - -# Extra tools through npm -RUN npm install -g markdown-link-check - -# Extra tools through gem -RUN gem install mixlib-config -v 2.2.4 # required because ruby is 2.1 -RUN gem install mdl - -# Install wrk -RUN git clone https://github.com/wg/wrk.git wrk -RUN make -C wrk/ -RUN cp wrk/wrk /usr/local/bin - -ADD . /go/src/github.com/knative/test-infra - -# Extra custom tools -RUN cp /go/src/github.com/knative/test-infra/tools/githubhelper/githubhelper . -RUN go install github.com/knative/test-infra/tools/dep-collector diff --git a/vendor/github.com/knative/test-infra/images/prow-tests/Makefile b/vendor/github.com/knative/test-infra/images/prow-tests/Makefile deleted file mode 100644 index 6e1ce3c08ca..00000000000 --- a/vendor/github.com/knative/test-infra/images/prow-tests/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -IMG = gcr.io/knative-tests/test-infra/prow-tests -TAG := $(shell date +v%Y%m%d)-$(shell git describe --tags --always --dirty) - -all: build - -build: - make -C ../../tools/githubhelper - docker build -t $(IMG):$(TAG) -f Dockerfile ../.. - docker tag $(IMG):$(TAG) $(IMG):latest - -push_versioned: build - docker push $(IMG):$(TAG) - -push_latest: build - docker push $(IMG):latest - -clean: - rm -fr githubhelper dep-collector - -push: push_versioned push_latest clean diff --git a/vendor/github.com/knative/test-infra/images/prow-tests/README.md b/vendor/github.com/knative/test-infra/images/prow-tests/README.md deleted file mode 100644 index d1b904427e4..00000000000 --- a/vendor/github.com/knative/test-infra/images/prow-tests/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Prow Test Job Image - -This directory contains the custom Docker image used by our Prow test jobs. - -## Building and publishing a new image - -To build and push a new image, just run `make push`. - -For testing purposes you can build an image but not push it; to do so, run `make build`. - -Note that you must have proper permission in the `knative-tests` project to push new images to the GCR. - -The `prow-tests` image is pinned on a specific `kubekins` image; update `Dockerfile` if you need to use a newer/different image. This will basically define the versions of `bazel`, `go`, `kubectl` and other build tools. diff --git a/vendor/github.com/knative/test-infra/test/e2e-tests.sh b/vendor/github.com/knative/test-infra/test/e2e-tests.sh deleted file mode 100755 index 128733ce38d..00000000000 --- a/vendor/github.com/knative/test-infra/test/e2e-tests.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This script runs the end-to-end tests. - -# If you already have a Knative cluster setup and kubectl pointing -# to it, call this script with the --run-tests arguments and it will use -# the cluster and run the tests. - -# Calling this script without arguments will create a new cluster in -# project $PROJECT_ID, run the tests and delete the cluster. - -source $(dirname $0)/../scripts/e2e-tests.sh - -function parse_flags() { - if [[ "$1" == "--smoke-test-custom-flag" ]]; then - echo "--smoke-test-custom-flag passed" - exit 0 - fi - return 0 -} - -# Script entry point. - -initialize $@ - -if (( USING_EXISTING_CLUSTER )); then - echo "ERROR: this test isn't intended to run against an existing cluster" - fail_test -fi - -start_latest_knative_serving || fail_test "Knative Serving is not up" - -# This is actually a unit test, but it does exercise the necessary helper functions. -go_test_e2e -run TestE2ESucceeds ./test || fail_test - -success diff --git a/vendor/github.com/knative/test-infra/test/presubmit-tests.sh b/vendor/github.com/knative/test-infra/test/presubmit-tests.sh deleted file mode 100755 index ae0e0cc42ee..00000000000 --- a/vendor/github.com/knative/test-infra/test/presubmit-tests.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This script runs the presubmit tests; it is started by prow for each PR. -# For convenience, it can also be executed manually. -# Running the script without parameters, or with the --all-tests -# flag, causes all tests to be executed, in the right order. -# Use the flags --build-tests, --unit-tests and --integration-tests -# to run a specific set of tests. - -source $(dirname $0)/../scripts/presubmit-tests.sh - -function build_tests() { - header "Running build tests" - local failed=0 - make -C ci/prow test || failed=1 - make -C ci/testgrid test || failed=1 - for script in scripts/*.sh; do - subheader "Checking integrity of ${script}" - bash -c "source ${script}" || failed=1 - done - return ${failed} -} - -function unit_tests() { - header "Running unit tests" - local failed=0 - for test in ./test/unit/*-tests.sh; do - subheader "Running tests in ${test}" - ${test} || failed=1 - done - return ${failed} -} - -# We use the default integration test runner. - -main $@ diff --git a/vendor/github.com/knative/test-infra/test/unit/e2e-custom-flag-tests.sh b/vendor/github.com/knative/test-infra/test/unit/e2e-custom-flag-tests.sh deleted file mode 100755 index b5528861752..00000000000 --- a/vendor/github.com/knative/test-infra/test/unit/e2e-custom-flag-tests.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This script runs the end-to-end tests. - -# If you already have a Knative cluster setup and kubectl pointing -# to it, call this script with the --run-tests arguments and it will use -# the cluster and run the tests. - -# Calling this script without arguments will create a new cluster in -# project $PROJECT_ID, run the tests and delete the cluster. - -source $(dirname $0)/../../scripts/e2e-tests.sh - -function parse_flags() { - if [[ "$1" == "--smoke-test-custom-flag" ]]; then - echo "OK: --smoke-test-custom-flag passed" - exit 0 - fi - fail_test "Unexpected flag $1 passed" -} - -# Script entry point. - -initialize --smoke-test-custom-flag diff --git a/vendor/github.com/knative/test-infra/test/unit/library-tests.sh b/vendor/github.com/knative/test-infra/test/unit/library-tests.sh deleted file mode 100755 index a8be4415fcd..00000000000 --- a/vendor/github.com/knative/test-infra/test/unit/library-tests.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Fake we're in a Prow job, if running locally. -[[ -z "${PROW_JOB_ID:-}" ]] && PROW_JOB_ID=123 - -source $(dirname $0)/../../scripts/library.sh - -set -e - -function test_report() { - local REPORT="$(mktemp)" - report_go_test -run $1 ./test > ${REPORT} || true - cat ${REPORT} - grep "$2" ${REPORT} > /dev/null - grep "Done parsing 1 tests" ${REPORT} > /dev/null -} - -# Cleanup bazel stuff to avoid confusing Prow -function cleanup_bazel() { - bazel clean -} - -trap cleanup_bazel EXIT - -echo "Testing report_go_test" - -echo "Test pass" -test_report TestSucceeds "^- TestSucceeds :PASS:" - -echo "Test fails with fatal" -test_report TestFailsWithFatal "^- TestFailsWithFatal :FAIL:" - -echo "Test fails with SIGQUIT" -test_report TestFailsWithSigQuit "^- TestFailsWithSigQuit :FAIL:" - -echo "All tests passed" diff --git a/vendor/github.com/knative/test-infra/test/unit/presubmit-full-custom-integration-tests.sh b/vendor/github.com/knative/test-infra/test/unit/presubmit-full-custom-integration-tests.sh deleted file mode 100755 index d22b66e32dc..00000000000 --- a/vendor/github.com/knative/test-infra/test/unit/presubmit-full-custom-integration-tests.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -source $(dirname $0)/presubmit-integration-tests-common.sh - -function check_results() { - (( PRE_INTEGRATION_TESTS )) || failed "Pre integration tests did not run" - (( CUSTOM_INTEGRATION_TESTS )) || failed "Custom integration tests did not run" - (( POST_INTEGRATION_TESTS )) || failed "Post integration tests did not run" - echo "Test passed" -} - -echo "Testing all custom test integration functions" - -main $@ diff --git a/vendor/github.com/knative/test-infra/test/unit/presubmit-integration-tests-common.sh b/vendor/github.com/knative/test-infra/test/unit/presubmit-integration-tests-common.sh deleted file mode 100755 index 78c0f4d0646..00000000000 --- a/vendor/github.com/knative/test-infra/test/unit/presubmit-integration-tests-common.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -source $(dirname $0)/../../scripts/presubmit-tests.sh - -function failed() { - echo $1 - exit 1 -} - -function pre_integration_tests() { - PRE_INTEGRATION_TESTS=1 -} - -function integration_tests() { - CUSTOM_INTEGRATION_TESTS=1 -} - -function post_integration_tests() { - POST_INTEGRATION_TESTS=1 -} - -function build_tests() { - return 0 -} - -function unit_tests() { - return 0 -} - -PRE_INTEGRATION_TESTS=0 -CUSTOM_INTEGRATION_TESTS=0 -POST_INTEGRATION_TESTS=0 - -trap check_results EXIT diff --git a/vendor/github.com/knative/test-infra/test/unit/presubmit-partial-custom-integration-tests.sh b/vendor/github.com/knative/test-infra/test/unit/presubmit-partial-custom-integration-tests.sh deleted file mode 100755 index e0fb4ef24fa..00000000000 --- a/vendor/github.com/knative/test-infra/test/unit/presubmit-partial-custom-integration-tests.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Test that pre/post integration tests don't run if unset. - -source $(dirname $0)/presubmit-integration-tests-common.sh - -function check_results() { - (( ! PRE_INTEGRATION_TESTS )) || failed "Pre integration tests did run" - (( CUSTOM_INTEGRATION_TESTS )) || failed "Custom integration tests did not run" - (( ! POST_INTEGRATION_TESTS )) || failed "Post integration tests did run" - echo "Test passed" -} - -echo "Testing custom test integration function" - -unset -f pre_integration_tests -unset -f post_integration_tests - -main $@ diff --git a/vendor/github.com/knative/test-infra/test/unit/release-tests.sh b/vendor/github.com/knative/test-infra/test/unit/release-tests.sh deleted file mode 100755 index 6fcd5d35f94..00000000000 --- a/vendor/github.com/knative/test-infra/test/unit/release-tests.sh +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/bash - -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -source $(dirname $0)/../../scripts/release.sh - -set -e - -# Call a function and verify its return value and output. -# Parameters: $1 - expected return code. -# $2 - expected output ("" if no output is expected) -# $3 ..$n - function to call and its parameters. -function test_function() { - local expected_retcode=$1 - local expected_string=$2 - local output="$(mktemp)" - local output_code="$(mktemp)" - shift 2 - echo -n "$(trap '{ echo $? > ${output_code}; }' EXIT ; "$@")" &> ${output} - local retcode=$(cat ${output_code}) - if [[ ${retcode} -ne ${expected_retcode} ]]; then - cat ${output} - echo "Return code ${retcode} doesn't match expected return code ${expected_retcode}" - return 1 - fi - if [[ -n "${expected_string}" ]]; then - local found=1 - grep "${expected_string}" ${output} > /dev/null || found=0 - if (( ! found )); then - cat ${output} - echo "String '${expected_string}' not found" - return 1 - fi - else - if [[ -s ${output} ]]; then - ls ${output} - cat ${output} - echo "Unexpected output" - return 1 - fi - fi - echo "'$@' returns code ${expected_retcode} and displays '${expected_string}'" -} - -function mock_branch_release() { - set -e - BRANCH_RELEASE=1 - TAG=sometag - function git() { - echo $@ - } - function hub() { - echo $@ - } - branch_release "$@" 2>&1 -} - -function call_function() { - set -e - local init=$1 - shift - eval ${init} - "$@" 2>&1 -} - -echo ">> Testing initialization" - -test_function 1 "error: missing version" initialize --version -test_function 1 "error: version format" initialize --version a -test_function 1 "error: version format" initialize --version 0.0 -test_function 0 "" initialize --version 1.0.0 - -test_function 1 "error: missing branch" initialize --branch -test_function 1 "error: branch name must be" initialize --branch a -test_function 1 "error: branch name must be" initialize --branch 0.0 -test_function 0 "" initialize --branch release-0.0 - -test_function 1 "error: missing release notes" initialize --release-notes -test_function 1 "error: file a doesn't" initialize --release-notes a -test_function 0 "" initialize --release-notes $(mktemp) - -echo ">> Testing release branching" - -test_function 0 "" branch_release -test_function 129 "usage: git tag" call_function BRANCH_RELEASE=1 branch_release -test_function 1 "No such file" call_function BRANCH_RELEASE=1 branch_release "K Foo" "a.yaml b.yaml" -test_function 0 "release create" mock_branch_release "K Foo" "$(mktemp) $(mktemp)" - -echo ">> Testing validation tests" - -test_function 0 "Running release validation" run_validation_tests true -test_function 0 "" call_function SKIP_TESTS=1 run_validation_tests true -test_function 0 "i_passed" run_validation_tests "echo i_passed" -test_function 1 "validation tests failed" run_validation_tests false - -echo ">> All tests passed" diff --git a/vendor/github.com/knative/test-infra/tools/README.md b/vendor/github.com/knative/test-infra/tools/README.md deleted file mode 100644 index d4cf2a272f2..00000000000 --- a/vendor/github.com/knative/test-infra/tools/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Test Infrastructure tools - -This directory contains tools used by our Prow jobs. diff --git a/vendor/github.com/knative/test-infra/tools/apicoverage/README.md b/vendor/github.com/knative/test-infra/tools/apicoverage/README.md deleted file mode 100644 index 01ddf855151..00000000000 --- a/vendor/github.com/knative/test-infra/tools/apicoverage/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# API Coverage Tool -This tool is designed to show the field level coverage exercised by the conformance tests. - -## Read from GCS -This tool reads the logs from the latest continous build of knative/serving. The logs have the information of which CRD objects are being created and which fields are being set for the testing. -It uses the service account passed in or by default will use the GOOGLE_APPLICATION_CREDENTIALS variable to get the logs. - -## Creating Output -This tool creates an output xml in the prow artifacts directory. The prow artifacts directory is passed in or by default will use `./artifacts` directory. - -This output xml will be read by testgrid and displayed on the [dashboard](https://testgrid.knative.dev/knative-serving#api-coverage). - -## Prow Job -There is a daily prow job that triggers this tool that is run at 01:05 AM PST. This tool will then generate the output xml which is then displayed in the testgrid dashboard. diff --git a/vendor/github.com/knative/test-infra/tools/apicoverage/apicoverage.go b/vendor/github.com/knative/test-infra/tools/apicoverage/apicoverage.go deleted file mode 100644 index 6e007a7270b..00000000000 --- a/vendor/github.com/knative/test-infra/tools/apicoverage/apicoverage.go +++ /dev/null @@ -1,241 +0,0 @@ -/* -Copyright 2018 The Knative Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// apicoverage.go parses the log file and outputs the api coverage numbers in a -// testgrid expected output xml file - -package main - -import ( - "context" - "encoding/json" - "flag" - "fmt" - "log" - "os" - "reflect" - "strings" - - "github.com/knative/serving/pkg/apis/serving/v1alpha1" - "github.com/knative/test-infra/tools/gcs" - "github.com/knative/test-infra/tools/testgrid" -) - -const ( - logDir = "logs/ci-knative-serving-continuous/" - buildFile = "build-log.txt" - apiCoverage = "api_coverage" - overallRoute = "OverallRoute" - overallConfig = "OverallConfiguration" - overallService = "OverallService" -) - -// ResourceObjects defines the resource objects in knative-serving -type ResourceObjects struct { - Route *v1alpha1.Route - Configuration *v1alpha1.Configuration - Service *v1alpha1.Service -} - -// OverallAPICoverage defines the overall api coverage for knative serving -type OverallAPICoverage struct { - RouteAPICovered map[string]int - RouteAPINotCovered map[string]int - ConfigurationAPICovered map[string]int - ConfigurationAPINotCovered map[string]int - ServiceAPICovered map[string]int - ServiceAPINotCovered map[string]int -} - -type apiObjectName string - -const ( - apiObjectRoute apiObjectName = "route" - apiObjectConfiguration = "configuration" - apiObjectService = "service" -) - -// check if the object value is nil or empty. -// Uses https://golang.org/pkg/reflect/#Kind to get the variable type -func isNil(v reflect.Value) bool { - switch v.Kind() { - case reflect.Array, reflect.Map, reflect.Slice, reflect.String: - return v.Len() == 0 - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return v.Int() == 0 - case reflect.Float32, reflect.Float64: - return v.Float() == 0 - } - return false -} - -func isStruct(v reflect.Value) bool { - return v.Kind() == reflect.Struct -} - -// Parse the struct and returns a map of -func parseStruct(v reflect.Value) map[string]reflect.Value { - f := make(map[string]reflect.Value) - - for i := 0; i < v.NumField(); i++ { - // Include only public vars. https://golang.org/pkg/reflect/#StructField. - if len(v.Type().Field(i).PkgPath) == 0 { - f[v.Type().Field(i).Name] = v.Field(i) - } - } - - return f -} - -func incrementCoverageValues(name string, covered map[string]int) { - if i, ok := covered[name]; ok { - covered[name] = i + 1 - } else { - covered[name] = 1 - } -} - -func handleCovered(name string, coverage *OverallAPICoverage) { - if strings.HasPrefix(name, "route") { - incrementCoverageValues(name, coverage.RouteAPICovered) - } else if strings.HasPrefix(name, "configuration") { - incrementCoverageValues(name, coverage.ConfigurationAPICovered) - } else if strings.HasPrefix(name, "service") { - incrementCoverageValues(name, coverage.ServiceAPICovered) - } -} - -func handleNotCovered(name string, coverage *OverallAPICoverage) { - if strings.HasPrefix(name, "route") { - coverage.RouteAPINotCovered[name] = 0 - } else if strings.HasPrefix(name, "configuration") { - coverage.ConfigurationAPINotCovered[name] = 0 - } else if strings.HasPrefix(name, "service") { - coverage.ServiceAPINotCovered[name] = 0 - } -} - -func getCoverage(value reflect.Value, name string, coverage *OverallAPICoverage) { - // Parse all the fields in the struct - for key, v := range parseStruct(value) { - name := name + "." + key - if isStruct(v) { - getCoverage(v, name, coverage) - } else { - // check if it is empty/nil - if isNil(v) { - handleNotCovered(name, coverage) - } else { - handleCovered(name, coverage) - } - } - } -} - -func calculateCoverage(covLogs []string, coverage *OverallAPICoverage) { - if len(covLogs) == 0 { - return - } - - for _, f := range covLogs { - var obj ResourceObjects - if err := json.Unmarshal([]byte(f), &obj); err != nil { - log.Fatalf("Cannot read resource object: %v", err) - } else { - if obj.Route != nil { - getCoverage(reflect.ValueOf(obj.Route).Elem(), "route", coverage) - } else if obj.Configuration != nil { - getCoverage(reflect.ValueOf(obj.Configuration).Elem(), "configuration", coverage) - } else if obj.Service != nil { - getCoverage(reflect.ValueOf(obj.Service).Elem(), "service", coverage) - } - } - } -} - -func initCoverage() *OverallAPICoverage { - coverage := OverallAPICoverage{} - coverage.RouteAPICovered = make(map[string]int) - coverage.RouteAPINotCovered = make(map[string]int) - coverage.ConfigurationAPICovered = make(map[string]int) - coverage.ConfigurationAPINotCovered = make(map[string]int) - coverage.ServiceAPICovered = make(map[string]int) - coverage.ServiceAPINotCovered = make(map[string]int) - - return &coverage -} - -func getRelevantLogs(fields []string) *string { - // I0727 16:23:30.055] 2018-10-12T18:18:06.835-0700 info TestRouteCreation test/configuration.go:34 resource {: }"} - if len(fields) == 8 && fields[3] == "info" && fields[6] == "resource" { - s := strings.Join(fields[7:], " ") - return &s - } - return nil -} - -func createCases(tcName string, covered map[string]int, notCovered map[string]int) []testgrid.TestCase { - var tc []testgrid.TestCase - - var percentCovered = float32(100 * len(covered) / (len(covered) + len(notCovered))) - tp := []testgrid.TestProperty{testgrid.TestProperty{Name: apiCoverage, Value: percentCovered}} - tc = append(tc, testgrid.TestCase{Name: tcName, Properties: testgrid.TestProperties{Property: tp}, Fail: false}) - - for key, value := range covered { - tp := []testgrid.TestProperty{testgrid.TestProperty{Name: apiCoverage, Value: float32(value)}} - tc = append(tc, testgrid.TestCase{Name: tcName + "/" + key, Properties: testgrid.TestProperties{Property: tp}, Fail: false}) - } - - for key, value := range notCovered { - tp := []testgrid.TestProperty{testgrid.TestProperty{Name: apiCoverage, Value: float32(value)}} - tc = append(tc, testgrid.TestCase{Name: tcName + "/" + key, Properties: testgrid.TestProperties{Property: tp}, Fail: true}) - } - return tc -} - -func createTestgridXML(coverage *OverallAPICoverage, artifactsDir string) { - tc := createCases(overallRoute, coverage.RouteAPICovered, coverage.RouteAPINotCovered) - tc = append(tc, createCases(overallConfig, coverage.ConfigurationAPICovered, coverage.ConfigurationAPINotCovered)...) - tc = append(tc, createCases(overallService, coverage.ServiceAPICovered, coverage.ServiceAPINotCovered)...) - ts := testgrid.TestSuite{TestCases: tc} - - if err := testgrid.CreateXMLOutput(ts, artifactsDir); err != nil { - log.Fatalf("Cannot create the xml output file: %v", err) - } -} - -func main() { - - artifactsDir := flag.String("artifacts-dir", "./artifacts", "Directory to store the generated XML file") - serviceAccount := flag.String("service-account", os.Getenv("GOOGLE_APPLICATION_CREDENTIALS"), "JSON key file for service account to use") - flag.Parse() - - // Read the latest-build.txt file to get the latest build number - ctx := context.Background() - num, err := gcs.GetLatestBuildNumber(ctx, logDir, *serviceAccount) - if err != nil { - log.Fatalf("Cannot get latest build number: %v", err) - } - - // Calculate coverage - coverage := initCoverage() - calculateCoverage( - gcs.ParseLog(ctx, fmt.Sprintf("%s/%d/%s", logDir, num, buildFile), getRelevantLogs), - coverage) - - // Write the testgrid xml to artifacts - createTestgridXML(coverage, *artifactsDir) -} diff --git a/vendor/github.com/knative/test-infra/tools/gcs/gcs.go b/vendor/github.com/knative/test-infra/tools/gcs/gcs.go deleted file mode 100644 index a41fbbb21a0..00000000000 --- a/vendor/github.com/knative/test-infra/tools/gcs/gcs.go +++ /dev/null @@ -1,112 +0,0 @@ -/* -Copyright 2018 The Knative Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// gcs.go defines functions to use GCS - -package gcs - -import ( - "bufio" - "context" - "fmt" - "io/ioutil" - "log" - "strconv" - "strings" - - "cloud.google.com/go/storage" - "google.golang.org/api/option" -) - -const ( - bucketName = "knative-prow" - latest = "latest-build.txt" -) - -var client *storage.Client - -func createStorageClient(ctx context.Context, sa string) error { - var err error - client, err = storage.NewClient(ctx, option.WithCredentialsFile(sa)) - return err -} - -func createStorageObject(filename string) *storage.ObjectHandle { - return client.Bucket(bucketName).Object(filename) -} - -// GetLatestBuildNumber gets the latest build number for the specified log directory -func GetLatestBuildNumber(ctx context.Context, logDir string, sa string) (int, error) { - contents, err := ReadGcsFile(ctx, logDir+latest, sa) - if err != nil { - return 0, err - } - latestBuild, err := strconv.Atoi(string(contents)) - if err != nil { - return 0, err - } - - return latestBuild, nil -} - -//ReadGcsFile reads the specified file using the provided service account -func ReadGcsFile(ctx context.Context, filename string, sa string) ([]byte, error) { - // Create a new GCS client - if err := createStorageClient(ctx, sa); err != nil { - log.Fatalf("Failed to create GCS client: %v", err) - } - o := createStorageObject(filename) - if _, err := o.Attrs(ctx); err != nil { - return []byte(fmt.Sprintf("Cannot get attributes of '%s'", filename)), err - } - f, err := o.NewReader(ctx) - if err != nil { - return []byte(fmt.Sprintf("Cannot open '%s'", filename)), err - } - defer f.Close() - contents, err := ioutil.ReadAll(f) - if err != nil { - return []byte(fmt.Sprintf("Cannot read '%s'", filename)), err - } - return contents, nil -} - -// ParseLog parses the log and returns the lines where the checkLog func does not return an empty slice. -// checkLog function should take in the log statement and return a part from that statement that should be in the log output. -func ParseLog(ctx context.Context, filename string, checkLog func(s []string) *string) []string { - var logs []string - - log.Printf("Parsing '%s'", filename) - o := createStorageObject(filename) - if _, err := o.Attrs(ctx); err != nil { - log.Printf("Cannot get attributes of '%s', assuming not ready yet: %v", filename, err) - return nil - } - f, err := o.NewReader(ctx) - if err != nil { - log.Fatalf("Error opening '%s': %v", filename, err) - } - defer f.Close() - - scanner := bufio.NewScanner(f) - - for scanner.Scan() { - if s := checkLog(strings.Fields(scanner.Text())); s != nil { - logs = append(logs, *s) - } - } - return logs -} diff --git a/vendor/github.com/knative/test-infra/tools/githubhelper/Makefile b/vendor/github.com/knative/test-infra/tools/githubhelper/Makefile deleted file mode 100644 index c8fef33a770..00000000000 --- a/vendor/github.com/knative/test-infra/tools/githubhelper/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2018 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -all: - go get -u github.com/google/go-github/github - CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build . diff --git a/vendor/github.com/knative/test-infra/tools/githubhelper/README.md b/vendor/github.com/knative/test-infra/tools/githubhelper/README.md deleted file mode 100644 index 5975a23521b..00000000000 --- a/vendor/github.com/knative/test-infra/tools/githubhelper/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# GitHub Helper Tool - -This tool is designed to interact with GitHub, providing useful data for a Prow job. Actions performed and the output are governed by the flags used. - -Currently the tool makes unauthenticated requests to GitHub API. - -## Flags - -* `-list-changed-files` will list the files that are touched by the current PR in a Prow job. -* `-verbose` will dump extra info on output when executing the comments; it is intended for debugging. diff --git a/vendor/github.com/knative/test-infra/tools/githubhelper/githubhelper.go b/vendor/github.com/knative/test-infra/tools/githubhelper/githubhelper.go deleted file mode 100644 index d45fad475cc..00000000000 --- a/vendor/github.com/knative/test-infra/tools/githubhelper/githubhelper.go +++ /dev/null @@ -1,85 +0,0 @@ -/* -Copyright 2018 The Knative Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// githubhelper.go interacts with GitHub, providing useful data for a Prow job. - -package main - -import ( - "context" - "flag" - "fmt" - "log" - "os" - "strconv" - - "github.com/google/go-github/github" -) - -var ( - // Info about the current PR - repoOwner = os.Getenv("REPO_OWNER") - repoName = os.Getenv("REPO_NAME") - pullNumber = atoi(os.Getenv("PULL_NUMBER"), "pull number") - - // Shared useful variables - ctx = context.Background() - onePageList = &github.ListOptions{Page: 1} - verbose = false - anonymousGitHubClient *github.Client -) - -// atoi is a convenience function to convert a string to integer, failing in case of error. -func atoi(str, valueName string) int { - value, err := strconv.Atoi(str) - if err != nil { - log.Fatalf("Unexpected non number '%s' for %s: %v", str, valueName, err) - } - return value -} - -// infof if a convenience wrapper around log.Infof, and does nothing unless --verbose is passed. -func infof(template string, args ...interface{}) { - if verbose { - log.Printf(template, args...) - } -} - -// listChangedFiles simply lists the files changed by the current PR. -func listChangedFiles() { - infof("Listing changed files for PR %d in repository %s/%s", pullNumber, repoOwner, repoName) - files, _, err := anonymousGitHubClient.PullRequests.ListFiles(ctx, repoOwner, repoName, pullNumber, onePageList) - if err != nil { - log.Fatalf("Error listing files: %v", err) - } - for _, file := range files { - fmt.Println(*file.Filename) - } -} - -func main() { - listChangedFilesFlag := flag.Bool("list-changed-files", false, "List the files changed by the current pull request") - verboseFlag := flag.Bool("verbose", false, "Whether to dump extra info on output or not; intended for debugging") - flag.Parse() - - verbose = *verboseFlag - anonymousGitHubClient = github.NewClient(nil) - - if *listChangedFilesFlag { - listChangedFiles() - } -} - diff --git a/vendor/github.com/knative/test-infra/tools/testgrid/testgrid.go b/vendor/github.com/knative/test-infra/tools/testgrid/testgrid.go deleted file mode 100644 index 30d7ff2c13c..00000000000 --- a/vendor/github.com/knative/test-infra/tools/testgrid/testgrid.go +++ /dev/null @@ -1,69 +0,0 @@ -/* -Copyright 2018 The Knative Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// testgrid.go provides methods to perform action on testgrid. - -package testgrid - -import ( - "encoding/xml" - "os" -) - -// TestProperty defines a property of the test -type TestProperty struct { - Name string `xml:"name,attr"` - Value float32 `xml:"value,attr"` -} - -// TestProperties is an array of test properties -type TestProperties struct { - Property []TestProperty `xml:"property"` -} - -// TestCase defines a test case that was executed -type TestCase struct { - ClassName string `xml:"class_name,attr"` - Name string `xml:"name,attr"` - Time int `xml:"time,attr"` - Properties TestProperties `xml:"properties"` - Fail bool `xml:"failure,omitempty"` -} - -// TestSuite defines the set of relevant test cases -type TestSuite struct { - XMLName xml.Name `xml:"testsuite"` - TestCases []TestCase `xml:"testcase"` -} - -// CreateXMLOutput creates the junit xml file in the provided artifacts directory -func CreateXMLOutput(ts TestSuite, artifactsDir string) error { - op, err := xml.MarshalIndent(ts, "", " ") - if err != nil { - return err - } - - outputFile := artifactsDir + "/junit_bazel.xml" - f, err := os.Create(outputFile) - if err != nil { - return err - } - defer f.Close() - if _, err := f.WriteString(string(op) + "\n"); err != nil { - return err - } - return nil -} diff --git a/vendor/github.com/sergi/go-diff/AUTHORS b/vendor/github.com/sergi/go-diff/AUTHORS new file mode 100644 index 00000000000..2d7bb2bf572 --- /dev/null +++ b/vendor/github.com/sergi/go-diff/AUTHORS @@ -0,0 +1,25 @@ +# This is the official list of go-diff authors for copyright purposes. +# This file is distinct from the CONTRIBUTORS files. +# See the latter for an explanation. + +# Names should be added to this file as +# Name or Organization +# The email address is not required for organizations. + +# Please keep the list sorted. + +Danny Yoo +James Kolb +Jonathan Amsterdam +Markus Zimmermann +Matt Kovars +Örjan Persson +Osman Masood +Robert Carlsen +Rory Flynn +Sergi Mansilla +Shatrugna Sadhu +Shawn Smith +Stas Maksimov +Tor Arvid Lund +Zac Bergquist diff --git a/vendor/github.com/sergi/go-diff/CONTRIBUTORS b/vendor/github.com/sergi/go-diff/CONTRIBUTORS new file mode 100644 index 00000000000..369e3d55190 --- /dev/null +++ b/vendor/github.com/sergi/go-diff/CONTRIBUTORS @@ -0,0 +1,32 @@ +# This is the official list of people who can contribute +# (and typically have contributed) code to the go-diff +# repository. +# +# The AUTHORS file lists the copyright holders; this file +# lists people. For example, ACME Inc. employees would be listed here +# but not in AUTHORS, because ACME Inc. would hold the copyright. +# +# When adding J Random Contributor's name to this file, +# either J's name or J's organization's name should be +# added to the AUTHORS file. +# +# Names should be added to this file like so: +# Name +# +# Please keep the list sorted. + +Danny Yoo +James Kolb +Jonathan Amsterdam +Markus Zimmermann +Matt Kovars +Örjan Persson +Osman Masood +Robert Carlsen +Rory Flynn +Sergi Mansilla +Shatrugna Sadhu +Shawn Smith +Stas Maksimov +Tor Arvid Lund +Zac Bergquist diff --git a/vendor/github.com/sergi/go-diff/LICENSE b/vendor/github.com/sergi/go-diff/LICENSE new file mode 100644 index 00000000000..937942c2b2c --- /dev/null +++ b/vendor/github.com/sergi/go-diff/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2012-2016 The go-diff Authors. All rights reserved. + +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/sergi/go-diff/diffmatchpatch/diff.go b/vendor/github.com/sergi/go-diff/diffmatchpatch/diff.go new file mode 100644 index 00000000000..82ad7bc8f1c --- /dev/null +++ b/vendor/github.com/sergi/go-diff/diffmatchpatch/diff.go @@ -0,0 +1,1344 @@ +// Copyright (c) 2012-2016 The go-diff authors. All rights reserved. +// https://github.com/sergi/go-diff +// See the included LICENSE file for license details. +// +// go-diff is a Go implementation of Google's Diff, Match, and Patch library +// Original library is Copyright (c) 2006 Google Inc. +// http://code.google.com/p/google-diff-match-patch/ + +package diffmatchpatch + +import ( + "bytes" + "errors" + "fmt" + "html" + "math" + "net/url" + "regexp" + "strconv" + "strings" + "time" + "unicode/utf8" +) + +// Operation defines the operation of a diff item. +type Operation int8 + +const ( + // DiffDelete item represents a delete diff. + DiffDelete Operation = -1 + // DiffInsert item represents an insert diff. + DiffInsert Operation = 1 + // DiffEqual item represents an equal diff. + DiffEqual Operation = 0 +) + +// Diff represents one diff operation +type Diff struct { + Type Operation + Text string +} + +func splice(slice []Diff, index int, amount int, elements ...Diff) []Diff { + return append(slice[:index], append(elements, slice[index+amount:]...)...) +} + +// DiffMain finds the differences between two texts. +// If an invalid UTF-8 sequence is encountered, it will be replaced by the Unicode replacement character. +func (dmp *DiffMatchPatch) DiffMain(text1, text2 string, checklines bool) []Diff { + return dmp.DiffMainRunes([]rune(text1), []rune(text2), checklines) +} + +// DiffMainRunes finds the differences between two rune sequences. +// If an invalid UTF-8 sequence is encountered, it will be replaced by the Unicode replacement character. +func (dmp *DiffMatchPatch) DiffMainRunes(text1, text2 []rune, checklines bool) []Diff { + var deadline time.Time + if dmp.DiffTimeout > 0 { + deadline = time.Now().Add(dmp.DiffTimeout) + } + return dmp.diffMainRunes(text1, text2, checklines, deadline) +} + +func (dmp *DiffMatchPatch) diffMainRunes(text1, text2 []rune, checklines bool, deadline time.Time) []Diff { + if runesEqual(text1, text2) { + var diffs []Diff + if len(text1) > 0 { + diffs = append(diffs, Diff{DiffEqual, string(text1)}) + } + return diffs + } + // Trim off common prefix (speedup). + commonlength := commonPrefixLength(text1, text2) + commonprefix := text1[:commonlength] + text1 = text1[commonlength:] + text2 = text2[commonlength:] + + // Trim off common suffix (speedup). + commonlength = commonSuffixLength(text1, text2) + commonsuffix := text1[len(text1)-commonlength:] + text1 = text1[:len(text1)-commonlength] + text2 = text2[:len(text2)-commonlength] + + // Compute the diff on the middle block. + diffs := dmp.diffCompute(text1, text2, checklines, deadline) + + // Restore the prefix and suffix. + if len(commonprefix) != 0 { + diffs = append([]Diff{Diff{DiffEqual, string(commonprefix)}}, diffs...) + } + if len(commonsuffix) != 0 { + diffs = append(diffs, Diff{DiffEqual, string(commonsuffix)}) + } + + return dmp.DiffCleanupMerge(diffs) +} + +// diffCompute finds the differences between two rune slices. Assumes that the texts do not have any common prefix or suffix. +func (dmp *DiffMatchPatch) diffCompute(text1, text2 []rune, checklines bool, deadline time.Time) []Diff { + diffs := []Diff{} + if len(text1) == 0 { + // Just add some text (speedup). + return append(diffs, Diff{DiffInsert, string(text2)}) + } else if len(text2) == 0 { + // Just delete some text (speedup). + return append(diffs, Diff{DiffDelete, string(text1)}) + } + + var longtext, shorttext []rune + if len(text1) > len(text2) { + longtext = text1 + shorttext = text2 + } else { + longtext = text2 + shorttext = text1 + } + + if i := runesIndex(longtext, shorttext); i != -1 { + op := DiffInsert + // Swap insertions for deletions if diff is reversed. + if len(text1) > len(text2) { + op = DiffDelete + } + // Shorter text is inside the longer text (speedup). + return []Diff{ + Diff{op, string(longtext[:i])}, + Diff{DiffEqual, string(shorttext)}, + Diff{op, string(longtext[i+len(shorttext):])}, + } + } else if len(shorttext) == 1 { + // Single character string. + // After the previous speedup, the character can't be an equality. + return []Diff{ + Diff{DiffDelete, string(text1)}, + Diff{DiffInsert, string(text2)}, + } + // Check to see if the problem can be split in two. + } else if hm := dmp.diffHalfMatch(text1, text2); hm != nil { + // A half-match was found, sort out the return data. + text1A := hm[0] + text1B := hm[1] + text2A := hm[2] + text2B := hm[3] + midCommon := hm[4] + // Send both pairs off for separate processing. + diffsA := dmp.diffMainRunes(text1A, text2A, checklines, deadline) + diffsB := dmp.diffMainRunes(text1B, text2B, checklines, deadline) + // Merge the results. + return append(diffsA, append([]Diff{Diff{DiffEqual, string(midCommon)}}, diffsB...)...) + } else if checklines && len(text1) > 100 && len(text2) > 100 { + return dmp.diffLineMode(text1, text2, deadline) + } + return dmp.diffBisect(text1, text2, deadline) +} + +// diffLineMode does a quick line-level diff on both []runes, then rediff the parts for greater accuracy. This speedup can produce non-minimal diffs. +func (dmp *DiffMatchPatch) diffLineMode(text1, text2 []rune, deadline time.Time) []Diff { + // Scan the text on a line-by-line basis first. + text1, text2, linearray := dmp.diffLinesToRunes(text1, text2) + + diffs := dmp.diffMainRunes(text1, text2, false, deadline) + + // Convert the diff back to original text. + diffs = dmp.DiffCharsToLines(diffs, linearray) + // Eliminate freak matches (e.g. blank lines) + diffs = dmp.DiffCleanupSemantic(diffs) + + // Rediff any replacement blocks, this time character-by-character. + // Add a dummy entry at the end. + diffs = append(diffs, Diff{DiffEqual, ""}) + + pointer := 0 + countDelete := 0 + countInsert := 0 + + // NOTE: Rune slices are slower than using strings in this case. + textDelete := "" + textInsert := "" + + for pointer < len(diffs) { + switch diffs[pointer].Type { + case DiffInsert: + countInsert++ + textInsert += diffs[pointer].Text + case DiffDelete: + countDelete++ + textDelete += diffs[pointer].Text + case DiffEqual: + // Upon reaching an equality, check for prior redundancies. + if countDelete >= 1 && countInsert >= 1 { + // Delete the offending records and add the merged ones. + diffs = splice(diffs, pointer-countDelete-countInsert, + countDelete+countInsert) + + pointer = pointer - countDelete - countInsert + a := dmp.diffMainRunes([]rune(textDelete), []rune(textInsert), false, deadline) + for j := len(a) - 1; j >= 0; j-- { + diffs = splice(diffs, pointer, 0, a[j]) + } + pointer = pointer + len(a) + } + + countInsert = 0 + countDelete = 0 + textDelete = "" + textInsert = "" + } + pointer++ + } + + return diffs[:len(diffs)-1] // Remove the dummy entry at the end. +} + +// DiffBisect finds the 'middle snake' of a diff, split the problem in two and return the recursively constructed diff. +// If an invalid UTF-8 sequence is encountered, it will be replaced by the Unicode replacement character. +// See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations. +func (dmp *DiffMatchPatch) DiffBisect(text1, text2 string, deadline time.Time) []Diff { + // Unused in this code, but retained for interface compatibility. + return dmp.diffBisect([]rune(text1), []rune(text2), deadline) +} + +// diffBisect finds the 'middle snake' of a diff, splits the problem in two and returns the recursively constructed diff. +// See Myers's 1986 paper: An O(ND) Difference Algorithm and Its Variations. +func (dmp *DiffMatchPatch) diffBisect(runes1, runes2 []rune, deadline time.Time) []Diff { + // Cache the text lengths to prevent multiple calls. + runes1Len, runes2Len := len(runes1), len(runes2) + + maxD := (runes1Len + runes2Len + 1) / 2 + vOffset := maxD + vLength := 2 * maxD + + v1 := make([]int, vLength) + v2 := make([]int, vLength) + for i := range v1 { + v1[i] = -1 + v2[i] = -1 + } + v1[vOffset+1] = 0 + v2[vOffset+1] = 0 + + delta := runes1Len - runes2Len + // If the total number of characters is odd, then the front path will collide with the reverse path. + front := (delta%2 != 0) + // Offsets for start and end of k loop. Prevents mapping of space beyond the grid. + k1start := 0 + k1end := 0 + k2start := 0 + k2end := 0 + for d := 0; d < maxD; d++ { + // Bail out if deadline is reached. + if !deadline.IsZero() && time.Now().After(deadline) { + break + } + + // Walk the front path one step. + for k1 := -d + k1start; k1 <= d-k1end; k1 += 2 { + k1Offset := vOffset + k1 + var x1 int + + if k1 == -d || (k1 != d && v1[k1Offset-1] < v1[k1Offset+1]) { + x1 = v1[k1Offset+1] + } else { + x1 = v1[k1Offset-1] + 1 + } + + y1 := x1 - k1 + for x1 < runes1Len && y1 < runes2Len { + if runes1[x1] != runes2[y1] { + break + } + x1++ + y1++ + } + v1[k1Offset] = x1 + if x1 > runes1Len { + // Ran off the right of the graph. + k1end += 2 + } else if y1 > runes2Len { + // Ran off the bottom of the graph. + k1start += 2 + } else if front { + k2Offset := vOffset + delta - k1 + if k2Offset >= 0 && k2Offset < vLength && v2[k2Offset] != -1 { + // Mirror x2 onto top-left coordinate system. + x2 := runes1Len - v2[k2Offset] + if x1 >= x2 { + // Overlap detected. + return dmp.diffBisectSplit(runes1, runes2, x1, y1, deadline) + } + } + } + } + // Walk the reverse path one step. + for k2 := -d + k2start; k2 <= d-k2end; k2 += 2 { + k2Offset := vOffset + k2 + var x2 int + if k2 == -d || (k2 != d && v2[k2Offset-1] < v2[k2Offset+1]) { + x2 = v2[k2Offset+1] + } else { + x2 = v2[k2Offset-1] + 1 + } + var y2 = x2 - k2 + for x2 < runes1Len && y2 < runes2Len { + if runes1[runes1Len-x2-1] != runes2[runes2Len-y2-1] { + break + } + x2++ + y2++ + } + v2[k2Offset] = x2 + if x2 > runes1Len { + // Ran off the left of the graph. + k2end += 2 + } else if y2 > runes2Len { + // Ran off the top of the graph. + k2start += 2 + } else if !front { + k1Offset := vOffset + delta - k2 + if k1Offset >= 0 && k1Offset < vLength && v1[k1Offset] != -1 { + x1 := v1[k1Offset] + y1 := vOffset + x1 - k1Offset + // Mirror x2 onto top-left coordinate system. + x2 = runes1Len - x2 + if x1 >= x2 { + // Overlap detected. + return dmp.diffBisectSplit(runes1, runes2, x1, y1, deadline) + } + } + } + } + } + // Diff took too long and hit the deadline or number of diffs equals number of characters, no commonality at all. + return []Diff{ + Diff{DiffDelete, string(runes1)}, + Diff{DiffInsert, string(runes2)}, + } +} + +func (dmp *DiffMatchPatch) diffBisectSplit(runes1, runes2 []rune, x, y int, + deadline time.Time) []Diff { + runes1a := runes1[:x] + runes2a := runes2[:y] + runes1b := runes1[x:] + runes2b := runes2[y:] + + // Compute both diffs serially. + diffs := dmp.diffMainRunes(runes1a, runes2a, false, deadline) + diffsb := dmp.diffMainRunes(runes1b, runes2b, false, deadline) + + return append(diffs, diffsb...) +} + +// DiffLinesToChars splits two texts into a list of strings, and educes the texts to a string of hashes where each Unicode character represents one line. +// It's slightly faster to call DiffLinesToRunes first, followed by DiffMainRunes. +func (dmp *DiffMatchPatch) DiffLinesToChars(text1, text2 string) (string, string, []string) { + chars1, chars2, lineArray := dmp.DiffLinesToRunes(text1, text2) + return string(chars1), string(chars2), lineArray +} + +// DiffLinesToRunes splits two texts into a list of runes. Each rune represents one line. +func (dmp *DiffMatchPatch) DiffLinesToRunes(text1, text2 string) ([]rune, []rune, []string) { + // '\x00' is a valid character, but various debuggers don't like it. So we'll insert a junk entry to avoid generating a null character. + lineArray := []string{""} // e.g. lineArray[4] == 'Hello\n' + lineHash := map[string]int{} // e.g. lineHash['Hello\n'] == 4 + + chars1 := dmp.diffLinesToRunesMunge(text1, &lineArray, lineHash) + chars2 := dmp.diffLinesToRunesMunge(text2, &lineArray, lineHash) + + return chars1, chars2, lineArray +} + +func (dmp *DiffMatchPatch) diffLinesToRunes(text1, text2 []rune) ([]rune, []rune, []string) { + return dmp.DiffLinesToRunes(string(text1), string(text2)) +} + +// diffLinesToRunesMunge splits a text into an array of strings, and reduces the texts to a []rune where each Unicode character represents one line. +// We use strings instead of []runes as input mainly because you can't use []rune as a map key. +func (dmp *DiffMatchPatch) diffLinesToRunesMunge(text string, lineArray *[]string, lineHash map[string]int) []rune { + // Walk the text, pulling out a substring for each line. text.split('\n') would would temporarily double our memory footprint. Modifying text would create many large strings to garbage collect. + lineStart := 0 + lineEnd := -1 + runes := []rune{} + + for lineEnd < len(text)-1 { + lineEnd = indexOf(text, "\n", lineStart) + + if lineEnd == -1 { + lineEnd = len(text) - 1 + } + + line := text[lineStart : lineEnd+1] + lineStart = lineEnd + 1 + lineValue, ok := lineHash[line] + + if ok { + runes = append(runes, rune(lineValue)) + } else { + *lineArray = append(*lineArray, line) + lineHash[line] = len(*lineArray) - 1 + runes = append(runes, rune(len(*lineArray)-1)) + } + } + + return runes +} + +// DiffCharsToLines rehydrates the text in a diff from a string of line hashes to real lines of text. +func (dmp *DiffMatchPatch) DiffCharsToLines(diffs []Diff, lineArray []string) []Diff { + hydrated := make([]Diff, 0, len(diffs)) + for _, aDiff := range diffs { + chars := aDiff.Text + text := make([]string, len(chars)) + + for i, r := range chars { + text[i] = lineArray[r] + } + + aDiff.Text = strings.Join(text, "") + hydrated = append(hydrated, aDiff) + } + return hydrated +} + +// DiffCommonPrefix determines the common prefix length of two strings. +func (dmp *DiffMatchPatch) DiffCommonPrefix(text1, text2 string) int { + // Unused in this code, but retained for interface compatibility. + return commonPrefixLength([]rune(text1), []rune(text2)) +} + +// DiffCommonSuffix determines the common suffix length of two strings. +func (dmp *DiffMatchPatch) DiffCommonSuffix(text1, text2 string) int { + // Unused in this code, but retained for interface compatibility. + return commonSuffixLength([]rune(text1), []rune(text2)) +} + +// commonPrefixLength returns the length of the common prefix of two rune slices. +func commonPrefixLength(text1, text2 []rune) int { + short, long := text1, text2 + if len(short) > len(long) { + short, long = long, short + } + for i, r := range short { + if r != long[i] { + return i + } + } + return len(short) +} + +// commonSuffixLength returns the length of the common suffix of two rune slices. +func commonSuffixLength(text1, text2 []rune) int { + n := min(len(text1), len(text2)) + for i := 0; i < n; i++ { + if text1[len(text1)-i-1] != text2[len(text2)-i-1] { + return i + } + } + return n + + // TODO research and benchmark this, why is it not activated? https://github.com/sergi/go-diff/issues/54 + // Binary search. + // Performance analysis: http://neil.fraser.name/news/2007/10/09/ + /* + pointermin := 0 + pointermax := math.Min(len(text1), len(text2)) + pointermid := pointermax + pointerend := 0 + for pointermin < pointermid { + if text1[len(text1)-pointermid:len(text1)-pointerend] == + text2[len(text2)-pointermid:len(text2)-pointerend] { + pointermin = pointermid + pointerend = pointermin + } else { + pointermax = pointermid + } + pointermid = math.Floor((pointermax-pointermin)/2 + pointermin) + } + return pointermid + */ +} + +// DiffCommonOverlap determines if the suffix of one string is the prefix of another. +func (dmp *DiffMatchPatch) DiffCommonOverlap(text1 string, text2 string) int { + // Cache the text lengths to prevent multiple calls. + text1Length := len(text1) + text2Length := len(text2) + // Eliminate the null case. + if text1Length == 0 || text2Length == 0 { + return 0 + } + // Truncate the longer string. + if text1Length > text2Length { + text1 = text1[text1Length-text2Length:] + } else if text1Length < text2Length { + text2 = text2[0:text1Length] + } + textLength := int(math.Min(float64(text1Length), float64(text2Length))) + // Quick check for the worst case. + if text1 == text2 { + return textLength + } + + // Start by looking for a single character match and increase length until no match is found. Performance analysis: http://neil.fraser.name/news/2010/11/04/ + best := 0 + length := 1 + for { + pattern := text1[textLength-length:] + found := strings.Index(text2, pattern) + if found == -1 { + break + } + length += found + if found == 0 || text1[textLength-length:] == text2[0:length] { + best = length + length++ + } + } + + return best +} + +// DiffHalfMatch checks whether the two texts share a substring which is at least half the length of the longer text. This speedup can produce non-minimal diffs. +func (dmp *DiffMatchPatch) DiffHalfMatch(text1, text2 string) []string { + // Unused in this code, but retained for interface compatibility. + runeSlices := dmp.diffHalfMatch([]rune(text1), []rune(text2)) + if runeSlices == nil { + return nil + } + + result := make([]string, len(runeSlices)) + for i, r := range runeSlices { + result[i] = string(r) + } + return result +} + +func (dmp *DiffMatchPatch) diffHalfMatch(text1, text2 []rune) [][]rune { + if dmp.DiffTimeout <= 0 { + // Don't risk returning a non-optimal diff if we have unlimited time. + return nil + } + + var longtext, shorttext []rune + if len(text1) > len(text2) { + longtext = text1 + shorttext = text2 + } else { + longtext = text2 + shorttext = text1 + } + + if len(longtext) < 4 || len(shorttext)*2 < len(longtext) { + return nil // Pointless. + } + + // First check if the second quarter is the seed for a half-match. + hm1 := dmp.diffHalfMatchI(longtext, shorttext, int(float64(len(longtext)+3)/4)) + + // Check again based on the third quarter. + hm2 := dmp.diffHalfMatchI(longtext, shorttext, int(float64(len(longtext)+1)/2)) + + hm := [][]rune{} + if hm1 == nil && hm2 == nil { + return nil + } else if hm2 == nil { + hm = hm1 + } else if hm1 == nil { + hm = hm2 + } else { + // Both matched. Select the longest. + if len(hm1[4]) > len(hm2[4]) { + hm = hm1 + } else { + hm = hm2 + } + } + + // A half-match was found, sort out the return data. + if len(text1) > len(text2) { + return hm + } + + return [][]rune{hm[2], hm[3], hm[0], hm[1], hm[4]} +} + +// diffHalfMatchI checks if a substring of shorttext exist within longtext such that the substring is at least half the length of longtext? +// Returns a slice containing the prefix of longtext, the suffix of longtext, the prefix of shorttext, the suffix of shorttext and the common middle, or null if there was no match. +func (dmp *DiffMatchPatch) diffHalfMatchI(l, s []rune, i int) [][]rune { + var bestCommonA []rune + var bestCommonB []rune + var bestCommonLen int + var bestLongtextA []rune + var bestLongtextB []rune + var bestShorttextA []rune + var bestShorttextB []rune + + // Start with a 1/4 length substring at position i as a seed. + seed := l[i : i+len(l)/4] + + for j := runesIndexOf(s, seed, 0); j != -1; j = runesIndexOf(s, seed, j+1) { + prefixLength := commonPrefixLength(l[i:], s[j:]) + suffixLength := commonSuffixLength(l[:i], s[:j]) + + if bestCommonLen < suffixLength+prefixLength { + bestCommonA = s[j-suffixLength : j] + bestCommonB = s[j : j+prefixLength] + bestCommonLen = len(bestCommonA) + len(bestCommonB) + bestLongtextA = l[:i-suffixLength] + bestLongtextB = l[i+prefixLength:] + bestShorttextA = s[:j-suffixLength] + bestShorttextB = s[j+prefixLength:] + } + } + + if bestCommonLen*2 < len(l) { + return nil + } + + return [][]rune{ + bestLongtextA, + bestLongtextB, + bestShorttextA, + bestShorttextB, + append(bestCommonA, bestCommonB...), + } +} + +// DiffCleanupSemantic reduces the number of edits by eliminating semantically trivial equalities. +func (dmp *DiffMatchPatch) DiffCleanupSemantic(diffs []Diff) []Diff { + changes := false + // Stack of indices where equalities are found. + type equality struct { + data int + next *equality + } + var equalities *equality + + var lastequality string + // Always equal to diffs[equalities[equalitiesLength - 1]][1] + var pointer int // Index of current position. + // Number of characters that changed prior to the equality. + var lengthInsertions1, lengthDeletions1 int + // Number of characters that changed after the equality. + var lengthInsertions2, lengthDeletions2 int + + for pointer < len(diffs) { + if diffs[pointer].Type == DiffEqual { + // Equality found. + + equalities = &equality{ + data: pointer, + next: equalities, + } + lengthInsertions1 = lengthInsertions2 + lengthDeletions1 = lengthDeletions2 + lengthInsertions2 = 0 + lengthDeletions2 = 0 + lastequality = diffs[pointer].Text + } else { + // An insertion or deletion. + + if diffs[pointer].Type == DiffInsert { + lengthInsertions2 += len(diffs[pointer].Text) + } else { + lengthDeletions2 += len(diffs[pointer].Text) + } + // Eliminate an equality that is smaller or equal to the edits on both sides of it. + difference1 := int(math.Max(float64(lengthInsertions1), float64(lengthDeletions1))) + difference2 := int(math.Max(float64(lengthInsertions2), float64(lengthDeletions2))) + if len(lastequality) > 0 && + (len(lastequality) <= difference1) && + (len(lastequality) <= difference2) { + // Duplicate record. + insPoint := equalities.data + diffs = append( + diffs[:insPoint], + append([]Diff{Diff{DiffDelete, lastequality}}, diffs[insPoint:]...)...) + + // Change second copy to insert. + diffs[insPoint+1].Type = DiffInsert + // Throw away the equality we just deleted. + equalities = equalities.next + + if equalities != nil { + equalities = equalities.next + } + if equalities != nil { + pointer = equalities.data + } else { + pointer = -1 + } + + lengthInsertions1 = 0 // Reset the counters. + lengthDeletions1 = 0 + lengthInsertions2 = 0 + lengthDeletions2 = 0 + lastequality = "" + changes = true + } + } + pointer++ + } + + // Normalize the diff. + if changes { + diffs = dmp.DiffCleanupMerge(diffs) + } + diffs = dmp.DiffCleanupSemanticLossless(diffs) + // Find any overlaps between deletions and insertions. + // e.g: abcxxxxxxdef + // -> abcxxxdef + // e.g: xxxabcdefxxx + // -> defxxxabc + // Only extract an overlap if it is as big as the edit ahead or behind it. + pointer = 1 + for pointer < len(diffs) { + if diffs[pointer-1].Type == DiffDelete && + diffs[pointer].Type == DiffInsert { + deletion := diffs[pointer-1].Text + insertion := diffs[pointer].Text + overlapLength1 := dmp.DiffCommonOverlap(deletion, insertion) + overlapLength2 := dmp.DiffCommonOverlap(insertion, deletion) + if overlapLength1 >= overlapLength2 { + if float64(overlapLength1) >= float64(len(deletion))/2 || + float64(overlapLength1) >= float64(len(insertion))/2 { + + // Overlap found. Insert an equality and trim the surrounding edits. + diffs = append( + diffs[:pointer], + append([]Diff{Diff{DiffEqual, insertion[:overlapLength1]}}, diffs[pointer:]...)...) + + diffs[pointer-1].Text = + deletion[0 : len(deletion)-overlapLength1] + diffs[pointer+1].Text = insertion[overlapLength1:] + pointer++ + } + } else { + if float64(overlapLength2) >= float64(len(deletion))/2 || + float64(overlapLength2) >= float64(len(insertion))/2 { + // Reverse overlap found. Insert an equality and swap and trim the surrounding edits. + overlap := Diff{DiffEqual, deletion[:overlapLength2]} + diffs = append( + diffs[:pointer], + append([]Diff{overlap}, diffs[pointer:]...)...) + + diffs[pointer-1].Type = DiffInsert + diffs[pointer-1].Text = insertion[0 : len(insertion)-overlapLength2] + diffs[pointer+1].Type = DiffDelete + diffs[pointer+1].Text = deletion[overlapLength2:] + pointer++ + } + } + pointer++ + } + pointer++ + } + + return diffs +} + +// Define some regex patterns for matching boundaries. +var ( + nonAlphaNumericRegex = regexp.MustCompile(`[^a-zA-Z0-9]`) + whitespaceRegex = regexp.MustCompile(`\s`) + linebreakRegex = regexp.MustCompile(`[\r\n]`) + blanklineEndRegex = regexp.MustCompile(`\n\r?\n$`) + blanklineStartRegex = regexp.MustCompile(`^\r?\n\r?\n`) +) + +// diffCleanupSemanticScore computes a score representing whether the internal boundary falls on logical boundaries. +// Scores range from 6 (best) to 0 (worst). Closure, but does not reference any external variables. +func diffCleanupSemanticScore(one, two string) int { + if len(one) == 0 || len(two) == 0 { + // Edges are the best. + return 6 + } + + // Each port of this function behaves slightly differently due to subtle differences in each language's definition of things like 'whitespace'. Since this function's purpose is largely cosmetic, the choice has been made to use each language's native features rather than force total conformity. + rune1, _ := utf8.DecodeLastRuneInString(one) + rune2, _ := utf8.DecodeRuneInString(two) + char1 := string(rune1) + char2 := string(rune2) + + nonAlphaNumeric1 := nonAlphaNumericRegex.MatchString(char1) + nonAlphaNumeric2 := nonAlphaNumericRegex.MatchString(char2) + whitespace1 := nonAlphaNumeric1 && whitespaceRegex.MatchString(char1) + whitespace2 := nonAlphaNumeric2 && whitespaceRegex.MatchString(char2) + lineBreak1 := whitespace1 && linebreakRegex.MatchString(char1) + lineBreak2 := whitespace2 && linebreakRegex.MatchString(char2) + blankLine1 := lineBreak1 && blanklineEndRegex.MatchString(one) + blankLine2 := lineBreak2 && blanklineEndRegex.MatchString(two) + + if blankLine1 || blankLine2 { + // Five points for blank lines. + return 5 + } else if lineBreak1 || lineBreak2 { + // Four points for line breaks. + return 4 + } else if nonAlphaNumeric1 && !whitespace1 && whitespace2 { + // Three points for end of sentences. + return 3 + } else if whitespace1 || whitespace2 { + // Two points for whitespace. + return 2 + } else if nonAlphaNumeric1 || nonAlphaNumeric2 { + // One point for non-alphanumeric. + return 1 + } + return 0 +} + +// DiffCleanupSemanticLossless looks for single edits surrounded on both sides by equalities which can be shifted sideways to align the edit to a word boundary. +// E.g: The cat came. -> The cat came. +func (dmp *DiffMatchPatch) DiffCleanupSemanticLossless(diffs []Diff) []Diff { + pointer := 1 + + // Intentionally ignore the first and last element (don't need checking). + for pointer < len(diffs)-1 { + if diffs[pointer-1].Type == DiffEqual && + diffs[pointer+1].Type == DiffEqual { + + // This is a single edit surrounded by equalities. + equality1 := diffs[pointer-1].Text + edit := diffs[pointer].Text + equality2 := diffs[pointer+1].Text + + // First, shift the edit as far left as possible. + commonOffset := dmp.DiffCommonSuffix(equality1, edit) + if commonOffset > 0 { + commonString := edit[len(edit)-commonOffset:] + equality1 = equality1[0 : len(equality1)-commonOffset] + edit = commonString + edit[:len(edit)-commonOffset] + equality2 = commonString + equality2 + } + + // Second, step character by character right, looking for the best fit. + bestEquality1 := equality1 + bestEdit := edit + bestEquality2 := equality2 + bestScore := diffCleanupSemanticScore(equality1, edit) + + diffCleanupSemanticScore(edit, equality2) + + for len(edit) != 0 && len(equality2) != 0 { + _, sz := utf8.DecodeRuneInString(edit) + if len(equality2) < sz || edit[:sz] != equality2[:sz] { + break + } + equality1 += edit[:sz] + edit = edit[sz:] + equality2[:sz] + equality2 = equality2[sz:] + score := diffCleanupSemanticScore(equality1, edit) + + diffCleanupSemanticScore(edit, equality2) + // The >= encourages trailing rather than leading whitespace on edits. + if score >= bestScore { + bestScore = score + bestEquality1 = equality1 + bestEdit = edit + bestEquality2 = equality2 + } + } + + if diffs[pointer-1].Text != bestEquality1 { + // We have an improvement, save it back to the diff. + if len(bestEquality1) != 0 { + diffs[pointer-1].Text = bestEquality1 + } else { + diffs = splice(diffs, pointer-1, 1) + pointer-- + } + + diffs[pointer].Text = bestEdit + if len(bestEquality2) != 0 { + diffs[pointer+1].Text = bestEquality2 + } else { + diffs = append(diffs[:pointer+1], diffs[pointer+2:]...) + pointer-- + } + } + } + pointer++ + } + + return diffs +} + +// DiffCleanupEfficiency reduces the number of edits by eliminating operationally trivial equalities. +func (dmp *DiffMatchPatch) DiffCleanupEfficiency(diffs []Diff) []Diff { + changes := false + // Stack of indices where equalities are found. + type equality struct { + data int + next *equality + } + var equalities *equality + // Always equal to equalities[equalitiesLength-1][1] + lastequality := "" + pointer := 0 // Index of current position. + // Is there an insertion operation before the last equality. + preIns := false + // Is there a deletion operation before the last equality. + preDel := false + // Is there an insertion operation after the last equality. + postIns := false + // Is there a deletion operation after the last equality. + postDel := false + for pointer < len(diffs) { + if diffs[pointer].Type == DiffEqual { // Equality found. + if len(diffs[pointer].Text) < dmp.DiffEditCost && + (postIns || postDel) { + // Candidate found. + equalities = &equality{ + data: pointer, + next: equalities, + } + preIns = postIns + preDel = postDel + lastequality = diffs[pointer].Text + } else { + // Not a candidate, and can never become one. + equalities = nil + lastequality = "" + } + postIns = false + postDel = false + } else { // An insertion or deletion. + if diffs[pointer].Type == DiffDelete { + postDel = true + } else { + postIns = true + } + + // Five types to be split: + // ABXYCD + // AXCD + // ABXC + // AXCD + // ABXC + var sumPres int + if preIns { + sumPres++ + } + if preDel { + sumPres++ + } + if postIns { + sumPres++ + } + if postDel { + sumPres++ + } + if len(lastequality) > 0 && + ((preIns && preDel && postIns && postDel) || + ((len(lastequality) < dmp.DiffEditCost/2) && sumPres == 3)) { + + insPoint := equalities.data + + // Duplicate record. + diffs = append(diffs[:insPoint], + append([]Diff{Diff{DiffDelete, lastequality}}, diffs[insPoint:]...)...) + + // Change second copy to insert. + diffs[insPoint+1].Type = DiffInsert + // Throw away the equality we just deleted. + equalities = equalities.next + lastequality = "" + + if preIns && preDel { + // No changes made which could affect previous entry, keep going. + postIns = true + postDel = true + equalities = nil + } else { + if equalities != nil { + equalities = equalities.next + } + if equalities != nil { + pointer = equalities.data + } else { + pointer = -1 + } + postIns = false + postDel = false + } + changes = true + } + } + pointer++ + } + + if changes { + diffs = dmp.DiffCleanupMerge(diffs) + } + + return diffs +} + +// DiffCleanupMerge reorders and merges like edit sections. Merge equalities. +// Any edit section can move as long as it doesn't cross an equality. +func (dmp *DiffMatchPatch) DiffCleanupMerge(diffs []Diff) []Diff { + // Add a dummy entry at the end. + diffs = append(diffs, Diff{DiffEqual, ""}) + pointer := 0 + countDelete := 0 + countInsert := 0 + commonlength := 0 + textDelete := []rune(nil) + textInsert := []rune(nil) + + for pointer < len(diffs) { + switch diffs[pointer].Type { + case DiffInsert: + countInsert++ + textInsert = append(textInsert, []rune(diffs[pointer].Text)...) + pointer++ + break + case DiffDelete: + countDelete++ + textDelete = append(textDelete, []rune(diffs[pointer].Text)...) + pointer++ + break + case DiffEqual: + // Upon reaching an equality, check for prior redundancies. + if countDelete+countInsert > 1 { + if countDelete != 0 && countInsert != 0 { + // Factor out any common prefixies. + commonlength = commonPrefixLength(textInsert, textDelete) + if commonlength != 0 { + x := pointer - countDelete - countInsert + if x > 0 && diffs[x-1].Type == DiffEqual { + diffs[x-1].Text += string(textInsert[:commonlength]) + } else { + diffs = append([]Diff{Diff{DiffEqual, string(textInsert[:commonlength])}}, diffs...) + pointer++ + } + textInsert = textInsert[commonlength:] + textDelete = textDelete[commonlength:] + } + // Factor out any common suffixies. + commonlength = commonSuffixLength(textInsert, textDelete) + if commonlength != 0 { + insertIndex := len(textInsert) - commonlength + deleteIndex := len(textDelete) - commonlength + diffs[pointer].Text = string(textInsert[insertIndex:]) + diffs[pointer].Text + textInsert = textInsert[:insertIndex] + textDelete = textDelete[:deleteIndex] + } + } + // Delete the offending records and add the merged ones. + if countDelete == 0 { + diffs = splice(diffs, pointer-countInsert, + countDelete+countInsert, + Diff{DiffInsert, string(textInsert)}) + } else if countInsert == 0 { + diffs = splice(diffs, pointer-countDelete, + countDelete+countInsert, + Diff{DiffDelete, string(textDelete)}) + } else { + diffs = splice(diffs, pointer-countDelete-countInsert, + countDelete+countInsert, + Diff{DiffDelete, string(textDelete)}, + Diff{DiffInsert, string(textInsert)}) + } + + pointer = pointer - countDelete - countInsert + 1 + if countDelete != 0 { + pointer++ + } + if countInsert != 0 { + pointer++ + } + } else if pointer != 0 && diffs[pointer-1].Type == DiffEqual { + // Merge this equality with the previous one. + diffs[pointer-1].Text += diffs[pointer].Text + diffs = append(diffs[:pointer], diffs[pointer+1:]...) + } else { + pointer++ + } + countInsert = 0 + countDelete = 0 + textDelete = nil + textInsert = nil + break + } + } + + if len(diffs[len(diffs)-1].Text) == 0 { + diffs = diffs[0 : len(diffs)-1] // Remove the dummy entry at the end. + } + + // Second pass: look for single edits surrounded on both sides by equalities which can be shifted sideways to eliminate an equality. E.g: ABAC -> ABAC + changes := false + pointer = 1 + // Intentionally ignore the first and last element (don't need checking). + for pointer < (len(diffs) - 1) { + if diffs[pointer-1].Type == DiffEqual && + diffs[pointer+1].Type == DiffEqual { + // This is a single edit surrounded by equalities. + if strings.HasSuffix(diffs[pointer].Text, diffs[pointer-1].Text) { + // Shift the edit over the previous equality. + diffs[pointer].Text = diffs[pointer-1].Text + + diffs[pointer].Text[:len(diffs[pointer].Text)-len(diffs[pointer-1].Text)] + diffs[pointer+1].Text = diffs[pointer-1].Text + diffs[pointer+1].Text + diffs = splice(diffs, pointer-1, 1) + changes = true + } else if strings.HasPrefix(diffs[pointer].Text, diffs[pointer+1].Text) { + // Shift the edit over the next equality. + diffs[pointer-1].Text += diffs[pointer+1].Text + diffs[pointer].Text = + diffs[pointer].Text[len(diffs[pointer+1].Text):] + diffs[pointer+1].Text + diffs = splice(diffs, pointer+1, 1) + changes = true + } + } + pointer++ + } + + // If shifts were made, the diff needs reordering and another shift sweep. + if changes { + diffs = dmp.DiffCleanupMerge(diffs) + } + + return diffs +} + +// DiffXIndex returns the equivalent location in s2. +func (dmp *DiffMatchPatch) DiffXIndex(diffs []Diff, loc int) int { + chars1 := 0 + chars2 := 0 + lastChars1 := 0 + lastChars2 := 0 + lastDiff := Diff{} + for i := 0; i < len(diffs); i++ { + aDiff := diffs[i] + if aDiff.Type != DiffInsert { + // Equality or deletion. + chars1 += len(aDiff.Text) + } + if aDiff.Type != DiffDelete { + // Equality or insertion. + chars2 += len(aDiff.Text) + } + if chars1 > loc { + // Overshot the location. + lastDiff = aDiff + break + } + lastChars1 = chars1 + lastChars2 = chars2 + } + if lastDiff.Type == DiffDelete { + // The location was deleted. + return lastChars2 + } + // Add the remaining character length. + return lastChars2 + (loc - lastChars1) +} + +// DiffPrettyHtml converts a []Diff into a pretty HTML report. +// It is intended as an example from which to write one's own display functions. +func (dmp *DiffMatchPatch) DiffPrettyHtml(diffs []Diff) string { + var buff bytes.Buffer + for _, diff := range diffs { + text := strings.Replace(html.EscapeString(diff.Text), "\n", "¶
", -1) + switch diff.Type { + case DiffInsert: + _, _ = buff.WriteString("") + _, _ = buff.WriteString(text) + _, _ = buff.WriteString("") + case DiffDelete: + _, _ = buff.WriteString("") + _, _ = buff.WriteString(text) + _, _ = buff.WriteString("") + case DiffEqual: + _, _ = buff.WriteString("") + _, _ = buff.WriteString(text) + _, _ = buff.WriteString("") + } + } + return buff.String() +} + +// DiffPrettyText converts a []Diff into a colored text report. +func (dmp *DiffMatchPatch) DiffPrettyText(diffs []Diff) string { + var buff bytes.Buffer + for _, diff := range diffs { + text := diff.Text + + switch diff.Type { + case DiffInsert: + _, _ = buff.WriteString("\x1b[32m") + _, _ = buff.WriteString(text) + _, _ = buff.WriteString("\x1b[0m") + case DiffDelete: + _, _ = buff.WriteString("\x1b[31m") + _, _ = buff.WriteString(text) + _, _ = buff.WriteString("\x1b[0m") + case DiffEqual: + _, _ = buff.WriteString(text) + } + } + + return buff.String() +} + +// DiffText1 computes and returns the source text (all equalities and deletions). +func (dmp *DiffMatchPatch) DiffText1(diffs []Diff) string { + //StringBuilder text = new StringBuilder() + var text bytes.Buffer + + for _, aDiff := range diffs { + if aDiff.Type != DiffInsert { + _, _ = text.WriteString(aDiff.Text) + } + } + return text.String() +} + +// DiffText2 computes and returns the destination text (all equalities and insertions). +func (dmp *DiffMatchPatch) DiffText2(diffs []Diff) string { + var text bytes.Buffer + + for _, aDiff := range diffs { + if aDiff.Type != DiffDelete { + _, _ = text.WriteString(aDiff.Text) + } + } + return text.String() +} + +// DiffLevenshtein computes the Levenshtein distance that is the number of inserted, deleted or substituted characters. +func (dmp *DiffMatchPatch) DiffLevenshtein(diffs []Diff) int { + levenshtein := 0 + insertions := 0 + deletions := 0 + + for _, aDiff := range diffs { + switch aDiff.Type { + case DiffInsert: + insertions += len(aDiff.Text) + case DiffDelete: + deletions += len(aDiff.Text) + case DiffEqual: + // A deletion and an insertion is one substitution. + levenshtein += max(insertions, deletions) + insertions = 0 + deletions = 0 + } + } + + levenshtein += max(insertions, deletions) + return levenshtein +} + +// DiffToDelta crushes the diff into an encoded string which describes the operations required to transform text1 into text2. +// E.g. =3\t-2\t+ing -> Keep 3 chars, delete 2 chars, insert 'ing'. Operations are tab-separated. Inserted text is escaped using %xx notation. +func (dmp *DiffMatchPatch) DiffToDelta(diffs []Diff) string { + var text bytes.Buffer + for _, aDiff := range diffs { + switch aDiff.Type { + case DiffInsert: + _, _ = text.WriteString("+") + _, _ = text.WriteString(strings.Replace(url.QueryEscape(aDiff.Text), "+", " ", -1)) + _, _ = text.WriteString("\t") + break + case DiffDelete: + _, _ = text.WriteString("-") + _, _ = text.WriteString(strconv.Itoa(utf8.RuneCountInString(aDiff.Text))) + _, _ = text.WriteString("\t") + break + case DiffEqual: + _, _ = text.WriteString("=") + _, _ = text.WriteString(strconv.Itoa(utf8.RuneCountInString(aDiff.Text))) + _, _ = text.WriteString("\t") + break + } + } + delta := text.String() + if len(delta) != 0 { + // Strip off trailing tab character. + delta = delta[0 : utf8.RuneCountInString(delta)-1] + delta = unescaper.Replace(delta) + } + return delta +} + +// DiffFromDelta given the original text1, and an encoded string which describes the operations required to transform text1 into text2, comAdde the full diff. +func (dmp *DiffMatchPatch) DiffFromDelta(text1 string, delta string) (diffs []Diff, err error) { + i := 0 + runes := []rune(text1) + + for _, token := range strings.Split(delta, "\t") { + if len(token) == 0 { + // Blank tokens are ok (from a trailing \t). + continue + } + + // Each token begins with a one character parameter which specifies the operation of this token (delete, insert, equality). + param := token[1:] + + switch op := token[0]; op { + case '+': + // Decode would Diff all "+" to " " + param = strings.Replace(param, "+", "%2b", -1) + param, err = url.QueryUnescape(param) + if err != nil { + return nil, err + } + if !utf8.ValidString(param) { + return nil, fmt.Errorf("invalid UTF-8 token: %q", param) + } + + diffs = append(diffs, Diff{DiffInsert, param}) + case '=', '-': + n, err := strconv.ParseInt(param, 10, 0) + if err != nil { + return nil, err + } else if n < 0 { + return nil, errors.New("Negative number in DiffFromDelta: " + param) + } + + i += int(n) + // Break out if we are out of bounds, go1.6 can't handle this very well + if i > len(runes) { + break + } + // Remember that string slicing is by byte - we want by rune here. + text := string(runes[i-int(n) : i]) + + if op == '=' { + diffs = append(diffs, Diff{DiffEqual, text}) + } else { + diffs = append(diffs, Diff{DiffDelete, text}) + } + default: + // Anything else is an error. + return nil, errors.New("Invalid diff operation in DiffFromDelta: " + string(token[0])) + } + } + + if i != len(runes) { + return nil, fmt.Errorf("Delta length (%v) is different from source text length (%v)", i, len(text1)) + } + + return diffs, nil +} diff --git a/vendor/github.com/sergi/go-diff/diffmatchpatch/diffmatchpatch.go b/vendor/github.com/sergi/go-diff/diffmatchpatch/diffmatchpatch.go new file mode 100644 index 00000000000..d3acc32ce13 --- /dev/null +++ b/vendor/github.com/sergi/go-diff/diffmatchpatch/diffmatchpatch.go @@ -0,0 +1,46 @@ +// Copyright (c) 2012-2016 The go-diff authors. All rights reserved. +// https://github.com/sergi/go-diff +// See the included LICENSE file for license details. +// +// go-diff is a Go implementation of Google's Diff, Match, and Patch library +// Original library is Copyright (c) 2006 Google Inc. +// http://code.google.com/p/google-diff-match-patch/ + +// Package diffmatchpatch offers robust algorithms to perform the operations required for synchronizing plain text. +package diffmatchpatch + +import ( + "time" +) + +// DiffMatchPatch holds the configuration for diff-match-patch operations. +type DiffMatchPatch struct { + // Number of seconds to map a diff before giving up (0 for infinity). + DiffTimeout time.Duration + // Cost of an empty edit operation in terms of edit characters. + DiffEditCost int + // How far to search for a match (0 = exact location, 1000+ = broad match). A match this many characters away from the expected location will add 1.0 to the score (0.0 is a perfect match). + MatchDistance int + // When deleting a large block of text (over ~64 characters), how close do the contents have to be to match the expected contents. (0.0 = perfection, 1.0 = very loose). Note that MatchThreshold controls how closely the end points of a delete need to match. + PatchDeleteThreshold float64 + // Chunk size for context length. + PatchMargin int + // The number of bits in an int. + MatchMaxBits int + // At what point is no match declared (0.0 = perfection, 1.0 = very loose). + MatchThreshold float64 +} + +// New creates a new DiffMatchPatch object with default parameters. +func New() *DiffMatchPatch { + // Defaults. + return &DiffMatchPatch{ + DiffTimeout: time.Second, + DiffEditCost: 4, + MatchThreshold: 0.5, + MatchDistance: 1000, + PatchDeleteThreshold: 0.5, + PatchMargin: 4, + MatchMaxBits: 32, + } +} diff --git a/vendor/github.com/sergi/go-diff/diffmatchpatch/match.go b/vendor/github.com/sergi/go-diff/diffmatchpatch/match.go new file mode 100644 index 00000000000..17374e109fe --- /dev/null +++ b/vendor/github.com/sergi/go-diff/diffmatchpatch/match.go @@ -0,0 +1,160 @@ +// Copyright (c) 2012-2016 The go-diff authors. All rights reserved. +// https://github.com/sergi/go-diff +// See the included LICENSE file for license details. +// +// go-diff is a Go implementation of Google's Diff, Match, and Patch library +// Original library is Copyright (c) 2006 Google Inc. +// http://code.google.com/p/google-diff-match-patch/ + +package diffmatchpatch + +import ( + "math" +) + +// MatchMain locates the best instance of 'pattern' in 'text' near 'loc'. +// Returns -1 if no match found. +func (dmp *DiffMatchPatch) MatchMain(text, pattern string, loc int) int { + // Check for null inputs not needed since null can't be passed in C#. + + loc = int(math.Max(0, math.Min(float64(loc), float64(len(text))))) + if text == pattern { + // Shortcut (potentially not guaranteed by the algorithm) + return 0 + } else if len(text) == 0 { + // Nothing to match. + return -1 + } else if loc+len(pattern) <= len(text) && text[loc:loc+len(pattern)] == pattern { + // Perfect match at the perfect spot! (Includes case of null pattern) + return loc + } + // Do a fuzzy compare. + return dmp.MatchBitap(text, pattern, loc) +} + +// MatchBitap locates the best instance of 'pattern' in 'text' near 'loc' using the Bitap algorithm. +// Returns -1 if no match was found. +func (dmp *DiffMatchPatch) MatchBitap(text, pattern string, loc int) int { + // Initialise the alphabet. + s := dmp.MatchAlphabet(pattern) + + // Highest score beyond which we give up. + scoreThreshold := dmp.MatchThreshold + // Is there a nearby exact match? (speedup) + bestLoc := indexOf(text, pattern, loc) + if bestLoc != -1 { + scoreThreshold = math.Min(dmp.matchBitapScore(0, bestLoc, loc, + pattern), scoreThreshold) + // What about in the other direction? (speedup) + bestLoc = lastIndexOf(text, pattern, loc+len(pattern)) + if bestLoc != -1 { + scoreThreshold = math.Min(dmp.matchBitapScore(0, bestLoc, loc, + pattern), scoreThreshold) + } + } + + // Initialise the bit arrays. + matchmask := 1 << uint((len(pattern) - 1)) + bestLoc = -1 + + var binMin, binMid int + binMax := len(pattern) + len(text) + lastRd := []int{} + for d := 0; d < len(pattern); d++ { + // Scan for the best match; each iteration allows for one more error. Run a binary search to determine how far from 'loc' we can stray at this error level. + binMin = 0 + binMid = binMax + for binMin < binMid { + if dmp.matchBitapScore(d, loc+binMid, loc, pattern) <= scoreThreshold { + binMin = binMid + } else { + binMax = binMid + } + binMid = (binMax-binMin)/2 + binMin + } + // Use the result from this iteration as the maximum for the next. + binMax = binMid + start := int(math.Max(1, float64(loc-binMid+1))) + finish := int(math.Min(float64(loc+binMid), float64(len(text))) + float64(len(pattern))) + + rd := make([]int, finish+2) + rd[finish+1] = (1 << uint(d)) - 1 + + for j := finish; j >= start; j-- { + var charMatch int + if len(text) <= j-1 { + // Out of range. + charMatch = 0 + } else if _, ok := s[text[j-1]]; !ok { + charMatch = 0 + } else { + charMatch = s[text[j-1]] + } + + if d == 0 { + // First pass: exact match. + rd[j] = ((rd[j+1] << 1) | 1) & charMatch + } else { + // Subsequent passes: fuzzy match. + rd[j] = ((rd[j+1]<<1)|1)&charMatch | (((lastRd[j+1] | lastRd[j]) << 1) | 1) | lastRd[j+1] + } + if (rd[j] & matchmask) != 0 { + score := dmp.matchBitapScore(d, j-1, loc, pattern) + // This match will almost certainly be better than any existing match. But check anyway. + if score <= scoreThreshold { + // Told you so. + scoreThreshold = score + bestLoc = j - 1 + if bestLoc > loc { + // When passing loc, don't exceed our current distance from loc. + start = int(math.Max(1, float64(2*loc-bestLoc))) + } else { + // Already passed loc, downhill from here on in. + break + } + } + } + } + if dmp.matchBitapScore(d+1, loc, loc, pattern) > scoreThreshold { + // No hope for a (better) match at greater error levels. + break + } + lastRd = rd + } + return bestLoc +} + +// matchBitapScore computes and returns the score for a match with e errors and x location. +func (dmp *DiffMatchPatch) matchBitapScore(e, x, loc int, pattern string) float64 { + accuracy := float64(e) / float64(len(pattern)) + proximity := math.Abs(float64(loc - x)) + if dmp.MatchDistance == 0 { + // Dodge divide by zero error. + if proximity == 0 { + return accuracy + } + + return 1.0 + } + return accuracy + (proximity / float64(dmp.MatchDistance)) +} + +// MatchAlphabet initialises the alphabet for the Bitap algorithm. +func (dmp *DiffMatchPatch) MatchAlphabet(pattern string) map[byte]int { + s := map[byte]int{} + charPattern := []byte(pattern) + for _, c := range charPattern { + _, ok := s[c] + if !ok { + s[c] = 0 + } + } + i := 0 + + for _, c := range charPattern { + value := s[c] | int(uint(1)< y { + return x + } + return y +} diff --git a/vendor/github.com/sergi/go-diff/diffmatchpatch/patch.go b/vendor/github.com/sergi/go-diff/diffmatchpatch/patch.go new file mode 100644 index 00000000000..223c43c4268 --- /dev/null +++ b/vendor/github.com/sergi/go-diff/diffmatchpatch/patch.go @@ -0,0 +1,556 @@ +// Copyright (c) 2012-2016 The go-diff authors. All rights reserved. +// https://github.com/sergi/go-diff +// See the included LICENSE file for license details. +// +// go-diff is a Go implementation of Google's Diff, Match, and Patch library +// Original library is Copyright (c) 2006 Google Inc. +// http://code.google.com/p/google-diff-match-patch/ + +package diffmatchpatch + +import ( + "bytes" + "errors" + "math" + "net/url" + "regexp" + "strconv" + "strings" +) + +// Patch represents one patch operation. +type Patch struct { + diffs []Diff + Start1 int + Start2 int + Length1 int + Length2 int +} + +// String emulates GNU diff's format. +// Header: @@ -382,8 +481,9 @@ +// Indices are printed as 1-based, not 0-based. +func (p *Patch) String() string { + var coords1, coords2 string + + if p.Length1 == 0 { + coords1 = strconv.Itoa(p.Start1) + ",0" + } else if p.Length1 == 1 { + coords1 = strconv.Itoa(p.Start1 + 1) + } else { + coords1 = strconv.Itoa(p.Start1+1) + "," + strconv.Itoa(p.Length1) + } + + if p.Length2 == 0 { + coords2 = strconv.Itoa(p.Start2) + ",0" + } else if p.Length2 == 1 { + coords2 = strconv.Itoa(p.Start2 + 1) + } else { + coords2 = strconv.Itoa(p.Start2+1) + "," + strconv.Itoa(p.Length2) + } + + var text bytes.Buffer + _, _ = text.WriteString("@@ -" + coords1 + " +" + coords2 + " @@\n") + + // Escape the body of the patch with %xx notation. + for _, aDiff := range p.diffs { + switch aDiff.Type { + case DiffInsert: + _, _ = text.WriteString("+") + case DiffDelete: + _, _ = text.WriteString("-") + case DiffEqual: + _, _ = text.WriteString(" ") + } + + _, _ = text.WriteString(strings.Replace(url.QueryEscape(aDiff.Text), "+", " ", -1)) + _, _ = text.WriteString("\n") + } + + return unescaper.Replace(text.String()) +} + +// PatchAddContext increases the context until it is unique, but doesn't let the pattern expand beyond MatchMaxBits. +func (dmp *DiffMatchPatch) PatchAddContext(patch Patch, text string) Patch { + if len(text) == 0 { + return patch + } + + pattern := text[patch.Start2 : patch.Start2+patch.Length1] + padding := 0 + + // Look for the first and last matches of pattern in text. If two different matches are found, increase the pattern length. + for strings.Index(text, pattern) != strings.LastIndex(text, pattern) && + len(pattern) < dmp.MatchMaxBits-2*dmp.PatchMargin { + padding += dmp.PatchMargin + maxStart := max(0, patch.Start2-padding) + minEnd := min(len(text), patch.Start2+patch.Length1+padding) + pattern = text[maxStart:minEnd] + } + // Add one chunk for good luck. + padding += dmp.PatchMargin + + // Add the prefix. + prefix := text[max(0, patch.Start2-padding):patch.Start2] + if len(prefix) != 0 { + patch.diffs = append([]Diff{Diff{DiffEqual, prefix}}, patch.diffs...) + } + // Add the suffix. + suffix := text[patch.Start2+patch.Length1 : min(len(text), patch.Start2+patch.Length1+padding)] + if len(suffix) != 0 { + patch.diffs = append(patch.diffs, Diff{DiffEqual, suffix}) + } + + // Roll back the start points. + patch.Start1 -= len(prefix) + patch.Start2 -= len(prefix) + // Extend the lengths. + patch.Length1 += len(prefix) + len(suffix) + patch.Length2 += len(prefix) + len(suffix) + + return patch +} + +// PatchMake computes a list of patches. +func (dmp *DiffMatchPatch) PatchMake(opt ...interface{}) []Patch { + if len(opt) == 1 { + diffs, _ := opt[0].([]Diff) + text1 := dmp.DiffText1(diffs) + return dmp.PatchMake(text1, diffs) + } else if len(opt) == 2 { + text1 := opt[0].(string) + switch t := opt[1].(type) { + case string: + diffs := dmp.DiffMain(text1, t, true) + if len(diffs) > 2 { + diffs = dmp.DiffCleanupSemantic(diffs) + diffs = dmp.DiffCleanupEfficiency(diffs) + } + return dmp.PatchMake(text1, diffs) + case []Diff: + return dmp.patchMake2(text1, t) + } + } else if len(opt) == 3 { + return dmp.PatchMake(opt[0], opt[2]) + } + return []Patch{} +} + +// patchMake2 computes a list of patches to turn text1 into text2. +// text2 is not provided, diffs are the delta between text1 and text2. +func (dmp *DiffMatchPatch) patchMake2(text1 string, diffs []Diff) []Patch { + // Check for null inputs not needed since null can't be passed in C#. + patches := []Patch{} + if len(diffs) == 0 { + return patches // Get rid of the null case. + } + + patch := Patch{} + charCount1 := 0 // Number of characters into the text1 string. + charCount2 := 0 // Number of characters into the text2 string. + // Start with text1 (prepatchText) and apply the diffs until we arrive at text2 (postpatchText). We recreate the patches one by one to determine context info. + prepatchText := text1 + postpatchText := text1 + + for i, aDiff := range diffs { + if len(patch.diffs) == 0 && aDiff.Type != DiffEqual { + // A new patch starts here. + patch.Start1 = charCount1 + patch.Start2 = charCount2 + } + + switch aDiff.Type { + case DiffInsert: + patch.diffs = append(patch.diffs, aDiff) + patch.Length2 += len(aDiff.Text) + postpatchText = postpatchText[:charCount2] + + aDiff.Text + postpatchText[charCount2:] + case DiffDelete: + patch.Length1 += len(aDiff.Text) + patch.diffs = append(patch.diffs, aDiff) + postpatchText = postpatchText[:charCount2] + postpatchText[charCount2+len(aDiff.Text):] + case DiffEqual: + if len(aDiff.Text) <= 2*dmp.PatchMargin && + len(patch.diffs) != 0 && i != len(diffs)-1 { + // Small equality inside a patch. + patch.diffs = append(patch.diffs, aDiff) + patch.Length1 += len(aDiff.Text) + patch.Length2 += len(aDiff.Text) + } + if len(aDiff.Text) >= 2*dmp.PatchMargin { + // Time for a new patch. + if len(patch.diffs) != 0 { + patch = dmp.PatchAddContext(patch, prepatchText) + patches = append(patches, patch) + patch = Patch{} + // Unlike Unidiff, our patch lists have a rolling context. http://code.google.com/p/google-diff-match-patch/wiki/Unidiff Update prepatch text & pos to reflect the application of the just completed patch. + prepatchText = postpatchText + charCount1 = charCount2 + } + } + } + + // Update the current character count. + if aDiff.Type != DiffInsert { + charCount1 += len(aDiff.Text) + } + if aDiff.Type != DiffDelete { + charCount2 += len(aDiff.Text) + } + } + + // Pick up the leftover patch if not empty. + if len(patch.diffs) != 0 { + patch = dmp.PatchAddContext(patch, prepatchText) + patches = append(patches, patch) + } + + return patches +} + +// PatchDeepCopy returns an array that is identical to a given an array of patches. +func (dmp *DiffMatchPatch) PatchDeepCopy(patches []Patch) []Patch { + patchesCopy := []Patch{} + for _, aPatch := range patches { + patchCopy := Patch{} + for _, aDiff := range aPatch.diffs { + patchCopy.diffs = append(patchCopy.diffs, Diff{ + aDiff.Type, + aDiff.Text, + }) + } + patchCopy.Start1 = aPatch.Start1 + patchCopy.Start2 = aPatch.Start2 + patchCopy.Length1 = aPatch.Length1 + patchCopy.Length2 = aPatch.Length2 + patchesCopy = append(patchesCopy, patchCopy) + } + return patchesCopy +} + +// PatchApply merges a set of patches onto the text. Returns a patched text, as well as an array of true/false values indicating which patches were applied. +func (dmp *DiffMatchPatch) PatchApply(patches []Patch, text string) (string, []bool) { + if len(patches) == 0 { + return text, []bool{} + } + + // Deep copy the patches so that no changes are made to originals. + patches = dmp.PatchDeepCopy(patches) + + nullPadding := dmp.PatchAddPadding(patches) + text = nullPadding + text + nullPadding + patches = dmp.PatchSplitMax(patches) + + x := 0 + // delta keeps track of the offset between the expected and actual location of the previous patch. If there are patches expected at positions 10 and 20, but the first patch was found at 12, delta is 2 and the second patch has an effective expected position of 22. + delta := 0 + results := make([]bool, len(patches)) + for _, aPatch := range patches { + expectedLoc := aPatch.Start2 + delta + text1 := dmp.DiffText1(aPatch.diffs) + var startLoc int + endLoc := -1 + if len(text1) > dmp.MatchMaxBits { + // PatchSplitMax will only provide an oversized pattern in the case of a monster delete. + startLoc = dmp.MatchMain(text, text1[:dmp.MatchMaxBits], expectedLoc) + if startLoc != -1 { + endLoc = dmp.MatchMain(text, + text1[len(text1)-dmp.MatchMaxBits:], expectedLoc+len(text1)-dmp.MatchMaxBits) + if endLoc == -1 || startLoc >= endLoc { + // Can't find valid trailing context. Drop this patch. + startLoc = -1 + } + } + } else { + startLoc = dmp.MatchMain(text, text1, expectedLoc) + } + if startLoc == -1 { + // No match found. :( + results[x] = false + // Subtract the delta for this failed patch from subsequent patches. + delta -= aPatch.Length2 - aPatch.Length1 + } else { + // Found a match. :) + results[x] = true + delta = startLoc - expectedLoc + var text2 string + if endLoc == -1 { + text2 = text[startLoc:int(math.Min(float64(startLoc+len(text1)), float64(len(text))))] + } else { + text2 = text[startLoc:int(math.Min(float64(endLoc+dmp.MatchMaxBits), float64(len(text))))] + } + if text1 == text2 { + // Perfect match, just shove the Replacement text in. + text = text[:startLoc] + dmp.DiffText2(aPatch.diffs) + text[startLoc+len(text1):] + } else { + // Imperfect match. Run a diff to get a framework of equivalent indices. + diffs := dmp.DiffMain(text1, text2, false) + if len(text1) > dmp.MatchMaxBits && float64(dmp.DiffLevenshtein(diffs))/float64(len(text1)) > dmp.PatchDeleteThreshold { + // The end points match, but the content is unacceptably bad. + results[x] = false + } else { + diffs = dmp.DiffCleanupSemanticLossless(diffs) + index1 := 0 + for _, aDiff := range aPatch.diffs { + if aDiff.Type != DiffEqual { + index2 := dmp.DiffXIndex(diffs, index1) + if aDiff.Type == DiffInsert { + // Insertion + text = text[:startLoc+index2] + aDiff.Text + text[startLoc+index2:] + } else if aDiff.Type == DiffDelete { + // Deletion + startIndex := startLoc + index2 + text = text[:startIndex] + + text[startIndex+dmp.DiffXIndex(diffs, index1+len(aDiff.Text))-index2:] + } + } + if aDiff.Type != DiffDelete { + index1 += len(aDiff.Text) + } + } + } + } + } + x++ + } + // Strip the padding off. + text = text[len(nullPadding) : len(nullPadding)+(len(text)-2*len(nullPadding))] + return text, results +} + +// PatchAddPadding adds some padding on text start and end so that edges can match something. +// Intended to be called only from within patchApply. +func (dmp *DiffMatchPatch) PatchAddPadding(patches []Patch) string { + paddingLength := dmp.PatchMargin + nullPadding := "" + for x := 1; x <= paddingLength; x++ { + nullPadding += string(x) + } + + // Bump all the patches forward. + for i := range patches { + patches[i].Start1 += paddingLength + patches[i].Start2 += paddingLength + } + + // Add some padding on start of first diff. + if len(patches[0].diffs) == 0 || patches[0].diffs[0].Type != DiffEqual { + // Add nullPadding equality. + patches[0].diffs = append([]Diff{Diff{DiffEqual, nullPadding}}, patches[0].diffs...) + patches[0].Start1 -= paddingLength // Should be 0. + patches[0].Start2 -= paddingLength // Should be 0. + patches[0].Length1 += paddingLength + patches[0].Length2 += paddingLength + } else if paddingLength > len(patches[0].diffs[0].Text) { + // Grow first equality. + extraLength := paddingLength - len(patches[0].diffs[0].Text) + patches[0].diffs[0].Text = nullPadding[len(patches[0].diffs[0].Text):] + patches[0].diffs[0].Text + patches[0].Start1 -= extraLength + patches[0].Start2 -= extraLength + patches[0].Length1 += extraLength + patches[0].Length2 += extraLength + } + + // Add some padding on end of last diff. + last := len(patches) - 1 + if len(patches[last].diffs) == 0 || patches[last].diffs[len(patches[last].diffs)-1].Type != DiffEqual { + // Add nullPadding equality. + patches[last].diffs = append(patches[last].diffs, Diff{DiffEqual, nullPadding}) + patches[last].Length1 += paddingLength + patches[last].Length2 += paddingLength + } else if paddingLength > len(patches[last].diffs[len(patches[last].diffs)-1].Text) { + // Grow last equality. + lastDiff := patches[last].diffs[len(patches[last].diffs)-1] + extraLength := paddingLength - len(lastDiff.Text) + patches[last].diffs[len(patches[last].diffs)-1].Text += nullPadding[:extraLength] + patches[last].Length1 += extraLength + patches[last].Length2 += extraLength + } + + return nullPadding +} + +// PatchSplitMax looks through the patches and breaks up any which are longer than the maximum limit of the match algorithm. +// Intended to be called only from within patchApply. +func (dmp *DiffMatchPatch) PatchSplitMax(patches []Patch) []Patch { + patchSize := dmp.MatchMaxBits + for x := 0; x < len(patches); x++ { + if patches[x].Length1 <= patchSize { + continue + } + bigpatch := patches[x] + // Remove the big old patch. + patches = append(patches[:x], patches[x+1:]...) + x-- + + Start1 := bigpatch.Start1 + Start2 := bigpatch.Start2 + precontext := "" + for len(bigpatch.diffs) != 0 { + // Create one of several smaller patches. + patch := Patch{} + empty := true + patch.Start1 = Start1 - len(precontext) + patch.Start2 = Start2 - len(precontext) + if len(precontext) != 0 { + patch.Length1 = len(precontext) + patch.Length2 = len(precontext) + patch.diffs = append(patch.diffs, Diff{DiffEqual, precontext}) + } + for len(bigpatch.diffs) != 0 && patch.Length1 < patchSize-dmp.PatchMargin { + diffType := bigpatch.diffs[0].Type + diffText := bigpatch.diffs[0].Text + if diffType == DiffInsert { + // Insertions are harmless. + patch.Length2 += len(diffText) + Start2 += len(diffText) + patch.diffs = append(patch.diffs, bigpatch.diffs[0]) + bigpatch.diffs = bigpatch.diffs[1:] + empty = false + } else if diffType == DiffDelete && len(patch.diffs) == 1 && patch.diffs[0].Type == DiffEqual && len(diffText) > 2*patchSize { + // This is a large deletion. Let it pass in one chunk. + patch.Length1 += len(diffText) + Start1 += len(diffText) + empty = false + patch.diffs = append(patch.diffs, Diff{diffType, diffText}) + bigpatch.diffs = bigpatch.diffs[1:] + } else { + // Deletion or equality. Only take as much as we can stomach. + diffText = diffText[:min(len(diffText), patchSize-patch.Length1-dmp.PatchMargin)] + + patch.Length1 += len(diffText) + Start1 += len(diffText) + if diffType == DiffEqual { + patch.Length2 += len(diffText) + Start2 += len(diffText) + } else { + empty = false + } + patch.diffs = append(patch.diffs, Diff{diffType, diffText}) + if diffText == bigpatch.diffs[0].Text { + bigpatch.diffs = bigpatch.diffs[1:] + } else { + bigpatch.diffs[0].Text = + bigpatch.diffs[0].Text[len(diffText):] + } + } + } + // Compute the head context for the next patch. + precontext = dmp.DiffText2(patch.diffs) + precontext = precontext[max(0, len(precontext)-dmp.PatchMargin):] + + postcontext := "" + // Append the end context for this patch. + if len(dmp.DiffText1(bigpatch.diffs)) > dmp.PatchMargin { + postcontext = dmp.DiffText1(bigpatch.diffs)[:dmp.PatchMargin] + } else { + postcontext = dmp.DiffText1(bigpatch.diffs) + } + + if len(postcontext) != 0 { + patch.Length1 += len(postcontext) + patch.Length2 += len(postcontext) + if len(patch.diffs) != 0 && patch.diffs[len(patch.diffs)-1].Type == DiffEqual { + patch.diffs[len(patch.diffs)-1].Text += postcontext + } else { + patch.diffs = append(patch.diffs, Diff{DiffEqual, postcontext}) + } + } + if !empty { + x++ + patches = append(patches[:x], append([]Patch{patch}, patches[x:]...)...) + } + } + } + return patches +} + +// PatchToText takes a list of patches and returns a textual representation. +func (dmp *DiffMatchPatch) PatchToText(patches []Patch) string { + var text bytes.Buffer + for _, aPatch := range patches { + _, _ = text.WriteString(aPatch.String()) + } + return text.String() +} + +// PatchFromText parses a textual representation of patches and returns a List of Patch objects. +func (dmp *DiffMatchPatch) PatchFromText(textline string) ([]Patch, error) { + patches := []Patch{} + if len(textline) == 0 { + return patches, nil + } + text := strings.Split(textline, "\n") + textPointer := 0 + patchHeader := regexp.MustCompile("^@@ -(\\d+),?(\\d*) \\+(\\d+),?(\\d*) @@$") + + var patch Patch + var sign uint8 + var line string + for textPointer < len(text) { + + if !patchHeader.MatchString(text[textPointer]) { + return patches, errors.New("Invalid patch string: " + text[textPointer]) + } + + patch = Patch{} + m := patchHeader.FindStringSubmatch(text[textPointer]) + + patch.Start1, _ = strconv.Atoi(m[1]) + if len(m[2]) == 0 { + patch.Start1-- + patch.Length1 = 1 + } else if m[2] == "0" { + patch.Length1 = 0 + } else { + patch.Start1-- + patch.Length1, _ = strconv.Atoi(m[2]) + } + + patch.Start2, _ = strconv.Atoi(m[3]) + + if len(m[4]) == 0 { + patch.Start2-- + patch.Length2 = 1 + } else if m[4] == "0" { + patch.Length2 = 0 + } else { + patch.Start2-- + patch.Length2, _ = strconv.Atoi(m[4]) + } + textPointer++ + + for textPointer < len(text) { + if len(text[textPointer]) > 0 { + sign = text[textPointer][0] + } else { + textPointer++ + continue + } + + line = text[textPointer][1:] + line = strings.Replace(line, "+", "%2b", -1) + line, _ = url.QueryUnescape(line) + if sign == '-' { + // Deletion. + patch.diffs = append(patch.diffs, Diff{DiffDelete, line}) + } else if sign == '+' { + // Insertion. + patch.diffs = append(patch.diffs, Diff{DiffInsert, line}) + } else if sign == ' ' { + // Minor equality. + patch.diffs = append(patch.diffs, Diff{DiffEqual, line}) + } else if sign == '@' { + // Start of next patch. + break + } else { + // WTF? + return patches, errors.New("Invalid patch mode '" + string(sign) + "' in: " + string(line)) + } + textPointer++ + } + + patches = append(patches, patch) + } + return patches, nil +} diff --git a/vendor/github.com/sergi/go-diff/diffmatchpatch/stringutil.go b/vendor/github.com/sergi/go-diff/diffmatchpatch/stringutil.go new file mode 100644 index 00000000000..265f29cc7e5 --- /dev/null +++ b/vendor/github.com/sergi/go-diff/diffmatchpatch/stringutil.go @@ -0,0 +1,88 @@ +// Copyright (c) 2012-2016 The go-diff authors. All rights reserved. +// https://github.com/sergi/go-diff +// See the included LICENSE file for license details. +// +// go-diff is a Go implementation of Google's Diff, Match, and Patch library +// Original library is Copyright (c) 2006 Google Inc. +// http://code.google.com/p/google-diff-match-patch/ + +package diffmatchpatch + +import ( + "strings" + "unicode/utf8" +) + +// unescaper unescapes selected chars for compatibility with JavaScript's encodeURI. +// In speed critical applications this could be dropped since the receiving application will certainly decode these fine. Note that this function is case-sensitive. Thus "%3F" would not be unescaped. But this is ok because it is only called with the output of HttpUtility.UrlEncode which returns lowercase hex. Example: "%3f" -> "?", "%24" -> "$", etc. +var unescaper = strings.NewReplacer( + "%21", "!", "%7E", "~", "%27", "'", + "%28", "(", "%29", ")", "%3B", ";", + "%2F", "/", "%3F", "?", "%3A", ":", + "%40", "@", "%26", "&", "%3D", "=", + "%2B", "+", "%24", "$", "%2C", ",", "%23", "#", "%2A", "*") + +// indexOf returns the first index of pattern in str, starting at str[i]. +func indexOf(str string, pattern string, i int) int { + if i > len(str)-1 { + return -1 + } + if i <= 0 { + return strings.Index(str, pattern) + } + ind := strings.Index(str[i:], pattern) + if ind == -1 { + return -1 + } + return ind + i +} + +// lastIndexOf returns the last index of pattern in str, starting at str[i]. +func lastIndexOf(str string, pattern string, i int) int { + if i < 0 { + return -1 + } + if i >= len(str) { + return strings.LastIndex(str, pattern) + } + _, size := utf8.DecodeRuneInString(str[i:]) + return strings.LastIndex(str[:i+size], pattern) +} + +// runesIndexOf returns the index of pattern in target, starting at target[i]. +func runesIndexOf(target, pattern []rune, i int) int { + if i > len(target)-1 { + return -1 + } + if i <= 0 { + return runesIndex(target, pattern) + } + ind := runesIndex(target[i:], pattern) + if ind == -1 { + return -1 + } + return ind + i +} + +func runesEqual(r1, r2 []rune) bool { + if len(r1) != len(r2) { + return false + } + for i, c := range r1 { + if c != r2[i] { + return false + } + } + return true +} + +// runesIndex is the equivalent of strings.Index for rune slices. +func runesIndex(r1, r2 []rune) int { + last := len(r1) - len(r2) + for i := 0; i <= last; i++ { + if runesEqual(r1[i:i+len(r2)], r2) { + return i + } + } + return -1 +}