Thursday, February 2, 2023
Learning Code
  • Home
  • JavaScript
  • Java
  • Python
  • Swift
  • C++
  • C#
No Result
View All Result
  • Home
  • JavaScript
  • Java
  • Python
  • Swift
  • C++
  • C#
No Result
View All Result
Learning Code
No Result
View All Result
Home Swift

How to build better command line apps and tools using Swift?

learningcode_x1mckf by learningcode_x1mckf
September 14, 2022
in Swift
0
How to build better command line apps and tools using Swift?
74
SHARES
1.2k
VIEWS
Share on FacebookShare on Twitter


2021/08/05

The following tips will make it easier to to create wonderful CLI instruments, utility apps, server aspect initiatives or terminal scripts utilizing the Swift language.

Swift

Operating Swift recordsdata as scripts

It’s doable to run a Swift file straight from the command line should you add a hashbang to the start of the file. This manner you do not have to manually compile the code utilizing the swiftc command. You’ll be able to merely give the file the executable permission flag and the system will name the Swift REPL beneath the hood, so our app will be evaluated mechanically. 🔨


#!/usr/bin/env swift

print("Howdy, world!")


For instance this essential.swift file above will be marked as an executable file, and we are able to merely name it by way of the ./essential.swift command in a while (you simply have to make use of chmod just one time).


chmod +x essential.swift 
./essential.swift  


The great thing about this methodology is you could quickly check your Swift command line snippets. You’ll be able to even place the completed Swift scripts beneath the /usr/native/bin/ listing with out the swift file extension to make them obtainable “globally” to your working system consumer. 💪




Utilizing command line arguments in Swift

The CommandLine enum makes it very straightforward to fetch the arguments handed to our Swift software or script. You’ll be able to entry each argument utilizing the arguments variable as an array of Strings, however additionally it is doable to get the uncooked knowledge utilizing the argc and unsafeArgv properties.


#!/usr/bin/env swift


let script = CommandLine.arguments[0]
print("Script:", script)


let inputArgs = CommandLine.arguments.dropFirst()
print("Variety of arguments:", inputArgs.depend)

print("Arguments:")
for arg in inputArgs 
    print("-", arg)


It is best to word that the primary argument is all the time the trail of the present script, so if you’re solely in search of the enter arguments you need to use the dropFirst() methodology to return a subset of the enter strings. Normally every argument is separated by an area character.


./essential.swift hiya world




In Xcode you’ll be able to add customized arguments beneath the Edit Scheme… menu merchandise while you click on on the present scheme, search for the Arguments tab and use the Arguments Handed On Launch part.



Course of data and surroundings in Swift

Similar to we are able to entry command line arguments, it’s doable to look at the present course of together with some {hardware} data and surroundings variables.


#!/usr/bin/env swift
import Basis

let data = ProcessInfo.processInfo

print("Course of data")
print("Course of identifier:", data.processIdentifier)
print("System uptime:", data.systemUptime)
print("Globally distinctive course of id string:", data.globallyUniqueString)
print("Course of identify:", data.processName)

print("Software program data")
print("Host identify:", data.hostName)
print("OS main model:", data.operatingSystemVersion.majorVersion)
print("OS model string", data.operatingSystemVersionString)

print("{Hardware} data")
print("Energetic processor depend:", data.activeProcessorCount)
print("Bodily reminiscence (bytes)", data.physicalMemory)


print("Arguments")
print(ProcessInfo.processInfo.arguments)

print("Surroundings")

print(data.surroundings)


The surroundings variables property is a Dictionary the place each the keys and the values can be found as strings, so that you may need to parse them if you’re in search of totally different worth sorts. You’ll be able to arrange surroundings customized variables in Xcode similar to arguments, or you’ll be able to go them by way of the command line earlier than you execute the Swift script utilizing the export command.




Normal enter and output in Swift

You should use the print perform to write down textual content to the usual output, however you must word that the print perform has a variadic gadgets definition, so you’ll be able to go round a number of arguments and a customized separator & terminator parameter to show extra superior outputs.


There may be additionally a typical error stream, which is a part of the standard streams in fact, however what’s fascinating about it’s you could additionally write to this channel by way of the FileHandle.standardError property there may be fairly a chic answer on a Stack Overflow thread initially created by Rob Napier, I’ll embrace that one right here as effectively. 🙏


One other nice function of the print perform is the to parameter, which might settle for a customized TextOutputStream so you’ll be able to wrap the stderr stream in a customized object or you may also create customized output handlers and separate your print statements e.g. by context should you want.


#!/usr/bin/env swift
import Basis


print("This", "is", "enjoyable", separator: "-", terminator: "!")


"This goes to the usual error output"
    .knowledge(utilizing: .utf8)
    .map(FileHandle.standardError.write)


ultimate class StandardErrorOutputStream: TextOutputStream 
    func write(_ string: String) 
        FileHandle.standardError.write(Information(string.utf8))
    


var outputStream = StandardErrorOutputStream()
print("That is additionally an error", to: &outputStream)



func clear() 
    print("u1B[2J")
    print("u1B[(1);(0)H", terminator: "")


print("foooooooooooooooooooooo")
clear()
print("Hello, world!")



print("u1b[31;1mu1b[40;1m("Hello, world!")u1b[m")
print("u1b[32;1m("Hello, world!")u1b[m")


print("Please enter your input:")
guard let input = readLine(strippingNewline: true) else 
    fatalError("Missing input")

print(input)


The second half of the snippet is full of ANSI escape codes which I like quite a lot, because it can make our terminal output quite beautiful. The only problem is that they don’t work in Xcode at all (come-on Apple, please support this…). You can clear the console or change the background / foreground color of the output by using these codes.


There are quite a lot of libraries on GitHub that you can use to print colorful output, for example ColorizeSwift, ANSITerminal, ANSIEscapeCode and many more cool ones.


The very last thing that I’d like to show you is the readLine function, which you can use to read a line from the standard input. This comes handy if you need to get user input from the command line.



Use an argument parser library


If you are looking for a type-safe argument parser written in Swift, you should definitely take a look at the Swift Argument Parser library. It is created and maintained by Apple, so it’s kind of an official solution for this particular issue, but IMHO it lacks some advanced features.


This is the main reason why I prefer the Vapor command API built on top of the ConsoleKit library. Both libraries can parse arguments, options and flags, but ConsoleKit is also capable of displaying progress indicators, it features multiple command groups, secure input, auto-completion, multiple log levels and many more.




import Foundation
import ConsoleKit

final class HelloCommand: Command 
        
    struct Signature: CommandSignature 

        @Argument(name: "name", help: "The name to say hello")
        var name: String

        @Option(name: "greeting", short: "g", help: "Greeting used")
        var greeting: String?

        @Flag(name: "capitalize", short: "c", help: "Capitalizes the name")
        var capitalize: Bool
    

    static var name = "hello"
    let help = "This command will say hello to a given name."

    func run(using context: CommandContext, signature: Signature) throws 
        let greeting = signature.greeting ?? "Hello"
        var name = signature.name
        if signature.capitalize 
            name = name.capitalized
        
        print("(greeting) (name)!")
        
        
        let bar = context.console.progressBar(title: "Hello")
        bar.start()
        
        bar.succeed()
        
        
        let foo = context.console.ask("What?")
        print(foo)
        
        
        let baz = context.console.ask("Secure what?", isSecure: true)
        print(baz)
        
        
        let c = context.console.choose("Make a choice", from: ["foo", "bar", "baz"])
        print(c)

        
    



import Basis
import ConsoleKit

let console: Console = Terminal()
var enter = CommandInput(arguments: CommandLine.arguments)
var context = CommandContext(console: console, enter: enter)

var instructions = Instructions(enableAutocomplete: true)
instructions.use(HelloCommand(), as: HelloCommand.identify, isDefault: false)

do 
    let group = instructions.group(assist: "Utilizing ConsoleKit with out Vapor.")
    attempt console.run(group, enter: enter)

catch 
    console.error("(error)")
    exit(1)


You should use each answer by way of the Swift Package Manager, the setup course of is sort of straightforward, you may discover extra tutorials concerning the Swift Argument Parser and I believe that it’s more durable to seek out correct docs for ConsoleKit, so yeah… anyway, they’re nice libraries you will not remorse utilizing them. 😉



