localvoid
localvoid

Reputation: 101

How to find path to the package directory when the script is running with `pub run` command

I am writing a package that loads additional data from the lib directory and would like to provide an easy way to load this data with something like this:

const dataPath = 'mypackage/data/data.json';

initializeMyLibrary(dataPath).then((_) {
  // library is ready
});

I've made two separate libraries browser.dart and standalone.dart, similar to how it is done in the Intl package.

It is quite easy to load this data from the "browser" environment, but when it comes to the "standalone" environment, it is not so easy, because of the pub run command.

When the script is running with simple $ dart myscript.dart, I can find a package path using dart:io.Platform Platform.script and Platform.packageRoot properties.

But when the script is running with $ pub run tool/mytool, the correct way to load data should be:

And even if I want to load data directly from the file system, when the script is running with pub run, Platform.script returns /mytool path.

So, the question is there any way to find that the script is running from pub run and how to find server host for the pub server?

Upvotes: 4

Views: 351

Answers (1)

localvoid
localvoid

Reputation: 101

I am not sure that this is the right way, but when I am running script with pub run, Package.script actually returns http://localhost:<port>/myscript.dart. So, when the scheme is http, I can download using http client, and when it is a file, load from the file system.

Something like this:

import 'dart:async';
import 'dart:io';
import 'package:path/path.dart' as ospath;

Future<List<int>> loadAsBytes(String path) {
  final script = Platform.script;
  final scheme = Platform.script.scheme;

  if (scheme.startsWith('http')) {
    return new HttpClient().getUrl(
        new Uri(
            scheme: script.scheme,
            host: script.host,
            port: script.port,
            path: 'packages/' + path)).then((req) {
      return req.close();
    }).then((response) {
      return response.fold(
          new BytesBuilder(),
          (b, d) => b..add(d)).then((builder) {
        return builder.takeBytes();
      });
    });

  } else if (scheme == 'file') {
    return new File(
        ospath.join(ospath.dirname(script.path), 'packages', path)).readAsBytes();
  }

  throw new Exception('...');
}

Upvotes: 4

Related Questions