Skip to content

Conversation

@szakarias
Copy link
Contributor

This PR solves the problem of including package code that makes use of assets.

  1. With this change we add assets from packages to the asset bundle if they are listed in the pubspec.yaml of the package.

For instance if a package my_package contains a directory with an image: assets/kitten.png

and its pubspec.yaml has

assets:
  -assets/kitten.png

then we add an entry called packages/my_package/assets/kitten.png .

  1. The image implementation has been changed to take an optional package parameter. The idea is that package code should use this extra parameter to specify the name of the package so that it can be used when resolving the image.

For instance the package code could be:

new Image.asset('assets/kitten.jpg', package: 'my_package')

As an alternative to 2) we could require package developers to write

new Image.asset('packages/my_package/assets/kitten.jpg')

I will work on some tests for this but would love some comments on the design.

Copy link
Contributor

@mravn-google mravn-google left a comment

Choose a reason for hiding this comment

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

The possibly-null package parameter seems complicated enough to warrant a lot of dartdoc. Can't we do anything simpler? Like e.g. adding the packages/my_package/ prefix automatically in package code?

I'm not sure the term "package" (=Flutter package) would be readily understood by the average reader.

Added some style nits below.

Copy link
Contributor

Choose a reason for hiding this comment

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

final

Copy link
Contributor

Choose a reason for hiding this comment

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

final

Copy link
Contributor

Choose a reason for hiding this comment

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

You could make this final, if you remove line 134 and then use packageManifestDescriptor['flutter'] directly in line 138.

Copy link
Contributor

Choose a reason for hiding this comment

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

=> hashValues(base, assetEntry, relativePath, source);

Copy link
Contributor

Choose a reason for hiding this comment

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

final

Copy link
Contributor

Choose a reason for hiding this comment

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

Add trailing ,

Copy link
Contributor

Choose a reason for hiding this comment

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

Add trailing ,

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 fine with adding trailing , but this file does not seem to adopt that convention...

Copy link
Contributor

Choose a reason for hiding this comment

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

Our conventions change over time and we slowly transition the entire codebase over time. Always aim for the most up to date conventions (which ideally are described in the style guide).

You should feel empowered to apply new conventions to old code aggressively. For example I will often pepper trailing commas around the codebase as I'm doing other things.

You should feel empowered to proposed PRs for the Flutter style guide, especially for updating it to match explicit conventions you hear about in reviews, or implicit conventions you observe in the codebase. The style guide isn't complete.

Copy link
Contributor

Choose a reason for hiding this comment

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

Add trailing ,

Copy link
Contributor

Choose a reason for hiding this comment

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

Looking at other Flutter implementations of == it seems the convention is to do:

@override
bool operator ==(dynamic other) {
  if (identical(other, this))
    return true;
  if (other.runtimeType != runtimeType)
    return false;
  final _Asset typedOther = other;
  return typedOther.base == base
      && typedOther.assetEntry == assetEntry
      && typedOther.relativePath == relativePath
      && typedOther.source == source;
}

Copy link
Contributor

@jakobr-google jakobr-google left a comment

Choose a reason for hiding this comment

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

LGTM.

Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: I'd remove the 'only'. The package argument can also be used in the app implementation, to refer to an asset in an imported package, but it must be specified in the package implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, true.

Copy link
Contributor

Choose a reason for hiding this comment

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

final flutterManifest = ... ?

Copy link
Contributor

Choose a reason for hiding this comment

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

IIRC, we usually do something fancier to combine the hashcodes (multiply, xor, or shift), and make sure we stay in the 30-bit range.

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 if you did if (other is! _Asset) return false;, then the analyzer should be smart enough to know that other is an _Asset below, so you wouldn't need the extra variable and cast.

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

@szakarias
Copy link
Contributor Author

I'm not entirely happy about the package parameter either. Unfortunately I don't see a much better alternative. Whatever we do, it seems that we need to explicitly specify the package name since as far as I know we are not able to ask what package we are in...

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: space before ?

Copy link
Contributor

Choose a reason for hiding this comment

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

trailing comma

Copy link
Contributor

Choose a reason for hiding this comment

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

update the docs

Copy link
Contributor

Choose a reason for hiding this comment

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

this should include more details about:
(a) what this does
(b) how you write pubspec.yaml files to use this

