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
d56af3ca
Unverified
Commit
d56af3ca
authored
May 08, 2020
by
Christopher Fujino
Committed by
GitHub
May 08, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add --force to `roll_dev.dart` (#56501)
parent
7ba5078f
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
521 additions
and
136 deletions
+521
-136
roll_dev.dart
dev/tools/lib/roll_dev.dart
+180
-122
roll_dev_test.dart
dev/tools/test/roll_dev_test.dart
+341
-14
No files found.
dev/tools/lib/roll_dev.dart
View file @
d56af3ca
...
...
@@ -10,6 +10,7 @@
import
'dart:io'
;
import
'package:args/args.dart'
;
import
'package:meta/meta.dart'
;
const
String
kIncrement
=
'increment'
;
const
String
kX
=
'x'
;
...
...
@@ -20,131 +21,93 @@ const String kOrigin = 'origin';
const
String
kJustPrint
=
'just-print'
;
const
String
kYes
=
'yes'
;
const
String
kHelp
=
'help'
;
const
String
kForce
=
'force'
;
const
String
kUpstreamRemote
=
'git@github.com:flutter/flutter.git'
;
void
main
(
List
<
String
>
args
)
{
final
ArgParser
argParser
=
ArgParser
(
allowTrailingOptions:
false
);
argParser
.
addOption
(
kIncrement
,
help:
'Specifies which part of the x.y.z version number to increment. Required.'
,
valueHelp:
'level'
,
allowed:
<
String
>[
kX
,
kY
,
kZ
],
allowedHelp:
<
String
,
String
>{
kX:
'Indicates a major development, e.g. typically changed after a big press event.'
,
kY:
'Indicates a minor development, e.g. typically changed after a beta release.'
,
kZ:
'Indicates the least notable level of change. You normally want this.'
,
},
);
argParser
.
addOption
(
kCommit
,
help:
'Specifies which git commit to roll to the dev branch. Required.'
,
valueHelp:
'hash'
,
defaultsTo:
null
,
// This option is required
);
argParser
.
addOption
(
kOrigin
,
help:
'Specifies the name of the upstream repository'
,
valueHelp:
'repository'
,
defaultsTo:
'upstream'
,
);
argParser
.
addFlag
(
kJustPrint
,
negatable:
false
,
help:
"Don't actually roll the dev channel; "
'just print the would-be version and quit.'
,
);
argParser
.
addFlag
(
kYes
,
negatable:
false
,
abbr:
'y'
,
help:
'Skip the confirmation prompt.'
);
argParser
.
addFlag
(
kHelp
,
negatable:
false
,
help:
'Show this help message.'
,
hide:
true
);
ArgResults
argResults
;
try
{
argResults
=
argParser
.
parse
(
args
);
argResults
=
parseArguments
(
argParser
,
args
);
}
on
ArgParserException
catch
(
error
)
{
print
(
error
.
message
);
print
(
argParser
.
usage
);
exit
(
1
);
}
try
{
run
(
usage:
argParser
.
usage
,
argResults:
argResults
,
git:
const
Git
(),
);
}
on
Exception
catch
(
e
)
{
print
(
e
.
toString
());
exit
(
1
);
}
}
/// Main script execution.
///
/// Returns true if publishing was successful, else false.
bool
run
(
{
@required
String
usage
,
@required
ArgResults
argResults
,
@required
Git
git
,
})
{
final
String
level
=
argResults
[
kIncrement
]
as
String
;
final
String
commit
=
argResults
[
kCommit
]
as
String
;
final
String
origin
=
argResults
[
kOrigin
]
as
String
;
final
bool
justPrint
=
argResults
[
kJustPrint
]
as
bool
;
final
bool
autoApprove
=
argResults
[
kYes
]
as
bool
;
final
bool
help
=
argResults
[
kHelp
]
as
bool
;
final
bool
force
=
argResults
[
kForce
]
as
bool
;
if
(
help
||
level
==
null
||
commit
==
null
)
{
print
(
'roll_dev.dart --increment=level --commit=hash • update the version tags and roll a new dev build.
\n
'
);
print
(
argParser
.
usage
);
exit
(
0
);
print
(
'roll_dev.dart --increment=level --commit=hash • update the version tags '
'and roll a new dev build.
\n
$usage
'
);
return
false
;
}
if
(
getGitOutput
(
'remote get-url
$origin
'
,
'check whether this is a flutter checkout'
)
!=
kUpstreamRemote
)
{
print
(
'The current directory is not a Flutter repository checkout with a correctly configured upstream remote.'
);
print
(
'For more details see: https://github.com/flutter/flutter/wiki/Release-process'
);
exit
(
1
);
final
String
remote
=
git
.
getOutput
(
'remote get-url
$origin
'
,
'check whether this is a flutter checkout'
,
);
if
(
remote
!=
kUpstreamRemote
)
{
throw
Exception
(
'The current directory is not a Flutter repository checkout with a '
'correctly configured upstream remote.
\n
For more details see: '
'https://github.com/flutter/flutter/wiki/Release-process'
);
}
if
(
getGitOutput
(
'status --porcelain'
,
'check status of your local checkout'
)
!=
''
)
{
print
(
'Your git repository is not clean. Try running "git clean -fd". Warning, this '
);
print
(
'will delete files! Run with -n to find out which ones.'
);
exit
(
1
);
if
(
git
.
getOutput
(
'status --porcelain'
,
'check status of your local checkout'
)
!=
''
)
{
throw
Exception
(
'Your git repository is not clean. Try running "git clean -fd". Warning, '
'this will delete files! Run with -n to find out which ones.'
);
}
runGit
(
'fetch
$origin
'
,
'fetch
$origin
'
);
runGit
(
'reset
$commit
--hard'
,
'reset to the release commit'
);
// TODO(fujino): move this after `justPrint`
git
.
run
(
'fetch
$origin
'
,
'fetch
$origin
'
);
git
.
run
(
'reset
$commit
--hard'
,
'reset to the release commit'
);
String
version
=
getFullTag
();
final
Match
match
=
parseFullTag
(
version
);
if
(
match
==
null
)
{
print
(
'Could not determine the version for this build.'
);
if
(
version
.
isNotEmpty
)
print
(
'Git reported the latest version as "
$version
", which does not fit the expected pattern.'
);
exit
(
1
);
}
String
version
=
getFullTag
(
git
);
final
List
<
int
>
parts
=
match
.
groups
(<
int
>[
1
,
2
,
3
,
4
,
5
]).
map
<
int
>(
int
.
parse
).
toList
();
if
(
match
.
group
(
6
)
==
'0'
)
{
print
(
'This commit has already been released, as version
${getVersionFromParts(parts)}
.'
);
exit
(
0
);
}
switch
(
level
)
{
case
kX:
parts
[
0
]
+=
1
;
parts
[
1
]
=
0
;
parts
[
2
]
=
0
;
parts
[
3
]
=
0
;
parts
[
4
]
=
0
;
break
;
case
kY:
parts
[
1
]
+=
1
;
parts
[
2
]
=
0
;
parts
[
3
]
=
0
;
parts
[
4
]
=
0
;
break
;
case
kZ:
parts
[
2
]
=
0
;
parts
[
3
]
+=
1
;
parts
[
4
]
=
0
;
break
;
default
:
print
(
'Unknown increment level. The valid values are "
$kX
", "
$kY
", and "
$kZ
".'
);
exit
(
1
);
}
version
=
getVersionFromParts
(
parts
);
version
=
incrementLevel
(
version
,
level
);
if
(
justPrint
)
{
print
(
version
);
exit
(
0
)
;
return
false
;
}
final
String
hash
=
g
etGi
tOutput
(
'rev-parse HEAD'
,
'Get git hash for
$commit
'
);
final
String
hash
=
g
it
.
ge
tOutput
(
'rev-parse HEAD'
,
'Get git hash for
$commit
'
);
runGit
(
'tag
$version
'
,
'tag the commit with the version label'
);
git
.
run
(
'tag
$version
'
,
'tag the commit with the version label'
);
// PROMPT
...
...
@@ -155,29 +118,79 @@ void main(List<String> args) {
'to the "dev" channel.'
);
stdout
.
write
(
'Are you? [yes/no] '
);
if
(
stdin
.
readLineSync
()
!=
'yes'
)
{
runGit
(
'tag -d
$version
'
,
'remove the tag you did not want to publish'
);
git
.
run
(
'tag -d
$version
'
,
'remove the tag you did not want to publish'
);
print
(
'The dev roll has been aborted.'
);
exit
(
0
)
;
return
false
;
}
}
runGit
(
'push
$origin
$version
'
,
'publish the version'
);
runGit
(
'push
$origin
HEAD:dev'
,
'land the new version on the "dev" branch'
);
git
.
run
(
'push
$origin
$version
'
,
'publish the version'
);
git
.
run
(
'push
${force ? "--force " : ""}$origin
HEAD:dev'
,
'land the new version on the "dev" branch'
,
);
print
(
'Flutter version
$version
has been rolled to the "dev" channel!'
);
return
true
;
}
ArgResults
parseArguments
(
ArgParser
argParser
,
List
<
String
>
args
)
{
argParser
.
addOption
(
kIncrement
,
help:
'Specifies which part of the x.y.z version number to increment. Required.'
,
valueHelp:
'level'
,
allowed:
<
String
>[
kX
,
kY
,
kZ
],
allowedHelp:
<
String
,
String
>{
kX:
'Indicates a major development, e.g. typically changed after a big press event.'
,
kY:
'Indicates a minor development, e.g. typically changed after a beta release.'
,
kZ:
'Indicates the least notable level of change. You normally want this.'
,
},
);
argParser
.
addOption
(
kCommit
,
help:
'Specifies which git commit to roll to the dev branch. Required.'
,
valueHelp:
'hash'
,
defaultsTo:
null
,
// This option is required
);
argParser
.
addOption
(
kOrigin
,
help:
'Specifies the name of the upstream repository'
,
valueHelp:
'repository'
,
defaultsTo:
'upstream'
,
);
argParser
.
addFlag
(
kForce
,
abbr:
'f'
,
help:
'Force push. Necessary when the previous release had cherry-picks.'
,
negatable:
false
,
);
argParser
.
addFlag
(
kJustPrint
,
negatable:
false
,
help:
"Don't actually roll the dev channel; "
'just print the would-be version and quit.'
,
);
argParser
.
addFlag
(
kYes
,
negatable:
false
,
abbr:
'y'
,
help:
'Skip the confirmation prompt.'
);
argParser
.
addFlag
(
kHelp
,
negatable:
false
,
help:
'Show this help message.'
,
hide:
true
);
return
argParser
.
parse
(
args
);
}
String
getFullTag
(
)
{
/// Obtain the version tag of the previous dev release.
String
getFullTag
(
Git
git
)
{
const
String
glob
=
'*.*.*-*.*.pre'
;
return
getGitOutput
(
'describe --match
$glob
--first-parent --long --tags'
,
// describe the latest dev release
const
String
ref
=
'refs/heads/dev'
;
return
git
.
getOutput
(
'describe --match
$glob
--exact-match --tags
$ref
'
,
'obtain last released version number'
,
);
}
Match
parseFullTag
(
String
version
)
{
// of the form: x.y.z-m.n.pre
-c-g<revision>
// of the form: x.y.z-m.n.pre
final
RegExp
versionPattern
=
RegExp
(
r'^(\d+)\.(\d+)\.(\d+)-(\d+)\.(\d+)\.pre
-(\d+)-g([a-f0-9]+)
$'
);
r'^(\d+)\.(\d+)\.(\d+)-(\d+)\.(\d+)\.pre$'
);
return
versionPattern
.
matchAsPrefix
(
version
);
}
...
...
@@ -195,33 +208,78 @@ String getVersionFromParts(List<int> parts) {
return
buf
.
toString
();
}
String
getGitOutput
(
String
command
,
String
explanation
)
{
final
ProcessResult
result
=
_runGit
(
command
);
if
((
result
.
stderr
as
String
).
isEmpty
&&
result
.
exitCode
==
0
)
return
(
result
.
stdout
as
String
).
trim
();
_reportGitFailureAndExit
(
result
,
explanation
);
return
null
;
// for the analyzer's sake
}
class
Git
{
const
Git
();
void
runGit
(
String
command
,
String
explanation
)
{
final
ProcessResult
result
=
_runGit
(
command
);
if
(
result
.
exitCode
!=
0
)
_reportGitFailureAndExit
(
result
,
explanation
);
}
String
getOutput
(
String
command
,
String
explanation
)
{
final
ProcessResult
result
=
_run
(
command
);
if
((
result
.
stderr
as
String
).
isEmpty
&&
result
.
exitCode
==
0
)
return
(
result
.
stdout
as
String
).
trim
();
_reportFailureAndExit
(
result
,
explanation
);
return
null
;
// for the analyzer's sake
}
void
run
(
String
command
,
String
explanation
)
{
final
ProcessResult
result
=
_run
(
command
);
if
(
result
.
exitCode
!=
0
)
_reportFailureAndExit
(
result
,
explanation
);
}
ProcessResult
_run
(
String
command
)
{
return
Process
.
runSync
(
'git'
,
command
.
split
(
' '
));
}
ProcessResult
_runGit
(
String
command
)
{
return
Process
.
runSync
(
'git'
,
command
.
split
(
' '
));
void
_reportFailureAndExit
(
ProcessResult
result
,
String
explanation
)
{
if
(
result
.
exitCode
!=
0
)
{
print
(
'Failed to
$explanation
. Git exited with error code
${result.exitCode}
.'
);
}
else
{
print
(
'Failed to
$explanation
.'
);
}
if
((
result
.
stdout
as
String
).
isNotEmpty
)
print
(
'stdout from git:
\n
${result.stdout}
\n
'
);
if
((
result
.
stderr
as
String
).
isNotEmpty
)
print
(
'stderr from git:
\n
${result.stderr}
\n
'
);
exit
(
1
);
}
}
void
_reportGitFailureAndExit
(
ProcessResult
result
,
String
explanation
)
{
if
(
result
.
exitCode
!=
0
)
{
print
(
'Failed to
$explanation
. Git exited with error code
${result.exitCode}
.'
);
}
else
{
print
(
'Failed to
$explanation
.'
);
/// Return a copy of the [version] with [level] incremented by one.
String
incrementLevel
(
String
version
,
String
level
)
{
final
Match
match
=
parseFullTag
(
version
);
if
(
match
==
null
)
{
String
errorMessage
;
if
(
version
.
isEmpty
)
{
errorMessage
=
'Could not determine the version for this build.'
;
}
else
{
errorMessage
=
'Git reported the latest version as "
$version
", which '
'does not fit the expected pattern.'
;
}
throw
Exception
(
errorMessage
);
}
final
List
<
int
>
parts
=
match
.
groups
(<
int
>[
1
,
2
,
3
,
4
,
5
]).
map
<
int
>(
int
.
parse
).
toList
();
switch
(
level
)
{
case
kX:
parts
[
0
]
+=
1
;
parts
[
1
]
=
0
;
parts
[
2
]
=
0
;
parts
[
3
]
=
0
;
parts
[
4
]
=
0
;
break
;
case
kY:
parts
[
1
]
+=
1
;
parts
[
2
]
=
0
;
parts
[
3
]
=
0
;
parts
[
4
]
=
0
;
break
;
case
kZ:
parts
[
2
]
=
0
;
parts
[
3
]
+=
1
;
parts
[
4
]
=
0
;
break
;
default
:
throw
Exception
(
'Unknown increment level. The valid values are "
$kX
", "
$kY
", and "
$kZ
".'
);
}
if
((
result
.
stdout
as
String
).
isNotEmpty
)
print
(
'stdout from git:
\n
${result.stdout}
\n
'
);
if
((
result
.
stderr
as
String
).
isNotEmpty
)
print
(
'stderr from git:
\n
${result.stderr}
\n
'
);
exit
(
1
);
return
getVersionFromParts
(
parts
);
}
dev/tools/test/roll_dev_test.dart
View file @
d56af3ca
...
...
@@ -2,20 +2,227 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:args/args.dart'
;
import
'package:dev_tools/roll_dev.dart'
;
import
'package:mockito/mockito.dart'
;
import
'./common.dart'
;
void
main
(
)
{
group
(
'run()'
,
()
{
const
String
usage
=
'usage info...'
;
const
String
level
=
'z'
;
const
String
commit
=
'abcde012345'
;
const
String
origin
=
'upstream'
;
FakeArgResults
fakeArgResults
;
MockGit
mockGit
;
setUp
(()
{
mockGit
=
MockGit
();
});
test
(
'returns false if help requested'
,
()
{
fakeArgResults
=
FakeArgResults
(
level:
level
,
commit:
commit
,
origin:
origin
,
justPrint:
false
,
autoApprove:
true
,
help:
true
,
);
expect
(
run
(
usage:
usage
,
argResults:
fakeArgResults
,
git:
mockGit
,
),
false
,
);
});
test
(
'returns false if level not provided'
,
()
{
fakeArgResults
=
FakeArgResults
(
level:
level
,
commit:
commit
,
origin:
origin
,
justPrint:
false
,
autoApprove:
true
,
help:
true
,
);
expect
(
run
(
usage:
usage
,
argResults:
fakeArgResults
,
git:
mockGit
,
),
false
,
);
});
test
(
'returns false if commit not provided'
,
()
{
fakeArgResults
=
FakeArgResults
(
level:
level
,
commit:
commit
,
origin:
origin
,
justPrint:
false
,
autoApprove:
true
,
help:
true
,
);
expect
(
run
(
usage:
usage
,
argResults:
fakeArgResults
,
git:
mockGit
,
),
false
,
);
});
test
(
'throws exception if upstream remote wrong'
,
()
{
when
(
mockGit
.
getOutput
(
'remote get-url
$origin
'
,
any
)).
thenReturn
(
'wrong-remote'
);
fakeArgResults
=
FakeArgResults
(
level:
level
,
commit:
commit
,
origin:
origin
,
justPrint:
false
,
autoApprove:
true
,
help:
false
,
);
Exception
exception
;
try
{
run
(
usage:
usage
,
argResults:
fakeArgResults
,
git:
mockGit
,
);
}
on
Exception
catch
(
e
)
{
exception
=
e
;
}
const
String
pattern
=
r'The current directory is not a Flutter '
'repository checkout with a correctly configured upstream remote.'
;
expect
(
exception
?.
toString
(),
contains
(
pattern
));
});
test
(
'throws exception if git checkout not clean'
,
()
{
when
(
mockGit
.
getOutput
(
'remote get-url
$origin
'
,
any
)).
thenReturn
(
kUpstreamRemote
);
when
(
mockGit
.
getOutput
(
'status --porcelain'
,
any
)).
thenReturn
(
' M dev/tools/test/roll_dev_test.dart'
,
);
fakeArgResults
=
FakeArgResults
(
level:
level
,
commit:
commit
,
origin:
origin
,
justPrint:
false
,
autoApprove:
true
,
help:
false
,
);
Exception
exception
;
try
{
run
(
usage:
usage
,
argResults:
fakeArgResults
,
git:
mockGit
,
);
}
on
Exception
catch
(
e
)
{
exception
=
e
;
}
const
String
pattern
=
r'Your git repository is not clean. Try running '
'"git clean -fd". Warning, this will delete files! Run with -n to find '
'out which ones.'
;
expect
(
exception
?.
toString
(),
contains
(
pattern
));
});
test
(
'does not tag if --just-print is specified'
,
()
{
when
(
mockGit
.
getOutput
(
'remote get-url
$origin
'
,
any
)).
thenReturn
(
kUpstreamRemote
);
when
(
mockGit
.
getOutput
(
'status --porcelain'
,
any
)).
thenReturn
(
''
);
when
(
mockGit
.
getOutput
(
'describe --match *.*.*-*.*.pre --exact-match --tags refs/heads/dev'
,
any
,
)).
thenReturn
(
'1.2.3-0.0.pre'
);
fakeArgResults
=
FakeArgResults
(
level:
level
,
commit:
commit
,
origin:
origin
,
justPrint:
true
,
autoApprove:
true
,
help:
false
,
);
expect
(
run
(
usage:
usage
,
argResults:
fakeArgResults
,
git:
mockGit
,
),
false
);
verify
(
mockGit
.
run
(
'fetch
$origin
'
,
any
));
verify
(
mockGit
.
run
(
'reset
$commit
--hard'
,
any
));
verifyNever
(
mockGit
.
getOutput
(
'rev-parse HEAD'
,
any
));
});
test
(
'successfully tags and publishes release'
,
()
{
when
(
mockGit
.
getOutput
(
'remote get-url
$origin
'
,
any
)).
thenReturn
(
kUpstreamRemote
);
when
(
mockGit
.
getOutput
(
'status --porcelain'
,
any
)).
thenReturn
(
''
);
when
(
mockGit
.
getOutput
(
'describe --match *.*.*-*.*.pre --exact-match --tags refs/heads/dev'
,
any
,
)).
thenReturn
(
'1.2.3-0.0.pre'
);
when
(
mockGit
.
getOutput
(
'rev-parse HEAD'
,
any
)).
thenReturn
(
commit
);
fakeArgResults
=
FakeArgResults
(
level:
level
,
commit:
commit
,
origin:
origin
,
justPrint:
false
,
autoApprove:
true
,
help:
false
,
);
expect
(
run
(
usage:
usage
,
argResults:
fakeArgResults
,
git:
mockGit
,
),
true
);
verify
(
mockGit
.
run
(
'fetch
$origin
'
,
any
));
verify
(
mockGit
.
run
(
'reset
$commit
--hard'
,
any
));
verify
(
mockGit
.
run
(
'tag 1.2.0-1.0.pre'
,
any
));
verify
(
mockGit
.
run
(
'push
$origin
HEAD:dev'
,
any
));
});
test
(
'successfully publishes release with --force'
,
()
{
when
(
mockGit
.
getOutput
(
'remote get-url
$origin
'
,
any
)).
thenReturn
(
kUpstreamRemote
);
when
(
mockGit
.
getOutput
(
'status --porcelain'
,
any
)).
thenReturn
(
''
);
when
(
mockGit
.
getOutput
(
'describe --match *.*.*-*.*.pre --exact-match --tags refs/heads/dev'
,
any
,
)).
thenReturn
(
'1.2.3-0.0.pre'
);
when
(
mockGit
.
getOutput
(
'rev-parse HEAD'
,
any
)).
thenReturn
(
commit
);
fakeArgResults
=
FakeArgResults
(
level:
level
,
commit:
commit
,
origin:
origin
,
justPrint:
false
,
autoApprove:
true
,
help:
false
,
force:
true
,
);
expect
(
run
(
usage:
usage
,
argResults:
fakeArgResults
,
git:
mockGit
,
),
true
);
verify
(
mockGit
.
run
(
'fetch
$origin
'
,
any
));
verify
(
mockGit
.
run
(
'reset
$commit
--hard'
,
any
));
verify
(
mockGit
.
run
(
'tag 1.2.0-1.0.pre'
,
any
));
verify
(
mockGit
.
run
(
'push --force
$origin
HEAD:dev'
,
any
));
});
});
group
(
'parseFullTag'
,
()
{
test
(
'returns match on valid version input'
,
()
{
final
List
<
String
>
validTags
=
<
String
>[
'1.2.3-1.2.pre
-3-gabc123
'
,
'10.2.30-12.22.pre
-45-gabc123
'
,
'1.18.0-0.0.pre
-0-gf0adb240a
'
,
'2.0.0-1.99.pre
-45-gf0adb240a
'
,
'12.34.56-78.90.pre
-12-g9db2703a2
'
,
'0.0.1-0.0.pre
-1-g07601eb95ff82f01e870566586340ed2e87b9cbb
'
,
'958.80.144-6.224.pre
-7803-g06e90
'
,
'1.2.3-1.2.pre'
,
'10.2.30-12.22.pre'
,
'1.18.0-0.0.pre'
,
'2.0.0-1.99.pre'
,
'12.34.56-78.90.pre'
,
'0.0.1-0.0.pre'
,
'958.80.144-6.224.pre'
,
];
for
(
final
String
validTag
in
validTags
)
{
final
Match
match
=
parseFullTag
(
validTag
);
...
...
@@ -25,15 +232,15 @@ void main() {
test
(
'returns null on invalid version input'
,
()
{
final
List
<
String
>
invalidTags
=
<
String
>[
'1.2.3-dev.1.2-3-gabc123'
,
'1.2.3-1.2-3-gabc123'
,
'1.2.3-1.2.pre-3-gabc123'
,
'1.2.3-1.2.3.pre'
,
'1.2.3.1.2.pre'
,
'1.2.3-dev.1.2'
,
'1.2.3-1.2-3'
,
'v1.2.3'
,
'2.0.0'
,
'v1.2.3-1.2.pre-3-gabc123'
,
'10.0.1-0.0.pre-gf0adb240a'
,
'10.0.1-0.0.pre-3-gggggggggg'
,
'1.2.3-1.2.pre-3-abc123'
,
'1.2.3-1.2.pre-3-gabc123_'
,
'v1.2.3-1.2.pre'
,
'1.2.3-1.2.pre_'
,
];
for
(
final
String
invalidTag
in
invalidTags
)
{
final
Match
match
=
parseFullTag
(
invalidTag
);
...
...
@@ -51,4 +258,124 @@ void main() {
expect
(
getVersionFromParts
(
parts
),
'11.2.33-1.0.pre'
);
});
});
group
(
'incrementLevel()'
,
()
{
const
String
hash
=
'abc123'
;
test
(
'throws exception if hash is not valid release candidate'
,
()
{
String
level
=
'z'
;
String
version
=
'1.0.0-0.0.pre-1-g
$hash
'
;
expect
(
()
=>
incrementLevel
(
version
,
level
),
throwsException
,
reason:
'should throw because
$version
should be an exact tag'
,
);
version
=
'1.2.3'
;
expect
(
()
=>
incrementLevel
(
version
,
level
),
throwsException
,
reason:
'should throw because
$version
should be a dev tag, not stable.'
);
version
=
'1.0.0-0.0.pre-1-g
$hash
'
;
level
=
'q'
;
expect
(
()
=>
incrementLevel
(
version
,
level
),
throwsException
,
reason:
'should throw because
$level
is unsupported'
,
);
});
test
(
'successfully increments x'
,
()
{
const
String
level
=
'x'
;
String
version
=
'1.0.0-0.0.pre'
;
expect
(
incrementLevel
(
version
,
level
),
'2.0.0-0.0.pre'
);
version
=
'10.20.0-40.50.pre'
;
expect
(
incrementLevel
(
version
,
level
),
'11.0.0-0.0.pre'
);
version
=
'1.18.0-3.0.pre'
;
expect
(
incrementLevel
(
version
,
level
),
'2.0.0-0.0.pre'
);
});
test
(
'successfully increments y'
,
()
{
const
String
level
=
'y'
;
String
version
=
'1.0.0-0.0.pre'
;
expect
(
incrementLevel
(
version
,
level
),
'1.1.0-0.0.pre'
);
version
=
'10.20.0-40.50.pre'
;
expect
(
incrementLevel
(
version
,
level
),
'10.21.0-0.0.pre'
);
version
=
'1.18.0-3.0.pre'
;
expect
(
incrementLevel
(
version
,
level
),
'1.19.0-0.0.pre'
);
});
test
(
'successfully increments z'
,
()
{
const
String
level
=
'z'
;
String
version
=
'1.0.0-0.0.pre'
;
expect
(
incrementLevel
(
version
,
level
),
'1.0.0-1.0.pre'
);
version
=
'10.20.0-40.50.pre'
;
expect
(
incrementLevel
(
version
,
level
),
'10.20.0-41.0.pre'
);
version
=
'1.18.0-3.0.pre'
;
expect
(
incrementLevel
(
version
,
level
),
'1.18.0-4.0.pre'
);
});
});
}
class
FakeArgResults
implements
ArgResults
{
FakeArgResults
({
String
level
,
String
commit
,
String
origin
,
bool
justPrint
,
bool
autoApprove
,
bool
help
,
bool
force
=
false
,
})
:
_parsedArgs
=
<
String
,
dynamic
>{
'increment'
:
level
,
'commit'
:
commit
,
'origin'
:
origin
,
'just-print'
:
justPrint
,
'yes'
:
autoApprove
,
'help'
:
help
,
'force'
:
force
,
};
@override
String
name
;
@override
ArgResults
command
;
@override
final
List
<
String
>
rest
=
<
String
>[];
@override
List
<
String
>
arguments
;
final
Map
<
String
,
dynamic
>
_parsedArgs
;
@override
Iterable
<
String
>
get
options
{
return
null
;
}
@override
dynamic
operator
[](
String
name
)
{
return
_parsedArgs
[
name
];
}
@override
bool
wasParsed
(
String
name
)
{
return
null
;
}
}
class
MockGit
extends
Mock
implements
Git
{}
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