Giter VIP home page Giter VIP logo

myke's Introduction

myke Latest Release Build Status Go Report Card codecov

myke makes it easy to write development tasks

Development scripts usually begin as a simple shell wrapper with switch cases (service.sh start|stop|etc), and then aggregate multiple scripts, add arguments, discovery/listing, environment variable handling, then easy overriding and defaults, and soon manipulating files based on these variables, sed|awk|envsubst, then proceed to python/ruby/etc with some real templating, then start adding dependencies, then become projects themselves with a checkout/setup process :trollface:

myke solves all these problems in a single tiny binary, to avoid reinventing the same stuff over and over again.

Features

  • Define tasks in simple .yml files
  • Tasks execute in a predictable environment irrespective of which folder they are invoked from
  • Nice aggregation and discovery with tag-based grouping, suitable for few and many tasks, organizing into subfolders/submodules/repos/projects
  • Robust environment handling - Can be defined as keys in the YML or as dotenv files, overridden by dotenv.local files, PATH is always prepended, shell always takes precedence
  • Built-in templating using golang text/template and 50+ functions provided by sprig
  • Mixin ymls to share tasks, envvars, etc
  • Runtime arguments like myke task1 --key1=val1 task2 --key2=val2 ...
  • before/after/error hooks to perform cleanups, chains with mixins, etc
  • retry support with max and delay for failing tasks
  • Tiny, cross-platform binaries
  • and a lot of small utilities packed in

Usage

Create myke.yml with tasks. For example, running myke on this folder prints:

  PROJECT  |    TAGS    |             TASKS
+----------+------------+-------------------------------------+
  myke     |            | test
  example  |            | build
  env      |            | env
  tags1    | tagA, tagB | tag
  tags2    | tagB, tagC | tag
  depends  |            | after, before, before_after, itself
  template |            | args, file
  mixin    |            | task2, task3, task1

Using the above myke.yml, you can invoke tasks like:

  • myke build runs build in all projects
  • myke <project>/build runs build in that specific <project>
  • myke <tag>/build runs build in all projects tagged <tag>
  • myke <tagA>/<tagB>/.../build can match tasks by many tags (AND)
  • myke task1 --key1=val1 task2 --key2=val2 ... passes arguments to individual tasks

Installation

Examples

Explore the self documenting examples folder.

Task Execution Environment

  • tasks always run with cwd set to the folder where the task is defined
  • cwd/bin is always added to PATH
  • environment variables are loaded from:
    • env property in yml
    • dotenv files from env_files
    • for every dotenv file, the corresponding dotenv .local file is also loaded if present
  • same is done for every mixin that the yml uses
    • So, if you mixin <some-other-folder>/myke.yml, then that yml's cwd/bin is also added to the PATH, that yml's env/env_files/env_files.local are also loaded, and so on
  • shell exported environment variables take precedence
  • additional variables: $MYKE_PROJECT, $MYKE_TASK, $MYKE_CWD are always set
    • $myke is set to full path of myke itself to easily nest myke calls (e.g. $myke do_something will become myke.exe do_something in windows)
  • command is templated using golang text/template and sprig
    • environment and task arguments are passed in as variables
  • command is run using sh -exc

FAQs

How do I share common logic in tasks?

There are multiple ways including:

  • Place shared scripts in bin folder (remember that CWD/bin is always added to the PATH). If the scripts are complex, you can write them in any scripting language of your choice
  • If multiple projects need to share the same scripts, then use a common mixin folder (remember that for mixin ymls - the same CWD/bin is added to PATH, same env files are loaded, etc, refer Task Execution Environment above)

For example,

  • java-mixin
    • myke.yml - project template with tasks
    • myke.env - environment vars, can be overridden by extending projects
    • bin - gets added to the PATH of extending projects
      • any shared scripts that you want
  • kubernetes-mixin
    • ...
    • ...

Why use myke?

Deferring higher order build logic (like reading scm history for changelogs, updating scm tags/branches, generating version numbers, etc) to a meta-build tool (like a task runner or aggregator), restricting build tools to do only simple source builds, and having a shared build vocabulary across projects is a generally good idea. There are millions of such meta-build tools or task aggregators out there, we just wanted something fast, zero-dependency and language-agnostic while still helping us manage multiple components across repositories with ease.

