-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(#165): reserved-name
lint
#440
Conversation
reserved-name
lint
@volodya-lombrozo updated. Take a look, please |
private static final Pattern NON_UNIX = Pattern.compile("\\\\"); | ||
|
||
/** | ||
* Reserved names. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@h1alexbel I was reading this file and asked myself several times what the keys and values are. I guess a key here is an object name and a value is an object path. Am I right? If so, it would be better to clarify this in the Javadocs.
* @checkstyle IllegalCatchCheck (15 lines) | ||
*/ | ||
@SuppressWarnings("PMD.AvoidCatchingGenericException") | ||
private static Consumer<Path> jar(final Map<String, String> names) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@h1alexbel What is the difference between file
and jar
methods? Aren't they the same?
This code looks similar to me:
parsed = new EoSyntax(
"reserved", new UncheckedInput(new InputOf(eo.toFile()))
).parsed();
and
InputStream input = Files.newInputStream(eo)
parsed = new EoSyntax(
"reserved", new TextOf(input).asString()
).parsed();
Moreover, under the hood EoSyntax
will wrap the string from the last example to the same Input
:
public EoSyntax(final String nme, final String ipt) {
this(nme, new InputOf(ipt));
}
Maybe I'm missing something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@volodya-lombrozo in the jar
method, we need to read the content from the input
first, and only then parse it, otherwise we are getting:
Caused by: java.io.EOFException: Unexpected end of ZLIB input stream
at jdk.zipfs/jdk.nio.zipfs.ZipFileSystem$2.fill(ZipFileSystem.java:2275)
at java.base/java.util.zip.InflaterInputStream.read(InflaterInputStream.java:175)
at org.cactoos.io.TeeInputStream.read(TeeInputStream.java:61)
at org.cactoos.io.TeeInputStream.read(TeeInputStream.java:55)
at org.cactoos.bytes.InputAsBytes.asBytes(InputAsBytes.java:63)
at org.cactoos.bytes.BytesOf.asBytes(BytesOf.java:732)
at org.cactoos.text.TextOf.lambda$new$0(TextOf.java:272)
at org.cactoos.text.TextOfScalar.asString(TextOfScalar.java:39)
at org.cactoos.text.TextEnvelope.asString(TextEnvelope.java:32)
at org.cactoos.text.Split.lambda$new$0(Split.java:108)
at org.cactoos.scalar.Checked.value(Checked.java:56)
at org.cactoos.scalar.IoChecked.value(IoChecked.java:44)
at org.cactoos.scalar.Unchecked.value(Unchecked.java:37)
... 34 more
Also, we cannot convert Path
in jar
to file:
Caused by: java.lang.UnsupportedOperationException
at jdk.zipfs/jdk.nio.zipfs.ZipPath.toFile(ZipPath.java:673)
at org.eolang.lints.LtReservedName.lambda$jar$3(LtReservedName.java:199)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1939)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
at org.eolang.lints.LtReservedName.home(LtReservedName.java:148)
at org.eolang.lints.LtReservedName.<init>(LtReservedName.java:61)
at org.eolang.lints.MonoLints.<clinit>(MonoLints.java:35)
... 6 more
* @param names Names | ||
* @return File consumer from path | ||
*/ | ||
private static Consumer<Path> file(final Map<String, String> names) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@h1alexbel To be honest, I have some doubts about the design of file()
, jar()
, and processXmir()
. In all of these methods, you pass a final Map<String, String> names
to populate it. This approach works well and is efficient. However, it feels a bit overcomplicated to me and relies on indirection through Consumer<Path>
.
Could we transform these methods from manipulators to builders (similar to the home()
method)? What I mean is that it might be better to change their signatures from
Consumer<Path> file(final Map<String, String> names)
to something like
Map<String, String> file(final Path path)
or
Entry<Map<String, String>> file(final Path path)
Then, instead of the following code:
Files.walk(Paths.get(resource.toURI()))
.filter(sources)
.forEach(LtReservedName.file(names));
You could use something like:
Files.walk(Paths.get(resource.toURI()))
.filter(sources)
.map(LtReservedName::file)
.toMap()
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@volodya-lombrozo yes, indeed it overcomplicated, refactoring to Map<String, String> namesInFile(Path path)
now.
@volodya-lombrozo updated. Take a look, please |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@h1alexbel Thank you for the changes. Now it's much better. I've left one more question.
.toString().replace("\\", "/") | ||
); | ||
}; | ||
if ("jar".equals(resource.getProtocol())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@h1alexbel Can you somehow get a jar here? As I understood, you copy all the .eo
files from https://github.com/objectionary/home.git and then just look object inside of them. Please, correct me if I'm wrong. Thus, how can you can get a jar
here? Moreover, you have the only one constructor:
LtReservedName() {
this(LtReservedName.home(Paths.get("cloned", "home").toString()));
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@volodya-lombrozo during the build of the lints
project, we are cloning home using git clone https://github.com/objectionary/home.git
to clone it to the build directory: ${project.build.directory}/cloned/home
. Then, to be able reuse those files outside of lints
, when we are importing lints
project - we copy ${project.build.directory}/cloned/home
to classes in lints JAR: ${project.build.directory}/classes/cloned/home
.
This expression if ("jar".equals(resource.getProtocol())) {
returns true, when dependent on lint project executes linting via Program
. Such example is our invoker integration test. While, in local tests, cloned home repo will be accessed as normal file.
Both methods depend on the same directory, which we pass in the ctor: cloned/home
, the only difference in the term of access - for JAR we need to "mount" the file system using java.nio.file.FileSystem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@h1alexbel I see, thank you for the comprehensive explanation. Now it's clear. Could you add this explanation to the JavaDocs, please? It will greatly help other developers to understand what is going on.
Also I would highly recommend simplifying the solution. For example, you can generate a list of objects during the lints
build and just reuse it in runtime. Yes, it's a less dynamic approach and each time when eo
changes we will need to rebuild and release lints
, but it's much more reliable solution (KISS principle). However, It's better to discuss in a separate issue. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@volodya-lombrozo yes, I will add this information to the JavaDocs. About simplification, let's discuss in a separate issue.
.toString().replace("\\", "/") | ||
); | ||
}; | ||
if ("jar".equals(resource.getProtocol())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@h1alexbel I see, thank you for the comprehensive explanation. Now it's clear. Could you add this explanation to the JavaDocs, please? It will greatly help other developers to understand what is going on.
Also I would highly recommend simplifying the solution. For example, you can generate a list of objects during the lints
build and just reuse it in runtime. Yes, it's a less dynamic approach and each time when eo
changes we will need to rebuild and release lints
, but it's much more reliable solution (KISS principle). However, It's better to discuss in a separate issue. What do you think?
@volodya-lombrozo added JavaDoc. Take a look, please |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@h1alexbel Looks good to me. Thanks.
@yegor256 take a look, please |
pom.xml
Outdated
<configuration> | ||
<executable>git</executable> | ||
<arguments> | ||
<argument>clone</argument> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@h1alexbel maybe a shallow copy will be enough? Full git clone is very time/space expensive.
pom.xml
Outdated
<arguments> | ||
<argument>clone</argument> | ||
<argument>https://github.com/objectionary/home.git</argument> | ||
<argument>${project.build.directory}/cloned/home</argument> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@h1alexbel try to do this: mvn clean install && mvn install
and see the result
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@h1alexbel maybe it's better to use git submodule
instead of git clone
? Or maybe just wget
to download master from home in ZIP archive?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yegor256 wget
will fail on windows. Am I understood correctly that we should add home
repo as Git submodule to the lints
repo?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@h1alexbel this one can do the same as wget: https://github.com/download-maven-plugin/download-maven-plugin
@h1alexbel many thanks for the contribution! See a few comments above. |
@yegor256 updated. Take a look, please |
@rultor merge |
In this PR I've implemented new lint:
reserved-name
, that issues defect withwarning
severity if object uses name, already reserved by object inorg.eolang.*
package.closes #165
History: