A cross-platform task runner for executing commands and generating files from templates

Overview

orbit's logo

Orbit

A cross-platform task runner for executing commands and generating files from templates

Travis CI AppVeyor GoDoc Go Report Card Codecov


Orbit started with the need to find a cross-platform alternative of make and sed -i commands. As it does not aim to be as powerful as these two commands, Orbit offers an elegant solution for running tasks and generating files from templates, whatever the platform you're using.

Menu

Install

Download the latest release of Orbit from the releases page. You can get Orbit for a large range of OS and architecture.

The file you downloaded is a compressed archive. You'll need to extract the Orbit binary and move it into a folder where you can execute it easily.

Linux/MacOS:

tar -xzf orbit*.tar.gz orbit
sudo mv ./orbit /usr/local/bin && chmod +x /usr/local/bin/orbit

Windows:

Right click on the file and choose Extract All.

Move the binary to a folder like C:\Orbit. Then, add it in your Path system environment variables. Click System, Advanced system settings, Environment Variables... and open Path under System variables. Edit the Variable value by adding the folder with the Orbit binary.

Alright, you're almost done 🤘 ! Let's check your installation by running:

orbit version

Generating a file from a template

Orbit uses the Go package text/template under the hood as a template engine. It provides a interesting amount of logic for your templates.

The Go documentation and the Hugo documentation cover a lot of features that aren't mentioned here. Don't hesitate to take a look at these links to understand the Go template engine! 😃

Also, Orbit provides Sprig library and three custom functions:

  • os which returns the current OS name at runtime (you may find all available names in the official documentation).
  • verbose which returns true if logging is set to info level.
  • debug which returns true if logging is set to debug level.

Command description

Base

orbit generate [flags]

Flags

-f --file

Specify the path of the template. This flag is required.

-o --output

Specify the output file which will be generated from the template.

Good to know: if no output is specified, Orbit will print the result to Stdout.

-p --payload

The flag -p allows you to specify many data sources which will be applied to your template:

orbit generate [...] -p "key_1,file_1.yml"
orbit generate [...] -p "key_1,file_1.yml;key_2,file_2.toml;key_3,file_3.json;key_4,.env;key_5,some raw data"

As you can see, Orbit handles 5 types of data sources:

  • YAML files (*.yaml, *.yml)
  • TOML files (*.toml)
  • JSON files (*.json)
  • .env files
  • raw data

The data will be accessible in your template through {{ .Orbit.my_key.my_data }}.

If you don't want to specify the payload each time your running orbit generate, you may also create a file named orbit-payload.yml in the folder where your running your command:

payload:

    - key: my_key
      value: my_file.yml
      
    - key: my_other_key
      value: Some raw data

By doing so, running orbit generate [...] will be equivalent to running orbit generate [...] -p "my_key,my_file.yml;my_other_key,Some raw data".

Note: you are able to override a data source from the file orbit-payload.yml if you set the same key in the -p flag.

-t --templates

The flag -t allows you to specify additional templates which are used in your template:

orbit generate [...] -t "template_1.txt"
orbit generate [...] -t "template_1.txt,template_2.yml"
orbit generate [...] -t "template_1.txt,template_2.yml,../../template_3.toml"

So, in order to generate a file from this template:

{{ template "additional_template.txt" }}

You should run:

orbit generate [...] -t "path/to/additional_template.txt"

If you don't want to specify the templates each time your running orbit generate, you may also use the file orbit-payload.yml in the folder where your running your command:

payload:

[...]

templates:

  - template_1.txt
  - template_2.yml

By doing so, running orbit generate [...] will be equivalent to running orbit generate [...] -t "template_1.txt,template_2.yml".

--delimiters

The flag --delimiters allows you to specify an alternative template delimiter pair (left/open, right/close). If unspecified, the Go defaults ({{ and }}) will be used. Note that, if this option is used, exactly two delimiters must be specified.

Examples:

<<,>>" orbit generate [...] --delimiters "<<" --delimiters ">>" ">
orbit generate [...] --delimiters "<<,>>"
orbit generate [...] --delimiters "<<" --delimiters ">>"

The first delimiter (<< in the examples above) is used for the left/opening delimiter while the second delimiter (>> in the examples above) is used for the right/closing delimiter. This applies regardless of whether the delimiters are specified as a comma-separated pair (first example) or by repeated use of the option (second example).

-v --verbose

Sets logging to info level.

-d --debug

Sets logging to debug level.

Basic example

Let's create our simple template template.yml:

companies:

{{- range $company := .Orbit.Values.companies }}
  - name: {{ $company.name }}
    launchers:
  {{- range $launcher := $company.launchers }}
    - {{ $launcher }}
  {{ end }}
{{- end }}

And the data provided a YAML file named data-source.yml:

companies:

  - name: SpaceX
    launchers:
      - Falcon 9
      - Falcon Heavy
      
  - name: Blue Origin
    launchers:
      - New Shepard
      - New Glenn

agencies:

  - name: ESA
    launchers:
      - Ariane 5
      - Vega

The command for generating a file from this template is quite simple:

orbit generate -f template.yml -p "Values,data-source.yml" -o companies.yml

This command will create the companies.yml file with this content:

companies:

  - name: SpaceX
    launchers:
      - Falcon 9
      - Falcon Heavy
      
  - name: Blue Origin
    launchers:
      - New Shepard
      - New Glenn

Defining and running tasks

Command description

Base

orbit run [tasks] [flags]

Flags

-f --file

Like the make command with its Makefile, Orbit requires a configuration file (YAML, by default orbit.yml) where you define your tasks:

tasks:

  - use: my_first_task
    short: My first task short description
    run:
      - command [args]
      - command [args]
      - ...
      
  - use: my_second_task
    private: true
    run:
      - command [args]
      - command [args]
      - ...
  • the use attribute is the name of your task.
  • the short attribute is optional and is displayed when running orbit run.
  • the private attribute is optional and hides the considered task when running orbit run.
  • the run attribute is the stack of commands to run.
  • a command is a binary which is available in your $PATH.

Once you've created your orbit.yml file, you're able to run your tasks with:

orbit run my_first_task
orbit run my_second_task
orbit run my_first_task my_second_task

Notice that you may run nested tasks 🤘 !

Also a cool feature of Orbit is its ability to read its configuration through a template.

For example, if you need to execute a platform specific script, you may write:

tasks:

  - use: script
    run:
    {{ if ne "windows" os }}
      - my_script.sh
    {{ else }}
      - .\my_script.bat
    {{ end }}

Orbit will automatically detect the shell you're using (with the SHELL environment variable on POSIX system and COMSPEC on Windows).

Running the task script from the previous example will in fact executes cmd.exe /c .\my_script.bat on Windows or /bin/sh -c my_script.sh (or /bin/zsh -c my_script.sh etc.) on others OS.

Of course, if you want to specify the binary which is calling your commands, there is a shell attribute available:

tasks:

  - use: script
    shell: /bin/bash -c
    run:
      - command [args]
      - ...

Last but not least, a task is able to call others tasks within the same context thanks to the run function:

tasks:

  - use: task
    run:
      - {{ run "subtask_1" "subtask_2" }}

  - use: subtask_1
    run:
      - command [args]
      - ...
     
  - use: subtask_2
    run:
      - command [args]
      - ...
-p --payload

The flag -p allows you to specify many data sources which will be applied to your configuration file.

It works the same as the -p flag from the generate command.

Of course, you may also create a file named orbit-payload.yml in the same folder where you're executing Orbit.

-t --templates

The flag -t allows you to specify additional templates which are used in your configuration file.

It works the same as the -t flag from the generate command.

Of course, you may also create a file named orbit-payload.yml in the same folder where you're executing Orbit.

