Skip to content
This repository has been archived by the owner on Mar 18, 2021. It is now read-only.

Commit

Permalink
Deprecate --heroku option in setup cli (#543)
Browse files Browse the repository at this point in the history
* Deprecate --heroku option in setup cli

* update changelog

* Fix content-negotiation test
  • Loading branch information
itsjoeconway authored Aug 31, 2018
1 parent 965e32f commit 1fefe56
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 113 deletions.
2 changes: 2 additions & 0 deletions aqueduct/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

- `Controller` is now an abstract class that requires implementing `handle`. This is a minor breaking change that should not have an impact.
- 'Serializable' can now implement static 'document' method to override component documentation behavior
- Removes `aqueduct setup --heroku=<name>` and instead points to documentation.
- Fixes issue ORM had with transformed values (e.g. enums) and nullable columns

## 3.0.0

Expand Down
67 changes: 4 additions & 63 deletions aqueduct/lib/src/cli/commands/setup.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ class CLISetup extends CLICommand with CLIProject {

@Option("heroku",
help:
"Sets up the project in the current directory for deplying to Heroku.",
valueHelp: "The name of the Heroku application.")
"DEPRECATED. Please see https://aqueduct.io/docs/deploy/deploy_heroku/.")
String get herokuName => decode("heroku");

@Flag("tests",
Expand All @@ -35,73 +34,15 @@ class CLISetup extends CLICommand with CLIProject {
@override
Future<int> handle() async {
if (shouldSetupHeroku) {
return setupHerokuProject();
displayInfo("This option has been deprecated.");
displayProgress("Please see https://aqueduct.io/docs/deploy/deploy_heroku/ for instructions.");
return 0;
} else /*if (shouldSetupTests*/ {
return setupTestEnvironment();
}
}

bool get hasGitCLI => isExecutableInShellPath("git");
bool get hasPSQLCLI => isExecutableInShellPath("psql");
bool get hasHerokuCLI => isExecutableInShellPath("heroku");

Future<int> setupHerokuProject() async {
if (!hasHerokuCLI) {
displayError("The application 'heroku' was not found in \$PATH.");
displayProgress(
"Install 'heroku' from https://devcenter.heroku.com/articles/heroku-cli.");
return -1;
}

if (!hasGitCLI) {
displayError("The application 'git' was not found in \$PATH.");
displayProgress("Install 'git' from https://git-scm.com/downloads.");
}

displayInfo("Setting up Heroku for $herokuName");

var commands = [
["git:remote", "-a", herokuName],
[
"config:set",
"DART_SDK_URL=https://storage.googleapis.com/dart-archive/channels/stable/release/latest/sdk/dartsdk-linux-x64-release.zip"
],
[
"config:add",
"BUILDPACK_URL=https://github.com/stablekernel/heroku-buildpack-dart.git"
],
[
"config:set",
"PATH=/app/bin:/usr/local/bin:/usr/bin:/bin:/app/.pub-cache/bin:/app/dart-sdk/bin"
],
["config:set", "PUB_CACHE=/app/pub-cache"],
];

for (var cmd in commands) {
displayProgress(
"Running heroku ${cmd.join(" ")} in ${projectDirectory.path}");
var result = await Process.run("heroku", cmd,
workingDirectory: projectDirectory.path);
if (result.exitCode != 0) {
throw CLIException("Heroku command failed",
instructions: ["${result.stdout} ${result.stderr}"]);
}
}

displayProgress("Removing config.yaml from .gitignore");
var gitIgnore = fileInProjectDirectory(".gitignore");
var contents =
gitIgnore.readAsStringSync().replaceAll(RegExp("config.yaml\\n"), "");
gitIgnore.writeAsStringSync(contents);

var procFile = fileInProjectDirectory("Procfile");
procFile.writeAsStringSync("""
release: /app/dart-sdk/bin/pub global run aqueduct:aqueduct db upgrade --connect \$DATABASE_URL
web: /app/dart-sdk/bin/pub global run aqueduct:aqueduct serve --port \$PORT --no-monitor
""");

return 0;
}

Future<int> setupTestEnvironment() async {
if (!hasPSQLCLI) {
Expand Down
1 change: 0 additions & 1 deletion aqueduct/lib/src/http/resource_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import 'dart:io';
import 'dart:mirrors';

import 'package:aqueduct/src/auth/objects.dart';
import 'package:aqueduct/src/db/managed/entity_mirrors.dart';
import 'package:aqueduct/src/openapi/openapi.dart';
import 'package:aqueduct/src/utilities/documented_element.dart';
import 'package:aqueduct/src/utilities/mirror_helpers.dart';
Expand Down
103 changes: 54 additions & 49 deletions aqueduct/test/http/content_negotiation_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,26 @@ import 'package:aqueduct/aqueduct.dart';
import 'package:test/test.dart';

void main() {
HttpServer server;
Request request;
HttpClient client;

setUpAll(() {
client = HttpClient();
});

tearDownAll(() async {
client.close(force: true);
});
ClientServer clientServer = ClientServer();

setUp(() async {
server = await HttpServer.bind(InternetAddress.loopbackIPv4, 8123);
await clientServer.open();
});

tearDown(() async {
await request?.raw?.response?.close();
await server?.close(force: true);
await clientServer.close();
});

test("No accept header returns [], all are allowed", () async {
// ignore: unawaited_futures
getWithTypes(client, null);
request = Request(await server.first);
final request = await clientServer.getWithTypes(null);
expect(request.acceptableContentTypes, []);
expect(request.acceptsContentType(ContentType.json), true);
expect(request.acceptsContentType(ContentType.html), true);
expect(request.acceptsContentType(ContentType.binary), true);
});

test("Empty Accept header returns [], all are allowed", () async {
// ignore: unawaited_futures
getWithTypes(client, []);
request = Request(await server.first);

final request = await clientServer.getWithTypes([]);
expect(request.acceptableContentTypes.isEmpty, true);
expect(request.acceptsContentType(ContentType.json), true);
expect(request.acceptsContentType(ContentType.html), true);
Expand All @@ -50,9 +34,8 @@ void main() {
test(
"Two implicitly equal q-values order is defined by their position in request",
() async {
// ignore: unawaited_futures
getWithTypes(client, ["text/plain", "text/html"]);
request = Request(await server.first);
final request =
await clientServer.getWithTypes(["text/plain", "text/html"]);
expect(
request.acceptableContentTypes
.any((ct) => ct.primaryType == "text" && ct.subType == "plain"),
Expand All @@ -70,9 +53,9 @@ void main() {
test(
"Two explicitly equal q-values order is defined by their position in request",
() async {
// ignore: unawaited_futures
getWithTypes(client, ["text/plain; q=1.0", "text/html; q=1.0"]);
request = Request(await server.first);
final request = await clientServer
.getWithTypes(["text/plain; q=1.0", "text/html; q=1.0"]);

expect(
request.acceptableContentTypes.first.primaryType == "text" &&
request.acceptableContentTypes.first.subType == "plain",
Expand All @@ -88,9 +71,8 @@ void main() {
});

test("Q-value with explicit 1 (not 1.0) is interpreted as 1.0", () async {
// ignore: unawaited_futures
getWithTypes(client, ["text/plain; q=1.0", "text/html; q=1"]);
request = Request(await server.first);
final request = await clientServer
.getWithTypes(["text/plain; q=1.0", "text/html; q=1"]);
expect(
request.acceptableContentTypes.first.primaryType == "text" &&
request.acceptableContentTypes.first.subType == "plain",
Expand All @@ -107,9 +89,7 @@ void main() {

test("Two equal q-values but primary type is * prefers to other type",
() async {
// ignore: unawaited_futures
getWithTypes(client, ["*/*", "text/html"]);
request = Request(await server.first);
final request = await clientServer.getWithTypes(["*/*", "text/html"]);
expect(
request.acceptableContentTypes.first.primaryType == "text" &&
request.acceptableContentTypes.first.subType == "html",
Expand All @@ -125,9 +105,7 @@ void main() {
});

test("Two equal q-values but subtype is * prefers to other type", () async {
// ignore: unawaited_futures
getWithTypes(client, ["text/*", "text/html"]);
request = Request(await server.first);
final request = await clientServer.getWithTypes(["text/*", "text/html"]);
expect(
request.acceptableContentTypes.first.primaryType == "text" &&
request.acceptableContentTypes.first.subType == "html",
Expand All @@ -143,13 +121,12 @@ void main() {
});

test("Sorted by q-value if all content-types are fully defined", () async {
// ignore: unawaited_futures
getWithTypes(client, [
final request = await clientServer.getWithTypes([
"text/plain; q=0.4",
"text/html; q=0.8",
"application/json; charset=utf-8"
]);
request = Request(await server.first);

expect(
request.acceptableContentTypes.first.primaryType == "application" &&
request.acceptableContentTypes.first.subType == "json",
Expand All @@ -169,16 +146,44 @@ void main() {
});
}

Future getWithTypes(HttpClient client, List<String> contentTypeStrings) async {
var req = await client.openUrl("GET", Uri.parse("http://localhost:8123"));
if (contentTypeStrings != null) {
if (contentTypeStrings.isEmpty) {
req.headers.set(HttpHeaders.acceptHeader, "");
} else {
req.headers.add(HttpHeaders.acceptHeader, contentTypeStrings.join(", "));
}
class ClientServer {
HttpServer server;
HttpClient client;

List<Request> _requests = [];

Future open() async {
client = HttpClient();
server = await HttpServer.bind(InternetAddress.loopbackIPv4, 8123);
server.map((r) => Request(r)).listen((r) {
_requests.add(r);
r.raw.response.statusCode = 200;
r.raw.response.close();
});
}

var response = await req.close();
return response.drain();
Future close() async {
_requests = [];
client.close(force: true);
await server.close();
}

Future<Request> getWithTypes(List<String> contentTypeStrings) async {
assert(_requests.isEmpty);

var req = await client.openUrl("GET", Uri.parse("http://localhost:8123"));
if (contentTypeStrings != null) {
if (contentTypeStrings.isEmpty) {
req.headers.set(HttpHeaders.acceptHeader, "");
} else {
req.headers
.add(HttpHeaders.acceptHeader, contentTypeStrings.join(", "));
}
}

var response = await req.close();
await response.drain();

return _requests.removeAt(0);
}
}

0 comments on commit 1fefe56

Please sign in to comment.