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
cdf5b1d4
Unverified
Commit
cdf5b1d4
authored
Jul 15, 2022
by
Jesús S Guerrero
Committed by
GitHub
Jul 15, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Pub dependencies project validator (#106895)
parent
da8070d6
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
275 additions
and
8 deletions
+275
-8
executable.dart
packages/flutter_tools/lib/executable.dart
+1
-0
analyze.dart
packages/flutter_tools/lib/src/commands/analyze.dart
+8
-3
validate_project.dart
...ages/flutter_tools/lib/src/commands/validate_project.dart
+5
-1
dart_pub_json_formatter.dart
packages/flutter_tools/lib/src/dart_pub_json_formatter.dart
+71
-0
project_validator.dart
packages/flutter_tools/lib/src/project_validator.dart
+82
-4
pub_dependencies_project_validator_test.dart
...eneral.shard/pub_dependencies_project_validator_test.dart
+77
-0
analyze_suggestions_integration_test.dart
...tegration.shard/analyze_suggestions_integration_test.dart
+31
-0
No files found.
packages/flutter_tools/lib/executable.dart
View file @
cdf5b1d4
...
...
@@ -142,6 +142,7 @@ List<FlutterCommand> generateCommands({
logger:
globals
.
logger
,
terminal:
globals
.
terminal
,
artifacts:
globals
.
artifacts
!,
// new ProjectValidators should be added here for the --suggestions to run
allProjectValidators:
<
ProjectValidator
>[],
),
AssembleCommand
(
verboseHelp:
verboseHelp
,
buildSystem:
globals
.
buildSystem
),
...
...
packages/flutter_tools/lib/src/commands/analyze.dart
View file @
cdf5b1d4
...
...
@@ -138,10 +138,14 @@ class AnalyzeCommand extends FlutterCommand {
}
if
(
workingDirectory
==
null
)
{
final
Set
<
String
>
items
=
findDirectories
(
argResults
!,
_fileSystem
);
if
(
items
.
isEmpty
||
items
.
length
>
1
)
{
throwToolExit
(
'The suggestions flags needs one directory path'
);
if
(
items
.
isEmpty
)
{
// user did not specify any path
directoryPath
=
_fileSystem
.
currentDirectory
.
path
;
_logger
.
printTrace
(
'Showing suggestions for current directory:
$directoryPath
'
);
}
else
if
(
items
.
length
>
1
)
{
// if the user sends more than one path
throwToolExit
(
'The suggestions flag can process only one directory path'
);
}
else
{
directoryPath
=
items
.
first
;
}
directoryPath
=
items
.
first
;
}
else
{
directoryPath
=
workingDirectory
!.
path
;
}
...
...
@@ -150,6 +154,7 @@ class AnalyzeCommand extends FlutterCommand {
logger:
_logger
,
allProjectValidators:
_allProjectValidators
,
userPath:
directoryPath
,
processManager:
_processManager
,
).
run
();
}
else
if
(
boolArgDeprecated
(
'watch'
))
{
await
AnalyzeContinuously
(
...
...
packages/flutter_tools/lib/src/commands/validate_project.dart
View file @
cdf5b1d4
...
...
@@ -2,6 +2,8 @@
// 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/file_system.dart'
;
import
'../base/logger.dart'
;
import
'../project.dart'
;
...
...
@@ -15,7 +17,8 @@ class ValidateProject {
required
this
.
logger
,
required
this
.
allProjectValidators
,
required
this
.
userPath
,
this
.
verbose
=
false
required
this
.
processManager
,
this
.
verbose
=
false
,
});
final
FileSystem
fileSystem
;
...
...
@@ -23,6 +26,7 @@ class ValidateProject {
final
bool
verbose
;
final
String
userPath
;
final
List
<
ProjectValidator
>
allProjectValidators
;
final
ProcessManager
processManager
;
Future
<
FlutterCommandResult
>
run
()
async
{
final
Directory
workingDirectory
=
userPath
.
isEmpty
?
fileSystem
.
currentDirectory
:
fileSystem
.
directory
(
userPath
);
...
...
packages/flutter_tools/lib/src/dart_pub_json_formatter.dart
0 → 100644
View file @
cdf5b1d4
// 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
'dart:collection'
;
/// Parsing the output of "dart pub deps --json"
///
/// expected structure: {"name": "package name", "source": "hosted", "dependencies": [...]}
class
DartDependencyPackage
{
DartDependencyPackage
({
required
this
.
name
,
required
this
.
version
,
required
this
.
source
,
required
this
.
dependencies
,
});
factory
DartDependencyPackage
.
fromHashMap
(
dynamic
packageInfo
)
{
String
name
=
''
;
String
version
=
''
;
String
source
=
''
;
List
<
dynamic
>
dependencies
=
<
dynamic
>[];
if
(
packageInfo
is
LinkedHashMap
)
{
final
LinkedHashMap
<
String
,
dynamic
>
info
=
packageInfo
as
LinkedHashMap
<
String
,
dynamic
>;
if
(
info
.
containsKey
(
'name'
))
{
name
=
info
[
'name'
]
as
String
;
}
if
(
info
.
containsKey
(
'version'
))
{
version
=
info
[
'version'
]
as
String
;
}
if
(
info
.
containsKey
(
'source'
))
{
source
=
info
[
'source'
]
as
String
;
}
if
(
info
.
containsKey
(
'dependencies'
))
{
dependencies
=
info
[
'dependencies'
]
as
List
<
dynamic
>;
}
}
return
DartDependencyPackage
(
name:
name
,
version:
version
,
source
:
source
,
dependencies:
dependencies
.
map
((
dynamic
e
)
=>
e
.
toString
()).
toList
(),
);
}
final
String
name
;
final
String
version
;
final
String
source
;
final
List
<
String
>
dependencies
;
}
class
DartPubJson
{
DartPubJson
(
this
.
_json
);
final
LinkedHashMap
<
String
,
dynamic
>
_json
;
final
List
<
DartDependencyPackage
>
_packages
=
<
DartDependencyPackage
>[];
List
<
DartDependencyPackage
>
get
packages
{
if
(
_packages
.
isNotEmpty
)
{
return
_packages
;
}
if
(
_json
.
containsKey
(
'packages'
))
{
final
List
<
dynamic
>
packagesInfo
=
_json
[
'packages'
]
as
List
<
dynamic
>;
for
(
final
dynamic
info
in
packagesInfo
)
{
_packages
.
add
(
DartDependencyPackage
.
fromHashMap
(
info
));
}
}
return
_packages
;
}
}
packages/flutter_tools/lib/src/project_validator.dart
View file @
cdf5b1d4
...
...
@@ -2,19 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:collection'
;
import
'package:process/process.dart'
;
import
'base/io.dart'
;
import
'convert.dart'
;
import
'dart_pub_json_formatter.dart'
;
import
'flutter_manifest.dart'
;
import
'project.dart'
;
import
'project_validator_result.dart'
;
abstract
class
ProjectValidator
{
const
ProjectValidator
();
String
get
title
;
bool
supportsProject
(
FlutterProject
project
);
/// Can return more than one result in case a file/command have a lot of info to share to the user
Future
<
List
<
ProjectValidatorResult
>>
start
(
FlutterProject
project
);
/// new ProjectValidators should be added here for the ValidateProjectCommand to run
static
List
<
ProjectValidator
>
allProjectValidators
=
<
ProjectValidator
>[
GeneralInfoProjectValidator
(),
];
}
/// Validator run for all platforms that extract information from the pubspec.yaml.
...
...
@@ -109,3 +113,77 @@ class GeneralInfoProjectValidator extends ProjectValidator{
@override
String
get
title
=>
'General Info'
;
}
class
PubDependenciesProjectValidator
extends
ProjectValidator
{
const
PubDependenciesProjectValidator
(
this
.
_processManager
);
final
ProcessManager
_processManager
;
@override
Future
<
List
<
ProjectValidatorResult
>>
start
(
FlutterProject
project
)
async
{
const
String
name
=
'Dart dependencies'
;
final
ProcessResult
processResult
=
await
_processManager
.
run
(<
String
>[
'dart'
,
'pub'
,
'deps'
,
'--json'
]);
if
(
processResult
.
stdout
is
!
String
)
{
return
<
ProjectValidatorResult
>[
_createProjectValidatorError
(
name
,
'Command dart pub deps --json failed'
)
];
}
final
LinkedHashMap
<
String
,
dynamic
>
jsonResult
;
final
List
<
ProjectValidatorResult
>
result
=
<
ProjectValidatorResult
>[];
try
{
jsonResult
=
json
.
decode
(
processResult
.
stdout
.
toString
()
)
as
LinkedHashMap
<
String
,
dynamic
>;
}
on
FormatException
{
result
.
add
(
_createProjectValidatorError
(
name
,
processResult
.
stderr
.
toString
()));
return
result
;
}
final
DartPubJson
dartPubJson
=
DartPubJson
(
jsonResult
);
final
List
<
String
>
dependencies
=
<
String
>[];
// Information retrieved from the pubspec.lock file if a dependency comes from
// the hosted url https://pub.dartlang.org we ignore it or if the package
// is the current directory being analyzed (root).
final
Set
<
String
>
hostedDependencies
=
<
String
>{
'hosted'
,
'root'
};
for
(
final
DartDependencyPackage
package
in
dartPubJson
.
packages
)
{
if
(!
hostedDependencies
.
contains
(
package
.
source
))
{
dependencies
.
addAll
(
package
.
dependencies
);
}
}
if
(
dependencies
.
isNotEmpty
)
{
final
String
verb
=
dependencies
.
length
==
1
?
'is'
:
'are'
;
result
.
add
(
ProjectValidatorResult
(
name:
name
,
value:
'
${dependencies.join(', ')}
$verb
not hosted'
,
status:
StatusProjectValidator
.
warning
,
)
);
}
else
{
result
.
add
(
const
ProjectValidatorResult
(
name:
name
,
value:
'All pub dependencies are hosted on https://pub.dartlang.org'
,
status:
StatusProjectValidator
.
success
,
)
);
}
return
result
;
}
@override
bool
supportsProject
(
FlutterProject
project
)
{
return
true
;
}
@override
String
get
title
=>
'Pub dependencies'
;
ProjectValidatorResult
_createProjectValidatorError
(
String
name
,
String
value
)
{
return
ProjectValidatorResult
(
name:
name
,
value:
value
,
status:
StatusProjectValidator
.
error
);
}
}
packages/flutter_tools/test/general.shard/pub_dependencies_project_validator_test.dart
0 → 100644
View file @
cdf5b1d4
// 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/memory.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/project.dart'
;
import
'package:flutter_tools/src/project_validator.dart'
;
import
'package:flutter_tools/src/project_validator_result.dart'
;
import
'../src/common.dart'
;
import
'../src/context.dart'
;
void
main
(
)
{
late
FileSystem
fileSystem
;
group
(
'PubDependenciesProjectValidator'
,
()
{
setUp
(()
{
fileSystem
=
MemoryFileSystem
.
test
();
});
testWithoutContext
(
'success when all dependencies are hosted'
,
()
async
{
final
ProcessManager
processManager
=
FakeProcessManager
.
list
(<
FakeCommand
>[
const
FakeCommand
(
command:
<
String
>[
'dart'
,
'pub'
,
'deps'
,
'--json'
],
stdout:
'{"packages": [{"dependencies": ["abc"], "source": "hosted"}]}'
,
),
]);
final
PubDependenciesProjectValidator
validator
=
PubDependenciesProjectValidator
(
processManager
);
final
List
<
ProjectValidatorResult
>
result
=
await
validator
.
start
(
FlutterProject
.
fromDirectoryTest
(
fileSystem
.
currentDirectory
)
);
const
String
expected
=
'All pub dependencies are hosted on https://pub.dartlang.org'
;
expect
(
result
.
length
,
1
);
expect
(
result
[
0
].
value
,
expected
);
expect
(
result
[
0
].
status
,
StatusProjectValidator
.
success
);
});
testWithoutContext
(
'error when command dart pub deps fails'
,
()
async
{
final
ProcessManager
processManager
=
FakeProcessManager
.
list
(<
FakeCommand
>[
const
FakeCommand
(
command:
<
String
>[
'dart'
,
'pub'
,
'deps'
,
'--json'
],
stderr:
'command fail'
,
),
]);
final
PubDependenciesProjectValidator
validator
=
PubDependenciesProjectValidator
(
processManager
);
final
List
<
ProjectValidatorResult
>
result
=
await
validator
.
start
(
FlutterProject
.
fromDirectoryTest
(
fileSystem
.
currentDirectory
)
);
const
String
expected
=
'command fail'
;
expect
(
result
.
length
,
1
);
expect
(
result
[
0
].
value
,
expected
);
expect
(
result
[
0
].
status
,
StatusProjectValidator
.
error
);
});
testWithoutContext
(
'warning on dependencies not hosted'
,
()
async
{
final
ProcessManager
processManager
=
FakeProcessManager
.
list
(<
FakeCommand
>[
const
FakeCommand
(
command:
<
String
>[
'dart'
,
'pub'
,
'deps'
,
'--json'
],
stdout:
'{"packages": [{"dependencies": ["dep1", "dep2"], "source": "other"}]}'
,
),
]);
final
PubDependenciesProjectValidator
validator
=
PubDependenciesProjectValidator
(
processManager
);
final
List
<
ProjectValidatorResult
>
result
=
await
validator
.
start
(
FlutterProject
.
fromDirectoryTest
(
fileSystem
.
currentDirectory
)
);
const
String
expected
=
'dep1, dep2 are not hosted'
;
expect
(
result
.
length
,
1
);
expect
(
result
[
0
].
value
,
expected
);
expect
(
result
[
0
].
status
,
StatusProjectValidator
.
warning
);
});
});
}
packages/flutter_tools/test/integration.shard/analyze_suggestions_integration_test.dart
View file @
cdf5b1d4
...
...
@@ -54,5 +54,36 @@ void main() {
expect
(
loggerTest
.
statusText
,
contains
(
expected
));
});
testUsingContext
(
'PubDependenciesProjectValidator success '
,
()
async
{
final
BufferLogger
loggerTest
=
BufferLogger
.
test
();
final
AnalyzeCommand
command
=
AnalyzeCommand
(
artifacts:
globals
.
artifacts
!,
fileSystem:
fileSystem
,
logger:
loggerTest
,
platform:
globals
.
platform
,
terminal:
globals
.
terminal
,
processManager:
globals
.
processManager
,
allProjectValidators:
<
ProjectValidator
>[
PubDependenciesProjectValidator
(
globals
.
processManager
),
],
);
final
CommandRunner
<
void
>
runner
=
createTestCommandRunner
(
command
);
await
runner
.
run
(<
String
>[
'analyze'
,
'--no-pub'
,
'--no-current-package'
,
'--suggestions'
,
'../../dev/integration_tests/flutter_gallery'
,
]);
const
String
expected
=
'
\n
'
'┌────────────────────────────────────────────────────────────────────────────────────┐
\n
'
'│ Pub dependencies │
\n
'
'│ [✓] Dart dependencies: All pub dependencies are hosted on https://pub.dartlang.org │
\n
'
'└────────────────────────────────────────────────────────────────────────────────────┘
\n
'
;
expect
(
loggerTest
.
statusText
,
contains
(
expected
));
});
});
}
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