In that sense, myke is never a build or deployment tool, its just a task aggregator. Its not designed to be an alternative for source build tools, rather it just augments them. The comparison below is on that same perspective.

  • maven is a lifecycle reactor and/or project management tool that does a lot of things (compilation/scm/release/lifecycle/build/etc), except its hard to use it as a simple task runner. myke focuses only on the latter
  • bazel buck pants gradle ... replace your current buildchain by giving you a totally new DSL to compile your programs (java_binary, etc). myke simply acts as a yml-based interface to your existing tools and workflows, thereby not needing to change your project and IDE setup
  • grunt gulp pyinvoke rake sake thor ... myke is zero-dependency, language agnostic, uses simple yml and allows aggregation of tasks through hierarchies, templates and tags
  • make scons ninja ... they are low-level build tools with a crux of file-based dependencies. Most buildchains today are already intelligent enough to process only changed files, so myke completely bypasses file tracking and only focuses on task aggregation and discoverability
  • capistrano fabric ... myke is not a deployment tool for remote machines, and does not do anything over SSH
  • ansible salt ... myke is not a configuration management tool, its a task runner
  • robo is the closest relative to myke, you should check it out as well

Development

Use docker/docker-compose to develop. You don't need to have golang installed.

  • docker-compose build Builds and runs tests
  • docker-compose up Produces bin folder with executables
  • docker-compose run --rm default /bin/bash Gives you a terminal inside the container, from where you can run go commands like:
    • go test ./... Runs all tests
    • go run main.go Compiles and runs main

myke's People

Contributors

blaubaer avatar pkuczynski avatar rdsubhas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

myke's Issues

Add CLA

Add Contributor License Agreement to start accepting contributions

Review README

Make sure README acts as a good documentation for a newcomer reading it.

Load extra .env file as a global CLI flag

Right now, if we want to override flags, one must:

export A=... B=...
# or
set -a
source .env-file
# or
A=... B=... myke doSomething

Proposal to support a CLI flag to load an extra dotenv file:

myke -e test.env doSomething

Could be useful for templating

Environment variables/files for specific tasks

Proposal

Support env and env_files for tasks

Questions

  • How will env variable cascading/inheritance work between project, shell, tasks, etc

Alternative

  • Use export ... in the task's cmd

Avoid conflicting namespace for built-in tasks

Right now, there are some core tasks like myke list, myke run, etc.

myke --help
COMMANDS:
     list      list available tasks
     run       query to execute of format tag1/tag2/project/task[arg1=val1,arg2=val2,...]
     template  render a template file with environment variables
     license   prints licenses
     help, h   Shows a list of commands or help for one command

They will conflict with tasks defined in YML files (e.g. mysql/run or api/run). Decide on a namespace for built-in tasks.

Allow globbing in files

  • Allow wildcard globbing in files
  • Things to ponder: not conflicting with shell expansion, using the same globbing in mixin/discover, etc.
  • Descoped for 1.0 because its not required now

Execute after tasks regardless of exit code

Moving issue from old repo /cc @vpillac @piotrpolatowski

Option 1

task:
  cmd: doSomething
  finally: doCleanup

Where finally is always executed upon task exit

Option 2

task:
  cmd: doSomething
  after: doCleanup
  error: doCleanup

Where after is already supported (before/after) and error would be a new keyword which runs only upon error. Doing cleanup would mean you would fill in both error and after, which is slightly more verbose (i.e. midway between Option 1 and bash), but at the same time gives an additional flexibility of doing stuff upon error (like alerting, scraping logs, etc). So while its slightly more verbose, it also kills two birds in one stone.

There are also other specifics, like what to do if Ctrl+C/SIGTERM/SIGINT is sent when a command is half-executing - in that case should myke trap those signals and call the failure/finally command, etc. But for now, lets assume that behavior is undefined when forcefully exiting myke, and then define it later...

Better task list rendering

  • Current tabular output is capped at 80 chars. Make it full terminal width. Unfortunately most table formatting libraries in Golang aren't termwidth friendly, might have to make it custom
  • Provide flag to switch between tabular or list mode

