Repository: owensd/apous Branch: master Commit: 56ac30c37f54 Files: 29 Total size: 43.0 KB Directory structure: gitextract_ssdk6qb7/ ├── .gitignore ├── Features.md ├── LICENSE ├── Makefile ├── README.md ├── apous.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── xcshareddata/ │ └── xcschemes/ │ └── apous.xcscheme ├── misc/ │ ├── Components.plist │ └── scripts/ │ └── bootstrap.sh ├── samples/ │ ├── basic/ │ │ └── basic.swift │ ├── carthage/ │ │ ├── Cartfile │ │ └── main.swift │ ├── cocoapods/ │ │ ├── Podfile │ │ └── main.swift │ ├── multi/ │ │ ├── bar.swift │ │ ├── foo.swift │ │ └── main.swift │ ├── nested/ │ │ ├── main.swift │ │ └── os/ │ │ └── path/ │ │ ├── abspath.swift │ │ └── basename.swift │ └── shebang/ │ └── main.swift ├── src/ │ ├── ErrorCodes.swift │ ├── Tools.swift │ ├── Utils.swift │ ├── main.swift │ └── version.sh └── test/ ├── Info.plist └── Samples.swift ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # OS X .DS_Store # Xcode # build/ *.pbxuser !default.pbxuser *.mode1v3 !default.mode1v3 *.mode2v3 !default.mode2v3 *.perspectivev3 !default.perspectivev3 xcuserdata *.xccheckout *.moved-aside DerivedData *.hmap *.ipa *.xcuserstate # CocoaPods # # We recommend against adding the Pods directory to your .gitignore. However # you should judge for yourself, the pros and cons are mentioned at: # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control # Pods/ Rome/ # Carthage # # Add this line if you want to avoid checking in source code from Carthage dependencies. Carthage/ # Apous bin/ .apousscript VersionInfo.swift releases/ ================================================ FILE: Features.md ================================================ Features Planned for v0.2.0: 1. Refactoring project to support unit tests 2. Support nested directories for the script Possible for v0.2.0: 1. Creation of implicit Xcode file for Xcode authoring support ================================================ FILE: LICENSE ================================================ The MIT License (MIT) Copyright (c) 2015 Kiad Software, LLC. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Makefile ================================================ TEMPORARY_FOLDER=/tmp/Apous.dst PREFIX=/usr/local BUILD_TOOL=xcodebuild XCODEFLAGS=-project 'apous.xcodeproj' -scheme 'apous' DSTROOT=$(TEMPORARY_FOLDER) APOUS_EXECUTABLE=$(TEMPORARY_FOLDER)/apous FRAMEWORKS_FOLDER=/Library/Frameworks BINARIES_FOLDER=/usr/local/bin VERSION_STRING=v0.2.2 COMPONENTS_PLIST=misc/Components.plist OUTPUT_PACKAGE=Apous.pkg .PHONY: all bootstrap clean install package test uninstall all: bootstrap $(BUILD_TOOL) $(XCODEFLAGS) build bootstrap: misc/scripts/bootstrap.sh test: clean bootstrap $(BUILD_TOOL) $(XCODEFLAGS) test clean: rm -f "$(OUTPUT_PACKAGE)" rm -rf "$(TEMPORARY_FOLDER)" $(BUILD_TOOL) $(XCODEFLAGS) clean install: package sudo installer -pkg "$(TEMPORARY_FOLDER)/$(OUTPUT_PACKAGE)" -target / uninstall: rm -f "$(BINARIES_FOLDER)/apous" installables: clean bootstrap $(BUILD_TOOL) $(XCODEFLAGS) install mkdir -p "$(TEMPORARY_FOLDER)$(BINARIES_FOLDER)" prefix_install: installables mkdir -p "$(PREFIX)/Frameworks" "$(PREFIX)/bin" cp -f "$(TEMPORARY_FOLDER)$(BINARIES_FOLDER)/apous" "$(PREFIX)/bin/" package: installables pkgbuild \ --component-plist "$(COMPONENTS_PLIST)" \ --identifier "io.owensd.apous" \ --install-location "/" \ --root "$(TEMPORARY_FOLDER)" \ --version "$(VERSION_STRING)" \ "$(TEMPORARY_FOLDER)/$(OUTPUT_PACKAGE)" ================================================ FILE: README.md ================================================ _______ | _ .-----.-----.--.--.-----. |. 1 | _ | _ | | |__ --| |. _ | __|_____|_____|_____| |: | |__| |::.|:. | `--- ---' # Apous [![GitHub license](https://img.shields.io/github/license/mashape/apistatus.svg)](https://raw.githubusercontent.com/owensd/apous/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/owensd/apous.svg)](https://github.com/owensd/Apous/releases) Apous is a simple tool that allows for easier authoring of Swift scripts. Primary features: 1. Allow the breaking up of scripts into multiple files. 2. Dependency management through [Carthage](https://github.com/Carthage/Carthage) or [CocoaPods](https://github.com/CocoaPods/CocoaPods/). ## How it Works Apous works by first checking for a `Cartfile` or `Podfile` in your script's directory. If one is present, then `carthage update` or `pod install --no-integrate` will be run. Next, all of your Swift files are compiled into a single `.apousscript` binary that will then be run automatically for you. It's really that simple. ## Getting Started First, you need to install the latest build of Apous. 1. Download the latest version of `apous` from "Releases". 2. Copy it to a location in your path, such as `/usr/local/bin/`. Homebrew support is pending: https://github.com/Homebrew/homebrew/pull/41473 ## Creating Your First Script 1. Create a new directory for your scripts, say `mkdir demo` 2. Change to that directory: `cd demo` 3. Create a new script file: `touch demo.swift` 4. Change the contents of the file to: ```swift import Foundation print("Welcome to Apous!") ``` 5. Run the script: `apous .` This will output: Welcome to Apous! You can see some other samples here: [Samples](https://github.com/owensd/apous/tree/master/samples). ### Alternatively Apous also supports running scripts with `#!`. Note that your entry point script **must** be named `main.swift`. ```swift #!/usr/local/bin/apous import Foundation print("Welcome to Apous!") ``` Then run: > chmod +x main.swift > ./main.swift Welcome to Apous! ## FAQ **Q: What is Apous mean?** A: It's from the ancient Greek απους, meaning "without feet". ================================================ FILE: apous.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 7D0373391B49021700E2711D /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D0373381B49021700E2711D /* main.swift */; }; 7D0F00941B4AF32F003B6EF0 /* Samples.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D0F00931B4AF32F003B6EF0 /* Samples.swift */; }; 7D3AC3461B49F99B0068CC83 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D3AC3451B49F99B0068CC83 /* Utils.swift */; }; 7D3AC3481B49FE170068CC83 /* ErrorCodes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D3AC3471B49FE170068CC83 /* ErrorCodes.swift */; }; 7D3AC34A1B4A37BC0068CC83 /* Tools.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D3AC3491B4A37BC0068CC83 /* Tools.swift */; }; 7DF997441B4B33A200E90F56 /* VersionInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DF997431B4B33A200E90F56 /* VersionInfo.swift */; }; 7DF997511B4B4A6900E90F56 /* Tools.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D3AC3491B4A37BC0068CC83 /* Tools.swift */; }; 7DF9988C1B4B72FD00E90F56 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D3AC3451B49F99B0068CC83 /* Utils.swift */; }; 7DF9988D1B4B730500E90F56 /* ErrorCodes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D3AC3471B49FE170068CC83 /* ErrorCodes.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ 7DF9974B1B4B354000E90F56 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 7D03732D1B49021700E2711D /* Project object */; proxyType = 1; remoteGlobalIDString = 7DF997471B4B353600E90F56; remoteInfo = GenerateVersionInfo; }; 7DF9974D1B4B354800E90F56 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 7D03732D1B49021700E2711D /* Project object */; proxyType = 1; remoteGlobalIDString = 7DF997471B4B353600E90F56; remoteInfo = GenerateVersionInfo; }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ 7D0373331B49021700E2711D /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = /usr/share/man/man1/; dstSubfolderSpec = 0; files = ( ); runOnlyForDeploymentPostprocessing = 1; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ 7D0373351B49021700E2711D /* apous */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = apous; sourceTree = BUILT_PRODUCTS_DIR; }; 7D0373381B49021700E2711D /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; 7D0F00911B4AF32F003B6EF0 /* apoustest.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = apoustest.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 7D0F00931B4AF32F003B6EF0 /* Samples.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Samples.swift; sourceTree = ""; }; 7D0F00951B4AF32F003B6EF0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 7D0F009A1B4AF3F1003B6EF0 /* Features.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = Features.md; sourceTree = ""; }; 7D3AC3421B49F1FC0068CC83 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 7D3AC3441B49F62F0068CC83 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; 7D3AC3451B49F99B0068CC83 /* Utils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = ""; }; 7D3AC3471B49FE170068CC83 /* ErrorCodes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ErrorCodes.swift; sourceTree = ""; }; 7D3AC3491B4A37BC0068CC83 /* Tools.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Tools.swift; sourceTree = ""; }; 7DC546B91B4C55640070A858 /* samples */ = {isa = PBXFileReference; lastKnownFileType = folder; path = samples; sourceTree = SOURCE_ROOT; }; 7DF997431B4B33A200E90F56 /* VersionInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VersionInfo.swift; sourceTree = ""; }; 7DF9974F1B4B356700E90F56 /* version.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = version.sh; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 7D0373321B49021700E2711D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 7D0F008E1B4AF32F003B6EF0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 7D03732C1B49021700E2711D = { isa = PBXGroup; children = ( 7D0F00991B4AF3D9003B6EF0 /* docs */, 7D0373371B49021700E2711D /* src */, 7D0F00921B4AF32F003B6EF0 /* test */, 7D0373361B49021700E2711D /* Products */, ); sourceTree = ""; }; 7D0373361B49021700E2711D /* Products */ = { isa = PBXGroup; children = ( 7D0373351B49021700E2711D /* apous */, 7D0F00911B4AF32F003B6EF0 /* apoustest.xctest */, ); name = Products; sourceTree = ""; }; 7D0373371B49021700E2711D /* src */ = { isa = PBXGroup; children = ( 7DF997501B4B37B100E90F56 /* Versioning */, 7D0373381B49021700E2711D /* main.swift */, 7D3AC3451B49F99B0068CC83 /* Utils.swift */, 7D3AC3471B49FE170068CC83 /* ErrorCodes.swift */, 7D3AC3491B4A37BC0068CC83 /* Tools.swift */, ); path = src; sourceTree = ""; }; 7D0F00921B4AF32F003B6EF0 /* test */ = { isa = PBXGroup; children = ( 7DC546B91B4C55640070A858 /* samples */, 7D0F00931B4AF32F003B6EF0 /* Samples.swift */, 7D0F00951B4AF32F003B6EF0 /* Info.plist */, ); path = test; sourceTree = ""; }; 7D0F00991B4AF3D9003B6EF0 /* docs */ = { isa = PBXGroup; children = ( 7D0F009A1B4AF3F1003B6EF0 /* Features.md */, 7D3AC3441B49F62F0068CC83 /* LICENSE */, 7D3AC3421B49F1FC0068CC83 /* README.md */, ); name = docs; sourceTree = ""; }; 7DF997501B4B37B100E90F56 /* Versioning */ = { isa = PBXGroup; children = ( 7DF997431B4B33A200E90F56 /* VersionInfo.swift */, 7DF9974F1B4B356700E90F56 /* version.sh */, ); name = Versioning; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXLegacyTarget section */ 7DF997471B4B353600E90F56 /* GenerateVersionInfo */ = { isa = PBXLegacyTarget; buildArgumentsString = version.sh; buildConfigurationList = 7DF997481B4B353600E90F56 /* Build configuration list for PBXLegacyTarget "GenerateVersionInfo" */; buildPhases = ( ); buildToolPath = /bin/sh; buildWorkingDirectory = "$(SRCROOT)/src"; dependencies = ( ); name = GenerateVersionInfo; passBuildSettingsInEnvironment = 1; productName = GenerateVersionInfo; }; /* End PBXLegacyTarget section */ /* Begin PBXNativeTarget section */ 7D0373341B49021700E2711D /* apous */ = { isa = PBXNativeTarget; buildConfigurationList = 7D03733C1B49021700E2711D /* Build configuration list for PBXNativeTarget "apous" */; buildPhases = ( 7D0373311B49021700E2711D /* Sources */, 7D0373321B49021700E2711D /* Frameworks */, 7D0373331B49021700E2711D /* CopyFiles */, 7DE115081B4C4A9100B198FB /* Package for GitHub Release */, ); buildRules = ( ); dependencies = ( 7DF9974C1B4B354000E90F56 /* PBXTargetDependency */, ); name = apous; productName = apous; productReference = 7D0373351B49021700E2711D /* apous */; productType = "com.apple.product-type.tool"; }; 7D0F00901B4AF32F003B6EF0 /* apoustest */ = { isa = PBXNativeTarget; buildConfigurationList = 7D0F00981B4AF32F003B6EF0 /* Build configuration list for PBXNativeTarget "apoustest" */; buildPhases = ( 7D0F008D1B4AF32F003B6EF0 /* Sources */, 7D0F008E1B4AF32F003B6EF0 /* Frameworks */, 7D0F008F1B4AF32F003B6EF0 /* Resources */, 7DF9988B1B4B4C5600E90F56 /* Copy Samples */, ); buildRules = ( ); dependencies = ( 7DF9974E1B4B354800E90F56 /* PBXTargetDependency */, ); name = apoustest; productName = apoustest; productReference = 7D0F00911B4AF32F003B6EF0 /* apoustest.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 7D03732D1B49021700E2711D /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0700; ORGANIZATIONNAME = owensd.io; TargetAttributes = { 7D0373341B49021700E2711D = { CreatedOnToolsVersion = 7.0; }; 7D0F00901B4AF32F003B6EF0 = { CreatedOnToolsVersion = 7.0; }; 7DF997471B4B353600E90F56 = { CreatedOnToolsVersion = 7.0; }; }; }; buildConfigurationList = 7D0373301B49021700E2711D /* Build configuration list for PBXProject "apous" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, ); mainGroup = 7D03732C1B49021700E2711D; productRefGroup = 7D0373361B49021700E2711D /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 7DF997471B4B353600E90F56 /* GenerateVersionInfo */, 7D0373341B49021700E2711D /* apous */, 7D0F00901B4AF32F003B6EF0 /* apoustest */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 7D0F008F1B4AF32F003B6EF0 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ 7DE115081B4C4A9100B198FB /* Package for GitHub Release */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "Package for GitHub Release"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "#mkdir -p releases\n#rm -f $SRCROOT/releases/$TARGET_NAME.zip\n#zip -j $SRCROOT/releases/$TARGET_NAME.zip $SRCROOT/bin/$TARGET_NAME"; }; 7DF9988B1B4B4C5600E90F56 /* Copy Samples */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "$(SRCROOT)/samples", ); name = "Copy Samples"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "rm -rf \"$TARGET_BUILD_DIR/samples\"\ncp -R \"$SRCROOT/samples\" \"$TARGET_BUILD_DIR\""; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 7D0373311B49021700E2711D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 7D3AC3461B49F99B0068CC83 /* Utils.swift in Sources */, 7D3AC3481B49FE170068CC83 /* ErrorCodes.swift in Sources */, 7D0373391B49021700E2711D /* main.swift in Sources */, 7DF997441B4B33A200E90F56 /* VersionInfo.swift in Sources */, 7D3AC34A1B4A37BC0068CC83 /* Tools.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 7D0F008D1B4AF32F003B6EF0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 7D0F00941B4AF32F003B6EF0 /* Samples.swift in Sources */, 7DF997511B4B4A6900E90F56 /* Tools.swift in Sources */, 7DF9988C1B4B72FD00E90F56 /* Utils.swift in Sources */, 7DF9988D1B4B730500E90F56 /* ErrorCodes.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ 7DF9974C1B4B354000E90F56 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 7DF997471B4B353600E90F56 /* GenerateVersionInfo */; targetProxy = 7DF9974B1B4B354000E90F56 /* PBXContainerItemProxy */; }; 7DF9974E1B4B354800E90F56 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 7DF997471B4B353600E90F56 /* GenerateVersionInfo */; targetProxy = 7DF9974D1B4B354800E90F56 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ 7D03733A1B49021700E2711D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 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; GCC_C_LANGUAGE_STANDARD = gnu99; 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; MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; }; 7D03733B1B49021700E2711D /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 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; GCC_C_LANGUAGE_STANDARD = gnu99; 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; MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; }; name = Release; }; 7D03733D1B49021700E2711D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; 7D03733E1B49021700E2711D /* Release */ = { isa = XCBuildConfiguration; buildSettings = { PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; 7D0F00961B4AF32F003B6EF0 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = test/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = io.owensd.apoustest; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; 7D0F00971B4AF32F003B6EF0 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = test/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = io.owensd.apoustest; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; 7DF997491B4B353600E90F56 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { DEBUGGING_SYMBOLS = YES; DEBUG_INFORMATION_FORMAT = dwarf; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; 7DF9974A1B4B353600E90F56 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 7D0373301B49021700E2711D /* Build configuration list for PBXProject "apous" */ = { isa = XCConfigurationList; buildConfigurations = ( 7D03733A1B49021700E2711D /* Debug */, 7D03733B1B49021700E2711D /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 7D03733C1B49021700E2711D /* Build configuration list for PBXNativeTarget "apous" */ = { isa = XCConfigurationList; buildConfigurations = ( 7D03733D1B49021700E2711D /* Debug */, 7D03733E1B49021700E2711D /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 7D0F00981B4AF32F003B6EF0 /* Build configuration list for PBXNativeTarget "apoustest" */ = { isa = XCConfigurationList; buildConfigurations = ( 7D0F00961B4AF32F003B6EF0 /* Debug */, 7D0F00971B4AF32F003B6EF0 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 7DF997481B4B353600E90F56 /* Build configuration list for PBXLegacyTarget "GenerateVersionInfo" */ = { isa = XCConfigurationList; buildConfigurations = ( 7DF997491B4B353600E90F56 /* Debug */, 7DF9974A1B4B353600E90F56 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 7D03732D1B49021700E2711D /* Project object */; } ================================================ FILE: apous.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: apous.xcodeproj/xcshareddata/xcschemes/apous.xcscheme ================================================ ================================================ FILE: misc/Components.plist ================================================ ================================================ FILE: misc/scripts/bootstrap.sh ================================================ #!/bin/bash export SCRIPT_DIR=$(dirname "$0") ## ## Bootstrap Process ## main () { local submodules=$(git submodule status) local result=$? if [ "$result" -ne "0" ] then exit $result fi if [ -n "$submodules" ] then echo "*** Updating submodules..." update_submodules fi } bootstrap_submodule () { local bootstrap="script/bootstrap" if [ -e "$bootstrap" ] then echo "*** Bootstrapping $name..." "$bootstrap" >/dev/null else update_submodules fi } update_submodules () { git submodule sync --quiet && git submodule update --init && git submodule foreach --quiet bootstrap_submodule } export -f bootstrap_submodule export -f update_submodules main ================================================ FILE: samples/basic/basic.swift ================================================ print("Hello! This is a simple sample that contains no dependencies.") ================================================ FILE: samples/carthage/Cartfile ================================================ github "thoughtbot/Argo" "td-swift-2" ================================================ FILE: samples/carthage/main.swift ================================================ import Argo import Runes print("dependencies imported properly") ================================================ FILE: samples/cocoapods/Podfile ================================================ platform :osx, '10.10' use_frameworks! plugin 'cocoapods-rome' pod "Argo", :git => "https://github.com/thoughtbot/Argo", :branch => "td-swift-2" ================================================ FILE: samples/cocoapods/main.swift ================================================ import Argo import Runes print("dependencies imported properly") ================================================ FILE: samples/multi/bar.swift ================================================ func bar() -> Int { return 1 } ================================================ FILE: samples/multi/foo.swift ================================================ func foo() -> Int { return 2 } ================================================ FILE: samples/multi/main.swift ================================================ print("foo: \(foo())") print("bar: \(bar())") ================================================ FILE: samples/nested/main.swift ================================================ print("Testing Nested Directories") print("abspath: \(abspath())") print("basename: \(basename())") ================================================ FILE: samples/nested/os/path/abspath.swift ================================================ func abspath() -> String { return "abspath!" } ================================================ FILE: samples/nested/os/path/basename.swift ================================================ func basename() -> String { return "basename!" } ================================================ FILE: samples/shebang/main.swift ================================================ #!/usr/local/bin/apous print("Hello! This is a simple sample that contains no dependencies.") ================================================ FILE: src/ErrorCodes.swift ================================================ // // ErrorCodes.swift // apous // // Created by David Owens on 7/5/15. // Copyright © 2015 owensd.io. All rights reserved. // enum ErrorCode: Int, ErrorType { case InvalidUsage = 1 case PathNotFound case CarthageNotInstalled case CocoaPodsNotInstalled case SwiftNotInstalled case PTYCreationFailed } ================================================ FILE: src/Tools.swift ================================================ // // Tools.swift // apous // // Created by David Owens on 7/5/15. // Copyright © 2015 owensd.io. All rights reserved. // import Foundation // I'm playing around with using functions as the types here because that's all // that is really needed. The types with a protocol extension in the previous // version just felt like way too much for what was really needed, which is // essentially just a way to invoke the tool with some arguments. /// The output type for a `Tool`. typealias TaskResult = (out: String,code: Int32) /// The function signature that all tools must conform to. typealias Tool = (args: String...) throws -> TaskResult /// Runs the given tool at `launchPath` passing in `args`. The output is then captured /// by `output` and `error`. func runTask(launchPath: String, args: [String] = [], outputToStandardOut: Bool = true) throws -> TaskResult { // This is the buffered output that will be returned. var out = "" // It turns out this code is not robust; it does not seem to always get all of the stream data. // BUG #12 - https://github.com/owensd/apous/issues/12 // // // Ok, so stdout sucks the big one. If your NSTask actually does any redirection to another // // tool that then outputs to stdout, that is going to be buffered and will only come back in // // chunks. // // var master: Int32 = 0 // var slave: Int32 = 0 // if openpty(&master, &slave, nil, nil, nil) == -1 { // throw ErrorCode.PTYCreationFailed // } // defer { // close(master) // close(slave) // } // // let output = NSFileHandle(fileDescriptor: master) func stream(handle: NSFileHandle) -> String { let data = handle.availableData let str = NSString(data: data, encoding: NSUTF8StringEncoding) as? String ?? "" // Sample string might look like this: ^[[34;1m***^[[0m Fetching ^[[1mArgo^[[0m // However, we need the escape codes to look like this: \e[34;1m***\e[0m Fetching \e[1mArgo\e[0m // Also, the normal output logged needs to have all of that stripped... func process(input: String, fn: (inout string: String, range: Range) -> ()) -> String { var str = input var range: Range? = nil var nextRange: Range? = nil repeat { range = str.rangeOfString( "(\\^)\\[\\[(\\d+;\\d+m|\\d+m)", options: NSStringCompareOptions.RegularExpressionSearch, range: nextRange) if let range = range { nextRange?.startIndex = range.endIndex fn(string: &str, range: range) } } while range != nil return str } let replaced = process(str) { (inout string: String, range: Range) in string.replaceRange(range.startIndex ..< range.startIndex.advancedBy(2), with: "\\e") } let stripped = process(str) { (inout string: String, range: Range) in string.removeRange(range) } if outputToStandardOut { // NOTE(owensd): Without the -n, additional newlines are getting in there... NSTask.launchedTaskWithLaunchPath("/bin/bash", arguments: ["-c", "echo -en $'\(replaced)'"]) } return stripped } let output = NSPipe() output.fileHandleForReading.readabilityHandler = { out += stream($0) } let task = NSTask() task.launchPath = try canonicalPath(launchPath) task.arguments = args task.standardOutput = output task.standardError = output task.terminationHandler = { ($0.standardOutput as? NSFileHandle)?.readabilityHandler = nil } task.launch() task.waitUntilExit() return ( out: out.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()), code: task.terminationStatus) } // Psuedo-namespace "tools" simulated with an enum with no cases. enum tools {} private func launchPathForTool(tool: String) throws -> String? { let result = try tools.which(tool) return result.out.characters.count == 0 ? nil : result.out } extension tools { static func which(args: String...) throws -> TaskResult { return try runTask("/usr/bin/which", args: args, outputToStandardOut: false) } static func pod(args: String...) throws -> TaskResult { guard let path = try launchPathForTool("pod") else { throw ErrorCode.CocoaPodsNotInstalled } let info = args.reduce("") { $0 + $1 + " " } print("Running pod \(info)") return try runTask(path, args: args) } static func carthage(args: String...) throws -> TaskResult { guard let path = try launchPathForTool("carthage") else { throw ErrorCode.CarthageNotInstalled } let info = args.reduce("") { $0 + $1 + " " } print("Running carthage \(info)") return try runTask(path, args: args) } static func swiftc(args: [String]) throws -> TaskResult { guard let path = try launchPathForTool("swiftc") else { throw ErrorCode.SwiftNotInstalled } return try runTask(path, args: args) } static func swiftc(args: String...) throws -> TaskResult { return try tools.swiftc(args) } } extension tools { static let CartfileConfig = "Cartfile" static let PodfileConfig = "Podfile" static func apous(path: String) throws -> TaskResult { let fileManager = NSFileManager.defaultManager() // The tools need to be run under the context of the script directory. fileManager.changeCurrentDirectoryPath(path) var frameworkPaths: [String] = [] if fileManager.fileExistsAtPath(path.stringByAppendingPathComponent(CartfileConfig)) { try tools.carthage("update") frameworkPaths += ["-F", "Carthage/Build/Mac"] } if fileManager.fileExistsAtPath(path.stringByAppendingPathComponent(PodfileConfig)) { try tools.pod("install", "--no-integrate") frameworkPaths += ["-F", "Rome"] } let files = filesAtPath(path) let args = frameworkPaths + ["-o", ".apousscript"] + files try tools.swiftc(args) return try runTask("./.apousscript") } } ================================================ FILE: src/Utils.swift ================================================ // // Utils.swift // apous // // Created by David Owens on 7/5/15. // Copyright © 2015 owensd.io. All rights reserved. // import Foundation public extension String { public var pathExtension: String { return (self as NSString).pathExtension } public var lastPathComponent: String { return (self as NSString).lastPathComponent } public var stringByDeletingLastPathComponent: String { return (self as NSString).stringByDeletingLastPathComponent } public var pathComponents: [String] { return (self as NSString).pathComponents } public func stringByAppendingPathComponent(str: String) -> String { return (self as NSString).stringByAppendingPathComponent(str) } } /// Returns the root path that contains the script(s). func canonicalPath(path: String) throws -> String { guard let cpath = path.cStringUsingEncoding(NSUTF8StringEncoding) else { throw ErrorCode.PathNotFound } let rpath = realpath(cpath, nil) if rpath == nil { throw ErrorCode.PathNotFound } guard let abspath = String(CString: rpath, encoding: NSUTF8StringEncoding) else { throw ErrorCode.PathNotFound } return abspath } /// Exit the process error with the given `ErrorCode`. @noreturn func exit(code: ErrorCode) { exit(Int32(code.rawValue)) } /// Returns the full path of the valid script files at the given `path`. func filesAtPath(path: String) -> [String] { let items: [String] = { return NSFileManager.defaultManager().subpathsAtPath(path) ?? [] }() return items .filter() { let root = $0.pathComponents[0] return $0.pathExtension == "swift" && (root != "Carthage" && root != "Rome" && root != "Pods") } .map() { path.stringByAppendingPathComponent($0) } } ================================================ FILE: src/main.swift ================================================ // // main.swift // apous // // Created by David Owens on 7/4/15. // Copyright © 2015 owensd.io. All rights reserved. // import Foundation func printUsage() { print("OVERVIEW: Apous Swift Script Runner (build: \(VersionInfo.Version.rawValue)-\(VersionInfo.Branch.rawValue))") print("") print("USAGE: apous [|]") } // // The body of the script. // let arguments = NSProcessInfo.processInfo().arguments if arguments.contains("-help") { printUsage() exit(0) } // This is used to enable more verbose logging. let DebugOutputEnabled = arguments.contains("-debug") // NOTE(owensd): This method is a workaround because of Swift bugs and code in the top-level scope. func run() throws { let scriptItem = arguments[1.. $VERSION_FILE echo "enum VersionInfo : String {" >> $VERSION_FILE echo " case Version = \"$VERSION\"" >> $VERSION_FILE echo " case Branch = \"$BRANCH_NAME\"" >> $VERSION_FILE echo "}" >> $VERSION_FILE ================================================ FILE: test/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType BNDL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 ================================================ FILE: test/Samples.swift ================================================ // // apoustest.swift // apoustest // // Created by David Owens on 7/6/15. // Copyright © 2015 owensd.io. All rights reserved. // import XCTest class SamplesTest : XCTestCase { lazy var samplesPath: String = { let path = NSBundle(forClass: self.dynamicType) .bundlePath .stringByDeletingLastPathComponent .stringByAppendingPathComponent("samples") ?? "" return path }() func validateSampleToolOutput(sample: String, output: String) { do { let path: String = samplesPath.stringByAppendingPathComponent(sample) if !NSFileManager.defaultManager().fileExistsAtPath(path) { XCTFail("The given samples path does not exist: \(path)") return } let result = try tools.apous(path) XCTAssertEqual( result.out.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()), output.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()), "The sample output does not match the expected.") } catch { XCTFail("An error occurred during test execution.") } } func testBasic() { let output = "Hello! This is a simple sample that contains no dependencies." validateSampleToolOutput("basic", output: output) } func testMulti() { let output = "foo: 2\nbar: 1" validateSampleToolOutput("multi", output: output) } func testNested() { let output = "Testing Nested Directories\nabspath: abspath!\nbasename: basename!" validateSampleToolOutput("nested", output: output) } }