Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
28682568
Commit
28682568
authored
Feb 27, 2016
by
Devon Carew
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2245 from devoncarew/improve_startup_time
improve startup time
parents
3c7ede15
4e10bf59
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
207 additions
and
92 deletions
+207
-92
flutter_tools.dart
packages/flutter_tools/lib/flutter_tools.dart
+2
-3
android_device.dart
packages/flutter_tools/lib/src/android/android_device.dart
+19
-34
process.dart
packages/flutter_tools/lib/src/base/process.dart
+12
-4
utils.dart
packages/flutter_tools/lib/src/base/utils.dart
+9
-0
apk.dart
packages/flutter_tools/lib/src/commands/apk.dart
+11
-11
flx.dart
packages/flutter_tools/lib/src/flx.dart
+36
-39
zip.dart
packages/flutter_tools/lib/src/zip.dart
+117
-0
bundle.dart
packages/flx/lib/bundle.dart
+1
-1
No files found.
packages/flutter_tools/lib/flutter_tools.dart
View file @
28682568
...
...
@@ -3,8 +3,7 @@
// found in the LICENSE file.
import
'dart:async'
;
import
'package:archive/archive.dart'
;
import
'dart:io'
;
import
'src/flx.dart'
as
flx
;
...
...
@@ -12,7 +11,7 @@ import 'src/flx.dart' as flx;
/// pre-compiled snapshot.
Future
<
int
>
assembleFlx
({
Map
manifestDescriptor:
const
{},
Archive
File
snapshotFile:
null
,
File
snapshotFile:
null
,
String
assetBasePath:
flx
.
defaultAssetBasePath
,
String
materialAssetBasePath:
flx
.
defaultMaterialAssetBasePath
,
String
outputPath:
flx
.
defaultFlxOutputPath
,
...
...
packages/flutter_tools/lib/src/android/android_device.dart
View file @
28682568
...
...
@@ -5,7 +5,6 @@
import
'dart:async'
;
import
'dart:io'
;
import
'package:crypto/crypto.dart'
;
import
'package:path/path.dart'
as
path
;
import
'../android/android_sdk.dart'
;
...
...
@@ -136,26 +135,16 @@ class AndroidDevice extends Device {
}
String
_getSourceSha1
(
ApplicationPackage
app
)
{
var
sha1
=
new
SHA1
();
var
file
=
new
File
(
app
.
localPath
);
sha1
.
add
(
file
.
readAsBytesSync
());
return
CryptoUtils
.
bytesToHex
(
sha1
.
close
());
File
shaFile
=
new
File
(
'
${app.localPath}
.sha1'
);
return
shaFile
.
existsSync
()
?
shaFile
.
readAsStringSync
()
:
''
;
}
String
get
name
=>
modelID
;
@override
bool
isAppInstalled
(
ApplicationPackage
app
)
{
if
(
runCheckedSync
(
adbCommandForDevice
(<
String
>[
'shell'
,
'pm'
,
'path'
,
app
.
id
]))
==
''
)
{
printTrace
(
'TODO(iansf): move this log to the caller.
${app.name}
is not on the device. Installing now...'
);
return
false
;
}
if
(
_getDeviceApkSha1
(
app
)
!=
_getSourceSha1
(
app
))
{
printTrace
(
'TODO(iansf): move this log to the caller.
${app.name}
is out of date. Installing now...'
);
return
false
;
}
return
true
;
// Just check for the existence of the application SHA.
return
_getDeviceApkSha1
(
app
)
==
_getSourceSha1
(
app
);
}
@override
...
...
@@ -179,7 +168,7 @@ class AndroidDevice extends Device {
if
(
port
==
0
)
{
// Auto-bind to a port. Set up forwarding for that port. Emit a stdout
// message similar to the command-line VM
,
so that tools can parse the output.
// message similar to the command-line VM so that tools can parse the output.
// "Observatory listening on http://127.0.0.1:52111"
port
=
await
findAvailablePort
();
}
...
...
@@ -258,30 +247,26 @@ class AndroidDevice extends Device {
if
(!
_checkForSupportedAdbVersion
()
||
!
_checkForSupportedAndroidVersion
())
return
false
;
flx
.
DirectoryResult
buildResult
=
await
flx
.
buildInTempDir
(
String
localBundlePath
=
await
flx
.
buildFlx
(
toolchain
,
mainPath:
mainPath
);
printTrace
(
'Starting bundle for
$this
.'
);
try
{
if
(
await
startBundle
(
package
,
buildResult
.
localBundlePath
,
checked:
checked
,
traceStartup:
platformArgs
[
'trace-startup'
],
route:
route
,
clearLogs:
clearLogs
,
startPaused:
startPaused
,
debugPort:
debugPort
))
{
return
true
;
}
else
{
return
false
;
}
}
finally
{
buildResult
.
dispose
();
if
(
await
startBundle
(
package
,
localBundlePath
,
checked:
checked
,
traceStartup:
platformArgs
[
'trace-startup'
],
route:
route
,
clearLogs:
clearLogs
,
startPaused:
startPaused
,
debugPort:
debugPort
))
{
return
true
;
}
else
{
return
false
;
}
}
...
...
packages/flutter_tools/lib/src/base/process.dart
View file @
28682568
...
...
@@ -65,8 +65,12 @@ Future<Process> runDetached(List<String> cmd) {
/// Run cmd and return stdout.
/// Throws an error if cmd exits with a non-zero value.
String
runCheckedSync
(
List
<
String
>
cmd
,
{
String
workingDirectory
})
{
return
_runWithLoggingSync
(
cmd
,
workingDirectory:
workingDirectory
,
checked:
true
,
noisyErrors:
true
);
String
runCheckedSync
(
List
<
String
>
cmd
,
{
String
workingDirectory
,
bool
truncateCommand:
false
})
{
return
_runWithLoggingSync
(
cmd
,
workingDirectory:
workingDirectory
,
checked:
true
,
noisyErrors:
true
,
truncateCommand:
truncateCommand
);
}
/// Run cmd and return stdout.
...
...
@@ -91,9 +95,13 @@ bool exitsHappy(List<String> cli) {
String
_runWithLoggingSync
(
List
<
String
>
cmd
,
{
bool
checked:
false
,
bool
noisyErrors:
false
,
String
workingDirectory
String
workingDirectory
,
bool
truncateCommand:
false
})
{
printTrace
(
cmd
.
join
(
' '
));
String
cmdText
=
cmd
.
join
(
' '
);
if
(
truncateCommand
&&
cmdText
.
length
>
160
)
cmdText
=
cmdText
.
substring
(
0
,
160
)
+
'…'
;
printTrace
(
cmdText
);
ProcessResult
results
=
Process
.
runSync
(
cmd
[
0
],
cmd
.
getRange
(
1
,
cmd
.
length
).
toList
(),
workingDirectory:
workingDirectory
);
if
(
results
.
exitCode
!=
0
)
{
...
...
packages/flutter_tools/lib/src/base/utils.dart
View file @
28682568
...
...
@@ -3,6 +3,15 @@
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:io'
;
import
'package:crypto/crypto.dart'
;
String
calculateSha
(
File
file
)
{
SHA1
sha1
=
new
SHA1
();
sha1
.
add
(
file
.
readAsBytesSync
());
return
CryptoUtils
.
bytesToHex
(
sha1
.
close
());
}
/// A class to maintain a list of items, fire events when items are added or
/// removed, and calculate a diff of changes when a new list of items is
...
...
packages/flutter_tools/lib/src/commands/apk.dart
View file @
28682568
...
...
@@ -13,6 +13,7 @@ import '../artifacts.dart';
import
'../base/file_system.dart'
show
ensureDirectoryExists
;
import
'../base/os.dart'
;
import
'../base/process.dart'
;
import
'../base/utils.dart'
;
import
'../build_configuration.dart'
;
import
'../device.dart'
;
import
'../flx.dart'
as
flx
;
...
...
@@ -296,6 +297,9 @@ int _buildApk(
ensureDirectoryExists
(
finalApk
.
path
);
builder
.
align
(
unalignedApk
,
finalApk
);
File
apkShaFile
=
new
File
(
'
$outputFile
.sha1'
);
apkShaFile
.
writeAsStringSync
(
calculateSha
(
finalApk
));
printStatus
(
'Generated APK to
${finalApk.path}
.'
);
return
0
;
...
...
@@ -313,7 +317,7 @@ int _signApk(
String
keyPassword
;
if
(
keystoreInfo
==
null
)
{
print
Error
(
'S
igning the APK using the debug keystore.'
);
print
Status
(
'Warning: s
igning the APK using the debug keystore.'
);
keystore
=
components
.
debugKeystore
;
keystorePassword
=
_kDebugKeystorePassword
;
keyAlias
=
_kDebugKeystoreKeyAlias
;
...
...
@@ -345,13 +349,14 @@ bool _needsRebuild(String apkPath, String manifest) {
Iterable
<
FileStat
>
dependenciesStat
=
[
manifest
,
_kFlutterManifestPath
,
_kPackagesStatusPath
_kPackagesStatusPath
,
'
$apkPath
.sha1'
].
map
((
String
path
)
=>
FileStat
.
statSync
(
path
));
if
(
apkStat
.
type
==
FileSystemEntityType
.
NOT_FOUND
)
return
true
;
for
(
FileStat
dep
in
dependenciesStat
)
{
if
(
dep
.
modified
.
isAfter
(
apkStat
.
modified
))
if
(
dep
.
modified
==
null
||
dep
.
modified
.
isAfter
(
apkStat
.
modified
))
return
true
;
}
return
false
;
...
...
@@ -381,7 +386,7 @@ Future<int> buildAndroid({
}
if
(!
force
&&
!
_needsRebuild
(
outputFile
,
manifest
))
{
printTrace
(
'APK up to date
. S
kipping build step.'
);
printTrace
(
'APK up to date
; s
kipping build step.'
);
return
0
;
}
...
...
@@ -408,13 +413,8 @@ Future<int> buildAndroid({
String
mainPath
=
findMainDartFile
(
target
);
// Build the FLX.
flx
.
DirectoryResult
buildResult
=
await
flx
.
buildInTempDir
(
toolchain
,
mainPath:
mainPath
);
try
{
return
_buildApk
(
components
,
buildResult
.
localBundlePath
,
keystore
,
outputFile
);
}
finally
{
buildResult
.
dispose
();
}
String
localBundlePath
=
await
flx
.
buildFlx
(
toolchain
,
mainPath:
mainPath
);
return
_buildApk
(
components
,
localBundlePath
,
keystore
,
outputFile
);
}
}
...
...
packages/flutter_tools/lib/src/flx.dart
View file @
28682568
...
...
@@ -5,9 +5,7 @@
import
'dart:async'
;
import
'dart:convert'
;
import
'dart:io'
;
import
'dart:typed_data'
;
import
'package:archive/archive.dart'
;
import
'package:flx/bundle.dart'
;
import
'package:flx/signing.dart'
;
import
'package:path/path.dart'
as
path
;
...
...
@@ -16,6 +14,7 @@ import 'package:yaml/yaml.dart';
import
'base/file_system.dart'
show
ensureDirectoryExists
;
import
'globals.dart'
;
import
'toolchain.dart'
;
import
'zip.dart'
;
const
String
defaultMainPath
=
'lib/main.dart'
;
const
String
defaultAssetBasePath
=
'.'
;
...
...
@@ -140,20 +139,17 @@ dynamic _loadManifest(String manifestPath) {
return
loadYaml
(
manifestDescriptor
);
}
bool
_addAssetFile
(
Archive
archive
,
_Asset
asset
)
{
ZipEntry
_createAssetEntry
(
_Asset
asset
)
{
String
source
=
asset
.
source
??
asset
.
key
;
File
file
=
new
File
(
'
${asset.base}
/
$source
'
);
if
(!
file
.
existsSync
())
{
printError
(
'Cannot find asset "
$source
" in directory "
${path.absolute(asset.base)}
".'
);
return
false
;
return
null
;
}
List
<
int
>
content
=
file
.
readAsBytesSync
();
archive
.
addFile
(
new
ArchiveFile
.
noCompress
(
asset
.
key
,
content
.
length
,
content
));
return
true
;
return
new
ZipEntry
.
fromFile
(
asset
.
key
,
file
);
}
ArchiveFile
_createAssetManifest
(
Map
<
_Asset
,
List
<
_Asset
>>
assets
)
{
String
key
=
'AssetManifest.json'
;
ZipEntry
_createAssetManifest
(
Map
<
_Asset
,
List
<
_Asset
>>
assets
)
{
Map
<
String
,
List
<
String
>>
json
=
<
String
,
List
<
String
>>{};
for
(
_Asset
main
in
assets
.
keys
)
{
List
<
String
>
variants
=
<
String
>[];
...
...
@@ -161,34 +157,25 @@ ArchiveFile _createAssetManifest(Map<_Asset, List<_Asset>> assets) {
variants
.
add
(
variant
.
key
);
json
[
main
.
key
]
=
variants
;
}
List
<
int
>
content
=
UTF8
.
encode
(
JSON
.
encode
(
json
));
return
new
ArchiveFile
.
noCompress
(
key
,
content
.
length
,
content
);
return
new
ZipEntry
.
fromString
(
'AssetManifest.json'
,
JSON
.
encode
(
json
));
}
ArchiveFile
_createFontManifest
(
Map
manifestDescriptor
)
{
ZipEntry
_createFontManifest
(
Map
manifestDescriptor
)
{
if
(
manifestDescriptor
!=
null
&&
manifestDescriptor
.
containsKey
(
'fonts'
))
{
List
<
int
>
content
=
UTF8
.
encode
(
JSON
.
encode
(
manifestDescriptor
[
'fonts'
]));
return
new
ArchiveFile
.
noCompress
(
'FontManifest.json'
,
content
.
length
,
content
);
return
new
ZipEntry
.
fromString
(
'FontManifest.json'
,
JSON
.
encode
(
manifestDescriptor
[
'fonts'
]));
}
else
{
return
null
;
}
}
ArchiveFile
_createSnapshotFile
(
String
snapshotPath
)
{
File
file
=
new
File
(
snapshotPath
);
List
<
int
>
content
=
file
.
readAsBytesSync
();
return
new
ArchiveFile
(
_kSnapshotKey
,
content
.
length
,
content
);
}
/// Build the flx in a temp dir and return `localBundlePath` on success.
Future
<
DirectoryResult
>
buildInTempDir
(
/// Build the flx in the build/ directory and return `localBundlePath` on success.
Future
<
String
>
buildFlx
(
Toolchain
toolchain
,
{
String
mainPath:
defaultMainPath
})
async
{
int
result
;
Directory
tempDir
=
await
Directory
.
systemTemp
.
createTemp
(
'flutter_tools'
);
String
localBundlePath
=
path
.
join
(
tempDir
.
path
,
'app.flx'
);
String
localSnapshotPath
=
path
.
join
(
tempDir
.
path
,
'snapshot_blob.bin'
);
String
localBundlePath
=
path
.
join
(
'build'
,
'app.flx'
);
String
localSnapshotPath
=
path
.
join
(
'build'
,
'snapshot_blob.bin'
);
result
=
await
build
(
toolchain
,
snapshotPath:
localSnapshotPath
,
...
...
@@ -196,7 +183,7 @@ Future<DirectoryResult> buildInTempDir(
mainPath:
mainPath
);
if
(
result
==
0
)
return
new
DirectoryResult
(
tempDir
,
localBundlePath
)
;
return
localBundlePath
;
else
throw
result
;
}
...
...
@@ -227,7 +214,8 @@ Future<int> build(
Map
manifestDescriptor
=
_loadManifest
(
manifestPath
);
String
assetBasePath
=
path
.
dirname
(
path
.
absolute
(
manifestPath
));
ArchiveFile
snapshotFile
=
null
;
File
snapshotFile
;
if
(!
precompiledSnapshot
)
{
ensureDirectoryExists
(
snapshotPath
);
...
...
@@ -239,7 +227,7 @@ Future<int> build(
return
result
;
}
snapshotFile
=
_createSnapshot
File
(
snapshotPath
);
snapshotFile
=
new
File
(
snapshotPath
);
}
return
assemble
(
...
...
@@ -254,7 +242,7 @@ Future<int> build(
Future
<
int
>
assemble
({
Map
manifestDescriptor:
const
{},
Archive
File
snapshotFile
,
File
snapshotFile
,
String
assetBasePath:
defaultAssetBasePath
,
String
materialAssetBasePath:
defaultMaterialAssetBasePath
,
String
outputPath:
defaultFlxOutputPath
,
...
...
@@ -265,25 +253,32 @@ Future<int> assemble({
Map
<
_Asset
,
List
<
_Asset
>>
assets
=
_parseAssets
(
manifestDescriptor
,
assetBasePath
);
assets
.
addAll
(
_parseMaterialAssets
(
manifestDescriptor
,
materialAssetBasePath
));
Archive
archive
=
new
Archive
();
ZipBuilder
zipBuilder
=
new
ZipBuilder
();
if
(
snapshotFile
!=
null
)
archive
.
addFile
(
snapshotFile
);
zipBuilder
.
addEntry
(
new
ZipEntry
.
fromFile
(
_kSnapshotKey
,
snapshotFile
)
);
for
(
_Asset
asset
in
assets
.
keys
)
{
if
(!
_addAssetFile
(
archive
,
asset
))
ZipEntry
assetEntry
=
_createAssetEntry
(
asset
);
if
(
assetEntry
==
null
)
return
1
;
else
zipBuilder
.
addEntry
(
assetEntry
);
for
(
_Asset
variant
in
assets
[
asset
])
{
if
(!
_addAssetFile
(
archive
,
variant
))
ZipEntry
variantEntry
=
_createAssetEntry
(
variant
);
if
(
variantEntry
==
null
)
return
1
;
else
zipBuilder
.
addEntry
(
variantEntry
);
}
}
archive
.
addFile
(
_createAssetManifest
(
assets
));
zipBuilder
.
addEntry
(
_createAssetManifest
(
assets
));
ArchiveFile
fontManifest
=
_createFontManifest
(
manifestDescriptor
);
ZipEntry
fontManifest
=
_createFontManifest
(
manifestDescriptor
);
if
(
fontManifest
!=
null
)
archive
.
addFile
(
fontManifest
);
zipBuilder
.
addEntry
(
fontManifest
);
AsymmetricKeyPair
keyPair
=
keyPairFromPrivateKeyFileSync
(
privateKeyPath
);
printTrace
(
'KeyPair from
$privateKeyPath
:
$keyPair
.'
);
...
...
@@ -293,8 +288,10 @@ Future<int> assemble({
CipherParameters
.
get
().
seedRandom
();
}
printTrace
(
'Encoding zip file.'
);
Uint8List
zipBytes
=
new
Uint8List
.
fromList
(
new
ZipEncoder
().
encode
(
archive
));
File
zipFile
=
new
File
(
outputPath
.
substring
(
0
,
outputPath
.
length
-
4
)
+
'.zip'
);
printTrace
(
'Encoding zip file to
${zipFile.path}
'
);
zipBuilder
.
createZip
(
zipFile
,
new
Directory
(
'build/flx'
));
List
<
int
>
zipBytes
=
zipFile
.
readAsBytesSync
();
ensureDirectoryExists
(
outputPath
);
...
...
@@ -307,7 +304,7 @@ Future<int> assemble({
);
bundle
.
writeSync
();
printTrace
(
'Built
and signed flx at
$outputPath
.'
);
printTrace
(
'Built
$outputPath
.'
);
return
0
;
}
packages/flutter_tools/lib/src/zip.dart
0 → 100644
View file @
28682568
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:io'
;
import
'dart:convert'
show
UTF8
;
import
'package:archive/archive.dart'
;
import
'package:path/path.dart'
as
path
;
import
'base/process.dart'
;
abstract
class
ZipBuilder
{
factory
ZipBuilder
()
{
if
(
exitsHappy
(<
String
>[
'which'
,
'zip'
]))
{
return
new
_ZipToolBuilder
();
}
else
{
return
new
_ArchiveZipBuilder
();
}
}
ZipBuilder
.
_
();
List
<
ZipEntry
>
entries
=
<
ZipEntry
>[];
void
addEntry
(
ZipEntry
entry
)
=>
entries
.
add
(
entry
);
void
createZip
(
File
outFile
,
Directory
zipBuildDir
);
}
class
ZipEntry
{
ZipEntry
.
fromFile
(
this
.
archivePath
,
File
file
)
{
this
.
_file
=
file
;
}
ZipEntry
.
fromString
(
this
.
archivePath
,
String
contents
)
{
this
.
_contents
=
contents
;
}
final
String
archivePath
;
File
_file
;
String
_contents
;
bool
get
isStringEntry
=>
_contents
!=
null
;
}
class
_ArchiveZipBuilder
extends
ZipBuilder
{
_ArchiveZipBuilder
()
:
super
.
_
();
void
createZip
(
File
outFile
,
Directory
zipBuildDir
)
{
Archive
archive
=
new
Archive
();
for
(
ZipEntry
entry
in
entries
)
{
if
(
entry
.
isStringEntry
)
{
List
<
int
>
data
=
UTF8
.
encode
(
entry
.
_contents
);
archive
.
addFile
(
new
ArchiveFile
.
noCompress
(
entry
.
archivePath
,
data
.
length
,
data
));
}
else
{
List
<
int
>
data
=
entry
.
_file
.
readAsBytesSync
();
archive
.
addFile
(
new
ArchiveFile
(
entry
.
archivePath
,
data
.
length
,
data
));
}
}
List
<
int
>
zipData
=
new
ZipEncoder
().
encode
(
archive
);
outFile
.
writeAsBytesSync
(
zipData
);
}
}
class
_ZipToolBuilder
extends
ZipBuilder
{
_ZipToolBuilder
()
:
super
.
_
();
void
createZip
(
File
outFile
,
Directory
zipBuildDir
)
{
if
(
outFile
.
existsSync
())
outFile
.
deleteSync
();
if
(
zipBuildDir
.
existsSync
())
zipBuildDir
.
deleteSync
(
recursive:
true
);
zipBuildDir
.
createSync
(
recursive:
true
);
for
(
ZipEntry
entry
in
entries
)
{
if
(
entry
.
isStringEntry
)
{
List
<
int
>
data
=
UTF8
.
encode
(
entry
.
_contents
);
File
file
=
new
File
(
path
.
join
(
zipBuildDir
.
path
,
entry
.
archivePath
));
file
.
parent
.
createSync
(
recursive:
true
);
file
.
writeAsBytesSync
(
data
);
}
else
{
List
<
int
>
data
=
entry
.
_file
.
readAsBytesSync
();
File
file
=
new
File
(
path
.
join
(
zipBuildDir
.
path
,
entry
.
archivePath
));
file
.
parent
.
createSync
(
recursive:
true
);
file
.
writeAsBytesSync
(
data
);
}
}
runCheckedSync
(
<
String
>[
'zip'
,
'-q'
,
outFile
.
absolute
.
path
]..
addAll
(
_getCompressedNames
()),
workingDirectory:
zipBuildDir
.
path
,
truncateCommand:
true
);
runCheckedSync
(
<
String
>[
'zip'
,
'-q'
,
'-0'
,
outFile
.
absolute
.
path
]..
addAll
(
_getStoredNames
()),
workingDirectory:
zipBuildDir
.
path
,
truncateCommand:
true
);
}
Iterable
<
String
>
_getCompressedNames
()
{
return
entries
.
where
((
ZipEntry
entry
)
=>
!
entry
.
isStringEntry
)
.
map
((
ZipEntry
entry
)
=>
entry
.
archivePath
);
}
Iterable
<
String
>
_getStoredNames
()
{
return
entries
.
where
((
ZipEntry
entry
)
=>
entry
.
isStringEntry
)
.
map
((
ZipEntry
entry
)
=>
entry
.
archivePath
);
}
}
packages/flx/lib/bundle.dart
View file @
28682568
...
...
@@ -71,7 +71,7 @@ class Bundle {
Bundle
.
fromContent
({
this
.
path
,
this
.
manifest
,
contentBytes
,
List
<
int
>
contentBytes
,
AsymmetricKeyPair
keyPair
})
:
_contentBytes
=
contentBytes
{
assert
(
path
!=
null
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment