Skip to content

Commit

Permalink
Move server code to devtools_server package (#539)
Browse files Browse the repository at this point in the history
* Move server code to devtools_server package
  • Loading branch information
kenzieschmoll authored Apr 16, 2019
1 parent 1bd61b7 commit 1efd6e0
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 109 deletions.
107 changes: 2 additions & 105 deletions packages/devtools/bin/devtools.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,111 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:convert';
import 'dart:io';
import 'dart:isolate';

import 'package:args/args.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
import 'package:shelf/shelf.dart' as shelf;
import 'package:shelf/shelf_io.dart' as shelf;
import 'package:shelf_static/shelf_static.dart';

const argHelp = 'help';
const argMachine = 'machine';
const argPort = 'port';

final argParser = new ArgParser()
..addFlag(
argHelp,
negatable: false,
abbr: 'h',
help: 'Prints help output.',
)
..addOption(
argPort,
defaultsTo: '9100',
abbr: 'p',
help: 'Port to serve DevTools on. '
'Pass 0 to automatically assign an available port.',
)
..addFlag(
argMachine,
negatable: false,
abbr: 'm',
help: 'Sets output format to JSON for consumption in tools.',
);
import 'package:devtools_server/devtools_server.dart';

void main(List<String> arguments) async {
final args = argParser.parse(arguments);
if (args[argHelp]) {
print('Dart DevTools version ${await _getVersion()}');
print('');
print('usage: devtools <options>');
print('');
print(argParser.usage);
return;
}

final bool machineMode = args[argMachine];
final port = args[argPort] != null ? int.tryParse(args[argPort]) ?? 0 : 0;

final Uri resourceUri = await Isolate.resolvePackageUri(
Uri(scheme: 'package', path: 'devtools/devtools.dart'));
final packageDir = path.dirname(path.dirname(resourceUri.toFilePath()));

// Default static handler for all non-package requests.
final String buildDir = path.join(packageDir, 'build');
final buildHandler =
createStaticHandler(buildDir, defaultDocument: 'index.html');

// The packages folder is renamed in the pub package so this handler serves
// out of the `pack` folder.
final String packagesDir = path.join(packageDir, 'build', 'pack');
final packHandler =
createStaticHandler(packagesDir, defaultDocument: 'index.html');

// Make a handler that delegates to the correct handler based on path.
final handler = (shelf.Request request) {
return request.url.path.startsWith('packages/')
// request.change here will strip the `packages` prefix from the path
// so it's relative to packHandler's root.
? packHandler(request.change(path: 'packages'))
: buildHandler(request);
};

final server = await shelf.serve(handler, '127.0.0.1', port);

printOutput(
'Serving DevTools at http://${server.address.host}:${server.port}',
{
'method': 'server.started',

This comment has been minimized.

Copy link
@DanTup

DanTup Apr 22, 2019

Contributor

@devoncarew I think I got this wrong, this one should be event not method? I'm gonna make VS Code tolerate both (((evt as any).method || evt.event)), it might make sense for IntelliJ to do the same so we can fix it in future?

This comment has been minimized.

Copy link
@devoncarew

devoncarew Apr 22, 2019

Member

Yup, that's correct. I just checked - we don't call that out in the daemon.md docs in flutter_tools, but should.

This comment has been minimized.

Copy link
@DanTup

DanTup Apr 22, 2019

Contributor

Ok, I'll add a note.

BTW, I tracked down the IntelliJ code here:

https://github.com/flutter/flutter-intellij/blob/e40af7df0b3d40888443a5fc218ee866a8eaf4ba/src/io/flutter/devtools/DevToolsManager.java#L170

Looks like you assume this is the only event, and don't actually check method or event, so I think it's only VS Code effected here. I think I could add event now (keeping method too, for compatibility with VS Code vCurrent) and remove it sometime after the next release?

This comment has been minimized.

Copy link
@devoncarew

devoncarew Apr 22, 2019

Member

Ah, yes, looks like we're only making very light use of the json protocol currently.

Having both fields, and later moving to just having event, sounds great.

This comment has been minimized.

Copy link
@DanTup

DanTup Apr 22, 2019

Contributor

I've added it to my open PR (#563) with a TODO to remove method later.

'params': {'host': server.address.host, 'port': server.port, 'pid': pid}
},
machineMode: machineMode,
);
}

Future<String> _getVersion() async {
final Uri resourceUri = await Isolate.resolvePackageUri(
Uri(scheme: 'package', path: 'devtools/devtools.dart'));
final String packageDir =
path.dirname(path.dirname(resourceUri.toFilePath()));
final File pubspecFile = File(path.join(packageDir, 'pubspec.yaml'));
final String versionLine =
pubspecFile.readAsLinesSync().firstWhere((String line) {
return line.startsWith('version: ');
}, orElse: () => null);
return versionLine == null
? 'unknown'
: versionLine.substring('version: '.length).trim();
}

void printOutput(
String message,
Object json, {
@required bool machineMode,
}) {
print(machineMode ? jsonEncode(json) : message);
serveDevToolsWithArgs(arguments);
}
6 changes: 2 additions & 4 deletions packages/devtools/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,17 @@ environment:
sdk: '>=2.2.0-dev <3.0.0'

dependencies:
args: ^1.5.1
codemirror: ^0.5.3
collection: ^1.14.11
devtools_server:
path: ../devtools_server
http: ^0.12.0+1
intl: ^0.15.0
js: ^0.6.1+1
meta: ^1.1.0
path: ^1.6.0
pedantic: ^1.4.0
platform_detect: ^1.3.5
rxdart: ^0.21.0
shelf: ^0.7.4
shelf_static: ^0.2.8
vm_service_lib: ^3.14.3-dev.4
# We would use local dependencies for these packages if pub publish allowed it.
octicons_css:
Expand Down
2 changes: 2 additions & 0 deletions packages/devtools_server/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Use the same analysis options that we use in package:devtools
include: package:devtools/analysis_options.yaml
5 changes: 5 additions & 0 deletions packages/devtools_server/lib/devtools_server.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright 2018 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.

export 'src/server.dart';
126 changes: 126 additions & 0 deletions packages/devtools_server/lib/src/server.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// Copyright 2019 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:convert';
import 'dart:io';
import 'dart:isolate';

import 'package:args/args.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
import 'package:shelf/shelf.dart' as shelf;
import 'package:shelf/shelf_io.dart' as shelf;
import 'package:shelf_static/shelf_static.dart';

const argHelp = 'help';
const argMachine = 'machine';
const argPort = 'port';

final argParser = new ArgParser()
..addFlag(
argHelp,
negatable: false,
abbr: 'h',
help: 'Prints help output.',
)
..addOption(
argPort,
defaultsTo: '9100',
abbr: 'p',
help: 'Port to serve DevTools on. '
'Pass 0 to automatically assign an available port.',
)
..addFlag(
argMachine,
negatable: false,
abbr: 'm',
help: 'Sets output format to JSON for consumption in tools.',
);

void serveDevToolsWithArgs(List<String> arguments) async {
final args = argParser.parse(arguments);

final help = args[argHelp];
final bool machineMode = args[argMachine];
final port = args[argPort] != null ? int.tryParse(args[argPort]) ?? 0 : 0;

serveDevTools(help: help, machineMode: machineMode, port: port);
}

void serveDevTools({
bool help = false,
bool machineMode = false,
int port = 0,
}) async {
if (help) {
print('Dart DevTools version ${await _getVersion()}');
print('');
print('usage: devtools <options>');
print('');
print(argParser.usage);
return;
}

final Uri resourceUri = await Isolate.resolvePackageUri(
Uri(scheme: 'package', path: 'devtools/devtools.dart'));
final packageDir = path.dirname(path.dirname(resourceUri.toFilePath()));

// Default static handler for all non-package requests.
final String buildDir = path.join(packageDir, 'build');
final buildHandler = createStaticHandler(
buildDir,
defaultDocument: 'index.html',
);

// The packages folder is renamed in the pub package so this handler serves
// out of the `pack` folder.
final String packagesDir = path.join(packageDir, 'build', 'pack');
final packHandler = createStaticHandler(
packagesDir,
defaultDocument: 'index.html',
);

// Make a handler that delegates to the correct handler based on path.
final handler = (shelf.Request request) {
return request.url.path.startsWith('packages/')
// request.change here will strip the `packages` prefix from the path
// so it's relative to packHandler's root.
? packHandler(request.change(path: 'packages'))
: buildHandler(request);
};

final server = await shelf.serve(handler, '127.0.0.1', port);

printOutput(
'Serving DevTools at http://${server.address.host}:${server.port}',
{
'method': 'server.started',
'params': {'host': server.address.host, 'port': server.port, 'pid': pid}
},
machineMode: machineMode,
);
}

Future<String> _getVersion() async {
final Uri resourceUri = await Isolate.resolvePackageUri(
Uri(scheme: 'package', path: 'devtools/devtools.dart'));
final String packageDir =
path.dirname(path.dirname(resourceUri.toFilePath()));
final File pubspecFile = File(path.join(packageDir, 'pubspec.yaml'));
final String versionLine =
pubspecFile.readAsLinesSync().firstWhere((String line) {
return line.startsWith('version: ');
}, orElse: () => null);
return versionLine == null
? 'unknown'
: versionLine.substring('version: '.length).trim();
}

void printOutput(
String message,
Object json, {
@required bool machineMode,
}) {
print(machineMode ? jsonEncode(json) : message);
}
18 changes: 18 additions & 0 deletions packages/devtools_server/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: devtools_server
description: A server for shared DevTools support.

version: 0.0.1

author: Dart Team <[email protected]>
homepage: https://github.com/flutter/devtools

environment:
sdk: '>=2.2.0-dev <3.0.0'

dependencies:
args: ^1.5.1
meta: ^1.1.0
path: ^1.6.0
pedantic: ^1.4.0
shelf: ^0.7.4
shelf_static: ^0.2.8

0 comments on commit 1efd6e0

Please sign in to comment.