Skip to content

Commit 77a0e21

Browse files
committed
feat (core): Initial version of working $proto link on UI - yay!
This commit is the accumulation of the work I've done over the past few week-ends; see #451 for history. There is some unrelated early code in here which is related to more things to come soon-ish.
1 parent 5f39817 commit 77a0e21

File tree

58 files changed

+1464
-135
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1464
-135
lines changed

.bazelrc

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
common --enable_bzlmod
55
common --extra_toolchains=@local_jdk//:all
66

7+
# Java version must match .devcontainer/devcontainer.json
78
# https://bazel.build/docs/bazel-and-java#java-versions
89
build --java_language_version=21
910
build --tool_java_language_version=21

.devcontainer/devcontainer.json

+5
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,13 @@
2222

2323
// Features to add to the dev container. More info: https://containers.dev/features.
2424
"features": {
25+
// Java version must match .bazelrc
2526
"ghcr.io/devcontainers/features/java:1": {
2627
"version": "21"
28+
},
29+
// protoc is used by tools/protoc/protoc.bash
30+
"ghcr.io/devcontainers-contrib/features/protoc-asdf:1": {
31+
"version": "3.6.1"
2732
}
2833
},
2934

.editorconfig

+3
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,17 @@ max_line_length = unset
4747
max_line_length = unset
4848
indent_size = 2
4949
tab_width = 2
50+
max_line_length = unset
5051

5152
[*.jsonc]
5253
indent_size = 2
5354
tab_width = 2
55+
max_line_length = unset
5456

5557
[*.json5]
5658
indent_size = 2
5759
tab_width = 2
60+
max_line_length = unset
5861

5962
[*.toml]
6063
indent_size = 2

.github/dependabot.yml

+7
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,10 @@ updates:
1414
day: monday
1515
time: "04:00"
1616
open-pull-requests-limit: 99
17+
- package-ecosystem: "devcontainers"
18+
directory: "/"
19+
schedule:
20+
interval: "monthly"
21+
day: monday
22+
time: "04:00"
23+
open-pull-requests-limit: 99

.pre-commit-config.yaml

+35-4
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,44 @@ repos:
152152
hooks:
153153
- id: csslint
154154

155-
# https://editorconfig.org check should run AFTER all of the formatters (above)
156-
- repo: https://github.com/editorconfig-checker/editorconfig-checker.python
157-
rev: 2.7.3
155+
# https://yamllint.readthedocs.io/en/stable/integration.html#integration-with-pre-commit
156+
- repo: https://github.com/adrienverge/yamllint.git
157+
rev: v1.33.0
158158
hooks:
159-
- id: editorconfig-checker
159+
- id: yamllint
160+
# https://yamllint.readthedocs.io/en/stable/configuration.html#errors-and-warnings
161+
args: [--strict]
160162

161163
- repo: https://github.com/shellcheck-py/shellcheck-py
162164
rev: v0.9.0.6
163165
hooks:
164166
- id: shellcheck
167+
168+
- repo: https://github.com/python-jsonschema/check-jsonschema
169+
rev: 0.28.0
170+
hooks:
171+
- id: check-github-actions
172+
args: ["--verbose"]
173+
- id: check-github-workflows
174+
args: ["--verbose"]
175+
- id: check-dependabot
176+
args: ["--verbose"]
177+
- id: check-renovate
178+
args: ["--verbose"]
179+
- id: check-metaschema
180+
files: \.schema\.json$
181+
args: ["--verbose"]
182+
# TODO Change once https://github.com/python-jsonschema/check-jsonschema/issues/340 is implemented
183+
- id: check-jsonschema
184+
# files: .+/models/.+\.(yaml|json)$
185+
files: \.types\.yaml$
186+
args: ["--verbose", "--schemafile", "docs/models/enola/schemas/Types.schema.json"]
187+
- id: check-jsonschema
188+
files: \.type\.yaml$
189+
args: ["--verbose", "--schemafile", "docs/models/enola/schemas/Type.schema.json"]
190+
191+
# https://editorconfig.org check should run AFTER all of the formatters (above)
192+
- repo: https://github.com/editorconfig-checker/editorconfig-checker.python
193+
rev: 2.7.3
194+
hooks:
195+
- id: editorconfig-checker

