Skip to content
Snippets Groups Projects
Commit 5ddc8540 authored by Alex Clemmer's avatar Alex Clemmer
Browse files

Add schemas for `app.yaml` and `registry.yaml`

Every ksonnet application has an `app.yaml`, which is similar in
principle to node.js's `package.json`. It contains important metadata,
such as description, names, and information about dependencies. This is
similarly true of `registry.yaml`, which contains information about a
package registry.

This commit will introduce schemas for both these files.
parent 6f9afae6
No related branches found
No related tags found
No related merge requests found
// Copyright 2017 The kubecfg 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.
package app
import (
"encoding/json"
"fmt"
)
const (
DefaultAPIVersion = "0.1"
Kind = "ksonnet.io/app"
DefaultVersion = "0.0.1"
)
var ErrRegistryNameInvalid = fmt.Errorf("Registry name is invalid")
var ErrRegistryExists = fmt.Errorf("Registry with name already exists, but has different URL or protocol")
type Spec struct {
APIVersion string `json:"apiVersion,omitempty"`
Kind string `json:"kind,omitempty"`
Name string `json:"name,omitempty"`
Version string `json:"version,omitempty"`
Description string `json:"description,omitempty"`
Authors []string `json:"authors,omitempty"`
Contributors ContributorSpecs `json:"contributors,omitempty"`
Repository *RepositorySpec `json:"repository,omitempty"`
Bugs string `json:"bugs,omitempty"`
Keywords []string `json:"keywords,omitempty"`
Registries RegistryRefSpecs `json:"registries,omitempty"`
License string `json:"license,omitempty"`
}
func (s *Spec) Marshal() ([]byte, error) {
return json.MarshalIndent(s, "", " ")
}
func (s *Spec) GetRegistryRef(name string) (*RegistryRefSpec, bool) {
registryRefSpec, ok := s.Registries[name]
if ok {
// Populate name, which we do not include in the deserialization
// process.
registryRefSpec.Name = name
return registryRefSpec, true
}
return nil, false
}
func (s *Spec) AddRegistryRef(name, protocol, uri string) (*RegistryRefSpec, error) {
if name == "" {
return nil, ErrRegistryNameInvalid
}
registryRefSpec, registryRefExists := s.Registries[name]
if registryRefExists {
storedURI, uriExists := registryRefSpec.Spec["uri"]
if registryRefSpec.Protocol != protocol || !uriExists || storedURI != uri {
return nil, ErrRegistryExists
}
} else {
registryRefSpec = &RegistryRefSpec{
Protocol: protocol,
Spec: map[string]interface{}{
"uri": uri,
},
Name: name,
}
}
s.Registries[name] = registryRefSpec
return registryRefSpec, nil
}
type RepositorySpec struct {
Type string `json:"type"`
URI string `json:"uri"`
}
type RegistryRefSpec struct {
Protocol string `json:"protocol"`
Spec map[string]interface{} `json:"spec"`
Name string
}
type RegistryRefSpecs map[string]*RegistryRefSpec
type ContributorSpec struct {
Name string `json:"name"`
Email string `json:"email"`
}
type ContributorSpecs []*ContributorSpec
package app
import (
"testing"
)
func TestGetRegistryRefSuccess(t *testing.T) {
example1 := Spec{
Registries: RegistryRefSpecs{
"simple1": &RegistryRefSpec{
Spec: map[string]interface{}{
"uri": "example.com",
},
Protocol: "github",
},
},
}
r1, ok := example1.GetRegistryRef("simple1")
if r1 == nil || !ok {
t.Error("Expected registry to contain 'simple1'")
}
uri, ok := r1.Spec["uri"]
if !ok || uri.(string) != "example.com" || r1.Name != "simple1" || r1.Protocol != "github" {
t.Errorf("Registry did not add correct values:\n%s", r1)
}
}
func TestGetRegistryRefFailure(t *testing.T) {
example1 := Spec{
Registries: RegistryRefSpecs{
"simple1": &RegistryRefSpec{
Spec: map[string]interface{}{
"uri": "example.com",
},
Protocol: "github",
},
},
}
r1, ok := example1.GetRegistryRef("simple2")
if r1 != nil || ok {
t.Error("Expected registry to not contain 'simple2'")
}
}
func TestAddRegistryRefSuccess(t *testing.T) {
var example1 = Spec{
Registries: RegistryRefSpecs{},
}
r1, err := example1.AddRegistryRef("simple1", "github", "example.com")
if r1 == nil || err != nil {
t.Errorf("Expected registry add to succeed:\n%s", err)
}
uri1, ok1 := r1.Spec["uri"]
if !ok1 || uri1.(string) != "example.com" || r1.Name != "simple1" || r1.Protocol != "github" {
t.Errorf("Registry did not add correct values:\n%s", r1)
}
// Test that the `Name` field is added properly if it already exists.
r2, err := example1.AddRegistryRef("simple1", "github", "example.com")
if r2 == nil || err != nil {
t.Errorf("Expected registry add to succeed:\n%s", err)
}
uri2, ok2 := r2.Spec["uri"]
if !ok2 || uri2.(string) != "example.com" || r1.Name != "simple1" || r1.Protocol != "github" {
t.Errorf("Registry did not add correct values:\n%s", r1)
}
}
func TestAddRegistryRefFailure(t *testing.T) {
example1 := Spec{
Registries: RegistryRefSpecs{
"simple1": &RegistryRefSpec{
Spec: map[string]interface{}{
"uri": "example.com",
},
Protocol: "github",
},
},
}
r1, err := example1.AddRegistryRef("", "github", "example.com")
if r1 != nil || err != ErrRegistryNameInvalid {
t.Error("Expected registry to fail to add registry with invalid name")
}
r2, err := example1.AddRegistryRef("simple1", "fakeProtocol", "example.com")
if r2 != nil || err != ErrRegistryExists {
t.Error("Expected registry to fail to add registry with duplicate name and different protocol")
}
r3, err := example1.AddRegistryRef("simple1", "github", "fakeUrl")
if r3 != nil || err != ErrRegistryExists {
t.Error("Expected registry to fail to add registry with duplicate name and different uri")
}
}
// Copyright 2017 The kubecfg 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.
package registry
const (
DefaultApiVersion = "0.1"
DefaultKind = "ksonnet.io/registry"
)
type Spec struct {
APIVersion string `json:"apiVersion"`
Kind string `json:"kind"`
Prototypes PrototypeRefSpecs `json:"prototypes"`
Libraries LibraryRefSpecs `json:"libraries"`
}
type Specs []*Spec
type LibraryRefSpecs map[string]string
type PrototypeRefSpecs map[string]string
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment