GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — GitHub - macmade/ShellKit: Objective-C framework for running shell scripts.

BranchesTags
Open more actions menu

Latest commit

 

History

75 Commits
75 Commits

Folders and files

NameName
Last commit message
Last commit date
Assets
Assets
 
 
Documentation
Documentation
 
 
ShellKit-Test
ShellKit-Test
 
 
ShellKit.xcodeproj
ShellKit.xcodeproj
 
 
ShellKit
ShellKit
 
 
.gitignore
.gitignore
 
 
.travis.yml
.travis.yml
 
 
LICENSE
LICENSE
 
 
README.md
README.md
 
 

Repository files navigation

ShellKit

Build Status Coverage Status Issues Status License Contact
Donate-Patreon Donate-Gratipay Donate-Paypal

About

Objective-C framework for running shell scripts.

Terminal

Documentation

Documentation and API reference can be found at: http://doc.xs-labs.com/ShellKit/

Code Examples

ShellKit provides a test executable.
For complete examples, please take a look at the source code.

Shell informations

Various shell informations, like paths for commands, can be retrieved using the SKShell class:

[ [ SKShell currentShell ] commandIsAvailable: @"xcodebuild" ]

NSString * path = [ [ SKShell currentShell ] pathForCommand: @"xcodebuild" ]

Running simple commands

Arbitrary shell commands can be run using the SKShell class.
Note that commands are executed using the shell defined in the SHELL environment variable, invoked as a login shell.
Data for stdin can be provided; stdout and stderr can be retrieved.

[ [ SKShell currentShell ] runCommand: @"ls -al"
                           completion: ^( int status, NSString * output, NSString * error )
    {
        NSLog( @"%i", status );
        NSLog( @"%@", output );
        NSLog( @"%@", error );
    }
];

Running shell script tasks

A shell command can by run by using the SKTask object:

SKTask * task;

task = [ SKTask taskWithShellScript: @"ls -al" ];

[ task run ];

The task is run synchronously, and its output, if any, will be automatically printed to stdout.

The task will print the executed command prior to running, and print a status message once it's terminated, along with the elapsed time:

[ ShellKit ]> 🚦  Running task: ls -al
total 536
drwxr-xr-x  5 macmade  staff     170 May 11 23:49 .
drwxr-xr-x@ 4 macmade  staff     136 May 11 22:18 ..
-rwxr-xr-x  1 macmade  staff  124624 May 11 23:49 ShellKit-Test
drwxr-xr-x  7 macmade  staff     238 May 11 23:48 ShellKit.framework
-rw-r--r--  1 macmade  staff  143936 May 11 23:48 libShellKit-Static.a
[ ShellKit ]> ✅  Task completed successfully (63 ms)

A task can have sub-tasks, to try to recover from a failure:

SKTask * task;

task = [ SKTask taskWithShellScript: @"false" recoverTask: [ SKTask taskWithShellScript: @"true" ] ];

[ task run ];

Here, the false task will obviously fail, but it will then execute the true task, set as recovery.
As true will succeed, the false task will also succeed:

[ ShellKit ]> 🚦  Running task: false
[ ShellKit ]> ⚠️  Task failed - Trying to recover...
[ ShellKit ]> 🚦  Running task: true
[ ShellKit ]> ✅  Task completed successfully (66 ms)
[ ShellKit ]> ✅  Task recovered successfully (66 ms)

Optional tasks

A task can be marked as optional by using the SKOptionalTask.
In such a case, the task will succeed, regardless of its exit status:

SKOptionalTask * task;
            
task = [ SKOptionalTask taskWithShellScript: @"false" ];

[ task run ];
[ ShellKit ]> 🚦  Running task: false
[ ShellKit ]> ❌  Error - Task exited with status 1
[ ShellKit ]> ✅  Task is marked as optional - Not failing

Running task groups

Multiple tasks can be grouped in a SKTaskGroup object:

SKTask      * t1;
SKTask      * t2;
SKTaskGroup * group;

t1    = [ SKTask taskWithShellScript: @"true" ];
t2    = [ SKTask taskWithShellScript: @"true" ];
group = [ SKTaskGroup taskGroupWithName: @"task-group" tasks: @[ t1, t2 ] ];
        
