Confusing doc on "Working with files"

It seems that the doc contradicts itself twice within a few lines, and I wonder whether I’m just incorrectly reading it.

In Single files and directories, we can read:

Never use new File(relative path) because this creates a path relative to the current working directory (CWD)

And then a few lines below in the example code snippet, new File() is used with a relative path:

configFile = file(new File('src/config.xml'))

Maybe the doc meant to read "unless passed to file()", but then the next section on File collections comes, and we can explicitly read:

Although the files() method accepts File instances, never use new File(relative path) with it because this creates a path relative to the current working directory (CWD)

And literally in the example for this section a few lines below:

FileCollection collection = layout.files('src/file1.txt',
                                  new File('src/file2.txt'),
                                  ['src/file3.csv', 'src/file4.csv'],
                                  Paths.get('src', 'file5.txt'))

What am I missing here? Are the code examples incorrect or is the warning incorrect?

You got it exactly right.

It should read "never use with relative path unless passed to file() or files() or from() or other methods being defined in terms of file() or files()" and the second warning is misleading.

The examples are fine actually, though I would avoid doing it like that, it is mainly useful for cases where you have a File instance and don’t know whether it is relative or absolute and if relative, then should be relative to the project directory.

Actually it is a good advice for almost any Java program to be careful.
Whenever you use a relative path as argument to File constructor or FileInputStream constructor or similar, it is interpreted relative to the current working directory. So if you develop a tool where the user specifies a file to process on the commandline, that is exactly what you want to have.
But if you want to read a file that lies somewhere known, like in subfolder X below the start script of the tool, or in folder Y of the project you are building, then it is very bad practice to depend on the current working directory.
In case of Gradle this often actually is the project directory and will work but it is not guaranteed and there are indeed cases where it will not be the project directory and in the future maybe never is the project directory, so any build depending on this is actually buggy.

But, the docs of file(...) and files(...) explicitly state both that they properly handle relative paths and relative File instances, resolving them relative to the project directory, hence the second warning seems to be totally wrong. And also all other methods like ConfigurableFileCollection#from and others defining their behavior in terms of file(...) or files(...) should handle it properly, otherwise that would be a bug.

Where it is important is, if a File instance is used directly, not filtered through file(...) directly or indirectly.

1 Like

Very clear, thanks. Do you know how to report a problem with the doc or contribute a change?

Same as with code.
The docs are in the same repository.
Just open an issue, or of course optimally a PR.

It’s the first thing I tried, but the issue templates didn’t seem to account for this kind of issues, and the last option directed me here.

I guess I’ll file it as a bug then, but it doesn’t seem right.

Sure, it is a documentation bug. :slight_smile: