dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.06k stars 1.55k forks source link

Dart:io does not run path commands on macOS #38364

Open faridg18 opened 4 years ago

faridg18 commented 4 years ago

I am making a CLI project with dart using dart io to run flutter command, but process throws the following error when trying to run flutter only on macOS

Unhandled exception: ProcessException: No such file or directory Command: flutter doctor

0 _ProcessImpl._runAndWait (dart:io-patch/process_patch.dart:496:7)

1 _runNonInteractiveProcessSync (dart:io-patch/process_patch.dart:641:18)

2 Process.runSync (dart:io-patch/process_patch.dart:66:12)

3 File.initProject (package:real_product/package/entities/file.dart:45:20)

4 main (package:real_product/main.dart:46:11)

5 _startIsolate. (dart:isolate-patch/isolate_patch.dart:303:32)

6 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:172:12)

I have flutter on my path and I am able to run commands from the terminal. the weird thing is that it works perfectly on linux.

here is my flutter doctor output from the terminal.

Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel stable, v1.9.1+hotfix.2, on Mac OS X 10.14.6 18G95, locale en-US)

[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2) [✓] Xcode - develop for iOS and macOS (Xcode 10.3) [✓] Android Studio (version 3.5) [✓] VS Code (version 1.38.1) [!] Connected device ! No devices available

! Doctor found issues in 1 category.

srawlins commented 4 years ago

Can you post the dart:io API you are using? I'm guessing you need to separate "flutter" and "doctor", if you are using Process.run, for example.

faridg18 commented 4 years ago

Here is the pub spec.yaml

name: real_product
description: A new Flutter project.

# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1

environment:
  sdk: ">=2.1.0 <3.0.0"

dependencies:
  archive: ^2.0.10
  path: ^1.6.2
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2

dev_dependencies:

  flutter_test:
    sdk: flutter

# For information on the generic Dart part of this file, see the
# following page: https://www.dartlang.org/tools/pub/pubspec

# The following section is specific to Flutter.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

I am running flutter doctor by hand to show my version of flutter. My problem is that dart:o does not want to run any flutter command on my machine, although flutter runs when typed directly into the terminal

GroovinChip commented 3 years ago

I'm running into a problem where Process.run calls to invoke CLI commands crash my Flutter macOS app in release mode. I've been trying to catch and log the crash with no luck so I cannot provide logs. But I suspect the issue is the same.

When running my app in release mode the commands can be invoked without issue. But when clicking on the .app file generated by flutter build macos the app crashes when calling Process.run().

Is anyone able to provide any input on this?

`flutter doctor -v` output: ``` [✓] Flutter (Channel stable, 2.0.2, on macOS 11.2.2 20D80 darwin-x64, locale en-US) • Flutter version 2.0.2 at /Users/groov/development/flutter • Framework revision 8962f6dc68 (9 days ago), 2021-03-11 13:22:20 -0800 • Engine revision 5d8bf811b3 • Dart version 2.12.1 [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2) • Android SDK at /Users/groov/Library/Android/sdk • Platform android-30, build-tools 30.0.2 • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS • Xcode at /Applications/Xcode.app/Contents/Developer • Xcode 12.4, Build version 12D4e • CocoaPods version 1.10.1 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 4.1) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495) [✓] VS Code (version 1.54.3) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.20.0 [✓] Connected device (2 available) • macOS (desktop) • macos • darwin-x64 • macOS 11.2.2 20D80 darwin-x64 • Chrome (web) • chrome • web-javascript • Google Chrome 89.0.4389.90 ! Device R38M607AKSY is not authorized. You might need to check your device for an authorization dialog. • No issues found! ```
GroovinChip commented 3 years ago

Update: I set runInShell to true and it keeps the app from crashing, and I was able to capture a log:

/bin/sh: my_cli: command not found and the exit code is 127

FilledStacks commented 2 years ago

@GroovinChip did you have to give the app any special permissions? My Process spawn use to work now it's not working.

GroovinChip commented 2 years ago

@FilledStacks it's been a long time, so I don't remember perfectly, but I don't think that I needed to give any special permissions

RonanLB commented 2 years ago

I have the same issue here. What I've been able to figure out is that when the app is run with flutter run vs flutter build the PATH environment variable isn't the same at all. This would mean the app inherit from a different environment at startup. I still haven't found how to fix the built app though, so If anyone has an idea!

Another interesting fact is that if I open the app from the shell with

$ open [path to the app]

The app inherits from the shell path and works properly

If I open the app by double clicking from finder it will fail or crash on Process.start

mit-mit commented 2 years ago

Does anyone have some code that repros this issue?

jpv123 commented 2 years ago

@mit-mit Yes it's simple actually, just call the following code:

Process.start("flutter", ["--version"],
            runInShell: true,
            workingDirectory: workingDirectory
        )

That will throw an error of /bin/sh: flutter: command not found.

Remember that for this to fail it has to be on a flutter build macos --release product. If you run this from VSCode it will work flawlessly

@RonanLB @GroovinChip where you able to solve the issue? I'm a little bit blocked since I can't get Process.start to read other commands like flutter

szpnygo commented 2 years ago

I have the same issue here. @RonanLB @GroovinChip @jpv123

I print the Platform.environment['SHELL'] and I found is not same with echo $PATH in my shell

mit-mit commented 2 years ago

@lrhn came up with this solution:

import 'dart:io';

void main(List<String> arguments) async {
  final process = await Process.start(
    '/bin/bash',
    ['-c', r'/bin/echo ${PATH:-none}'],
    runInShell: false,
  );
  stdout.addStream(process.stdout);
  stderr.addStream(process.stderr);
}
szpnygo commented 2 years ago

@lrhn came up with this solution:

import 'dart:io';

void main(List<String> arguments) async {
  final process = await Process.start(
    '/bin/bash',
    ['-c', r'/bin/echo ${PATH:-none}'],
    runInShell: false,
  );
  stdout.addStream(process.stdout);
  stderr.addStream(process.stderr);
}

I use the Platform.environment['SHELL']. But I still can get the user environment. Finally, I read the ~/.zshrc file to get the user environment.

Platform.environment['SHELL'] ?? "/bin/zsh"