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
93126a85
Commit
93126a85
authored
Apr 04, 2017
by
Yegor
Committed by
GitHub
Apr 04, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
warn about outdated Flutter installations (#9163)
parent
eb9046b1
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
473 additions
and
12 deletions
+473
-12
cache.dart
packages/flutter_tools/lib/src/cache.dart
+10
-0
flutter_command_runner.dart
.../flutter_tools/lib/src/runner/flutter_command_runner.dart
+1
-0
version.dart
packages/flutter_tools/lib/src/version.dart
+203
-11
pubspec.yaml
packages/flutter_tools/pubspec.yaml
+2
-0
context.dart
packages/flutter_tools/test/src/context.dart
+5
-1
flutter_command_runner_test.dart
...er_tools/test/src/runner/flutter_command_runner_test.dart
+29
-0
version_test.dart
packages/flutter_tools/test/src/version_test.dart
+223
-0
No files found.
packages/flutter_tools/lib/src/cache.dart
View file @
93126a85
...
...
@@ -74,6 +74,16 @@ class Cache {
_lock
=
null
;
}
/// Checks if the current process owns the lock for the cache directory at
/// this very moment; throws a [StateError] if it doesn't.
static
void
checkLockAcquired
()
{
if
(
_lockEnabled
&&
_lock
==
null
)
{
throw
new
StateError
(
'The current process does not own the lock for the cache directory. This is a bug in Flutter CLI tools.'
,
);
}
}
static
String
_dartSdkVersion
;
static
String
get
dartSdkVersion
{
...
...
packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
View file @
93126a85
...
...
@@ -236,6 +236,7 @@ class FlutterCommandRunner extends CommandRunner<Null> {
flutterUsage
.
suppressAnalytics
=
true
;
_checkFlutterCopy
();
await
FlutterVersion
.
instance
.
checkFlutterVersionFreshness
();
if
(
globalResults
.
wasParsed
(
'packages'
))
PackageMap
.
globalPackagesPath
=
fs
.
path
.
normalize
(
fs
.
path
.
absolute
(
globalResults
[
'packages'
]));
...
...
packages/flutter_tools/lib/src/version.dart
View file @
93126a85
...
...
@@ -2,11 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:convert'
;
import
'package:meta/meta.dart'
;
import
'package:quiver/time.dart'
;
import
'base/common.dart'
;
import
'base/context.dart'
;
import
'base/io.dart'
;
import
'base/process.dart'
;
import
'base/process_manager.dart'
;
import
'cache.dart'
;
import
'globals.dart'
;
final
Set
<
String
>
kKnownBranchNames
=
new
Set
<
String
>.
from
(<
String
>[
'master'
,
...
...
@@ -17,7 +25,8 @@ final Set<String> kKnownBranchNames = new Set<String>.from(<String>[
]);
class
FlutterVersion
{
FlutterVersion
.
_
()
{
@visibleForTesting
FlutterVersion
(
this
.
_clock
)
{
_channel
=
_runGit
(
'git rev-parse --abbrev-ref --symbolic @{u}'
);
final
int
slash
=
_channel
.
indexOf
(
'/'
);
...
...
@@ -33,6 +42,8 @@ class FlutterVersion {
_frameworkAge
=
_runGit
(
'git log -n 1 --pretty=format:%ar'
);
}
final
Clock
_clock
;
String
_repositoryUrl
;
String
get
repositoryUrl
=>
_repositoryUrl
;
...
...
@@ -72,20 +83,64 @@ class FlutterVersion {
}
/// A date String describing the last framework commit.
static
String
get
frameworkCommitDate
{
return
_runSync
(<
String
>[
'git'
,
'log'
,
'-n'
,
'1'
,
'--pretty=format:%ad'
,
'--date=format:%Y-%m-%d %H:%M:%S'
],
Cache
.
flutterRoot
);
String
get
frameworkCommitDate
=>
_latestGitCommitDate
();
static
String
_latestGitCommitDate
([
String
branch
])
{
final
List
<
String
>
args
=
<
String
>[
'git'
,
'log'
];
if
(
branch
!=
null
)
args
.
add
(
branch
);
args
.
addAll
(<
String
>[
'-n'
,
'1'
,
'--pretty=format:%ad'
,
'--date=iso'
]);
return
_runSync
(
args
,
lenient:
false
);
}
/// The name of the temporary git remote used to check for the latest
/// available Flutter framework version.
///
/// In the absence of bugs and crashes a Flutter developer should never see
/// this remote appear in their `git remote` list, but also if it happens to
/// persist we do the proper clean-up for extra robustness.
static
const
String
_kVersionCheckRemote
=
'__flutter_version_check__'
;
/// The date of the latest framework commit in the remote repository.
///
/// Throws [ToolExit] if a git command fails, for example, when the remote git
/// repository is not reachable due to a network issue.
static
Future
<
String
>
fetchRemoteFrameworkCommitDate
()
async
{
await
_removeVersionCheckRemoteIfExists
();
try
{
await
_run
(<
String
>[
'git'
,
'remote'
,
'add'
,
_kVersionCheckRemote
,
'https://github.com/flutter/flutter.git'
,
]);
await
_run
(<
String
>[
'git'
,
'fetch'
,
_kVersionCheckRemote
,
'master'
]);
return
_latestGitCommitDate
(
'
$_kVersionCheckRemote
/master'
);
}
finally
{
await
_removeVersionCheckRemoteIfExists
();
}
}
static
Future
<
Null
>
_removeVersionCheckRemoteIfExists
()
async
{
final
List
<
String
>
remotes
=
(
await
_run
(<
String
>[
'git'
,
'remote'
]))
.
split
(
'
\n
'
)
.
map
((
String
name
)
=>
name
.
trim
())
// to account for OS-specific line-breaks
.
toList
();
if
(
remotes
.
contains
(
_kVersionCheckRemote
))
await
_run
(<
String
>[
'git'
,
'remote'
,
'remove'
,
_kVersionCheckRemote
]);
}
static
FlutterVersion
get
instance
=>
context
.
putIfAbsent
(
FlutterVersion
,
()
=>
new
FlutterVersion
.
_
(
));
static
FlutterVersion
get
instance
=>
context
.
putIfAbsent
(
FlutterVersion
,
()
=>
new
FlutterVersion
(
const
Clock
()
));
/// Return a short string for the version (`alpha/a76bc8e22b`).
static
String
getVersionString
({
bool
whitelistBranchName:
false
})
{
final
String
cwd
=
Cache
.
flutterRoot
;
String
commit
=
_shortGitRevision
(
_runSync
(<
String
>[
'git'
,
'rev-parse'
,
'HEAD'
],
cwd
));
String
commit
=
_shortGitRevision
(
_runSync
(<
String
>[
'git'
,
'rev-parse'
,
'HEAD'
]));
commit
=
commit
.
isEmpty
?
'unknown'
:
commit
;
String
branch
=
_runSync
(<
String
>[
'git'
,
'rev-parse'
,
'--abbrev-ref'
,
'HEAD'
]
,
cwd
);
String
branch
=
_runSync
(<
String
>[
'git'
,
'rev-parse'
,
'--abbrev-ref'
,
'HEAD'
]);
branch
=
branch
==
'HEAD'
?
'master'
:
branch
;
if
(
whitelistBranchName
||
branch
.
isEmpty
)
{
...
...
@@ -96,11 +151,148 @@ class FlutterVersion {
return
'
$branch
/
$commit
'
;
}
/// The amount of time we wait before pinging the server to check for the
/// availability of a newer version of Flutter.
@visibleForTesting
static
const
Duration
kCheckAgeConsideredUpToDate
=
const
Duration
(
days:
7
);
/// We warn the user if the age of their Flutter installation is greater than
/// this duration.
@visibleForTesting
static
final
Duration
kVersionAgeConsideredUpToDate
=
kCheckAgeConsideredUpToDate
*
4
;
/// The prefix of the stamp file where we cache Flutter version check data.
@visibleForTesting
static
const
String
kFlutterVersionCheckStampFile
=
'flutter_version_check'
;
/// Checks if the currently installed version of Flutter is up-to-date, and
/// warns the user if it isn't.
///
/// This function must run while [Cache.lock] is acquired because it reads and
/// writes shared cache files.
Future
<
Null
>
checkFlutterVersionFreshness
()
async
{
final
DateTime
localFrameworkCommitDate
=
DateTime
.
parse
(
frameworkCommitDate
);
final
Duration
frameworkAge
=
_clock
.
now
().
difference
(
localFrameworkCommitDate
);
final
bool
installationSeemsOutdated
=
frameworkAge
>
kVersionAgeConsideredUpToDate
;
Future
<
bool
>
newerFrameworkVersionAvailable
()
async
{
final
DateTime
latestFlutterCommitDate
=
await
_getLatestAvailableFlutterVersion
();
if
(
latestFlutterCommitDate
==
null
)
return
false
;
return
latestFlutterCommitDate
.
isAfter
(
localFrameworkCommitDate
);
}
if
(
installationSeemsOutdated
&&
await
newerFrameworkVersionAvailable
())
printStatus
(
versionOutOfDateMessage
(
frameworkAge
),
emphasis:
true
);
}
@visibleForTesting
static
String
versionOutOfDateMessage
(
Duration
frameworkAge
)
{
String
warning
=
'WARNING: your installation of Flutter is
${frameworkAge.inDays}
days old.'
;
// Append enough spaces to match the message box width.
warning
+=
' '
*
(
74
-
warning
.
length
);
return
'''
╔════════════════════════════════════════════════════════════════════════════╗
║
$warning
║
║ ║
║ To update to the latest version, run "flutter upgrade". ║
╚════════════════════════════════════════════════════════════════════════════╝
'''
;
}
/// Gets the release date of the latest available Flutter version.
///
/// This method sends a server request if it's been more than
/// [kCheckAgeConsideredUpToDate] since the last version check.
///
/// Returns `null` if the cached version is out-of-date or missing, and we are
/// unable to reach the server to get the latest version.
Future
<
DateTime
>
_getLatestAvailableFlutterVersion
()
async
{
Cache
.
checkLockAcquired
();
const
JsonEncoder
kPrettyJsonEncoder
=
const
JsonEncoder
.
withIndent
(
' '
);
final
String
versionCheckStamp
=
Cache
.
instance
.
getStampFor
(
kFlutterVersionCheckStampFile
);
if
(
versionCheckStamp
!=
null
)
{
final
Map
<
String
,
String
>
data
=
JSON
.
decode
(
versionCheckStamp
);
final
DateTime
lastTimeVersionWasChecked
=
DateTime
.
parse
(
data
[
'lastTimeVersionWasChecked'
]);
final
Duration
timeSinceLastCheck
=
_clock
.
now
().
difference
(
lastTimeVersionWasChecked
);
// Don't ping the server too often. Return cached value if it's fresh.
if
(
timeSinceLastCheck
<
kCheckAgeConsideredUpToDate
)
return
DateTime
.
parse
(
data
[
'lastKnownRemoteVersion'
]);
}
// Cache is empty or it's been a while since the last server ping. Ping the server.
try
{
final
DateTime
remoteFrameworkCommitDate
=
DateTime
.
parse
(
await
FlutterVersion
.
fetchRemoteFrameworkCommitDate
());
Cache
.
instance
.
setStampFor
(
kFlutterVersionCheckStampFile
,
kPrettyJsonEncoder
.
convert
(<
String
,
String
>{
'lastTimeVersionWasChecked'
:
'
${_clock.now()}
'
,
'lastKnownRemoteVersion'
:
'
$remoteFrameworkCommitDate
'
,
}));
return
remoteFrameworkCommitDate
;
}
on
VersionCheckError
catch
(
error
)
{
// This happens when any of the git commands fails, which can happen when
// there's no Internet connectivity. Remote version check is best effort
// only. We do not prevent the command from running when it fails.
printTrace
(
'Failed to check Flutter version in the remote repository:
$error
'
);
return
null
;
}
}
}
String
_runSync
(
List
<
String
>
command
,
String
cwd
)
{
final
ProcessResult
results
=
processManager
.
runSync
(
command
,
workingDirectory:
cwd
);
return
results
.
exitCode
==
0
?
results
.
stdout
.
trim
()
:
''
;
/// Thrown when we fail to check Flutter version.
///
/// This can happen when we attempt to `git fetch` but there is no network, or
/// when the installation is not git-based (e.g. a user clones the repo but
/// then removes .git).
class
VersionCheckError
implements
Exception
{
VersionCheckError
(
this
.
message
);
final
String
message
;
@override
String
toString
()
=>
'
$VersionCheckError
:
$message
'
;
}
/// Runs [command] and returns the standard output as a string.
///
/// If [lenient] is `true` and the command fails, returns an empty string.
/// Otherwise, throws a [ToolExit] exception.
String
_runSync
(
List
<
String
>
command
,
{
bool
lenient:
true
})
{
final
ProcessResult
results
=
processManager
.
runSync
(
command
,
workingDirectory:
Cache
.
flutterRoot
);
if
(
results
.
exitCode
==
0
)
return
results
.
stdout
.
trim
();
if
(!
lenient
)
{
throw
new
VersionCheckError
(
'Command exited with code
${results.exitCode}
:
${command.join(' ')}
\n
'
'Standard error:
${results.stderr}
'
);
}
return
''
;
}
/// Runs [command] in the root of the Flutter installation and returns the
/// standard output as a string.
///
/// If the command fails, throws a [ToolExit] exception.
Future
<
String
>
_run
(
List
<
String
>
command
)
async
{
final
ProcessResult
results
=
await
processManager
.
run
(
command
,
workingDirectory:
Cache
.
flutterRoot
);
if
(
results
.
exitCode
==
0
)
return
results
.
stdout
.
trim
();
throw
new
VersionCheckError
(
'Command exited with code
${results.exitCode}
:
${command.join(' ')}
\n
'
'Standard error:
${results.stderr}
'
);
}
String
_shortGitRevision
(
String
revision
)
{
...
...
packages/flutter_tools/pubspec.yaml
View file @
93126a85
...
...
@@ -10,6 +10,7 @@ environment:
dependencies
:
archive
:
^1.0.20
args
:
^0.13.4
collection
:
'
>=1.9.1
<2.0.0'
coverage
:
^0.8.0
crypto
:
'
>=1.1.1
<3.0.0'
file
:
2.3.2
...
...
@@ -23,6 +24,7 @@ dependencies:
package_config
:
'
>=0.1.5
<2.0.0'
platform
:
1.1.1
process
:
2.0.1
quiver
:
^0.24.0
stack_trace
:
^1.4.0
usage
:
^3.0.1
vm_service_client
:
'
0.2.2+4'
...
...
packages/flutter_tools/test/src/context.dart
View file @
93126a85
...
...
@@ -20,6 +20,7 @@ import 'package:flutter_tools/src/ios/mac.dart';
import
'package:flutter_tools/src/ios/simulators.dart'
;
import
'package:flutter_tools/src/run_hot.dart'
;
import
'package:flutter_tools/src/usage.dart'
;
import
'package:flutter_tools/src/version.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:process/process.dart'
;
import
'package:test/test.dart'
;
...
...
@@ -53,7 +54,8 @@ void _defaultInitializeContext(AppContext testContext) {
return
mock
;
})
..
putIfAbsent
(
SimControl
,
()
=>
new
MockSimControl
())
..
putIfAbsent
(
Usage
,
()
=>
new
MockUsage
());
..
putIfAbsent
(
Usage
,
()
=>
new
MockUsage
())
..
putIfAbsent
(
FlutterVersion
,
()
=>
new
MockFlutterVersion
());
}
void
testUsingContext
(
String
description
,
dynamic
testMethod
(),
{
...
...
@@ -230,3 +232,5 @@ class _MockUsageTimer implements UsageTimer {
@override
void
finish
()
{
}
}
class
MockFlutterVersion
extends
Mock
implements
FlutterVersion
{}
packages/flutter_tools/test/src/runner/flutter_command_runner_test.dart
0 → 100644
View file @
93126a85
// Copyright 2017 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
'package:mockito/mockito.dart'
;
import
'package:test/test.dart'
;
import
'package:flutter_tools/src/version.dart'
;
import
'../context.dart'
;
import
'../common.dart'
;
import
'flutter_command_test.dart'
;
void
main
(
)
{
group
(
'FlutterCommandRunner'
,
()
{
testUsingContext
(
'checks that Flutter installation is up-to-date'
,
()
async
{
final
MockFlutterVersion
version
=
FlutterVersion
.
instance
;
bool
versionChecked
=
false
;
when
(
version
.
checkFlutterVersionFreshness
()).
thenAnswer
((
_
)
async
{
versionChecked
=
true
;
});
await
createTestCommandRunner
(
new
DummyFlutterCommand
(
shouldUpdateCache:
false
))
.
run
(<
String
>[
'dummy'
]);
expect
(
versionChecked
,
isTrue
);
});
});
}
packages/flutter_tools/test/src/version_test.dart
0 → 100644
View file @
93126a85
// Copyright 2017 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:convert'
;
import
'package:collection/collection.dart'
;
import
'package:meta/meta.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:process/process.dart'
;
import
'package:quiver/time.dart'
;
import
'package:test/test.dart'
;
import
'package:flutter_tools/src/base/context.dart'
;
import
'package:flutter_tools/src/base/io.dart'
;
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/version.dart'
;
import
'context.dart'
;
const
JsonEncoder
_kPrettyJsonEncoder
=
const
JsonEncoder
.
withIndent
(
' '
);
final
Clock
_testClock
=
new
Clock
.
fixed
(
new
DateTime
(
2015
,
1
,
1
));
final
DateTime
_upToDateVersion
=
_testClock
.
agoBy
(
FlutterVersion
.
kVersionAgeConsideredUpToDate
~/
2
);
final
DateTime
_outOfDateVersion
=
_testClock
.
agoBy
(
FlutterVersion
.
kVersionAgeConsideredUpToDate
*
2
);
final
DateTime
_stampUpToDate
=
_testClock
.
agoBy
(
FlutterVersion
.
kCheckAgeConsideredUpToDate
~/
2
);
final
DateTime
_stampOutOfDate
=
_testClock
.
agoBy
(
FlutterVersion
.
kCheckAgeConsideredUpToDate
*
2
);
const
String
_stampMissing
=
'____stamp_missing____'
;
void
main
(
)
{
group
(
'FlutterVersion'
,
()
{
setUpAll
(()
{
Cache
.
disableLocking
();
});
testFlutterVersion
(
'prints nothing when Flutter installation looks fresh'
,
()
async
{
fakeData
(
localCommitDate:
_upToDateVersion
);
await
FlutterVersion
.
instance
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
''
);
});
testFlutterVersion
(
'prints nothing when Flutter installation looks out-of-date by is actually up-to-date'
,
()
async
{
final
FlutterVersion
version
=
FlutterVersion
.
instance
;
fakeData
(
localCommitDate:
_outOfDateVersion
,
versionCheckStamp:
_testStamp
(
lastTimeVersionWasChecked:
_stampOutOfDate
,
lastKnownRemoteVersion:
_outOfDateVersion
,
),
remoteCommitDate:
_outOfDateVersion
,
expectSetStamp:
true
,
);
await
version
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
''
);
});
testFlutterVersion
(
'does not ping server when version stamp is up-to-date'
,
()
async
{
final
FlutterVersion
version
=
FlutterVersion
.
instance
;
fakeData
(
localCommitDate:
_outOfDateVersion
,
versionCheckStamp:
_testStamp
(
lastTimeVersionWasChecked:
_stampUpToDate
,
lastKnownRemoteVersion:
_upToDateVersion
,
),
);
await
version
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
FlutterVersion
.
versionOutOfDateMessage
(
_testClock
.
now
().
difference
(
_outOfDateVersion
)));
});
testFlutterVersion
(
'pings server when version stamp is missing'
,
()
async
{
final
FlutterVersion
version
=
FlutterVersion
.
instance
;
fakeData
(
localCommitDate:
_outOfDateVersion
,
versionCheckStamp:
_stampMissing
,
remoteCommitDate:
_upToDateVersion
,
expectSetStamp:
true
,
);
await
version
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
FlutterVersion
.
versionOutOfDateMessage
(
_testClock
.
now
().
difference
(
_outOfDateVersion
)));
});
testFlutterVersion
(
'pings server when version stamp is out-of-date'
,
()
async
{
final
FlutterVersion
version
=
FlutterVersion
.
instance
;
fakeData
(
localCommitDate:
_outOfDateVersion
,
versionCheckStamp:
_testStamp
(
lastTimeVersionWasChecked:
_stampOutOfDate
,
lastKnownRemoteVersion:
_testClock
.
ago
(
days:
2
),
),
remoteCommitDate:
_upToDateVersion
,
expectSetStamp:
true
,
);
await
version
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
FlutterVersion
.
versionOutOfDateMessage
(
_testClock
.
now
().
difference
(
_outOfDateVersion
)));
});
testFlutterVersion
(
'ignores network issues'
,
()
async
{
final
FlutterVersion
version
=
FlutterVersion
.
instance
;
fakeData
(
localCommitDate:
_outOfDateVersion
,
versionCheckStamp:
_stampMissing
,
errorOnFetch:
true
,
);
await
version
.
checkFlutterVersionFreshness
();
_expectVersionMessage
(
''
);
});
});
}
void
_expectVersionMessage
(
String
message
)
{
final
BufferLogger
logger
=
context
[
Logger
];
expect
(
logger
.
statusText
.
trim
(),
message
.
trim
());
}
String
_testStamp
(
{
@required
DateTime
lastTimeVersionWasChecked
,
@required
DateTime
lastKnownRemoteVersion
})
{
return
_kPrettyJsonEncoder
.
convert
(<
String
,
String
>{
'lastTimeVersionWasChecked'
:
'
$lastTimeVersionWasChecked
'
,
'lastKnownRemoteVersion'
:
'
$lastKnownRemoteVersion
'
,
});
}
void
testFlutterVersion
(
String
description
,
dynamic
testMethod
())
{
testUsingContext
(
description
,
testMethod
,
overrides:
<
Type
,
Generator
>{
FlutterVersion:
()
=>
new
FlutterVersion
(
_testClock
),
ProcessManager:
()
=>
new
MockProcessManager
(),
Cache:
()
=>
new
MockCache
(),
},
);
}
void
fakeData
(
{
@required
DateTime
localCommitDate
,
DateTime
remoteCommitDate
,
String
versionCheckStamp
,
bool
expectSetStamp:
false
,
bool
errorOnFetch:
false
,
})
{
final
MockProcessManager
pm
=
context
[
ProcessManager
];
final
MockCache
cache
=
context
[
Cache
];
ProcessResult
success
(
String
standardOutput
)
{
return
new
ProcessResult
(
1
,
0
,
standardOutput
,
''
);
}
ProcessResult
failure
(
int
exitCode
)
{
return
new
ProcessResult
(
1
,
exitCode
,
''
,
'error'
);
}
when
(
cache
.
getStampFor
(
any
)).
thenAnswer
((
Invocation
invocation
)
{
expect
(
invocation
.
positionalArguments
.
single
,
FlutterVersion
.
kFlutterVersionCheckStampFile
);
if
(
versionCheckStamp
==
_stampMissing
)
{
return
null
;
}
if
(
versionCheckStamp
!=
null
)
{
return
versionCheckStamp
;
}
throw
new
StateError
(
'Unexpected call to Cache.getStampFor(
${invocation.positionalArguments}
,
${invocation.namedArguments}
)'
);
});
when
(
cache
.
setStampFor
(
any
,
any
)).
thenAnswer
((
Invocation
invocation
)
{
expect
(
invocation
.
positionalArguments
.
first
,
FlutterVersion
.
kFlutterVersionCheckStampFile
);
if
(
expectSetStamp
)
{
expect
(
invocation
.
positionalArguments
[
1
],
_testStamp
(
lastKnownRemoteVersion:
remoteCommitDate
,
lastTimeVersionWasChecked:
_testClock
.
now
(),
));
return
null
;
}
throw
new
StateError
(
'Unexpected call to Cache.setStampFor(
${invocation.positionalArguments}
,
${invocation.namedArguments}
)'
);
});
final
Answering
syncAnswer
=
(
Invocation
invocation
)
{
bool
argsAre
(
String
a1
,
[
String
a2
,
String
a3
,
String
a4
,
String
a5
,
String
a6
,
String
a7
,
String
a8
])
{
const
ListEquality
<
String
>
equality
=
const
ListEquality
<
String
>();
final
List
<
String
>
args
=
invocation
.
positionalArguments
.
single
;
final
List
<
String
>
expectedArgs
=
<
String
>[
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
]
.
where
((
String
arg
)
=>
arg
!=
null
)
.
toList
();
return
equality
.
equals
(
args
,
expectedArgs
);
}
if
(
argsAre
(
'git'
,
'log'
,
'-n'
,
'1'
,
'--pretty=format:%ad'
,
'--date=iso'
))
{
return
success
(
localCommitDate
.
toString
());
}
else
if
(
argsAre
(
'git'
,
'remote'
))
{
return
success
(
''
);
}
else
if
(
argsAre
(
'git'
,
'remote'
,
'add'
,
'__flutter_version_check__'
,
'https://github.com/flutter/flutter.git'
))
{
return
success
(
''
);
}
else
if
(
argsAre
(
'git'
,
'fetch'
,
'__flutter_version_check__'
,
'master'
))
{
return
errorOnFetch
?
failure
(
128
)
:
success
(
''
);
}
else
if
(
remoteCommitDate
!=
null
&&
argsAre
(
'git'
,
'log'
,
'__flutter_version_check__/master'
,
'-n'
,
'1'
,
'--pretty=format:%ad'
,
'--date=iso'
))
{
return
success
(
remoteCommitDate
.
toString
());
}
throw
new
StateError
(
'Unexpected call to ProcessManager.run(
${invocation.positionalArguments}
,
${invocation.namedArguments}
)'
);
};
when
(
pm
.
runSync
(
any
,
workingDirectory:
any
)).
thenAnswer
(
syncAnswer
);
when
(
pm
.
run
(
any
,
workingDirectory:
any
)).
thenAnswer
((
Invocation
invocation
)
async
{
return
syncAnswer
(
invocation
);
});
}
class
MockProcessManager
extends
Mock
implements
ProcessManager
{}
class
MockCache
extends
Mock
implements
Cache
{}
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