|
6 | 6 | "compress/gzip" |
7 | 7 | "context" |
8 | 8 | "fmt" |
| 9 | + "github.com/loft-sh/devspace/pkg/util/fsutil" |
9 | 10 | "io" |
| 11 | + "io/ioutil" |
10 | 12 | "os" |
11 | 13 | "path" |
12 | 14 | "path/filepath" |
@@ -412,101 +414,138 @@ func (u *upstream) getFileInformationFromEvent(events []notify.EventInfo) ([]*Fi |
412 | 414 | continue |
413 | 415 | } |
414 | 416 |
|
415 | | - relativePath := getRelativeFromFullPath(fullPath, u.sync.LocalPath) |
416 | | - |
417 | 417 | // Determine what kind of change we got (Create or Remove) |
418 | | - newChange, err := u.evaluateChange(relativePath, fullPath) |
| 418 | + relativePath := getRelativeFromFullPath(fullPath, u.sync.LocalPath) |
| 419 | + newChanges, err := u.evaluateChange(relativePath, fullPath) |
419 | 420 | if err != nil { |
420 | 421 | return nil, errors.Wrap(err, "evaluate change") |
421 | 422 | } |
422 | 423 |
|
423 | | - if newChange != nil { |
424 | | - changes = append(changes, newChange) |
425 | | - } |
| 424 | + changes = append(changes, newChanges...) |
426 | 425 | } |
427 | 426 | } |
428 | 427 |
|
429 | 428 | return changes, nil |
430 | 429 | } |
431 | 430 |
|
432 | | -func (u *upstream) evaluateChange(relativePath, fullpath string) (*FileInformation, error) { |
433 | | - stat, err := os.Stat(fullpath) |
| 431 | +func (u *upstream) evaluateChange(relativePath, fullPath string) ([]*FileInformation, error) { |
| 432 | + stat, err := os.Stat(fullPath) |
| 433 | + if err != nil { |
| 434 | + // Remove symlinks |
| 435 | + u.RemoveSymlinks(fullPath) |
434 | 436 |
|
435 | | - // File / Folder exist -> Create File or Folder |
436 | | - // if File / Folder does not exist, we create a new remove change |
437 | | - if err == nil { |
438 | | - // Exclude changes on the upload exclude list |
439 | | - if u.sync.uploadIgnoreMatcher != nil { |
440 | | - if u.sync.uploadIgnoreMatcher.Matches(relativePath, stat.IsDir()) { |
441 | | - // Add to file map and prevent download if local file is newer than the remote one |
442 | | - if u.sync.fileIndex.fileMap[relativePath] != nil && u.sync.fileIndex.fileMap[relativePath].Mtime < stat.ModTime().Unix() { |
443 | | - // Add it to the fileMap |
444 | | - u.sync.fileIndex.fileMap[relativePath] = &FileInformation{ |
445 | | - Name: relativePath, |
446 | | - Mtime: stat.ModTime().Unix(), |
447 | | - Mode: stat.Mode(), |
448 | | - Size: stat.Size(), |
449 | | - IsDirectory: stat.IsDir(), |
450 | | - } |
451 | | - } |
| 437 | + // Check if we should remove path remote |
| 438 | + if shouldRemoveRemote(relativePath, u.sync) { |
| 439 | + // New Remove Task |
| 440 | + return []*FileInformation{ |
| 441 | + { |
| 442 | + Name: relativePath, |
| 443 | + }, |
| 444 | + }, nil |
| 445 | + } |
| 446 | + |
| 447 | + return nil, nil |
| 448 | + } |
452 | 449 |
|
453 | | - return nil, nil |
| 450 | + // Exclude changes on the upload exclude list |
| 451 | + if u.sync.uploadIgnoreMatcher != nil && u.sync.uploadIgnoreMatcher.Matches(relativePath, stat.IsDir()) { |
| 452 | + // Add to file map and prevent download if local file is newer than the remote one |
| 453 | + if u.sync.fileIndex.fileMap[relativePath] != nil && u.sync.fileIndex.fileMap[relativePath].Mtime < stat.ModTime().Unix() { |
| 454 | + // Add it to the fileMap |
| 455 | + u.sync.fileIndex.fileMap[relativePath] = &FileInformation{ |
| 456 | + Name: relativePath, |
| 457 | + Mtime: stat.ModTime().Unix(), |
| 458 | + Mode: stat.Mode(), |
| 459 | + Size: stat.Size(), |
| 460 | + IsDirectory: stat.IsDir(), |
454 | 461 | } |
455 | 462 | } |
456 | 463 |
|
457 | | - // Check if symbolic link |
458 | | - lstat, err := os.Lstat(fullpath) |
459 | | - if err == nil && lstat.Mode()&os.ModeSymlink != 0 { |
460 | | - _, symlinkExists := u.sync.upstream.symlinks[fullpath] |
| 464 | + return nil, nil |
| 465 | + } |
| 466 | + |
| 467 | + // File / Folder exist -> Create File or Folder |
| 468 | + // if File / Folder does not exist, we create a new remove change |
| 469 | + // Check if symbolic link |
| 470 | + lstat, err := os.Lstat(fullPath) |
| 471 | + if err == nil && lstat.Mode()&os.ModeSymlink != 0 { |
| 472 | + _, symlinkExists := u.sync.upstream.symlinks[fullPath] |
| 473 | + |
| 474 | + // Add symlink to map |
| 475 | + stat, err = u.sync.upstream.AddSymlink(relativePath, fullPath) |
| 476 | + if err != nil { |
| 477 | + return nil, errors.Wrap(err, "add symlink") |
| 478 | + } |
| 479 | + if stat == nil { |
| 480 | + return nil, nil |
| 481 | + } |
461 | 482 |
|
462 | | - // Add symlink to map |
463 | | - stat, err = u.sync.upstream.AddSymlink(relativePath, fullpath) |
| 483 | + // Only crawl if symlink wasn't there before and it is a directory |
| 484 | + if !symlinkExists && stat.IsDir() { |
| 485 | + // Crawl all linked files & folders |
| 486 | + err = u.symlinks[fullPath].Crawl() |
464 | 487 | if err != nil { |
465 | | - return nil, errors.Wrap(err, "add symlink") |
466 | | - } |
467 | | - if stat == nil { |
468 | | - return nil, nil |
| 488 | + return nil, errors.Wrap(err, "crawl symlink") |
469 | 489 | } |
| 490 | + } |
| 491 | + } else if err != nil { |
| 492 | + u.sync.log.Debugf("Error in lstat %s: %v", fullPath, err) |
| 493 | + return nil, nil |
| 494 | + } else if stat == nil { |
| 495 | + return nil, nil |
| 496 | + } |
470 | 497 |
|
471 | | - // Only crawl if symlink wasn't there before and it is a directory |
472 | | - if !symlinkExists && stat.IsDir() { |
473 | | - // Crawl all linked files & folders |
474 | | - err = u.symlinks[fullpath].Crawl() |
475 | | - if err != nil { |
476 | | - return nil, errors.Wrap(err, "crawl symlink") |
477 | | - } |
| 498 | + fileInfo := &FileInformation{ |
| 499 | + Name: relativePath, |
| 500 | + Mtime: stat.ModTime().Unix(), |
| 501 | + MtimeNano: stat.ModTime().UnixNano(), |
| 502 | + Size: stat.Size(), |
| 503 | + Mode: stat.Mode(), |
| 504 | + IsDirectory: stat.IsDir(), |
| 505 | + IsSymbolicLink: stat.Mode()&os.ModeSymlink != 0, |
| 506 | + } |
| 507 | + |
| 508 | + // should we upload the file? |
| 509 | + if shouldUpload(u.sync, fileInfo, u.sync.log) { |
| 510 | + // New Create Task |
| 511 | + return []*FileInformation{fileInfo}, nil |
| 512 | + } else if stat.IsDir() { |
| 513 | + // if the change is a directory we walk the directory for other potential changes |
| 514 | + files, err := ioutil.ReadDir(fullPath) |
| 515 | + if err != nil { |
| 516 | + // Remove symlinks |
| 517 | + u.RemoveSymlinks(fullPath) |
| 518 | + |
| 519 | + // Check if we should remove path remote |
| 520 | + if shouldRemoveRemote(relativePath, u.sync) { |
| 521 | + // New Remove Task |
| 522 | + return []*FileInformation{ |
| 523 | + { |
| 524 | + Name: relativePath, |
| 525 | + }, |
| 526 | + }, nil |
478 | 527 | } |
479 | | - } else if err != nil { |
480 | | - u.sync.log.Debugf("Error in lstat %s: %v", fullpath, err) |
481 | | - return nil, nil |
482 | | - } else if stat == nil { |
| 528 | + |
483 | 529 | return nil, nil |
484 | 530 | } |
485 | 531 |
|
486 | | - fileInfo := &FileInformation{ |
487 | | - Name: relativePath, |
488 | | - Mtime: stat.ModTime().Unix(), |
489 | | - MtimeNano: stat.ModTime().UnixNano(), |
490 | | - Size: stat.Size(), |
491 | | - Mode: stat.Mode(), |
492 | | - IsDirectory: stat.IsDir(), |
493 | | - IsSymbolicLink: stat.Mode()&os.ModeSymlink != 0, |
494 | | - } |
495 | | - if shouldUpload(u.sync, fileInfo, u.sync.log) { |
496 | | - // New Create Task |
497 | | - return fileInfo, nil |
498 | | - } |
499 | | - } else { |
500 | | - // Remove symlinks |
501 | | - u.RemoveSymlinks(fullpath) |
| 532 | + changes := []*FileInformation{} |
| 533 | + for _, f := range files { |
| 534 | + newFullPath := filepath.Join(fullPath, f.Name()) |
| 535 | + newRelativePath := path.Join(relativePath, f.Name()) |
| 536 | + if fsutil.IsRecursiveSymlink(f, newFullPath) { |
| 537 | + continue |
| 538 | + } |
502 | 539 |
|
503 | | - // Check if we should remove path remote |
504 | | - if shouldRemoveRemote(relativePath, u.sync) { |
505 | | - // New Remove Task |
506 | | - return &FileInformation{ |
507 | | - Name: relativePath, |
508 | | - }, nil |
| 540 | + otherChanges, err := u.evaluateChange(newRelativePath, newFullPath) |
| 541 | + if err != nil { |
| 542 | + return nil, errors.Wrap(err, "evaluate change") |
| 543 | + } |
| 544 | + |
| 545 | + changes = append(changes, otherChanges...) |
509 | 546 | } |
| 547 | + |
| 548 | + return changes, nil |
510 | 549 | } |
511 | 550 |
|
512 | 551 | return nil, nil |
|
0 commit comments