Skip to content
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

ResourcesItem specification might be incomplete #181

Open
adpi2 opened this issue Jun 17, 2021 · 7 comments
Open

ResourcesItem specification might be incomplete #181

adpi2 opened this issue Jun 17, 2021 · 7 comments

Comments

@adpi2
Copy link
Member

adpi2 commented Jun 17, 2021

Related to sbt/sbt#6550 and sbt/sbt#6552

According to the specification, the ResourcesItem contains

export interface ResourcesItem {
  target: BuildTargetIdentifier;
  /** List of resource files. */
  resources: Uri[];
}

I think this is incomplete because the build client might want to know for each resource URI if it is a file or a directory. In the case it is a file, it does not know the relative path of the file to be copied to the target directory.

@jastice Is this part already implemented in IntelliJ and how? Do you think it is worth improving this part of the spec?

As a comparison the content of a SourcesItem is:

export interface SourcesItem {
  target: BuildTargetIdentifer;
  /** The text documents or and directories that belong to this build target. */
  sources: SourceItem[];
  /** The root directories from where source files should be relativized.
   *
   * Example: ["file://Users/name/dev/metals/src/main/scala"]
   */
  roots?: Uri[];
}

export interface SourceItem {
  /** Either a text document or a directory. A directory entry must end with a forward
   * slash "/" and a directory entry implies that every nested text document within the
   * directory belongs to this source item.
   */
  uri: Uri;

  /** Type of file of the source item, such as whether it is file or directory.
   */
  kind: SourceItemKind;

  /** Indicates if this source is automatically generated by the build and is not
   * intended to be manually edited by the user. */
  generated: Boolean;
}
@olafurpg
Copy link
Member

I think this is incomplete because the build client might want to know for each resource URI if it is a file or a directory.

URIs ending with / should be treated as a directory, same as for SourceItem. I think this is a standard convention for URIs.

In the case it is a file, it does not know the relative path of the file to be copied to the target directory.

My understanding is that files should get added directly to the runtime classpath, without getting relativized by a directory. I'm not sure what effect that has however, I'm unable to load up a resource file that was added directly to the classpath.

❯ scala -cp $PWD/FuzzySearch.ts
Welcome to Scala 2.13.4 (OpenJDK 64-Bit Server VM, Java 1.8.0_292).
Type in expressions for evaluation. Or try :help.

scala> this.getClass.getResource("/FuzzySearch.ts")
val res0: java.net.URL = null

scala> this.getClass.getClassLoader.getResource("/FuzzySearch.ts")
val res1: java.net.URL = null

scala> this.getClass.getClassLoader.getResource("FuzzySearch.ts")
val res2: java.net.URL = null

scala> this.getClass.getResource("FuzzySearch.ts")
val res3: java.net.URL = null

@olafurpg
Copy link
Member

The roots docstring should use a trailing slash for the example ["file://Users/name/dev/metals/src/main/scala/"]

@adpi2
Copy link
Member Author

adpi2 commented Jun 18, 2021

My understanding is that files should get added directly to the runtime classpath, without getting relativized by a directory. I'm not sure what effect that has however, I'm unable to load up a resource file that was added directly to the classpath.

Well yes that should work but it would be better if made explicit in the data structure and specification of ResourcesItem.

Also I think the client might need to know if a resource is generated or not for the same reason as a SourceItem:

/** Indicates if this source is automatically generated by the build and is not
   * intended to be manually edited by the user. */

So I think it is worth aligning the ResourceItems structure and spec with the existing SourceItems. It would look like this:

export interface ResourcesItem {
  target: BuildTargetIdentifer;
  /** The resource files or and directories that belong to this build target. */
  resources: ResourceItem[];
}

export interface ResourceItem {
  /** Either a file or a directory.
   * A directory entry must end with a forward slash "/".
   * A directory entry implies that every nested file within the
   * directory belongs to this resource item.
   */
  uri: Uri;

  /** Type of file of the source item, such as whether it is file or directory.
   */
  kind: ResourceItemKind;

  /** Indicates if this resource is automatically generated by the build and is not
   * intended to be manually edited by the user. */
  generated: Boolean;
}

export namespace ResourceItemKind {
  /** The resource item references a normal file.  */
  export const File: Int = 1;
  /** The resource item references a directory. */
  export const Directory: Int = 2;
}

@jastice
Copy link
Member

jastice commented Jun 22, 2021

Yes, not fixing this was an oversight that I've been procrastinating on fixing ever since I noticed it after we changed SourceItem ...

The problem now is that changing ResourcesItem to the same format as SourcesItem would be an incompatible change, and we have somewhat more API adoption now. Ideas on this? One way would be to put it behind a new request, so that clients/servers that know only the old request can continue to work with that. Of course that adds additional work for implementors on both sides.

@github-samuel-clarenc
Copy link

Yes it's indeed a breaking change, a new request will probably be a good solution.

It still remains to find a relevant name for this new request !

@adpi2
Copy link
Member Author

adpi2 commented Jun 22, 2021

Or we can mix the old spec with the new spec so that all the old and new clients/servers can talk to each other:

export interface ResourcesItem {
  target: BuildTargetIdentifer;

  /** The resource files or and directories that belong to this build target. */
  resourceItems: ResourceItem[]

  /** Deprecated version of the resourceItems field
  * Servers should provide it to maintain the compatibility with older clients
  * Clients should try to read resourceItems first and fallback to resources if 
  * resourceItems is not defined.
  */
  resources: Uri[];
}

@jastice
Copy link
Member

jastice commented Jun 22, 2021

Yup, I was thinking that, though it would duplicate some data. But it would keep the implementations simpler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants