goreleaser/nfpm

Recursive globs behaviour has changed

nhooyr opened this issue · 14 comments

See #232 (comment)

This seems to have broken recursive globs like the following:
https://github.com/cdr/code-server/blob/1826399cd230acc1f62556a5af7bba9c25a03a25/ci/build/nfpm.yaml#L19

./release-standalone/**/*: "/usr/lib/code-server/"

Only files two levels below the top level are copied now whereas before all files were.
Caused a regression in code-server as nfpm wouldn't include the files in ./release-standalone/* but only ./release-standalone/*/**/*. i.e only files in subdirectories of the top level.
See coder/code-server#2310

The previous behavior was "wrong"... you can try it with ls. I think what you want is ./release-standalone/**.

**/* implies only files within subdirectories.

I will make this change clearer on the release notes though.

Hm, I thought so too at first (that **/* implies only files with subdirectories). However, I just tested it with three files that contain their own file name. This way I can demonstrate it with cat which does does do special directory processing like ls:

$ tree
.
├── a
│   └── b
│       └── f1
├── c
│   └── f2
└── f3

3 directories, 3 files

$ cat ./**/*
cat: ./a: Is a directory
cat: ./a/b: Is a directory
f1
cat: ./c: Is a directory
f2
f3

$ echo $SHELL
/bin/zsh

$ /bin/zsh --version
zsh 5.7.1 (x86_64-apple-darwin19.0)

So could indeed be a bug in https://github.com/gobwas/glob that we mistook for a feature.

They probably would match ** to an empty string but don't collapse multiple separator characters so ./**/* would match .//foo which we consider equivalent to ./foo.

This indeed seems to be what's happening: https://play.golang.org/p/geU9afuijny

There is also a closed issue for this (gobwas/glob#20). It seems like gobwas thinks that the current behaviour is correct. I made a new issue though: gobwas/glob#46

yeah, makes sense @erikgeiser 🤔

Maybe we could hack around it and replace **/* with ** only? 🤔
No idea about the side effects of this though

Ah, I thought I tried ** at some point and nfpm didn't see any files but it must have been PEBCAK.

I'll switch to that and upgrade us back.

PEBCAK

TIL: PEBCAK 🤣

I'm not sure any solution is right. There seem to be so many glob variants that behave differently in these exact cases. This behavior is also configurable in many shells. We probably just have to decide on a behavior we like.

Just hacking around on the pattern before compiling does not seem like a good long term solution through.

Maybe forking is a good workaround for now?

First we need to decide what we'll do exactly. We can't really rely on shell behaviour because shell globbing behaviour is also configurable in most shells.

My zsh for example also treats bare ** at the end differently than we do now:

$ tree
.
├── a
│   └── b
│       └── f1
├── c
│   └── f2
└── f3

3 directories, 3 files
$ cat ./**
cat: ./a: Is a directory
cat: ./c: Is a directory
f3

To fix this issue here (/**/*) we could probably replace /**/ in the AST with {/**/,/}. However, we will have to decide how we move forward with this if gobwas/glob does not want these changes. Do we continue our fork?

Do we continue our fork?

I would say if they don't want the changes back, either that or leave as-is. So far only this issue was opened about this behavior change, so I would say its probably not too bad to leave as-is....

You can now add directories (as long as some files exist in a nested directory) without needing globbing https://github.com/goreleaser/nfpm/blob/master/files/files_test.go#L71

contents:
- src: testdata/deep-paths/
  dst: /bla

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.