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
23e7449a
Unverified
Commit
23e7449a
authored
Jan 10, 2022
by
Greg Spencer
Committed by
GitHub
Jan 10, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Warm cache with all transitive dependencies in `flutter update-packages` command (#96258)
parent
44849ab4
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
504 additions
and
161 deletions
+504
-161
cache.dart
packages/flutter_tools/lib/src/cache.dart
+1
-1
update_packages.dart
packages/flutter_tools/lib/src/commands/update_packages.dart
+225
-127
flutter_command.dart
packages/flutter_tools/lib/src/runner/flutter_command.dart
+5
-2
update_packages_test.dart
...ls/test/commands.shard/hermetic/update_packages_test.dart
+210
-0
update_packages_test.dart
...lutter_tools/test/general.shard/update_packages_test.dart
+63
-31
No files found.
packages/flutter_tools/lib/src/cache.dart
View file @
23e7449a
...
...
@@ -153,7 +153,7 @@ class Cache {
platform
??=
FakePlatform
(
environment:
<
String
,
String
>{});
logger
??=
BufferLogger
.
test
();
return
Cache
(
rootOverride:
rootOverride
??
=
fileSystem
.
directory
(
'cache'
),
rootOverride:
rootOverride
??
fileSystem
.
directory
(
'cache'
),
artifacts:
artifacts
??
<
ArtifactSet
>[],
logger:
logger
,
fileSystem:
fileSystem
,
...
...
packages/flutter_tools/lib/src/commands/update_packages.dart
View file @
23e7449a
...
...
@@ -97,6 +97,12 @@ class UpdatePackagesCommand extends FlutterCommand {
help:
'For Flutter CLI testing only, forces this command to throw an unhandled exception.'
,
defaultsTo:
false
,
negatable:
false
,
)
..
addOption
(
'jobs'
,
abbr:
'j'
,
help:
'Causes the "pub get" runs to happen concurrently on this many '
'CPUs. Defaults to the number of CPUs that this machine has.'
,
);
}
...
...
@@ -141,19 +147,19 @@ class UpdatePackagesCommand extends FlutterCommand {
Future
<
FlutterCommandResult
>
runCommand
()
async
{
final
List
<
Directory
>
packages
=
runner
.
getRepoPackages
();
final
bool
u
pgrade
=
boolArg
(
'force-upgrade'
);
final
bool
forceU
pgrade
=
boolArg
(
'force-upgrade'
);
final
bool
isPrintPaths
=
boolArg
(
'paths'
);
final
bool
isPrintTransitiveClosure
=
boolArg
(
'transitive-closure'
);
final
bool
isVerifyOnly
=
boolArg
(
'verify-only'
);
final
bool
isConsumerOnly
=
boolArg
(
'consumer-only'
);
final
bool
offline
=
boolArg
(
'offline'
);
final
bool
crash
=
boolArg
(
'crash'
)
;
final
bool
doUpgrade
=
forceUpgrade
||
isPrintPaths
||
isPrintTransitiveClosure
;
if
(
crash
)
{
if
(
boolArg
(
'crash'
)
)
{
throw
StateError
(
'test crash please ignore.'
);
}
if
(
u
pgrade
&&
offline
)
{
if
(
forceU
pgrade
&&
offline
)
{
throwToolExit
(
'--force-upgrade cannot be used with the --offline flag'
);
...
...
@@ -177,60 +183,10 @@ class UpdatePackagesCommand extends FlutterCommand {
}
if
(
isVerifyOnly
)
{
bool
needsUpdate
=
false
;
globals
.
printStatus
(
'Verifying pubspecs...'
);
for
(
final
Directory
directory
in
packages
)
{
PubspecYaml
pubspec
;
try
{
pubspec
=
PubspecYaml
(
directory
);
}
on
String
catch
(
message
)
{
throwToolExit
(
message
);
}
globals
.
printTrace
(
'Reading pubspec.yaml from
${directory.path}
'
);
if
(
pubspec
.
checksum
.
value
==
null
)
{
// If the checksum is invalid or missing, we can just ask them run to run
// upgrade again to compute it.
globals
.
printWarning
(
'Warning: pubspec in
${directory.path}
has out of date dependencies. '
'Please run "flutter update-packages --force-upgrade" to update them correctly.'
);
needsUpdate
=
true
;
}
// all dependencies in the pubspec sorted lexically.
final
Map
<
String
,
String
>
checksumDependencies
=
<
String
,
String
>{};
for
(
final
PubspecLine
data
in
pubspec
.
inputData
)
{
if
(
data
is
PubspecDependency
&&
data
.
kind
==
DependencyKind
.
normal
)
{
checksumDependencies
[
data
.
name
]
=
data
.
version
;
}
}
final
String
checksum
=
_computeChecksum
(
checksumDependencies
.
keys
,
(
String
name
)
=>
checksumDependencies
[
name
]);
if
(
checksum
!=
pubspec
.
checksum
.
value
)
{
// If the checksum doesn't match, they may have added or removed some dependencies.
// we need to run update-packages to recapture the transitive deps.
globals
.
printWarning
(
'Warning: pubspec in
${directory.path}
has updated or new dependencies. '
'Please run "flutter update-packages --force-upgrade" to update them correctly '
'(checksum
${pubspec.checksum.value}
!=
$checksum
).'
);
needsUpdate
=
true
;
}
else
{
// everything is correct in the pubspec.
globals
.
printTrace
(
'pubspec in
${directory.path}
is up to date!'
);
}
}
if
(
needsUpdate
)
{
throwToolExit
(
'Warning: one or more pubspecs have invalid dependencies. '
'Please run "flutter update-packages --force-upgrade" to update them correctly.'
,
exitCode:
1
,
);
}
globals
.
printStatus
(
'All pubspecs were up to date.'
);
_verifyPubspecs
(
packages
);
return
FlutterCommandResult
.
success
();
}
final
Map
<
String
,
PubspecDependency
>
dependencies
=
<
String
,
PubspecDependency
>{};
final
bool
doUpgrade
=
upgrade
||
isPrintPaths
||
isPrintTransitiveClosure
;
if
(
doUpgrade
)
{
// This feature attempts to collect all the packages used across all the
// pubspec.yamls in the repo (including via transitive dependencies), and
...
...
@@ -239,9 +195,116 @@ class UpdatePackagesCommand extends FlutterCommand {
globals
.
printStatus
(
'Upgrading packages...'
);
}
// First, collect
up the explicit
dependencies:
// First, collect
the
dependencies:
final
List
<
PubspecYaml
>
pubspecs
=
<
PubspecYaml
>[];
final
Map
<
String
,
PubspecDependency
>
explicitDependencies
=
<
String
,
PubspecDependency
>{};
final
Map
<
String
,
PubspecDependency
>
allDependencies
=
<
String
,
PubspecDependency
>{};
final
Set
<
String
>
specialDependencies
=
<
String
>{};
_collectDependencies
(
packages:
packages
,
pubspecs:
pubspecs
,
explicitDependencies:
explicitDependencies
,
allDependencies:
allDependencies
,
specialDependencies:
specialDependencies
,
doUpgrade:
doUpgrade
,
);
// Now that we have all the dependencies we care about, we are going to
// create a fake package and then run either "pub upgrade", if requested,
// followed by "pub get" on it. If upgrading, the pub tool will attempt to
// bring these dependencies up to the most recent possible versions while
// honoring all their constraints. If not upgrading the pub tool will only
// attempt to download any necessary package versions to the pub cache to
// warm the cache.
final
PubDependencyTree
tree
=
PubDependencyTree
();
// object to collect results
final
Directory
tempDir
=
globals
.
fs
.
systemTempDirectory
.
createTempSync
(
'flutter_update_packages.'
);
await
_generateFakePackage
(
tempDir:
tempDir
,
dependencies:
doUpgrade
?
explicitDependencies
.
values
:
allDependencies
.
values
,
pubspecs:
pubspecs
,
tree:
tree
,
doUpgrade:
doUpgrade
,
);
if
(
doUpgrade
)
{
final
bool
done
=
_upgradePubspecs
(
tree:
tree
,
pubspecs:
pubspecs
,
explicitDependencies:
explicitDependencies
,
specialDependencies:
specialDependencies
,
);
if
(
done
)
{
// Complete early if we were just printing data.
return
FlutterCommandResult
.
success
();
}
}
await
_runPubGetOnPackages
(
packages
);
return
FlutterCommandResult
.
success
();
}
void
_verifyPubspecs
(
List
<
Directory
>
packages
)
{
bool
needsUpdate
=
false
;
globals
.
printStatus
(
'Verifying pubspecs...'
);
for
(
final
Directory
directory
in
packages
)
{
PubspecYaml
pubspec
;
try
{
pubspec
=
PubspecYaml
(
directory
);
}
on
String
catch
(
message
)
{
throwToolExit
(
message
);
}
globals
.
printTrace
(
'Reading pubspec.yaml from
${directory.path}
'
);
if
(
pubspec
.
checksum
.
value
==
null
)
{
// If the checksum is invalid or missing, we can just ask them run to run
// upgrade again to compute it.
globals
.
printWarning
(
'Warning: pubspec in
${directory.path}
has out of date dependencies. '
'Please run "flutter update-packages --force-upgrade" to update them correctly.'
);
needsUpdate
=
true
;
}
// all dependencies in the pubspec sorted lexically.
final
Map
<
String
,
String
>
checksumDependencies
=
<
String
,
String
>{};
for
(
final
PubspecLine
data
in
pubspec
.
inputData
)
{
if
(
data
is
PubspecDependency
&&
data
.
kind
==
DependencyKind
.
normal
)
{
checksumDependencies
[
data
.
name
]
=
data
.
version
;
}
}
final
String
checksum
=
_computeChecksum
(
checksumDependencies
.
keys
,
(
String
name
)
=>
checksumDependencies
[
name
]);
if
(
checksum
!=
pubspec
.
checksum
.
value
)
{
// If the checksum doesn't match, they may have added or removed some dependencies.
// we need to run update-packages to recapture the transitive deps.
globals
.
printWarning
(
'Warning: pubspec in
${directory.path}
has updated or new dependencies. '
'Please run "flutter update-packages --force-upgrade" to update them correctly '
'(checksum
${pubspec.checksum.value}
!=
$checksum
).'
);
needsUpdate
=
true
;
}
else
{
// everything is correct in the pubspec.
globals
.
printTrace
(
'pubspec in
${directory.path}
is up to date!'
);
}
}
if
(
needsUpdate
)
{
throwToolExit
(
'Warning: one or more pubspecs have invalid dependencies. '
'Please run "flutter update-packages --force-upgrade" to update them correctly.'
,
exitCode:
1
,
);
}
globals
.
printStatus
(
'All pubspecs were up to date.'
);
}
void
_collectDependencies
({
@required
List
<
Directory
>
packages
,
@required
List
<
PubspecYaml
>
pubspecs
,
@required
Set
<
String
>
specialDependencies
,
@required
Map
<
String
,
PubspecDependency
>
explicitDependencies
,
@required
Map
<
String
,
PubspecDependency
>
allDependencies
,
@required
bool
doUpgrade
,
})
{
// Visit all the directories with pubspec.yamls we care about.
for
(
final
Directory
directory
in
packages
)
{
if
(
doUpgrade
)
{
...
...
@@ -254,8 +317,38 @@ class UpdatePackagesCommand extends FlutterCommand {
throwToolExit
(
message
);
}
pubspecs
.
add
(
pubspec
);
// remember it for later
for
(
final
PubspecDependency
dependency
in
pubspec
.
allDependencies
)
{
// this is all the explicit dependencies
if
(
dependencies
.
containsKey
(
dependency
.
name
))
{
for
(
final
PubspecDependency
dependency
in
pubspec
.
allDependencies
)
{
if
(
allDependencies
.
containsKey
(
dependency
.
name
))
{
// If we've seen the dependency before, make sure that we are
// importing it the same way. There's several ways to import a
// dependency. Hosted (from pub via version number), by path (e.g.
// pointing at the version of a package we get from the Dart SDK
// that we download with Flutter), by SDK (e.g. the "flutter"
// package is explicitly from "sdk: flutter").
//
// This makes sure that we don't import a package in two different
// ways, e.g. by saying "sdk: flutter" in one pubspec.yaml and
// saying "path: ../../..." in another.
final
PubspecDependency
previous
=
allDependencies
[
dependency
.
name
];
if
(
dependency
.
kind
!=
previous
.
kind
||
dependency
.
lockTarget
!=
previous
.
lockTarget
)
{
throwToolExit
(
'Inconsistent requirements around
${dependency.name}
; '
'saw
${dependency.kind}
(
${dependency.lockTarget}
) in "
${dependency.sourcePath}
" '
'and
${previous.kind}
(
${previous.lockTarget}
) in "
${previous.sourcePath}
".'
);
}
if
(
dependency
.
version
!=
previous
.
version
)
{
globals
.
printError
(
'Requiring multiple versions: multiple versions required by
${dependency.name}
; '
'saw
${dependency.version}
in "
${dependency.sourcePath}
" '
'and
${previous.version}
in "
${previous.sourcePath}
".'
);
}
}
allDependencies
[
dependency
.
name
]
=
dependency
;
}
for
(
final
PubspecDependency
dependency
in
pubspec
.
allExplicitDependencies
)
{
if
(
explicitDependencies
.
containsKey
(
dependency
.
name
))
{
// If we've seen the dependency before, make sure that we are
// importing it the same way. There's several ways to import a
// dependency. Hosted (from pub via version number), by path (e.g.
...
...
@@ -266,17 +359,17 @@ class UpdatePackagesCommand extends FlutterCommand {
// This makes sure that we don't import a package in two different
// ways, e.g. by saying "sdk: flutter" in one pubspec.yaml and
// saying "path: ../../..." in another.
final
PubspecDependency
previous
=
d
ependencies
[
dependency
.
name
];
final
PubspecDependency
previous
=
explicitD
ependencies
[
dependency
.
name
];
if
(
dependency
.
kind
!=
previous
.
kind
||
dependency
.
lockTarget
!=
previous
.
lockTarget
)
{
throwToolExit
(
'Inconsistent requirements around
${dependency.name}
; '
'saw
${dependency.kind}
(
${dependency.lockTarget}
) in "
${dependency.sourcePath}
" '
'and
${previous.kind}
(
${previous.lockTarget}
) in "
${previous.sourcePath}
".'
'Inconsistent requirements around
${dependency.name}
; '
'saw
${dependency.kind}
(
${dependency.lockTarget}
) in "
${dependency.sourcePath}
" '
'and
${previous.kind}
(
${previous.lockTarget}
) in "
${previous.sourcePath}
".'
);
}
}
// Remember this dependency by name so we can look it up again.
d
ependencies
[
dependency
.
name
]
=
dependency
;
explicitD
ependencies
[
dependency
.
name
]
=
dependency
;
// Normal dependencies are those we get from pub. The others we
// already implicitly pin since we pull down one version of the
// Flutter and Dart SDKs, so we track which those are here so that we
...
...
@@ -286,29 +379,28 @@ class UpdatePackagesCommand extends FlutterCommand {
}
}
}
}
// Now that we have all the dependencies we explicitly care about, we are
// going to create a fake package and then run either "pub upgrade" or "pub
// get" on it, depending on whether we are upgrading or not. If upgrading,
// the pub tool will attempt to bring these dependencies up to the most
// recent possible versions while honoring all their constraints. If not
// upgrading the pub tool will attempt to download any necessary package
// versions to the pub cache to warm the cache.
final
PubDependencyTree
tree
=
PubDependencyTree
();
// object to collect results
final
Directory
tempDir
=
globals
.
fs
.
systemTempDirectory
.
createTempSync
(
'flutter_update_packages.'
);
Future
<
void
>
_generateFakePackage
({
Directory
tempDir
,
Iterable
<
PubspecDependency
>
dependencies
,
List
<
PubspecYaml
>
pubspecs
,
PubDependencyTree
tree
,
bool
doUpgrade
,
})
async
{
try
{
final
File
fakePackage
=
_pubspecFor
(
tempDir
);
fakePackage
.
createSync
();
fakePackage
.
writeAsStringSync
(
_generateFakePubspec
(
dependencies
.
values
,
dependencies
,
useAnyVersion:
doUpgrade
,
),
);
// Create a synthetic flutter SDK so that transitive flutter SDK
// constraints are not affected by this upgrade.
Directory
temporaryFlutterSdk
;
if
(
u
pgrade
)
{
if
(
doU
pgrade
)
{
temporaryFlutterSdk
=
createTemporaryFlutterSdk
(
globals
.
logger
,
globals
.
fs
,
...
...
@@ -317,17 +409,14 @@ class UpdatePackagesCommand extends FlutterCommand {
);
}
// Next we run "pub upgrade" on this generated package, if we're doing
// an upgrade. Otherwise, we just run a regular "pub get" on it in order
// to force the download of any needed packages to the pub cache.
// Next we run "pub get" on it in order to force the download of any
// needed packages to the pub cache, upgrading if requested.
await
pub
.
get
(
context:
PubContext
.
updatePackages
,
directory:
tempDir
.
path
,
upgrade:
doUpgrade
,
offline:
offline
,
flutterRootOverride:
upgrade
?
temporaryFlutterSdk
.
path
:
null
,
offline:
boolArg
(
'offline'
),
flutterRootOverride:
doUpgrade
?
temporaryFlutterSdk
.
path
:
null
,
generateSyntheticPackage:
false
,
);
// Cleanup the temporary SDK
...
...
@@ -354,54 +443,57 @@ class UpdatePackagesCommand extends FlutterCommand {
}
finally
{
tempDir
.
deleteSync
(
recursive:
true
);
}
}
if
(
doUpgrade
)
{
// The transitive dependency tree for the fake package does not contain
// dependencies between Flutter SDK packages and pub packages. We add them
// here.
for
(
final
PubspecYaml
pubspec
in
pubspecs
)
{
final
String
package
=
pubspec
.
name
;
specialDependencies
.
add
(
package
);
tree
.
_versions
[
package
]
=
pubspec
.
version
;
assert
(!
tree
.
_dependencyTree
.
containsKey
(
package
));
tree
.
_dependencyTree
[
package
]
=
<
String
>{};
for
(
final
PubspecDependency
dependency
in
pubspec
.
dependencies
)
{
if
(
dependency
.
kind
==
DependencyKind
.
normal
)
{
tree
.
_dependencyTree
[
package
].
add
(
dependency
.
name
);
}
bool
_upgradePubspecs
({
@required
PubDependencyTree
tree
,
@required
List
<
PubspecYaml
>
pubspecs
,
@required
Set
<
String
>
specialDependencies
,
@required
Map
<
String
,
PubspecDependency
>
explicitDependencies
,
})
{
// The transitive dependency tree for the fake package does not contain
// dependencies between Flutter SDK packages and pub packages. We add them
// here.
for
(
final
PubspecYaml
pubspec
in
pubspecs
)
{
final
String
package
=
pubspec
.
name
;
specialDependencies
.
add
(
package
);
tree
.
_versions
[
package
]
=
pubspec
.
version
;
assert
(!
tree
.
_dependencyTree
.
containsKey
(
package
));
tree
.
_dependencyTree
[
package
]
=
<
String
>{};
for
(
final
PubspecDependency
dependency
in
pubspec
.
dependencies
)
{
if
(
dependency
.
kind
==
DependencyKind
.
normal
)
{
tree
.
_dependencyTree
[
package
].
add
(
dependency
.
name
);
}
}
}
if
(
isPrintTransitiveClosure
)
{
tree
.
_dependencyTree
.
forEach
((
String
from
,
Set
<
String
>
to
)
{
globals
.
printStatus
(
'
$from
->
$to
'
);
});
return
FlutterCommandResult
.
success
();
}
if
(
isPrintPaths
)
{
showDependencyPaths
(
from:
stringArg
(
'from'
),
to:
stringArg
(
'to'
),
tree:
tree
);
return
FlutterCommandResult
.
success
();
}
if
(
boolArg
(
'transitive-closure'
))
{
tree
.
_dependencyTree
.
forEach
((
String
from
,
Set
<
String
>
to
)
{
globals
.
printStatus
(
'
$from
->
$to
'
);
});
return
true
;
}
// Now that we have collected all the data, we can apply our dependency
// versions to each pubspec.yaml that we collected. This mutates the
// pubspec.yaml files.
//
// The specialDependencies argument is the set of package names to not pin
// to specific versions because they are explicitly pinned by their
// constraints. Here we list the names we earlier established we didn't
// need to pin because they come from the Dart or Flutter SDKs.
for
(
final
PubspecYaml
pubspec
in
pubspecs
)
{
pubspec
.
apply
(
tree
,
specialDependencies
);
}
if
(
boolArg
(
'paths'
))
{
showDependencyPaths
(
from:
stringArg
(
'from'
),
to:
stringArg
(
'to'
),
tree:
tree
);
return
true
;
}
// Now that the pubspec.yamls are updated, we run "pub get" on each one so
// that the various packages are ready to use. This is what "flutter
// update-packages" does without --force-upgrade, so we can just fall into
// the regular code path.
// Now that we have collected all the data, we can apply our dependency
// versions to each pubspec.yaml that we collected. This mutates the
// pubspec.yaml files.
//
// The specialDependencies argument is the set of package names to not pin
// to specific versions because they are explicitly pinned by their
// constraints. Here we list the names we earlier established we didn't
// need to pin because they come from the Dart or Flutter SDKs.
for
(
final
PubspecYaml
pubspec
in
pubspecs
)
{
pubspec
.
apply
(
tree
,
specialDependencies
);
}
return
false
;
}
Future
<
void
>
_runPubGetOnPackages
(
List
<
Directory
>
packages
)
async
{
final
Stopwatch
timer
=
Stopwatch
()..
start
();
int
count
=
0
;
...
...
@@ -416,7 +508,7 @@ class UpdatePackagesCommand extends FlutterCommand {
'Running "flutter pub get" in affected packages...'
,
);
try
{
final
TaskQueue
<
void
>
queue
=
TaskQueue
<
void
>();
final
TaskQueue
<
void
>
queue
=
TaskQueue
<
void
>(
maxJobs:
intArg
(
'jobs'
)
);
for
(
final
Directory
dir
in
packages
)
{
unawaited
(
queue
.
add
(()
async
{
final
Stopwatch
stopwatch
=
Stopwatch
();
...
...
@@ -424,7 +516,9 @@ class UpdatePackagesCommand extends FlutterCommand {
await
pub
.
get
(
context:
PubContext
.
updatePackages
,
directory:
dir
.
path
,
offline:
offline
,
// All dependencies should already have been downloaded by the fake
// package, so the concurrent checks can all happen offline.
offline:
true
,
generateSyntheticPackage:
false
,
printProgress:
false
,
);
...
...
@@ -452,8 +546,6 @@ class UpdatePackagesCommand extends FlutterCommand {
final
double
seconds
=
timer
.
elapsedMilliseconds
/
1000.0
;
globals
.
printStatus
(
"
\n
Ran 'pub get'
$count
time
${count == 1 ? "" : "s"}
and fetched coverage data in
${seconds.toStringAsFixed(1)}
s."
);
return
FlutterCommandResult
.
success
();
}
void
showDependencyPaths
({
...
...
@@ -752,12 +844,17 @@ class PubspecYaml {
}
/// This returns all regular dependencies and all dev dependencies.
Iterable
<
PubspecDependency
>
get
allDependencies
{
Iterable
<
PubspecDependency
>
get
all
Explicit
Dependencies
{
return
inputData
.
whereType
<
PubspecDependency
>()
.
where
((
PubspecDependency
data
)
=>
data
.
kind
!=
DependencyKind
.
overridden
&&
!
data
.
isTransitive
);
}
/// This returns all dependencies.
Iterable
<
PubspecDependency
>
get
allDependencies
{
return
inputData
.
whereType
<
PubspecDependency
>();
}
/// Take a dependency graph with explicit version numbers, and apply them to
/// the pubspec.yaml, ignoring any that we know are special dependencies (those
/// that depend on the Flutter or Dart SDK directly and are thus automatically
...
...
@@ -814,7 +911,8 @@ class PubspecYaml {
// We output data that matches the format that
// PubspecDependency.parse can handle. The data.suffix is any
// previously-specified trailing comment.
assert
(
versions
.
contains
(
data
.
name
));
assert
(
versions
.
contains
(
data
.
name
),
"versions doesn't contain
${data.name}
"
);
output
.
add
(
'
${data.name}
:
${versions.versionFor(data.name)}${data.suffix}
'
);
}
else
{
// If it wasn't a regular dependency, then we output the line
...
...
packages/flutter_tools/lib/src/runner/flutter_command.dart
View file @
23e7449a
...
...
@@ -1473,12 +1473,15 @@ abstract class FlutterCommand extends Command<void> {
ApplicationPackageFactory
?
applicationPackages
;
/// Gets the parsed command-line option named [name] as `bool`.
/// Gets the parsed command-line option named [name] as
a
`bool`.
bool
boolArg
(
String
name
)
=>
argResults
?[
name
]
as
bool
?
??
false
;
/// Gets the parsed command-line option named [name] as `String`.
/// Gets the parsed command-line option named [name] as
a
`String`.
String
?
stringArg
(
String
name
)
=>
argResults
?[
name
]
as
String
?;
/// Gets the parsed command-line option named [name] as an `int`.
int
?
intArg
(
String
name
)
=>
argResults
?[
name
]
as
int
?;
/// Gets the parsed command-line option named [name] as `List<String>`.
List
<
String
>
stringsArg
(
String
name
)
=>
argResults
?[
name
]
as
List
<
String
>?
??
<
String
>[];
}
...
...
packages/flutter_tools/test/commands.shard/hermetic/update_packages_test.dart
View file @
23e7449a
...
...
@@ -4,9 +4,75 @@
// @dart = 2.8
import
'package:file/file.dart'
;
import
'package:file/memory.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/commands/update_packages.dart'
;
import
'package:flutter_tools/src/dart/pub.dart'
;
import
'package:meta/meta.dart'
;
import
'package:test/fake.dart'
;
import
'../../src/common.dart'
;
import
'../../src/context.dart'
;
import
'../../src/test_flutter_command_runner.dart'
;
// An example pubspec.yaml from flutter, not necessary for it to be up to date.
const
String
kFlutterPubspecYaml
=
r''
'
name: flutter
description: A framework for writing Flutter applications
homepage: http://flutter.dev
environment:
sdk: ">=2.2.2 <3.0.0"
dependencies:
# To update these, use "flutter update-packages --force-upgrade".
collection: 1.14.11
meta: 1.1.8
typed_data: 1.1.6
vector_math: 2.0.8
sky_engine:
sdk: flutter
gallery:
git:
url: https://github.com/flutter/gallery.git
ref: d00362e6bdd0f9b30bba337c358b9e4a6e4ca950
dev_dependencies:
flutter_test:
sdk: flutter
flutter_goldens:
sdk: flutter
archive: 2.0.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
# PUBSPEC CHECKSUM: 1234
'''
;
// An example pubspec.yaml, not necessary for it to be up to date.
const
String
kExamplesPubspecYaml
=
r''
'
name: examples
description: Examples for flutter
homepage: http://flutter.dev
version: 1.0.0
environment:
sdk: ">=2.14.0-383.0.dev <3.0.0"
flutter: ">=2.5.0-6.0.pre.30 <3.0.0"
dependencies:
cupertino_icons: 1.0.4
flutter:
sdk: flutter
archive: 2.0.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
# PUBSPEC CHECKSUM: 6543
'''
;
void
main
(
)
{
testWithoutContext
(
'kManuallyPinnedDependencies pins are actually pins'
,
()
{
...
...
@@ -16,4 +82,148 @@ void main() {
reason:
'Version pins in kManuallyPinnedDependencies must be specific pins, not ranges.'
,
);
});
group
(
'update-packages'
,
()
{
FileSystem
fileSystem
;
Directory
flutterSdk
;
Directory
flutter
;
FakePub
pub
;
setUpAll
(()
{
Cache
.
disableLocking
();
});
setUp
(()
{
fileSystem
=
MemoryFileSystem
.
test
();
flutterSdk
=
fileSystem
.
directory
(
'flutter'
)..
createSync
();
flutterSdk
.
childFile
(
'version'
).
writeAsStringSync
(
'1.2.3'
);
flutter
=
flutterSdk
.
childDirectory
(
'packages'
).
childDirectory
(
'flutter'
)
..
createSync
(
recursive:
true
);
flutterSdk
.
childDirectory
(
'dev'
).
createSync
(
recursive:
true
);
flutterSdk
.
childDirectory
(
'examples'
).
childFile
(
'pubspec.yaml'
)
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
kExamplesPubspecYaml
);
flutter
.
childFile
(
'pubspec.yaml'
).
writeAsStringSync
(
kFlutterPubspecYaml
);
Cache
.
flutterRoot
=
flutterSdk
.
absolute
.
path
;
pub
=
FakePub
(
fileSystem
);
});
testUsingContext
(
'updates packages'
,
()
async
{
final
UpdatePackagesCommand
command
=
UpdatePackagesCommand
();
await
createTestCommandRunner
(
command
).
run
(<
String
>[
'update-packages'
]);
expect
(
pub
.
pubGetDirectories
,
equals
(<
String
>[
'/.tmp_rand0/flutter_update_packages.rand0'
,
'/flutter/examples'
,
'/flutter/packages/flutter'
,
]));
expect
(
pub
.
pubBatchDirectories
,
isEmpty
);
},
overrides:
<
Type
,
Generator
>{
Pub:
()
=>
pub
,
FileSystem:
()
=>
fileSystem
,
ProcessManager:
()
=>
FakeProcessManager
.
any
(),
Cache:
()
=>
Cache
.
test
(
processManager:
FakeProcessManager
.
any
(),
),
});
testUsingContext
(
'force updates packages'
,
()
async
{
final
UpdatePackagesCommand
command
=
UpdatePackagesCommand
();
await
createTestCommandRunner
(
command
).
run
(<
String
>[
'update-packages'
,
'--force-upgrade'
,
]);
expect
(
pub
.
pubGetDirectories
,
equals
(<
String
>[
'/.tmp_rand0/flutter_update_packages.rand0'
,
'/flutter/examples'
,
'/flutter/packages/flutter'
,
]));
expect
(
pub
.
pubBatchDirectories
,
equals
(<
String
>[
'/.tmp_rand0/flutter_update_packages.rand0'
,
]));
},
overrides:
<
Type
,
Generator
>{
Pub:
()
=>
pub
,
FileSystem:
()
=>
fileSystem
,
ProcessManager:
()
=>
FakeProcessManager
.
any
(),
Cache:
()
=>
Cache
.
test
(
processManager:
FakeProcessManager
.
any
(),
),
});
});
}
class
FakePub
extends
Fake
implements
Pub
{
FakePub
(
this
.
fileSystem
);
final
FileSystem
fileSystem
;
final
List
<
String
>
pubGetDirectories
=
<
String
>[];
final
List
<
String
>
pubBatchDirectories
=
<
String
>[];
@override
Future
<
void
>
get
({
@required
PubContext
context
,
String
directory
,
bool
skipIfAbsent
=
false
,
bool
upgrade
=
false
,
bool
offline
=
false
,
bool
generateSyntheticPackage
=
false
,
String
flutterRootOverride
,
bool
checkUpToDate
=
false
,
bool
shouldSkipThirdPartyGenerator
=
true
,
bool
printProgress
=
true
,
})
async
{
pubGetDirectories
.
add
(
directory
);
fileSystem
.
directory
(
directory
).
childFile
(
'pubspec.lock'
)
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
'''
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
async:
dependency: "direct dev"
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.8.2"
sdks:
dart: ">=2.14.0 <3.0.0"
'''
);
fileSystem
.
currentDirectory
.
childDirectory
(
'.dart_tool'
)
.
childFile
(
'package_config.json'
)
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
'{"configVersion":2,"packages":[]}'
);
}
@override
Future
<
void
>
batch
(
List
<
String
>
arguments
,
{
@required
PubContext
context
,
String
directory
,
MessageFilter
filter
,
String
failureMessage
=
'pub failed'
,
@required
bool
retry
,
bool
showTraceForErrors
,
})
async
{
pubBatchDirectories
.
add
(
directory
);
'''
Dart SDK 2.16.0-144.0.dev
Flutter SDK 2.9.0-1.0.pre.263
flutter_api_samples 1.0.0
dependencies:
- cupertino_icons 1.0.4
- collection 1.15.0
- meta 1.7.0
- typed_data 1.3.0 [collection]
- vector_math 2.1.1
dev dependencies:
transitive dependencies:
- platform 3.1.0
- process 4.2.4 [file path platform]
'''
.
split
(
'
\n
'
).
forEach
(
filter
);
}
}
packages/flutter_tools/test/general.shard/update_packages_test.dart
View file @
23e7449a
...
...
@@ -79,36 +79,36 @@ dependencies:
'''
;
void
main
(
)
{
testWithoutContext
(
'createTemporaryFlutterSdk creates an unpinned flutter SDK'
,
()
{
final
FileSystem
fileSystem
=
MemoryFileSystem
.
test
();
FileSystem
fileSystem
;
Directory
flutterSdk
;
Directory
flutter
;
setUp
(()
{
fileSystem
=
MemoryFileSystem
.
test
();
// Setup simplified Flutter SDK.
final
Directory
flutterSdk
=
fileSystem
.
directory
(
'flutter'
)
..
createSync
();
flutterSdk
=
fileSystem
.
directory
(
'flutter'
)..
createSync
();
// Create version file
flutterSdk
.
childFile
(
'version'
).
writeAsStringSync
(
'1.2.3'
);
// Create a pubspec file
final
Directory
flutter
=
flutterSdk
.
childDirectory
(
'packages'
)
.
childDirectory
(
'flutter'
)
flutter
=
flutterSdk
.
childDirectory
(
'packages'
).
childDirectory
(
'flutter'
)
..
createSync
(
recursive:
true
);
flutter
.
childFile
(
'pubspec.yaml'
)
.
writeAsStringSync
(
kFlutterPubspecYaml
);
flutter
.
childFile
(
'pubspec.yaml'
).
writeAsStringSync
(
kFlutterPubspecYaml
);
});
testWithoutContext
(
'createTemporaryFlutterSdk creates an unpinned flutter SDK'
,
()
{
// A stray extra package should not cause a crash.
final
Directory
extra
=
flutterSdk
.
childDirectory
(
'packages'
)
.
childDirectory
(
'extra'
)
.
childDirectory
(
'packages'
)
.
childDirectory
(
'extra'
)
..
createSync
(
recursive:
true
);
extra
.
childFile
(
'pubspec.yaml'
)
.
writeAsStringSync
(
kExtraPubspecYaml
);
extra
.
childFile
(
'pubspec.yaml'
).
writeAsStringSync
(
kExtraPubspecYaml
);
// Create already parsed pubspecs.
final
PubspecYaml
flutterPubspec
=
PubspecYaml
(
flutter
);
final
PubspecDependency
gitDependency
=
flutterPubspec
.
dependencies
.
firstWhere
((
PubspecDependency
dep
)
=>
dep
.
kind
==
DependencyKind
.
git
);
final
PubspecDependency
gitDependency
=
flutterPubspec
.
dependencies
.
firstWhere
((
PubspecDependency
dep
)
=>
dep
.
kind
==
DependencyKind
.
git
);
expect
(
gitDependency
.
lockLine
,
'''
...
...
@@ -152,25 +152,57 @@ void main() {
});
testWithoutContext
(
'Throws a StateError on a malformed git: reference'
,
()
{
final
FileSystem
fileSystem
=
MemoryFileSystem
.
test
();
// Setup simplified Flutter SDK.
final
Directory
flutterSdk
=
fileSystem
.
directory
(
'flutter'
)
..
createSync
();
// Create version file
flutterSdk
.
childFile
(
'version'
).
writeAsStringSync
(
'1.2.3'
);
// Create a pubspec file
final
Directory
flutter
=
flutterSdk
.
childDirectory
(
'packages'
)
.
childDirectory
(
'flutter'
)
..
createSync
(
recursive:
true
);
flutter
.
childFile
(
'pubspec.yaml'
)
.
writeAsStringSync
(
kInvalidGitPubspec
);
// Create an invalid pubspec file.
flutter
.
childFile
(
'pubspec.yaml'
).
writeAsStringSync
(
kInvalidGitPubspec
);
expect
(
()
=>
PubspecYaml
(
flutter
),
throwsStateError
,
);
});
testWithoutContext
(
'PubspecYaml Loads dependencies'
,
()
async
{
final
PubspecYaml
pubspecYaml
=
PubspecYaml
(
flutter
);
expect
(
pubspecYaml
.
allDependencies
.
map
<
String
>((
PubspecDependency
dependency
)
=>
'
${dependency.name}
:
${dependency.version}
'
)
.
toSet
(),
equals
(<
String
>{
'collection: 1.14.11'
,
'meta: 1.1.8'
,
'typed_data: 1.1.6'
,
'vector_math: 2.0.8'
,
'sky_engine: '
,
'gallery: '
,
'flutter_test: '
,
'flutter_goldens: '
,
'archive: 2.0.11'
,
}));
expect
(
pubspecYaml
.
allExplicitDependencies
.
map
<
String
>((
PubspecDependency
dependency
)
=>
'
${dependency.name}
:
${dependency.version}
'
)
.
toSet
(),
equals
(<
String
>{
'collection: 1.14.11'
,
'meta: 1.1.8'
,
'typed_data: 1.1.6'
,
'vector_math: 2.0.8'
,
'sky_engine: '
,
'gallery: '
,
'flutter_test: '
,
'flutter_goldens: '
}));
expect
(
pubspecYaml
.
dependencies
.
map
<
String
>((
PubspecDependency
dependency
)
=>
'
${dependency.name}
:
${dependency.version}
'
)
.
toSet
(),
equals
(<
String
>{
'collection: 1.14.11'
,
'meta: 1.1.8'
,
'typed_data: 1.1.6'
,
'vector_math: 2.0.8'
,
'sky_engine: '
,
'gallery: '
}));
});
}
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