-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
an implementation of the init command #293
Changes from all commits
270e15d
7f2defd
b4d8b7e
9e98a69
151bdc5
6841788
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,105 @@ | ||||||||||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file | ||||||||||
// for details. 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:io'; | ||||||||||
|
||||||||||
import 'package:args/command_runner.dart'; | ||||||||||
import 'package:io/ansi.dart'; | ||||||||||
import 'package:path/path.dart' as p; | ||||||||||
|
||||||||||
const _pubspecFileName = 'pubspec.yaml'; | ||||||||||
const _pkgCfgFileName = 'mono_pkg.yaml'; | ||||||||||
const _repoCfgFileName = 'mono_repo.yaml'; | ||||||||||
const _recursiveScanFlag = 'recursive'; | ||||||||||
|
||||||||||
const _repoCfgContents = r''' | ||||||||||
# See with https://github.com/dart-lang/mono_repo for details on this file | ||||||||||
self_validate: analyze_and_format | ||||||||||
|
||||||||||
github: | ||||||||||
# Setting just `cron` keeps the defaults for `push` and `pull_request` | ||||||||||
cron: '0 0 * * 0' | ||||||||||
on_completion: | ||||||||||
- name: "Notify failure" | ||||||||||
runs-on: ubuntu-latest | ||||||||||
# Run only if other jobs have failed and this is a push or scheduled build. | ||||||||||
if: (github.event_name == 'push' || github.event_name == 'schedule') && failure() | ||||||||||
steps: | ||||||||||
- run: > | ||||||||||
curl -H "Content-Type: application/json" -X POST -d \ | ||||||||||
"{'text':'Build failed! ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}'}" \ | ||||||||||
"${CHAT_WEBHOOK_URL}" | ||||||||||
env: | ||||||||||
CHAT_WEBHOOK_URL: ${{ secrets.BUILD_AND_TEST_TEAM_CHAT_WEBHOOK_URL }} | ||||||||||
|
||||||||||
merge_stages: | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
- analyze_and_format | ||||||||||
'''; | ||||||||||
|
||||||||||
const _pkgCfgContents = r''' | ||||||||||
dart: | ||||||||||
- dev | ||||||||||
- stable | ||||||||||
|
||||||||||
os: | ||||||||||
- linux | ||||||||||
|
||||||||||
stages: | ||||||||||
- analyze_and_format: | ||||||||||
- dartanalyzer: --fatal-infos --fatal-warnings . | ||||||||||
- dartfmt: sdk | ||||||||||
- unit_test: | ||||||||||
- test: | ||||||||||
'''; | ||||||||||
|
||||||||||
class InitCommand extends Command<void> { | ||||||||||
@override | ||||||||||
String get name => 'init'; | ||||||||||
|
||||||||||
@override | ||||||||||
String get description => 'Scaffold a new mono repo.'; | ||||||||||
|
||||||||||
@override | ||||||||||
void run() => scaffold(p.current, globalResults[_recursiveScanFlag] as bool); | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This command should use its own arg parser and then use |
||||||||||
} | ||||||||||
|
||||||||||
void scaffold(String rootDir, bool recursive) { | ||||||||||
configureDirectory(rootDir, recursive: recursive); | ||||||||||
} | ||||||||||
|
||||||||||
void configureDirectory(String rootDir, | ||||||||||
{String currentDir, bool recursive = false}) { | ||||||||||
currentDir ??= rootDir; | ||||||||||
|
||||||||||
if (currentDir == rootDir) { | ||||||||||
final repoCfgPath = p.join(rootDir, _repoCfgFileName); | ||||||||||
if (!File(repoCfgPath).existsSync()) { | ||||||||||
File(repoCfgPath).writeAsStringSync(_repoCfgContents); | ||||||||||
print(styleBold.wrap('Added $_repoCfgFileName to $rootDir')); | ||||||||||
} else { | ||||||||||
print(yellow.wrap('$_repoCfgFileName already present in $rootDir.')); | ||||||||||
} | ||||||||||
} else { | ||||||||||
final pkgCfgPath = p.join(currentDir, _pkgCfgFileName); | ||||||||||
final pubspecPath = p.join(currentDir, _pubspecFileName); | ||||||||||
|
||||||||||
if (File(pubspecPath).existsSync()) { | ||||||||||
if (!File(pkgCfgPath).existsSync()) { | ||||||||||
File(pkgCfgPath).writeAsStringSync(_pkgCfgContents); | ||||||||||
print(styleBold.wrap('Added $_pkgCfgFileName to $currentDir')); | ||||||||||
} else { | ||||||||||
print(yellow.wrap('$_pkgCfgFileName already present in $currentDir')); | ||||||||||
} | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
final subdirs = | ||||||||||
Directory(currentDir).listSync().whereType<Directory>().toList(); | ||||||||||
for (var subdir in subdirs) { | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am a bit on the fence about this behavior - especially in the case of pre-existing packages we wouldn't want to go creating a whole bunch of pubspecs in all nested packages. I am somewhat inclined to just not support this for the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we add the mono_pkg.yaml only to directories that already have a pubspec.yaml, we're assuming the user is never starting from scratch. And I was initially adding the mono_pkg.yaml file only to the immediate subdirectories of root. But directory structures such as root/pkgs/package1,package2 are common too, so doing it recursively seemed to make more sense. But this would add the files in the pkgs directory too, which would be wrong. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would be safest to add the mono_pkg.yaml only to directories that have a pubspec.yaml. |
||||||||||
if (recursive || currentDir == rootDir) { | ||||||||||
configureDirectory(rootDir, | ||||||||||
currentDir: subdir.path, recursive: recursive); | ||||||||||
} | ||||||||||
} | ||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import 'dart:io'; | ||
|
||
import 'package:path/path.dart' as p; | ||
import 'package:test/test.dart'; | ||
import 'package:test_descriptor/test_descriptor.dart' as d; | ||
|
||
import 'package:mono_repo/src/commands/init.dart'; | ||
|
||
void main() { | ||
const repoCfgFileName = 'mono_repo.yaml'; | ||
const pkgCfgFileName = 'mono_pkg.yaml'; | ||
|
||
test('scaffold a new mono repo', () async { | ||
await d.dir('top_level', [ | ||
d.dir('package1', [d.file('pubspec.yaml')]), | ||
d.dir('package2', [d.file('pubspec.yaml')]) | ||
]).create(); | ||
final rootDirectory = '${d.sandbox}/top_level'; | ||
final package1Directory = '${d.sandbox}/top_level/package1'; | ||
final package2Directory = '${d.sandbox}/top_level/package2'; | ||
|
||
final repoCfg = p.join(rootDirectory, repoCfgFileName); | ||
final pkg1Cfg = p.join(package1Directory, pkgCfgFileName); | ||
final pkg2Cfg = p.join(package2Directory, pkgCfgFileName); | ||
scaffold(rootDirectory, false); | ||
expect( | ||
File(repoCfg).existsSync() && | ||
File(pkg1Cfg).existsSync() && | ||
File(pkg2Cfg).existsSync(), | ||
equals(true)); | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section should be commented out, as it won't work without some repo level configuration and it is also specific to the expected payload for google chat webhooks and won't work for slack, etc.