Annoying behaviour of file:resolve-path

Tuesday, 28 October 2014 · 5 messages
MG
Marc van Grootel28 Oct 2014 10:31 #
Hi, For a while I wasn't aware, then I noticed it and then I got annoyed by it. It's not a big issue but it does require extra code to work around this, in my opinion, annoying behaviour. When using file:resolve-path it depends if the file exists or not. The output is different. Say I have an existing directory F:\tmp then
  file:resolve-path('F:/tmp') => F:\tmp\
However, when I have a path that points to a non-existing directory (or file, we cannot know!)
  file:resolve-path('F:/tmp/not-exists') => F:/tmp/not-exists
Notice the absence of a slash. I guess the assumption that is made is that in the future this will refer to a file and not a directory. The same behaviour occurs with file:path-to-uri(), and file:base-dir() also returns a path with a trailing slash. I think that this is annoying, or let's say at least, inconsistent behaviour and had me add code that defensively strips of trailing slash. I cannot rely on file:resolve-path results because if a directory doesn't exist it has no slash at the end, and if it does it has and sometimes I don't want to check for existence at that point. When combining paths I tend to use string-join($parts,'/') and having slash at the end of URL's and filesystem paths doesn't feel right so I always strip them off. Hope I didn't sound too grumpy ;-) Opinions? Guess, changing it would trip up a lot of existing path handling code. --Marc
CG
Christian Grün28 Oct 2014 15:03 #
Hi Marc, this behavior is compliant with the current spec [1]: The file:resolve-path function is non-deterministic, because its result is dependent on both the existence of the targeted file and the current working directory. If you want to address non-existing directories, you will indeed have to add the directory separator. By looking at your example…
Quoted text · Marc van Grootel · 1 line
> file:resolve-path('F:/tmp') => F:\tmp\
…I was wondering why you use file:resolve-path at all, and why you don't simply take your original path string for further operations? Best, Christian [1] http://expath.org/spec/file#fn.resolve-path
Quoted text · Marc van Grootel · 40 lines
On Tue, Oct 28, 2014 at 10:31 AM, Marc van Grootel <marc.van.grootel at gmail.com> wrote: > Hi, > > For a while I wasn't aware, then I noticed it and then I got annoyed > by it. It's not a big issue but it does require extra code to work > around this, in my opinion, annoying behaviour. > > When using file:resolve-path it depends if the file exists or not. The > output is different. > > Say I have an existing directory F:\tmp then > > file:resolve-path('F:/tmp') => F:\tmp\ > > However, when I have a path that points to a non-existing directory > (or file, we cannot know!) > > file:resolve-path('F:/tmp/not-exists') => F:/tmp/not-exists > > Notice the absence of a slash. I guess the assumption that is made is > that in the future this will refer to a file and not a directory. > > The same behaviour occurs with file:path-to-uri(), and file:base-dir() > also returns a path with a trailing slash. > > I think that this is annoying, or let's say at least, inconsistent > behaviour and had me add code that defensively strips of trailing > slash. I cannot rely on file:resolve-path results because if a > directory doesn't exist it has no slash at the end, and if it does it > has and sometimes I don't want to check for existence at that point. > When combining paths I tend to use string-join($parts,'/') and having > slash at the end of URL's and filesystem paths doesn't feel right so I > always strip them off. > > Hope I didn't sound too grumpy ;-) > Opinions? > Guess, changing it would trip up a lot of existing path handling code. > > --Marc
MG
Marc van Grootel28 Oct 2014 15:29 #
Hi Christian, Sorry in my example I should've used a relative path because that's what I'm processing most of the time and I use it to resolve to an absolute path. However I'm working with file sets for which the directory at that time may not yet exist. Hmm it's in the spec. Didn't know about that. Coming from Java I would say that this is not what I expect. A java.io.File object may represent both a file or a dir and when getting its absolute path it doesn't attach a slash. File:resolve-path mixes up file existence with path handling. Guess, I will keep the 'fix' in a wrapper function then. Personally I don't see the rationale for this in the spec. --Marc
Quoted text · Christian Grün · 64 lines
On Tue, Oct 28, 2014 at 3:03 PM, Christian Grün <christian.gruen at gmail.com> wrote: > Hi Marc, > > this behavior is compliant with the current spec [1]: The > file:resolve-path function is non-deterministic, because its result is > dependent on both the existence of the targeted file and the current > working directory. If you want to address non-existing directories, > you will indeed have to add the directory separator. > > By looking at your example… > >> file:resolve-path('F:/tmp') => F:\tmp\ > > …I was wondering why you use file:resolve-path at all, and why you > don't simply take your original path string for further operations? > > Best, > Christian > > [1] http://expath.org/spec/file#fn.resolve-path > > > > On Tue, Oct 28, 2014 at 10:31 AM, Marc van Grootel > <marc.van.grootel at gmail.com> wrote: >> Hi, >> >> For a while I wasn't aware, then I noticed it and then I got annoyed >> by it. It's not a big issue but it does require extra code to work >> around this, in my opinion, annoying behaviour. >> >> When using file:resolve-path it depends if the file exists or not. The >> output is different. >> >> Say I have an existing directory F:\tmp then >> >> file:resolve-path('F:/tmp') => F:\tmp\ >> >> However, when I have a path that points to a non-existing directory >> (or file, we cannot know!) >> >> file:resolve-path('F:/tmp/not-exists') => F:/tmp/not-exists >> >> Notice the absence of a slash. I guess the assumption that is made is >> that in the future this will refer to a file and not a directory. >> >> The same behaviour occurs with file:path-to-uri(), and file:base-dir() >> also returns a path with a trailing slash. >> >> I think that this is annoying, or let's say at least, inconsistent >> behaviour and had me add code that defensively strips of trailing >> slash. I cannot rely on file:resolve-path results because if a >> directory doesn't exist it has no slash at the end, and if it does it >> has and sometimes I don't want to check for existence at that point. >> When combining paths I tend to use string-join($parts,'/') and having >> slash at the end of URL's and filesystem paths doesn't feel right so I >> always strip them off. >> >> Hope I didn't sound too grumpy ;-) >> Opinions? >> Guess, changing it would trip up a lot of existing path handling code. >> >> --Marc
-- --Marc
CG
Christian Grün28 Oct 2014 15:58 #
Quoted text · Marc van Grootel · 4 lines
> Sorry in my example I should've used a relative path because that's > what I'm processing most of the time and I use it to resolve to an > absolute path. However I'm working with file sets for which the > directory at that time may not yet exist.
I see. Personally, I didn't use file:resolve-path() at all; what's your reason for working with absolute paths?
Quoted text · Marc van Grootel · 2 lines
> Guess, I will keep the 'fix' in a wrapper function then. Personally I > don't see the rationale for this in the spec.
It's surely something that could be discussed a bit more (however, it could already a bit late). C.
MG
Marc van Grootel28 Oct 2014 16:26 #
My use case may well be not very typical. I have created an abstraction for passing sets of filesystem or database resources (resource sets) around. They achieve something similar as Ant file sets and have an XML representation but internally are represented as maps. When creating them I want to make sure they point to a specific location that cannot change. I also pass information from these resource sets into XSLT (which may have an entirely different concept of current dir) and it needs to be able to find these resources as well. Here's a serialized example of such a resource set.
{
  "meta": {
    "export-date": "27-10-2014",
  },
  "base": "file:///F:/home/marcg/work/projects/website/_from_cms/locale/EN/xml",
  "selectors": {
    "includes": "*.xml",
    "excludes": ()
  },
  "type": "set",
  "id": "source"
}
--Marc
Quoted text · Christian Grün · 17 lines
On Tue, Oct 28, 2014 at 3:58 PM, Christian Grün <christian.gruen at gmail.com> wrote: >> Sorry in my example I should've used a relative path because that's >> what I'm processing most of the time and I use it to resolve to an >> absolute path. However I'm working with file sets for which the >> directory at that time may not yet exist. > > I see. Personally, I didn't use file:resolve-path() at all; what's > your reason for working with absolute paths? > >> Guess, I will keep the 'fix' in a wrapper function then. Personally I >> don't see the rationale for this in the spec. > > It's surely something that could be discussed a bit more (however, it > could already a bit late). > > C.
-- --Marc

⚡Generated with XQuery