Benefit from the Swift Package deal Supervisor

The Swift Package Manager is among the neatest thing concerning the Swift programming language. I actually adore it and I take advantage of it virtually every single day. The truth that the bundle manifest file is outlined utilizing Swift itself makes it straightforward to make use of & perceive.



import PackageDescription

let bundle = Package deal(
    identify: "myProject",
    platforms: [
        .macOS(.v10_15)
    ],
    dependencies: [
        .package(url: "https://github.com/vapor/console-kit", from: "4.1.0"),
    ],
    targets: [
        .executableTarget(name: "myProject",dependencies: [
            .product(name: "ConsoleKit", package: "console-kit"),
        ]),
        .testTarget(identify: "myProjectTests", dependencies: ["myProject"]),
    ]
)


The bundle supervisor developed rather a lot in the course of the previous few months, should you check out the Swift Evolution dashboard you’ll be able to monitor these adjustments, the latest replace was the introduction of customized, user-defined Package Collections, however if you’re in search of packages you’ll be able to all the time check out the Swift Package Index web site. 👍






Source link

You might also like

The abstract Vapor service factory design pattern

SwiftNIO tutorial – The echo server

Introducing – Vapor cheatsheet – The.Swift.Dev.

Share30Tweet19
learningcode_x1mckf

learningcode_x1mckf

Recommended For You

The abstract Vapor service factory design pattern

by learningcode_x1mckf
February 1, 2023
0
The abstract Vapor service factory design pattern

I've written a number of articles about manufacturing unit design patterns on my weblog and this time I might like to speak a couple of particular one, which...

Read more

SwiftNIO tutorial – The echo server

by learningcode_x1mckf
January 27, 2023
0
SwiftNIO tutorial – The echo server

Intoducing SwiftNIO In the event you used a excessive degree net framework, corresponding to Vapor, up to now, you would possibly had some interplay with occasion loops...

Read more

Introducing – Vapor cheatsheet – The.Swift.Dev.

by learningcode_x1mckf
January 23, 2023
0
Introducing – Vapor cheatsheet – The.Swift.Dev.

Out there on Gumroad Thanks for supporting my work by buying the cheatsheet. 🙏 Download now A whole Vapor framework reference for novices. greater than...

Read more

iCloud Programming Tutorial for iOS: An Introduction

by learningcode_x1mckf
January 18, 2023
0
iCloud Programming Tutorial for iOS: An Introduction

Editor’s observe: This week, we work with Ziad Tamim once more to provide you an introduction of iCloud programming. You’ll learn to save and retrieve knowledge from iCloud.On...

Read more

Easy multipart file upload for Swift

by learningcode_x1mckf
January 18, 2023
0
Easy multipart file upload for Swift

I imagine that you've got already heard in regards to the well-known multipart-data add method that everybody likes to add recordsdata and submit type knowledge, but when not,...

Read more
Next Post
How to fix Javascript error: ipython is not defined?

How to fix Javascript error: ipython is not defined?

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Related News

Building Python Project Documentation With MkDocs – Real Python

Building Python Project Documentation With MkDocs – Real Python

September 20, 2022
Introduction to async/await in Swift

Introduction to async/await in Swift

September 15, 2022
The differences between Java and TypeScript devs must know

The differences between Java and TypeScript devs must know

October 26, 2022

Browse by Category

  • C#
  • C++
  • Java
  • JavaScript
  • Python
  • Swift

RECENT POSTS

  • Java :Full Stack Developer – Western Cape saon_careerjunctionza_state
  • Pay What You Want for this Learn to Code JavaScript Certification Bundle
  • UPB Java Jam brings coffeehouse vibes to Taylor Down Under | Culture

CATEGORIES

  • C#
  • C++
  • Java
  • JavaScript
  • Python
  • Swift

© 2022 Copyright Learning Code

No Result
View All Result
  • Home
  • JavaScript
  • Java
  • Python
  • Swift
  • C++
  • C#

© 2022 Copyright Learning Code

Are you sure want to unlock this post?
Unlock left : 0
Are you sure want to cancel subscription?