Search code examples
flutterdartbuildflutter-dependenciesdart-pub

Flutter/Dart/Pub: Is there a way to download external large binary dependencies while running a build?


At my company, we've worked on a library that utilizes OpenCV for edge detection. Because of a questionable decision, we currently have large OpenCV binaries (one >100MB, another >400MB) directly in the library repository.

When including the library in our flutter project, we've usually been referencing to tags in the library repo. This has been kind of working for us for some time now.

However, we've been gradually migrating our projects to GitHub now, and we have the issue that GitHub permits large binaries over 100 MB only when using git LFS. I'm aware that there has been an effort to add support for git LFS to pub, but it doesn't look like that feature will be finished anytime soon.

So my question is: Is there a way to download large files from a custom location during the dart "build process" (in our case thats fetching dependencies and running the build tool for code generation)? Or do you have other suggestions like e.g. writing a custom script around the build?

The goal would be to specify these steps only once for the dart package/library and simply reference the lib in our pubspec.yaml, so we don't have to duplicate the code of loading external dependencies multiple times in all library consumers.


Solution

  • You can use run() method of Process class in dart:io if you want to keep it in Dart. It enables you to run cli commands so you can write your own script for build process. In the documentation sample code is written like this:

    var result = await Process.run('grep', ['-i', 'main', 'test.dart']);
    stdout.write(result.stdout);
    stderr.write(result.stderr);
    

    Instead of "grep", you need to specify your build process one by one. First you need to get the dependencies you need so you can write a command like "curl" or use any http client in Dart. Once you download dependecies you can run something like this:

    var result = await Process.run('dart', ['compile', 'exe', 'bin/app.dart']);
    

    You just need to write a basic dart program, define your build steps and do basic error handling if you are not able to reach the server. I would create a folder called something like "static_dependecies" in lib folder so someone who reads code can understand the situation.

    Process class documentation: https://api.dart.dev/stable/2.19.6/dart-io/Process-class.html

    If you do not want to use Dart for this steps are same, just implement it in bash or bat. I would suggest using Dart and compiling your build script at worst case.