Merge pull request #74904 from sttts/sttts-proto-tests

Rework proto generation scripts and add tests
pull/564/head
Kubernetes Prow Robot 2019-03-07 10:58:05 -08:00 committed by GitHub
commit f8024ab087
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
74 changed files with 1720 additions and 59 deletions

14
Godeps/Godeps.json generated
View File

@ -1,6 +1,6 @@
{
"ImportPath": "k8s.io/kubernetes",
"GoVersion": "go1.11",
"GoVersion": "go1.12",
"GodepVersion": "v80-k8s-r1",
"Packages": [
"github.com/bazelbuild/bazel-gazelle/cmd/gazelle",
@ -3884,6 +3884,10 @@
"ImportPath": "gonum.org/v1/gonum/graph/formats/dot/internal/token",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/graph/internal/linear",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/graph/internal/ordered",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
@ -3900,6 +3904,14 @@
"ImportPath": "gonum.org/v1/gonum/graph/simple",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/graph/topo",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/graph/traverse",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/internal/asm/c128",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"

90
Godeps/LICENSES generated
View File

@ -103221,6 +103221,36 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================================================
================================================================================
= vendor/gonum.org/v1/gonum/graph/internal/linear licensed under: =
Copyright ©2013 The Gonum Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the gonum project nor the names of its authors and
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
= vendor/gonum.org/v1/gonum/LICENSE 665e67d07d85e236cceb8de602c6255a
================================================================================
================================================================================
= vendor/gonum.org/v1/gonum/graph/internal/ordered licensed under: =
@ -103341,6 +103371,66 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================================================
================================================================================
= vendor/gonum.org/v1/gonum/graph/topo licensed under: =
Copyright ©2013 The Gonum Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the gonum project nor the names of its authors and
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
= vendor/gonum.org/v1/gonum/LICENSE 665e67d07d85e236cceb8de602c6255a
================================================================================
================================================================================
= vendor/gonum.org/v1/gonum/graph/traverse licensed under: =
Copyright ©2013 The Gonum Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the gonum project nor the names of its authors and
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
= vendor/gonum.org/v1/gonum/LICENSE 665e67d07d85e236cceb8de602c6255a
================================================================================
================================================================================
= vendor/gonum.org/v1/gonum/internal/asm/c128 licensed under: =

View File

@ -41,57 +41,8 @@ fi
gotoprotobuf=$(kube::util::find-binary "go-to-protobuf")
PACKAGES=(
k8s.io/apiserver/pkg/apis/example/v1
k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1
k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1
k8s.io/kube-aggregator/pkg/apis/apiregistration/v1
k8s.io/api/core/v1
k8s.io/api/policy/v1beta1
k8s.io/api/extensions/v1beta1
k8s.io/api/autoscaling/v1
k8s.io/api/authorization/v1
k8s.io/api/autoscaling/v2beta1
k8s.io/api/autoscaling/v2beta2
k8s.io/api/authorization/v1beta1
k8s.io/api/batch/v1
k8s.io/api/batch/v1beta1
k8s.io/api/batch/v2alpha1
k8s.io/api/apps/v1beta1
k8s.io/api/apps/v1beta2
k8s.io/api/apps/v1
k8s.io/api/authentication/v1
k8s.io/api/authentication/v1beta1
k8s.io/api/events/v1beta1
k8s.io/api/rbac/v1alpha1
k8s.io/api/rbac/v1beta1
k8s.io/api/rbac/v1
k8s.io/api/certificates/v1beta1
k8s.io/api/coordination/v1beta1
k8s.io/api/coordination/v1
k8s.io/api/imagepolicy/v1alpha1
k8s.io/api/scheduling/v1alpha1
k8s.io/api/scheduling/v1beta1
k8s.io/api/scheduling/v1
k8s.io/api/settings/v1alpha1
k8s.io/api/storage/v1alpha1
k8s.io/api/storage/v1beta1
k8s.io/api/storage/v1
k8s.io/api/admissionregistration/v1beta1
k8s.io/api/admission/v1beta1
k8s.io/api/auditregistration/v1alpha1
k8s.io/api/networking/v1beta1
k8s.io/api/networking/v1
k8s.io/metrics/pkg/apis/metrics/v1alpha1
k8s.io/metrics/pkg/apis/metrics/v1beta1
k8s.io/metrics/pkg/apis/custom_metrics/v1beta1
k8s.io/metrics/pkg/apis/custom_metrics/v1beta2
k8s.io/metrics/pkg/apis/external_metrics/v1beta1
k8s.io/apiserver/pkg/apis/audit/v1alpha1
k8s.io/apiserver/pkg/apis/audit/v1beta1
k8s.io/apiserver/pkg/apis/audit/v1
k8s.io/apiserver/pkg/apis/example2/v1
)
APIROOTS=( ${1} )
shift
# requires the 'proto' tag to build (will remove when ready)
# searches for the protoc-gen-gogo extension in the output directory
@ -101,6 +52,6 @@ PATH="${KUBE_ROOT}/_output/bin:${PATH}" \
"${gotoprotobuf}" \
--proto-import="${KUBE_ROOT}/vendor" \
--proto-import="${KUBE_ROOT}/third_party/protobuf" \
--packages=$(IFS=, ; echo "${PACKAGES[*]}") \
--packages=$(IFS=, ; echo "${APIROOTS[*]}") \
--go-header-file ${KUBE_ROOT}/hack/boilerplate/boilerplate.generatego.txt \
"$@"

View File

@ -24,6 +24,12 @@ KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
# source tree. This is managed in kube::build::copy_output in build/common.sh.
# If the output set is changed update that function.
"${KUBE_ROOT}/build/run.sh" hack/update-generated-protobuf-dockerized.sh "$@"
APIROOTS=${APIROOTS:-$(git grep --files-with-matches -e '// +k8s:protobuf-gen=package' cmd pkg staging | \
xargs -n 1 dirname | \
sed 's,^,k8s.io/kubernetes/,;s,k8s.io/kubernetes/staging/src/,,' | \
sort | uniq
)}
"${KUBE_ROOT}/build/run.sh" hack/update-generated-protobuf-dockerized.sh "${APIROOTS}" "$@"
# ex: ts=2 sw=2 et filetype=sh

View File

@ -23,7 +23,8 @@ source "${KUBE_ROOT}/hack/lib/init.sh"
kube::golang::setup_env
APIROOTS=${APIROOTS:-pkg/api pkg/apis pkg/watch staging/src/k8s.io/apimachinery/pkg/api staging/src/k8s.io/apimachinery/pkg/apis staging/src/k8s.io/apiserver/pkg staging/src/k8s.io/api staging/src/k8s.io/metrics/pkg/apis}
APIROOTS=$(git grep --files-with-matches -e '// +k8s:protobuf-gen=package' cmd pkg staging | xargs -n 1 dirname | sort | uniq)
_tmp="${KUBE_ROOT}/_tmp"
cleanup() {

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=false
// +groupName=admission.k8s.io

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
// +groupName=admissionregistration.k8s.io

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
package v1 // import "k8s.io/api/apps/v1"

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
package v1beta1 // import "k8s.io/api/apps/v1beta1"

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
package v1beta2 // import "k8s.io/api/apps/v1beta2"

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
// +groupName=auditregistration.k8s.io

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +groupName=authentication.k8s.io
// +k8s:openapi-gen=true

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +groupName=authentication.k8s.io
// +k8s:openapi-gen=true

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
// +groupName=authorization.k8s.io

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
// +groupName=authorization.k8s.io

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
package v1 // import "k8s.io/api/autoscaling/v1"

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
package v2beta1 // import "k8s.io/api/autoscaling/v2beta1"

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
package v2beta2 // import "k8s.io/api/autoscaling/v2beta2"

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
package v1 // import "k8s.io/api/batch/v1"

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
package v1beta1 // import "k8s.io/api/batch/v1beta1"

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
package v2alpha1 // import "k8s.io/api/batch/v2alpha1"

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
// +groupName=certificates.k8s.io

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
// +groupName=coordination.k8s.io

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
// +groupName=coordination.k8s.io

View File

@ -16,6 +16,7 @@ limitations under the License.
// +k8s:openapi-gen=true
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// Package v1 is the v1 version of the core API.
package v1 // import "k8s.io/api/core/v1"

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
// +groupName=events.k8s.io

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
package v1beta1 // import "k8s.io/api/extensions/v1beta1"

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
// +groupName=imagepolicy.k8s.io

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
// +groupName=networking.k8s.io

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
// +groupName=networking.k8s.io

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
// Package policy is for any kind of policy object. Suitable examples, even if

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
// +groupName=rbac.authorization.k8s.io

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
// +groupName=rbac.authorization.k8s.io

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
// +groupName=rbac.authorization.k8s.io

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
// +groupName=scheduling.k8s.io

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
// +groupName=scheduling.k8s.io

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
// +groupName=scheduling.k8s.io

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
// +groupName=settings.k8s.io

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +groupName=storage.k8s.io
// +k8s:openapi-gen=true

View File

@ -14,7 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// +k8s:deepcopy-gen=package,register
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +groupName=storage.k8s.io
// +k8s:openapi-gen=true

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +groupName=storage.k8s.io
// +k8s:openapi-gen=true

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:conversion-gen=k8s.io/apiextensions-apiserver/pkg/apis/apiextensions
// +k8s:defaulter-gen=TypeMeta
// +k8s:openapi-gen=true

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:conversion-gen=k8s.io/apiserver/pkg/apis/audit
// +k8s:openapi-gen=true
// +k8s:defaulter-gen=TypeMeta

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:conversion-gen=k8s.io/apiserver/pkg/apis/audit
// +k8s:openapi-gen=true
// +k8s:defaulter-gen=TypeMeta

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:conversion-gen=k8s.io/apiserver/pkg/apis/audit
// +k8s:openapi-gen=true
// +k8s:defaulter-gen=TypeMeta

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:conversion-gen=k8s.io/apiserver/pkg/apis/example
// +k8s:openapi-gen=false
// +k8s:defaulter-gen=TypeMeta

View File

@ -154,6 +154,86 @@
"ImportPath": "golang.org/x/tools/internal/semver",
"Rev": "7f7074d5bcfd282eb16bc382b0bb3da762461985"
},
{
"ImportPath": "gonum.org/v1/gonum/blas",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/blas/blas64",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/blas/gonum",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/floats",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/graph",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/graph/internal/linear",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/graph/internal/ordered",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/graph/internal/set",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/graph/internal/uid",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/graph/simple",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/graph/topo",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/graph/traverse",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/internal/asm/c128",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/internal/asm/f32",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/internal/asm/f64",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/internal/math32",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/lapack",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/lapack/gonum",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/lapack/lapack64",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "gonum.org/v1/gonum/mat",
"Rev": "cebdade430ccb61c1feba4878085f6cf8cb3320e"
},
{
"ImportPath": "k8s.io/gengo/args",
"Rev": "51747d6e00da1fc578d5a333a93bb2abcbce7a95"

View File

@ -23,6 +23,9 @@ go_library(
"//staging/src/k8s.io/code-generator/pkg/util:go_default_library",
"//staging/src/k8s.io/code-generator/third_party/forked/golang/reflect:go_default_library",
"//vendor/github.com/spf13/pflag:go_default_library",
"//vendor/gonum.org/v1/gonum/graph:go_default_library",
"//vendor/gonum.org/v1/gonum/graph/simple:go_default_library",
"//vendor/gonum.org/v1/gonum/graph/topo:go_default_library",
"//vendor/k8s.io/gengo/args:go_default_library",
"//vendor/k8s.io/gengo/generator:go_default_library",
"//vendor/k8s.io/gengo/namer:go_default_library",

View File

@ -25,16 +25,20 @@ import (
"os"
"os/exec"
"path/filepath"
"sort"
"strings"
flag "github.com/spf13/pflag"
"gonum.org/v1/gonum/graph"
"gonum.org/v1/gonum/graph/simple"
"gonum.org/v1/gonum/graph/topo"
"k8s.io/code-generator/pkg/util"
"k8s.io/gengo/args"
"k8s.io/gengo/generator"
"k8s.io/gengo/namer"
"k8s.io/gengo/parser"
"k8s.io/gengo/types"
flag "github.com/spf13/pflag"
)
type Generator struct {
@ -202,6 +206,18 @@ func Run(g *Generator) {
c.Verify = g.Common.VerifyOnly
c.FileTypes["protoidl"] = NewProtoFile()
// order package by imports, importees first
deps := deps(c, protobufNames.packages)
order, err := importOrder(deps)
if err != nil {
log.Fatalf("Failed to order packages by imports: %v", err)
}
topologicalPos := map[string]int{}
for i, p := range order {
topologicalPos[p] = i
}
sort.Sort(positionOrder{topologicalPos, protobufNames.packages})
var vendoredOutputPackages, localOutputPackages generator.Packages
for _, p := range protobufNames.packages {
if _, ok := nonOutputPackages[p.Name()]; ok {
@ -347,3 +363,66 @@ func Run(g *Generator) {
}
}
}
func deps(c *generator.Context, pkgs []*protobufPackage) map[string][]string {
ret := map[string][]string{}
for _, p := range pkgs {
for _, d := range c.Universe[p.PackagePath].Imports {
ret[p.PackagePath] = append(ret[p.PackagePath], d.Path)
}
}
return ret
}
func importOrder(deps map[string][]string) ([]string, error) {
nodes := map[string]graph.Node{}
names := map[int64]string{}
g := simple.NewDirectedGraph()
for pkg, imports := range deps {
for _, imp := range imports {
if _, found := nodes[pkg]; !found {
n := g.NewNode()
g.AddNode(n)
nodes[pkg] = n
names[n.ID()] = pkg
}
if _, found := nodes[imp]; !found {
n := g.NewNode()
g.AddNode(n)
nodes[imp] = n
names[n.ID()] = imp
}
g.SetEdge(g.NewEdge(nodes[imp], nodes[pkg]))
}
}
ret := []string{}
sorted, err := topo.Sort(g)
if err != nil {
return nil, err
}
for _, n := range sorted {
ret = append(ret, names[n.ID()])
fmt.Println("topological order", names[n.ID()])
}
return ret, nil
}
type positionOrder struct {
pos map[string]int
elements []*protobufPackage
}
func (o positionOrder) Len() int {
return len(o.elements)
}
func (o positionOrder) Less(i, j int) bool {
return o.pos[o.elements[i].PackagePath] < o.pos[o.elements[j].PackagePath]
}
func (o positionOrder) Swap(i, j int) {
x := o.elements[i]
o.elements[i] = o.elements[j]
o.elements[j] = x
}

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// +k8s:deepcopy-gen=package,register
// +k8s:deepcopy-gen=package
// +groupName=csi.storage.k8s.io
// +k8s:openapi-gen=true

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:conversion-gen=k8s.io/kube-aggregator/pkg/apis/apiregistration
// +k8s:openapi-gen=true
// +groupName=apiregistration.k8s.io

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:conversion-gen=k8s.io/kube-aggregator/pkg/apis/apiregistration
// +k8s:openapi-gen=true
// +groupName=apiregistration.k8s.io

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:conversion-gen=k8s.io/metrics/pkg/apis/custom_metrics
// +k8s:openapi-gen=true

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:conversion-gen=k8s.io/metrics/pkg/apis/custom_metrics
// +k8s:openapi-gen=true

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:conversion-gen=k8s.io/metrics/pkg/apis/external_metrics
// +k8s:openapi-gen=true

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:conversion-gen=k8s.io/metrics/pkg/apis/metrics
// +k8s:openapi-gen=true

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:conversion-gen=k8s.io/metrics/pkg/apis/metrics
// +k8s:openapi-gen=true

View File

@ -26,10 +26,13 @@ filegroup(
":package-srcs",
"//vendor/gonum.org/v1/gonum/graph/encoding:all-srcs",
"//vendor/gonum.org/v1/gonum/graph/formats/dot:all-srcs",
"//vendor/gonum.org/v1/gonum/graph/internal/linear:all-srcs",
"//vendor/gonum.org/v1/gonum/graph/internal/ordered:all-srcs",
"//vendor/gonum.org/v1/gonum/graph/internal/set:all-srcs",
"//vendor/gonum.org/v1/gonum/graph/internal/uid:all-srcs",
"//vendor/gonum.org/v1/gonum/graph/simple:all-srcs",
"//vendor/gonum.org/v1/gonum/graph/topo:all-srcs",
"//vendor/gonum.org/v1/gonum/graph/traverse:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],

27
vendor/gonum.org/v1/gonum/graph/internal/linear/BUILD generated vendored Normal file
View File

@ -0,0 +1,27 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"linear.go",
],
importmap = "k8s.io/kubernetes/vendor/gonum.org/v1/gonum/graph/internal/linear",
importpath = "gonum.org/v1/gonum/graph/internal/linear",
visibility = ["//vendor/gonum.org/v1/gonum/graph:__subpackages__"],
deps = ["//vendor/gonum.org/v1/gonum/graph:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,6 @@
// Copyright ©2017 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package linear provides common linear data structures.
package linear

View File

@ -0,0 +1,73 @@
// Copyright ©2015 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package linear
import (
"gonum.org/v1/gonum/graph"
)
// NodeStack implements a LIFO stack of graph.Node.
type NodeStack []graph.Node
// Len returns the number of graph.Nodes on the stack.
func (s *NodeStack) Len() int { return len(*s) }
// Pop returns the last graph.Node on the stack and removes it
// from the stack.
func (s *NodeStack) Pop() graph.Node {
v := *s
v, n := v[:len(v)-1], v[len(v)-1]
*s = v
return n
}
// Push adds the node n to the stack at the last position.
func (s *NodeStack) Push(n graph.Node) { *s = append(*s, n) }
// NodeQueue implements a FIFO queue.
type NodeQueue struct {
head int
data []graph.Node
}
// Len returns the number of graph.Nodes in the queue.
func (q *NodeQueue) Len() int { return len(q.data) - q.head }
// Enqueue adds the node n to the back of the queue.
func (q *NodeQueue) Enqueue(n graph.Node) {
if len(q.data) == cap(q.data) && q.head > 0 {
l := q.Len()
copy(q.data, q.data[q.head:])
q.head = 0
q.data = append(q.data[:l], n)
} else {
q.data = append(q.data, n)
}
}
// Dequeue returns the graph.Node at the front of the queue and
// removes it from the queue.
func (q *NodeQueue) Dequeue() graph.Node {
if q.Len() == 0 {
panic("queue: empty queue")
}
var n graph.Node
n, q.data[q.head] = q.data[q.head], nil
q.head++
if q.Len() == 0 {
q.head = 0
q.data = q.data[:0]
}
return n
}
// Reset clears the queue for reuse.
func (q *NodeQueue) Reset() {
q.head = 0
q.data = q.data[:0]
}

39
vendor/gonum.org/v1/gonum/graph/topo/BUILD generated vendored Normal file
View File

@ -0,0 +1,39 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"bron_kerbosch.go",
"clique_graph.go",
"doc.go",
"johnson_cycles.go",
"non_tomita_choice.go",
"paton_cycles.go",
"tarjan.go",
"topo.go",
],
importmap = "k8s.io/kubernetes/vendor/gonum.org/v1/gonum/graph/topo",
importpath = "gonum.org/v1/gonum/graph/topo",
visibility = ["//visibility:public"],
deps = [
"//vendor/gonum.org/v1/gonum/graph:go_default_library",
"//vendor/gonum.org/v1/gonum/graph/internal/linear:go_default_library",
"//vendor/gonum.org/v1/gonum/graph/internal/ordered:go_default_library",
"//vendor/gonum.org/v1/gonum/graph/internal/set:go_default_library",
"//vendor/gonum.org/v1/gonum/graph/traverse:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

250
vendor/gonum.org/v1/gonum/graph/topo/bron_kerbosch.go generated vendored Normal file
View File

@ -0,0 +1,250 @@
// Copyright ©2015 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package topo
import (
"gonum.org/v1/gonum/graph"
"gonum.org/v1/gonum/graph/internal/ordered"
"gonum.org/v1/gonum/graph/internal/set"
)
// DegeneracyOrdering returns the degeneracy ordering and the k-cores of
// the undirected graph g.
func DegeneracyOrdering(g graph.Undirected) (order []graph.Node, cores [][]graph.Node) {
order, offsets := degeneracyOrdering(g)
ordered.Reverse(order)
cores = make([][]graph.Node, len(offsets))
offset := len(order)
for i, n := range offsets {
cores[i] = order[offset-n : offset]
offset -= n
}
return order, cores
}
// KCore returns the k-core of the undirected graph g with nodes in an
// optimal ordering for the coloring number.
func KCore(k int, g graph.Undirected) []graph.Node {
order, offsets := degeneracyOrdering(g)
var offset int
for _, n := range offsets[:k] {
offset += n
}
core := make([]graph.Node, len(order)-offset)
copy(core, order[offset:])
return core
}
// degeneracyOrdering is the common code for DegeneracyOrdering and KCore. It
// returns l, the nodes of g in optimal ordering for coloring number and
// s, a set of relative offsets into l for each k-core, where k is an index
// into s.
func degeneracyOrdering(g graph.Undirected) (l []graph.Node, s []int) {
nodes := g.Nodes()
// The algorithm used here is essentially as described at
// http://en.wikipedia.org/w/index.php?title=Degeneracy_%28graph_theory%29&oldid=640308710
// Initialize an output list L in return parameters.
// Compute a number d_v for each vertex v in G,
// the number of neighbors of v that are not already in L.
// Initially, these numbers are just the degrees of the vertices.
dv := make(map[int64]int, len(nodes))
var (
maxDegree int
neighbours = make(map[int64][]graph.Node)
)
for _, n := range nodes {
id := n.ID()
adj := g.From(id)
neighbours[id] = adj
dv[id] = len(adj)
if len(adj) > maxDegree {
maxDegree = len(adj)
}
}
// Initialize an array D such that D[i] contains a list of the
// vertices v that are not already in L for which d_v = i.
d := make([][]graph.Node, maxDegree+1)
for _, n := range nodes {
deg := dv[n.ID()]
d[deg] = append(d[deg], n)
}
// Initialize k to 0.
k := 0
// Repeat n times:
s = []int{0}
for range nodes {
// Scan the array cells D[0], D[1], ... until
// finding an i for which D[i] is nonempty.
var (
i int
di []graph.Node
)
for i, di = range d {
if len(di) != 0 {
break
}
}
// Set k to max(k,i).
if i > k {
k = i
s = append(s, make([]int, k-len(s)+1)...)
}
// Select a vertex v from D[i]. Add v to the
// beginning of L and remove it from D[i].
var v graph.Node
v, d[i] = di[len(di)-1], di[:len(di)-1]
l = append(l, v)
s[k]++
delete(dv, v.ID())
// For each neighbor w of v not already in L,
// subtract one from d_w and move w to the
// cell of D corresponding to the new value of d_w.
for _, w := range neighbours[v.ID()] {
dw, ok := dv[w.ID()]
if !ok {
continue
}
for i, n := range d[dw] {
if n.ID() == w.ID() {
d[dw][i], d[dw] = d[dw][len(d[dw])-1], d[dw][:len(d[dw])-1]
dw--
d[dw] = append(d[dw], w)
break
}
}
dv[w.ID()] = dw
}
}
return l, s
}
// BronKerbosch returns the set of maximal cliques of the undirected graph g.
func BronKerbosch(g graph.Undirected) [][]graph.Node {
nodes := g.Nodes()
// The algorithm used here is essentially BronKerbosch3 as described at
// http://en.wikipedia.org/w/index.php?title=Bron%E2%80%93Kerbosch_algorithm&oldid=656805858
p := make(set.Nodes, len(nodes))
for _, n := range nodes {
p.Add(n)
}
x := make(set.Nodes)
var bk bronKerbosch
order, _ := degeneracyOrdering(g)
ordered.Reverse(order)
for _, v := range order {
neighbours := g.From(v.ID())
nv := make(set.Nodes, len(neighbours))
for _, n := range neighbours {
nv.Add(n)
}
bk.maximalCliquePivot(g, []graph.Node{v}, make(set.Nodes).Intersect(p, nv), make(set.Nodes).Intersect(x, nv))
p.Remove(v)
x.Add(v)
}
return bk
}
type bronKerbosch [][]graph.Node
func (bk *bronKerbosch) maximalCliquePivot(g graph.Undirected, r []graph.Node, p, x set.Nodes) {
if len(p) == 0 && len(x) == 0 {
*bk = append(*bk, r)
return
}
neighbours := bk.choosePivotFrom(g, p, x)
nu := make(set.Nodes, len(neighbours))
for _, n := range neighbours {
nu.Add(n)
}
for _, v := range p {
if nu.Has(v) {
continue
}
vid := v.ID()
neighbours := g.From(vid)
nv := make(set.Nodes, len(neighbours))
for _, n := range neighbours {
nv.Add(n)
}
var found bool
for _, n := range r {
if n.ID() == vid {
found = true
break
}
}
var sr []graph.Node
if !found {
sr = append(r[:len(r):len(r)], v)
}
bk.maximalCliquePivot(g, sr, make(set.Nodes).Intersect(p, nv), make(set.Nodes).Intersect(x, nv))
p.Remove(v)
x.Add(v)
}
}
func (*bronKerbosch) choosePivotFrom(g graph.Undirected, p, x set.Nodes) (neighbors []graph.Node) {
// TODO(kortschak): Investigate the impact of pivot choice that maximises
// |p ⋂ neighbours(u)| as a function of input size. Until then, leave as
// compile time option.
if !tomitaTanakaTakahashi {
for _, n := range p {
return g.From(n.ID())
}
for _, n := range x {
return g.From(n.ID())
}
panic("bronKerbosch: empty set")
}
var (
max = -1
pivot graph.Node
)
maxNeighbors := func(s set.Nodes) {
outer:
for _, u := range s {
nb := g.From(u.ID())
c := len(nb)
if c <= max {
continue
}
for n := range nb {
if _, ok := p[int64(n)]; ok {
continue
}
c--
if c <= max {
continue outer
}
}
max = c
pivot = u
neighbors = nb
}
}
maxNeighbors(p)
maxNeighbors(x)
if pivot == nil {
panic("bronKerbosch: empty set")
}
return neighbors
}

106
vendor/gonum.org/v1/gonum/graph/topo/clique_graph.go generated vendored Normal file
View File

@ -0,0 +1,106 @@
// Copyright ©2017 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package topo
import (
"sort"
"gonum.org/v1/gonum/graph"
"gonum.org/v1/gonum/graph/internal/ordered"
"gonum.org/v1/gonum/graph/internal/set"
)
// Builder is a pure topological graph construction type.
type Builder interface {
AddNode(graph.Node)
SetEdge(graph.Edge)
}
// CliqueGraph builds the clique graph of g in dst using Clique and CliqueGraphEdge
// nodes and edges. The nodes returned by calls to Nodes on the nodes and edges of
// the constructed graph are the cliques and the common nodes between cliques
// respectively. The dst graph is not cleared.
func CliqueGraph(dst Builder, g graph.Undirected) {
cliques := BronKerbosch(g)
// Construct a consistent view of cliques in g. Sorting costs
// us a little, but not as much as the cliques themselves.
for _, c := range cliques {
sort.Sort(ordered.ByID(c))
}
sort.Sort(ordered.BySliceIDs(cliques))
cliqueNodes := make(cliqueNodeSets, len(cliques))
for id, c := range cliques {
s := make(set.Nodes, len(c))
for _, n := range c {
s.Add(n)
}
ns := &nodeSet{Clique: Clique{id: int64(id), nodes: c}, nodes: s}
dst.AddNode(ns.Clique)
for _, n := range c {
nid := n.ID()
cliqueNodes[nid] = append(cliqueNodes[nid], ns)
}
}
for _, cliques := range cliqueNodes {
for i, uc := range cliques {
for _, vc := range cliques[i+1:] {
// Retain the nodes that contribute to the
// edge between the cliques.
var edgeNodes []graph.Node
switch 1 {
case len(uc.Clique.nodes):
edgeNodes = []graph.Node{uc.Clique.nodes[0]}
case len(vc.Clique.nodes):
edgeNodes = []graph.Node{vc.Clique.nodes[0]}
default:
for _, n := range make(set.Nodes).Intersect(uc.nodes, vc.nodes) {
edgeNodes = append(edgeNodes, n)
}
sort.Sort(ordered.ByID(edgeNodes))
}
dst.SetEdge(CliqueGraphEdge{from: uc.Clique, to: vc.Clique, nodes: edgeNodes})
}
}
}
}
type cliqueNodeSets map[int64][]*nodeSet
type nodeSet struct {
Clique
nodes set.Nodes
}
// Clique is a node in a clique graph.
type Clique struct {
id int64
nodes []graph.Node
}
// ID returns the node ID.
func (n Clique) ID() int64 { return n.id }
// Nodes returns the nodes in the clique.
func (n Clique) Nodes() []graph.Node { return n.nodes }
// CliqueGraphEdge is an edge in a clique graph.
type CliqueGraphEdge struct {
from, to Clique
nodes []graph.Node
}
// From returns the from node of the edge.
func (e CliqueGraphEdge) From() graph.Node { return e.from }
// To returns the to node of the edge.
func (e CliqueGraphEdge) To() graph.Node { return e.to }
// Nodes returns the common nodes in the cliques of the underlying graph
// corresponding to the from and to nodes in the clique graph.
func (e CliqueGraphEdge) Nodes() []graph.Node { return e.nodes }

6
vendor/gonum.org/v1/gonum/graph/topo/doc.go generated vendored Normal file
View File

@ -0,0 +1,6 @@
// Copyright ©2017 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package topo provides graph topology analysis functions.
package topo

281
vendor/gonum.org/v1/gonum/graph/topo/johnson_cycles.go generated vendored Normal file
View File

@ -0,0 +1,281 @@
// Copyright ©2015 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package topo
import (
"sort"
"gonum.org/v1/gonum/graph"
"gonum.org/v1/gonum/graph/internal/ordered"
"gonum.org/v1/gonum/graph/internal/set"
)
// johnson implements Johnson's "Finding all the elementary
// circuits of a directed graph" algorithm. SIAM J. Comput. 4(1):1975.
//
// Comments in the johnson methods are kept in sync with the comments
// and labels from the paper.
type johnson struct {
adjacent johnsonGraph // SCC adjacency list.
b []set.Ints // Johnson's "B-list".
blocked []bool
s int
stack []graph.Node
result [][]graph.Node
}
// DirectedCyclesIn returns the set of elementary cycles in the graph g.
func DirectedCyclesIn(g graph.Directed) [][]graph.Node {
jg := johnsonGraphFrom(g)
j := johnson{
adjacent: jg,
b: make([]set.Ints, len(jg.orig)),
blocked: make([]bool, len(jg.orig)),
}
// len(j.nodes) is the order of g.
for j.s < len(j.adjacent.orig)-1 {
// We use the previous SCC adjacency to reduce the work needed.
sccs := TarjanSCC(j.adjacent.subgraph(j.s))
// A_k = adjacency structure of strong component K with least
// vertex in subgraph of G induced by {s, s+1, ... ,n}.
j.adjacent = j.adjacent.sccSubGraph(sccs, 2) // Only allow SCCs with >= 2 vertices.
if j.adjacent.order() == 0 {
break
}
// s = least vertex in V_k
if s := j.adjacent.leastVertexIndex(); s < j.s {
j.s = s
}
for i, v := range j.adjacent.orig {
if !j.adjacent.nodes.Has(v.ID()) {
continue
}
if len(j.adjacent.succ[v.ID()]) > 0 {
j.blocked[i] = false
j.b[i] = make(set.Ints)
}
}
//L3:
_ = j.circuit(j.s)
j.s++
}
return j.result
}
// circuit is the CIRCUIT sub-procedure in the paper.
func (j *johnson) circuit(v int) bool {
f := false
n := j.adjacent.orig[v]
j.stack = append(j.stack, n)
j.blocked[v] = true
//L1:
for w := range j.adjacent.succ[n.ID()] {
w := j.adjacent.indexOf(w)
if w == j.s {
// Output circuit composed of stack followed by s.
r := make([]graph.Node, len(j.stack)+1)
copy(r, j.stack)
r[len(r)-1] = j.adjacent.orig[j.s]
j.result = append(j.result, r)
f = true
} else if !j.blocked[w] {
if j.circuit(w) {
f = true
}
}
}
//L2:
if f {
j.unblock(v)
} else {
for w := range j.adjacent.succ[n.ID()] {
j.b[j.adjacent.indexOf(w)].Add(v)
}
}
j.stack = j.stack[:len(j.stack)-1]
return f
}
// unblock is the UNBLOCK sub-procedure in the paper.
func (j *johnson) unblock(u int) {
j.blocked[u] = false
for w := range j.b[u] {
j.b[u].Remove(w)
if j.blocked[w] {
j.unblock(w)
}
}
}
// johnsonGraph is an edge list representation of a graph with helpers
// necessary for Johnson's algorithm
type johnsonGraph struct {
// Keep the original graph nodes and a
// look-up to into the non-sparse
// collection of potentially sparse IDs.
orig []graph.Node
index map[int64]int
nodes set.Int64s
succ map[int64]set.Int64s
}
// johnsonGraphFrom returns a deep copy of the graph g.
func johnsonGraphFrom(g graph.Directed) johnsonGraph {
nodes := g.Nodes()
sort.Sort(ordered.ByID(nodes))
c := johnsonGraph{
orig: nodes,
index: make(map[int64]int, len(nodes)),
nodes: make(set.Int64s, len(nodes)),
succ: make(map[int64]set.Int64s),
}
for i, u := range nodes {
uid := u.ID()
c.index[uid] = i
for _, v := range g.From(uid) {
if c.succ[uid] == nil {
c.succ[uid] = make(set.Int64s)
c.nodes.Add(uid)
}
c.nodes.Add(v.ID())
c.succ[uid].Add(v.ID())
}
}
return c
}
// order returns the order of the graph.
func (g johnsonGraph) order() int { return g.nodes.Count() }
// indexOf returns the index of the retained node for the given node ID.
func (g johnsonGraph) indexOf(id int64) int {
return g.index[id]
}
// leastVertexIndex returns the index into orig of the least vertex.
func (g johnsonGraph) leastVertexIndex() int {
for _, v := range g.orig {
if g.nodes.Has(v.ID()) {
return g.indexOf(v.ID())
}
}
panic("johnsonCycles: empty set")
}
// subgraph returns a subgraph of g induced by {s, s+1, ... , n}. The
// subgraph is destructively generated in g.
func (g johnsonGraph) subgraph(s int) johnsonGraph {
sn := g.orig[s].ID()
for u, e := range g.succ {
if u < sn {
g.nodes.Remove(u)
delete(g.succ, u)
continue
}
for v := range e {
if v < sn {
g.succ[u].Remove(v)
}
}
}
return g
}
// sccSubGraph returns the graph of the tarjan's strongly connected
// components with each SCC containing at least min vertices.
// sccSubGraph returns nil if there is no SCC with at least min
// members.
func (g johnsonGraph) sccSubGraph(sccs [][]graph.Node, min int) johnsonGraph {
if len(g.nodes) == 0 {
g.nodes = nil
g.succ = nil
return g
}
sub := johnsonGraph{
orig: g.orig,
index: g.index,
nodes: make(set.Int64s),
succ: make(map[int64]set.Int64s),
}
var n int
for _, scc := range sccs {
if len(scc) < min {
continue
}
n++
for _, u := range scc {
for _, v := range scc {
if _, ok := g.succ[u.ID()][v.ID()]; ok {
if sub.succ[u.ID()] == nil {
sub.succ[u.ID()] = make(set.Int64s)
sub.nodes.Add(u.ID())
}
sub.nodes.Add(v.ID())
sub.succ[u.ID()].Add(v.ID())
}
}
}
}
if n == 0 {
g.nodes = nil
g.succ = nil
return g
}
return sub
}
// Nodes is required to satisfy Tarjan.
func (g johnsonGraph) Nodes() []graph.Node {
n := make([]graph.Node, 0, len(g.nodes))
for id := range g.nodes {
n = append(n, johnsonGraphNode(id))
}
return n
}
// Successors is required to satisfy Tarjan.
func (g johnsonGraph) From(id int64) []graph.Node {
adj := g.succ[id]
if len(adj) == 0 {
return nil
}
succ := make([]graph.Node, 0, len(adj))
for id := range adj {
succ = append(succ, johnsonGraphNode(id))
}
return succ
}
func (johnsonGraph) Has(int64) bool {
panic("topo: unintended use of johnsonGraph")
}
func (johnsonGraph) HasEdgeBetween(_, _ int64) bool {
panic("topo: unintended use of johnsonGraph")
}
func (johnsonGraph) Edge(_, _ int64) graph.Edge {
panic("topo: unintended use of johnsonGraph")
}
func (johnsonGraph) HasEdgeFromTo(_, _ int64) bool {
panic("topo: unintended use of johnsonGraph")
}
func (johnsonGraph) To(int64) []graph.Node {
panic("topo: unintended use of johnsonGraph")
}
type johnsonGraphNode int64
func (n johnsonGraphNode) ID() int64 { return int64(n) }

View File

@ -0,0 +1,9 @@
// Copyright ©2015 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !tomita
package topo
const tomitaTanakaTakahashi = false

81
vendor/gonum.org/v1/gonum/graph/topo/paton_cycles.go generated vendored Normal file
View File

@ -0,0 +1,81 @@
// Copyright ©2017 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package topo
import (
"gonum.org/v1/gonum/graph"
"gonum.org/v1/gonum/graph/internal/linear"
"gonum.org/v1/gonum/graph/internal/set"
)
// UndirectedCyclesIn returns a set of cycles that forms a cycle basis in the graph g.
// Any cycle in g can be constructed as a symmetric difference of its elements.
func UndirectedCyclesIn(g graph.Undirected) [][]graph.Node {
// From "An algorithm for finding a fundamental set of cycles of a graph"
// https://doi.org/10.1145/363219.363232
var cycles [][]graph.Node
done := make(set.Int64s)
var tree linear.NodeStack
for _, n := range g.Nodes() {
id := n.ID()
if done.Has(id) {
continue
}
done.Add(id)
tree = tree[:0]
tree.Push(n)
from := sets{id: set.Int64s{}}
to := map[int64]graph.Node{id: n}
for tree.Len() != 0 {
u := tree.Pop()
uid := u.ID()
adj := from[uid]
for _, v := range g.From(uid) {
vid := v.ID()
switch {
case uid == vid:
cycles = append(cycles, []graph.Node{u})
case !from.has(vid):
done.Add(vid)
to[vid] = u
tree.Push(v)
from.add(uid, vid)
case !adj.Has(vid):
c := []graph.Node{v, u}
adj := from[vid]
p := to[uid]
for !adj.Has(p.ID()) {
c = append(c, p)
p = to[p.ID()]
}
c = append(c, p, c[0])
cycles = append(cycles, c)
adj.Add(uid)
}
}
}
}
return cycles
}
type sets map[int64]set.Int64s
func (s sets) add(uid, vid int64) {
e, ok := s[vid]
if !ok {
e = make(set.Int64s)
s[vid] = e
}
e.Add(uid)
}
func (s sets) has(uid int64) bool {
_, ok := s[uid]
return ok
}

197
vendor/gonum.org/v1/gonum/graph/topo/tarjan.go generated vendored Normal file
View File

@ -0,0 +1,197 @@
// Copyright ©2015 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package topo
import (
"fmt"
"sort"
"gonum.org/v1/gonum/graph"
"gonum.org/v1/gonum/graph/internal/ordered"
"gonum.org/v1/gonum/graph/internal/set"
)
// Unorderable is an error containing sets of unorderable graph.Nodes.
type Unorderable [][]graph.Node
// Error satisfies the error interface.
func (e Unorderable) Error() string {
const maxNodes = 10
var n int
for _, c := range e {
n += len(c)
}
if n > maxNodes {
// Don't return errors that are too long.
return fmt.Sprintf("topo: no topological ordering: %d nodes in %d cyclic components", n, len(e))
}
return fmt.Sprintf("topo: no topological ordering: cyclic components: %v", [][]graph.Node(e))
}
func lexical(nodes []graph.Node) { sort.Sort(ordered.ByID(nodes)) }
// Sort performs a topological sort of the directed graph g returning the 'from' to 'to'
// sort order. If a topological ordering is not possible, an Unorderable error is returned
// listing cyclic components in g with each cyclic component's members sorted by ID. When
// an Unorderable error is returned, each cyclic component's topological position within
// the sorted nodes is marked with a nil graph.Node.
func Sort(g graph.Directed) (sorted []graph.Node, err error) {
sccs := TarjanSCC(g)
return sortedFrom(sccs, lexical)
}
// SortStabilized performs a topological sort of the directed graph g returning the 'from'
// to 'to' sort order, or the order defined by the in place order sort function where there
// is no unambiguous topological ordering. If a topological ordering is not possible, an
// Unorderable error is returned listing cyclic components in g with each cyclic component's
// members sorted by the provided order function. If order is nil, nodes are ordered lexically
// by node ID. When an Unorderable error is returned, each cyclic component's topological
// position within the sorted nodes is marked with a nil graph.Node.
func SortStabilized(g graph.Directed, order func([]graph.Node)) (sorted []graph.Node, err error) {
if order == nil {
order = lexical
}
sccs := tarjanSCCstabilized(g, order)
return sortedFrom(sccs, order)
}
func sortedFrom(sccs [][]graph.Node, order func([]graph.Node)) ([]graph.Node, error) {
sorted := make([]graph.Node, 0, len(sccs))
var sc Unorderable
for _, s := range sccs {
if len(s) != 1 {
order(s)
sc = append(sc, s)
sorted = append(sorted, nil)
continue
}
sorted = append(sorted, s[0])
}
var err error
if sc != nil {
for i, j := 0, len(sc)-1; i < j; i, j = i+1, j-1 {
sc[i], sc[j] = sc[j], sc[i]
}
err = sc
}
ordered.Reverse(sorted)
return sorted, err
}
// TarjanSCC returns the strongly connected components of the graph g using Tarjan's algorithm.
//
// A strongly connected component of a graph is a set of vertices where it's possible to reach any
// vertex in the set from any other (meaning there's a cycle between them.)
//
// Generally speaking, a directed graph where the number of strongly connected components is equal
// to the number of nodes is acyclic, unless you count reflexive edges as a cycle (which requires
// only a little extra testing.)
//
func TarjanSCC(g graph.Directed) [][]graph.Node {
return tarjanSCCstabilized(g, nil)
}
func tarjanSCCstabilized(g graph.Directed, order func([]graph.Node)) [][]graph.Node {
nodes := g.Nodes()
var succ func(id int64) []graph.Node
if order == nil {
succ = g.From
} else {
order(nodes)
ordered.Reverse(nodes)
succ = func(id int64) []graph.Node {
to := g.From(id)
order(to)
ordered.Reverse(to)
return to
}
}
t := tarjan{
succ: succ,
indexTable: make(map[int64]int, len(nodes)),
lowLink: make(map[int64]int, len(nodes)),
onStack: make(set.Int64s),
}
for _, v := range nodes {
if t.indexTable[v.ID()] == 0 {
t.strongconnect(v)
}
}
return t.sccs
}
// tarjan implements Tarjan's strongly connected component finding
// algorithm. The implementation is from the pseudocode at
//
// http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm?oldid=642744644
//
type tarjan struct {
succ func(id int64) []graph.Node
index int
indexTable map[int64]int
lowLink map[int64]int
onStack set.Int64s
stack []graph.Node
sccs [][]graph.Node
}
// strongconnect is the strongconnect function described in the
// wikipedia article.
func (t *tarjan) strongconnect(v graph.Node) {
vID := v.ID()
// Set the depth index for v to the smallest unused index.
t.index++
t.indexTable[vID] = t.index
t.lowLink[vID] = t.index
t.stack = append(t.stack, v)
t.onStack.Add(vID)
// Consider successors of v.
for _, w := range t.succ(vID) {
wID := w.ID()
if t.indexTable[wID] == 0 {
// Successor w has not yet been visited; recur on it.
t.strongconnect(w)
t.lowLink[vID] = min(t.lowLink[vID], t.lowLink[wID])
} else if t.onStack.Has(wID) {
// Successor w is in stack s and hence in the current SCC.
t.lowLink[vID] = min(t.lowLink[vID], t.indexTable[wID])
}
}
// If v is a root node, pop the stack and generate an SCC.
if t.lowLink[vID] == t.indexTable[vID] {
// Start a new strongly connected component.
var (
scc []graph.Node
w graph.Node
)
for {
w, t.stack = t.stack[len(t.stack)-1], t.stack[:len(t.stack)-1]
t.onStack.Remove(w.ID())
// Add w to current strongly connected component.
scc = append(scc, w)
if w.ID() == vID {
break
}
}
// Output the current strongly connected component.
t.sccs = append(t.sccs, scc)
}
}
func min(a, b int) int {
if a < b {
return a
}
return b
}

View File

@ -0,0 +1,9 @@
// Copyright ©2015 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build tomita
package topo
const tomitaTanakaTakahashi = true

68
vendor/gonum.org/v1/gonum/graph/topo/topo.go generated vendored Normal file
View File

@ -0,0 +1,68 @@
// Copyright ©2014 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package topo
import (
"gonum.org/v1/gonum/graph"
"gonum.org/v1/gonum/graph/traverse"
)
// IsPathIn returns whether path is a path in g.
//
// As special cases, IsPathIn returns true for a zero length path or for
// a path of length 1 when the node in path exists in the graph.
func IsPathIn(g graph.Graph, path []graph.Node) bool {
switch len(path) {
case 0:
return true
case 1:
return g.Has(path[0].ID())
default:
var canReach func(uid, vid int64) bool
switch g := g.(type) {
case graph.Directed:
canReach = g.HasEdgeFromTo
default:
canReach = g.HasEdgeBetween
}
for i, u := range path[:len(path)-1] {
if !canReach(u.ID(), path[i+1].ID()) {
return false
}
}
return true
}
}
// PathExistsIn returns whether there is a path in g starting at from extending
// to to.
//
// PathExistsIn exists as a helper function. If many tests for path existence
// are being performed, other approaches will be more efficient.
func PathExistsIn(g graph.Graph, from, to graph.Node) bool {
var t traverse.BreadthFirst
return t.Walk(g, from, func(n graph.Node, _ int) bool { return n.ID() == to.ID() }) != nil
}
// ConnectedComponents returns the connected components of the undirected graph g.
func ConnectedComponents(g graph.Undirected) [][]graph.Node {
var (
w traverse.DepthFirst
c []graph.Node
cc [][]graph.Node
)
during := func(n graph.Node) {
c = append(c, n)
}
after := func() {
cc = append(cc, []graph.Node(nil))
cc[len(cc)-1] = append(cc[len(cc)-1], c...)
c = c[:0]
}
w.WalkAll(g, nil, after, during)
return cc
}

31
vendor/gonum.org/v1/gonum/graph/traverse/BUILD generated vendored Normal file
View File

@ -0,0 +1,31 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"traverse.go",
],
importmap = "k8s.io/kubernetes/vendor/gonum.org/v1/gonum/graph/traverse",
importpath = "gonum.org/v1/gonum/graph/traverse",
visibility = ["//visibility:public"],
deps = [
"//vendor/gonum.org/v1/gonum/graph:go_default_library",
"//vendor/gonum.org/v1/gonum/graph/internal/linear:go_default_library",
"//vendor/gonum.org/v1/gonum/graph/internal/set:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

6
vendor/gonum.org/v1/gonum/graph/traverse/doc.go generated vendored Normal file
View File

@ -0,0 +1,6 @@
// Copyright ©2017 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package traverse provides basic graph traversal primitives.
package traverse

199
vendor/gonum.org/v1/gonum/graph/traverse/traverse.go generated vendored Normal file
View File

@ -0,0 +1,199 @@
// Copyright ©2015 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package traverse
import (
"gonum.org/v1/gonum/graph"
"gonum.org/v1/gonum/graph/internal/linear"
"gonum.org/v1/gonum/graph/internal/set"
)
var _ Graph = graph.Graph(nil)
// Graph is the subset of graph.Graph necessary for graph traversal.
type Graph interface {
// From returns all nodes that can be reached directly
// from the node with the given ID.
From(id int64) []graph.Node
// Edge returns the edge from u to v, with IDs uid and vid,
// if such an edge exists and nil otherwise. The node v
// must be directly reachable from u as defined by the
// From method.
Edge(uid, vid int64) graph.Edge
}
// BreadthFirst implements stateful breadth-first graph traversal.
type BreadthFirst struct {
EdgeFilter func(graph.Edge) bool
Visit func(u, v graph.Node)
queue linear.NodeQueue
visited set.Int64s
}
// Walk performs a breadth-first traversal of the graph g starting from the given node,
// depending on the the EdgeFilter field and the until parameter if they are non-nil. The
// traversal follows edges for which EdgeFilter(edge) is true and returns the first node
// for which until(node, depth) is true. During the traversal, if the Visit field is
// non-nil, it is called with the nodes joined by each followed edge.
func (b *BreadthFirst) Walk(g Graph, from graph.Node, until func(n graph.Node, d int) bool) graph.Node {
if b.visited == nil {
b.visited = make(set.Int64s)
}
b.queue.Enqueue(from)
b.visited.Add(from.ID())
var (
depth int
children int
untilNext = 1
)
for b.queue.Len() > 0 {
t := b.queue.Dequeue()
if until != nil && until(t, depth) {
return t
}
tid := t.ID()
for _, n := range g.From(tid) {
nid := n.ID()
if b.EdgeFilter != nil && !b.EdgeFilter(g.Edge(tid, nid)) {
continue
}
if b.visited.Has(nid) {
continue
}
if b.Visit != nil {
b.Visit(t, n)
}
b.visited.Add(nid)
children++
b.queue.Enqueue(n)
}
if untilNext--; untilNext == 0 {
depth++
untilNext = children
children = 0
}
}
return nil
}
// WalkAll calls Walk for each unvisited node of the graph g using edges independent
// of their direction. The functions before and after are called prior to commencing
// and after completing each walk if they are non-nil respectively. The function
// during is called on each node as it is traversed.
func (b *BreadthFirst) WalkAll(g graph.Undirected, before, after func(), during func(graph.Node)) {
b.Reset()
for _, from := range g.Nodes() {
if b.Visited(from) {
continue
}
if before != nil {
before()
}
b.Walk(g, from, func(n graph.Node, _ int) bool {
if during != nil {
during(n)
}
return false
})
if after != nil {
after()
}
}
}
// Visited returned whether the node n was visited during a traverse.
func (b *BreadthFirst) Visited(n graph.Node) bool {
return b.visited.Has(n.ID())
}
// Reset resets the state of the traverser for reuse.
func (b *BreadthFirst) Reset() {
b.queue.Reset()
b.visited = nil
}
// DepthFirst implements stateful depth-first graph traversal.
type DepthFirst struct {
EdgeFilter func(graph.Edge) bool
Visit func(u, v graph.Node)
stack linear.NodeStack
visited set.Int64s
}
// Walk performs a depth-first traversal of the graph g starting from the given node,
// depending on the the EdgeFilter field and the until parameter if they are non-nil. The
// traversal follows edges for which EdgeFilter(edge) is true and returns the first node
// for which until(node) is true. During the traversal, if the Visit field is non-nil, it
// is called with the nodes joined by each followed edge.
func (d *DepthFirst) Walk(g Graph, from graph.Node, until func(graph.Node) bool) graph.Node {
if d.visited == nil {
d.visited = make(set.Int64s)
}
d.stack.Push(from)
d.visited.Add(from.ID())
for d.stack.Len() > 0 {
t := d.stack.Pop()
if until != nil && until(t) {
return t
}
tid := t.ID()
for _, n := range g.From(tid) {
nid := n.ID()
if d.EdgeFilter != nil && !d.EdgeFilter(g.Edge(tid, nid)) {
continue
}
if d.visited.Has(nid) {
continue
}
if d.Visit != nil {
d.Visit(t, n)
}
d.visited.Add(nid)
d.stack.Push(n)
}
}
return nil
}
// WalkAll calls Walk for each unvisited node of the graph g using edges independent
// of their direction. The functions before and after are called prior to commencing
// and after completing each walk if they are non-nil respectively. The function
// during is called on each node as it is traversed.
func (d *DepthFirst) WalkAll(g graph.Undirected, before, after func(), during func(graph.Node)) {
d.Reset()
for _, from := range g.Nodes() {
if d.Visited(from) {
continue
}
if before != nil {
before()
}
d.Walk(g, from, func(n graph.Node) bool {
if during != nil {
during(n)
}
return false
})
if after != nil {
after()
}
}
}
// Visited returned whether the node n was visited during a traverse.
func (d *DepthFirst) Visited(n graph.Node) bool {
return d.visited.Has(n.ID())
}
// Reset resets the state of the traverser for reuse.
func (d *DepthFirst) Reset() {
d.stack = d.stack[:0]
d.visited = nil
}