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

Incorrect relative path in gulp.dest() > vinyl-fs #699

Closed
demisx opened this issue Sep 24, 2014 · 15 comments · Fixed by #700
Closed

Incorrect relative path in gulp.dest() > vinyl-fs #699

demisx opened this issue Sep 24, 2014 · 15 comments · Fixed by #700

Comments

@demisx
Copy link
Contributor

demisx commented Sep 24, 2014

I have an issue with relative path being incorrectly calculated in vinyl-fs module used by gulp. Please let me know if this should be entered under vinyl-fs project instead.

When I pass gulp.src a direct path string, the relative.path in vinyl-fs/lib/dest/index.js is set to the file name only, meaning it looses the directory prefix:

gulp.task "watch-less", -> 
  gulp.src "app/css/bootstrap-scoped.less"
  .pipe gulp.dest('.build') # file.relative == 'bootstrap-scoped.less' (note: `css/` dir is lost)
  return  

However, if I pass a glob string instead of direct path, then the relative path is properly calculated and the directory prefix is present:

gulp.task "watch-less", -> 
  gulp.src "app/**/bootstrap-scoped.less"
  .pipe gulp.dest('.build') # file.relative== 'css/bootstrap-scoped.less' (note: 'css/' directory is present)
  return  

This is a contrived example just to show where the issue exists. In our gulp build, this result in files being written to the wrong directory.

@demisx demisx changed the title Incorrect relative path in gulp.dest() Incorrect relative path in gulp.dest() > vinyl-fs Sep 24, 2014
@yocontra
Copy link
Member

The base (by default) is where the glob starts. If you want to change this you can pass the base param to gulp.src

@demisx
Copy link
Contributor Author

demisx commented Sep 25, 2014

I don't want to change the base. I simply don't want to loose the directories in the relative path when gulp.src is given a string path instead of a glob. In my example above, the css/ directory is lost from the file.relative in vinyl-fs/dest/index.js when gulp.src is called with a string path, but it's there when it is called with glob. Shouldn't this work consistently for both arguments?

@yocontra
Copy link
Member

@demisx Again, this is what "base" means. The path that .dest writes is relative to "base"

@demisx
Copy link
Contributor Author

demisx commented Sep 25, 2014

@contra Thank you for the prompt reply. I understand what the base is, but, I don't quite understand why I need to set the base when I pass a string path to gulp.src in order to make this work. Shouldn't the default base kick in as it does when I pass the glob path? After all, I am running both from the same directory. glob path works, but string path doesn't. Am I missing something?

@yocontra
Copy link
Member

@demisx How would gulp automatically figure out what path you want to be the base if you don't use a glob? In your example it could be either app/ or app/css/ - there is no way for gulp to know unless you specify it somehow.

@stringparser
Copy link

Sorry for interrupt. Its app/css/isn't it? that is, the base should default to the dirname of the input file. Is glob2base the module that does this from glob-stream right?

Looking at this glob-stream line

@yocontra
Copy link
Member

@stringparser There still seems to be a miscommunication here - maybe I'm failing to articulate my point:

There are two possible cases -

  1. Use wants to send files/folder/whatever.txt to build/whatever.txt
  2. User wants to send files/folder/whatever.txt to build/folder/whatever.txt

Which case should this code fulfill?

gulp.src('files/folder/whatever.txt')
  .pipe(gulp.dest('build'))

Currently the answer is 1 as this seems to make the most sense. I'm open to discussion if we want to switch it, but I think using the dirname of the input file is not the most common case. It's easier for you to just do gulp.src('files/folder/whatever.txt', {base: 'file'}) or .pipe(gulp.dest('build/css'))

@stringparser
Copy link

Haha :). I'm sorry @contra. Super clear now. Is just that is confusing to have different behavior for non-starred globs compared to the opposite. That is, having

gulp.src(['files/folder/something.txt', 'files/**/whatever.txt'])
     .pipe(gulp.dest('build'))

Will result on

build
├── folder
│   └── whatever.txt
└── something.txt

@stringparser
Copy link

Just use the base option @demisx. Understand what base means from below

files/folder/whatever.txt -> whatever.txt
files/gloder/something.txt -> something.txt
files/else.txt -> else.txt
files/*/name.txt -> folder/name.txt
files/folder/*.txt -> name.txt

As @contra said, the start of the glob is where the base is taken if not, it will match the path.basename, right?

So yes @contra, I didn't understood what base meant 💃


edit
Yees, got it!

@demisx
Copy link
Contributor Author

demisx commented Sep 25, 2014

@stringparser Thank you for chiming in. You actually helped me look at this from a different prospective. Just like you, I was initially confused by the different behavior between the glob path vs string path. I didn't realize that with glob, the file.base is set by default to the leading substring up till where the first * begins, e.g. with dir1/dir2/**/whatever.txt the base will be set to dir1/dir2. On the other hand, with direct string paths, e.g. dir1/dir2/whatever.txt the base is empty and it will be responsibility of the programmer to set it, otherwise gulp.dest(destDir) will write all files into the root of the destDir. Thus, in my case with the string path, this is what worked:

gulp.task "watch-less", -> 
  gulp.src "app/css/bootstrap-scoped.less",
    base: 'app'
  .pipe gulp.dest('.build') # file.relative correctly set to 'css/bootstrap-scoped.less' 
  return  

I suggest we capture this behavior under https://github.com/gulpjs/gulp/blob/master/docs/API.md#gulpsrcglobs-options, so it is clear for others as well. I can take a stab at writing a few sentences with @contra's blessing.

@stringparser
Copy link

glad that I was able to help @demisx :)

I arrived to the same conclusion you write on your snippet. Be explicit about the base so even then you can make more than one write at the end. The last two links I left were when I understood why.

I think a little bullet point on the md file you point out would be useful to know that if you write a non-starred glob the base is the basename of the path and if you do write one the first glob star is from which the base is taken.

@yocontra
Copy link
Member

I would love a PR to document this better.

@stringparser
Copy link

@demisx seems to be busy, if he doesn't take the lead I'll do it tomorrow ;)

@demisx
Copy link
Contributor Author

demisx commented Sep 26, 2014

Sorry, I was able to get to it just this morning.

@stringparser Please feel free to comment/edit. Writing docs is not my strongest skill. :)

@stringparser
Copy link

Very complete @demix. No worries is just that lately I've been having more time than usual haha.

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

Successfully merging a pull request may close this issue.

3 participants