[ group run ];

The group will try to run each task.
If a task fails, the whole group will also fail.

[ ShellKit ]> [ task-group ]> 🚦  Running 2 tasks
[ ShellKit ]> [ task-group ]> [ #1 ]> 🚦  Running task: true
[ ShellKit ]> [ task-group ]> [ #1 ]> ✅  Task completed successfully (64 ms)
[ ShellKit ]> [ task-group ]> [ #2 ]> 🚦  Running task: true
[ ShellKit ]> [ task-group ]> [ #2 ]> ✅  Task completed successfully (65 ms)
[ ShellKit ]> [ task-group ]> ✅  2 tasks completed successfully (132 ms)

Running task groups within task groups

A task group may also contain other task groups:

SKTask      * t1;
SKTask      * t2;
SKTaskGroup * g1;
SKTaskGroup * g2;

t1 = [ SKTask taskWithShellScript: @"true" ];
t2 = [ SKTask taskWithShellScript: @"true" ];
g1 = [ SKTaskGroup taskGroupWithName: @"child-group" tasks: @[ t1, t2 ] ];
g2 = [ SKTaskGroup taskGroupWithName: @"parent-group" tasks: @[ g1 ] ];
        
[ g2 run ];

The hierarchy of groups will be reflected by the prompt, like:

[ ShellKit ]> [ parent-group ]> [ #1 ]> [ child-group ]> [ #1 ]> 🚦  Running task: true

Note that task groups can also run custom classes, as long as they conform to the SKRunableObject protocol.

Variables substitution

A task may contain variables, that will be substituted when running.
A variable has the following form:

%{name}%

The variable name may contain letters from A to Z (uppercase or lowercase) and numbers from 0 to 9.

Variables are passed using the run: method of SKTask and SKTaskGroup.

SKTask * task;

task = [ SKTask taskWithShellScript: @"ls %{args}% %{dir}%" ];

[ task run: @{ @"args" : @"-al", @"dir" : @"/usr" } ];

In the example above, the executed script will be: ls -al /usr.

If no value is provided for a variable, the task will fail:

SKTask * task;

task = [ SKTask taskWithShellScript: @"echo %{hello}% %{foo}% %{bar}%" ];

[ task run: @{ @"hello" : @"hello, world" } ];
[ ShellKit ]> 🚦  Running task: echo hello, world %{foo}% %{bar}%
[ ShellKit ]> ⚠️  No value provided value for variable: foo
[ ShellKit ]> ⚠️  No value provided value for variable: bar
[ ShellKit ]> ❌  Error - Script contains unsubstituted variables

Printing messages

Messages can be printed very easily.
For this purpose, the SKShell class provides several methods, like the following one:

- ( void )printMessage: ( NSString * )format
          status:       ( SKStatus )status
          color:        ( SKColor )color,
                        ...;

The status represents an optional icon.
Colors can also be used, if the terminal supports it.

As an example:

[ [ SKShell currentShell ] printMessage: @"hello, %@"
                           status:       SKStatusDebug
                           color:        SKColorCyan,
                                         @"world"
];

will produce:

🚸 hello, world

Customising prompt

The prompt can be customised to reflect the hierarchy of the invoked commands.

For instance:

[ SKShell currentShell ].promptParts = @[ @"foo", @"bar" ];

Then, every printed message will be prefixed by:

[ foo ]> [ bar ]> ... message ...

License

ShellKit is released under the terms of the MIT license.

Repository Infos

Owner:          Jean-David Gadina - XS-Labs
Web:            www.xs-labs.com
Blog:           www.noxeos.com
Twitter:        @macmade
GitHub:         github.com/macmade
LinkedIn:       ch.linkedin.com/in/macmade/
StackOverflow:  stackoverflow.com/users/182676/macmade

About

Objective-C framework for running shell scripts.

www.xs-labs.com

Topics

commandframeworkmacosobjective-cshelltasktravisxcodebuild

Resources

Readme
MIT license
Activity

Stars

88 stars

Watchers

7 watching

Forks

6 forks
Report repository

Releases

Packages

Contributors

Languages

You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.