Aalexander
Aalexander

Reputation: 5004

swift main run / build from command line

I will build an CLI Tool in Swift. I have created the project with this command swift package init --type executable

When I build my project and parse the read-aliases parameter in Xcode and click the "Play" Button everything worked fine.

Play Button I defined the read-aliases parameter

parameter

Then I receive the right output it is the following, the aliases from my .zsh file

These are your Aliases
zshconfig="mate ~/.zshrc"
ohmyzsh="mate ~/.oh-my-zsh"
python="/usr/local/bin/python3.7"
python2="/usr/bin/python2"
Program ended with exit code: 0

But when I run the following command swift run inside my project in the command line

Then I receive start from command line

Which seems to work so far these are the messages from my tool.

An when I parse the same parameter like this

 $ swift run read-aliases

I get this error

error: no executable product named 'read-aliases'

Here is my code

import Foundation
import ArgumentParser

struct Alias: ParsableCommand {
    static let configuration = CommandConfiguration(
        abstract: "Make Editing Your .zshrc Much Easier",
        subcommands: [readAliases.self])
}
extension Alias {
    struct readAliases: ParsableCommand {
        static let configuration = CommandConfiguration(
            abstract: "Reads All The Aliases In Your .zshrc File")
        
        func run() {

            print("These are your Aliases");
            readFile(path: "/Users/alexanderhess/.zshrc")
           }
            func readFile(path: String) -> Int {
                errno = 0
                if freopen(path, "r", stdin) == nil {
                    perror(path)
                    return 1
                }
                while let line = readLine() {
                    if(line.starts(with: "# alias")){
                        print(line.dropFirst(8));
                    }
                }
                return 0
            }
    }
}
Alias.main();

My Package.swift

// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "easy-aliaser",
    dependencies: [
        // Dependencies declare other packages that this package depends on.
        // .package(url: /* package url */, from: "1.0.0"),
         .package(url: "https://github.com/apple/swift-argument-parser", from: "0.2.0"),
    ],
    targets: [
        // Targets are the basic building blocks of a package. A target can define a module or a test suite.
        // Targets can depend on other targets in this package, and on products in packages this package depends on.
        .target(
            name: "easy-aliaser",
            dependencies: [
                .product(name: "ArgumentParser", package: "swift-argument-parser")
            ]),
        .testTarget(
            name: "easy-aliaserTests",
            dependencies: ["easy-aliaser"]),
    ]
)

Here is my github repository in case you would like to reproduce it.

So why I receive this Error in the Command Line but not in Xcode?

Thanks in advance.

Upvotes: 3

Views: 2302

Answers (1)

Franco Rondini
Franco Rondini

Reputation: 11011

the problem

the command command line specify sub-command but miss the executable product

$ swift run read-aliases

the solution

you must use the executable product before sub-command

swift run easy-aliaser read-aliases

steps to reproduce

[so-test]$ git clone https://github.com/CreaTorAleXander/easy-aliaser
Cloning into 'easy-aliaser'...
remote: Enumerating objects: 41, done.
remote: Counting objects: 100% (41/41), done.
remote: Compressing objects: 100% (32/32), done.
remote: Total 41 (delta 2), reused 38 (delta 1), pack-reused 0
Unpacking objects: 100% (41/41), done.
[so-test]$ cd easy-aliaser 

#
# [easy-aliaser (main)]$ swift package generate-xcodeproj
# edited the wired filename in your code just to refer to an existing file
# run the project in XCode without problems  
# back to the command line 
#

[easy-aliaser (main)]$ swift run easy-aliaser read-aliases
Fetching https://github.com/apple/swift-argument-parser
Cloning https://github.com/apple/swift-argument-parser
Resolving https://github.com/apple/swift-argument-parser at 0.3.1
/Users/me/projects/so-test/easy-aliaser/Sources/easy-aliaser/main.swift:23:13: warning: result of call to 'readFile(path:)' is unused
            readFile(path: "/Users/me/projects/so-test/65203567/myzshrc")
            ^       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[3/3] Linking easy-aliaser
These are your Aliases
who_listening='sudo lsof -nP -iTCP -sTCP:LISTEN'
du-docker="du -h ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/Docker.qcow2 && docker images"
du-openshift=" /Users/ronda/.docker/machine/machines/openshift/disk.vmdk && du -h ~/.docker/machine/machines/openshift/boot2docker.iso"

Upvotes: 4

Related Questions