-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
implement PushBetaGroupsCommand and PullBetaGroupsCommand
- Loading branch information
Showing
2 changed files
with
59 additions
and
68 deletions.
There are no files selected for viewing
41 changes: 8 additions & 33 deletions
41
Sources/AppStoreConnectCLI/Commands/TestFlight/BetaGroups/Sync/PullBetaGroupsCommand.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,54 +1,29 @@ | ||
// Copyright 2020 Itty Bitty Apps Pty Ltd | ||
|
||
import ArgumentParser | ||
import Foundation | ||
import Files | ||
import Yams | ||
import CodableCSV | ||
|
||
struct PullBetaGroupsCommand: CommonParsableCommand { | ||
|
||
static var configuration = CommandConfiguration( | ||
commandName: "pull", | ||
abstract: "Load or update local beta group config files from server." | ||
abstract: "Pull down server beta groups, refresh local beta group config files" | ||
) | ||
|
||
@OptionGroup() | ||
var common: CommonOptions | ||
|
||
@Option(help: "Path to the Folder containing the information about beta groups. (default: ./config/betagroups)") | ||
var outputPath: String? | ||
@Option( | ||
default: "./config/betagroups", | ||
help: "Path to the Folder containing the information about beta groups. (default: './config/betagroups')" | ||
) var outputPath: String | ||
|
||
func run() throws { | ||
let service = try makeService() | ||
|
||
let betaGroups: [(BetaGroup, [BetaTester])] = try service.pullBetaGroups() | ||
let betaGroupWithTesters = try service.pullBetaGroups() | ||
|
||
let folder = outputPath != nil | ||
? try Folder(path: outputPath!) | ||
: try Folder(path: "./config").createSubfolder(named: "betagroups") | ||
|
||
try betaGroups.forEach { (group: BetaGroup, testers: [BetaTester]) in | ||
|
||
// desired output: app-name_group-name | ||
let groupFileName = "\(group.app.name ?? "")_\(group.groupName ?? "grouo-name")" | ||
.components(separatedBy: .whitespacesAndNewlines) | ||
.joined() | ||
.snakeCased() ?? "file_name" | ||
|
||
// desired output: app-name_group-name_beta-testers.csv | ||
let testersFile = try folder | ||
.createFile(named: "\(groupFileName)_beta-testers.csv") | ||
|
||
try testersFile.write(testers.renderAsCSV()) | ||
|
||
var group = group | ||
group.testers = testersFile.path | ||
|
||
let groupFile = try folder.createFile(named: "\(groupFileName).yml") | ||
|
||
try groupFile.write(try YAMLEncoder().encode(group)) | ||
} | ||
try BetaGroupFolderManager(path: outputPath) | ||
.save(groupsWithTesters: betaGroupWithTesters) | ||
} | ||
|
||
} |
86 changes: 51 additions & 35 deletions
86
Sources/AppStoreConnectCLI/Commands/TestFlight/BetaGroups/Sync/PushBetaGroupsCommand.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,68 +1,84 @@ | ||
// Copyright 2020 Itty Bitty Apps Pty Ltd | ||
|
||
import ArgumentParser | ||
import Foundation | ||
import Files | ||
|
||
struct PushBetaGroupsCommand: CommonParsableCommand { | ||
|
||
static var configuration = CommandConfiguration( | ||
commandName: "push", | ||
abstract: "TODO." | ||
abstract: "Push local beta group config files to server, update server beta groups" | ||
) | ||
|
||
@OptionGroup() | ||
var common: CommonOptions | ||
|
||
@Flag(help: "TODO") | ||
@Option( | ||
default: "./config/betagroups", | ||
help: "Path to the Folder containing the information about beta groups. (default: './config/betagroups')" | ||
) var inputPath: String | ||
|
||
@Flag(help: "Perform a dry run.") | ||
var dryRun: Bool | ||
|
||
func run() throws { | ||
let service = try makeService() | ||
let folderManager = BetaGroupFolderManager(path: inputPath) | ||
|
||
let serverGroups = Set(try service.pullBetaGroups().map{ $0.betaGroup }) | ||
let localGroups = Set(try folderManager.read()) | ||
|
||
let strategies = compareGroups( | ||
localGroups: localGroups, | ||
serverGroups: serverGroups | ||
) | ||
|
||
let renderer = Renderers.SyncResultRenderer<BetaGroup>() | ||
|
||
if dryRun { | ||
renderer.render(strategies, isDryRun: true) | ||
} else { | ||
try strategies.forEach { (strategy: SyncStrategy) in | ||
switch strategy { | ||
case .create(let group): | ||
_ = try service.createBetaGroup( | ||
appBundleId: group.app.bundleId!, | ||
groupName: group.groupName!, | ||
publicLinkEnabled: group.publicLinkEnabled ?? false, | ||
publicLinkLimit: group.publicLinkLimit | ||
) | ||
case .delete(let group): | ||
try service.deleteBetaGroup(with: group.id!) | ||
case .update(let group): | ||
try service.updateBetaGroup(betaGroup: group) | ||
} | ||
|
||
renderer.render(strategy, isDryRun: false) | ||
} | ||
|
||
var localGroups = Set<BetaGroup>() | ||
|
||
for file in try Folder(path: "./config/betagroups").files { | ||
if file.extension == "yml" { | ||
let group = Readers | ||
.FileReader<BetaGroup>(format: .yaml) | ||
.read(filePath: file.path) | ||
let betaGroupWithTesters = try service.pullBetaGroups() | ||
|
||
localGroups.insert(group) | ||
} | ||
try folderManager.save(groupsWithTesters: betaGroupWithTesters) | ||
} | ||
} | ||
|
||
func compareGroups(localGroups: Set<BetaGroup>, serverGroups: Set<BetaGroup>) -> [SyncStrategy<BetaGroup>] { | ||
var strategies: [SyncStrategy<BetaGroup>] = [] | ||
|
||
let groupToCreate = localGroups.subtracting(serverGroups) | ||
let groupToDelete = serverGroups.subtracting(localGroups) | ||
|
||
guard !dryRun else { | ||
groupToCreate.forEach { | ||
print("+\($0.groupName!)") | ||
groupToDelete.forEach { group in | ||
if !localGroups.contains(where: { group.id == $0.id }) { | ||
strategies.append(.delete(group)) | ||
} | ||
|
||
groupToDelete.forEach { | ||
print("-\($0.groupName!)") | ||
} | ||
return | ||
} | ||
|
||
try groupToDelete.forEach { | ||
try service.deleteBetaGroup(with: $0.id!) | ||
print("➖ \($0.groupName!)") | ||
groupToCreate.forEach { group in | ||
serverGroups.contains(where: { group.id == $0.id }) | ||
? strategies.append(.update(group)) | ||
: strategies.append(.create(group)) | ||
} | ||
|
||
try groupToCreate.forEach { | ||
_ = try service.createBetaGroup( | ||
appBundleId: $0.app.bundleId!, | ||
groupName: $0.groupName ?? "group name", | ||
publicLinkEnabled: $0.publicLinkEnabled ?? false, | ||
publicLinkLimit: $0.publicLinkLimit | ||
) | ||
|
||
print("➕ \($0.groupName!)") | ||
} | ||
return strategies | ||
} | ||
|
||
} |