WIP: implement CLI
This commit is contained in:
parent
481927c3fd
commit
b9c6226b00
4 changed files with 357 additions and 0 deletions
|
@ -54,6 +54,10 @@
|
||||||
80820145275FFD380040996E /* SidebarBudgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80820144275FFD380040996E /* SidebarBudgetView.swift */; };
|
80820145275FFD380040996E /* SidebarBudgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80820144275FFD380040996E /* SidebarBudgetView.swift */; };
|
||||||
8094A9C327567CAC006C6C62 /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = 8094A9C227567CAC006C6C62 /* Collections */; };
|
8094A9C327567CAC006C6C62 /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = 8094A9C227567CAC006C6C62 /* Collections */; };
|
||||||
809B942327221EC800B1DAE2 /* CategoryFormSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 809B942227221EC800B1DAE2 /* CategoryFormSheet.swift */; };
|
809B942327221EC800B1DAE2 /* CategoryFormSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 809B942227221EC800B1DAE2 /* CategoryFormSheet.swift */; };
|
||||||
|
80A419ED2787C0A00090C515 /* TwigsCli.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80A419EC2787C0A00090C515 /* TwigsCli.swift */; };
|
||||||
|
80A419F32787C13E0090C515 /* ArgumentParser in Frameworks */ = {isa = PBXBuildFile; productRef = 80A419F22787C13E0090C515 /* ArgumentParser */; };
|
||||||
|
80A419F52787C1520090C515 /* ArgumentParser in Frameworks */ = {isa = PBXBuildFile; productRef = 80A419F42787C1520090C515 /* ArgumentParser */; };
|
||||||
|
80A419F72788A3880090C515 /* TwigsCore in Frameworks */ = {isa = PBXBuildFile; productRef = 80A419F62788A3880090C515 /* TwigsCore */; };
|
||||||
80D1FC14277C1EF9007F17FB /* InlineLoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80D1FC13277C1EF9007F17FB /* InlineLoadingView.swift */; };
|
80D1FC14277C1EF9007F17FB /* InlineLoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80D1FC13277C1EF9007F17FB /* InlineLoadingView.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
@ -74,6 +78,18 @@
|
||||||
};
|
};
|
||||||
/* End PBXContainerItemProxy section */
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
|
80A419E82787C0A00090C515 /* CopyFiles */ = {
|
||||||
|
isa = PBXCopyFilesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
dstPath = /usr/share/man/man1/;
|
||||||
|
dstSubfolderSpec = 0;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 1;
|
||||||
|
};
|
||||||
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
2821265F23555FD300072D52 /* TransactionFormSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionFormSheet.swift; sourceTree = "<group>"; };
|
2821265F23555FD300072D52 /* TransactionFormSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionFormSheet.swift; sourceTree = "<group>"; };
|
||||||
282126A0235929B800072D52 /* ProfileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileView.swift; sourceTree = "<group>"; };
|
282126A0235929B800072D52 /* ProfileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileView.swift; sourceTree = "<group>"; };
|
||||||
|
@ -129,6 +145,8 @@
|
||||||
808582CD277E5E9E00006859 /* TwigsCore */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = TwigsCore; path = ../TwigsCore; sourceTree = "<group>"; };
|
808582CD277E5E9E00006859 /* TwigsCore */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = TwigsCore; path = ../TwigsCore; sourceTree = "<group>"; };
|
||||||
809B942227221EC800B1DAE2 /* CategoryFormSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CategoryFormSheet.swift; sourceTree = "<group>"; };
|
809B942227221EC800B1DAE2 /* CategoryFormSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CategoryFormSheet.swift; sourceTree = "<group>"; };
|
||||||
809B94242722597800B1DAE2 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
|
809B94242722597800B1DAE2 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
|
80A419EA2787C0A00090C515 /* twigs-cli */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "twigs-cli"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
80A419EC2787C0A00090C515 /* TwigsCli.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwigsCli.swift; sourceTree = "<group>"; };
|
||||||
80D1FC13277C1EF9007F17FB /* InlineLoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InlineLoadingView.swift; sourceTree = "<group>"; };
|
80D1FC13277C1EF9007F17FB /* InlineLoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InlineLoadingView.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
@ -137,6 +155,7 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
80A419F32787C13E0090C515 /* ArgumentParser in Frameworks */,
|
||||||
8005FD5B277E623900E48B23 /* TwigsCore in Frameworks */,
|
8005FD5B277E623900E48B23 /* TwigsCore in Frameworks */,
|
||||||
8094A9C327567CAC006C6C62 /* Collections in Frameworks */,
|
8094A9C327567CAC006C6C62 /* Collections in Frameworks */,
|
||||||
);
|
);
|
||||||
|
@ -156,6 +175,15 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
80A419E72787C0A00090C515 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
80A419F72788A3880090C515 /* TwigsCore in Frameworks */,
|
||||||
|
80A419F52787C1520090C515 /* ArgumentParser in Frameworks */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
|
@ -207,6 +235,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
80DBED432774AE4F00CB0A88 /* Packages */,
|
80DBED432774AE4F00CB0A88 /* Packages */,
|
||||||
|
80A419EB2787C0A00090C515 /* twigs-cli */,
|
||||||
28AC94EB233C373900BFB70A /* Products */,
|
28AC94EB233C373900BFB70A /* Products */,
|
||||||
28AC94EC233C373900BFB70A /* Twigs */,
|
28AC94EC233C373900BFB70A /* Twigs */,
|
||||||
28AC9503233C373A00BFB70A /* TwigsTests */,
|
28AC9503233C373A00BFB70A /* TwigsTests */,
|
||||||
|
@ -221,6 +250,7 @@
|
||||||
28AC94EA233C373900BFB70A /* Twigs.app */,
|
28AC94EA233C373900BFB70A /* Twigs.app */,
|
||||||
28AC9500233C373A00BFB70A /* TwigsTests.xctest */,
|
28AC9500233C373A00BFB70A /* TwigsTests.xctest */,
|
||||||
28AC950B233C373A00BFB70A /* TwigsUITests.xctest */,
|
28AC950B233C373A00BFB70A /* TwigsUITests.xctest */,
|
||||||
|
80A419EA2787C0A00090C515 /* twigs-cli */,
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -320,6 +350,14 @@
|
||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
80A419EB2787C0A00090C515 /* twigs-cli */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
80A419EC2787C0A00090C515 /* TwigsCli.swift */,
|
||||||
|
);
|
||||||
|
path = "twigs-cli";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
80D6B1EF275B11C10075D0EC /* Recurring Transactions */ = {
|
80D6B1EF275B11C10075D0EC /* Recurring Transactions */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -358,6 +396,7 @@
|
||||||
packageProductDependencies = (
|
packageProductDependencies = (
|
||||||
8094A9C227567CAC006C6C62 /* Collections */,
|
8094A9C227567CAC006C6C62 /* Collections */,
|
||||||
8005FD5A277E623900E48B23 /* TwigsCore */,
|
8005FD5A277E623900E48B23 /* TwigsCore */,
|
||||||
|
80A419F22787C13E0090C515 /* ArgumentParser */,
|
||||||
);
|
);
|
||||||
productName = Budget;
|
productName = Budget;
|
||||||
productReference = 28AC94EA233C373900BFB70A /* Twigs.app */;
|
productReference = 28AC94EA233C373900BFB70A /* Twigs.app */;
|
||||||
|
@ -399,6 +438,27 @@
|
||||||
productReference = 28AC950B233C373A00BFB70A /* TwigsUITests.xctest */;
|
productReference = 28AC950B233C373A00BFB70A /* TwigsUITests.xctest */;
|
||||||
productType = "com.apple.product-type.bundle.ui-testing";
|
productType = "com.apple.product-type.bundle.ui-testing";
|
||||||
};
|
};
|
||||||
|
80A419E92787C0A00090C515 /* twigs-cli */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 80A419F02787C0A00090C515 /* Build configuration list for PBXNativeTarget "twigs-cli" */;
|
||||||
|
buildPhases = (
|
||||||
|
80A419E62787C0A00090C515 /* Sources */,
|
||||||
|
80A419E72787C0A00090C515 /* Frameworks */,
|
||||||
|
80A419E82787C0A00090C515 /* CopyFiles */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = "twigs-cli";
|
||||||
|
packageProductDependencies = (
|
||||||
|
80A419F42787C1520090C515 /* ArgumentParser */,
|
||||||
|
80A419F62788A3880090C515 /* TwigsCore */,
|
||||||
|
);
|
||||||
|
productName = "twigs-cli";
|
||||||
|
productReference = 80A419EA2787C0A00090C515 /* twigs-cli */;
|
||||||
|
productType = "com.apple.product-type.tool";
|
||||||
|
};
|
||||||
/* End PBXNativeTarget section */
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
/* Begin PBXProject section */
|
/* Begin PBXProject section */
|
||||||
|
@ -420,6 +480,9 @@
|
||||||
CreatedOnToolsVersion = 11.0;
|
CreatedOnToolsVersion = 11.0;
|
||||||
TestTargetID = 28AC94E9233C373900BFB70A;
|
TestTargetID = 28AC94E9233C373900BFB70A;
|
||||||
};
|
};
|
||||||
|
80A419E92787C0A00090C515 = {
|
||||||
|
CreatedOnToolsVersion = 13.2.1;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
buildConfigurationList = 28AC94E5233C373900BFB70A /* Build configuration list for PBXProject "Twigs" */;
|
buildConfigurationList = 28AC94E5233C373900BFB70A /* Build configuration list for PBXProject "Twigs" */;
|
||||||
|
@ -434,6 +497,7 @@
|
||||||
mainGroup = 28AC94E1233C373900BFB70A;
|
mainGroup = 28AC94E1233C373900BFB70A;
|
||||||
packageReferences = (
|
packageReferences = (
|
||||||
8094A9C127567CAC006C6C62 /* XCRemoteSwiftPackageReference "swift-collections" */,
|
8094A9C127567CAC006C6C62 /* XCRemoteSwiftPackageReference "swift-collections" */,
|
||||||
|
80A419F12787C13E0090C515 /* XCRemoteSwiftPackageReference "swift-argument-parser" */,
|
||||||
);
|
);
|
||||||
productRefGroup = 28AC94EB233C373900BFB70A /* Products */;
|
productRefGroup = 28AC94EB233C373900BFB70A /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
|
@ -442,6 +506,7 @@
|
||||||
28AC94E9233C373900BFB70A /* Twigs */,
|
28AC94E9233C373900BFB70A /* Twigs */,
|
||||||
28AC94FF233C373A00BFB70A /* TwigsTests */,
|
28AC94FF233C373A00BFB70A /* TwigsTests */,
|
||||||
28AC950A233C373A00BFB70A /* TwigsUITests */,
|
28AC950A233C373A00BFB70A /* TwigsUITests */,
|
||||||
|
80A419E92787C0A00090C515 /* twigs-cli */,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
|
@ -538,6 +603,14 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
80A419E62787C0A00090C515 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
80A419ED2787C0A00090C515 /* TwigsCli.swift in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXTargetDependency section */
|
/* Begin PBXTargetDependency section */
|
||||||
|
@ -834,6 +907,34 @@
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
80A419EE2787C0A00090C515 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
DEVELOPMENT_TEAM = VJ33S6H7W7;
|
||||||
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 12.1;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SDKROOT = macosx;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
80A419EF2787C0A00090C515 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
DEVELOPMENT_TEAM = VJ33S6H7W7;
|
||||||
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 12.1;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SDKROOT = macosx;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
/* Begin XCConfigurationList section */
|
||||||
|
@ -873,6 +974,15 @@
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
|
80A419F02787C0A00090C515 /* Build configuration list for PBXNativeTarget "twigs-cli" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
80A419EE2787C0A00090C515 /* Debug */,
|
||||||
|
80A419EF2787C0A00090C515 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
/* Begin XCRemoteSwiftPackageReference section */
|
/* Begin XCRemoteSwiftPackageReference section */
|
||||||
|
@ -884,6 +994,14 @@
|
||||||
minimumVersion = 1.0.0;
|
minimumVersion = 1.0.0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
80A419F12787C13E0090C515 /* XCRemoteSwiftPackageReference "swift-argument-parser" */ = {
|
||||||
|
isa = XCRemoteSwiftPackageReference;
|
||||||
|
repositoryURL = "https://github.com/apple/swift-argument-parser.git";
|
||||||
|
requirement = {
|
||||||
|
kind = upToNextMajorVersion;
|
||||||
|
minimumVersion = 1.0.0;
|
||||||
|
};
|
||||||
|
};
|
||||||
/* End XCRemoteSwiftPackageReference section */
|
/* End XCRemoteSwiftPackageReference section */
|
||||||
|
|
||||||
/* Begin XCSwiftPackageProductDependency section */
|
/* Begin XCSwiftPackageProductDependency section */
|
||||||
|
@ -896,6 +1014,20 @@
|
||||||
package = 8094A9C127567CAC006C6C62 /* XCRemoteSwiftPackageReference "swift-collections" */;
|
package = 8094A9C127567CAC006C6C62 /* XCRemoteSwiftPackageReference "swift-collections" */;
|
||||||
productName = Collections;
|
productName = Collections;
|
||||||
};
|
};
|
||||||
|
80A419F22787C13E0090C515 /* ArgumentParser */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = 80A419F12787C13E0090C515 /* XCRemoteSwiftPackageReference "swift-argument-parser" */;
|
||||||
|
productName = ArgumentParser;
|
||||||
|
};
|
||||||
|
80A419F42787C1520090C515 /* ArgumentParser */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = 80A419F12787C13E0090C515 /* XCRemoteSwiftPackageReference "swift-argument-parser" */;
|
||||||
|
productName = ArgumentParser;
|
||||||
|
};
|
||||||
|
80A419F62788A3880090C515 /* TwigsCore */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
productName = TwigsCore;
|
||||||
|
};
|
||||||
/* End XCSwiftPackageProductDependency section */
|
/* End XCSwiftPackageProductDependency section */
|
||||||
};
|
};
|
||||||
rootObject = 28AC94E2233C373900BFB70A /* Project object */;
|
rootObject = 28AC94E2233C373900BFB70A /* Project object */;
|
||||||
|
|
|
@ -1,6 +1,15 @@
|
||||||
{
|
{
|
||||||
"object": {
|
"object": {
|
||||||
"pins": [
|
"pins": [
|
||||||
|
{
|
||||||
|
"package": "swift-argument-parser",
|
||||||
|
"repositoryURL": "https://github.com/apple/swift-argument-parser.git",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "e1465042f195f374b94f915ba8ca49de24300a0d",
|
||||||
|
"version": "1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"package": "swift-collections",
|
"package": "swift-collections",
|
||||||
"repositoryURL": "https://github.com/apple/swift-collections.git",
|
"repositoryURL": "https://github.com/apple/swift-collections.git",
|
||||||
|
|
92
Twigs.xcodeproj/xcshareddata/xcschemes/twigs-cli.xcscheme
Normal file
92
Twigs.xcodeproj/xcshareddata/xcschemes/twigs-cli.xcscheme
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Scheme
|
||||||
|
LastUpgradeVersion = "1320"
|
||||||
|
version = "1.3">
|
||||||
|
<BuildAction
|
||||||
|
parallelizeBuildables = "YES"
|
||||||
|
buildImplicitDependencies = "YES">
|
||||||
|
<BuildActionEntries>
|
||||||
|
<BuildActionEntry
|
||||||
|
buildForTesting = "YES"
|
||||||
|
buildForRunning = "YES"
|
||||||
|
buildForProfiling = "YES"
|
||||||
|
buildForArchiving = "YES"
|
||||||
|
buildForAnalyzing = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "80A419E92787C0A00090C515"
|
||||||
|
BuildableName = "twigs-cli"
|
||||||
|
BlueprintName = "twigs-cli"
|
||||||
|
ReferencedContainer = "container:Twigs.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildActionEntry>
|
||||||
|
</BuildActionEntries>
|
||||||
|
</BuildAction>
|
||||||
|
<TestAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
|
<Testables>
|
||||||
|
</Testables>
|
||||||
|
</TestAction>
|
||||||
|
<LaunchAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
launchStyle = "0"
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
|
debugDocumentVersioning = "YES"
|
||||||
|
debugServiceExtension = "internal"
|
||||||
|
allowLocationSimulation = "YES">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "80A419E92787C0A00090C515"
|
||||||
|
BuildableName = "twigs-cli"
|
||||||
|
BlueprintName = "twigs-cli"
|
||||||
|
ReferencedContainer = "container:Twigs.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
<CommandLineArguments>
|
||||||
|
<CommandLineArgument
|
||||||
|
argument = "auth"
|
||||||
|
isEnabled = "YES">
|
||||||
|
</CommandLineArgument>
|
||||||
|
<CommandLineArgument
|
||||||
|
argument = "login"
|
||||||
|
isEnabled = "YES">
|
||||||
|
</CommandLineArgument>
|
||||||
|
<CommandLineArgument
|
||||||
|
argument = "-u https://twigs.api.wbrawner.com"
|
||||||
|
isEnabled = "YES">
|
||||||
|
</CommandLineArgument>
|
||||||
|
</CommandLineArguments>
|
||||||
|
</LaunchAction>
|
||||||
|
<ProfileAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
savedToolIdentifier = ""
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
debugDocumentVersioning = "YES">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "80A419E92787C0A00090C515"
|
||||||
|
BuildableName = "twigs-cli"
|
||||||
|
BlueprintName = "twigs-cli"
|
||||||
|
ReferencedContainer = "container:Twigs.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
</ProfileAction>
|
||||||
|
<AnalyzeAction
|
||||||
|
buildConfiguration = "Debug">
|
||||||
|
</AnalyzeAction>
|
||||||
|
<ArchiveAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
revealArchiveInOrganizer = "YES">
|
||||||
|
</ArchiveAction>
|
||||||
|
</Scheme>
|
124
twigs-cli/TwigsCli.swift
Normal file
124
twigs-cli/TwigsCli.swift
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
//
|
||||||
|
// main.swift
|
||||||
|
// twigs-cli
|
||||||
|
//
|
||||||
|
// Created by William Brawner on 1/6/22.
|
||||||
|
// Copyright © 2022 William Brawner. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import ArgumentParser
|
||||||
|
import TwigsCore
|
||||||
|
|
||||||
|
@main
|
||||||
|
enum TwigsCli {
|
||||||
|
static func main() async throws {
|
||||||
|
await Twigs.main()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol AsyncParsableCommand: ParsableCommand {
|
||||||
|
mutating func runAsync() async throws
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ParsableCommand {
|
||||||
|
static func main() async {
|
||||||
|
do {
|
||||||
|
var command = try parseAsRoot(nil)
|
||||||
|
if var asyncCommand = command as? AsyncParsableCommand {
|
||||||
|
try await asyncCommand.runAsync()
|
||||||
|
} else {
|
||||||
|
try command.run()
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
exit(withError: error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Twigs: ParsableCommand {
|
||||||
|
static var configuration = CommandConfiguration(
|
||||||
|
commandName: "twigs-cli",
|
||||||
|
abstract: "A CLI for Twigs, a personal finance application focused on individual and family budgeting",
|
||||||
|
version: "1.0.0",
|
||||||
|
subcommands: [Twigs.Auth.self]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Twigs {
|
||||||
|
struct Auth: ParsableCommand {
|
||||||
|
static var configuration = CommandConfiguration(
|
||||||
|
abstract: "commands for authentication with a Twigs server",
|
||||||
|
subcommands: [Twigs.Auth.Login.self]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Twigs.Auth {
|
||||||
|
struct Login: AsyncParsableCommand {
|
||||||
|
static var configuration = CommandConfiguration(
|
||||||
|
abstract: "login with an existing account"
|
||||||
|
)
|
||||||
|
|
||||||
|
@Option(name: [.short, .long], help: "")
|
||||||
|
var token: String = ""
|
||||||
|
|
||||||
|
@Option(name: [.short, .long], parsing: SingleValueParsingStrategy.next, help: "the URL to the twigs server")
|
||||||
|
var url: String = ""
|
||||||
|
|
||||||
|
mutating func runAsync() async throws {
|
||||||
|
let config = Config(url: url, token: token)
|
||||||
|
// TODO: Check if token was provided, if not check config file
|
||||||
|
if let token = await config.token, !token.isEmpty {
|
||||||
|
print("using token for login")
|
||||||
|
// TODO: Save token to disk
|
||||||
|
return
|
||||||
|
}
|
||||||
|
print("Username:", terminator: " ")
|
||||||
|
if let input = readLine(), !input.isEmpty {
|
||||||
|
await config.setUsername(input)
|
||||||
|
} else {
|
||||||
|
throw TwigsErrors.input("ERROR: Username cannot be empty")
|
||||||
|
}
|
||||||
|
guard let passChars = getpass("Password: ") else {
|
||||||
|
throw TwigsErrors.input("ERROR: Unable to read password")
|
||||||
|
}
|
||||||
|
let password = String(cString: passChars)
|
||||||
|
if password.isEmpty {
|
||||||
|
throw TwigsErrors.input("ERROR: Password cannot be empty")
|
||||||
|
}
|
||||||
|
await config.setPassword(password)
|
||||||
|
if let username = await config.username, let password = await config.password {
|
||||||
|
print("Logging in as \(username) with password \(password)")
|
||||||
|
let apiService = TwigsApiService()
|
||||||
|
apiService.baseUrl = await config.url
|
||||||
|
try await apiService.login(username: username, password: password)
|
||||||
|
// TODO: Persist url and token in config file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actor Config {
|
||||||
|
var url: String? = nil
|
||||||
|
var username: String? = nil
|
||||||
|
var password: String? = nil
|
||||||
|
var token: String? = nil
|
||||||
|
|
||||||
|
init(url: String? = nil, token: String? = nil) {
|
||||||
|
self.url = url
|
||||||
|
self.token = token
|
||||||
|
}
|
||||||
|
|
||||||
|
func setUsername(_ username: String) {
|
||||||
|
self.username = username
|
||||||
|
}
|
||||||
|
|
||||||
|
func setPassword(_ password: String) {
|
||||||
|
self.password = password
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum TwigsErrors: Error {
|
||||||
|
case input(String)
|
||||||
|
}
|
Loading…
Reference in a new issue