From 6b97f58e8d5f23f89f2586cb1cdbf408f1f35463 Mon Sep 17 00:00:00 2001 From: Michael Goderbauer Date: Thu, 11 May 2017 16:12:45 -0700 Subject: [PATCH 1/2] Added Travis --- .travis.yml | 82 +++++++++++++++++ README.md | 2 + scripts/.gitignore | 1 + scripts/cli.dart | 215 +++++++++++++++++++++++++++++++++++++++++++ scripts/pubspec.yaml | 6 ++ 5 files changed, 306 insertions(+) create mode 100644 .travis.yml create mode 100644 scripts/.gitignore create mode 100644 scripts/cli.dart create mode 100644 scripts/pubspec.yaml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000000..1e81ba8d0ed0 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,82 @@ +matrix: + include: + - os: linux + jdk: oraclejdk8 + sudo: false + addons: + apt: + # Flutter depends on /usr/lib/x86_64-linux-gnu/libstdc++.so.6 version GLIBCXX_3.4.18 + sources: + - ubuntu-toolchain-r-test # if we don't specify this, the libstdc++6 we get is the wrong version + - llvm-toolchain-precise # for clang-format-5.0 + packages: + - libstdc++6 + - fonts-droid + - clang-format-5.0 + before_script: + - git clone https://github.com/flutter/flutter.git --depth 1 + - ./flutter/bin/flutter doctor + - export PATH=`pwd`/flutter/bin:`pwd`/flutter/bin/cache/dart-sdk/bin:$PATH + - (cd scripts; ../flutter/bin/cache/dart-sdk/bin/pub get) + script: + - dart scripts/cli.dart format --travis --clang-format=clang-format-5.0 + - dart scripts/cli.dart test + - os: linux + language: android + licenses: + - 'android-sdk-preview-license-.+' + - 'android-sdk-license-.+' + - 'google-gdk-license-.+' + android: + components: + - tools + - platform-tools + - build-tools-25.0.3 + - android-25 + - sys-img-armeabi-v7a-google_apis-25 + - extra-android-m2repository + - extra-google-m2repository + - extra-google-android-support + jdk: oraclejdk8 + sudo: false + addons: + apt: + # Flutter depends on /usr/lib/x86_64-linux-gnu/libstdc++.so.6 version GLIBCXX_3.4.18 + sources: + - ubuntu-toolchain-r-test # if we don't specify this, the libstdc++6 we get is the wrong version + packages: + - libstdc++6 + - fonts-droid + before_script: + - wget http://services.gradle.org/distributions/gradle-3.5-bin.zip + - unzip -qq gradle-3.5-bin.zip + - export GRADLE_HOME=$PWD/gradle-3.5 + - export PATH=$GRADLE_HOME/bin:$PATH + - gradle -v + - android list targets + - echo no | android create avd --force -n test -t android-25 --abi armeabi-v7a --tag google_apis + - git clone https://github.com/flutter/flutter.git --depth 1 + - ./flutter/bin/flutter doctor + - export PATH=`pwd`/flutter/bin:`pwd`/flutter/bin/cache/dart-sdk/bin:$PATH + - (cd scripts; ../flutter/bin/cache/dart-sdk/bin/pub get) + script: + - dart scripts/cli.dart build --apk + - os: osx + language: generic + osx_image: xcode8.3 + before_script: + - pip install six + - brew update + - brew install --HEAD libimobiledevice + - brew install ideviceinstaller + - brew install ios-deploy + - git clone https://github.com/flutter/flutter.git --depth 1 + - ./flutter/bin/flutter doctor + - export PATH=`pwd`/flutter/bin:`pwd`/flutter/bin/cache/dart-sdk/bin:$PATH + - (cd scripts; ../flutter/bin/cache/dart-sdk/bin/pub get) + script: + - dart scripts/cli.dart build --ipa + +cache: + directories: + - $HOME/.pub-cache diff --git a/README.md b/README.md index bb851287fcd9..75167d49640f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Flutter plugins +[![Build Status](https://travis-ci.org/flutter/plugins.svg?branch=master)](https://travis-ci.org/flutter/plugins) + This repo is a companion repo to the main [flutter repo](https://github.com/flutter/flutter). It contains the source code for Flutter first-party plugins. Check the `packages` directory for all plugins. diff --git a/scripts/.gitignore b/scripts/.gitignore new file mode 100644 index 000000000000..54bcef3ee712 --- /dev/null +++ b/scripts/.gitignore @@ -0,0 +1 @@ +google-java-format-1.3-all-deps.jar diff --git a/scripts/cli.dart b/scripts/cli.dart new file mode 100644 index 000000000000..d3fc8133e7d7 --- /dev/null +++ b/scripts/cli.dart @@ -0,0 +1,215 @@ +// Copyright 2017 The Chromium 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:async'; +import 'dart:io'; +import 'dart:convert'; + +import 'package:args/command_runner.dart'; +import 'package:path/path.dart' as p; +import 'package:http/http.dart' as http; + +void main(List args) { + Directory packagesDir = new Directory( + p.join(p.dirname(p.dirname(p.fromUri(Platform.script))), 'packages')); + + new CommandRunner('cli', 'Various productivity utils.') + ..addCommand(new TestCommand(packagesDir)) + ..addCommand(new AnalyzeCommand(packagesDir)) + ..addCommand(new FormatCommand(packagesDir)) + ..addCommand(new BuildCommand(packagesDir)) + ..run(args); +} + +class TestCommand extends Command { + TestCommand(this.packagesDir); + + final Directory packagesDir; + + final name = 'test'; + final description = 'Runs the tests for all packages.'; + + Future run() async { + List failingPackages = []; + for (Directory packageDir in _listAllPackages(packagesDir)) { + String packageName = p.relative(packageDir.path, from: packagesDir.path); + if (!new Directory(p.join(packageDir.path, 'test')).existsSync()) { + print('\nSKIPPING $packageName - no test subdirectory'); + continue; + } + + print('\nRUNNING $packageName tests...'); + Process process = await Process.start('flutter', ['test', '--color'], + workingDirectory: packageDir.path); + stdout.addStream(process.stdout); + stderr.addStream(process.stderr); + if (await process.exitCode != 0) { + failingPackages.add(packageName); + } + } + + print('\n\n'); + if (failingPackages.isNotEmpty) { + print('Tests for the following packages are failing (see above):'); + failingPackages.forEach((String package) { + print(' * $package'); + }); + } else { + print('All tests are passing!'); + } + exit(failingPackages.length); + } + + Iterable _listAllPackages(Directory root) => root + .listSync(recursive: true) + .where((FileSystemEntity entity) => + entity is File && p.basename(entity.path) == 'pubspec.yaml') + .map((FileSystemEntity entity) => entity.parent); +} + +class AnalyzeCommand extends Command { + AnalyzeCommand(this.packagesDir); + + final Directory packagesDir; + + final name = 'analyze'; + final description = 'Analyzes all packages.'; + + Future run() async { + print('TODO(goderbauer): Implement command when ' + 'https://github.com/flutter/flutter/issues/10015 is resolved.'); + exit(1); + } +} + +class FormatCommand extends Command { + FormatCommand(this.packagesDir) { + argParser.addFlag('travis', hide: true); + argParser.addOption('clang-format', defaultsTo: 'clang-format'); + } + + final Directory packagesDir; + + final name = 'format'; + final description = 'Formats the code of all packages.'; + + Future run() async { + String javaFormatterPath = p.join(p.dirname(p.fromUri(Platform.script)), + 'google-java-format-1.3-all-deps.jar'); + File javaFormatterFile = new File(javaFormatterPath); + + if (!javaFormatterFile.existsSync()) { + print('Downloading Google Java Format...'); + http.Response response = await http.get( + 'https://github.com/google/google-java-format/releases/download/google-java-format-1.3/google-java-format-1.3-all-deps.jar'); + javaFormatterFile.writeAsBytesSync(response.bodyBytes); + } + + print('Formatting all .dart files...'); + Process.runSync('flutter', ['format'], workingDirectory: packagesDir.path); + + print('Formatting all .java files...'); + Iterable javaFiles = _getFilesWithExtension(packagesDir, '.java'); + Process.runSync( + 'java', ['-jar', javaFormatterPath, '--replace']..addAll(javaFiles), + workingDirectory: packagesDir.path); + + print('Formatting all .m and .h files...'); + Iterable hFiles = _getFilesWithExtension(packagesDir, '.h'); + Iterable mFiles = _getFilesWithExtension(packagesDir, '.m'); + Process.runSync(argResults['clang-format'], + ['-i', '--style=Google']..addAll(hFiles)..addAll(mFiles), + workingDirectory: packagesDir.path); + + if (argResults['travis']) { + ProcessResult modifiedFiles = Process.runSync( + 'git', ['ls-files', '--modified'], + workingDirectory: packagesDir.path); + print('\n\n'); + if (modifiedFiles.stdout.isNotEmpty) { + ProcessResult diff = Process.runSync('git', ['diff', '--color'], + workingDirectory: packagesDir.path); + print(diff.stdout); + + print('These files are not formatted correctly (see diff above):'); + LineSplitter + .split(modifiedFiles.stdout) + .map((String line) => ' $line') + .forEach(print); + print('\nTo fix run "pub get && dart cli.dart format" inside scripts/'); + exit(1); + } else { + print('All files formatted correctly.'); + exit(0); + } + } + } + + Iterable _getFilesWithExtension(Directory dir, String extension) => + dir + .listSync(recursive: true) + .where((FileSystemEntity entity) => + entity is File && p.extension(entity.path) == extension) + .map((FileSystemEntity entity) => entity.path); +} + +class BuildCommand extends Command { + BuildCommand(this.packagesDir) { + argParser.addFlag('ipa', defaultsTo: Platform.isMacOS); + argParser.addFlag('apk'); + } + + final Directory packagesDir; + + final name = 'build'; + final description = 'Builds all example apps.'; + + Future run() async { + List failingPackages = []; + for (Directory example in _getExamplePackages(packagesDir)) { + String packageName = p.relative(example.path, from: packagesDir.path); + + if (argResults['ipa']) { + print('\nBUILDING IPA for $packageName'); + Process process = await Process.start( + 'flutter', ['build', 'ios', '--no-codesign'], + workingDirectory: example.path); + stdout.addStream(process.stdout); + stderr.addStream(process.stderr); + if (await process.exitCode != 0) { + failingPackages.add('$packageName (ipa)'); + } + } + + if (argResults['apk']) { + print('\nBUILDING APK for $packageName'); + Process process = await Process.start('flutter', ['build', 'apk'], + workingDirectory: example.path); + stdout.addStream(process.stdout); + stderr.addStream(process.stderr); + if (await process.exitCode != 0) { + failingPackages.add('$packageName (apk)'); + } + } + } + + print('\n\n'); + if (failingPackages.isNotEmpty) { + print('The following build are failing (see above for details):'); + failingPackages.forEach((String package) { + print(' * $package'); + }); + } else { + print('All builds successful!'); + } + exit(failingPackages.length); + } + + Iterable _getExamplePackages(Directory dir) => dir + .listSync(recursive: true) + .where((FileSystemEntity entity) => + entity is Directory && p.basename(entity.path) == 'example') + .where((Directory dir) => dir.listSync().any((FileSystemEntity entity) => + entity is File && p.basename(entity.path) == 'pubspec.yaml')); +} diff --git a/scripts/pubspec.yaml b/scripts/pubspec.yaml new file mode 100644 index 000000000000..77676ba327ad --- /dev/null +++ b/scripts/pubspec.yaml @@ -0,0 +1,6 @@ +name: scripts + +dependencies: + args: "^0.13.7" + path: "^1.4.1" + http: "^0.11.3+13" From 315cb74790cde806110a2fdbad5ad614ce5293a1 Mon Sep 17 00:00:00 2001 From: Michael Goderbauer Date: Fri, 12 May 2017 15:35:49 -0700 Subject: [PATCH 2/2] update to use flutter_plugin_tools --- .travis.yml | 14 +-- scripts/.gitignore | 1 - scripts/cli.dart | 215 ------------------------------------------- scripts/pubspec.yaml | 6 -- 4 files changed, 7 insertions(+), 229 deletions(-) delete mode 100644 scripts/.gitignore delete mode 100644 scripts/cli.dart delete mode 100644 scripts/pubspec.yaml diff --git a/.travis.yml b/.travis.yml index 1e81ba8d0ed0..d43312a7cfbd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,10 +17,10 @@ matrix: - git clone https://github.com/flutter/flutter.git --depth 1 - ./flutter/bin/flutter doctor - export PATH=`pwd`/flutter/bin:`pwd`/flutter/bin/cache/dart-sdk/bin:$PATH - - (cd scripts; ../flutter/bin/cache/dart-sdk/bin/pub get) + - ./flutter/bin/cache/dart-sdk/bin/pub global activate flutter_plugin_tools script: - - dart scripts/cli.dart format --travis --clang-format=clang-format-5.0 - - dart scripts/cli.dart test + - pub global run flutter_plugin_tools format --travis --clang-format=clang-format-5.0 + - pub global run flutter_plugin_tools test - os: linux language: android licenses: @@ -58,9 +58,9 @@ matrix: - git clone https://github.com/flutter/flutter.git --depth 1 - ./flutter/bin/flutter doctor - export PATH=`pwd`/flutter/bin:`pwd`/flutter/bin/cache/dart-sdk/bin:$PATH - - (cd scripts; ../flutter/bin/cache/dart-sdk/bin/pub get) + - ./flutter/bin/cache/dart-sdk/bin/pub global activate flutter_plugin_tools script: - - dart scripts/cli.dart build --apk + - pub global run flutter_plugin_tools build --apk - os: osx language: generic osx_image: xcode8.3 @@ -73,9 +73,9 @@ matrix: - git clone https://github.com/flutter/flutter.git --depth 1 - ./flutter/bin/flutter doctor - export PATH=`pwd`/flutter/bin:`pwd`/flutter/bin/cache/dart-sdk/bin:$PATH - - (cd scripts; ../flutter/bin/cache/dart-sdk/bin/pub get) + - ./flutter/bin/cache/dart-sdk/bin/pub global activate flutter_plugin_tools script: - - dart scripts/cli.dart build --ipa + - pub global run flutter_plugin_tools build --ipa cache: directories: diff --git a/scripts/.gitignore b/scripts/.gitignore deleted file mode 100644 index 54bcef3ee712..000000000000 --- a/scripts/.gitignore +++ /dev/null @@ -1 +0,0 @@ -google-java-format-1.3-all-deps.jar diff --git a/scripts/cli.dart b/scripts/cli.dart deleted file mode 100644 index d3fc8133e7d7..000000000000 --- a/scripts/cli.dart +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright 2017 The Chromium 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:async'; -import 'dart:io'; -import 'dart:convert'; - -import 'package:args/command_runner.dart'; -import 'package:path/path.dart' as p; -import 'package:http/http.dart' as http; - -void main(List args) { - Directory packagesDir = new Directory( - p.join(p.dirname(p.dirname(p.fromUri(Platform.script))), 'packages')); - - new CommandRunner('cli', 'Various productivity utils.') - ..addCommand(new TestCommand(packagesDir)) - ..addCommand(new AnalyzeCommand(packagesDir)) - ..addCommand(new FormatCommand(packagesDir)) - ..addCommand(new BuildCommand(packagesDir)) - ..run(args); -} - -class TestCommand extends Command { - TestCommand(this.packagesDir); - - final Directory packagesDir; - - final name = 'test'; - final description = 'Runs the tests for all packages.'; - - Future run() async { - List failingPackages = []; - for (Directory packageDir in _listAllPackages(packagesDir)) { - String packageName = p.relative(packageDir.path, from: packagesDir.path); - if (!new Directory(p.join(packageDir.path, 'test')).existsSync()) { - print('\nSKIPPING $packageName - no test subdirectory'); - continue; - } - - print('\nRUNNING $packageName tests...'); - Process process = await Process.start('flutter', ['test', '--color'], - workingDirectory: packageDir.path); - stdout.addStream(process.stdout); - stderr.addStream(process.stderr); - if (await process.exitCode != 0) { - failingPackages.add(packageName); - } - } - - print('\n\n'); - if (failingPackages.isNotEmpty) { - print('Tests for the following packages are failing (see above):'); - failingPackages.forEach((String package) { - print(' * $package'); - }); - } else { - print('All tests are passing!'); - } - exit(failingPackages.length); - } - - Iterable _listAllPackages(Directory root) => root - .listSync(recursive: true) - .where((FileSystemEntity entity) => - entity is File && p.basename(entity.path) == 'pubspec.yaml') - .map((FileSystemEntity entity) => entity.parent); -} - -class AnalyzeCommand extends Command { - AnalyzeCommand(this.packagesDir); - - final Directory packagesDir; - - final name = 'analyze'; - final description = 'Analyzes all packages.'; - - Future run() async { - print('TODO(goderbauer): Implement command when ' - 'https://github.com/flutter/flutter/issues/10015 is resolved.'); - exit(1); - } -} - -class FormatCommand extends Command { - FormatCommand(this.packagesDir) { - argParser.addFlag('travis', hide: true); - argParser.addOption('clang-format', defaultsTo: 'clang-format'); - } - - final Directory packagesDir; - - final name = 'format'; - final description = 'Formats the code of all packages.'; - - Future run() async { - String javaFormatterPath = p.join(p.dirname(p.fromUri(Platform.script)), - 'google-java-format-1.3-all-deps.jar'); - File javaFormatterFile = new File(javaFormatterPath); - - if (!javaFormatterFile.existsSync()) { - print('Downloading Google Java Format...'); - http.Response response = await http.get( - 'https://github.com/google/google-java-format/releases/download/google-java-format-1.3/google-java-format-1.3-all-deps.jar'); - javaFormatterFile.writeAsBytesSync(response.bodyBytes); - } - - print('Formatting all .dart files...'); - Process.runSync('flutter', ['format'], workingDirectory: packagesDir.path); - - print('Formatting all .java files...'); - Iterable javaFiles = _getFilesWithExtension(packagesDir, '.java'); - Process.runSync( - 'java', ['-jar', javaFormatterPath, '--replace']..addAll(javaFiles), - workingDirectory: packagesDir.path); - - print('Formatting all .m and .h files...'); - Iterable hFiles = _getFilesWithExtension(packagesDir, '.h'); - Iterable mFiles = _getFilesWithExtension(packagesDir, '.m'); - Process.runSync(argResults['clang-format'], - ['-i', '--style=Google']..addAll(hFiles)..addAll(mFiles), - workingDirectory: packagesDir.path); - - if (argResults['travis']) { - ProcessResult modifiedFiles = Process.runSync( - 'git', ['ls-files', '--modified'], - workingDirectory: packagesDir.path); - print('\n\n'); - if (modifiedFiles.stdout.isNotEmpty) { - ProcessResult diff = Process.runSync('git', ['diff', '--color'], - workingDirectory: packagesDir.path); - print(diff.stdout); - - print('These files are not formatted correctly (see diff above):'); - LineSplitter - .split(modifiedFiles.stdout) - .map((String line) => ' $line') - .forEach(print); - print('\nTo fix run "pub get && dart cli.dart format" inside scripts/'); - exit(1); - } else { - print('All files formatted correctly.'); - exit(0); - } - } - } - - Iterable _getFilesWithExtension(Directory dir, String extension) => - dir - .listSync(recursive: true) - .where((FileSystemEntity entity) => - entity is File && p.extension(entity.path) == extension) - .map((FileSystemEntity entity) => entity.path); -} - -class BuildCommand extends Command { - BuildCommand(this.packagesDir) { - argParser.addFlag('ipa', defaultsTo: Platform.isMacOS); - argParser.addFlag('apk'); - } - - final Directory packagesDir; - - final name = 'build'; - final description = 'Builds all example apps.'; - - Future run() async { - List failingPackages = []; - for (Directory example in _getExamplePackages(packagesDir)) { - String packageName = p.relative(example.path, from: packagesDir.path); - - if (argResults['ipa']) { - print('\nBUILDING IPA for $packageName'); - Process process = await Process.start( - 'flutter', ['build', 'ios', '--no-codesign'], - workingDirectory: example.path); - stdout.addStream(process.stdout); - stderr.addStream(process.stderr); - if (await process.exitCode != 0) { - failingPackages.add('$packageName (ipa)'); - } - } - - if (argResults['apk']) { - print('\nBUILDING APK for $packageName'); - Process process = await Process.start('flutter', ['build', 'apk'], - workingDirectory: example.path); - stdout.addStream(process.stdout); - stderr.addStream(process.stderr); - if (await process.exitCode != 0) { - failingPackages.add('$packageName (apk)'); - } - } - } - - print('\n\n'); - if (failingPackages.isNotEmpty) { - print('The following build are failing (see above for details):'); - failingPackages.forEach((String package) { - print(' * $package'); - }); - } else { - print('All builds successful!'); - } - exit(failingPackages.length); - } - - Iterable _getExamplePackages(Directory dir) => dir - .listSync(recursive: true) - .where((FileSystemEntity entity) => - entity is Directory && p.basename(entity.path) == 'example') - .where((Directory dir) => dir.listSync().any((FileSystemEntity entity) => - entity is File && p.basename(entity.path) == 'pubspec.yaml')); -} diff --git a/scripts/pubspec.yaml b/scripts/pubspec.yaml deleted file mode 100644 index 77676ba327ad..000000000000 --- a/scripts/pubspec.yaml +++ /dev/null @@ -1,6 +0,0 @@ -name: scripts - -dependencies: - args: "^0.13.7" - path: "^1.4.1" - http: "^0.11.3+13"