Skip to content
This repository was archived by the owner on Jan 14, 2025. It is now read-only.

Add ProcessManager and sharedStdIn #6

Merged
merged 7 commits into from
Jul 12, 2017

Conversation

matanlurey
Copy link
Contributor

See the examples in README.md for a better overview of these features.

Partially closes dart-lang/tools#1211.

@matanlurey matanlurey requested review from kevmoo, srawlins and grouma July 9, 2017 22:09
Copy link
Contributor

@kevmoo kevmoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some general questions.

What's your use-case for this?

README.md Outdated
A higher-level service for spawning and communicating with processes.

##### Use `spawn` to create a process similar to how a bash/shell script would:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of similar to how a bash/shell script would I'd just say what it does – forwards stdout/err – and...what else?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed! Thanks.


// Closes stdin for the entire program.
await sharedStdIn.terminate();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this do, exactly? Practically speaking?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Closes the underlying stdin stream (allowing the isolate to exit).

);
}

class _WindowsProcessManager extends ProcessManager {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the idea that this would do something different at some point?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep!

@matanlurey
Copy link
Contributor Author

@kevmoo:

What's your use-case for this?

Good question. A few things really:

  • I'd like to encourage package authors to use Dart instead of shell/bash scripts for simple tooling, but one reason that's really hard is that the default behavior of shell/bash is to spawn processes and auto-forward std[in|out|err], which is nice if you are running interactive processes.

  • For CLI projects or packages that have a CLI (like angular_test) you have to write brittle/repetitive code to run other processes but intercept their std[in|out|err] and use in your own program. I'd like to make this use case much easier.

  • If you look on github/stack overflow, using stdin in Dart is really hard because you can subscribe once, and then never again. It's easy enough to use some sort of shared global state if you are writing a single script, but much harder if you are writing modular code.

@matanlurey
Copy link
Contributor Author

I'll wait for @srawlins and @grouma to take a look since both of them are running into cases where these utilities might be useful and I'd like some input.

@kevmoo
Copy link
Contributor

kevmoo commented Jul 10, 2017 via email

}
final controller = _getCurrent();
if (controller.hasListener) {
throw new StateError(''
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the empty string? I assume for code readability but that's a pattern I haven't come across before.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Natalie is actually fixing this in dartfmt, but it is the only way to force the next lines to line up. I'm OK with removing it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other way to force a newline is if the string is just over 80 chars when at this indent, and under 80 chars if dartfmt is forced to drop it down to the next line.

String executable, {
Iterable<String> arguments: const [],
}) async {
final process = io.Process.start(executable, arguments.toList());
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we do any error handling here? Could we run into a state where io.Process.start executes but 'await process' never resolves?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we wouldn't run into any problems Process.start doesn't already have.

///
/// This is _similar_ to [io.Process.start], but all standard input and output
/// is forwarded/routed between the process and the host, similar to how a
/// bash or shell script works.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "shell script" (minus bash) is adequate here. Unless there are popular shells that don't have the concept of stdin, stdout...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

/// A process instance created and managed through [ProcessManager].
///
/// Unlike one created directly by [io.Process.start] or [io.Process.run], a
/// spawned process works more like executing a command in a shell or bash
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "shell script" (minus bash) is adequate here. Unless there are popular shells that don't have the concept of stdin, stdout...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

test('should output Hello from another process [via stderr]', () async {
final spawn = await processManager.spawn(
'dart',
arguments: [p.join('test', '_files', 'stderr_hello.dart')],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tested whether this test works when your PWD is not the package root? test/_files/stderr_hello.dart is relative to where you typically run pub run test, the repo root, right? I think it won't work if you are, e.g., sitting in the test directory, or at the root of some mega repo that has this as a third_party package :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For more context, I think the old way to get a relative resource was resolvePackageUri, but then package:test uses isolates, so that doesn't work. package:resource is the new way, which uses configurable imports. Alternatively, mirrors work.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm deferring on this one until it matters :)

@matanlurey matanlurey merged commit 2edda5b into dart-archive:master Jul 12, 2017
@matanlurey matanlurey deleted the process-manager branch July 12, 2017 16:21
mosuem pushed a commit to dart-lang/tools that referenced this pull request Dec 9, 2024
* Start on process manager.

* Ready for review.

* Pass on .24 and .25.

* Add travis badge.

* Actually fix travis.

* Update README.

* Address feedback.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging this pull request may close these issues.

A higher-level ProcessManager class
4 participants