Repository: creativeprojects/resticprofile (language: python)

Issue:
JSON Schemas are invalid
The JSON schemas provided [in the docs](https://creativeprojects.github.io/resticprofile/reference/json-schema/index.html) are invalid, and can't be parsed by e.g. the "Even Better TOML" v0.19.2 VS Code extension—suggested [in the docs](https://creativeprojects.github.io/resticprofile/configuration/getting_started/index.html#toml) too. I have confirmed schema parsing also fails with the [`boon`](https://github.com/santhosh-tekuri/boon) v0.6.0 validator.

I hope I'm not making a mistake—given how easy this is to reproduce you'd think someone would've reported the issue earlier.

The specific error shown in the "Even Better TOML LSP" output is:

```text
ERROR document_change:publish_diagnostics:collect_schema_errors: schema validation failed error=invalid schema https://creativeprojects.github.io/resticprofile/jsonschema/config-1.json

Caused by:
    invalid schema: relative URL without a base document_url=file:///<REDACTED>
```

I believe this is because the [2019-09 JSON Schema draft](https://json-schema.org/draft/2019-09/draft-handrews-json-schema-02#rfc.section.8.2.2) requires the `$id` keyword to be an absolute URI:

> If present, the value for this keyword MUST be a string, and MUST represent a valid [URI-reference](https://json-schema.org/draft/2019-09/draft-handrews-json-schema-02#RFC3986). This URI-reference SHOULD be normalized, and MUST resolve to an [absolute-URI](https://json-schema.org/draft/2019-09/draft-handrews-json-schema-02#RFC3986) (without a fragment).

whereas the resticprofile schema `$id` is just a path: `/resticprofile/jsonschema/config-1.json`.

Could you please change the `$id` to an absolute URI to make the schema parseable and conform to the spec?


Discussion / hints:
Sorry I was away the last few weeks.

Funny enough I did notice something was wrong with it just before going away.

I'll have a look, thanks for the investigation 
I was (finally) looking into it today:

I'm also getting the error you mentioned from the `Even Better TOML LSP` so I will make the change (it used to work so they must have changed something)

Our tests are using [ajv](https://github.com/ajv-validator/ajv) which is considering the schema valid. But then I also tried the tool you mentioned without any issue:

```
% boon -c -f https://creativeprojects.github.io/resticprofile/jsonschema/config-2.json
schema https://creativeprojects.github.io/resticprofile/jsonschema/config-2.json: ok
%
```

(It can't parse version 1 but it's because of an incompatible regex)


I'm just trying to avoid getting any related error in the future by making sure the tool we're using to validate our schemas in the pipeline are efficient.

How did you get the error with boon validator?


Fix patch:
diff --git a/Makefile b/Makefile
index d5cec0af..1cea6565 100644
--- a/Makefile
+++ b/Makefile
@@ -243,26 +243,13 @@ generate-jsonschema: build
 
 	mkdir -p $(JSONSCHEMA_DIR) || echo "$(JSONSCHEMA_DIR) exists"
 
-	$(abspath $(BINARY)) generate --json-schema v1 > $(JSONSCHEMA_DIR)/config-1.json
-	$(abspath $(BINARY)) generate --json-schema v2 > $(JSONSCHEMA_DIR)/config-2.json
-	$(abspath $(BINARY)) generate --json-schema --version 0.9 v1 > $(JSONSCHEMA_DIR)/config-1-restic-0-9.json
-	$(abspath $(BINARY)) generate --json-schema --version 0.9 v2 > $(JSONSCHEMA_DIR)/config-2-restic-0-9.json
-	$(abspath $(BINARY)) generate --json-schema --version 0.10 v1 > $(JSONSCHEMA_DIR)/config-1-restic-0-10.json
-	$(abspath $(BINARY)) generate --json-schema --version 0.10 v2 > $(JSONSCHEMA_DIR)/config-2-restic-0-10.json
-	$(abspath $(BINARY)) generate --json-schema --version 0.11 v1 > $(JSONSCHEMA_DIR)/config-1-restic-0-11.json
-	$(abspath $(BINARY)) generate --json-schema --version 0.11 v2 > $(JSONSCHEMA_DIR)/config-2-restic-0-11.json
-	$(abspath $(BINARY)) generate --json-schema --version 0.12 v1 > $(JSONSCHEMA_DIR)/config-1-restic-0-12.json
-	$(abspath $(BINARY)) generate --json-schema --version 0.12 v2 > $(JSONSCHEMA_DIR)/config-2-restic-0-12.json
-	$(abspath $(BINARY)) generate --json-schema --version 0.13 v1 > $(JSONSCHEMA_DIR)/config-1-restic-0-13.json
-	$(abspath $(BINARY)) generate --json-schema --version 0.13 v2 > $(JSONSCHEMA_DIR)/config-2-restic-0-13.json
-	$(abspath $(BINARY)) generate --json-schema --version 0.14 v1 > $(JSONSCHEMA_DIR)/config-1-restic-0-14.json
-	$(abspath $(BINARY)) generate --json-schema --version 0.14 v2 > $(JSONSCHEMA_DIR)/config-2-restic-0-14.json
-	$(abspath $(BINARY)) generate --json-schema --version 0.15 v1 > $(JSONSCHEMA_DIR)/config-1-restic-0-15.json
-	$(abspath $(BINARY)) generate --json-schema --version 0.15 v2 > $(JSONSCHEMA_DIR)/config-2-restic-0-15.json
-	$(abspath $(BINARY)) generate --json-schema --version 0.16 v1 > $(JSONSCHEMA_DIR)/config-1-restic-0-16.json
-	$(abspath $(BINARY)) generate --json-schema --version 0.16 v2 > $(JSONSCHEMA_DIR)/config-2-restic-0-16.json
-	$(abspath $(BINARY)) generate --json-schema --version 0.17 v1 > $(JSONSCHEMA_DIR)/config-1-restic-0-17.json
-	$(abspath $(BINARY)) generate --json-schema --version 0.17 v2 > $(JSONSCHEMA_DIR)/config-2-restic-0-17.json
+	for config_version in 1 2 ; do \
+		$(abspath $(BINARY)) generate --json-schema v$$config_version > $(JSONSCHEMA_DIR)/config-$$config_version.json ; \
+		for restic_version in 0.9 0.10 0.11 0.12 0.13 0.14 0.15 0.16 0.17 ; do \
+			name=$$(echo $$restic_version | sed 's/\./-/g') ; \
+			$(abspath $(BINARY)) generate --json-schema --version $$restic_version v$$config_version > $(JSONSCHEMA_DIR)/config-$$config_version-restic-$$name.json ; \
+		done ; \
+	done
 
 generate-config-reference: build
 	@echo "[*] $@"
diff --git a/codecov.yml b/codecov.yml
index f2ce922b..8a6734e8 100644
--- a/codecov.yml
+++ b/codecov.yml
@@ -8,6 +8,7 @@ ignore:
   - systemd.go
   - update.go
   - main.go
+  - run_profile.go
   - syslog.go
   - syslog_windows.go
 
diff --git a/config/jsonschema/model.go b/config/jsonschema/model.go
index fbb8c521..15c495f1 100644
--- a/config/jsonschema/model.go
+++ b/config/jsonschema/model.go
@@ -5,6 +5,7 @@ import (
 	"encoding/hex"
 	"encoding/json"
 	"fmt"
+	"os"
 	"regexp"
 	"slices"
 	"strings"
@@ -16,9 +17,10 @@ import (
 const (
 	// for best compatibility the schema is mostly "draft-07", but some new vocabulary of 2019-09 is used
 	jsonSchemaVersion    = "https://json-schema.org/draft/2019-09/schema"
-	schemaUrlTemplate    = "/resticprofile/jsonschema/config-%d%s.json"
+	schemaUrlTemplate    = "%sconfig-%d%s.json"
 	referenceUrlTemplate = "#/$defs/%s"
 	arrayTitleSuffix     = "..."
+	defaultBaseURL       = "https://creativeprojects.github.io/resticprofile/jsonschema/"
 )
 
 type schemaRoot struct {
@@ -47,9 +49,13 @@ func newSchema(version config.Version, id string, content *schemaObject) (root *
 		if len(id) > 0 {
 			id = fmt.Sprintf("-restic-%s", strings.ReplaceAll(id, ".", "-"))
 		}
+		baseURL := os.Getenv("SCHEMA_BASE_URL")
+		if len(baseURL) == 0 {
+			baseURL = defaultBaseURL
+		}
 		root = &schemaRoot{
 			Schema:       jsonSchemaVersion,
-			Id:           fmt.Sprintf(schemaUrlTemplate, version, id),
+			Id:           fmt.Sprintf(schemaUrlTemplate, baseURL, version, id),
 			Defs:         make(map[string]SchemaType),
 			schemaObject: *content,
 		}
diff --git a/docs/content/configuration/jsonschema/index.md b/docs/content/configuration/jsonschema/index.md
index 63ffdda1..6b969a38 100644
--- a/docs/content/configuration/jsonschema/index.md
+++ b/docs/content/configuration/jsonschema/index.md
@@ -28,9 +28,11 @@ These schemas contain only flags and commands of a specific *restic* version. Th
 validate a config only when flags are used that the selected *restic* version supports 
 according to its manual pages.
 
-{{% notice style="hint" %}}
+{{% notice style="info" %}}
 As an alternative to URLs, schemas can be generated locally with: 
 `resticprofile generate --json-schema [--version RESTIC_VERSION] [v2|v1]`
+
+You can prefix the command with the environment variable `SCHEMA_BASE_URL` to change the base URL (defaults to `https://creativeprojects.github.io/resticprofile/jsonschema/`). This can be useful if you're working in an offline environment or need to use a custom schema location.
 {{% /notice %}}
 
 ## Usage (vscode)
@@ -64,8 +66,8 @@ version: "2"
 {{% /tab %}}
 {{< /tabs >}}
 
-{{% notice style="hint" %}}
-YAML & TOML validation with JSON schema is not supported out of the box. Additional extensions are required.
+{{% notice style="info" %}}
+YAML & TOML validation with JSON schema is not supported out of the box. Additional extensions are required, such as 'redhat.vscode-yaml' for YAML and 'tamasfe.even-better-toml' for TOML in Visual Studio Code.
 {{% /notice %}}
 
 **Example**
diff --git a/examples/dev.toml b/examples/dev.toml
index bbd6d62b..d9bff191 100644
--- a/examples/dev.toml
+++ b/examples/dev.toml
@@ -1,3 +1,11 @@
+#:schema https://creativeprojects.github.io/resticprofile/jsonschema/config-1.json
+
+version = "1"
+
+[global]
+  default-command = "snapshots"
+  initialize = false
+  priority = "low"
 
 [default]
   initialize = false
@@ -17,11 +25,6 @@
   [documents.snapshots]
     tag = ["documents"]
 
-[global]
-  default-command = "version"
-  initialize = false
-  priority = "low"
-
 [groups]
   full-backup = ["root","src"]
 
diff --git a/examples/linux.toml b/examples/linux.toml
index d65fb8f1..d909af07 100644
--- a/examples/linux.toml
+++ b/examples/linux.toml
@@ -1,3 +1,5 @@
+#:schema https://creativeprojects.github.io/resticprofile/jsonschema/config-1.json
+
 [global]
 priority = "low"
 initialize = false
diff --git a/examples/linux.yaml b/examples/linux.yaml
index ca949f72..e67d6447 100644
--- a/examples/linux.yaml
+++ b/examples/linux.yaml
@@ -3,7 +3,7 @@
 version: "1"
 
 global:
-    default-command: version
+    default-command: snapshots
     initialize: false
     priority: low
     systemd-unit-template: sample.service
diff --git a/examples/v2._yaml b/examples/v2.yaml
similarity index 100%
rename from examples/v2._yaml
rename to examples/v2.yaml
diff --git a/examples/windows.conf b/examples/windows.toml
similarity index 100%
rename from examples/windows.conf
rename to examples/windows.toml
diff --git a/main_profile.go b/run_profile.go
similarity index 100%
rename from main_profile.go
rename to run_profile.go
diff --git a/sonar-project.properties b/sonar-project.properties
index 3ac2d3c0..6e0cb69e 100644
--- a/sonar-project.properties
+++ b/sonar-project.properties
@@ -1,7 +1,7 @@
 sonar.organization=creativeprojects
 sonar.projectKey=creativeprojects_resticprofile
 sonar.projectName=resticprofile
-sonar.projectVersion=0.27.0
+sonar.projectVersion=0.28.0
 
 sonar.sources=.
 sonar.exclusions=**/*_test.go,/docs/**


Test patch:
diff --git a/main_profile_test.go b/run_profile_test.go
similarity index 100%
rename from main_profile_test.go
rename to run_profile_test.go