.vscode/extensions.json

+6-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
"zignd.html-css-class-completion",
1717
"timonwong.shellcheck"
1818
],
19-
// https://github.com/kshetline/ligatures-limited/issues/39
20-
"unwantedRecommendations": ["kshetline.ligatures-limited"]
19+
"unwantedRecommendations": [
20+
// https://github.com/kshetline/ligatures-limited/issues/39
21+
"kshetline.ligatures-limited",
22+
"vscjava.vscode-gradle",
23+
"vscjava.vscode-maven"
24+
]
2125
}

.yamllint.yaml

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
#
3+
# Copyright 2024 The Enola <https://enola.dev> Authors
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
# https://yamllint.readthedocs.io/en/stable/configuration.html
18+
19+
rules:
20+
# Let's just check this only via .editorconfig instead
21+
line-length: disable

cli/src/main/java/dev/enola/cli/CommandWithModel.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,14 @@
1919

2020
import dev.enola.common.io.resource.ResourceProviders;
2121
import dev.enola.core.EnolaServiceProvider;
22+
import dev.enola.core.Repository;
2223
import dev.enola.core.grpc.EnolaGrpcClientProvider;
2324
import dev.enola.core.grpc.EnolaGrpcInProcess;
2425
import dev.enola.core.grpc.ServiceProvider;
2526
import dev.enola.core.meta.EntityKindRepository;
27+
import dev.enola.core.meta.proto.Type;
2628
import dev.enola.core.proto.EnolaServiceGrpc.EnolaServiceBlockingStub;
29+
import dev.enola.core.type.TypeRepositoryBuilder;
2730

