diff --git a/code/go/internal/validator/folder_item_spec.go b/code/go/internal/validator/folder_item_spec.go index 5131e19f5..aa2d41955 100644 --- a/code/go/internal/validator/folder_item_spec.go +++ b/code/go/internal/validator/folder_item_spec.go @@ -8,19 +8,14 @@ import ( "regexp" "sync" - ve "github.com/elastic/package-spec/code/go/internal/errors" - "github.com/pkg/errors" "github.com/xeipuuv/gojsonschema" + ve "github.com/elastic/package-spec/code/go/internal/errors" + "github.com/elastic/package-spec/code/go/internal/validator/semantic" "github.com/elastic/package-spec/code/go/internal/yamlschema" ) -const ( - relativePathFormat = "relative-path" - dataStreamNameFormat = "data-stream-name" -) - type folderItemSpec struct { Description string `yaml:"description"` ItemType string `yaml:"type"` @@ -91,13 +86,13 @@ func (s *folderItemSpec) validate(fs http.FileSystem, folderSpecPath string, ite formatCheckersMutex.Lock() defer func() { - unloadRelativePathFormatChecker() - unloadDataStreamNameFormatChecker() + semantic.UnloadRelativePathFormatChecker() + semantic.UnloadDataStreamNameFormatChecker() formatCheckersMutex.Unlock() }() - loadRelativePathFormatChecker(filepath.Dir(itemPath)) - loadDataStreamNameFormatChecker(filepath.Dir(itemPath)) + semantic.LoadRelativePathFormatChecker(filepath.Dir(itemPath)) + semantic.LoadDataStreamNameFormatChecker(filepath.Dir(itemPath)) result, err := gojsonschema.Validate(schemaLoader, documentLoader) if err != nil { return ve.ValidationErrors{err} @@ -113,23 +108,3 @@ func (s *folderItemSpec) validate(fs http.FileSystem, folderSpecPath string, ite } return errs } - -func loadRelativePathFormatChecker(currentPath string) { - gojsonschema.FormatCheckers.Add(relativePathFormat, RelativePathChecker{ - currentPath: currentPath, - }) -} - -func unloadRelativePathFormatChecker() { - gojsonschema.FormatCheckers.Remove(relativePathFormat) -} - -func loadDataStreamNameFormatChecker(currentPath string) { - gojsonschema.FormatCheckers.Add(dataStreamNameFormat, RelativePathChecker{ - currentPath: filepath.Join(currentPath, "data_stream"), - }) -} - -func unloadDataStreamNameFormatChecker() { - gojsonschema.FormatCheckers.Remove(dataStreamNameFormat) -} diff --git a/code/go/internal/validator/folder_item_spec_errors.go b/code/go/internal/validator/folder_item_spec_errors.go index ee39418fb..7790426f6 100644 --- a/code/go/internal/validator/folder_item_spec_errors.go +++ b/code/go/internal/validator/folder_item_spec_errors.go @@ -1,10 +1,12 @@ package validator +import "github.com/elastic/package-spec/code/go/internal/validator/semantic" + func adjustErrorDescription(description string) string { - if description == "Does not match format '" + relativePathFormat + "'" { + if description == "Does not match format '"+semantic.RelativePathFormat+"'" { return "relative path is invalid or target doesn't exist" - } else if description == "Does not match format '" + dataStreamNameFormat + "'" { + } else if description == "Does not match format '"+semantic.DataStreamNameFormat+"'" { return "data stream doesn't exist" } return description -} \ No newline at end of file +} diff --git a/code/go/internal/validator/semantic/format_checkers.go b/code/go/internal/validator/semantic/format_checkers.go new file mode 100644 index 000000000..931dd4d71 --- /dev/null +++ b/code/go/internal/validator/semantic/format_checkers.go @@ -0,0 +1,69 @@ +package semantic + +import ( + "os" + "path/filepath" + + "github.com/xeipuuv/gojsonschema" +) + +const ( + // RelativePathFormat defines the ID of the relative path format checker. This format checker + // should be used when a field's value refers to a relative filesystem path. The checker will + // ensure that the location pointed to by that relative filesystem path actually exists on + // the filesystem, relative to the file in which the field is defined. + RelativePathFormat = "relative-path" + + // DataStreamNameFormat defines the ID of the data stream name format checker. This format checker + // should be used when a field's value refers to a data stream name. The checker will ensure + // that a folder with that data stream name exists on the filesystem. + DataStreamNameFormat = "data-stream-name" +) + +// relativePathChecker is responsible for checking presence of the file path +type relativePathChecker struct { + currentPath string +} + +// IsFormat method checks if the path exists. +func (r relativePathChecker) IsFormat(input interface{}) bool { + asString, ok := input.(string) + if !ok { + return false + } + + path := filepath.Join(r.currentPath, asString) + _, err := os.Stat(path) + if err != nil { + return false + } + return true +} + +// LoadRelativePathFormatChecker loads the relative-path format checker into the +// json-schema validation library. +func LoadRelativePathFormatChecker(currentPath string) { + gojsonschema.FormatCheckers.Add(RelativePathFormat, relativePathChecker{ + currentPath: currentPath, + }) +} + +// UnloadRelativePathFormatChecker unloads the relative-path format checker from the +// json-schema validation library. +func UnloadRelativePathFormatChecker() { + gojsonschema.FormatCheckers.Remove(RelativePathFormat) +} + +// LoadDataStreamNameFormatChecker loads the data-stream-name format checker into the +// json-schema validation library. +func LoadDataStreamNameFormatChecker(currentPath string) { + gojsonschema.FormatCheckers.Add(DataStreamNameFormat, relativePathChecker{ + currentPath: filepath.Join(currentPath, "data_stream"), + }) +} + +// UnloadDataStreamNameFormatChecker unloads the data-stream-name format checker from the +// json-schema validation library. +func UnloadDataStreamNameFormatChecker() { + gojsonschema.FormatCheckers.Remove(DataStreamNameFormat) +}