Skip to content

Commit

Permalink
Replaced default remote repo provider (#67)
Browse files Browse the repository at this point in the history
* Replaced default remote repo provider

- GitHub API can be choosed using --provider github variable
- Default API - Forgejo
- GenerateCommand can be modified through custom EventProviderGenerator

* remote host URI parser added

* fix

---------

Co-authored-by: v.barabanov <[email protected]>
  • Loading branch information
BarabanovVVl and v.barabanov authored Jan 14, 2025
1 parent 0d33992 commit 46a17d9
Show file tree
Hide file tree
Showing 26 changed files with 378 additions and 114 deletions.
56 changes: 38 additions & 18 deletions Sources/AnalyticsGen/Commands/GenerateCommand.swift
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import DictionaryCoder
import Foundation
import SwiftCLI
import PromiseKit
import AnalyticsGenTools

final class GenerateCommand: AsyncExecutableCommand {

// MARK: - Instance Properties

let name = "generate"
let shortDescription = "Generate analytics events from schemas"

let configurationPath = Key<String>(
"--config",
"-c",
Expand All @@ -18,42 +19,59 @@ final class GenerateCommand: AsyncExecutableCommand {
Defaults to '\(String.defaultConfigurationPath)'.
"""
)

let force = Flag(
"--force",
description: """
Regenerate all analytics events ignoring last commit in lock file.
By default, generation will perform only if has new commits.
"""
)

let debug = Flag(
"--debug",
description: "Enable debug logging."
)

let generator: EventGenerator

// MARK: - Initializers

init(generator: EventGenerator) {
self.generator = generator

let provider = Key<String>(
"--provider",
"-p",
description: "Enter custom remote repository provider. Default - Forgejo"
)

let dependeciesGenerator: DependenciesGenerator
private(set) var generator: EventGenerator?
private let fileProvider: FileProvider = YAMLFileProvider()

init(
dependeciesGenerator: DependenciesGenerator = DefaultDependeciesGenerator()
) {
self.dependeciesGenerator = dependeciesGenerator
}

// MARK: - AsyncExecutableCommand

func executeAsyncAndExit() throws {
let configurationPath = self.configurationPath.value ?? .defaultConfigurationPath

let selectedRemoteRepoProvider = self.provider.value ?? .defaultRemoteRepoProvider
let configuration = try fileProvider.readFile(at: configurationPath, type: Configuration.self)
let remoteHost = configuration.remoteHost ?? .defaultRemoteRepoURI

generator = try dependeciesGenerator.createGenerator(for: selectedRemoteRepoProvider, remoteHost: remoteHost)

Log.isDebugLoggingEnabled = debug.value


guard let generator = generator else {
self.fail(message: "No generator setted up")
}

firstly {
generator.generate(configurationPath: configurationPath, force: force.value)
generator.generate(configuration: configuration, force: force.value)
}.done { result in
switch result {
case .success:
self.succeed(message: "Generation completed successfully!")

case .upToDate:
self.succeed(message: "Analytic events is up to date!")
}
Expand All @@ -68,4 +86,6 @@ private extension String {
// MARK: - Type Properties

static let defaultConfigurationPath = ".analyticsGen.yml"
static let defaultRemoteRepoProvider = "forgejo"
static let defaultRemoteRepoURI = "https://forgejo.pyn.ru/api/v1"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import Foundation
import AnalyticsGenTools
import DictionaryCoder

final class DefaultDependeciesGenerator: DependenciesGenerator {
let httpService: HTTPService
let yamlFileProvider: FileProvider
let templateContextCoder: TemplateContextCoder
let stencilExtensions: [StencilExtension]
let templateRenderer: TemplateRenderer

init() {
self.httpService = HTTPService()
self.yamlFileProvider = YAMLFileProvider()
self.templateContextCoder = DefaultTemplateContextCoder()
self.stencilExtensions = [
StencilStringUppercasePrefixFilter(),
StencilStringUppercaseSuffixFilter(),
StencilStringMultilineFilter(),
StencilStringMultilineAlignmentFilter()
]
self.templateRenderer = DefaultTemplateRenderer(
contextCoder: templateContextCoder,
stencilExtensions: stencilExtensions
)
}

func createGenerator(for provider: String, remoteHost: String) throws -> EventGenerator {

guard let baseURL = URL(string: remoteHost) else {
throw DependeciesGeneratorError.invalidRemoteHostURI
}

let repoProviderType = try RemoteRepoProviderType.from(string: provider)

var remoteRepoProvider: RemoteRepoProvider?

switch repoProviderType {
case .forgejo:
remoteRepoProvider = ForgejoRemoteRepoProvider(baseURL: baseURL, httpService: httpService)
case .github:
remoteRepoProvider = GitHubRemoteRepoProvider(baseURL: baseURL, httpService: httpService)
}

guard let remoteRepoProvider = remoteRepoProvider else {
throw DependeciesGeneratorError.unknownProvider
}

let remoteRepoReferenceFinder = RemoteRepoReferenceFinder(remoteRepoProvider: remoteRepoProvider)

return DefaultEventGenerator(
fileProvider: yamlFileProvider,
remoteRepoProvider: remoteRepoProvider,
templateRenderer: templateRenderer,
dictionaryDecoder: DictionaryDecoder(),
remoteRepoReferenceFinder: remoteRepoReferenceFinder
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Foundation

enum DependeciesGeneratorError: Error {
case unknownProvider
case invalidRemoteHostURI

var errorDescription: String {
switch self {
case .unknownProvider:
"The specified remote repository provider is unknown"
case .invalidRemoteHostURI:
"The remote repository URI is not correct"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import AnalyticsGenTools

protocol DependenciesGenerator {
var httpService: HTTPService { get }
var yamlFileProvider: FileProvider { get }
var templateContextCoder: TemplateContextCoder { get }
var stencilExtensions: [StencilExtension] { get }
var templateRenderer: TemplateRenderer { get }

func createGenerator(for provider: String, remoteHost: String) throws -> EventGenerator
}
36 changes: 0 additions & 36 deletions Sources/AnalyticsGen/Dependencies.swift

This file was deleted.

48 changes: 24 additions & 24 deletions Sources/AnalyticsGen/Generators/Event/DefaultEventGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -267,24 +267,24 @@ final class DefaultEventGenerator: EventGenerator {
}

private func generateFromRemoteRepo(
gitHubConfiguration: GitHubSourceConfiguration,
remoteRepoConfiguration: RemoteRepoSourceConfiguration,
ref: String,
configuration: GeneratedConfiguration,
remoteReferenceSHA: String
) -> Promise<EventGenerationResult> {
firstly {
remoteRepoProvider.fetchRepo(
owner: gitHubConfiguration.owner,
repo: gitHubConfiguration.repo,
owner: remoteRepoConfiguration.owner,
repo: remoteRepoConfiguration.repo,
ref: ref,
token: try gitHubConfiguration.accessToken.resolveToken(),
token: try remoteRepoConfiguration.accessToken.resolveToken(),
key: configuration.name
)
}.map { repoPathURL in
try self.generate(
configuration: configuration,
targetPath: gitHubConfiguration.path,
schemasPath: gitHubConfiguration.path.map { targetPath in
targetPath: remoteRepoConfiguration.path,
schemasPath: remoteRepoConfiguration.path.map { targetPath in
repoPathURL.appendingPathComponent(targetPath)
} ?? repoPathURL
)
Expand All @@ -296,17 +296,17 @@ final class DefaultEventGenerator: EventGenerator {
}

private func fetchRemoteReferenceSHA(
gitHubConfiguration: GitHubSourceConfiguration,
remoteRepoConfiguration: RemoteRepoSourceConfiguration,
gitReferenceType: GitReferenceType
) -> Promise<String> {
switch gitReferenceType {
case .tag, .branch:
return firstly {
remoteRepoProvider.fetchReference(
owner: gitHubConfiguration.owner,
repo: gitHubConfiguration.repo,
owner: remoteRepoConfiguration.owner,
repo: remoteRepoConfiguration.repo,
ref: gitReferenceType.rawValue,
token: try gitHubConfiguration.accessToken.resolveToken()
token: try remoteRepoConfiguration.accessToken.resolveToken()
)
}.map { reference in
reference.object.sha
Expand All @@ -318,13 +318,13 @@ final class DefaultEventGenerator: EventGenerator {
}

private func generateFromRemoteRepo(
gitHubConfiguration: GitHubSourceConfiguration,
remoteRepoConfiguration: RemoteRepoSourceConfiguration,
gitReferenceType: GitReferenceType,
configuration: GeneratedConfiguration,
force: Bool
) -> Promise<EventGenerationResult> {
firstly {
fetchRemoteReferenceSHA(gitHubConfiguration: gitHubConfiguration, gitReferenceType: gitReferenceType)
fetchRemoteReferenceSHA(remoteRepoConfiguration: remoteRepoConfiguration, gitReferenceType: gitReferenceType)
}.then { remoteReferenceSHA in
let shouldPerformGeneration = try self.shouldGenerate(
configuration: configuration,
Expand All @@ -333,7 +333,7 @@ final class DefaultEventGenerator: EventGenerator {

if shouldPerformGeneration || force {
return self.generateFromRemoteRepo(
gitHubConfiguration: gitHubConfiguration,
remoteRepoConfiguration: remoteRepoConfiguration,
ref: gitReferenceType.rawValue,
configuration: configuration,
remoteReferenceSHA: remoteReferenceSHA
Expand All @@ -345,8 +345,8 @@ final class DefaultEventGenerator: EventGenerator {
}

private func performFinders(
finderConfigurations: [GitHubReferenceFinderConfiguration],
gitHubConfiguration: GitHubSourceConfiguration,
finderConfigurations: [RemoteRepoReferenceFinderConfiguration],
remoteRepoConfiguration: RemoteRepoSourceConfiguration,
generatedConfiguration: GeneratedConfiguration,
force: Bool
) throws -> Promise<EventGenerationResult> {
Expand All @@ -361,7 +361,7 @@ final class DefaultEventGenerator: EventGenerator {
return try remoteRepoReferenceFinder
.findReference(
configurations: finderConfigurations,
gitHubConfiguration: gitHubConfiguration
remoteRepoConfiguration: remoteRepoConfiguration
)
.map { gitReferenceType in
if let gitReferenceType {
Expand All @@ -381,7 +381,7 @@ final class DefaultEventGenerator: EventGenerator {
}
.then { gitReferenceType in
self.generateFromRemoteRepo(
gitHubConfiguration: gitHubConfiguration,
remoteRepoConfiguration: remoteRepoConfiguration,
gitReferenceType: gitReferenceType,
configuration: generatedConfiguration,
force: force
Expand All @@ -402,19 +402,19 @@ final class DefaultEventGenerator: EventGenerator {

return .value(.success)

case .gitHub(let gitHubConfiguration):
switch gitHubConfiguration.ref {
case .remoteRepo(let remoteRepoConfiguration):
switch remoteRepoConfiguration.ref {
case .tag(let name):
return generateFromRemoteRepo(
gitHubConfiguration: gitHubConfiguration,
remoteRepoConfiguration: remoteRepoConfiguration,
gitReferenceType: .tag(name: name),
configuration: configuration,
force: force
)

case .branch(let name):
return generateFromRemoteRepo(
gitHubConfiguration: gitHubConfiguration,
remoteRepoConfiguration: remoteRepoConfiguration,
gitReferenceType: .branch(name: name),
configuration: configuration,
force: force
Expand All @@ -423,7 +423,7 @@ final class DefaultEventGenerator: EventGenerator {
case .finders(let finders):
return try performFinders(
finderConfigurations: finders,
gitHubConfiguration: gitHubConfiguration,
remoteRepoConfiguration: remoteRepoConfiguration,
generatedConfiguration: configuration,
force: force
)
Expand All @@ -433,9 +433,9 @@ final class DefaultEventGenerator: EventGenerator {

// MARK: - EventGenerator

func generate(configurationPath: String, force: Bool) -> Promise<EventGenerationResult> {
func generate(configuration: Configuration, force: Bool) -> Promise<EventGenerationResult> {
firstly {
Promise.value(try fileProvider.readFile(at: configurationPath, type: Configuration.self))
Promise.value(configuration)
}.map { configuration in
configuration.configurations.reversed()
}.get { configurations in
Expand Down
2 changes: 1 addition & 1 deletion Sources/AnalyticsGen/Generators/Event/EventGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ protocol EventGenerator {

// MARK: - Instance Methods

func generate(configurationPath: String, force: Bool) -> Promise<EventGenerationResult>
func generate(configuration: Configuration, force: Bool) -> Promise<EventGenerationResult>
}
Loading

0 comments on commit 46a17d9

Please sign in to comment.