-
Notifications
You must be signed in to change notification settings - Fork 1.4k
simplify package collections model #3069
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
Changes from all commits
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 |
---|---|---|
|
@@ -14,20 +14,44 @@ import TSCBasic | |
// TODO: is there a better name? this conflicts with the module name which is okay in this case but not ideal in Swift | ||
public struct PackageCollections: PackageCollectionsProtocol { | ||
private let configuration: Configuration | ||
private let storage: Storage | ||
private let storageContainer: (storage: Storage, owned: Bool) | ||
private let collectionProviders: [PackageCollectionsModel.CollectionSourceType: PackageCollectionProvider] | ||
private let metadataProvider: PackageMetadataProvider | ||
|
||
init(configuration: Configuration, | ||
private var storage: Storage { | ||
self.storageContainer.storage | ||
} | ||
|
||
// initialize with defaults | ||
public init(configuration: Configuration = .init()) { | ||
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. |
||
let storage = Storage(sources: FilePackageCollectionsSourcesStorage(), | ||
collections: SQLitePackageCollectionsStorage()) | ||
let collectionProviders = [PackageCollectionsModel.CollectionSourceType.json: JSONPackageCollectionProvider()] | ||
let metadataProvider = GitHubPackageMetadataProvider() | ||
|
||
self.configuration = configuration | ||
self.storageContainer = (storage, true) | ||
self.collectionProviders = collectionProviders | ||
self.metadataProvider = metadataProvider | ||
} | ||
|
||
// internal initializer for testing | ||
init(configuration: Configuration = .init(), | ||
storage: Storage, | ||
collectionProviders: [PackageCollectionsModel.CollectionSourceType: PackageCollectionProvider], | ||
metadataProvider: PackageMetadataProvider) { | ||
self.configuration = configuration | ||
self.storage = storage | ||
self.storageContainer = (storage, false) | ||
self.collectionProviders = collectionProviders | ||
self.metadataProvider = metadataProvider | ||
} | ||
|
||
public func shutdown() throws { | ||
if self.storageContainer.owned { | ||
try self.storageContainer.storage.close() | ||
} | ||
} | ||
|
||
// MARK: - Collections | ||
|
||
public func listCollections(identifiers: Set<PackageCollectionsModel.CollectionIdentifier>? = nil, | ||
|
@@ -279,8 +303,8 @@ public struct PackageCollections: PackageCollectionsProtocol { | |
} | ||
|
||
private func targetListResultFromCollections(_ collections: [PackageCollectionsModel.Collection]) -> PackageCollectionsModel.TargetListResult { | ||
var packageCollections = [PackageReference: (package: PackageCollectionsModel.Collection.Package, collections: Set<PackageCollectionsModel.CollectionIdentifier>)]() | ||
var targetsPackages = [String: (target: PackageCollectionsModel.PackageTarget, packages: Set<PackageReference>)]() | ||
var packageCollections = [PackageReference: (package: PackageCollectionsModel.Package, collections: Set<PackageCollectionsModel.CollectionIdentifier>)]() | ||
var targetsPackages = [String: (target: PackageCollectionsModel.Target, packages: Set<PackageReference>)]() | ||
|
||
collections.forEach { collection in | ||
collection.packages.forEach { package in | ||
|
@@ -306,7 +330,7 @@ public struct PackageCollections: PackageCollectionsProtocol { | |
.map { pair -> PackageCollectionsModel.TargetListResult.Package in | ||
let versions = pair.package.versions.map { PackageCollectionsModel.TargetListResult.PackageVersion(version: $0.version, packageName: $0.packageName) } | ||
return .init(repository: pair.package.repository, | ||
description: pair.package.summary, | ||
description: pair.package.description, | ||
versions: versions, | ||
collections: Array(pair.collections)) | ||
} | ||
|
@@ -315,7 +339,7 @@ public struct PackageCollections: PackageCollectionsProtocol { | |
} | ||
} | ||
|
||
internal static func mergedPackageMetadata(package: PackageCollectionsModel.Collection.Package, | ||
internal static func mergedPackageMetadata(package: PackageCollectionsModel.Package, | ||
basicMetadata: PackageCollectionsModel.PackageBasicMetadata?) -> PackageCollectionsModel.Package { | ||
var versions = package.versions.map { packageVersion -> PackageCollectionsModel.Package.Version in | ||
.init(version: packageVersion.version, | ||
|
@@ -334,7 +358,8 @@ public struct PackageCollections: PackageCollectionsProtocol { | |
|
||
return .init( | ||
repository: package.repository, | ||
description: basicMetadata?.description ?? package.summary, | ||
description: basicMetadata?.description ?? package.description, | ||
keywords: basicMetadata?.keywords ?? package.keywords, | ||
versions: versions, | ||
latestVersion: latestVersion, | ||
watchersCount: basicMetadata?.watchersCount, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,10 +42,10 @@ struct GitHubPackageMetadataProvider: PackageMetadataProvider { | |
|
||
func get(_ reference: PackageReference, callback: @escaping (Result<PackageCollectionsModel.PackageBasicMetadata, Error>) -> Void) { | ||
guard reference.kind == .remote else { | ||
return callback(.failure(Errors.unprocessable(reference))) | ||
return callback(.failure(Errors.invalidReferenceType(reference))) | ||
} | ||
guard let baseURL = self.apiURL(reference.path) else { | ||
return callback(.failure(Errors.unprocessable(reference))) | ||
return callback(.failure(Errors.invalidGitUrl(reference.path))) | ||
} | ||
|
||
let metadataURL = baseURL | ||
|
@@ -61,7 +61,9 @@ struct GitHubPackageMetadataProvider: PackageMetadataProvider { | |
// get the main data | ||
sync.enter() | ||
let options = self.makeRequestOptions(validResponseCodes: [200]) | ||
httpClient.get(metadataURL, options: options) { result in | ||
var headers = HTTPClientHeaders() | ||
headers.add(name: "Accept", value: "application/vnd.github.mercy-preview+json") | ||
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. Is this a literal string or something that should be parameterized? 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. are you asking about constants for the header name? |
||
httpClient.get(metadataURL, headers: headers, options: options) { result in | ||
defer { sync.leave() } | ||
resultsLock.withLock { | ||
results[metadataURL] = result | ||
|
@@ -103,6 +105,7 @@ struct GitHubPackageMetadataProvider: PackageMetadataProvider { | |
|
||
callback(.success(.init( | ||
description: metadata.description, | ||
keywords: metadata.topics, | ||
versions: tags.compactMap { TSCUtility.Version(string: $0.name) }, | ||
watchersCount: metadata.watchersCount, | ||
readmeURL: readme?.downloadURL, | ||
|
@@ -127,7 +130,7 @@ struct GitHubPackageMetadataProvider: PackageMetadataProvider { | |
let owner = String(url[ownerRange]) | ||
let repo = String(url[repoRange]) | ||
|
||
return URL(string: "https://api.\(host)/\(owner)/\(repo)") | ||
return URL(string: "https://api.\(host)/repos/\(owner)/\(repo)") | ||
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. 👍 |
||
} | ||
} | ||
return nil | ||
|
@@ -154,7 +157,8 @@ struct GitHubPackageMetadataProvider: PackageMetadataProvider { | |
} | ||
|
||
enum Errors: Error, Equatable { | ||
case unprocessable(PackageReference) | ||
case invalidReferenceType(PackageReference) | ||
case invalidGitUrl(String) | ||
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. nit: URL |
||
case invalidResponse(URL) | ||
} | ||
} | ||
|
@@ -164,6 +168,7 @@ extension GitHubPackageMetadataProvider { | |
let name: String | ||
let fullName: String | ||
let description: String? | ||
let topics: [String]? | ||
tomerd marked this conversation as resolved.
Show resolved
Hide resolved
|
||
let isPrivate: Bool | ||
let isFork: Bool | ||
let defaultBranch: String | ||
|
@@ -181,6 +186,7 @@ extension GitHubPackageMetadataProvider { | |
case name | ||
case fullName = "full_name" | ||
case description | ||
case topics | ||
case isPrivate = "private" | ||
case isFork = "fork" | ||
case defaultBranch = "default_branch" | ||
|
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.
Is there a semantic distinction to an empty vs a nil collection of keywords, or is it mainly to avoid a coded entry for an empty collection?
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.
the latter