Copy link
Contributor

Choose a reason for hiding this comment

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

(c) how to know what string to use for "package"

Copy link
Contributor

Choose a reason for hiding this comment

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

same nits for this class as the other class

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: trailing comma here and elsewhere

Copy link
Contributor

Choose a reason for hiding this comment

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

include the same information here as earlier regarding what package does, how to use it, etc.

Copy link
Contributor

Choose a reason for hiding this comment

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

ditto

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: indent by two less

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: compare runtimeType

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: vertically align the expressions (you can put the && at the start of the line too to make it prettier)

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: never break a line that contains =>

Copy link
Contributor

Choose a reason for hiding this comment

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

use hashValues, not xor.

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 cannot use hashValues from dart:ui since the library is not available on the stand-alone VM. Do we have something else I can use instead?

Copy link
Contributor

Choose a reason for hiding this comment

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

Hm, good point. I guess xor is probably fine. dart-lang/sdk#25217 is the bug for getting hashValues into dart:core... :-)

Copy link
Contributor

Choose a reason for hiding this comment

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

style: if there's a line break after the (, there should be one before the )

@Hixie
Copy link
Contributor

Hixie commented Aug 24, 2017

This approach looks good!

At some point we should probably convert the Flutter gallery to use this since its assets come from a package too.

@szakarias szakarias force-pushed the implicitAssets branch 2 times, most recently from c6b6534 to 441bf7e Compare August 28, 2017 08:17
@szakarias
Copy link
Contributor Author

Thanks a lot for the comments! Could you please have another quick look?

Copy link
Contributor

Choose a reason for hiding this comment

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

Use of => with multi-line body should be avoided, e.g. by replacing with

@override
int get hashCode => base.hashCode ^ assetEntry.hashCode ^ relativePath.hashCode ^ source.hashCode;

or

@override
int get hashCode {
  return base.hashCode
       ^ assetEntry.hashCode 
       ^ relativePath.hashCode 
       ^ source.hashCode;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Indent by 2 less.

Copy link
Contributor

Choose a reason for hiding this comment

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

You can improve vertical alignment and consistency by always mentioning other first.

Copy link
Contributor

Choose a reason for hiding this comment

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

Cut extra space before ##...

Copy link
Contributor

Choose a reason for hiding this comment

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

... and paste it here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Remove extra line?

Copy link
Contributor

Choose a reason for hiding this comment

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

Above -- where?

Copy link
Contributor

Choose a reason for hiding this comment

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

assets

Copy link
Contributor

Choose a reason for hiding this comment

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

'packages/<package_name>/'

Copy link
Contributor

Choose a reason for hiding this comment

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

nitty nit nit: we really prefer it when the code is vertically aligned cleanly, as in:

    return base.hashCode
         ^ assetEntry.hashCode
         ^ relativePath.hashCode
         ^ source.hashCode;
```

@Hixie
Copy link
Contributor

Hixie commented Aug 29, 2017

This approach looks great. Just needs tests. Thanks!

@szakarias
Copy link
Contributor Author

Thanks! I am working on the tests.

Copy link
Contributor

@mravn-google mravn-google left a comment

Choose a reason for hiding this comment

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

LGTM

});

testUsingContext('One package with asset variants', () async {
// // Setting flutterRoot here so that it picks up the MemoryFileSystem's
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove extra //.

testUsingContext('One package with no assets', () async {
// Setting flutterRoot here so that it picks up the MemoryFileSystem's
// path separator.
Cache.flutterRoot = getFlutterRoot();
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe move this to an establishFlutterRoot function so you don't have to duplicate the comment in every test.

fs.file('p/p/$asset')
..createSync(recursive: true)
..writeAsStringSync(asset);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe extract this loop as a writeAssets function too?


writePubspecFile('pubspec.yaml', 'test');
writePackagesFile('test_package:p/p/lib/\ntest_package2:p2/p/lib/');
writePubspecFile('p/p/pubspec.yaml', 'test_package',
Copy link
Contributor

Choose a reason for hiding this comment

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

Move first and second parameter to their own lines.

@szakarias szakarias merged commit 02c10b7 into flutter:master Sep 5, 2017
mit-mit added a commit that referenced this pull request Sep 11, 2017
mit-mit added a commit that referenced this pull request Sep 12, 2017
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants