Skip to content

Feature install cmd packages homepage #1

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

Merged
merged 4 commits into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,8 @@ build/
key.json

node_modules/

# test profile files are also not needed

/app/dev-data-file.jsonl
test-profile.yml
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ AppEngine version, listed here to ease deployment and troubleshooting.
* Upgraded stable Dart analysis SDK to `3.2.3`.
* Upgraded stable Flutter analysis SDK to `3.16.3`.
* Upgraded pana to `0.21.44`.
* Upgraded dependencies.

## `20231206t130200-all`
* Bumped runtimeVersion to `2023.12.06`.
Expand Down
2 changes: 1 addition & 1 deletion app/lib/fake/server/fake_server_entrypoint.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class FakeServerCommand extends Command {
final watch = argResults!['watch'] == true;

setupDebugEnvBasedLogging();
await updateLocalBuiltFilesIfNeeded();

final state = LocalServerState();
if (dataFile != null) {
Expand Down Expand Up @@ -136,7 +137,6 @@ class FakeServerCommand extends Command {
return shelf.Response.notFound('Not Found.');
}

await updateLocalBuiltFilesIfNeeded();
await Future.wait(
[
storageServer.run(port: storagePort),
Expand Down
1 change: 1 addition & 0 deletions app/lib/fake/tool/init_data_file.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class FakeInitDataFileCommand extends Command {
final profile = TestProfile.fromYaml(
await File(argResults!['test-profile'] as String).readAsString(),
);
await updateLocalBuiltFilesIfNeeded();

final archiveCachePath = p.join(
resolveAppDir(),
Expand Down
6 changes: 6 additions & 0 deletions app/lib/frontend/templates/views/pkg/info_box.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.

import 'package:pana/pana.dart';
import 'package:pub_dev/frontend/templates/views/pkg/one_click_install.dart';
import 'package:pubspec_parse/pubspec_parse.dart' as pubspek;

import '../../../../package/models.dart';
Expand Down Expand Up @@ -67,6 +68,7 @@ d.Node packageInfoBoxNode({
}
}
return d.fragment([
_oneClickInstall(package.name!),
imageCarousel(),
labeledScores,
if (thumbnailUrl != null)
Expand Down Expand Up @@ -105,6 +107,10 @@ d.Node packageInfoBoxNode({
]);
}

d.Node _oneClickInstall(String packageName) {
return oneClickInstallNode(packageName: packageName);
}

d.Node _publisher(String? publisherId) {
return _block(
'Publisher',
Expand Down
38 changes: 38 additions & 0 deletions app/lib/frontend/templates/views/pkg/one_click_install.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) 2021, 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 '../../../dom/dom.dart' as d;
import '../../../static_files.dart';

d.Node oneClickInstallNode({required String packageName}) {
return d.fragment([
d.text('dart pub add $packageName'),
d.span(
classes: ['pkg-page-install-copy'],
children: [
d.img(
classes: ['pkg-page-install-copy-icon'],
attributes: {
'data-copy-content': 'dart pub add $packageName',
'data-ga-click-event': 'copy-package-version',
},
image: d.Image(
src: staticUrls.getAssetUrl('/static/img/content-copy-icon.svg'),
alt: 'copy "dart pub add $packageName" to clipboard',
width: 18,
height: 18,
),
title: 'Copy "dart pub add $packageName" to clipboard',
),
d.div(
classes: ['pkg-page-install-copy-feedback'],
children: [
d.span(classes: ['code'], text: '$packageName'),
d.text(' copied to clipboard'),
],
),
],
),
]);
}
111 changes: 111 additions & 0 deletions app/lib/shared/count_topics.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,28 @@
// 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:collection';
import 'dart:io';

import 'package:collection/collection.dart';
import 'package:gcloud/storage.dart';
import 'package:logging/logging.dart';
import 'package:path/path.dart' as p;
import 'package:pub_dev/package/backend.dart';
import 'package:pub_dev/package/models.dart';
import 'package:pub_dev/shared/configuration.dart';
import 'package:pub_dev/shared/datastore.dart';
import 'package:pub_dev/shared/storage.dart';
import 'package:pub_dev/shared/utils.dart';
import 'package:source_span/source_span.dart';
import 'package:yaml/yaml.dart';

import '../frontend/static_files.dart';

final topicsJsonFileName = 'topics.json';

final _log = Logger('count_topics');

Future<void> countTopics() async {
final topics = <String, int>{};

Expand All @@ -32,3 +44,102 @@ Future<void> countTopics() async {
await uploadBytesWithRetry(
reportsBucket, topicsJsonFileName, jsonUtf8Encoder.convert(topics));
}

typedef CanonicalTopic = ({
String topic,
String description,
Set<String> aliases,
});

final canonicalTopics = () {
try {
final f = File(p.join(resolveAppDir(), '../doc/topics.yaml'));
final root = loadYamlNode(f.readAsStringSync(), sourceUrl: f.uri);
if (root is! YamlMap) {
throw SourceSpanFormatException('expected a map', root.span);
}
if (root.keys.length > 1) {
throw SourceSpanFormatException(
'only the "topic" key is allowed',
root.span,
);
}

final topics = root.expectListOfObjects('topics');
return UnmodifiableListView(topics.map<CanonicalTopic>((entry) {
final topic = entry.expectString('topic', maxLength: 32);
if (!isValidTopicFormat(topic)) {
throw SourceSpanFormatException('must be valid topic', entry.span);
}
if (entry.keys.length > 3) {
throw SourceSpanFormatException(
'only keys "topic", "description" and "aliases" are allowed',
entry.span,
);
}
return (
topic: topic,
description: entry.expectString('description', maxLength: 160),
aliases: Set.unmodifiable(entry.expectList('aliases').nodes.map((node) {
final value = node.value;
if (value is! String) {
throw SourceSpanFormatException('must be a string', node.span);
}
if (!isValidTopicFormat(value)) {
throw SourceSpanFormatException('must be valid topic', node.span);
}
return value;
})),
);
}).toList(growable: false));
} on Exception catch (e, st) {
_log.shout('failed to load doc/topics.yaml', e, st);

// This is sad, but we can just ignore it!
return UnmodifiableListView(<CanonicalTopic>[]);
}
}();

/// True, if [topic] is formatted like a valid topic.
bool isValidTopicFormat(String topic) =>
RegExp(r'^[a-z0-9-]{2,32}$').hasMatch(topic) &&
!topic.contains('--') &&
topic.startsWith(RegExp(r'^[a-z]')) &&
!topic.endsWith('-');

extension on YamlMap {
YamlNode expectProperty(String key) {
if (nodes[key] case final YamlNode v) return v;
throw SourceSpanFormatException('expected a "$key" property', span);
}

YamlList expectList(String key) {
final value = expectProperty(key);
if (value case final YamlList v) return v;
throw SourceSpanFormatException('"$key" must be a list', value.span);
}

Iterable<YamlMap> expectListOfObjects(String key) sync* {
for (final entry in expectList(key).nodes) {
if (entry is! YamlMap) {
throw SourceSpanFormatException('expected an object', entry.span);
}
yield entry;
}
}

String expectString(String key, {int? maxLength}) {
final node = expectProperty(key);
final value = node.value;
if (value is! String) {
throw SourceSpanFormatException('"$key" must be a string', node.span);
}
if (maxLength != null && value.length > maxLength) {
throw SourceSpanFormatException(
'"$key" must be shorter than $maxLength',
node.span,
);
}
return value;
}
}
42 changes: 25 additions & 17 deletions app/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,10 @@ packages:
dependency: "direct dev"
description:
name: build_runner
sha256: "10c6bcdbf9d049a0b666702cf1cee4ddfdc38f02a19d35ae392863b47519848b"
sha256: "67d591d602906ef9201caf93452495ad1812bea2074f04e25dbd7c133785821b"
url: "https://pub.dev"
source: hosted
version: "2.4.6"
version: "2.4.7"
build_runner_core:
dependency: transitive
description:
Expand Down Expand Up @@ -162,10 +162,10 @@ packages:
dependency: transitive
description:
name: built_value
sha256: "723b4021e903217dfc445ec4cf5b42e27975aece1fc4ebbc1ca6329c2d9fb54e"
sha256: "69acb7007eb2a31dc901512bfe0f7b767168be34cb734835d54c070bfa74c1b2"
url: "https://pub.dev"
source: hosted
version: "8.7.0"
version: "8.8.0"
characters:
dependency: transitive
description:
Expand Down Expand Up @@ -210,10 +210,10 @@ packages:
dependency: transitive
description:
name: code_builder
sha256: "1be9be30396d7e4c0db42c35ea6ccd7cc6a1e19916b5dc64d6ac216b5544d677"
sha256: b2151ce26a06171005b379ecff6e08d34c470180ffe16b8e14b6d52be292b55f
url: "https://pub.dev"
source: hosted
version: "4.7.0"
version: "4.8.0"
collection:
dependency: "direct main"
description:
Expand Down Expand Up @@ -258,10 +258,10 @@ packages:
dependency: transitive
description:
name: dart_style
sha256: abd7625e16f51f554ea244d090292945ec4d4be7bfbaf2ec8cccea568919d334
sha256: "40ae61a5d43feea6d24bd22c0537a6629db858963b99b4bc1c3db80676f32368"
url: "https://pub.dev"
source: hosted
version: "2.3.3"
version: "2.3.4"
fake_async:
dependency: "direct main"
description:
Expand Down Expand Up @@ -361,10 +361,10 @@ packages:
dependency: "direct main"
description:
name: http
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139
url: "https://pub.dev"
source: hosted
version: "1.1.0"
version: "1.1.2"
http2:
dependency: transitive
description:
Expand Down Expand Up @@ -552,10 +552,10 @@ packages:
dependency: "direct main"
description:
name: path
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
url: "https://pub.dev"
source: hosted
version: "1.8.3"
version: "1.9.0"
pem:
dependency: "direct main"
description:
Expand Down Expand Up @@ -631,10 +631,10 @@ packages:
dependency: transitive
description:
name: safe_url_check
sha256: b85685b48d74dcd9659e1f2228f900b9fb37cd3b4ba085ca4f593d06c00c36a6
sha256: "49a3e060a7869cbafc8f4845ca1ecbbaaa53179980a32f4fdfeab1607e90f41d"
url: "https://pub.dev"
source: hosted
version: "1.1.1"
version: "1.1.2"
sanitize_html:
dependency: "direct main"
description:
Expand Down Expand Up @@ -783,10 +783,10 @@ packages:
dependency: "direct main"
description:
name: tar
sha256: "7196d37d26fcf4d523cd0d086b463b66550bae0c29777bf398006827d5e5d453"
sha256: "1680219f82dfa81c8d0e76e849b7b34ea969c721f55a8ebd294a9a95e740dd42"
url: "https://pub.dev"
source: hosted
version: "1.0.1"
version: "1.0.3"
term_glyph:
dependency: transitive
description:
Expand Down Expand Up @@ -867,6 +867,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.1.0"
web:
dependency: transitive
description:
name: web
sha256: edc8a9573dd8c5a83a183dae1af2b6fd4131377404706ca4e5420474784906fa
url: "https://pub.dev"
source: hosted
version: "0.4.0"
web_socket_channel:
dependency: transitive
description:
Expand Down Expand Up @@ -908,4 +916,4 @@ packages:
source: hosted
version: "2.1.1"
sdks:
dart: ">=3.0.0 <4.0.0"
dart: ">=3.2.0 <4.0.0"
2 changes: 1 addition & 1 deletion app/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ dependencies:
# 3rd-party packages with pinned versions
mailer: '6.0.1'
ulid: '2.0.0'
tar: '1.0.1'
tar: '1.0.3'
api_builder:
path: ../pkg/api_builder

Expand Down
2 changes: 1 addition & 1 deletion app/test/frontend/static_files_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ void main() {
final partsSize = parts
.map((p) => cache.getFile(p)!.bytes.length)
.reduce((a, b) => a + b);
expect((partsSize / 1024).round(), closeTo(208, 1));
expect((partsSize / 1024).round(), closeTo(210, 1));
});
});

Expand Down
Loading