Compare commits
1 Commits
dc99548d07
...
v0.1.2-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
584e77d29c |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -97,4 +97,4 @@ fastlane/test_output
|
||||
# https://github.com/johnno1962/injectionforxcode
|
||||
|
||||
iOSInjectionProject/
|
||||
|
||||
.DS_Store
|
||||
|
||||
69
.swift-format
Normal file
69
.swift-format
Normal file
@@ -0,0 +1,69 @@
|
||||
{
|
||||
"fileScopedDeclarationPrivacy" : {
|
||||
"accessLevel" : "private"
|
||||
},
|
||||
"indentation" : {
|
||||
"tabs" : 1
|
||||
},
|
||||
"indentConditionalCompilationBlocks" : true,
|
||||
"indentSwitchCaseLabels" : false,
|
||||
"lineBreakAroundMultilineExpressionChainComponents" : false,
|
||||
"lineBreakBeforeControlFlowKeywords" : false,
|
||||
"lineBreakBeforeEachArgument" : false,
|
||||
"lineBreakBeforeEachGenericRequirement" : false,
|
||||
"lineLength" : 80,
|
||||
"maximumBlankLines" : 1,
|
||||
"multiElementCollectionTrailingCommas" : true,
|
||||
"noAssignmentInExpressions" : {
|
||||
"allowedFunctions" : [
|
||||
"XCTAssertNoThrow"
|
||||
]
|
||||
},
|
||||
"prioritizeKeepingFunctionOutputTogether" : false,
|
||||
"respectsExistingLineBreaks" : true,
|
||||
"rules" : {
|
||||
"AllPublicDeclarationsHaveDocumentation" : false,
|
||||
"AlwaysUseLiteralForEmptyCollectionInit" : false,
|
||||
"AlwaysUseLowerCamelCase" : true,
|
||||
"AmbiguousTrailingClosureOverload" : true,
|
||||
"BeginDocumentationCommentWithOneLineSummary" : false,
|
||||
"DoNotUseSemicolons" : true,
|
||||
"DontRepeatTypeInStaticProperties" : true,
|
||||
"FileScopedDeclarationPrivacy" : true,
|
||||
"FullyIndirectEnum" : true,
|
||||
"GroupNumericLiterals" : true,
|
||||
"IdentifiersMustBeASCII" : true,
|
||||
"NeverForceUnwrap" : false,
|
||||
"NeverUseForceTry" : false,
|
||||
"NeverUseImplicitlyUnwrappedOptionals" : false,
|
||||
"NoAccessLevelOnExtensionDeclaration" : true,
|
||||
"NoAssignmentInExpressions" : true,
|
||||
"NoBlockComments" : true,
|
||||
"NoCasesWithOnlyFallthrough" : true,
|
||||
"NoEmptyTrailingClosureParentheses" : true,
|
||||
"NoLabelsInCasePatterns" : true,
|
||||
"NoLeadingUnderscores" : false,
|
||||
"NoParensAroundConditions" : true,
|
||||
"NoPlaygroundLiterals" : true,
|
||||
"NoVoidReturnOnFunctionSignature" : true,
|
||||
"OmitExplicitReturns" : false,
|
||||
"OneCasePerLine" : true,
|
||||
"OneVariableDeclarationPerLine" : true,
|
||||
"OnlyOneTrailingClosureArgument" : true,
|
||||
"OrderedImports" : true,
|
||||
"ReplaceForEachWithForLoop" : true,
|
||||
"ReturnVoidInsteadOfEmptyTuple" : true,
|
||||
"TypeNamesShouldBeCapitalized" : true,
|
||||
"UseEarlyExits" : false,
|
||||
"UseLetInEveryBoundCaseVariable" : true,
|
||||
"UseShorthandTypeNames" : true,
|
||||
"UseSingleLinePropertyGetter" : true,
|
||||
"UseSynthesizedInitializer" : true,
|
||||
"UseTripleSlashForDocumentationComments" : true,
|
||||
"UseWhereClausesInForLoops" : false,
|
||||
"ValidateDocumentationComments" : false
|
||||
},
|
||||
"spacesAroundRangeFormationOperators" : false,
|
||||
"tabWidth" : 4,
|
||||
"version" : 1
|
||||
}
|
||||
646
Brewer.xcodeproj/project.pbxproj
Normal file
646
Brewer.xcodeproj/project.pbxproj
Normal file
@@ -0,0 +1,646 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 56;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
9E6C73072C3D5E570056ADDC /* SearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6C73062C3D5E570056ADDC /* SearchView.swift */; };
|
||||
9E6C73092C3D5E950056ADDC /* InstalledView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6C73082C3D5E950056ADDC /* InstalledView.swift */; };
|
||||
9E6C730C2C3D796D0056ADDC /* DownloadButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6C730B2C3D796D0056ADDC /* DownloadButton.swift */; };
|
||||
9E6C730E2C3DB16F0056ADDC /* UninstallButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6C730D2C3DB16F0056ADDC /* UninstallButton.swift */; };
|
||||
9E6C73112C3DB5940056ADDC /* CaskDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6C73102C3DB5940056ADDC /* CaskDetailView.swift */; };
|
||||
9E6C73182C3E853E0056ADDC /* UpdateButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6C73172C3E853E0056ADDC /* UpdateButton.swift */; };
|
||||
9E8CE5362C3C545600A39146 /* BrewerApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E8CE5352C3C545600A39146 /* BrewerApp.swift */; };
|
||||
9E8CE5382C3C545600A39146 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E8CE5372C3C545600A39146 /* ContentView.swift */; };
|
||||
9E8CE53A2C3C545700A39146 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9E8CE5392C3C545700A39146 /* Assets.xcassets */; };
|
||||
9E8CE53D2C3C545700A39146 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9E8CE53C2C3C545700A39146 /* Preview Assets.xcassets */; };
|
||||
9E8CE5482C3C545800A39146 /* BrewerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E8CE5472C3C545800A39146 /* BrewerTests.swift */; };
|
||||
9E8CE5522C3C545800A39146 /* BrewerUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E8CE5512C3C545800A39146 /* BrewerUITests.swift */; };
|
||||
9E8CE5542C3C545800A39146 /* BrewerUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E8CE5532C3C545800A39146 /* BrewerUITestsLaunchTests.swift */; };
|
||||
9E8CE5622C3C5A6A00A39146 /* Homebrew.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E8CE5612C3C5A6A00A39146 /* Homebrew.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
9E8CE5442C3C545800A39146 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 9E8CE52A2C3C545600A39146 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 9E8CE5312C3C545600A39146;
|
||||
remoteInfo = Brewer;
|
||||
};
|
||||
9E8CE54E2C3C545800A39146 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 9E8CE52A2C3C545600A39146 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 9E8CE5312C3C545600A39146;
|
||||
remoteInfo = Brewer;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
9E6C73062C3D5E570056ADDC /* SearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchView.swift; sourceTree = "<group>"; };
|
||||
9E6C73082C3D5E950056ADDC /* InstalledView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstalledView.swift; sourceTree = "<group>"; };
|
||||
9E6C730B2C3D796D0056ADDC /* DownloadButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DownloadButton.swift; sourceTree = "<group>"; };
|
||||
9E6C730D2C3DB16F0056ADDC /* UninstallButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UninstallButton.swift; sourceTree = "<group>"; };
|
||||
9E6C73102C3DB5940056ADDC /* CaskDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CaskDetailView.swift; sourceTree = "<group>"; };
|
||||
9E6C73172C3E853E0056ADDC /* UpdateButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateButton.swift; sourceTree = "<group>"; };
|
||||
9E8CE5322C3C545600A39146 /* Brewer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Brewer.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9E8CE5352C3C545600A39146 /* BrewerApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrewerApp.swift; sourceTree = "<group>"; };
|
||||
9E8CE5372C3C545600A39146 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||
9E8CE5392C3C545700A39146 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
9E8CE53C2C3C545700A39146 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
||||
9E8CE53E2C3C545700A39146 /* Brewer.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Brewer.entitlements; sourceTree = "<group>"; };
|
||||
9E8CE5432C3C545800A39146 /* BrewerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BrewerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9E8CE5472C3C545800A39146 /* BrewerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrewerTests.swift; sourceTree = "<group>"; };
|
||||
9E8CE54D2C3C545800A39146 /* BrewerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BrewerUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9E8CE5512C3C545800A39146 /* BrewerUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrewerUITests.swift; sourceTree = "<group>"; };
|
||||
9E8CE5532C3C545800A39146 /* BrewerUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrewerUITestsLaunchTests.swift; sourceTree = "<group>"; };
|
||||
9E8CE5612C3C5A6A00A39146 /* Homebrew.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Homebrew.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
9E8CE52F2C3C545600A39146 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9E8CE5402C3C545800A39146 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9E8CE54A2C3C545800A39146 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
9E6C730A2C3D795D0056ADDC /* Components */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9E6C730B2C3D796D0056ADDC /* DownloadButton.swift */,
|
||||
9E6C73172C3E853E0056ADDC /* UpdateButton.swift */,
|
||||
9E6C730D2C3DB16F0056ADDC /* UninstallButton.swift */,
|
||||
);
|
||||
path = Components;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9E6C730F2C3DB5850056ADDC /* Details */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9E6C73102C3DB5940056ADDC /* CaskDetailView.swift */,
|
||||
);
|
||||
name = Details;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9E8CE5292C3C545600A39146 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9E8CE5342C3C545600A39146 /* Brewer */,
|
||||
9E8CE5462C3C545800A39146 /* BrewerTests */,
|
||||
9E8CE5502C3C545800A39146 /* BrewerUITests */,
|
||||
9E8CE5332C3C545600A39146 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9E8CE5332C3C545600A39146 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9E8CE5322C3C545600A39146 /* Brewer.app */,
|
||||
9E8CE5432C3C545800A39146 /* BrewerTests.xctest */,
|
||||
9E8CE54D2C3C545800A39146 /* BrewerUITests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9E8CE5342C3C545600A39146 /* Brewer */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9E6C730A2C3D795D0056ADDC /* Components */,
|
||||
9E8CE5602C3C5A5000A39146 /* Model */,
|
||||
9E8CE5352C3C545600A39146 /* BrewerApp.swift */,
|
||||
9E6C73062C3D5E570056ADDC /* SearchView.swift */,
|
||||
9E6C730F2C3DB5850056ADDC /* Details */,
|
||||
9E6C73082C3D5E950056ADDC /* InstalledView.swift */,
|
||||
9E8CE5372C3C545600A39146 /* ContentView.swift */,
|
||||
9E8CE5392C3C545700A39146 /* Assets.xcassets */,
|
||||
9E8CE53E2C3C545700A39146 /* Brewer.entitlements */,
|
||||
9E8CE53B2C3C545700A39146 /* Preview Content */,
|
||||
);
|
||||
path = Brewer;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9E8CE53B2C3C545700A39146 /* Preview Content */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9E8CE53C2C3C545700A39146 /* Preview Assets.xcassets */,
|
||||
);
|
||||
path = "Preview Content";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9E8CE5462C3C545800A39146 /* BrewerTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9E8CE5472C3C545800A39146 /* BrewerTests.swift */,
|
||||
);
|
||||
path = BrewerTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9E8CE5502C3C545800A39146 /* BrewerUITests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9E8CE5512C3C545800A39146 /* BrewerUITests.swift */,
|
||||
9E8CE5532C3C545800A39146 /* BrewerUITestsLaunchTests.swift */,
|
||||
);
|
||||
path = BrewerUITests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9E8CE5602C3C5A5000A39146 /* Model */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9E8CE5612C3C5A6A00A39146 /* Homebrew.swift */,
|
||||
);
|
||||
path = Model;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
9E8CE5312C3C545600A39146 /* Brewer */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 9E8CE5572C3C545800A39146 /* Build configuration list for PBXNativeTarget "Brewer" */;
|
||||
buildPhases = (
|
||||
9E8CE52E2C3C545600A39146 /* Sources */,
|
||||
9E8CE52F2C3C545600A39146 /* Frameworks */,
|
||||
9E8CE5302C3C545600A39146 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = Brewer;
|
||||
productName = Brewer;
|
||||
productReference = 9E8CE5322C3C545600A39146 /* Brewer.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
9E8CE5422C3C545800A39146 /* BrewerTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 9E8CE55A2C3C545800A39146 /* Build configuration list for PBXNativeTarget "BrewerTests" */;
|
||||
buildPhases = (
|
||||
9E8CE53F2C3C545800A39146 /* Sources */,
|
||||
9E8CE5402C3C545800A39146 /* Frameworks */,
|
||||
9E8CE5412C3C545800A39146 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
9E8CE5452C3C545800A39146 /* PBXTargetDependency */,
|
||||
);
|
||||
name = BrewerTests;
|
||||
productName = BrewerTests;
|
||||
productReference = 9E8CE5432C3C545800A39146 /* BrewerTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
9E8CE54C2C3C545800A39146 /* BrewerUITests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 9E8CE55D2C3C545800A39146 /* Build configuration list for PBXNativeTarget "BrewerUITests" */;
|
||||
buildPhases = (
|
||||
9E8CE5492C3C545800A39146 /* Sources */,
|
||||
9E8CE54A2C3C545800A39146 /* Frameworks */,
|
||||
9E8CE54B2C3C545800A39146 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
9E8CE54F2C3C545800A39146 /* PBXTargetDependency */,
|
||||
);
|
||||
name = BrewerUITests;
|
||||
productName = BrewerUITests;
|
||||
productReference = 9E8CE54D2C3C545800A39146 /* BrewerUITests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.ui-testing";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
9E8CE52A2C3C545600A39146 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
BuildIndependentTargetsInParallel = 1;
|
||||
LastSwiftUpdateCheck = 1540;
|
||||
LastUpgradeCheck = 1540;
|
||||
TargetAttributes = {
|
||||
9E8CE5312C3C545600A39146 = {
|
||||
CreatedOnToolsVersion = 15.4;
|
||||
};
|
||||
9E8CE5422C3C545800A39146 = {
|
||||
CreatedOnToolsVersion = 15.4;
|
||||
TestTargetID = 9E8CE5312C3C545600A39146;
|
||||
};
|
||||
9E8CE54C2C3C545800A39146 = {
|
||||
CreatedOnToolsVersion = 15.4;
|
||||
TestTargetID = 9E8CE5312C3C545600A39146;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 9E8CE52D2C3C545600A39146 /* Build configuration list for PBXProject "Brewer" */;
|
||||
compatibilityVersion = "Xcode 14.0";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 9E8CE5292C3C545600A39146;
|
||||
productRefGroup = 9E8CE5332C3C545600A39146 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
9E8CE5312C3C545600A39146 /* Brewer */,
|
||||
9E8CE5422C3C545800A39146 /* BrewerTests */,
|
||||
9E8CE54C2C3C545800A39146 /* BrewerUITests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
9E8CE5302C3C545600A39146 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9E8CE53D2C3C545700A39146 /* Preview Assets.xcassets in Resources */,
|
||||
9E8CE53A2C3C545700A39146 /* Assets.xcassets in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9E8CE5412C3C545800A39146 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9E8CE54B2C3C545800A39146 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
9E8CE52E2C3C545600A39146 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9E6C73072C3D5E570056ADDC /* SearchView.swift in Sources */,
|
||||
9E6C730C2C3D796D0056ADDC /* DownloadButton.swift in Sources */,
|
||||
9E8CE5382C3C545600A39146 /* ContentView.swift in Sources */,
|
||||
9E6C73182C3E853E0056ADDC /* UpdateButton.swift in Sources */,
|
||||
9E6C730E2C3DB16F0056ADDC /* UninstallButton.swift in Sources */,
|
||||
9E8CE5622C3C5A6A00A39146 /* Homebrew.swift in Sources */,
|
||||
9E6C73092C3D5E950056ADDC /* InstalledView.swift in Sources */,
|
||||
9E8CE5362C3C545600A39146 /* BrewerApp.swift in Sources */,
|
||||
9E6C73112C3DB5940056ADDC /* CaskDetailView.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9E8CE53F2C3C545800A39146 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9E8CE5482C3C545800A39146 /* BrewerTests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9E8CE5492C3C545800A39146 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9E8CE5522C3C545800A39146 /* BrewerUITests.swift in Sources */,
|
||||
9E8CE5542C3C545800A39146 /* BrewerUITestsLaunchTests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
9E8CE5452C3C545800A39146 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 9E8CE5312C3C545600A39146 /* Brewer */;
|
||||
targetProxy = 9E8CE5442C3C545800A39146 /* PBXContainerItemProxy */;
|
||||
};
|
||||
9E8CE54F2C3C545800A39146 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 9E8CE5312C3C545600A39146 /* Brewer */;
|
||||
targetProxy = 9E8CE54E2C3C545800A39146 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
9E8CE5552C3C545800A39146 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 14.5;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
9E8CE5562C3C545800A39146 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 14.5;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = macosx;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
9E8CE5582C3C545800A39146 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_ENTITLEMENTS = Brewer/Brewer.entitlements;
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = "0.1.2-beta";
|
||||
DEVELOPMENT_ASSET_PATHS = "\"Brewer/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = 96S93Z7LTG;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = Brewer;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||
INFOPLIST_KEY_LSUIElement = YES;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = "0.1.2-beta";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = dev.cems.Brewer;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
9E8CE5592C3C545800A39146 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_ENTITLEMENTS = Brewer/Brewer.entitlements;
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = "0.1.2-beta";
|
||||
DEVELOPMENT_ASSET_PATHS = "\"Brewer/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = 96S93Z7LTG;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = Brewer;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||
INFOPLIST_KEY_LSUIElement = YES;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = "0.1.2-beta";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = dev.cems.Brewer;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
9E8CE55B2C3C545800A39146 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = 96S93Z7LTG;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 14.5;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = dev.cems.BrewerTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Brewer.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Brewer";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
9E8CE55C2C3C545800A39146 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = 96S93Z7LTG;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 14.5;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = dev.cems.BrewerTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Brewer.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Brewer";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
9E8CE55E2C3C545800A39146 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = 96S93Z7LTG;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = dev.cems.BrewerUITests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TEST_TARGET_NAME = Brewer;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
9E8CE55F2C3C545800A39146 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = 96S93Z7LTG;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = dev.cems.BrewerUITests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TEST_TARGET_NAME = Brewer;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
9E8CE52D2C3C545600A39146 /* Build configuration list for PBXProject "Brewer" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
9E8CE5552C3C545800A39146 /* Debug */,
|
||||
9E8CE5562C3C545800A39146 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
9E8CE5572C3C545800A39146 /* Build configuration list for PBXNativeTarget "Brewer" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
9E8CE5582C3C545800A39146 /* Debug */,
|
||||
9E8CE5592C3C545800A39146 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
9E8CE55A2C3C545800A39146 /* Build configuration list for PBXNativeTarget "BrewerTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
9E8CE55B2C3C545800A39146 /* Debug */,
|
||||
9E8CE55C2C3C545800A39146 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
9E8CE55D2C3C545800A39146 /* Build configuration list for PBXNativeTarget "BrewerUITests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
9E8CE55E2C3C545800A39146 /* Debug */,
|
||||
9E8CE55F2C3C545800A39146 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 9E8CE52A2C3C545600A39146 /* Project object */;
|
||||
}
|
||||
7
Brewer.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
Brewer.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:/Volumes/Data/Projects/Brewer/Brewer.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
11
Brewer/Assets.xcassets/AccentColor.colorset/Contents.json
Normal file
11
Brewer/Assets.xcassets/AccentColor.colorset/Contents.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
58
Brewer/Assets.xcassets/AppIcon.appiconset/Contents.json
Normal file
58
Brewer/Assets.xcassets/AppIcon.appiconset/Contents.json
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "16x16"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "16x16"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "32x32"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "32x32"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "128x128"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "128x128"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "256x256"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "256x256"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "512x512"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "512x512"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
6
Brewer/Assets.xcassets/Contents.json
Normal file
6
Brewer/Assets.xcassets/Contents.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
5
Brewer/Brewer.entitlements
Normal file
5
Brewer/Brewer.entitlements
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict/>
|
||||
</plist>
|
||||
62
Brewer/BrewerApp.swift
Normal file
62
Brewer/BrewerApp.swift
Normal file
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// BrewerApp.swift
|
||||
// Brewer
|
||||
//
|
||||
// Created by Cédric MAS on 08/07/2024.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
@main
|
||||
struct BrewerApp: App {
|
||||
@AppStorage("isUpToDate") var isUpToDate: Bool = true
|
||||
init() {
|
||||
do {
|
||||
let res = try shell(
|
||||
"/opt/homebrew/bin/brew outdated --greedy-latest -g | wc -l")
|
||||
if let number = Int(
|
||||
res.trimmingCharacters(in: .whitespacesAndNewlines)), number > 0
|
||||
{
|
||||
print(number)
|
||||
isUpToDate = false
|
||||
}
|
||||
} catch {
|
||||
print(error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
var body: some Scene {
|
||||
MenuBarExtra {
|
||||
VStack(spacing: 0) {
|
||||
ContentView()
|
||||
.padding()
|
||||
.padding(.bottom, 0)
|
||||
Button {
|
||||
NSApplication.shared.terminate(self)
|
||||
} label: {
|
||||
Label("Quit", systemImage: "x")
|
||||
.symbolRenderingMode(.palette)
|
||||
.symbolVariant(.circle)
|
||||
.symbolVariant(.fill)
|
||||
.foregroundStyle(.white, .red)
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .trailing)
|
||||
.padding()
|
||||
.padding(.top, 0)
|
||||
}
|
||||
} label: {
|
||||
if isUpToDate {
|
||||
Label("Brewer", systemImage: "sparkle.magnifyingglass")
|
||||
} else {
|
||||
Label("Brewer", systemImage: "sparkle.magnifyingglass")
|
||||
.symbolRenderingMode(.palette)
|
||||
.foregroundStyle(.orange)
|
||||
}
|
||||
}
|
||||
.menuBarExtraStyle(.window)
|
||||
WindowGroup {
|
||||
EmptyView()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
39
Brewer/CaskDetailView.swift
Normal file
39
Brewer/CaskDetailView.swift
Normal file
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// CaskDetailView.swift
|
||||
// Brewer
|
||||
//
|
||||
// Created by Cédric MAS on 09/07/2024.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct CaskDetailView: View {
|
||||
var cask: Cask
|
||||
@Bindable var brewListing: Homebrew
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
VStack {
|
||||
Text("Identifier: \(cask.fullToken)")
|
||||
Text("Version: \(cask.version)")
|
||||
}
|
||||
.navigationTitle(cask.name.first ?? cask.fullToken)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .primaryAction) {
|
||||
if cask.installed == nil {
|
||||
DownloadButton(name: cask.fullToken, isCask: true)
|
||||
} else if cask.outdated {
|
||||
Button("Update") {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
if cask.installed != nil {
|
||||
ToolbarItem(placement: .primaryAction) {
|
||||
UninstallButton(
|
||||
name: cask.fullToken, brewListing: brewListing)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
53
Brewer/Components/DownloadButton.swift
Normal file
53
Brewer/Components/DownloadButton.swift
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// DownloadButton.swift
|
||||
// Brewer
|
||||
//
|
||||
// Created by Cédric MAS on 09/07/2024.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct DownloadButton: View {
|
||||
let name: String
|
||||
var isCask: Bool = false
|
||||
@State private var brew = Homebrew()
|
||||
@State private var downloaded = false
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
if downloaded {
|
||||
Image(systemName: "checkmark")
|
||||
.symbolRenderingMode(.palette)
|
||||
.symbolVariant(.circle)
|
||||
.symbolVariant(.fill)
|
||||
.foregroundStyle(.white, .green)
|
||||
} else if brew.isLoading {
|
||||
ProgressView()
|
||||
.controlSize(.small)
|
||||
} else if brew.errorMessage != nil {
|
||||
Image(systemName: "x")
|
||||
.symbolRenderingMode(.palette)
|
||||
.symbolVariant(.circle)
|
||||
.symbolVariant(.fill)
|
||||
.foregroundStyle(.white, .red)
|
||||
} else {
|
||||
Button("Get") {
|
||||
Task {
|
||||
downloaded = await brew.install(name, isCask: isCask)
|
||||
}
|
||||
}
|
||||
.buttonBorderShape(.capsule)
|
||||
.buttonStyle(.borderedProminent)
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
Task {
|
||||
downloaded = await brew.isDownloaded(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
DownloadButton(name: "firefox")
|
||||
}
|
||||
45
Brewer/Components/UninstallButton.swift
Normal file
45
Brewer/Components/UninstallButton.swift
Normal file
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// UninstallButton.swift
|
||||
// Brewer
|
||||
//
|
||||
// Created by Cédric MAS on 09/07/2024.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct UninstallButton: View {
|
||||
let name: String
|
||||
@State private var brew = Homebrew()
|
||||
@State private var uninstalled = false
|
||||
@Bindable var brewListing: Homebrew
|
||||
var body: some View {
|
||||
VStack {
|
||||
if uninstalled {
|
||||
EmptyView()
|
||||
} else if brew.isLoading {
|
||||
ProgressView()
|
||||
.controlSize(.small)
|
||||
} else if brew.errorMessage != nil {
|
||||
Image(systemName: "x")
|
||||
.symbolRenderingMode(.palette)
|
||||
.symbolVariant(.circle)
|
||||
.symbolVariant(.fill)
|
||||
.foregroundStyle(.white, .red)
|
||||
} else {
|
||||
Button("Uninstall", role: .destructive) {
|
||||
Task {
|
||||
uninstalled = await brew.uninstall(name)
|
||||
brewListing.getInstalled()
|
||||
}
|
||||
}
|
||||
.buttonBorderShape(.capsule)
|
||||
.buttonStyle(.borderedProminent)
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
Task {
|
||||
uninstalled = await brew.isDownloaded(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
61
Brewer/Components/UpdateButton.swift
Normal file
61
Brewer/Components/UpdateButton.swift
Normal file
@@ -0,0 +1,61 @@
|
||||
//
|
||||
// UpdateButton.swift
|
||||
// Brewer
|
||||
//
|
||||
// Created by Cédric MAS on 10/07/2024.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct UpdateButton: View {
|
||||
let name: String
|
||||
@State private var brew = Homebrew()
|
||||
@State private var newInfo = Homebrew()
|
||||
|
||||
private var updated: String? {
|
||||
if let cask = newInfo.data?.casks.first(where: { $0.fullToken == name }
|
||||
), !cask.outdated {
|
||||
return cask.version
|
||||
}
|
||||
if let formulae = newInfo.data?.formulae.first(where: {
|
||||
$0.fullName == name
|
||||
}), !formulae.outdated {
|
||||
return formulae.versions.stable
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
if let newVersion = updated {
|
||||
Text("Updated: \(newVersion)")
|
||||
} else if brew.isLoading {
|
||||
ProgressView()
|
||||
.controlSize(.small)
|
||||
} else if brew.errorMessage != nil {
|
||||
Image(systemName: "x")
|
||||
.symbolRenderingMode(.palette)
|
||||
.symbolVariant(.circle)
|
||||
.symbolVariant(.fill)
|
||||
.foregroundStyle(.white, .red)
|
||||
} else {
|
||||
Button {
|
||||
Task {
|
||||
await brew.update(name)
|
||||
newInfo.getInfo(on: name)
|
||||
}
|
||||
} label: {
|
||||
Label(
|
||||
"Update",
|
||||
systemImage:
|
||||
"arrow.counterclockwise"
|
||||
)
|
||||
.symbolRenderingMode(.palette)
|
||||
.symbolVariant(.circle)
|
||||
.symbolVariant(.fill)
|
||||
.foregroundStyle(
|
||||
.white, .orange)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
39
Brewer/ContentView.swift
Normal file
39
Brewer/ContentView.swift
Normal file
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// ContentView.swift
|
||||
// Brewer
|
||||
//
|
||||
// Created by Cédric MAS on 08/07/2024.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
enum SegementedSelection: String, CaseIterable {
|
||||
case search = "Search"
|
||||
case installed = "Installed"
|
||||
}
|
||||
|
||||
struct ContentView: View {
|
||||
@State private var segmentedSelection: SegementedSelection = .search
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
VStack {
|
||||
Picker("", selection: $segmentedSelection) {
|
||||
ForEach(SegementedSelection.allCases, id: \.self) { sel in
|
||||
Text(sel.rawValue).tag(sel)
|
||||
}
|
||||
}.pickerStyle(.segmented)
|
||||
.padding(.leading, -8)
|
||||
switch segmentedSelection {
|
||||
case .search:
|
||||
SearchView()
|
||||
case .installed:
|
||||
InstalledView()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
ContentView()
|
||||
}
|
||||
106
Brewer/InstalledView.swift
Normal file
106
Brewer/InstalledView.swift
Normal file
@@ -0,0 +1,106 @@
|
||||
//
|
||||
// InstalledView.swift
|
||||
// Brewer
|
||||
//
|
||||
// Created by Cédric MAS on 09/07/2024.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct InstalledView: View {
|
||||
@State private var brew = Homebrew()
|
||||
var body: some View {
|
||||
VStack {
|
||||
if brew.isLoading {
|
||||
ProgressView("Loading...")
|
||||
} else if let data = brew.data {
|
||||
List {
|
||||
if !data.casks.isEmpty {
|
||||
Section {
|
||||
ForEach(data.casks, id: \.fullToken) { cask in
|
||||
NavigationLink {
|
||||
CaskDetailView(
|
||||
cask: cask, brewListing: brew)
|
||||
} label: {
|
||||
HStack {
|
||||
Text(cask.name.first ?? cask.fullToken)
|
||||
Spacer()
|
||||
if cask.outdated {
|
||||
UpdateButton(name: cask.fullToken)
|
||||
} else {
|
||||
Text(cask.version)
|
||||
}
|
||||
}
|
||||
.contextMenu {
|
||||
UninstallButton(
|
||||
name: cask.fullToken,
|
||||
brewListing: brew)
|
||||
}
|
||||
}
|
||||
}
|
||||
} header: {
|
||||
HStack {
|
||||
Text("Casks")
|
||||
Spacer()
|
||||
Text("\(data.casks.count) installed")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !data.formulae.isEmpty {
|
||||
Section {
|
||||
ForEach(data.formulae, id: \.fullName) { formulae in
|
||||
HStack {
|
||||
Text(formulae.fullName)
|
||||
Spacer()
|
||||
if formulae.outdated {
|
||||
UpdateButton(name: formulae.fullName)
|
||||
} else {
|
||||
Text(formulae.versions.stable)
|
||||
}
|
||||
}
|
||||
.contextMenu {
|
||||
UninstallButton(
|
||||
name: formulae.fullName,
|
||||
brewListing: brew)
|
||||
}
|
||||
}
|
||||
} header: {
|
||||
HStack {
|
||||
Text("Formulae")
|
||||
Spacer()
|
||||
Text("\(data.formulae.count) installed")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.listStyle(.inset(alternatesRowBackgrounds: true))
|
||||
let areOutdated =
|
||||
data.casks.filter(\.outdated).count
|
||||
+ data.formulae.filter(\.outdated).count
|
||||
let _ = UserDefaults.standard.set(
|
||||
!(areOutdated > 0), forKey: "isUpToDate")
|
||||
if areOutdated > 0 {
|
||||
Button {
|
||||
|
||||
} label: {
|
||||
Label(
|
||||
"Update all",
|
||||
systemImage: "arrow.counterclockwise.circle.fill")
|
||||
}
|
||||
.buttonStyle(.borderedProminent)
|
||||
.tint(.orange)
|
||||
}
|
||||
} else if let error = brew.errorMessage {
|
||||
Text(error)
|
||||
.foregroundStyle(.red)
|
||||
}
|
||||
}.task {
|
||||
brew.getInstalled()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
InstalledView()
|
||||
}
|
||||
248
Brewer/Model/Homebrew.swift
Normal file
248
Brewer/Model/Homebrew.swift
Normal file
@@ -0,0 +1,248 @@
|
||||
//
|
||||
// Cask.swift
|
||||
// Brewer
|
||||
//
|
||||
// Created by Cédric MAS on 08/07/2024.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum ShellError: Error {
|
||||
case emptyOutput
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
func shell(_ command: String) throws -> String {
|
||||
let task = Process()
|
||||
task.executableURL = URL(filePath: "/bin/bash")
|
||||
task.arguments = ["-c", command]
|
||||
|
||||
let pipe = Pipe()
|
||||
task.standardError = pipe
|
||||
task.standardOutput = pipe
|
||||
|
||||
try task.run()
|
||||
if let data = try pipe.fileHandleForReading.readToEnd(),
|
||||
let output = String(data: data, encoding: .utf8)
|
||||
{
|
||||
return output
|
||||
}
|
||||
|
||||
throw ShellError.emptyOutput
|
||||
}
|
||||
|
||||
struct Cask: Codable {
|
||||
let token: String
|
||||
let fullToken: String
|
||||
let tap: String
|
||||
let name: [String]
|
||||
let desc: String
|
||||
let homepage: String
|
||||
let url: String
|
||||
let version: String
|
||||
let installed: String?
|
||||
var outdated: Bool
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case token, tap, name, desc, homepage, url, version, installed, outdated
|
||||
case fullToken = "full_token"
|
||||
}
|
||||
}
|
||||
|
||||
struct Formulae: Codable {
|
||||
|
||||
struct Version: Codable {
|
||||
let stable: String
|
||||
let head: String?
|
||||
let bottle: Bool
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case stable
|
||||
case head, bottle
|
||||
}
|
||||
}
|
||||
|
||||
let name: String
|
||||
let fullName: String
|
||||
let tap: String
|
||||
let oldNames: [String]
|
||||
let aliases: [String]
|
||||
let versionedFormulae: [String]
|
||||
let desc: String
|
||||
let license: String?
|
||||
let homepage: String
|
||||
let versions: Version
|
||||
let outdated: Bool
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case name
|
||||
case tap
|
||||
case aliases
|
||||
case desc
|
||||
case license
|
||||
case homepage
|
||||
case versions
|
||||
case outdated
|
||||
case fullName = "full_name"
|
||||
case oldNames = "oldnames"
|
||||
case versionedFormulae = "versioned_formulae"
|
||||
}
|
||||
}
|
||||
|
||||
struct InfoResponse: Codable {
|
||||
let formulae: [Formulae]
|
||||
let casks: [Cask]
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case casks
|
||||
case formulae
|
||||
}
|
||||
}
|
||||
|
||||
@Observable
|
||||
class Homebrew {
|
||||
var data: InfoResponse?
|
||||
var isLoading = false
|
||||
var errorMessage: String?
|
||||
|
||||
func getInfo(on query: String) {
|
||||
self.isLoading = true
|
||||
self.errorMessage = nil
|
||||
self.data = nil
|
||||
Task { [weak self] in
|
||||
do {
|
||||
let res = try shell(
|
||||
"/opt/homebrew/bin/brew info --json=v2 \(query)")
|
||||
if let data = res.data(using: .utf8) {
|
||||
let output = try JSONDecoder().decode(
|
||||
InfoResponse.self, from: data)
|
||||
self?.data = output
|
||||
}
|
||||
} catch {
|
||||
self?.errorMessage = error.localizedDescription
|
||||
}
|
||||
self?.isLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
func getInstalled() {
|
||||
self.isLoading = true
|
||||
self.data = nil
|
||||
self.errorMessage = nil
|
||||
Task { [weak self] in
|
||||
do {
|
||||
let res = try shell(
|
||||
"/opt/homebrew/bin/brew info --json=v2 --installed")
|
||||
if let data = res.data(using: .utf8) {
|
||||
let output = try JSONDecoder().decode(
|
||||
InfoResponse.self, from: data)
|
||||
self?.data = output
|
||||
}
|
||||
} catch {
|
||||
self?.errorMessage = error.localizedDescription
|
||||
}
|
||||
self?.isLoading = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func isDownloaded(_ name: String) async -> Bool {
|
||||
self.isLoading = true
|
||||
self.errorMessage = nil
|
||||
self.data = nil
|
||||
let task = Task { [weak self] in
|
||||
do {
|
||||
let res = try shell(
|
||||
"/opt/homebrew/bin/brew list -1 \(name) >/dev/null 2>&1; echo $?"
|
||||
)
|
||||
.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
self?.isLoading = false
|
||||
return res == "0"
|
||||
} catch {
|
||||
self?.errorMessage = error.localizedDescription
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
switch await task.result {
|
||||
case .success(let success):
|
||||
return success
|
||||
case .failure(let fail):
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func install(_ fullToken: String, isCask: Bool = false) async -> Bool {
|
||||
self.isLoading = true
|
||||
self.data = nil
|
||||
let task = Task { [weak self] in
|
||||
do {
|
||||
try shell(
|
||||
"/opt/homebrew/bin/brew install \(isCask ? "--cask" : "") \(fullToken)"
|
||||
)
|
||||
} catch {
|
||||
self?.errorMessage = error.localizedDescription
|
||||
}
|
||||
self?.isLoading = false
|
||||
return await self?.isDownloaded(fullToken) ?? false
|
||||
}
|
||||
|
||||
return switch await task.result {
|
||||
case .success(let success):
|
||||
success
|
||||
case .failure:
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
func uninstall(_ fullToken: String) async -> Bool {
|
||||
self.isLoading = true
|
||||
self.data = nil
|
||||
let task = Task { [weak self] in
|
||||
do {
|
||||
try shell(
|
||||
"/opt/homebrew/bin/brew uninstall \(fullToken)"
|
||||
)
|
||||
} catch {
|
||||
self?.errorMessage = error.localizedDescription
|
||||
}
|
||||
self?.isLoading = false
|
||||
return await !(self?.isDownloaded(fullToken) ?? true)
|
||||
}
|
||||
|
||||
return switch await task.result {
|
||||
case .success(let success):
|
||||
success
|
||||
case .failure:
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
func update(_ name: String) async -> Bool {
|
||||
self.isLoading = true
|
||||
self.errorMessage = nil
|
||||
self.data = nil
|
||||
let task = Task { [weak self] in
|
||||
do {
|
||||
let res = try shell(
|
||||
"/opt/homebrew/bin/brew upgrade \(name); echo $?"
|
||||
)
|
||||
.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
self?.isLoading = false
|
||||
return res == "0"
|
||||
} catch {
|
||||
self?.errorMessage = error.localizedDescription
|
||||
}
|
||||
self?.isLoading = false
|
||||
return false
|
||||
}
|
||||
|
||||
return switch await task.result {
|
||||
case .success(let success):
|
||||
success
|
||||
case .failure:
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
66
Brewer/SearchView.swift
Normal file
66
Brewer/SearchView.swift
Normal file
@@ -0,0 +1,66 @@
|
||||
//
|
||||
// SearchView.swift
|
||||
// Brewer
|
||||
//
|
||||
// Created by Cédric MAS on 09/07/2024.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct SearchView: View {
|
||||
@State private var query = ""
|
||||
@State private var brew = Homebrew()
|
||||
var body: some View {
|
||||
VStack {
|
||||
TextField("Search", text: $query)
|
||||
.onSubmit {
|
||||
brew.getInfo(on: query)
|
||||
}
|
||||
Spacer()
|
||||
if brew.isLoading {
|
||||
ProgressView("Loading...")
|
||||
} else if let data = brew.data {
|
||||
List {
|
||||
if !data.casks.isEmpty {
|
||||
Section("Casks") {
|
||||
ForEach(data.casks, id: \.fullToken) { cask in
|
||||
HStack {
|
||||
Text(cask.fullToken)
|
||||
Spacer()
|
||||
if cask.installed != nil {
|
||||
Image(
|
||||
systemName: "checkmark.circle.fill"
|
||||
)
|
||||
.symbolRenderingMode(.palette)
|
||||
.foregroundStyle(.white, .green)
|
||||
} else {
|
||||
DownloadButton(
|
||||
name: cask.fullToken, isCask: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !data.formulae.isEmpty {
|
||||
|
||||
Section("Formulaes") {
|
||||
ForEach(data.formulae, id: \.fullName) { formulae in
|
||||
HStack {
|
||||
Text(formulae.fullName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if let errorMessage = brew.errorMessage {
|
||||
Text(errorMessage)
|
||||
.foregroundStyle(.red)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#Preview {
|
||||
SearchView()
|
||||
}
|
||||
226
Brewer/formulae.json
Normal file
226
Brewer/formulae.json
Normal file
@@ -0,0 +1,226 @@
|
||||
{
|
||||
"name": "aom",
|
||||
"full_name": "aom",
|
||||
"tap": "homebrew/core",
|
||||
"oldnames": [],
|
||||
"aliases": [],
|
||||
"versioned_formulae": [],
|
||||
"desc": "Codec library for encoding and decoding AV1 video streams",
|
||||
"license": "BSD-2-Clause",
|
||||
"homepage": "https://aomedia.googlesource.com/aom",
|
||||
"versions": {
|
||||
"stable": "3.9.1",
|
||||
"head": null,
|
||||
"bottle": true
|
||||
},
|
||||
"urls": {
|
||||
"stable": {
|
||||
"url": "https://aomedia.googlesource.com/aom.git",
|
||||
"tag": "v3.9.1",
|
||||
"revision": "8ad484f8a18ed1853c094e7d3a4e023b2a92df28",
|
||||
"using": null,
|
||||
"checksum": null
|
||||
}
|
||||
},
|
||||
"revision": 0,
|
||||
"version_scheme": 0,
|
||||
"bottle": {
|
||||
"stable": {
|
||||
"rebuild": 0,
|
||||
"root_url": "https://ghcr.io/v2/homebrew/core",
|
||||
"files": {
|
||||
"arm64_sonoma": {
|
||||
"cellar": ":any",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/aom/blobs/sha256:8cb9a41dca274a535e5cf7ea728a694f3e9621d97ea48fa8fd270cd5d99f0347",
|
||||
"sha256": "8cb9a41dca274a535e5cf7ea728a694f3e9621d97ea48fa8fd270cd5d99f0347"
|
||||
},
|
||||
"arm64_ventura": {
|
||||
"cellar": ":any",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/aom/blobs/sha256:7b35304138ab104ff4c05cc78d16fdd6f3a4a19393d50cab274356f0dfc72479",
|
||||
"sha256": "7b35304138ab104ff4c05cc78d16fdd6f3a4a19393d50cab274356f0dfc72479"
|
||||
},
|
||||
"arm64_monterey": {
|
||||
"cellar": ":any",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/aom/blobs/sha256:1274fcede1882cd3cd3f176e2a44f461e3dba57f2fa77151722774c77753455b",
|
||||
"sha256": "1274fcede1882cd3cd3f176e2a44f461e3dba57f2fa77151722774c77753455b"
|
||||
},
|
||||
"sonoma": {
|
||||
"cellar": ":any",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/aom/blobs/sha256:cb0a6ac49c83d5377c1fe7fdc4df43e403af231c2d6db3398b01cd70b31f1ab7",
|
||||
"sha256": "cb0a6ac49c83d5377c1fe7fdc4df43e403af231c2d6db3398b01cd70b31f1ab7"
|
||||
},
|
||||
"ventura": {
|
||||
"cellar": ":any",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/aom/blobs/sha256:7410d19b27f952bc12722457ea58b904a6de0416f3d7ada42cfad2b1cd67e795",
|
||||
"sha256": "7410d19b27f952bc12722457ea58b904a6de0416f3d7ada42cfad2b1cd67e795"
|
||||
},
|
||||
"monterey": {
|
||||
"cellar": ":any",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/aom/blobs/sha256:9abf106327c58ffaae970744caad8b9bdace79220ba3ecf4e47fe4eb500f6fb0",
|
||||
"sha256": "9abf106327c58ffaae970744caad8b9bdace79220ba3ecf4e47fe4eb500f6fb0"
|
||||
},
|
||||
"x86_64_linux": {
|
||||
"cellar": ":any_skip_relocation",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/aom/blobs/sha256:d018fbe0e71201de17504c3a5ed73f3499dfd36b1b07a09173e826418abd00b8",
|
||||
"sha256": "d018fbe0e71201de17504c3a5ed73f3499dfd36b1b07a09173e826418abd00b8"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"pour_bottle_only_if": null,
|
||||
"keg_only": false,
|
||||
"keg_only_reason": null,
|
||||
"options": [],
|
||||
"build_dependencies": [
|
||||
"cmake",
|
||||
"pkg-config"
|
||||
],
|
||||
"dependencies": [
|
||||
"jpeg-xl",
|
||||
"libvmaf"
|
||||
],
|
||||
"test_dependencies": [],
|
||||
"recommended_dependencies": [],
|
||||
"optional_dependencies": [],
|
||||
"uses_from_macos": [],
|
||||
"uses_from_macos_bounds": [],
|
||||
"requirements": [],
|
||||
"conflicts_with": [],
|
||||
"conflicts_with_reasons": [],
|
||||
"link_overwrite": [],
|
||||
"caveats": null,
|
||||
"installed": [
|
||||
{
|
||||
"version": "3.9.1",
|
||||
"used_options": [],
|
||||
"built_as_bottle": true,
|
||||
"poured_from_bottle": true,
|
||||
"time": 1718172114,
|
||||
"runtime_dependencies": [
|
||||
{
|
||||
"full_name": "brotli",
|
||||
"version": "1.1.0",
|
||||
"revision": 0,
|
||||
"pkg_version": "1.1.0",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "giflib",
|
||||
"version": "5.2.2",
|
||||
"revision": 0,
|
||||
"pkg_version": "5.2.2",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "highway",
|
||||
"version": "1.2.0",
|
||||
"revision": 0,
|
||||
"pkg_version": "1.2.0",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "imath",
|
||||
"version": "3.1.11",
|
||||
"revision": 0,
|
||||
"pkg_version": "3.1.11",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "jpeg-turbo",
|
||||
"version": "3.0.3",
|
||||
"revision": 0,
|
||||
"pkg_version": "3.0.3",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "libpng",
|
||||
"version": "1.6.43",
|
||||
"revision": 0,
|
||||
"pkg_version": "1.6.43",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "xz",
|
||||
"version": "5.4.6",
|
||||
"revision": 0,
|
||||
"pkg_version": "5.4.6",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "lz4",
|
||||
"version": "1.9.4",
|
||||
"revision": 0,
|
||||
"pkg_version": "1.9.4",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "zstd",
|
||||
"version": "1.5.6",
|
||||
"revision": 0,
|
||||
"pkg_version": "1.5.6",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "libtiff",
|
||||
"version": "4.6.0",
|
||||
"revision": 0,
|
||||
"pkg_version": "4.6.0",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "little-cms2",
|
||||
"version": "2.16",
|
||||
"revision": 0,
|
||||
"pkg_version": "2.16",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "openexr",
|
||||
"version": "3.2.4",
|
||||
"revision": 0,
|
||||
"pkg_version": "3.2.4",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "webp",
|
||||
"version": "1.4.0",
|
||||
"revision": 0,
|
||||
"pkg_version": "1.4.0",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "jpeg-xl",
|
||||
"version": "0.10.2",
|
||||
"revision": 0,
|
||||
"pkg_version": "0.10.2",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
"full_name": "libvmaf",
|
||||
"version": "3.0.0",
|
||||
"revision": 0,
|
||||
"pkg_version": "3.0.0",
|
||||
"declared_directly": true
|
||||
}
|
||||
],
|
||||
"installed_as_dependency": true,
|
||||
"installed_on_request": false
|
||||
}
|
||||
],
|
||||
"linked_keg": "3.9.1",
|
||||
"pinned": false,
|
||||
"outdated": false,
|
||||
"deprecated": false,
|
||||
"deprecation_date": null,
|
||||
"deprecation_reason": null,
|
||||
"disabled": false,
|
||||
"disable_date": null,
|
||||
"disable_reason": null,
|
||||
"post_install_defined": false,
|
||||
"service": null,
|
||||
"tap_git_head": "e63757f09f6098330ee6073b756d52e9e4957b4b",
|
||||
"ruby_source_path": "Formula/a/aom.rb",
|
||||
"ruby_source_checksum": {
|
||||
"sha256": "3de11c9a16f43364bf721cb6253993143ca9e5c9baeef1e6cb6170ecb176524f"
|
||||
}
|
||||
}
|
||||
37
BrewerTests/BrewerTests.swift
Normal file
37
BrewerTests/BrewerTests.swift
Normal file
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// BrewerTests.swift
|
||||
// BrewerTests
|
||||
//
|
||||
// Created by Cédric MAS on 08/07/2024.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
|
||||
@testable import Brewer
|
||||
|
||||
final class BrewerTests: XCTestCase {
|
||||
|
||||
override func setUpWithError() throws {
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
override func tearDownWithError() throws {
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
func testExample() throws {
|
||||
// This is an example of a functional test case.
|
||||
// Use XCTAssert and related functions to verify your tests produce the correct results.
|
||||
// Any test you write for XCTest can be annotated as throws and async.
|
||||
// Mark your test throws to produce an unexpected failure when your test encounters an uncaught error.
|
||||
// Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards.
|
||||
}
|
||||
|
||||
func testPerformanceExample() throws {
|
||||
// This is an example of a performance test case.
|
||||
self.measure {
|
||||
// Put the code you want to measure the time of here.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
41
BrewerUITests/BrewerUITests.swift
Normal file
41
BrewerUITests/BrewerUITests.swift
Normal file
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// BrewerUITests.swift
|
||||
// BrewerUITests
|
||||
//
|
||||
// Created by Cédric MAS on 08/07/2024.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
|
||||
final class BrewerUITests: XCTestCase {
|
||||
|
||||
override func setUpWithError() throws {
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
|
||||
// In UI tests it is usually best to stop immediately when a failure occurs.
|
||||
continueAfterFailure = false
|
||||
|
||||
// In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
|
||||
}
|
||||
|
||||
override func tearDownWithError() throws {
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
func testExample() throws {
|
||||
// UI tests must launch the application that they test.
|
||||
let app = XCUIApplication()
|
||||
app.launch()
|
||||
|
||||
// Use XCTAssert and related functions to verify your tests produce the correct results.
|
||||
}
|
||||
|
||||
func testLaunchPerformance() throws {
|
||||
if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
|
||||
// This measures how long it takes to launch your application.
|
||||
measure(metrics: [XCTApplicationLaunchMetric()]) {
|
||||
XCUIApplication().launch()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
32
BrewerUITests/BrewerUITestsLaunchTests.swift
Normal file
32
BrewerUITests/BrewerUITestsLaunchTests.swift
Normal file
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// BrewerUITestsLaunchTests.swift
|
||||
// BrewerUITests
|
||||
//
|
||||
// Created by Cédric MAS on 08/07/2024.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
|
||||
final class BrewerUITestsLaunchTests: XCTestCase {
|
||||
|
||||
override class var runsForEachTargetApplicationUIConfiguration: Bool {
|
||||
true
|
||||
}
|
||||
|
||||
override func setUpWithError() throws {
|
||||
continueAfterFailure = false
|
||||
}
|
||||
|
||||
func testLaunch() throws {
|
||||
let app = XCUIApplication()
|
||||
app.launch()
|
||||
|
||||
// Insert steps here to perform after app launch but before taking a screenshot,
|
||||
// such as logging into a test account or navigating somewhere in the app
|
||||
|
||||
let attachment = XCTAttachment(screenshot: app.screenshot())
|
||||
attachment.name = "Launch Screen"
|
||||
attachment.lifetime = .keepAlways
|
||||
add(attachment)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user