onepub-dev / dcli

An extensive library and tooling for building console/cli applications and scripts using the Dart programming language.
242 stars 28 forks source link

Getting this error when using the dcli package together with Flutter #129

Closed therenca closed 3 years ago

therenca commented 3 years ago

ERROR: ../../flutter/.pub-cache/hosted/pub.dartlang.org/dcli-0.51.5/lib/src/util/wait_for_ex.dart:2:8: Error: Not found: 'dart:cli' ERROR: import 'dart:cli' as cli; ERROR: ^ ERROR: ../../flutter/.pub-cache/hosted/pub.dartlang.org/dcli-0.51.5/lib/src/script/runner.dart:1:8: Error: Not found: 'dart:cli' ERROR: import 'dart:cli'; ERROR: ^ ERROR: ../../flutter/.pub-cache/hosted/pub.dartlang.org/dcli-0.51.5/lib/src/util/wait_for_ex.dart:23:13: Error: Method not found: 'waitFor'. ERROR: value = cli.waitFor(future); ERROR: ^^^^^^^ ERROR: ../../flutter/.pub-cache/hosted/pub.dartlang.org/dcli-0.51.5/lib/src/script/runner.dart:32:21: Error: The method 'waitFor' isn't defined for the class 'ScriptRunner'. ERROR: - 'ScriptRunner' is from 'package:dcli/src/script/runner.dart' ('../../flutter/.pub-cache/hosted/pub.dartlang.org/dcli-0.51.5/lib/src/script/runner.dart'). ERROR: Try correcting the name to the name of an existing method, or defining a method named 'waitFor'. ERROR: final process = waitFor(Process.start( ERROR: ^^^^^^^ ERROR: Unhandled exception:

Exception: Build process failed

therenca commented 3 years ago

Does dcli only work on the server side?

bsutton commented 3 years ago

Yes, server side only.

I have some ideas about pulling out core libraries for flutter but would need some help as it would be a fair amount of work.

On Tue, 30 Mar 2021, 3:13 pm therenca, @.***> wrote:

Does dcli only work on the server side?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/bsutton/dcli/issues/129#issuecomment-809893533, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAG32OENZ7JY27BDLM2FG6LTGFFXXANCNFSM42BFR4DQ .

therenca commented 3 years ago

I could help

bsutton commented 3 years ago

The original design concept of dcli was to remove the need to use futures as in cli apps they are unnecessary and add significant overhead to programming.

We do this by using the dart function 'waitFor'.

waitFor essentially turns a async method into a sync method.

Dcli wraps waitFor in a method called waitForEx, the purpose of which is to repair the stacktrace when an error occurs so that it looks like a synchrounous stacktrace. This is only partially successful.

To make dcli usable for flutter the code base would have to be split into two libraries.

dcli_core and dcli

dcli would present the current synchronous api.

dcli_core would be an async library which the dcli library would use but then wrap calls with waitForEx.

As an example:

The find function looks something like:

  Progress _find(
    String pattern, {
    bool caseSensitive = false,
    bool recursive = true,
    String workingDirectory = '.',
    Progress? progress,
    List<FileSystemEntityType> types = const [Find.file],
    bool includeHidden = false,
  }) {
    var _workingDirectory = workingDirectory;
    var finalpattern = pattern;

    /// If the pattern contains a relative path we need
    /// to move it into the workingDirectory as the user really
    /// wants to search  in the directory workingDirectory/relativepath.
    /// This only applies for non-recursive searches as
    /// when we do
    final relativeDir = dirname(finalpattern);
    if (recursive == false && relativeDir != '.') {
      _workingDirectory = join(_workingDirectory, relativeDir);
      if (!exists(_workingDirectory)) {
        throw FindException(
            'The path ${truepath(_workingDirectory)} does not exists');
      }
      finalpattern = basename(finalpattern);
    }

    return waitForEx<Progress>(_innerFind(finalpattern,
        caseSensitive: caseSensitive,
        recursive: recursive,
        workingDirectory: _workingDirectory,
        progress: progress,
        types: types,
        includeHidden: includeHidden));
  }

The _innerFind method is async. If we split the method into the dart_core package and then the original find method calls the dart_core version to do the actual work and wraps the response with a call to waitForEx.

There are many functions that we could move without issue:

void copy(String from, String to, {bool overwrite = false}) =>
    _Copy().copy(from, to, overwrite: overwrite);

class _Copy extends DCliFunction {
  void copy(String from, String to, {bool overwrite = false}) {
    var finalto = to;
    if (isDirectory(finalto)) {
      finalto = join(finalto, basename(from));
    }

    Settings().verbose('copy ${truepath(from)} -> ${truepath(finalto)}');

    if (overwrite == false && exists(finalto)) {
      throw CopyException(
          'The target file ${truepath(finalto)} already exists');
    }

    try {
      File(from).copySync(finalto);
    }
    // ignore: avoid_catches_without_on_clauses
    catch (e) {
      throw CopyException(
          'An error occured copying ${truepath(from)} to ${truepath(finalto)}. Error: $e');
    }
  }
}

/// Throw when the [copy] function encounters an error.
class CopyException extends FunctionException {
  /// Throw when the [copy] function encounters an error.
  CopyException(String reason) : super(reason);
}

For instance the copy method above would work with flutter without change. There is a question here whether we should remove the call to File.copySync and move to the async version so we don't halt the flutter ui.

So the job would be to create the dcli_core package and then migrate the back end of functions across to dcli_core starting with the easy ones such as the copy command.

bsutton commented 3 years ago

If you are interested in doing this I would suggest that you start with a small sample of functions:

copy copy_tree move move_dir

This will allow us to evaluate the base way of setting up the code without investing too much time.

If you have some functions that you particularly needed you could start with those. This would be useful as you could add the dcli_core library to your flutter project to test them out.

bsutton commented 2 years ago

@therenca Have a look at dcli_core https://github.com/noojee/dcli_core

It provides some of the dcli libraries suitable for use in flutter, desktop or web.