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
e2554a92
Unverified
Commit
e2554a92
authored
Feb 13, 2020
by
Jonah Williams
Committed by
GitHub
Feb 13, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add "flutter downgrade" command (#50506)
parent
1f3d423f
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
835 additions
and
66 deletions
+835
-66
executable.dart
packages/flutter_tools/lib/executable.dart
+2
-0
downgrade.dart
packages/flutter_tools/lib/src/commands/downgrade.dart
+191
-0
upgrade.dart
packages/flutter_tools/lib/src/commands/upgrade.dart
+56
-27
version.dart
packages/flutter_tools/lib/src/commands/version.dart
+22
-1
persistent_tool_state.dart
packages/flutter_tools/lib/src/persistent_tool_state.dart
+33
-0
version.dart
packages/flutter_tools/lib/src/version.dart
+54
-11
downgrade_test.dart
...er_tools/test/commands.shard/hermetic/downgrade_test.dart
+249
-0
version_test.dart
...tter_tools/test/commands.shard/hermetic/version_test.dart
+49
-1
upgrade_test.dart
...ter_tools/test/commands.shard/permeable/upgrade_test.dart
+30
-24
persistent_tool_state_test.dart
..._tools/test/general.shard/persistent_tool_state_test.dart
+27
-2
downgrade_upgrade_integration_test.dart
...integration.shard/downgrade_upgrade_integration_test.dart
+122
-0
No files found.
packages/flutter_tools/lib/executable.dart
View file @
e2554a92
...
...
@@ -25,6 +25,7 @@ import 'src/commands/create.dart';
import
'src/commands/daemon.dart'
;
import
'src/commands/devices.dart'
;
import
'src/commands/doctor.dart'
;
import
'src/commands/downgrade.dart'
;
import
'src/commands/drive.dart'
;
import
'src/commands/emulators.dart'
;
import
'src/commands/format.dart'
;
...
...
@@ -76,6 +77,7 @@ Future<void> main(List<String> args) async {
DaemonCommand
(
hidden:
!
verboseHelp
),
DevicesCommand
(),
DoctorCommand
(
verbose:
verbose
),
DowngradeCommand
(),
DriveCommand
(),
EmulatorsCommand
(),
FormatCommand
(),
...
...
packages/flutter_tools/lib/src/commands/downgrade.dart
0 → 100644
View file @
e2554a92
// Copyright 2014 The Flutter 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:process/process.dart'
;
import
'../base/common.dart'
;
import
'../base/file_system.dart'
;
import
'../base/io.dart'
;
import
'../base/logger.dart'
;
import
'../base/process.dart'
;
import
'../base/terminal.dart'
;
import
'../base/time.dart'
;
import
'../cache.dart'
;
import
'../globals.dart'
as
globals
;
import
'../persistent_tool_state.dart'
;
import
'../runner/flutter_command.dart'
;
import
'../version.dart'
;
/// The flutter downgrade command returns the SDK to the last recorded version
/// for a particular branch.
///
/// For example, suppose a user on the beta channel upgrades from 1.2.3 to 1.4.6.
/// The tool will record that sha "abcdefg" was the last active beta channel in the
/// persistent tool state. If the user is still on the beta channel and runs
/// flutter downgrade, this will take the user back to "abcdefg". They will not be
/// able to downgrade again, since the tool only records one prior version.
/// Additionally, if they had switched channels to stable before trying to downgrade,
/// the command would fail since there was no previously recorded stable version.
class
DowngradeCommand
extends
FlutterCommand
{
DowngradeCommand
({
PersistentToolState
persistentToolState
,
Logger
logger
,
ProcessManager
processManager
,
FlutterVersion
flutterVersion
,
AnsiTerminal
terminal
,
Stdio
stdio
,
FileSystem
fileSystem
,
})
:
_terminal
=
terminal
,
_flutterVersion
=
flutterVersion
,
_persistentToolState
=
persistentToolState
,
_processManager
=
processManager
,
_stdio
=
stdio
,
_logger
=
logger
,
_fileSystem
=
fileSystem
{
argParser
.
addOption
(
'working-directory'
,
hide:
true
,
help:
'Override the downgrade working directory for integration testing.'
);
argParser
.
addFlag
(
'prompt'
,
defaultsTo:
true
,
hide:
true
,
help:
'Disable the downgrade prompt for integration testing.'
);
}
AnsiTerminal
_terminal
;
FlutterVersion
_flutterVersion
;
PersistentToolState
_persistentToolState
;
ProcessUtils
_processUtils
;
ProcessManager
_processManager
;
Logger
_logger
;
Stdio
_stdio
;
FileSystem
_fileSystem
;
@override
String
get
description
=>
'Downgrade Flutter to the last active version for the current channel.'
;
@override
String
get
name
=>
'downgrade'
;
@override
Future
<
FlutterCommandResult
>
runCommand
()
async
{
// Note: commands do not necessarily have access to the correct zone injected
// values when being created. Fields must be lazily instantiated in runCommand,
// at least until the zone injection is refactored.
_terminal
??=
globals
.
terminal
;
_logger
??=
globals
.
logger
;
_flutterVersion
??=
globals
.
flutterVersion
;
_persistentToolState
??=
globals
.
persistentToolState
;
_processManager
??=
globals
.
processManager
;
_processUtils
??=
ProcessUtils
(
processManager:
_processManager
,
logger:
_logger
);
_stdio
??=
globals
.
stdio
;
_fileSystem
??=
globals
.
fs
;
String
workingDirectory
=
Cache
.
flutterRoot
;
if
(
argResults
.
wasParsed
(
'working-directory'
))
{
workingDirectory
=
stringArg
(
'working-directory'
);
_flutterVersion
=
FlutterVersion
(
const
SystemClock
(),
workingDirectory
);
}
final
String
currentChannel
=
_flutterVersion
.
channel
;
final
Channel
channel
=
getChannelForName
(
currentChannel
);
if
(
channel
==
null
)
{
throwToolExit
(
'Flutter is not currently on a known channel. Use "flutter channel <name>" '
'to switch to an official channel.'
,
);
}
final
String
lastFlutterVesion
=
_persistentToolState
.
lastActiveVersion
(
channel
);
final
String
currentFlutterVersion
=
_flutterVersion
.
frameworkRevision
;
if
(
lastFlutterVesion
==
null
||
currentFlutterVersion
==
lastFlutterVesion
)
{
final
String
trailing
=
await
_createErrorMessage
(
workingDirectory
,
channel
);
throwToolExit
(
'There is no previously recorded version for channel "
$currentChannel
".
\n
'
'
$trailing
'
);
}
// Detect unkown versions.
final
RunResult
parseResult
=
await
_processUtils
.
run
(<
String
>[
'git'
,
'describe'
,
'--tags'
,
lastFlutterVesion
,
],
workingDirectory:
workingDirectory
);
if
(
parseResult
.
exitCode
!=
0
)
{
throwToolExit
(
'Failed to parse version for downgrade:
\n
${parseResult.stderr}
'
);
}
final
String
humanReadableVersion
=
parseResult
.
stdout
;
// If there is a terminal attached, prompt the user to confirm the downgrade.
if
(
_stdio
.
hasTerminal
&&
boolArg
(
'prompt'
))
{
_terminal
.
usesTerminalUi
=
true
;
final
String
result
=
await
_terminal
.
promptForCharInput
(
const
<
String
>[
'y'
,
'n'
],
prompt:
'Downgrade flutter to version
$humanReadableVersion
?'
,
logger:
_logger
,
);
if
(
result
==
'n'
)
{
return
FlutterCommandResult
.
success
();
}
}
else
{
_logger
.
printStatus
(
'Downgrading Flutter to version
$humanReadableVersion
'
);
}
// To downgrade the tool, we perform a git checkout --hard, and then
// switch channels. The version recorded must have existed on that branch
// so this operation is safe.
try
{
await
_processUtils
.
run
(
<
String
>[
'git'
,
'reset'
,
'--hard'
,
lastFlutterVesion
],
throwOnError:
true
,
workingDirectory:
workingDirectory
,
);
}
on
ProcessException
catch
(
error
)
{
throwToolExit
(
'Unable to downgrade Flutter: The tool could not update to the version '
'
$humanReadableVersion
. This may be due to git not being installed or an '
'internal error. Please ensure that git is installed on your computer and '
'retry again.
\n
Error:
$error
.'
);
}
try
{
await
_processUtils
.
run
(
<
String
>[
'git'
,
'checkout'
,
currentChannel
,
'--'
],
throwOnError:
true
,
workingDirectory:
workingDirectory
,
);
}
on
ProcessException
catch
(
error
)
{
throwToolExit
(
'Unable to downgrade Flutter: The tool could not switch to the channel '
'
$currentChannel
. This may be due to git not being installed or an '
'internal error. Please ensure that git is installed on your computer '
'and retry again.
\n
Error:
$error
.'
);
}
await
FlutterVersion
.
resetFlutterVersionFreshnessCheck
();
_logger
.
printStatus
(
'Success'
);
return
FlutterCommandResult
.
success
();
}
// Formats an error message that lists the currently stored versions.
Future
<
String
>
_createErrorMessage
(
String
workingDirectory
,
Channel
currentChannel
)
async
{
final
StringBuffer
buffer
=
StringBuffer
();
for
(
final
Channel
channel
in
Channel
.
values
)
{
if
(
channel
==
currentChannel
)
{
continue
;
}
final
String
sha
=
_persistentToolState
.
lastActiveVersion
(
channel
);
if
(
sha
==
null
)
{
continue
;
}
final
RunResult
parseResult
=
await
_processUtils
.
run
(<
String
>[
'git'
,
'describe'
,
'--tags'
,
sha
,
],
workingDirectory:
workingDirectory
);
if
(
parseResult
.
exitCode
==
0
)
{
buffer
.
writeln
(
'Channel "
${getNameForChannel(channel)}
" was previously on:
${parseResult.stdout}
.'
);
}
}
return
buffer
.
toString
();
}
}
packages/flutter_tools/lib/src/commands/upgrade.dart
View file @
e2554a92
...
...
@@ -10,6 +10,7 @@ import '../base/common.dart';
import
'../base/io.dart'
;
import
'../base/os.dart'
;
import
'../base/process.dart'
;
import
'../base/time.dart'
;
import
'../cache.dart'
;
import
'../dart/pub.dart'
;
import
'../globals.dart'
as
globals
;
...
...
@@ -34,6 +35,11 @@ class UpgradeCommand extends FlutterCommand {
help:
'For the second half of the upgrade flow requiring the new '
'version of Flutter. Should not be invoked manually, but '
're-entrantly by the standard upgrade command.'
,
)
..
addOption
(
'working-directory'
,
hide:
true
,
help:
'Override the upgrade working directoy for integration testing.'
);
}
...
...
@@ -50,36 +56,50 @@ class UpgradeCommand extends FlutterCommand {
@override
Future
<
FlutterCommandResult
>
runCommand
()
{
_commandRunner
.
workingDirectory
=
stringArg
(
'working-directory'
)
??
Cache
.
flutterRoot
;
return
_commandRunner
.
runCommand
(
boolArg
(
'force'
),
boolArg
(
'continue'
),
GitTagVersion
.
determine
(),
globals
.
flutterVersion
,
force:
boolArg
(
'force'
),
continueFlow:
boolArg
(
'continue'
),
testFlow:
stringArg
(
'working-directory'
)
!=
null
,
gitTagVersion:
GitTagVersion
.
determine
(
processUtils
),
flutterVersion:
stringArg
(
'working-directory'
)
==
null
?
globals
.
flutterVersion
:
FlutterVersion
(
const
SystemClock
(),
_commandRunner
.
workingDirectory
),
);
}
}
@visibleForTesting
class
UpgradeCommandRunner
{
Future
<
FlutterCommandResult
>
runCommand
(
bool
force
,
bool
continueFlow
,
GitTagVersion
gitTagVersion
,
FlutterVersion
flutterVersion
,
)
async
{
String
workingDirectory
;
Future
<
FlutterCommandResult
>
runCommand
({
@required
bool
force
,
@required
bool
continueFlow
,
@required
bool
testFlow
,
@required
GitTagVersion
gitTagVersion
,
@required
FlutterVersion
flutterVersion
,
})
async
{
if
(!
continueFlow
)
{
await
runCommandFirstHalf
(
force
,
gitTagVersion
,
flutterVersion
);
await
runCommandFirstHalf
(
force:
force
,
gitTagVersion:
gitTagVersion
,
flutterVersion:
flutterVersion
,
testFlow:
testFlow
,
);
}
else
{
await
runCommandSecondHalf
(
flutterVersion
);
}
return
FlutterCommandResult
.
success
();
}
Future
<
void
>
runCommandFirstHalf
(
bool
force
,
GitTagVersion
gitTagVersion
,
FlutterVersion
flutterVersion
,
)
async
{
Future
<
void
>
runCommandFirstHalf
({
@required
bool
force
,
@required
GitTagVersion
gitTagVersion
,
@required
FlutterVersion
flutterVersion
,
@required
bool
testFlow
,
})
async
{
await
verifyUpstreamConfigured
();
if
(!
force
&&
gitTagVersion
==
const
GitTagVersion
.
unknown
())
{
// If the commit is a recognized branch and not master,
...
...
@@ -110,6 +130,7 @@ class UpgradeCommandRunner {
'command with --force.'
);
}
recordState
(
flutterVersion
);
await
resetChanges
(
gitTagVersion
);
await
upgradeChannel
(
flutterVersion
);
final
bool
alreadyUpToDate
=
await
attemptFastForward
(
flutterVersion
);
...
...
@@ -117,11 +138,19 @@ class UpgradeCommandRunner {
// If the upgrade was a no op, then do not continue with the second half.
globals
.
printStatus
(
'Flutter is already up to date on channel
${flutterVersion.channel}
'
);
globals
.
printStatus
(
'
$flutterVersion
'
);
}
else
{
}
else
if
(!
testFlow
)
{
await
flutterUpgradeContinue
();
}
}
void
recordState
(
FlutterVersion
flutterVersion
)
{
final
Channel
channel
=
getChannelForName
(
flutterVersion
.
channel
);
if
(
channel
==
null
)
{
return
;
}
globals
.
persistentToolState
.
updateLastActiveVersion
(
flutterVersion
.
frameworkRevision
,
channel
);
}
Future
<
void
>
flutterUpgradeContinue
()
async
{
final
int
code
=
await
processUtils
.
stream
(
<
String
>[
...
...
@@ -130,7 +159,7 @@ class UpgradeCommandRunner {
'--continue'
,
'--no-version-check'
,
],
workingDirectory:
Cache
.
flutterRoot
,
workingDirectory:
workingDirectory
,
allowReentrantFlutter:
true
,
environment:
Map
<
String
,
String
>.
of
(
globals
.
platform
.
environment
),
);
...
...
@@ -156,7 +185,7 @@ class UpgradeCommandRunner {
final
RunResult
result
=
await
processUtils
.
run
(
<
String
>[
'git'
,
'status'
,
'-s'
],
throwOnError:
true
,
workingDirectory:
Cache
.
flutterRoot
,
workingDirectory:
workingDirectory
,
);
return
result
.
stdout
.
trim
().
isNotEmpty
;
}
on
ProcessException
catch
(
error
)
{
...
...
@@ -179,13 +208,13 @@ class UpgradeCommandRunner {
await
processUtils
.
run
(
<
String
>[
'git'
,
'rev-parse'
,
'@{u}'
],
throwOnError:
true
,
workingDirectory:
Cache
.
flutterRoot
,
workingDirectory:
workingDirectory
,
);
}
catch
(
e
)
{
throwToolExit
(
'Unable to upgrade Flutter: no origin repository configured. '
"Run 'git remote add origin "
"https://github.com/flutter/flutter' in
$
{Cache.flutterRoot}
"
,
"https://github.com/flutter/flutter' in
$
workingDirectory
"
,
);
}
}
...
...
@@ -206,7 +235,7 @@ class UpgradeCommandRunner {
await
processUtils
.
run
(
<
String
>[
'git'
,
'reset'
,
'--hard'
,
tag
],
throwOnError:
true
,
workingDirectory:
Cache
.
flutterRoot
,
workingDirectory:
workingDirectory
,
);
}
on
ProcessException
catch
(
error
)
{
throwToolExit
(
...
...
@@ -223,7 +252,7 @@ class UpgradeCommandRunner {
/// If the user is on a deprecated channel, attempts to migrate them off of
/// it.
Future
<
void
>
upgradeChannel
(
FlutterVersion
flutterVersion
)
async
{
globals
.
printStatus
(
'Upgrading Flutter from
$
{Cache.flutterRoot}
...'
);
globals
.
printStatus
(
'Upgrading Flutter from
$
workingDirectory
...'
);
await
ChannelCommand
.
upgradeChannel
();
}
...
...
@@ -237,7 +266,7 @@ class UpgradeCommandRunner {
Future
<
bool
>
attemptFastForward
(
FlutterVersion
oldFlutterVersion
)
async
{
final
int
code
=
await
processUtils
.
stream
(
<
String
>[
'git'
,
'pull'
,
'--ff'
],
workingDirectory:
Cache
.
flutterRoot
,
workingDirectory:
workingDirectory
,
mapFunction:
(
String
line
)
=>
matchesGitLine
(
line
)
?
null
:
line
,
);
if
(
code
!=
0
)
{
...
...
@@ -247,7 +276,7 @@ class UpgradeCommandRunner {
// Check if the upgrade did anything.
bool
alreadyUpToDate
=
false
;
try
{
final
FlutterVersion
newFlutterVersion
=
FlutterVersion
();
final
FlutterVersion
newFlutterVersion
=
FlutterVersion
(
const
SystemClock
(),
workingDirectory
);
alreadyUpToDate
=
newFlutterVersion
.
channel
==
oldFlutterVersion
.
channel
&&
newFlutterVersion
.
frameworkRevision
==
oldFlutterVersion
.
frameworkRevision
;
}
catch
(
e
)
{
...
...
@@ -268,7 +297,7 @@ class UpgradeCommandRunner {
<
String
>[
globals
.
fs
.
path
.
join
(
'bin'
,
'flutter'
),
'--no-color'
,
'--no-version-check'
,
'precache'
,
],
workingDirectory:
Cache
.
flutterRoot
,
workingDirectory:
workingDirectory
,
allowReentrantFlutter:
true
,
environment:
Map
<
String
,
String
>.
of
(
globals
.
platform
.
environment
),
);
...
...
@@ -296,7 +325,7 @@ class UpgradeCommandRunner {
<
String
>[
globals
.
fs
.
path
.
join
(
'bin'
,
'flutter'
),
'--no-version-check'
,
'doctor'
,
],
workingDirectory:
Cache
.
flutterRoot
,
workingDirectory:
workingDirectory
,
allowReentrantFlutter:
true
,
);
}
...
...
packages/flutter_tools/lib/src/commands/version.dart
View file @
e2554a92
...
...
@@ -57,8 +57,29 @@ class VersionCommand extends FlutterCommand {
final
List
<
String
>
tags
=
await
getTags
();
if
(
argResults
.
rest
.
isEmpty
)
{
tags
.
forEach
(
globals
.
printStatus
);
return
const
FlutterCommandResult
(
ExitStatus
.
success
);
return
FlutterCommandResult
.
success
(
);
}
globals
.
printStatus
(
'╔══════════════════════════════════════════════════════════════════════════════╗
\n
'
'║ Warning: "flutter version" will leave the SDK in a detached HEAD state. ║
\n
'
'║ If you are using the command to return to a previously installed SDK version ║
\n
'
'║ consider using the "flutter downgrade" command instead. ║
\n
'
'╚══════════════════════════════════════════════════════════════════════════════╝
\n
'
,
emphasis:
true
,
);
if
(
globals
.
stdio
.
stdinHasTerminal
)
{
globals
.
terminal
.
usesTerminalUi
=
true
;
final
String
result
=
await
globals
.
terminal
.
promptForCharInput
(
<
String
>[
'y'
,
'n'
],
logger:
globals
.
logger
,
prompt:
'Are you sure you want to proceed?'
);
if
(
result
==
'n'
)
{
return
FlutterCommandResult
.
success
();
}
}
final
String
version
=
argResults
.
rest
[
0
].
replaceFirst
(
'v'
,
''
);
if
(!
tags
.
contains
(
'v
$version
'
))
{
globals
.
printError
(
'There is no version:
$version
'
);
...
...
packages/flutter_tools/lib/src/persistent_tool_state.dart
View file @
e2554a92
...
...
@@ -9,6 +9,7 @@ import 'base/config.dart';
import
'base/context.dart'
;
import
'base/file_system.dart'
;
import
'base/logger.dart'
;
import
'version.dart'
;
/// A class that represents global (non-project-specific) internal state that
/// must persist across tool invocations.
...
...
@@ -37,6 +38,14 @@ abstract class PersistentToolState {
///
/// May give null if the value has not been set.
bool
redisplayWelcomeMessage
;
/// Returns the last active version for a given [channel].
///
/// If there was no active prior version, returns `null` instead.
String
lastActiveVersion
(
Channel
channel
);
/// Update the last active version for a given [channel].
void
updateLastActiveVersion
(
String
fullGitHash
,
Channel
channel
);
}
class
_DefaultPersistentToolState
implements
PersistentToolState
{
...
...
@@ -63,6 +72,12 @@ class _DefaultPersistentToolState implements PersistentToolState {
static
const
String
_kFileName
=
'.flutter_tool_state'
;
static
const
String
_kRedisplayWelcomeMessage
=
'redisplay-welcome-message'
;
static
const
Map
<
Channel
,
String
>
_lastActiveVersionKeys
=
<
Channel
,
String
>{
Channel
.
master
:
'last-active-master-version'
,
Channel
.
dev
:
'last-active-dev-version'
,
Channel
.
beta
:
'last-active-beta-version'
,
Channel
.
stable
:
'last-active-stable-version'
};
final
Config
_config
;
...
...
@@ -71,8 +86,26 @@ class _DefaultPersistentToolState implements PersistentToolState {
return
_config
.
getValue
(
_kRedisplayWelcomeMessage
)
as
bool
;
}
@override
String
lastActiveVersion
(
Channel
channel
)
{
final
String
versionKey
=
_versionKeyFor
(
channel
);
assert
(
versionKey
!=
null
);
return
_config
.
getValue
(
versionKey
)
as
String
;
}
@override
set
redisplayWelcomeMessage
(
bool
value
)
{
_config
.
setValue
(
_kRedisplayWelcomeMessage
,
value
);
}
@override
void
updateLastActiveVersion
(
String
fullGitHash
,
Channel
channel
)
{
final
String
versionKey
=
_versionKeyFor
(
channel
);
assert
(
versionKey
!=
null
);
_config
.
setValue
(
versionKey
,
fullGitHash
);
}
String
_versionKeyFor
(
Channel
channel
)
{
return
_lastActiveVersionKeys
[
channel
];
}
}
packages/flutter_tools/lib/src/version.dart
View file @
e2554a92
...
...
@@ -15,14 +15,45 @@ import 'cache.dart';
import
'convert.dart'
;
import
'globals.dart'
as
globals
;
/// The names of each channel/branch in order of increasing stability.
enum
Channel
{
master
,
dev
,
beta
,
stable
,
}
/// Retrieve a human-readable name for a given [channel].
///
/// Requires [FlutterVersion.officialChannels] to be correctly ordered.
String
getNameForChannel
(
Channel
channel
)
{
return
FlutterVersion
.
officialChannels
.
elementAt
(
channel
.
index
);
}
/// Retrieve the [Channel] representation for a string [name].
///
/// Returns `null` if [name] is not in the list of official channels, according
/// to [FlutterVersion.officialChannels].
Channel
getChannelForName
(
String
name
)
{
if
(
FlutterVersion
.
officialChannels
.
contains
(
name
))
{
return
Channel
.
values
[
FlutterVersion
.
officialChannels
.
toList
().
indexOf
(
name
)];
}
return
null
;
}
class
FlutterVersion
{
FlutterVersion
([
this
.
_clock
=
const
SystemClock
()])
{
_frameworkRevision
=
_runGit
(
gitLog
(<
String
>[
'-n'
,
'1'
,
'--pretty=format:%H'
]).
join
(
' '
));
_gitTagVersion
=
GitTagVersion
.
determine
();
FlutterVersion
([
this
.
_clock
=
const
SystemClock
(),
this
.
_workingDirectory
])
{
_frameworkRevision
=
_runGit
(
gitLog
(<
String
>[
'-n'
,
'1'
,
'--pretty=format:%H'
]).
join
(
' '
),
processUtils
,
_workingDirectory
,
);
_gitTagVersion
=
GitTagVersion
.
determine
(
processUtils
,
_workingDirectory
);
_frameworkVersion
=
gitTagVersion
.
frameworkVersionFor
(
_frameworkRevision
);
}
final
SystemClock
_clock
;
final
String
_workingDirectory
;
String
_repositoryUrl
;
String
get
repositoryUrl
{
...
...
@@ -60,11 +91,19 @@ class FlutterVersion {
/// `master`, `dev`, `beta`, `stable`; or old ones, like `alpha`, `hackathon`, ...
String
get
channel
{
if
(
_channel
==
null
)
{
final
String
channel
=
_runGit
(
'git rev-parse --abbrev-ref --symbolic @{u}'
);
final
String
channel
=
_runGit
(
'git rev-parse --abbrev-ref --symbolic @{u}'
,
processUtils
,
_workingDirectory
,
);
final
int
slash
=
channel
.
indexOf
(
'/'
);
if
(
slash
!=
-
1
)
{
final
String
remote
=
channel
.
substring
(
0
,
slash
);
_repositoryUrl
=
_runGit
(
'git ls-remote --get-url
$remote
'
);
_repositoryUrl
=
_runGit
(
'git ls-remote --get-url
$remote
'
,
processUtils
,
_workingDirectory
,
);
_channel
=
channel
.
substring
(
slash
+
1
);
}
else
if
(
channel
.
isEmpty
)
{
_channel
=
'unknown'
;
...
...
@@ -88,7 +127,11 @@ class FlutterVersion {
String
_frameworkAge
;
String
get
frameworkAge
{
return
_frameworkAge
??=
_runGit
(
gitLog
(<
String
>[
'-n'
,
'1'
,
'--pretty=format:%ar'
]).
join
(
' '
));
return
_frameworkAge
??=
_runGit
(
gitLog
(<
String
>[
'-n'
,
'1'
,
'--pretty=format:%ar'
]).
join
(
' '
),
processUtils
,
_workingDirectory
,
);
}
String
_frameworkVersion
;
...
...
@@ -226,7 +269,7 @@ class FlutterVersion {
/// the branch name will be returned as `'[user-branch]'`.
String
getBranchName
({
bool
redactUnknownBranches
=
false
})
{
_branch
??=
()
{
final
String
branch
=
_runGit
(
'git rev-parse --abbrev-ref HEAD'
);
final
String
branch
=
_runGit
(
'git rev-parse --abbrev-ref HEAD'
,
processUtils
);
return
branch
==
'HEAD'
?
channel
:
branch
;
}();
if
(
redactUnknownBranches
||
_branch
.
isEmpty
)
{
...
...
@@ -599,10 +642,10 @@ String _runSync(List<String> command, { bool lenient = true }) {
return
''
;
}
String
_runGit
(
String
command
)
{
String
_runGit
(
String
command
,
ProcessUtils
processUtils
,
[
String
workingDirectory
]
)
{
return
processUtils
.
runSync
(
command
.
split
(
' '
),
workingDirectory:
Cache
.
flutterRoot
,
workingDirectory:
workingDirectory
??
Cache
.
flutterRoot
,
).
stdout
.
trim
();
}
...
...
@@ -658,8 +701,8 @@ class GitTagVersion {
/// The git hash (or an abbreviation thereof) for this commit.
final
String
hash
;
static
GitTagVersion
determine
()
{
return
parse
(
_runGit
(
'git describe --match v*.*.* --first-parent --long --tags'
));
static
GitTagVersion
determine
(
ProcessUtils
processUtils
,
[
String
workingDirectory
]
)
{
return
parse
(
_runGit
(
'git describe --match v*.*.* --first-parent --long --tags'
,
processUtils
,
workingDirectory
));
}
static
GitTagVersion
parse
(
String
version
)
{
...
...
packages/flutter_tools/test/commands.shard/hermetic/downgrade_test.dart
0 → 100644
View file @
e2554a92
// Copyright 2014 The Flutter 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:file/file.dart'
;
import
'package:file/memory.dart'
;
import
'package:flutter_tools/src/base/io.dart'
;
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/base/terminal.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/commands/downgrade.dart'
;
import
'package:flutter_tools/src/persistent_tool_state.dart'
;
import
'package:flutter_tools/src/version.dart'
;
import
'package:mockito/mockito.dart'
;
import
'../../src/common.dart'
;
import
'../../src/context.dart'
;
import
'../../src/mocks.dart'
;
void
main
(
)
{
FileSystem
fileSystem
;
BufferLogger
bufferLogger
;
AnsiTerminal
terminal
;
ProcessManager
processManager
;
MockStdio
mockStdio
;
FlutterVersion
flutterVersion
;
setUpAll
(()
{
Cache
.
disableLocking
();
});
tearDownAll
(()
{
Cache
.
enableLocking
();
});
setUp
(()
{
flutterVersion
=
MockFlutterVersion
();
mockStdio
=
MockStdio
();
processManager
=
FakeProcessManager
.
any
();
terminal
=
MockTerminal
();
fileSystem
=
MemoryFileSystem
.
test
();
bufferLogger
=
BufferLogger
(
terminal:
terminal
,
outputPreferences:
OutputPreferences
.
test
());
});
testUsingContext
(
'Downgrade exits on unknown channel'
,
()
async
{
fileSystem
.
currentDirectory
.
childFile
(
'.flutter_tool_state'
)
.
writeAsStringSync
(
'{"last-active-master-version":"invalid"}'
);
final
DowngradeCommand
command
=
DowngradeCommand
(
persistentToolState:
PersistentToolState
.
test
(
directory:
fileSystem
.
currentDirectory
,
logger:
bufferLogger
),
processManager:
processManager
,
terminal:
terminal
,
stdio:
mockStdio
,
flutterVersion:
flutterVersion
,
logger:
bufferLogger
,
);
applyMocksToCommand
(
command
);
expect
(
createTestCommandRunner
(
command
).
run
(
const
<
String
>[
'downgrade'
]),
throwsToolExit
(
message:
'Flutter is not currently on a known channel.'
));
});
testUsingContext
(
'Downgrade exits on no recorded version'
,
()
async
{
when
(
flutterVersion
.
channel
).
thenReturn
(
'dev'
);
fileSystem
.
currentDirectory
.
childFile
(
'.flutter_tool_state'
)
.
writeAsStringSync
(
'{"last-active-master-version":"abcd"}'
);
final
DowngradeCommand
command
=
DowngradeCommand
(
persistentToolState:
PersistentToolState
.
test
(
directory:
fileSystem
.
currentDirectory
,
logger:
bufferLogger
),
processManager:
FakeProcessManager
.
list
(<
FakeCommand
>[
const
FakeCommand
(
command:
<
String
>[
'git'
,
'describe'
,
'--tags'
,
'abcd'
],
exitCode:
0
,
stdout:
'v1.2.3'
)
]),
terminal:
terminal
,
stdio:
mockStdio
,
flutterVersion:
flutterVersion
,
logger:
bufferLogger
,
);
applyMocksToCommand
(
command
);
expect
(
createTestCommandRunner
(
command
).
run
(
const
<
String
>[
'downgrade'
]),
throwsToolExit
(
message:
'There is no previously recorded version for channel "dev".
\n
'
'Channel "master" was previously on: v1.2.3.'
),
);
});
testUsingContext
(
'Downgrade exits on unknown recorded version'
,
()
async
{
when
(
flutterVersion
.
channel
).
thenReturn
(
'master'
);
fileSystem
.
currentDirectory
.
childFile
(
'.flutter_tool_state'
)
.
writeAsStringSync
(
'{"last-active-master-version":"invalid"}'
);
final
DowngradeCommand
command
=
DowngradeCommand
(
persistentToolState:
PersistentToolState
.
test
(
directory:
fileSystem
.
currentDirectory
,
logger:
bufferLogger
),
processManager:
FakeProcessManager
.
list
(<
FakeCommand
>[
const
FakeCommand
(
command:
<
String
>[
'git'
,
'describe'
,
'--tags'
,
'invalid'
],
exitCode:
1
,
)
]),
terminal:
terminal
,
stdio:
mockStdio
,
flutterVersion:
flutterVersion
,
logger:
bufferLogger
,
);
applyMocksToCommand
(
command
);
expect
(
createTestCommandRunner
(
command
).
run
(
const
<
String
>[
'downgrade'
]),
throwsToolExit
(
message:
'Failed to parse version for downgrade'
));
});
testUsingContext
(
'Downgrade prompts for user input when terminal is attached - y'
,
()
async
{
when
(
flutterVersion
.
channel
).
thenReturn
(
'master'
);
when
(
mockStdio
.
hasTerminal
).
thenReturn
(
true
);
fileSystem
.
currentDirectory
.
childFile
(
'.flutter_tool_state'
)
.
writeAsStringSync
(
'{"last-active-master-version":"g6b00b5e88"}'
);
final
DowngradeCommand
command
=
DowngradeCommand
(
persistentToolState:
PersistentToolState
.
test
(
directory:
fileSystem
.
currentDirectory
,
logger:
bufferLogger
),
processManager:
processManager
,
terminal:
terminal
,
stdio:
mockStdio
,
flutterVersion:
flutterVersion
,
logger:
bufferLogger
,
);
applyMocksToCommand
(
command
);
when
(
terminal
.
promptForCharInput
(
const
<
String
>[
'y'
,
'n'
],
prompt:
anyNamed
(
'prompt'
),
logger:
anyNamed
(
'logger'
),
)).
thenAnswer
((
Invocation
invocation
)
async
=>
'y'
);
await
createTestCommandRunner
(
command
).
run
(
const
<
String
>[
'downgrade'
]);
verify
(
terminal
.
promptForCharInput
(
const
<
String
>[
'y'
,
'n'
],
prompt:
anyNamed
(
'prompt'
),
logger:
anyNamed
(
'logger'
),
)).
called
(
1
);
expect
(
bufferLogger
.
statusText
,
contains
(
'Success'
));
});
testUsingContext
(
'Downgrade prompts for user input when terminal is attached - n'
,
()
async
{
when
(
flutterVersion
.
channel
).
thenReturn
(
'master'
);
when
(
mockStdio
.
hasTerminal
).
thenReturn
(
true
);
fileSystem
.
currentDirectory
.
childFile
(
'.flutter_tool_state'
)
.
writeAsStringSync
(
'{"last-active-master-version":"g6b00b5e88"}'
);
final
DowngradeCommand
command
=
DowngradeCommand
(
persistentToolState:
PersistentToolState
.
test
(
directory:
fileSystem
.
currentDirectory
,
logger:
bufferLogger
),
processManager:
processManager
,
terminal:
terminal
,
stdio:
mockStdio
,
flutterVersion:
flutterVersion
,
logger:
bufferLogger
,
);
applyMocksToCommand
(
command
);
when
(
terminal
.
promptForCharInput
(
const
<
String
>[
'y'
,
'n'
],
prompt:
anyNamed
(
'prompt'
),
logger:
anyNamed
(
'logger'
),
)).
thenAnswer
((
Invocation
invocation
)
async
=>
'n'
);
await
createTestCommandRunner
(
command
).
run
(
const
<
String
>[
'downgrade'
]);
verify
(
terminal
.
promptForCharInput
(
const
<
String
>[
'y'
,
'n'
],
prompt:
anyNamed
(
'prompt'
),
logger:
anyNamed
(
'logger'
),
)).
called
(
1
);
expect
(
bufferLogger
.
statusText
,
isNot
(
contains
(
'Success'
)));
});
testUsingContext
(
'Downgrade does not prompt when there is no terminal'
,
()
async
{
when
(
flutterVersion
.
channel
).
thenReturn
(
'master'
);
when
(
mockStdio
.
hasTerminal
).
thenReturn
(
false
);
fileSystem
.
currentDirectory
.
childFile
(
'.flutter_tool_state'
)
.
writeAsStringSync
(
'{"last-active-master-version":"g6b00b5e88"}'
);
final
DowngradeCommand
command
=
DowngradeCommand
(
persistentToolState:
PersistentToolState
.
test
(
directory:
fileSystem
.
currentDirectory
,
logger:
bufferLogger
,
),
processManager:
processManager
,
terminal:
terminal
,
stdio:
mockStdio
,
flutterVersion:
flutterVersion
,
logger:
bufferLogger
,
);
applyMocksToCommand
(
command
);
await
createTestCommandRunner
(
command
).
run
(
const
<
String
>[
'downgrade'
]);
verifyNever
(
terminal
.
promptForCharInput
(
const
<
String
>[
'y'
,
'n'
],
prompt:
anyNamed
(
'prompt'
),
logger:
anyNamed
(
'logger'
),
));
expect
(
bufferLogger
.
statusText
,
contains
(
'Success'
));
});
testUsingContext
(
'Downgrade performs correct git commands'
,
()
async
{
when
(
flutterVersion
.
channel
).
thenReturn
(
'master'
);
when
(
mockStdio
.
hasTerminal
).
thenReturn
(
false
);
fileSystem
.
currentDirectory
.
childFile
(
'.flutter_tool_state'
)
.
writeAsStringSync
(
'{"last-active-master-version":"g6b00b5e88"}'
);
final
DowngradeCommand
command
=
DowngradeCommand
(
persistentToolState:
PersistentToolState
.
test
(
directory:
fileSystem
.
currentDirectory
,
logger:
bufferLogger
,
),
processManager:
FakeProcessManager
.
list
(<
FakeCommand
>[
const
FakeCommand
(
command:
<
String
>[
'git'
,
'describe'
,
'--tags'
,
'g6b00b5e88'
],
stdout:
'v1.2.3'
,
),
const
FakeCommand
(
command:
<
String
>[
'git'
,
'reset'
,
'--hard'
,
'g6b00b5e88'
],
),
const
FakeCommand
(
command:
<
String
>[
'git'
,
'checkout'
,
'master'
,
'--'
]
),
]),
terminal:
terminal
,
stdio:
mockStdio
,
flutterVersion:
flutterVersion
,
logger:
bufferLogger
,
);
applyMocksToCommand
(
command
);
await
createTestCommandRunner
(
command
).
run
(
const
<
String
>[
'downgrade'
]);
expect
(
bufferLogger
.
statusText
,
contains
(
'Success'
));
});
}
class
MockTerminal
extends
Mock
implements
AnsiTerminal
{}
class
MockStdio
extends
Mock
implements
Stdio
{}
packages/flutter_tools/test/commands.shard/hermetic/version_test.dart
View file @
e2554a92
...
...
@@ -8,11 +8,13 @@ import 'dart:io';
import
'package:flutter_tools/src/base/common.dart'
;
import
'package:flutter_tools/src/base/io.dart'
;
import
'package:flutter_tools/src/base/terminal.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/commands/version.dart'
;
import
'package:flutter_tools/src/version.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:process/process.dart'
;
import
'package:flutter_tools/src/globals.dart'
as
globals
;
import
'../../src/common.dart'
;
import
'../../src/context.dart'
;
...
...
@@ -20,10 +22,18 @@ import '../../src/mocks.dart' show MockProcess;
void
main
(
)
{
group
(
'version'
,
()
{
MockStdio
mockStdio
;
setUpAll
(()
{
Cache
.
disableLocking
();
});
setUp
(()
{
mockStdio
=
MockStdio
();
when
(
mockStdio
.
stdinHasTerminal
).
thenReturn
(
false
);
when
(
mockStdio
.
hasTerminal
).
thenReturn
(
false
);
});
testUsingContext
(
'version ls'
,
()
async
{
final
VersionCommand
command
=
VersionCommand
();
await
createTestCommandRunner
(
command
).
run
(<
String
>[
...
...
@@ -33,11 +43,18 @@ void main() {
expect
(
testLogger
.
statusText
,
equals
(
'v10.0.0
\r\n
v20.0.0
\n
'
));
},
overrides:
<
Type
,
Generator
>{
ProcessManager:
()
=>
MockProcessManager
(),
Stdio:
()
=>
mockStdio
,
});
testUsingContext
(
'version switch'
,
()
async
{
testUsingContext
(
'version switch prompt is accepted'
,
()
async
{
when
(
mockStdio
.
stdinHasTerminal
).
thenReturn
(
true
);
const
String
version
=
'10.0.0'
;
final
VersionCommand
command
=
VersionCommand
();
when
(
globals
.
terminal
.
promptForCharInput
(<
String
>[
'y'
,
'n'
],
logger:
anyNamed
(
'logger'
),
prompt:
'Are you sure you want to proceed?'
)
).
thenAnswer
((
Invocation
invocation
)
async
=>
'y'
);
await
createTestCommandRunner
(
command
).
run
(<
String
>[
'version'
,
'--no-pub'
,
...
...
@@ -46,6 +63,29 @@ void main() {
expect
(
testLogger
.
statusText
,
contains
(
'Switching Flutter to version
$version
'
));
},
overrides:
<
Type
,
Generator
>{
ProcessManager:
()
=>
MockProcessManager
(),
Stdio:
()
=>
mockStdio
,
AnsiTerminal:
()
=>
MockTerminal
(),
});
testUsingContext
(
'version switch prompt is declined'
,
()
async
{
when
(
mockStdio
.
stdinHasTerminal
).
thenReturn
(
true
);
const
String
version
=
'10.0.0'
;
final
VersionCommand
command
=
VersionCommand
();
when
(
globals
.
terminal
.
promptForCharInput
(<
String
>[
'y'
,
'n'
],
logger:
anyNamed
(
'logger'
),
prompt:
'Are you sure you want to proceed?'
)
).
thenAnswer
((
Invocation
invocation
)
async
=>
'n'
);
await
createTestCommandRunner
(
command
).
run
(<
String
>[
'version'
,
'--no-pub'
,
version
,
]);
expect
(
testLogger
.
statusText
,
isNot
(
contains
(
'Switching Flutter to version
$version
'
)));
},
overrides:
<
Type
,
Generator
>{
ProcessManager:
()
=>
MockProcessManager
(),
Stdio:
()
=>
mockStdio
,
AnsiTerminal:
()
=>
MockTerminal
(),
});
testUsingContext
(
'version switch, latest commit query fails'
,
()
async
{
...
...
@@ -59,6 +99,7 @@ void main() {
expect
(
testLogger
.
errorText
,
contains
(
'git failed'
));
},
overrides:
<
Type
,
Generator
>{
ProcessManager:
()
=>
MockProcessManager
(
latestCommitFails:
true
),
Stdio:
()
=>
mockStdio
,
});
testUsingContext
(
'latest commit is parsable when query fails'
,
()
{
...
...
@@ -69,6 +110,7 @@ void main() {
);
},
overrides:
<
Type
,
Generator
>{
ProcessManager:
()
=>
MockProcessManager
(
latestCommitFails:
true
),
Stdio:
()
=>
mockStdio
,
});
testUsingContext
(
'switch to not supported version without force'
,
()
async
{
...
...
@@ -82,6 +124,7 @@ void main() {
expect
(
testLogger
.
errorText
,
contains
(
'Version command is not supported in'
));
},
overrides:
<
Type
,
Generator
>{
ProcessManager:
()
=>
MockProcessManager
(),
Stdio:
()
=>
mockStdio
,
});
testUsingContext
(
'switch to not supported version with force'
,
()
async
{
...
...
@@ -96,6 +139,7 @@ void main() {
expect
(
testLogger
.
statusText
,
contains
(
'Switching Flutter to version
$version
with force'
));
},
overrides:
<
Type
,
Generator
>{
ProcessManager:
()
=>
MockProcessManager
(),
Stdio:
()
=>
mockStdio
,
});
testUsingContext
(
'tool exit on confusing version'
,
()
async
{
...
...
@@ -111,6 +155,7 @@ void main() {
);
},
overrides:
<
Type
,
Generator
>{
ProcessManager:
()
=>
MockProcessManager
(),
Stdio:
()
=>
mockStdio
,
});
testUsingContext
(
"exit tool if can't get the tags"
,
()
async
{
...
...
@@ -123,10 +168,13 @@ void main() {
}
},
overrides:
<
Type
,
Generator
>{
ProcessManager:
()
=>
MockProcessManager
(
failGitTag:
true
),
Stdio:
()
=>
mockStdio
,
});
});
}
class
MockTerminal
extends
Mock
implements
AnsiTerminal
{}
class
MockStdio
extends
Mock
implements
Stdio
{}
class
MockProcessManager
extends
Mock
implements
ProcessManager
{
MockProcessManager
({
this
.
failGitTag
=
false
,
...
...
packages/flutter_tools/test/commands.shard/permeable/upgrade_test.dart
View file @
e2554a92
...
...
@@ -57,10 +57,11 @@ void main() {
testUsingContext
(
'throws on unknown tag, official branch, noforce'
,
()
async
{
final
Future
<
FlutterCommandResult
>
result
=
fakeCommandRunner
.
runCommand
(
false
,
false
,
const
GitTagVersion
.
unknown
(),
flutterVersion
,
force:
false
,
continueFlow:
false
,
testFlow:
false
,
gitTagVersion:
const
GitTagVersion
.
unknown
(),
flutterVersion:
flutterVersion
,
);
expect
(
result
,
throwsToolExit
());
},
overrides:
<
Type
,
Generator
>{
...
...
@@ -69,10 +70,11 @@ void main() {
testUsingContext
(
'does not throw on unknown tag, official branch, force'
,
()
async
{
final
Future
<
FlutterCommandResult
>
result
=
fakeCommandRunner
.
runCommand
(
true
,
false
,
const
GitTagVersion
.
unknown
(),
flutterVersion
,
force:
true
,
continueFlow:
false
,
testFlow:
false
,
gitTagVersion:
const
GitTagVersion
.
unknown
(),
flutterVersion:
flutterVersion
,
);
expect
(
await
result
,
FlutterCommandResult
.
success
());
},
overrides:
<
Type
,
Generator
>{
...
...
@@ -83,10 +85,11 @@ void main() {
testUsingContext
(
'throws tool exit with uncommitted changes'
,
()
async
{
fakeCommandRunner
.
willHaveUncomittedChanges
=
true
;
final
Future
<
FlutterCommandResult
>
result
=
fakeCommandRunner
.
runCommand
(
false
,
false
,
gitTagVersion
,
flutterVersion
,
force:
false
,
continueFlow:
false
,
testFlow:
false
,
gitTagVersion:
gitTagVersion
,
flutterVersion:
flutterVersion
,
);
expect
(
result
,
throwsToolExit
());
},
overrides:
<
Type
,
Generator
>{
...
...
@@ -97,10 +100,11 @@ void main() {
fakeCommandRunner
.
willHaveUncomittedChanges
=
true
;
final
Future
<
FlutterCommandResult
>
result
=
fakeCommandRunner
.
runCommand
(
true
,
false
,
gitTagVersion
,
flutterVersion
,
force:
true
,
continueFlow:
false
,
testFlow:
false
,
gitTagVersion:
gitTagVersion
,
flutterVersion:
flutterVersion
,
);
expect
(
await
result
,
FlutterCommandResult
.
success
());
},
overrides:
<
Type
,
Generator
>{
...
...
@@ -110,10 +114,11 @@ void main() {
testUsingContext
(
"Doesn't throw on known tag, dev branch, no force"
,
()
async
{
final
Future
<
FlutterCommandResult
>
result
=
fakeCommandRunner
.
runCommand
(
false
,
false
,
gitTagVersion
,
flutterVersion
,
force:
false
,
continueFlow:
false
,
testFlow:
false
,
gitTagVersion:
gitTagVersion
,
flutterVersion:
flutterVersion
,
);
expect
(
await
result
,
FlutterCommandResult
.
success
());
},
overrides:
<
Type
,
Generator
>{
...
...
@@ -124,10 +129,11 @@ void main() {
testUsingContext
(
"Doesn't continue on known tag, dev branch, no force, already up-to-date"
,
()
async
{
fakeCommandRunner
.
alreadyUpToDate
=
true
;
final
Future
<
FlutterCommandResult
>
result
=
fakeCommandRunner
.
runCommand
(
false
,
false
,
gitTagVersion
,
flutterVersion
,
force:
false
,
continueFlow:
false
,
testFlow:
false
,
gitTagVersion:
gitTagVersion
,
flutterVersion:
flutterVersion
,
);
expect
(
await
result
,
FlutterCommandResult
.
success
());
verifyNever
(
globals
.
processManager
.
start
(
...
...
packages/flutter_tools/test/general.shard/persistent_tool_state_test.dart
View file @
e2554a92
...
...
@@ -6,6 +6,7 @@ import 'package:file/memory.dart';
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/persistent_tool_state.dart'
;
import
'package:flutter_tools/src/version.dart'
;
import
'package:mockito/mockito.dart'
;
import
'../src/common.dart'
;
...
...
@@ -14,8 +15,8 @@ class MockLogger extends Mock implements Logger {}
void
main
(
)
{
testWithoutContext
(
'state can be set and persists'
,
()
{
final
MemoryFileSystem
f
s
=
MemoryFileSystem
();
final
Directory
directory
=
f
s
.
directory
(
'state_dir'
);
final
MemoryFileSystem
f
ileSystem
=
MemoryFileSystem
();
final
Directory
directory
=
f
ileSystem
.
directory
(
'state_dir'
);
directory
.
createSync
();
final
File
stateFile
=
directory
.
childFile
(
'.flutter_tool_state'
);
final
PersistentToolState
state1
=
PersistentToolState
.
test
(
...
...
@@ -35,4 +36,28 @@ void main() {
);
expect
(
state2
.
redisplayWelcomeMessage
,
false
);
});
testWithoutContext
(
'channel versions can be cached and stored'
,
()
{
final
MemoryFileSystem
fileSystem
=
MemoryFileSystem
();
final
Directory
directory
=
fileSystem
.
directory
(
'state_dir'
)..
createSync
();
final
PersistentToolState
state1
=
PersistentToolState
.
test
(
directory:
directory
,
logger:
MockLogger
(),
);
state1
.
updateLastActiveVersion
(
'abc'
,
Channel
.
master
);
state1
.
updateLastActiveVersion
(
'def'
,
Channel
.
dev
);
state1
.
updateLastActiveVersion
(
'ghi'
,
Channel
.
beta
);
state1
.
updateLastActiveVersion
(
'jkl'
,
Channel
.
stable
);
final
PersistentToolState
state2
=
PersistentToolState
.
test
(
directory:
directory
,
logger:
MockLogger
(),
);
expect
(
state2
.
lastActiveVersion
(
Channel
.
master
),
'abc'
);
expect
(
state2
.
lastActiveVersion
(
Channel
.
dev
),
'def'
);
expect
(
state2
.
lastActiveVersion
(
Channel
.
beta
),
'ghi'
);
expect
(
state2
.
lastActiveVersion
(
Channel
.
stable
),
'jkl'
);
});
}
packages/flutter_tools/test/integration.shard/downgrade_upgrade_integration_test.dart
0 → 100644
View file @
e2554a92
// Copyright 2014 The Flutter 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:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/io.dart'
;
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/base/process.dart'
;
import
'package:flutter_tools/src/base/terminal.dart'
;
import
'package:platform/platform.dart'
;
import
'package:process/process.dart'
;
import
'../src/common.dart'
;
const
String
_kInitialVersion
=
'v1.9.1+hotfix.6'
;
const
String
_kBranch
=
'stable'
;
const
FileSystem
fileSystem
=
LocalFileSystem
();
const
ProcessManager
processManager
=
LocalProcessManager
();
final
ProcessUtils
processUtils
=
ProcessUtils
(
processManager:
processManager
,
logger:
StdoutLogger
(
terminal:
AnsiTerminal
(
platform:
const
LocalPlatform
(),
stdio:
const
Stdio
(),
),
stdio:
const
Stdio
(),
outputPreferences:
OutputPreferences
.
test
(
wrapText:
true
),
timeoutConfiguration:
const
TimeoutConfiguration
(),
));
final
String
flutterBin
=
fileSystem
.
path
.
join
(
getFlutterRoot
(),
'bin'
,
'flutter'
);
/// A test for flutter upgrade & downgrade that checks out a parallel flutter repo.
void
main
(
)
{
Directory
parentDirectory
;
setUp
(()
{
parentDirectory
=
fileSystem
.
systemTempDirectory
.
createTempSync
(
'flutter_tools.'
);
parentDirectory
.
createSync
(
recursive:
true
);
});
tearDown
(()
{
try
{
parentDirectory
.
deleteSync
(
recursive:
true
);
}
on
FileSystemException
{
print
(
'Failed to delete test directory'
);
}
});
test
(
'Can upgrade and downgrade a Flutter checkout'
,
()
async
{
final
Directory
testDirectory
=
parentDirectory
.
childDirectory
(
'flutter'
);
testDirectory
.
createSync
(
recursive:
true
);
// Enable longpaths for windows integration test.
await
processManager
.
run
(<
String
>[
'git'
,
'config'
,
'--system'
,
'core.longpaths'
,
'true'
,
]);
// Step 1. Clone the dev branch of flutter into the test directory.
await
processUtils
.
stream
(<
String
>[
'git'
,
'clone'
,
'https://github.com/flutter/flutter.git'
,
],
workingDirectory:
parentDirectory
.
path
,
trace:
true
);
// Step 2. Switch to the dev branch.
await
processUtils
.
stream
(<
String
>[
'git'
,
'checkout'
,
'--track'
,
'-b'
,
_kBranch
,
'origin/
$_kBranch
'
,
],
workingDirectory:
testDirectory
.
path
,
trace:
true
);
// Step 3. Revert to a prior version.
await
processUtils
.
stream
(<
String
>[
'git'
,
'reset'
,
'--hard'
,
_kInitialVersion
,
],
workingDirectory:
testDirectory
.
path
,
trace:
true
);
// Step 4. Upgrade to the newest dev. This should update the persistent
// tool state with the sha for v1.14.3
await
processUtils
.
stream
(<
String
>[
flutterBin
,
'upgrade'
,
'--working-directory=
${testDirectory.path}
'
],
workingDirectory:
testDirectory
.
path
,
trace:
true
);
// Step 5. Verify that the version is different.
final
RunResult
versionResult
=
await
processUtils
.
run
(<
String
>[
'git'
,
'describe'
,
'--match'
,
'v*.*.*'
,
'--first-parent'
,
'--long'
,
'--tags'
,
],
workingDirectory:
testDirectory
.
path
);
expect
(
versionResult
.
stdout
,
isNot
(
contains
(
_kInitialVersion
)));
// Step 6. Downgrade back to initial version.
await
processUtils
.
stream
(<
String
>[
flutterBin
,
'downgrade'
,
'--no-prompt'
,
'--working-directory=
${testDirectory.path}
'
],
workingDirectory:
testDirectory
.
path
,
trace:
true
);
// Step 7. Verify downgraded version matches original version.
final
RunResult
oldVersionResult
=
await
processUtils
.
run
(<
String
>[
'git'
,
'describe'
,
'--match'
,
'v*.*.*'
,
'--first-parent'
,
'--long'
,
'--tags'
,
],
workingDirectory:
testDirectory
.
path
);
expect
(
oldVersionResult
.
stdout
,
contains
(
_kInitialVersion
));
});
}
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