-v --verbose

Sets logging to info level.

-d --debug

Sets logging to debug level.

Basic example

Let's create our simple configuration file orbit.yml:

tasks:

  - use: prepare
    run:
     - orbit generate -f configuration.template.yml -o configuration.yml -p "Data,config.json"
     - echo "configuration.yml has been succesfully created!"

You are now able to run the task prepare with:

orbit run prepare

This task will:

  • create a file named configuration.yml
  • print configuration.yml has been succesfully created! to Stdout

Voilà! 😃


Would you like to update this documentation ? Feel free to open an issue.

Issues
  • Orbit tasks fail if the caller shell is not compatible with the `run` expected shell

    Orbit tasks fail if the caller shell is not compatible with the `run` expected shell

    We found out that when designing a simple task such as:

    run
          - |
            cat > foo.yml <<EOF
            app:
              name: {{ $.Orbit.Values.app.name }}
            EOF
    

    it would fail for user having a shell not supporting this syntax (in my case, my fish shell is not happy about that:

    fish: Expected a string, but instead found a redirection
    cat > foo.yml <<EOF
    
    enhancement 
    opened by octplane 7
  • Running other tasks from a task

    Running other tasks from a task

    Context

    As a user, I would like to declare a task that calls other orbit task. Since the orbit.yml is templated, this makes it hard to call orbit again with the same calling parameters.

    Example: orbit is run using orbit run -p Tasks,tasks.yml -f ../shared-orbit.yml <task_name>

    In order to call other tasks from a given task, I would have to copy/paste that line which is far from ideal since it implies the task as knowledge of how it gets called.

    Proposal

    Add a tasks entry to refer to other tasks in the current file. In order to remove confusion, either tasks or run should be provided, not both, otherwise order of command execution would be unknown.

    tasks:
    {{ range $app := .Orbit.Tasks }}
      - use: {{ $app }}
        tasks:
        - {{ $app }}:render
        - {{ $app }}:upload
      - use: {{ $app }}:render
        run:
         - echo "{{$app }}: render step"
      - use: {{ $app }}:upload
        run:
         - echo "{{ $app }}: upload step"
    {{ end }}
    

    Now, with a tasks.yml with the following content

    - foo
    - bar
    

    Running orbit run -p Tasks,tasks.yml foo bar should print

    foo: render step
    foo: upload step
    bar: render step
    bar: upload step
    

    Your Environment

    • Version used (orbit version): 3.0.1

    Thanks for writing this app, it has been super useful so far 👍

    enhancement question 
    opened by j-vizcaino 6
  • Question : how to check if file exists ?

    Question : how to check if file exists ?

    Is it possible to check if some file exists in orbit.yml. I want to create a conditional task that runs one command if some file exists and another one if not.

    Thanks in advance for your help.

    opened by kpym 5
  • adding the possibility to call others tasks from a task

    adding the possibility to call others tasks from a task

    This PR enable calling others tasks from a task within the same context.

    orbit.yml:

    tasks:
      - use: app
      - run:
          - {{ run "render" "upload" }}
          - echo "done!"
    
      - use: render
      - run:
          - cmd
    
      - use: upload
      - run:
          - cmd
    

    Fixes #24

    opened by gulien 4
  • runner: support shell parameter

    runner: support shell parameter

    Summary

    This PR allows the user to choose a shell to run the task.

    shell support single or multiple commands to run the shell:

    Run using bash:

      - use: "falcon"
        shell: bash -c
        run:
          - dep status
    

    This PR implements the following feature:

    • [X] #27

    Fixes #27

    Checklist

    • [X] Have you followed the guidelines in our CONTRIBUTING guide?
    • [X] Have you fmt your code locally prior to submission (orbit run fmt)?
    • [X] Have you written new tests for your core changes, as applicable?
    • [X] Have you successfully ran tests with your changes locally (orbit run ci)?
    • [X] I have squashed any insignificant commits
    • [X] This change has comments for package types, values, functions, and non-obvious lines of code
    enhancement 
    opened by octplane 4
  • adding verbose flag

    adding verbose flag

    Adds -v--verbose flag which displays less logs than the -d --debug flag.

    Example when running a task:

    INFO[0000] running task fmt: Runs go fmt ./...
    INFO[0000] executing command [/bin/zsh -c go fmt ./...]
    

    Feature request from #29

    enhancement 
    opened by gulien 3
  • Optional delimiter specification

    Optional delimiter specification

    A similar PR may already be submitted! Please search among the pull requests before creating one.

    Thanks for submitting a pull request! Please provide enough information so that others can review your pull request:

    For more information, see the CONTRIBUTING guide.

    Summary

    This PR fixes/implements the following bugs/features

    • [x] Feature: Optional alternative template delimiters (#36)

    Explain the motivation for making this change. What existing problem does the pull request solve?

    This PR gives the user the ability to specify template delimiters that are alternative to the go defaults of {{ and }}. This is especially useful where a template contains many instances of these default sequences that are not to be interpolated/expanded by orbit, and would otherwise require potentially cumbersome escaping.

    Test plan (required)

    Demonstrate the code is solid. Example: The exact commands you ran and their output.

    Existing test suites have been extended to verify expected behaviour.

    Closing issues

    Fixes #36

    Checklist

    • [x] Have you followed the guidelines in our CONTRIBUTING guide?
    • [x] Have you fmt your code locally prior to submission (orbit run fmt)?
    • [x] Have you written new tests for your core changes, as applicable?
    • [x] Have you successfully ran tests with your changes locally (orbit run ci)?
    • [x] I have squashed any insignificant commits
    • [x] This change has comments for package types, values, functions, and non-obvious lines of code
    opened by i-am-david-fernandez 2
  • Display short field when running tasks

    Display short field when running tasks

    This is a feature request. Not sure this is an actual use case.

    In my tasks, I run several generated tasks from one single task (such as apps:upload that will upload a bunch of apps on a server).

    The fact that Orbit does not show any information about the tasks it runs is a bit confusing. I had to recode some artificial debug info to make that more easy:

    {{- $title := printf "Render and deploy app for %s to %s on %s" $.Orbit.Values.app.name $deploy.k8s_cluster $deploy.aws_account}}
      - use: {{ $stage }}
        short: {{ $title}}
        run:
          - echo "{{ $title }}"
    

    The alternative is to run Orbit -d but this is very verbose!

    I wanted to know if it could be possible:

    • either have a -i (like info) flag that would display this information
    • or inject an env variable so that the run code can access this information
    • or always print this information

    Let me know what you think of this...

    enhancement 
    opened by octplane 2
  • Orbit run kickoff - ValueError: dictionary update sequence element #0 has length 20; 2 is required

    Orbit run kickoff - ValueError: dictionary update sequence element #0 has length 20; 2 is required

    Hello, please check the error I found while doing run for the command

    [email protected]:~/Code/priips$ sudo orbit run kickoff Setting UID (0) to "www-data" user in Docker Sync configuration file ... Traceback (most recent call last): File "bin/docker-compose", line 6, in File "compose/cli/main.py", line 68, in main File "compose/cli/main.py", line 121, in perform_command File "compose/cli/main.py", line 768, in run File "compose/cli/main.py", line 1178, in run_one_off_container File "compose/service.py", line 288, in create_container File "compose/service.py", line 795, in _get_container_create_options File "compose/service.py", line 1338, in build_container_labels ValueError: dictionary update sequence element #0 has length 20; 2 is required Failed to execute script docker-compose

    this run inside vagrant machine

    opened by abdelrhman-allam 2
  • Ability to include other templates in generate

    Ability to include other templates in generate

    Expected Behavior

    I would like the ability to include the ability to insert other partial templates into my main template. so let say I have the following traefik.toml file (abbr.):

    {{ template "autogen_notice.txt" }}
    ... traefik config ...
    

    and then in my autogen_notice.txt I have a message warning devops peeps that the file is autogenerated and changes will be overridden if they edit it.

    Current Behavior

    Currently I get a error:

    ERRO[0000] unable to execute the template file ./templates/traefik.toml. Details:
    template: traefik.toml:1:12: executing "traefik.toml" at <{{template "./templa...>: template 
    "./templates/autogen.txt" not defined
    

    I suspect this is because the included template is not defined in template.ParseFiles, so I'm wondering if there is any kind of workaround for this.

    Possible Solution

    Could we have a flag in the generate command to specify a list of templates to include in ParseFiles?

    Context

    There are a couple of instances where I need to re-use config snippets or messages (like the one used above), and currently I'm just resorting to copying them into every file. But it means If I make a edit in one, then I have to remember and update the rest also.

    Your Environment

    • Version used (orbit version): 3.1.0
    • Operating System and version: n/a
    • Link to your project: n/a
    opened by andrewebdev 1
  • Template rendering fails when using an undefined variable

    Template rendering fails when using an undefined variable

    Summary

    Rendering fails when using an undefined variable. Previous implementation was replacing the value with <no value>. For more information, see https://devdocs.io/go/text/template/index#Template.Option

    Closing issues

    Fixes #25

    Checklist

    • [x] Have you fmt your code locally prior to submission (orbit run fmt)?
    • [x] Have you written new tests for your core changes, as applicable?
    • [x] Have you successfully ran tests with your changes locally (orbit run ci)?
    • [x] I have squashed any insignificant commits
    opened by j-vizcaino 1
  • Replace dep with go modules

    Replace dep with go modules

    A similar PR may already be submitted! Please search among the pull requests before creating one.

    Thanks for submitting a pull request! Please provide enough information so that others can review your pull request:

    For more information, see the CONTRIBUTING guide.

    Summary

    This PR fixes/implements the following bugs/features

    • [x] Replace dep with go modules

    Closing issues

    Fixes #35

    Checklist

    • [ ] Have you followed the guidelines in our CONTRIBUTING guide?
    • [x] Have you fmt your code locally prior to submission (orbit run fmt)?
    • [ ] Have you written new tests for your core changes, as applicable?
    • [x] Have you successfully ran tests with your changes locally (orbit run ci)?
    • [ ] I have squashed any insignificant commits
    • [ ] This change has comments for package types, values, functions, and non-obvious lines of code
    opened by condemil 2
  • Would it be worth migrating to go modules instead of dep?

    Would it be worth migrating to go modules instead of dep?

    Expected Behavior

    Use go modules instead of dep now that it's standard.

    Current Behavior

    Currently it seems that dep is being used, and while it may work, the repo and codebase could be simplified if we just use what's now provided as standard.

    Context

    I'm in the process of creating a pull request that will add snap package support for this app and using the standard go modules would make the packaging a bit simpler.

    opened by andrewebdev 1
Releases(v3.3.0)
Owner
Julien Neuhart
Senior Backend Developer @Meetic, previously IT Architect @thecodingmachine
Julien Neuhart
Task Timer (tt) is a dead simple TUI task timer

tasktimer Task Timer (tt) is a dead simple TUI task timer Usage To get started, just run tt: tt You'll be presented with something like this: You can

Carlos Alexandro Becker 230 Jun 28, 2022
Gotask - A simple task queue is stripped when the program is written to achieve the task delivery function

gotask The simple task queue is stripped when the program is written to achieve

SaiRson 4 Feb 14, 2022
Go-based runner for Cron Control

Cron Control Runner A Go-based runner for processing WordPress cron events, via Cron Control interfaces. Installation & Usage Clone the repo, and cd i

Automattic 7 Jun 11, 2022
Chrono is a scheduler library that lets you run your task and code periodically

Chrono is a scheduler library that lets you run your tasks and code periodically. It provides different scheduling functionalities to make it easier t

Procyon 182 Jun 18, 2022
Distributed Task Scheduling System|分布式定时任务调度平台

Crocodile Distributed Task Scheduling System English | 中文 Introduction A distributed task scheduling system based on Golang that supports http request

labulaka521 854 Jun 24, 2022
go task pool

Task Pool Task Pool 是一个易于使用且高度可配置的 golang类库,专门用于任务的管理&执行,支持自定义次数的重发。 功能特点 线程安全 - task pool 内所有的方法以及暴露的接口都是线程安全的 异步发送 - 调用 PushTask 方法后回立即返回,任务将会被传递到io

qinhan 30 Feb 21, 2022
Celery Distributed Task Queue in Go

gocelery Go Client/Server for Celery Distributed Task Queue Why? Having been involved in several projects migrating servers from Python to Go, I have

gocelery 2k Jun 19, 2022
Machinery is an asynchronous task queue/job queue based on distributed message passing.

Machinery Machinery is an asynchronous task queue/job queue based on distributed message passing. V2 Experiment First Steps Configuration Lock Broker

Richard Knop 6.3k Jun 21, 2022
high performance distributed task scheduling system, Support multi protocol scheduling tasks

high performance distributed task scheduling system, Support multi protocol scheduling tasks

null 52 Jun 14, 2022
YTask is an asynchronous task queue for handling distributed jobs in golang

YTask is an asynchronous task queue for handling distributed jobs in golang

gojuukaze 201 Jun 10, 2022
goInterLock is golang job/task scheduler with distributed locking mechanism (by Using Redis🔒).

goInterLock is golang job/task scheduler with distributed locking mechanism. In distributed system locking is preventing task been executed in every instant that has the scheduler,

Jay Ehsaniara 22 Jun 11, 2022
go-sche is a golang library that lets you schedule your task to be executed later.

go-sche is a golang library that lets you schedule your task to be executed later.

cza 2 May 29, 2022
Go distributed task scheduler

Go distributed task scheduler

Nuggets 1 Nov 13, 2021
Tasks - Golang CLI, Task manager

Tasks Golang CLI, Task manager Prerequisites Golang Setup environment variables

Santiago Bedoya 0 Jan 30, 2022
Easily schedule commands to run multiple times at set intervals (like a cronjob, but with one command)

hakcron Easily schedule commands to run multiple times at set intervals (like a cronjob, but for a single command) Description hakcron allows you to r

Luke Stephens (hakluke) 77 May 19, 2022
Cloud-native, enterprise-level cron job platform for Kubernetes

Furiko Furiko is a cloud-native, enterprise-level cron and adhoc job platform for Kubernetes. The main website for documentation and updates is hosted

Furiko 124 Jun 22, 2022
A simple Cron library for go that can execute closures or functions at varying intervals, from once a second to once a year on a specific date and time. Primarily for web applications and long running daemons.

Cron.go This is a simple library to handle scheduled tasks. Tasks can be run in a minimum delay of once a second--for which Cron isn't actually design

Robert K 210 May 4, 2022
Run Jobs on a schedule, supports fixed interval, timely, and cron-expression timers; Instrument your processes and expose metrics for each job.

A simple process manager that allows you to specify a Schedule that execute a Job based on a Timer. Schedule manage the state of this job allowing you to start/stop/restart in concurrent safe way. Schedule also instrument this Job and gather metrics and optionally expose them via uber-go/tally scope.

Sherif Abdel-Naby 57 Mar 28, 2022
Lightweight, fast and dependency-free Cron expression parser (due checker) for Golang (tested on v1.13 and above)

adhocore/gronx gronx is Golang cron expression parser ported from adhocore/cron-expr. Zero dependency. Very fast because it bails early in case a segm

Jitendra Adhikari 203 Jun 22, 2022