Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
module ballerina-lang-go

go 1.24.4

require github.com/BurntSushi/toml v1.5.0

require (
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
golang.org/x/text v0.14.0 // indirect
)
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ=
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
94 changes: 94 additions & 0 deletions tomlparser/schema.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com).
//
// WSO2 LLC. licenses this file to you 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 tomlparser

import (
"encoding/json"
"fmt"
"io"
"io/fs"
"os"

"github.com/santhosh-tekuri/jsonschema/v6"
)

type Schema interface {
Validate(data any) error
FromPath(fsys fs.FS, path string) (Schema, error)
FromString(content string) (Schema, error)
}

type schemaImpl struct {
compiled *jsonschema.Schema
}

func NewSchemaFromPath(fsys fs.FS, path string) (Schema, error) {
content, err := readFile(fsys, path)
if err != nil {
return nil, fmt.Errorf("failed to read schema file %s: %w", path, err)
}
return NewSchemaFromString(content)
}

func NewSchemaFromString(content string) (Schema, error) {
compiler := jsonschema.NewCompiler()

var schemaDoc any
if err := json.Unmarshal([]byte(content), &schemaDoc); err != nil {
return nil, fmt.Errorf("failed to parse schema JSON: %w", err)
}

if err := compiler.AddResource("schema.json", schemaDoc); err != nil {
return nil, fmt.Errorf("failed to add schema resource: %w", err)
}

schema, err := compiler.Compile("schema.json")
if err != nil {
return nil, fmt.Errorf("failed to compile schema: %w", err)
}

return &schemaImpl{
compiled: schema,
}, nil
}

func NewSchemaFromReader(reader io.Reader) (Schema, error) {
content, err := readFromReader(reader)
if err != nil {
return nil, fmt.Errorf("failed to read schema: %w", err)
}
return NewSchemaFromString(content)
}

func NewSchemaFromFile(file *os.File) (Schema, error) {
return NewSchemaFromReader(file)
}

func (s *schemaImpl) Validate(data any) error {
if err := s.compiled.Validate(data); err != nil {
return fmt.Errorf("schema validation failed: %w", err)
}
return nil
}

func (s *schemaImpl) FromPath(fsys fs.FS, path string) (Schema, error) {
return NewSchemaFromPath(fsys, path)
}

func (s *schemaImpl) FromString(content string) (Schema, error) {
return NewSchemaFromString(content)
}
9 changes: 9 additions & 0 deletions tomlparser/testdata/ballerina-package.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
org = "foo"
name = "winery"
version = "0.1.0"
license = ["MIT", "Apache-2.0"]
authors = ["jo@wso2.com", "pramodya@wso2.com"]
repository = "https://github.com/ballerinalang/ballerina"
keywords = ["ballerina", "security", "crypto"]
exported = ["winery", "service"]
10 changes: 10 additions & 0 deletions tomlparser/testdata/invalid-sample.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
org = "foo"
name = "winery"
version = "0.1.0"
license = ["MIT", "Apache-2.0"]
authors = ["jo@wso2.com", "pramodya@wso2.com"]
repository = "https://github.com/ballerinalang/ballerina"
keywords = ["ballerina", "security", "crypto"]
exported = ["winery", "service"]
unexpected = "this field is not in schema"
2 changes: 2 additions & 0 deletions tomlparser/testdata/missing-required.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
name = "test"
description = "missing version field"
19 changes: 19 additions & 0 deletions tomlparser/testdata/required-schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Config Schema",
"description": "Schema with required fields",
"type": "object",
"additionalProperties": false,
"required": ["name", "version"],
"properties": {
"name": {
"type": "string"
},
"version": {
"type": "string"
},
"description": {
"type": "string"
}
}
}
51 changes: 51 additions & 0 deletions tomlparser/testdata/sample-schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Ballerina Manifest Spec",
"description": "Schema for Ballerina Manifest",
"type": "object",
"additionalProperties": false,
"properties": {
"package": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"org": {
"type": "string"
},
"version": {
"type": "string"
},
"license": {
"type": "array",
"items": {
"type": "string"
}
},
"authors": {
"type": "array",
"items": {
"type": "string"
}
},
"repository": {
"type": "string"
},
"keywords": {
"type": "array",
"items": {
"type": "string"
}
},
"exported": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
28 changes: 28 additions & 0 deletions tomlparser/testdata/sample.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
title = "Server Configuration"

[owner]
name = "WSO2"

[database]
server = "192.168.1.1"
ports = [ 8001, 8001, 8002 ]
connection_max = 5000
enabled = true

[servers]
[servers.alpha]
ip = "10.0.0.1"
dc = "eqdc10"

[servers.beta]
ip = "10.0.0.2"
dc = "eqdc10"

[[routes]]
name = "health"
path = "/health"

[[routes]]
name = "metrics"
path = "/metrics"
method = "GET"
Loading