Skip to content

Commit 7aa1cce

Browse files
authored
feat(dart_frog_cli): support custom ports via --port (#82)
1 parent 26c3097 commit 7aa1cce

File tree

8 files changed

+75
-10
lines changed

8 files changed

+75
-10
lines changed

bricks/dart_frog_dev_server/__brick__/server.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ void main() => hotReload(createServer);
1212

1313
Future<HttpServer> createServer() async {
1414
final ip = InternetAddress.anyIPv4;
15-
final port = int.parse(Platform.environment['PORT'] ?? '8080');
15+
final port = int.parse(Platform.environment['PORT'] ?? '{{port}}');
1616
final handler = buildRootHandler();
1717
return serve(handler, ip, port);
1818
}

bricks/dart_frog_dev_server/hooks/pre_gen.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Future<void> run(HookContext context) async {
1313
}
1414

1515
context.vars = {
16+
'port': context.vars['port'] ?? '8080',
1617
'directories': configuration.directories
1718
.map((c) => c.toJson())
1819
.toList()

bricks/dart_frog_prod_server/__brick__/build/Dockerfile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,4 @@ COPY --from=build /runtime/ /
2424
COPY --from=build /app/bin/server /app/bin/
2525

2626
# Start server.
27-
EXPOSE 8080
2827
CMD ["/app/bin/server"]

packages/dart_frog_cli/lib/src/commands/build/build.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class BuildCommand extends DartFrogCommand {
2525
var vars = <String, dynamic>{};
2626

2727
await generator.hooks.preGen(
28+
vars: vars,
2829
workingDirectory: cwd.path,
2930
onVarsChanged: (v) => vars = v,
3031
);

packages/dart_frog_cli/lib/src/commands/build/templates/dart_frog_prod_server_bundle.dart

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/dart_frog_cli/lib/src/commands/dev/dev.dart

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'dart:convert';
22
import 'dart:io' as io;
3+
import 'dart:io';
34

45
import 'package:dart_frog_cli/src/command.dart';
56
import 'package:dart_frog_cli/src/commands/commands.dart';
@@ -49,7 +50,14 @@ class DevCommand extends DartFrogCommand {
4950
_isWindows = isWindows ?? io.Platform.isWindows,
5051
_runProcess = runProcess ?? io.Process.run,
5152
_sigint = sigint ?? io.ProcessSignal.sigint,
52-
_startProcess = startProcess ?? io.Process.start;
53+
_startProcess = startProcess ?? io.Process.start {
54+
argParser.addOption(
55+
'port',
56+
abbr: 'p',
57+
defaultsTo: '8080',
58+
help: 'Which port number the server should start on.',
59+
);
60+
}
5361

5462
final DirectoryWatcherBuilder _directoryWatcher;
5563
final GeneratorBuilder _generator;
@@ -67,11 +75,13 @@ class DevCommand extends DartFrogCommand {
6775

6876
@override
6977
Future<int> run() async {
78+
final port = Platform.environment['PORT'] ?? results['port'] as String;
7079
final generator = await _generator(dartFrogDevServerBundle);
7180

7281
Future<void> codegen() async {
73-
var vars = <String, dynamic>{};
82+
var vars = <String, dynamic>{'port': port};
7483
await generator.hooks.preGen(
84+
vars: vars,
7585
workingDirectory: cwd.path,
7686
onVarsChanged: (v) => vars = v,
7787
);
@@ -112,7 +122,7 @@ class DevCommand extends DartFrogCommand {
112122
final progress = logger.progress('Serving');
113123
await codegen();
114124
await serve();
115-
progress.complete('Running on http://localhost:8080');
125+
progress.complete('Running on http://localhost:$port');
116126

117127
final watcher = _directoryWatcher(path.join(cwd.path, 'routes'));
118128
final subscription = watcher.events.listen((event) async {

packages/dart_frog_cli/lib/src/commands/dev/templates/dart_frog_dev_server_bundle.dart

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/dart_frog_cli/test/src/commands/dev/dev_test.dart

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import 'dart:async';
22
import 'dart:io';
33

4+
import 'package:args/args.dart';
45
import 'package:dart_frog_cli/src/commands/commands.dart';
56
import 'package:mason/mason.dart';
67
import 'package:mocktail/mocktail.dart';
78
import 'package:test/test.dart';
89
import 'package:watcher/watcher.dart';
910

11+
class _MockArgResults extends Mock implements ArgResults {}
12+
1013
class _MockDirectoryWatcher extends Mock implements DirectoryWatcher {}
1114

1215
class _MockLogger extends Mock implements Logger {}
@@ -32,6 +35,7 @@ void main() {
3235
registerFallbackValue(_FakeDirectoryGeneratorTarget());
3336
});
3437

38+
late ArgResults argResults;
3539
late DirectoryWatcher directoryWatcher;
3640
late MasonGenerator generator;
3741
late bool isWindows;
@@ -43,6 +47,8 @@ void main() {
4347
late DevCommand command;
4448

4549
setUp(() {
50+
argResults = _MockArgResults();
51+
when<dynamic>(() => argResults['port']).thenReturn('8080');
4652
directoryWatcher = _MockDirectoryWatcher();
4753
generator = _MockMasonGenerator();
4854
isWindows = false;
@@ -68,7 +74,7 @@ void main() {
6874
return process;
6975
},
7076
sigint: sigint,
71-
);
77+
)..testArgResults = argResults;
7278
});
7379

7480
test('runs a dev server successfully.', () async {
@@ -102,6 +108,54 @@ void main() {
102108
);
103109
final exitCode = await command.run();
104110
expect(exitCode, equals(ExitCode.success.code));
111+
verify(
112+
() => generatorHooks.preGen(
113+
vars: <String, dynamic>{'port': '8080'},
114+
workingDirectory: any(named: 'workingDirectory'),
115+
onVarsChanged: any(named: 'onVarsChanged'),
116+
),
117+
).called(1);
118+
});
119+
120+
test('port can be specified using --port', () async {
121+
when<dynamic>(() => argResults['port']).thenReturn('4242');
122+
final generatorHooks = _MockGeneratorHooks();
123+
when(
124+
() => generatorHooks.preGen(
125+
vars: any(named: 'vars'),
126+
workingDirectory: any(named: 'workingDirectory'),
127+
onVarsChanged: any(named: 'onVarsChanged'),
128+
),
129+
).thenAnswer((invocation) async {
130+
(invocation.namedArguments[const Symbol('onVarsChanged')] as Function(
131+
Map<String, dynamic> vars,
132+
))
133+
.call(<String, dynamic>{});
134+
});
135+
when(
136+
() => generator.generate(
137+
any(),
138+
vars: any(named: 'vars'),
139+
fileConflictResolution: FileConflictResolution.overwrite,
140+
),
141+
).thenAnswer((_) async => []);
142+
when(() => generator.hooks).thenReturn(generatorHooks);
143+
when(() => process.stdout).thenAnswer((_) => const Stream.empty());
144+
when(() => process.stderr).thenAnswer((_) => const Stream.empty());
145+
when(
146+
() => directoryWatcher.events,
147+
).thenAnswer(
148+
(_) => Stream.value(WatchEvent(ChangeType.MODIFY, 'README.md')),
149+
);
150+
final exitCode = await command.run();
151+
expect(exitCode, equals(ExitCode.success.code));
152+
verify(
153+
() => generatorHooks.preGen(
154+
vars: <String, dynamic>{'port': '4242'},
155+
workingDirectory: any(named: 'workingDirectory'),
156+
onVarsChanged: any(named: 'onVarsChanged'),
157+
),
158+
).called(1);
105159
});
106160

107161
test('kills all child processes when sigint received on windows', () async {
@@ -155,7 +209,7 @@ void main() {
155209
return process;
156210
},
157211
sigint: sigint,
158-
);
212+
)..testArgResults = argResults;
159213
command.run().ignore();
160214
await untilCalled(() => process.pid);
161215
expect(exitCode, equals(ExitCode.success.code));

0 commit comments

Comments
 (0)