-
Notifications
You must be signed in to change notification settings - Fork 206
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
fix: maintain working directory across script steps #711
fix: maintain working directory across script steps #711
Conversation
); | ||
|
||
if (step.contains('cd ')) { |
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 there must be a better way to keep the environment between steps than to look for cd commands 🤔
cd
is also not the only way to change directory in Linux, for example pushd
and popd
are quite commonly used in scripts.
And I guess other things in the environment should be taken into consideration too, like exporting variables for example.
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.
It makes sense, I'll think of another approach then. Thanks for the feedback!
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.
what about if a step and/or script could define it's working directory rather than us trying to detect it and magically preserve it perhaps, e.g.:
fail:
# optional, for all steps:
workingDirectory: packages/
steps:
# Step as a YamlMap definition:
- run: pwd
# optional, for an individual step + overrides top level if set
workingDirectory: packages/
# Step as a string in the YamlArray:
- ls -la
Would also make it more cross-platform friendly and not worry about Windows weirdness too!
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.
Nice! I'm all in, it makes a tons of sense. I will start working on it
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.
@Salakar I think that many of the people that have asked for this feature don't just need to be in one directory, but jump around during the multi-step script. Isn't it possible to keep the shell session alive and just keep on executing all steps in there, instead of creating a new shell for each step? 🤔
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 did a proof of concept of the approach mentioned by @spydon, and it's doable. It actually follows the same logic of GitHub workflows, also mentioned in the comment replied by @timcreatedit:
I would understand if you keep it like this (also because it's more consistent with GitHub workflows)
The code that I used for the PoC is as follows:
class PersistentShell {
PersistentShell({required bool isWindows}) {
_isWindows = isWindows;
}
late Process _process;
late bool _isWindows;
Future<void> startShell() async {
_process = await Process.start(
_isWindows ? 'cmd.exe' : '/bin/sh',
_isWindows ? ['/Q'] : [],
);
_process.stdout.transform(utf8.decoder).listen(print);
_process.stderr.transform(utf8.decoder).listen((data) {
print('Error: $data');
});
}
void sendCommand(String command) {
_process.stdin.writeln(_isWindows ? command : 'eval "$command"');
}
Future<void> stopShell() async {
await _process.stdin.close();
await _process.exitCode;
}
}
void main() async {
var shell = PersistentShell(isWindows: Platform.isWindows);
await shell.startShell();
shell.sendCommand('echo Hello World');
await shell.stopShell();
}
I implemented the code and it works really well, as the hardcoded condition to check if 'cd ' is part of the step command but way better, because it's dynamic. Let me know if this is what you meant @spydon
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.
Sorry for the late reply, this is what I meant indeed! :)
Any progress on this @jessicatarra? 😊 |
4a8f856
to
e7fb6dc
Compare
Hey everyone, Example script
Output
|
e7fb6dc
to
d08fd0f
Compare
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.
@spydon Sorry for the late reply. Work's been pretty busy lately, but I finally got some time this weekend to dig back into this fix.
No worries! Thanks for looking into it again. :)
I managed to make things work, but now I'm stuck on figuring out how to keep the logs consistent with our current style.
I left a few suggestions that I think might help, let me know what you think.
7e177e2
to
4840a78
Compare
a4bfcbb
to
5d1bdb4
Compare
- Update command `_executeAndLogCommand` to use `PersistentShell` for executing scripts efficiently. - Add a new file `persistent_shell.dart` for defining the `PersistentShell` class. - Import `PersistentShell` in `runner.dart` for using it in the commands. - Introduce the `PersistentShell` class with methods for starting, sending commands, and stopping the shell. - Refactor the log handling in `MelosLogger` to complete based on specific markers. - Modify string manipulation in `utils.dart`, adding a method to prepend a step prefix emoji. - Update tests for `melos run` commands in `run_test.dart` to reflect the changes in the command execution flow.
5d1bdb4
to
494cad3
Compare
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.
Starts to look very good!
No idea about the test failing on windows though...
I see that there are some tests failing for windows on |
That's a good point @spydon . I'll check that out. Maybe it would be a good idea to separate the work and open a new PR to fix the failing Windows tests. |
Yeah, if there aren't tests failing due to this PR that sounds like a good idea |
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.
Lgtm! @jessicatarra this is ready for merge now right?
This PR addresses the issue raised in #470, where the working directory is not maintained across multiple steps in a script.
For example, consider the following script:
When running this script using melos run, the output will show the workspace root directory, not the
packages/
directory as expected.This PR introduces a change to ensure that the working directory is properly maintained across multiple steps in a script.
The key changes are:
By running the script defined in the issue with the fix implemented in this PR, the output is now:
Type of Change
feat
-- New feature (non-breaking change which adds functionality)fix
-- Bug fix (non-breaking change which fixes an issue)!
-- Breaking change (fix or feature that would cause existing functionality to change)refactor
-- Code refactorci
-- Build configuration changedocs
-- Documentationchore
-- Chore