Skip to content

Commit

Permalink
Improve handing of mode / permissions on install
Browse files Browse the repository at this point in the history
  • Loading branch information
evanpurkhiser committed Jul 24, 2018
1 parent b8237d3 commit 67267aa
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 19 deletions.
13 changes: 8 additions & 5 deletions installer/installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ func InstallDotfile(dotfile *PreparedDotfile, config InstallConfig) error {
return fmt.Errorf("Source files are not all regular files")
}

// No change
if !dotfile.IsNew && !dotfile.ContentsDiffer && dotfile.Permissions.IsSame() {
if !dotfile.IsChanged() {
return nil
}

Expand All @@ -46,10 +45,14 @@ func InstallDotfile(dotfile *PreparedDotfile, config InstallConfig) error {
return os.Remove(installPath)
}

targetMode := dotfile.Permissions.New | dotfile.Mode
targetMode := dotfile.Permissions.New | dotfile.Mode.New

// Only permissions differ
if !dotfile.IsNew && !dotfile.Permissions.IsSame() && !dotfile.ContentsDiffer {
// Only filemode differs
modeChanged := !dotfile.IsNew &&
!dotfile.ContentsDiffer &&
(dotfile.Permissions.IsChanged() || dotfile.Mode.IsChanged())

if modeChanged {
return os.Chmod(installPath, targetMode)
}

Expand Down
35 changes: 21 additions & 14 deletions installer/prepare.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@ type PreparedDotfile struct {
// compiled or installed.
SourcesAreIrregular bool

// Mode represents the mode bits of the os.FileMode (does not include
// permissions). This will not be set if the sources are irregular.
Mode os.FileMode
// Mode represents the change in the file mode bits of the source and
// target os.FileMode (does not include permissions). This will not be set
// if the sources are irregular.
Mode *FileMode

// Permissions represents the change in permission between the compiled source
// and the currently installed dotfile. Equal permissions can be verified
// by calling Permissions.IsSame.
Permissions Permissions
Permissions *FileMode

// SourcePermissionsDiffer indicates that a compiled dotfile (one with
// multiple sources) does not have consistent permissions across all
Expand All @@ -55,15 +56,21 @@ type PreparedDotfile struct {
sourceInfo []os.FileInfo
}

// Permissions represents a change in file permissions.
type Permissions struct {
// IsChanged reports if the prepared dotfile has changes from the target
// dotfile.
func (p *PreparedDotfile) IsChanged() bool {
return p.IsNew || p.ContentsDiffer || p.Permissions.IsChanged() || p.Mode.IsChanged()
}

// FileMode represents the new and old dotfile file mode.
type FileMode struct {
Old os.FileMode
New os.FileMode
}

// IsSame returns a boolean value indicating if the modes are equal.
func (d Permissions) IsSame() bool {
return d.New == d.Old
// IsChanged returns a boolean value indicating if the modes are equal.
func (d FileMode) IsChanged() bool {
return d.New != d.Old
}

// PreparedDotfiles is a list of prepared dotfiles.
Expand Down Expand Up @@ -129,19 +136,19 @@ func PrepareDotfiles(dotfiles resolver.Dotfiles, config config.SourceConfig) Pre

sourcePermissions, tookLowest := flattenPermissions(sourceInfo)

prepared.Permissions = Permissions{
prepared.Permissions = &FileMode{
Old: targetInfo.Mode() & os.ModePerm,
New: sourcePermissions,
}
prepared.SourcePermissionsDiffer = tookLowest

prepared.SourcesAreIrregular = !isAllRegular(sourceInfo)

// NOTE: This currently drops non-mode bits (permissions are included
// seperately), however should the dotfile set ModeAppend, ModeSticky,
// etc, these modes will not be included here.
if !prepared.SourcesAreIrregular {
prepared.Mode = sourceInfo[0].Mode() & os.ModeType
prepared.Mode = &FileMode{
Old: targetInfo.Mode() &^ os.ModePerm,
New: sourceInfo[0].Mode() &^ os.ModePerm,
}
}

// If the dotfile does not require compilation we can directly compare
Expand Down

0 comments on commit 67267aa

Please sign in to comment.