2831
import picocli.CommandLine.ArgGroup;
2932
import picocli.CommandLine.Model.CommandSpec;
@@ -54,7 +57,9 @@ public final void run() throws Exception {
5457
var modelResource = new ResourceProviders().getReadableResource(group.model);
5558
ekr = new EntityKindRepository();
5659
ekr.load(modelResource);
57-
esp = new EnolaServiceProvider(ekr);
60+
Repository<Type> tyr = new TypeRepositoryBuilder().build();
61+
// TODO --types for Types (and more?), e.g. from MD, YAML, textproto, etc.
62+
esp = new EnolaServiceProvider(ekr, tyr);
5863
var enolaService = esp.getEnolaService();
5964
grpc = new EnolaGrpcInProcess(esp, enolaService, false); // direct, single-threaded!
6065
gRPCService = grpc.get();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* Copyright 2024 The Enola <https://enola.dev> Authors
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* https://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package dev.enola.common.io.mediatype;
19+
20+
import static com.google.common.net.MediaType.create;
21+
22+
import com.google.common.base.Charsets;
23+
import com.google.common.collect.ImmutableMap;
24+
import com.google.common.collect.ImmutableSet;
25+
import com.google.common.net.MediaType;
26+
27+
import java.util.Map;
28+
import java.util.Set;
29+
30+
/**
31+
* The "text/markdown" media type, as per <a href="https://www.rfc-editor.org/rfc/rfc7763.html">RFC
32+
* 7763</a> (and <a href="https://www.rfc-editor.org/rfc/rfc7764.html">RFC 7764</a>).
33+
*/
34+
public class MarkdownMediaTypes implements MediaTypeProvider {
35+
36+
// TODO Distinguish https://commonmark.org from GFH et al. via a variant parameter; see
37+
// https://www.iana.org/assignments/markdown-variants/markdown-variants.xhtml
38+
39+
public static final MediaType MARKDOWN_UTF_8 =
40+
create("text", "markdown").withCharset(Charsets.UTF_8);
41+
;
42+
43+
@Override
44+
public Map<String, MediaType> extensionsToTypes() {
45+
return ImmutableMap.of("md", MARKDOWN_UTF_8);
46+
}
47+
48+
@Override
49+
public Map<MediaType, Set<MediaType>> knownTypesWithAlternatives() {
50+
return ImmutableMap.of(MARKDOWN_UTF_8, ImmutableSet.of(create("text", "x-markdown")));
51+
}
52+
}

common/common/src/main/java/dev/enola/common/io/mediatype/MediaTypeProvider.java

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
import java.util.Set;
2424

2525
public interface MediaTypeProvider {
26+
27+
// TODO An implementation based on enola.dev/mediaType Type YAML/binary!
28+
2629
Map<MediaType, Set<MediaType>> knownTypesWithAlternatives();
2730

2831
Map<String, MediaType> extensionsToTypes();

common/common/src/main/java/dev/enola/common/io/mediatype/YamlMediaType.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
import com.google.common.base.Charsets;
2323
import com.google.common.collect.ImmutableMap;
24-
import com.google.common.collect.Sets;
24+
import com.google.common.collect.ImmutableSet;
2525
import com.google.common.net.MediaType;
2626

2727
import java.util.Map;
@@ -41,7 +41,7 @@ public class YamlMediaType implements MediaTypeProvider {
4141
public Map<MediaType, Set<MediaType>> knownTypesWithAlternatives() {
4242
return ImmutableMap.of(
4343
YAML_UTF_8,
44-
Sets.newHashSet(
44+
ImmutableSet.of(
4545
create("text", "yaml"),
4646
create("text", "x-yaml"),
4747
create("application", "x-yaml")));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* Copyright 2024 The Enola <https://enola.dev> Authors
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* https://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package dev.enola.common.io.resource;
19+
20+
import com.google.common.collect.ImmutableMap;
21+
import com.google.common.collect.ImmutableSet;
22+
23+
import java.io.IOException;
24+
25+
public class DelegatingMultipartResource extends ReadableButNotWritableDelegatingResource
26+
implements MultipartResource {
27+
28+
private final ImmutableMap<String, Resource> parts;
29+
30+
public DelegatingMultipartResource(
31+
ReadableResource baseResource, ImmutableMap<String, Resource> parts)
32+
throws IOException {
33+
super(baseResource);
34+
this.parts = parts;
35+
}
36+
37+
@Override
38+
public ImmutableSet<String> parts() {
39+
return parts.keySet();
40+
}
41+
42+
@Override
43+
public Resource part(String name) {
44+
var r = parts.get(name);
45+
if (r == null)
46+
throw new IllegalArgumentException(
47+
"Only " + parts().toString() + ", invalid part: " + name);
48+
else return r;
49+
}
50+
}

common/common/src/main/java/dev/enola/common/io/resource/EmptyResource.java

+15-7
Original file line numberDiff line numberDiff line change
@@ -22,30 +22,38 @@
2222
import com.google.common.net.MediaType;
2323

2424
import java.net.URI;
25+
import java.util.function.Supplier;
2526

2627
/**
27-
* Resources which when read is always immediately EOF. Note that this is read-only, and
28-
* intentionally does not implement WritableResource; use e.g. {@link ResourceProviders#getResource}
29-
* with "empty:-" to get a wrapped implementation that implements writable but throws an error.
28+
* Read-only resources which when read are always immediately EOF. This is a bit like /dev/null on
29+
* *NIX OS for reading, but not for writing (because /dev/null ignores writes, whereas this fails).
3030
*
31-
* @see NullResource for an alternatives that returns 0s instead of EOF.
31+
* @see NullResource for an alternatives that returns infinite 0s instead of EOF.
3232
*/
33-
public class EmptyResource implements ReadableResource {
33+
public class EmptyResource implements ReadableButNotWritableResource {
3434
// TODO Perhaps rename this to VoidResource with void:/ URI?
3535

3636
static final String SCHEME = "empty";
3737
private static final URI EMPTY_URI = URI.create(SCHEME + ":?");
38-
private final MediaType mediaType;
3938

40-
private final URI uri;
39+
private final MediaType mediaType;
40+
private final Supplier<URI> uriSupplier;
41+
private URI uri;
4142

4243
public EmptyResource(MediaType mediaType) {
4344
this.mediaType = mediaType;
4445
this.uri = URIs.addMediaType(EMPTY_URI, mediaType);
46+
this.uriSupplier = null;
47+
}
48+
49+
public EmptyResource(MediaType mediaType, Supplier<URI> uriSupplier) {
50+
this.mediaType = mediaType;
51+
this.uriSupplier = uriSupplier;
4552
}
4653

4754
@Override
4855
public URI uri() {
56+
if (uri == null) uri = uriSupplier.get();
4957
return uri;
5058
}
5159

0 commit comments

Comments
 (0)