-
Notifications
You must be signed in to change notification settings - Fork 8
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
project sync executed in project root directory #86
Conversation
This needs more testing for execution when there isn't any project configuration. |
The change as implemented removes support for the current working directory as a fallback to their being no configuration files available, so that needs to be put back. |
So you are saying that before this PR the root for the sync dir was whatever dir you were in when you ran the command, and not the directory that the outrigger.yml file is in? Now with this PR it will only work if there is an outrigger.yml and use that file's directory, but we also need to account for the current working directory if that project config file doesn't exist? Also, with the issue you linked, recursive project config discovery, that seems kind of problematic. Maybe the project config file need to specify the sync dir, and if there is no project config in the recursive heirarchy that specifies a sync dir then it just uses the current dir? |
Correct, if you look at the code, it used
Yes, that's what my latest comment discussed. I over-corrected. We wanted to be able to use this functionality outside a project context. That seems like an edge case (similar to us using
The idea is that if an outrigger.yml is found, the rig project sync should be rooted in that directory. If not, it should be the current working directory. It makes sense to me that we further enhance the outrigger.yml unison config to specify a relative path to sync from below the project config structure. Currently all rig project scripts execute in the directory of the outrigger.yml file, we assume it is always at the repo root. |
But it is possibly to have a "global" outrigger.yml, say in your $HOME dir, and it is possible without a project config (for various use cases) that it will share your $HOME dir via unison. Should we additionally add a flag that says use $CWD? |
I think it makes sense to add a flag to designate the localhost side of the sync as a path. So In priority order, this gives us:
As long as we're talking about these options, it's worth noting that we currently have an argument that causes problems for other commands to interact with the sync container, so we should be careful to keep those use cases in mind. #85 for discussion on that. |
Would |
Re-introduced the CWD fallback, added --sync-path override, added verbose logging of what the working directory is for sync execution, followed that through to do similar in project scripts and tweaked a couple log messages for easier reading flow. |
cli/commands/project_sync.go
Outdated
// process is still watching the "current directory" and so needs the working | ||
// directory to be explicitly set. | ||
command.Dir = workingDir | ||
cmd.out.Verbose.Printf("Script execution - Working Directory: %s", workingDir) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Log message appears wrong. This should be Sync
or something besides Script execution
|
cli/commands/project_sync.go
Outdated
cmd.out.Info.Print("Waiting for initial sync detection") | ||
|
||
var tempFile = fmt.Sprintf(".%s.tmp", logFile) | ||
var tempFile = filepath.Join(workingDir, fmt.Sprintf(".test-sync-start.tmp")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don;t need a Sprintf here is the log file name is not patterned from a variable. %s
or whatevs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think what I meant to say is, why are you not using logFile
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, logFile
should already be a full absolute path, so I'm thinking that the filepath.Join
is not needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic predates the PR. I think logFile is used by unison, and we're checking that tempFile is synced. I wonder what happens if a project ignores *.tmp files... might need a parameter or less fraught ext.
cli/commands/project_sync.go
Outdated
volumeName := cmd.GetVolumeName(ctx, cmd.Config) | ||
// Determine the working directory for CWD-sensitive operations. | ||
var workingDir string | ||
if syncPath, err := cmd.DeriveLocalSyncPath(cmd.Config, ctx.String("sync-path")); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you not use workingDir
here as it is already defined as a var and avoid the else all together?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I declare the var so it's in function instead of block scope, but the := operator is caught by the compiler as an overwrite. I could nest the whole function inside the if with reversed err check.
cli/commands/project_sync.go
Outdated
cmd.out.Verbose.Printf("Stopping sync with volume: %s", volumeName) | ||
// Determine the working directory for CWD-sensitive operations. | ||
var workingDir string | ||
if syncPath, err := cmd.DeriveLocalSyncPath(cmd.Config, ctx.String("sync-path")); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same, can we use workingDir
here and remove the else
cli/commands/project_sync.go
Outdated
// Remove the Unison logfile. | ||
func (cmd *ProjectSync) RemoveLogFile(logFile string, workingDir string) error { | ||
command := exec.Command("rm", "-f", logFile) | ||
command.Dir = workingDir |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If logFile
is a variable with workingDir
already joined, you dont need to pass in workingDir
and set it the command.Dir
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My reasoning here is that if it is worth having this broken out as a separate function, and an exported one at that, it makes sense to not make assumptions about the logFile path. In fact, you could argue that this should be checking the logFile path exists.
I don't have strong feelings about folding it back in or helping it to stand alone better. Do you have a preference?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can keep it, I did not realize you intended to make that funciton for public consumption. If so, then don't call it RemoveLogFile
just call it RemoveFile
and rename the variable and then things make more sense as a general purpose function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a few comments about paths and such
|
@@ -38,14 +41,14 @@ func (cmd *ProjectSync) Commands() []cli.Command { | |||
start := cli.Command{ | |||
Name: "sync:start", | |||
Aliases: []string{"sync"}, | |||
Usage: "Start a unison sync on local project directory. Optionally provide a volume name.", | |||
Usage: "Start a Unison sync on local project directory. Optionally provide a volume name.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did some renaming so Unison is capitalized in messages.
var logFile = fmt.Sprintf("%s.log", volumeName) | ||
exec.Command("rm", "-f", logFile).Run() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Created util/filesystem.go for these basic kinds of operations.
// The use of os.Stat below is not subject to our working directory configuration, | ||
// so to ensure we can stat the log file we convert it to an absolute path. | ||
if logFilePath, err := util.AbsJoin(workingDir, logFile); err != nil { | ||
cmd.out.Info.Print(err.Error()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've attempted to fix the inconsistency between absolute paths vs. working direct & relative paths throughout this file, but os.Stat is an edge case that needs support.
var timeoutLoopSleep = time.Duration(100) * time.Millisecond | ||
// * 10 here because we loop once every 100 ms and we want to get to seconds | ||
var timeoutLoops = timeoutSeconds * 10 | ||
var statSleep = time.Duration(syncWaitSeconds) * time.Second |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved statSleep up because we were previously looping over an otherwise unchanging operation.
cmd.out.Info.Print(err.Error()) | ||
} else { | ||
// Create a temp file to cause a sync action | ||
var tempFile = ".rig-check-sync-start" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed this further to remove .tmp suffix and introduce rig in the name to clarify what it is and avoid potential sync ignores around not syncing tempfiles.
@@ -0,0 +1,53 @@ | |||
package util |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All new code in this file.
So, it will choose either the I will do a bit of a deeper review tonight, but i'm thinking this thing is just about good to merge, thanks for all the hard work on it. |
@febbraro my thinking is that projects will always sync relative to the outrigger.yml, because in that way if you connect via the CLI container all the pieces are the same, which I find tremendously valuable for general intuition. I could see the value of a sync-path option in outrigger.yml, but given the ignorenot modifier for Unison we theoretically support it already. https://www.cis.upenn.edu/~bcpierce/unison/download/releases/stable/unison-manual.html#ignore |
Travis failed the branch on a partial refactoring I had in the util directory, to take the easy way out I added those changes to this PR. I've broken up util.go into user_input.go and docker.go and folded image.go into docker.go. When there's more than one file I think semantically naming and categorizing everything makes it easier to find. |
This one wins the award for hardest easy PR I've landed in rig. |
Corrects the assumption in project_sync.go that commands should be executed from the current working directory. Instead, commands are executed the same as rig project scripts -- from the directory in which the configuration file is found.
Fixes #67