Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit a0d5b85

Browse files
committed
Added cli
1 parent 21c6300 commit a0d5b85

File tree

4 files changed

+308
-0
lines changed

4 files changed

+308
-0
lines changed

.travis.yml

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
matrix:
2+
include:
3+
- os: linux
4+
jdk: oraclejdk8
5+
sudo: false
6+
addons:
7+
apt:
8+
# Flutter depends on /usr/lib/x86_64-linux-gnu/libstdc++.so.6 version GLIBCXX_3.4.18
9+
sources:
10+
- ubuntu-toolchain-r-test # if we don't specify this, the libstdc++6 we get is the wrong version
11+
- llvm-toolchain-precise # for clang-format-5.0
12+
packages:
13+
- libstdc++6
14+
- fonts-droid
15+
- clang-format-5.0
16+
before_script:
17+
- git clone https://github.com/flutter/flutter.git --depth 1
18+
- ./flutter/bin/flutter doctor
19+
- export PATH=`pwd`/flutter/bin:`pwd`/flutter/bin/cache/dart-sdk/bin:$PATH
20+
- (cd scripts; ../flutter/bin/cache/dart-sdk/bin/pub get)
21+
script:
22+
- dart scripts/cli.dart format --travis --clang-format=clang-format-5.0
23+
- dart scripts/cli.dart test
24+
- os: linux
25+
language: android
26+
licenses:
27+
- 'android-sdk-preview-license-.+'
28+
- 'android-sdk-license-.+'
29+
- 'google-gdk-license-.+'
30+
android:
31+
components:
32+
- tools
33+
- platform-tools
34+
- build-tools-25.0.3
35+
- android-25
36+
- sys-img-armeabi-v7a-google_apis-25
37+
- extra-android-m2repository
38+
- extra-google-m2repository
39+
- extra-google-android-support
40+
jdk: oraclejdk8
41+
sudo: false
42+
addons:
43+
apt:
44+
# Flutter depends on /usr/lib/x86_64-linux-gnu/libstdc++.so.6 version GLIBCXX_3.4.18
45+
sources:
46+
- ubuntu-toolchain-r-test # if we don't specify this, the libstdc++6 we get is the wrong version
47+
packages:
48+
- libstdc++6
49+
- fonts-droid
50+
before_script:
51+
- wget http://services.gradle.org/distributions/gradle-3.5-bin.zip
52+
- unzip -qq gradle-3.5-bin.zip
53+
- export GRADLE_HOME=$PWD/gradle-3.5
54+
- export PATH=$GRADLE_HOME/bin:$PATH
55+
- gradle -v
56+
- android list targets
57+
- echo no | android create avd --force -n test -t android-25 --abi armeabi-v7a --tag google_apis
58+
- git clone https://github.com/flutter/flutter.git --depth 1
59+
- ./flutter/bin/flutter doctor
60+
- export PATH=`pwd`/flutter/bin:`pwd`/flutter/bin/cache/dart-sdk/bin:$PATH
61+
- (cd scripts; ../flutter/bin/cache/dart-sdk/bin/pub get)
62+
script:
63+
- dart scripts/cli.dart build --apk
64+
- os: osx
65+
language: generic
66+
osx_image: xcode8.3
67+
before_script:
68+
- pip install six
69+
- brew update
70+
- brew install --HEAD libimobiledevice
71+
- brew install ideviceinstaller
72+
- brew install ios-deploy
73+
- git clone https://github.com/flutter/flutter.git --depth 1
74+
- ./flutter/bin/flutter doctor
75+
- export PATH=`pwd`/flutter/bin:`pwd`/flutter/bin/cache/dart-sdk/bin:$PATH
76+
- (cd scripts; ../flutter/bin/cache/dart-sdk/bin/pub get)
77+
script:
78+
- dart scripts/cli.dart build --ipa
79+
80+
cache:
81+
directories:
82+
- $HOME/.pub-cache

scripts/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
google-java-format-1.3-all-deps.jar

