-
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
Add rig project run
#29
Conversation
Regarding point 4, being able to specify the config file name seems like a nice to have though if it's working great. It's not clear to me from the code (as I'm not as go proficient as I'd like) whether directory ascension is being done to search for a config file though given the function of the variable I suspect it isn't. I think that would be more useful as then one could run things like Regarding point 6, agreed in concept on OS compatibility though I think that can be left to a project level decision though we document the recommendation. I think it's fine to require posix compatible tools though even in cross os scenarios for a project. Most specifically, the find command on windows is abysmal. Regarding aliases, would we not recommend global aliases that make use of expected rig aliases? I can see why alignment but using the raw command is useful for projects that don't define aliases. If we build in a set of default ones the global aliases should use them. Clean and logs seem to be the only ones that don't assume Phase2 practices though. If combined with directory ascension looking for the config file that makes an alias like rr (expanding to |
It is not performing directory traversal. We could consider doing so in a followup, but I felt like a first step was just a bash helper function to do something like find the .git directory, check if a .outrigger.yml is next to it, and then invoke rig with that path. We can take it all the way as part of rig, but that seems like a follow-up. The numbered list contains things that seem to be working for me in my local OSX testing. |
Agreed on the follow up status for directory searching for config file, I wouldn't block this on that. Looking forward we may want to consider whether the environmental variable only contain the name of the file to use. Not conflating path and name may be useful when directory traversal is implemented. Though I can see benefits to having an option to have a path prefix so that the config could be stored relative to a directory that would be traversed. For example REPO_ROOT/outrigger/outrigger.aliases.yml in an Acquia repo with an environmental setting of outrigger/outrigger.aliases.yml such that when checking after walking up to the root of the repo it gets found. I think I've basically talked myself out of recommending any change to what can get put in the environmental variable as I've typed out possibilities here. |
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 some feedback and questions.
cli/util/yaml.go
Outdated
"gopkg.in/yaml.v2" | ||
) | ||
|
||
type ProjectConfig struct { |
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.
Why would these not be left in Project? or are you imagining this growing bigger than just project config in the future? If so, we may want to create a config util as opposed to yaml (or both)
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 was thinking this would head to both. I can imagine having a rig-wide config that allows controlling default behaviors on both project config and non-project config.
This is ProjectConfig here because the struct started as P, and my refactoring only took the intermediate step. This should probably just be interface in this file, and in a new project-config.go or in the existing project.go remap it to the more explicit data structure.
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 had a lot of trouble figuring out how to parse YAML without defining it's struct as part of the initial object. It ended up feeling cleaner & easier to just pour all the YAML handling into the new project-config.go
cli/util/shell-exec.go
Outdated
return err | ||
} | ||
|
||
func PassthruCommand(cmd *exec.Cmd) (stdout string, stderr string, exitCode int) { |
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.
Can you add a function commend for this one so we know the intent?
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.
Yes I can. This function is not yet working as intended so I'll be back to it :)
It started (pretty obviously) with http://stackoverflow.com/a/40770011/38408
cli/commands/project.go
Outdated
}, | ||
} | ||
|
||
command := cli.Command{ |
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.
So what happens if you just call rig project
? I was thinking this would list out all the scripts to run.
rig project
list all scripts
rig project build
would run the build script
rig project clean
would run the clean script
You are anticipating running rig project run
to get a list of all scripts? and rig project run build
to run the configured build script?
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.
rig project run
lists the scripts. rig project run build
would run the build script.
I wanted to have rig project create
to run the generator, and possibly other "built-in" commands that are project centric.
There could also be rig project aliases
and so on. If we are okay with rig -h
getting longer at the top, we could expand on the "Development" help category and just have create-project, project-aliases, etc as top-level.
I was also making space if we ever wanted to implement lifecycle scripts (maybe via a hook
or events
key) to do things like pre-start, post-start around rig start
. But again, we can implement any commands that might generate on the top level.
This also allows us to add additional meta data in the future such as "help" which could be used in a "rig project --help" output to describe each command, etc. Just having the script as the only value for the key just limits future applications I think. |
Background thought: One of the subtexts of the conversation is that YAML parsing in a strongly typed language like go is a bit more complex than in scripting languages, so accepting variations or more complex structures takes more effort.
Nope, it currently expects a single string. For more complexity in the command I think it should be committed as a bash script in a bin/ directory anyway. Is there some value-add rig can provide by accepting an array there? Also, there are no docs yet. The example in the code is mostly a note from Frank to me than even a finalized code comment :)
I'm not sure I'm clear on why something has value as an alias but not as a script. I figured just make everything a script and make all those things a simpler alias as well. Then have a generator prepopulate the more essential scripts/aliases we want to spread around. What do you see as the driving distinction? Just having the rig project run script having a longer name for clarity than the length of a good alias?
I had the notion of enabling an .outrigger.local.yml to merge on top of the main file. Would it make sense to have an OS-specific overlay approach? 99% of the time the Windows stuff will not be used, and then the users that do will not care about the POSIX bits. |
In response to @tekante, I was thinking we don't necessarily need to build the directory traversal into rig, as we kind of want it for rig and for docker-compose, which means maybe we just want #!/usr/bin/env bash
rig_project_activate () {
export GIT_REPO=$(git rev-parse --show-toplevel 2> /dev/null)
export RIG_PROJECT_CONFIG_FILE=$GIT_REPO/.outrigger.yml
export COMPOSE_FILE=$GIT_REPO/build.yml
}
r () {
if [ -z "$GIT_REPO" ]; then
rig_project_activate
fi
docker-compose run --rm "$@"
} Obviously this example is super naive on the idea that you would only ever navigate to one project repo in a terminal session, but this is the kind of thing I was thinking about. |
Sorry I wasn't clear. The purpose of the "alias" key is to specify the name of the alias you want to use instead of the default. This was in response to the auto-alias approach using Requiring the multi-line script to be moved to a bash file is fine but you still need the OS-specific. Because on Windows the script file would be "doit.bat" vs the "doit.sh" on linux/osx. Supporting multiline scripts just makes this more consistent with how scripts are managed in BLT and also decreases the number of files that you need to keep track of. The I don't know how YAML is parsed in "go" but seems like it should not be hard to detect if the script returned an array or a string value and then deal with it. I don't think just merging a "local" file solves the problem. If I'm a tech-lead on a project creating the outrigger config file for it, I would be setting up the scripts for all the devs to use. If we had a Windows dev on the project we would create Windows-specific versions of each script. Some developers would be on Mac and some devs would be on Windows, so "local" is different for each and could not just be committed as a single file to the code repo for the project. |
I'm not worried about consistency with BLT as much as npm or composer, but I do appreciate the argument that it has value.
What if we supported ".outrigger.windows.yml" as something rig would override with. Is a separation like that worth it? |
That's probably fine if merging is easier than just looking for the key in the main file when the script is executed, and maybe it has value if there are things other than the scripts that are OS-specific to override. I still believe that supporting sub-keys for the scripts (like the "alias" key, "description", etc) is still a valuable architecture as it allows easier expansion and addition of script metadata in the future. If we just assume the only value of the script key is the script itself and then later decide we need metadata it would make compatibility and migrating more difficult. |
I'm convinced about the metadata at least :) Just missing the description is one of the things I've regretted about the gdt scripts implementation. |
My comment about BLT wasn't to imply "we have to do it this way", but just indicating that BLT in general is easier to use so we should learn from it when it makes sense, and we do potentially have projects that move between Outrigger and BLT so having similar concepts and functionality can be useful. Also, composer does allow multiline scripts:
example from https://getcomposer.org/doc/articles/scripts.md. I guess I'm also looking for a more compelling reason not to allow multi-line scripts other than "it is harder." |
We're simultaneously discussing what is a blocker on this PR and what the ultimate goal should be. I do still contend that if it's more commands than can gracefully be concatenated, a separate script might be valuable. Still, here's what I propose: I am planning on this config file being versioned, which means we have a lot of flexibility to also support multiline in a followup, or mandate a multi-line style structure in a bc break. On that basis, can this be a future enhancement? I am working on alias & description support as an extension of refactoring the YAML parsing. |
I got multiple scripts working. Will have a nice big commit once I finish up a few details and figure out how to format the help better. |
Alright, lots of changes in the last couple of commits. But also some new todos.
|
I think this is looking pretty good.
|
@mike-potter so you are suggesting we might do something like That's an interesting idea. There's a couple downsides:
I like the idea of a |
In Windows you would join with ' & '. So you could set an OS delimiter the same place you set the command name. I agree that there might be cases where this interferes, but if it's a complex set of commands that is best put in a script file anyway. Trying to accomodate the 80% use-case here. Doing a "cd" between steps is common (looking at various build scripts I've used over time). I'm just really worried about people using "cd dir" and expecting it to work. The |
Provide Unison sync support for projects
…a project config file
…project Fix rig error when rigconfig not found.
… crashes if ignores were not defined
…y instances of ProjectConfig
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.
Had a few notes but nothing I think needs to block merging. I can submit a few of these as PRs once this one merges.
Example outrigger file needs double backslash in the Regex example line
rig project run
just errors rather than printing help. I think because run is an alias of project which I assume is because that's how things need to work to get the various help pieces to print out but wasn't what I was expecting. So just to confirm, is run really supposed to be an alias for project?
Should ./bin be prepended to the path rather than appended? I would think we want things in the project to take priority on the small chance that script calls match commands that happen to already exist in a person's path.
The scripts help needs a space in the description.
Good call. |
DEVTOOLS-229: Adding project create command
Thanks to febbraro for getting the branch started. I am opening this for initial feedback but still expect to work on some refinements.
This PR adds a new
rig project
command which wraps project-configuration of scripts as subcommands of the CLI.project
andwatch
are grouped. I debated adding doctor, or creating other categories, but left that to other tasks.TODOs
rig project
, removing the run subcommand.Follow-ups
Once this is merged we'll be in a position to file tickets. Filing tickets is sufficient to check off the boxes.
rig aliases
that can be sourced...eval $("rig project aliases")
Follow-up Aliases approach
(This probably belongs somewhere else, but jotting this down while I have a text area for now.)
A rig aliases system could be as simple as taking all the scripts, and proposing aliases such as:
So in that case, suppose we had this:
We would then get these for aliases with this proposal:
This has the virtue of keeping the rig scripts and aliases lined up and letting the project control most of it. If we have any notions for "build-in" aliases, we could have them but let the scripts configuration override the command.