Integrate with upx

For vastly smaller binaries. upx had an issue with macOS Sierra but that has been resolved, upx -f -o date.upx /bin/date works. Make myke also use it.

Right now gox compressed myke binaries are failing with upx, maybe because:

  • Some library is causing the problem (urfave/cli not the problem)
  • Or try with normal GOOS/GOARCH builds instead of gox

Before/After/Error Hook Semantics

Options:

before: taskA[a=b] taskB[c=d]

before: myke taskA[a=b] taskB[c=d]

before:
- taskA[a=b]
- taskB[c=d]

Should it behave like a command or a dependency tree?

Tag exclusion when running tasks

  • Allow myke tagA/-tagB/task to filter out tasks having tagB
  • Explore possible other syntaxes (related to #43) such as myke task+tagA-tagB or myke task --tagA --tagB --a=b ...

Errors in discovered `myke.yml` are printed without the actual path

I have a myke.yml config which references few others:

discover:
  - ../dir1
  - ../dir2
  - ../dir3

When one of them contains an error I receive the following message when running myke:

⨯ error error=yaml: line 34: could not find expected ':'

Without the actual path to the file causing the trouble, I have no easy way of figuring it out myself.

I would expect an error like:

⨯ error ../dir1/myke.yaml[34]: could not find expected ':'

Discover should include a myke config only once

I have a dir0/myke.yml config which references few others:

discover:
  - ../dir1
  - ../dir2
  - ../dir3

However dir1 also discovers dir2:

discover:
  - ../dir2

In such scenario, I will see duplicated dir2 entries when I run myke in dir0.

I would expect that discovery skips configs which have been already discovered...

Integrate with Travis

Integrate tests, building binaries and GitHub release (upon tags) and build status images with Travis

Add code coverage

Integrate code coverage with CI to make contributions easy after 1.0.0

Clarify includes vs extends

  • includes: is used to "discover"
  • extends is used to inherit tasks into current namespace
  • Maybe better nomenclature is required to clarify this, because the README says parent environment variable cascading, etc

Re-run failed commands

  • Add ability in YML to re-run failed commands
  • Its a really cumbersome and platform-specific problem for devs

Support templating in environment variables

Support environment variable expansion using templates /cc @vpillac

Few problems:

  • Environment variables are used for parameter substitution, but if they themselves have parameters, then 2-pass/n-pass
  • Ordering of the passes, with/without nested references
  • Potential recursion

Bring --loglevel back

Or something that allows to tell myke to be quiet.

Example : Calling a util task to get ip from kubeconfig.

tasks:
  my_task:
    cmd: |-
      netIp=`$myke --loglevel fatal _get_ip`
  _get_ip:
    cmd: |-
      echo `cat $KUBECONFIG | grep server | cut -d: -f2 | xargs`

Could also be :

myke --quiet _get_ip

env vars not available in windows

tested myke on windows 10 pro with cygwin, PowerShell and CMD - no env vars availabe.

  • myke.env present
  • myke.env.local present
  • env section ind myke.yml present

but none of the env vars is available.

Env vars in Windows 10 Pro are only availbe within the ubuntu linux bash layer ...

myke.yml

---
project: booking-system
env_files:
  - default-values.env
env:
  ABC: default
  PATH: path_from_yml
tasks:
  echo:
    cmd: "echo 123 $ABC def"
  test:
    cmd: env
    before: $myke echo

myke.env

ABC=abc

myke.env.local

ABC=def

output

$ myke test
booking-system/test: Running
+ echo

+ env
PWD=/cygdrive/c/Users/goeuro/projects/goeuro/booking-system/myke
HOME=/cygdrive/c/Users/goeuro
TERM=cygwin
SHLVL=1
_=/usr/bin/env
SYSTEMROOT=C:\WINDOWS
WINDIR=C:\WINDOWS
booking-system/test: Completed, Took: 80.0767ms

Decide whether to support cmd.exe or not

cmd.exe support was recently contributed, thanks to @blaubaer. But we are discovering that there is more specifics involved:

  • Subshells ($(command ...))
  • Variable substitution ($VAR, ${VAR}, ${VAR:-default}, etc)
  • Environment variable cascading to further subcommands
  • Exit codes
  • Piping (foo | grep), Tests (&&, ||), I/O Redirection (>, >>)
  • Any other sh "standard" expectations that we miss?
  • cmd.exe vs powershell

Keeping this issue open and 1.0.0 release on hold until this is decided.

regression from 0.9.0 to 0.9.1 (and higher) in handling shell commands

Running myke test on a yaml file with this content

project: test
tasks:
  test:
    cmd: |-
      echo SOMETHING=$(echo test)

provides this result with myke 0.9.0:

++ echo test
+ echo SOMETHING=test
SOMETHING=test
• mobileweb/test: Completed, Took: 11.366067ms

With myke 0.9.1 and higher the output is however an error:

sh: -c: line 0: syntax error near unexpected token `('
⨯ mobileweb/test: Failed, Took: 8.97756ms
⨯ error                     error=error running command: exit status 2

Expected behaviour: Same behaviour as with myke 0.9.0

Blackbox CLI Tests

Right now there are unit tests, but no blackbox CLI tests. Ideally, since we have the self-documenting examples folder, we could have a blackbox CLI test suite that just runs commands and validates the raw STDOUT output. This would cover the CLI contract as well.

TDD driven learning is a good starting point to a new language, so this could be a good starter issue for learning Golang as well.

Multi shell support for task execution

Right now, we invoke all tasks with /bin/sh. This thread is to discuss if and how to support multiple shells (example, cmd.exe, powershell, bash, zsh, etc). Options to be considered:

  • YML syntax
  • Multi-shell and/or multi-platform. e.g. Windows can use both /bin/sh or cmd.exe, Linux could use /bin/sh or /bin/bash, etc. So shells and platforms are not 1:1 but rather cross functional
  • myke specific feature compatibility: environment variable cascading, retry and exit codes, verbosity levels and stdout/stderr handling, etc

Refers #85

Clarify Environment Variables

  • Make sure README reflects correct environment variables (MYKE_HOME, MYKE_PROJECT, MYKE_TASK, etc)
  • Make sure CWD is correctly set

Verbose task list with descriptions

Now, the task list is a table. Allow a verbose task list option, which will print tasks with full details including the description.

TODO: Decide on command and output semantics

myke -v | myke -l
foo [project=a, tags=tagA,tagB]
  does something
bar [project=b, tags=tagA,tagB]
  does something else
...

Any other better command line UX we can borrow from?

Improve sub-command args syntax

# Before
myke --loglevel=info ... task1[a=1] task2[b=2]

# After
myke --myke-args task1 --task1-args task2 --task2-args

# User-defined task example
myke -v -f *.yml doSomething --from=a doSomethingElse --to=b

# Built-in tasks example
## either special actions that start with /
myke /template --file xyz.tpl
myke /licenses

## or flags
myke --template xyz.tpl
myke --licenses

handlebars or text/template?

  • Should we use a language-neutral template engine (handlebars or dtl)?
  • Or stick with go built-in text/template?

warn about missing mixins

When a mixin path cannot get resolved, myke is silently ignoring the whole myke.yml file where this mixin is referenced, (even other tasks declared in this myke.yml) without warning.

Proposal is to warn when a whole myke.yml gets ignored because of a missing mixin.

Blog post

Obligatory introduction blog post

Finalize templating

Finalize built-in filters for Pongo2

Right now we have only one filter (required), finalize if that's enough or document where necessary

Golang Port Status

Tracking status of Golang port

  • Dev bootstrap (docker, docker-compose, golang, cli framework, CI, cross compilation)
  • Load project/task/workspace/query with old behavior (env/param handling, extends/includes, etc)
  • List tasks, Note: Improvements welcome, not using full term width
  • Execute tasks
  • Templating, 90% done, Note: Slightly breaks compatibility, using pongo2, STDOUT heredoc handling to be fixed
  • Release binaries upon tags/releases (after open sourcing with travis-ci)

Dry run mode

Support dry-run mode that prints all tasks but doesn't actually run them

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.