scripts/cli.dart

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
// Copyright 2017 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:async';
6+
import 'dart:io';
7+
import 'dart:convert';
8+
9+
import 'package:args/command_runner.dart';
10+
import 'package:path/path.dart' as p;
11+
import 'package:http/http.dart' as http;
12+
13+
void main(List<String> args) {
14+
Directory packagesDir = new Directory(
15+
p.join(p.dirname(p.dirname(p.fromUri(Platform.script))), 'packages'));
16+
17+
new CommandRunner('cli', 'Various productivity utils.')
18+
..addCommand(new TestCommand(packagesDir))
19+
..addCommand(new AnalyzeCommand(packagesDir))
20+
..addCommand(new FormatCommand(packagesDir))
21+
..addCommand(new BuildCommand(packagesDir))
22+
..run(args);
23+
}
24+
25+
class TestCommand extends Command {
26+
TestCommand(this.packagesDir);
27+
28+
final Directory packagesDir;
29+
30+
final name = 'test';
31+
final description = 'Runs the tests for all packages.';
32+
33+
Future run() async {
34+
List<String> failingPackages = <String>[];
35+
for (Directory packageDir in _listAllPackages(packagesDir)) {
36+
String packageName = p.relative(packageDir.path, from: packagesDir.path);
37+
if (!new Directory(p.join(packageDir.path, 'test')).existsSync()) {
38+
print('\nSKIPPING $packageName - no test subdirectory');
39+
continue;
40+
}
41+
42+
print('\nRUNNING $packageName tests...');
43+
Process process = await Process.start('flutter', ['test', '--color'],
44+
workingDirectory: packageDir.path);
45+
stdout.addStream(process.stdout);
46+
stderr.addStream(process.stderr);
47+
if (await process.exitCode != 0) {
48+
failingPackages.add(packageName);
49+
}
50+
}
51+
52+
print('\n\n');
53+
if (failingPackages.isNotEmpty) {
54+
print('Tests for the following packages are failing (see above):');
55+
failingPackages.forEach((String package) {
56+
print(' * $package');
57+
});
58+
} else {
59+
print('All tests are passing!');
60+
}
61+
exit(failingPackages.length);
62+
}
63+
64+
Iterable<Directory> _listAllPackages(Directory root) => root
65+
.listSync(recursive: true)
66+
.where((FileSystemEntity entity) =>
67+
entity is File && p.basename(entity.path) == 'pubspec.yaml')
68+
.map((FileSystemEntity entity) => entity.parent);
69+
}
70+
71+
class AnalyzeCommand extends Command {
72+
AnalyzeCommand(this.packagesDir);
73+
74+
final Directory packagesDir;
75+
76+
final name = 'analyze';
77+
final description = 'Analyzes all packages.';
78+
79+
Future run() async {
80+
print('TODO(goderbauer): Implement command when '
81+
'https://github.com/flutter/flutter/issues/10015 is resolved.');
82+
exit(1);
83+
}
84+
}
85+
86+
class FormatCommand extends Command {
87+
FormatCommand(this.packagesDir) {
88+
argParser.addFlag('travis', hide: true);
89+
argParser.addOption('clang-format', defaultsTo: 'clang-format');
90+
}
91+
92+
final Directory packagesDir;
93+
94+
final name = 'format';
95+
final description = 'Formats the code of all packages.';
96+
97+
Future run() async {
98+
String javaFormatterPath = p.join(p.dirname(p.fromUri(Platform.script)),
99+
'google-java-format-1.3-all-deps.jar');
100+
File javaFormatterFile = new File(javaFormatterPath);
101+
102+
if (!javaFormatterFile.existsSync()) {
103+
print('Downloading Google Java Format...');
104+
http.Response response = await http.get(
105+
'https://github.com/google/google-java-format/releases/download/google-java-format-1.3/google-java-format-1.3-all-deps.jar');
106+
javaFormatterFile.writeAsBytesSync(response.bodyBytes);
107+
}
108+
109+
print('Formatting all .dart files...');
110+
Process.runSync('flutter', ['format'], workingDirectory: packagesDir.path);
111+
112+
print('Formatting all .java files...');
113+
Iterable<String> javaFiles = _getFilesWithExtension(packagesDir, '.java');
114+
Process.runSync(
115+
'java', ['-jar', javaFormatterPath, '--replace']..addAll(javaFiles),
116+
workingDirectory: packagesDir.path);
117+
118+
print('Formatting all .m and .h files...');
119+
Iterable<String> hFiles = _getFilesWithExtension(packagesDir, '.h');
120+
Iterable<String> mFiles = _getFilesWithExtension(packagesDir, '.m');
121+
Process.runSync(argResults['clang-format'],
122+
['-i', '--style=Google']..addAll(hFiles)..addAll(mFiles),
123+
workingDirectory: packagesDir.path);
124+
125+
if (argResults['travis']) {
126+
ProcessResult modifiedFiles = Process.runSync(
127+
'git', ['ls-files', '--modified'],
128+
workingDirectory: packagesDir.path);
129+
print('\n\n');
130+
if (modifiedFiles.stdout.isNotEmpty) {
131+
ProcessResult diff = Process.runSync('git', ['diff', '--color'],
132+
workingDirectory: packagesDir.path);
133+
print(diff.stdout);
134+
135+
print('These files are not formatted correctly (see diff above):');
136+
LineSplitter
137+
.split(modifiedFiles.stdout)
138+
.map((String line) => ' $line')
139+
.forEach(print);
140+
print('\nTo fix run "pub get && dart cli.dart format" inside scripts/');
141+
exit(1);
142+
} else {
143+
print('All files formatted correctly.');
144+
exit(0);
145+
}
146+
}
147+
}
148+
149+
Iterable<String> _getFilesWithExtension(Directory dir, String extension) =>
150+
dir
151+
.listSync(recursive: true)
152+
.where((FileSystemEntity entity) =>
153+
entity is File && p.extension(entity.path) == extension)
154+
.map((FileSystemEntity entity) => entity.path);
155+
}
156+
157+
class BuildCommand extends Command {
158+
BuildCommand(this.packagesDir) {
159+
argParser.addFlag('ipa', defaultsTo: Platform.isMacOS);
160+
argParser.addFlag('apk');
161+
}
162+
163+
final Directory packagesDir;
164+
165+
final name = 'build';
166+
final description = 'Builds all example apps.';
167+
168+
Future run() async {
169+
List<String> failingPackages = <String>[];
170+
for (Directory example in _getExamplePackages(packagesDir)) {
171+
String packageName = p.relative(example.path, from: packagesDir.path);
172+
173+
if (argResults['ipa']) {
174+
print('\nBUILDING IPA for $packageName');
175+
Process process = await Process.start(
176+
'flutter', ['build', 'ios', '--no-codesign'],
177+
workingDirectory: example.path);
178+
stdout.addStream(process.stdout);
179+
stderr.addStream(process.stderr);
180+
if (await process.exitCode != 0) {
181+
failingPackages.add('$packageName (ipa)');
182+
}
183+
} else {
184+
print('\nSkipping IPA for $packageName (run with --ipa to build this)');
185+
}
186+
187+
if (argResults['apk']) {
188+
print('\nBUILDING APK for $packageName');
189+
Process process = await Process.start('flutter', ['build', 'apk'],
190+
workingDirectory: example.path);
191+
stdout.addStream(process.stdout);
192+
stderr.addStream(process.stderr);
193+
if (await process.exitCode != 0) {
194+
failingPackages.add('$packageName (apk)');
195+
}
196+
} else {
197+
print('\nSkipping APK for $packageName (run with --apk to build this)');
198+
}
199+
}
200+
201+
print('\n\n');
202+
if (failingPackages.isNotEmpty) {
203+
print('The following build are failing (see above for details):');
204+
failingPackages.forEach((String package) {
205+
print(' * $package');
206+
});
207+
} else {
208+
print('All builds successful!');
209+
}
210+
exit(failingPackages.length);
211+
}
212+
213+
Iterable<Directory> _getExamplePackages(Directory dir) => dir
214+
.listSync(recursive: true)
215+
.where((FileSystemEntity entity) =>
216+
entity is Directory && p.basename(entity.path) == 'example')
217+
.where((Directory dir) => dir.listSync().any((FileSystemEntity entity) =>
218+
entity is File && p.basename(entity.path) == 'pubspec.yaml'));
219+
}

scripts/pubspec.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
name: scripts
2+
3+
dependencies:
4+
args: "^0.13.7"
5+
path: "^1.4.1"
6+
http: "^0.11.3+13"

0 commit comments

Comments
 (0)