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
beaf7e28
Unverified
Commit
beaf7e28
authored
Mar 25, 2019
by
Jonah Williams
Committed by
GitHub
Mar 25, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update upgrade to reset off of hotfix branches (#29786)
parent
377dfbd9
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
211 additions
and
20 deletions
+211
-20
upgrade.dart
packages/flutter_tools/lib/src/commands/upgrade.dart
+108
-18
upgrade_test.dart
packages/flutter_tools/test/commands/upgrade_test.dart
+103
-2
No files found.
packages/flutter_tools/lib/src/commands/upgrade.dart
View file @
beaf7e28
...
...
@@ -18,6 +18,15 @@ import '../version.dart';
import
'channel.dart'
;
class
UpgradeCommand
extends
FlutterCommand
{
UpgradeCommand
()
{
argParser
.
addFlag
(
'force'
,
abbr:
'f'
,
help:
'force upgrade the flutter branch, potentially discarding local changes.'
,
negatable:
false
,
);
}
@override
final
String
name
=
'upgrade'
;
...
...
@@ -29,64 +38,146 @@ class UpgradeCommand extends FlutterCommand {
@override
Future
<
FlutterCommandResult
>
runCommand
()
async
{
final
UpgradeCommandRunner
upgradeCommandRunner
=
UpgradeCommandRunner
();
await
upgradeCommandRunner
.
runCommand
(
argResults
[
'force'
],
GitTagVersion
.
determine
(),
FlutterVersion
.
instance
);
return
null
;
}
}
@visibleForTesting
class
UpgradeCommandRunner
{
Future
<
FlutterCommandResult
>
runCommand
(
bool
force
,
GitTagVersion
gitTagVersion
,
FlutterVersion
flutterVersion
)
async
{
await
verifyUpstreamConfigured
();
if
(!
force
&&
gitTagVersion
==
const
GitTagVersion
.
unknown
())
{
// If the commit is a recognized branch and not master,
// explain that we are avoiding potential damage.
if
(
flutterVersion
.
channel
!=
'master'
&&
FlutterVersion
.
officialChannels
.
contains
(
flutterVersion
.
channel
))
{
throwToolExit
(
'Unknown flutter tag. Abandoning upgrade to avoid destroying local '
'changes. It is recommended to use git directly if not working on '
'an official channel.'
);
// Otherwise explain that local changes can be lost.
}
else
{
throwToolExit
(
'Unknown flutter tag. Abandoning upgrade to avoid destroying local '
'changes. If it is okay to remove local changes, then re-run this '
'command with --force.'
);
}
}
await
resetChanges
(
gitTagVersion
);
await
upgradeChannel
(
flutterVersion
);
await
attemptFastForward
();
await
precacheArtifacts
();
await
updatePackages
(
flutterVersion
);
await
runDoctor
();
return
null
;
}
/// Check if there is an upstream repository configured.
///
/// Exits tool if there is no upstream.
Future
<
void
>
verifyUpstreamConfigured
()
async
{
try
{
await
runCheckedAsync
(<
String
>[
'git'
,
'rev-parse'
,
'@{u}'
,
],
workingDirectory:
Cache
.
flutterRoot
);
}
catch
(
e
)
{
throwToolExit
(
'Unable to upgrade Flutter: no upstream repository configured.'
);
throwToolExit
(
'Unable to upgrade Flutter: no origin repository configured. '
'Run
\'
git remote add origin '
'https://github.com/flutter/flutter
\'
in
${Cache.flutterRoot}
'
,
);
}
}
final
FlutterVersion
flutterVersion
=
FlutterVersion
.
instance
;
/// Attempts to reset to the last known tag or branch. This should restore the
/// history to something that is compatible with the regular upgrade
/// process.
Future
<
void
>
resetChanges
(
GitTagVersion
gitTagVersion
)
async
{
// We only got here by using --force.
String
tag
;
if
(
gitTagVersion
==
const
GitTagVersion
.
unknown
())
{
tag
=
'v0.0.0'
;
}
else
{
tag
=
'v
${gitTagVersion.x}
.
${gitTagVersion.y}
.
${gitTagVersion.z}
'
;
}
final
RunResult
runResult
=
await
runCheckedAsync
(<
String
>[
'git'
,
'reset'
,
'--hard'
,
tag
,
],
workingDirectory:
Cache
.
flutterRoot
);
if
(
runResult
.
exitCode
!=
0
)
{
throwToolExit
(
'Failed to restore branch from hotfix.'
);
}
}
/// Attempts to upgrade the channel.
///
/// If the user is on a deprecated channel, attempts to migrate them off of
/// it.
Future
<
void
>
upgradeChannel
(
FlutterVersion
flutterVersion
)
async
{
printStatus
(
'Upgrading Flutter from
${Cache.flutterRoot}
...'
);
await
ChannelCommand
.
upgradeChannel
();
}
int
code
=
await
runCommandAndStreamOutput
(
<
String
>[
'git'
,
'pull'
,
'--ff-only'
],
/// Attempts to rebase the upstream onto the local branch.
///
/// If there haven't been any hot fixes or local changes, this is equivalent
/// to a fast-forward.
Future
<
void
>
attemptFastForward
()
async
{
final
int
code
=
await
runCommandAndStreamOutput
(
<
String
>[
'git'
,
'pull'
,
'--ff'
],
workingDirectory:
Cache
.
flutterRoot
,
mapFunction:
(
String
line
)
=>
matchesGitLine
(
line
)
?
null
:
line
,
);
if
(
code
!=
0
)
if
(
code
!=
0
)
{
throwToolExit
(
null
,
exitCode:
code
);
}
}
// Check for and download any engine and pkg/ updates.
// We run the 'flutter' shell script re-entrantly here
// so that it will download the updated Dart and so forth
// if necessary.
/// Update the engine repository and precache all artifacts.
///
/// Check for and download any engine and pkg/ updates. We run the 'flutter'
/// shell script re-entrantly here so that it will download the updated
/// Dart and so forth if necessary.
Future
<
void
>
precacheArtifacts
()
async
{
printStatus
(
''
);
printStatus
(
'Upgrading engine...'
);
code
=
await
runCommandAndStreamOutput
(
final
int
code
=
await
runCommandAndStreamOutput
(
<
String
>[
fs
.
path
.
join
(
'bin'
,
'flutter'
),
'--no-color'
,
'--no-version-check'
,
'precache'
,
],
workingDirectory:
Cache
.
flutterRoot
,
allowReentrantFlutter:
true
,
);
if
(
code
!=
0
)
{
throwToolExit
(
null
,
exitCode:
code
);
}
}
/// Update the user's packages.
Future
<
void
>
updatePackages
(
FlutterVersion
flutterVersion
)
async
{
printStatus
(
''
);
printStatus
(
flutterVersion
.
toString
());
final
String
projectRoot
=
findProjectRoot
();
if
(
projectRoot
!=
null
)
{
printStatus
(
''
);
await
pubGet
(
context:
PubContext
.
pubUpgrade
,
directory:
projectRoot
,
upgrade:
true
,
checkLastModified:
false
);
}
}
// Run a doctor check in case system requirements have changed.
/// Run flutter doctor in case requirements have changed.
Future
<
void
>
runDoctor
()
async
{
printStatus
(
''
);
printStatus
(
'Running flutter doctor...'
);
code
=
await
runCommandAndStreamOutput
(
await
runCommandAndStreamOutput
(
<
String
>[
fs
.
path
.
join
(
'bin'
,
'flutter'
),
'--no-version-check'
,
'doctor'
,
],
workingDirectory:
Cache
.
flutterRoot
,
allowReentrantFlutter:
true
,
);
return
null
;
}
// dev/benchmarks/complex_layout/lib/main.dart | 24 +-
...
...
@@ -97,7 +188,6 @@ class UpgradeCommand extends FlutterCommand {
// create mode 100644 examples/flutter_gallery/lib/gallery/demo.dart
static
final
RegExp
_gitChangedRegex
=
RegExp
(
r' (rename|delete mode|create mode) .+'
);
@visibleForTesting
static
bool
matchesGitLine
(
String
line
)
{
return
_gitDiffRegex
.
hasMatch
(
line
)
||
_gitChangedRegex
.
hasMatch
(
line
)
...
...
packages/flutter_tools/test/commands/upgrade_test.dart
View file @
beaf7e28
...
...
@@ -2,21 +2,83 @@
// 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/common.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/io.dart'
;
import
'package:flutter_tools/src/base/os.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/commands/upgrade.dart'
;
import
'package:flutter_tools/src/runner/flutter_command.dart'
;
import
'package:flutter_tools/src/version.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:process/process.dart'
;
import
'../src/common.dart'
;
import
'../src/context.dart'
;
void
main
(
)
{
group
(
'upgrade'
,
()
{
group
(
'UpgradeCommandRunner'
,
()
{
FakeUpgradeCommandRunner
fakeCommandRunner
;
UpgradeCommandRunner
realCommandRunner
;
MockProcessManager
processManager
;
final
MockFlutterVersion
flutterVersion
=
MockFlutterVersion
();
const
GitTagVersion
gitTagVersion
=
GitTagVersion
(
1
,
2
,
3
,
4
,
5
,
'asd'
);
when
(
flutterVersion
.
channel
).
thenReturn
(
'dev'
);
setUp
(()
{
fakeCommandRunner
=
FakeUpgradeCommandRunner
();
realCommandRunner
=
UpgradeCommandRunner
();
processManager
=
MockProcessManager
();
});
test
(
'throws on unknown tag, official branch, noforce'
,
()
async
{
final
Future
<
FlutterCommandResult
>
result
=
fakeCommandRunner
.
runCommand
(
false
,
const
GitTagVersion
.
unknown
(),
flutterVersion
,
);
expect
(
result
,
throwsA
(
isInstanceOf
<
ToolExit
>()));
});
test
(
'does not throw on unknown tag, official branch, force'
,
()
async
{
final
Future
<
FlutterCommandResult
>
result
=
fakeCommandRunner
.
runCommand
(
true
,
const
GitTagVersion
.
unknown
(),
flutterVersion
,
);
expect
(
await
result
,
null
);
});
test
(
'Doesn
\'
t throw on known tag, dev branch, no force'
,
()
async
{
final
Future
<
FlutterCommandResult
>
result
=
fakeCommandRunner
.
runCommand
(
false
,
gitTagVersion
,
flutterVersion
,
);
expect
(
await
result
,
null
);
});
testUsingContext
(
'verifyUpstreamConfigured'
,
()
async
{
when
(
processManager
.
run
(
<
String
>[
'git'
,
'rev-parse'
,
'@{u}'
],
environment:
anyNamed
(
'environment'
),
workingDirectory:
anyNamed
(
'workingDirectory'
))
).
thenAnswer
((
Invocation
invocation
)
async
{
return
FakeProcessResult
()
..
exitCode
=
0
;
});
await
realCommandRunner
.
verifyUpstreamConfigured
();
},
overrides:
<
Type
,
Generator
>{
ProcessManager:
()
=>
processManager
,
});
});
group
(
'matchesGitLine'
,
()
{
setUpAll
(()
{
Cache
.
disableLocking
();
});
bool
_match
(
String
line
)
=>
UpgradeCommand
.
matchesGitLine
(
line
);
bool
_match
(
String
line
)
=>
UpgradeCommand
Runner
.
matchesGitLine
(
line
);
test
(
'regex match'
,
()
{
expect
(
_match
(
' .../flutter_gallery/lib/demo/buttons_demo.dart | 10 +--'
),
true
);
...
...
@@ -63,3 +125,42 @@ void main() {
});
});
}
class
FakeUpgradeCommandRunner
extends
UpgradeCommandRunner
{
@override
Future
<
void
>
verifyUpstreamConfigured
()
async
{}
@override
Future
<
void
>
resetChanges
(
GitTagVersion
gitTagVersion
)
async
{}
@override
Future
<
void
>
upgradeChannel
(
FlutterVersion
flutterVersion
)
async
{}
@override
Future
<
void
>
attemptFastForward
()
async
{}
@override
Future
<
void
>
precacheArtifacts
()
async
{}
@override
Future
<
void
>
updatePackages
(
FlutterVersion
flutterVersion
)
async
{}
@override
Future
<
void
>
runDoctor
()
async
{}
}
class
MockFlutterVersion
extends
Mock
implements
FlutterVersion
{}
class
MockProcessManager
extends
Mock
implements
ProcessManager
{}
class
FakeProcessResult
implements
ProcessResult
{
@override
int
exitCode
;
@override
int
pid
=
0
;
@override
String
stderr
=
''
;
@override
String
stdout
=
''
;
}
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