packages feed

azubi-0.1.0.1: README.md

# Azubi

[![Build Status](https://travis-ci.org/mrVanDalo/azubi.svg?branch=master)](https://travis-ci.org/mrVanDalo/azubi)

Is a very simple DevOps tool, which will never "reach" enterprise level.

## Goals

* Readable -> Haskell
* Check your rule set before changing your system -> Strong Type-system of Haskell
* Adaptive, -> can run on all kinds of Linux and it is also planed to run on osx and Windows
* Lightweight -> No installation (except some basic shell tools) needed on the target host.

## Features

### Different types of Execution

You can 

* enforce everything by command line (not yet)
* create a bash script which you can run for system setup
* use ssh to setup a target host (not yet)
* create different configurations for different situations (not yet)
* export to a Dockerfile (not yet)
* export to a Bat file (not yet)

### How to start

Install `azubi` via cabal.

    cabal install azubi

create a file (e.g. `config.hs`) somewhere you like with the content

    #!/usr/bin/env runghc
    
    import Azubi
    
    main :: IO ()
    main = azubiMain $ azubiConfig Gentoo $ []
        & installed "vim"


call the script to get a help

    ./config.hs --help


call the script to get a bashscript

    ./config.hs --output "my-first-azubi-script.sh"


# Syntax

## Commands

Every Command should be revertable.

### installed

#### Package 

install vim if not already done:

    & installed "vim"

uninstall vim if vim is installed:

    ! installed "vim"

### exists

#### Files

create files, directories and symlinks : 

    & exists (File "~/.vimrc")
    & exists (Directory "~/.vim")
    & exists (Symlink ".bashrc" "~/.bashrc.d/bashrc")
    
delete files files, directories and symlinks : 

    & exists (File "~/.vimrc")
    & exists (Directory "~/.vim")
    & exists (Symlink ".bashrc" "~/.bashrc.d/bashrc")

#### Git projects

pull git repository if not pressent:

    & exists (Git "git@github.com:mrVanDalo/azubi.git" "~/develop/azubi" [Branch "develop"])

you can give it options

* *Branch "branchname"*
* *Recursive*
* more to follow ... 


## Logic Components


### Combiner

#### &, !

Almost every command should be revertable. So you have 2 states

* do it -> `&`
* undo it -> `!`

this ensures the file `/tmp/foo` exist

        & exists (File "/tmp/foo")

and this ensures the file does not exist

        ! exists (File "/tmp/foo")

In most cases it happens what you expect, but sometimes it's not so obvious so we it is written right next to the command.
(e.g.:) `! exists (File "/tmp/foo")` will delete a file `/tmp/foo` but won't delete a directory `/tmp/foo`

#### !?&,!?!, &?&, &?!

They are special cases of `!` and `&` and should be read like `X if in context Y` -> `X?Y` and start only to make 
sense in combination of submodules (see later).

* `&?&` is `&` if you are in a `do it` context.
* `!?&` is `!` if you are in a `do it` context.
* `&?!` is `&` if you are in a `undo it` context.
* `!?!` is `!` if you are in a `undo it` context.

for example 

    & (submodule $ []
      &?& contains (File "/dev/shm/test") ["text"]
      & exists (Symlink  "~/.vimrc" "/dev/shm/test")
    )

would be reverted like this

    ! (submodule $ []
      &?& contains (File "/dev/shm/test") ["text"]
      & exists (Symlink  "~/.vimrc" "/dev/shm/test")
    )

which is similar to 

    ! exists (Symlink  "~/.vimrc" "/dev/shm/test")
    

### `submodule`

to group a bunch of command together to on command you can negate all at once if you want.
But you can create a much more sophisticated combination of commands using
`!?&`,`!?!`,`&?&` and `&?!`.

for example 

    & (submodule $ []
      & contains (File "/dev/shm/test") ["text"]
      & exists (Symlink  "~/.vimrc" "/dev/shm/test")
    )

is equivalent to

    & contains (File "/dev/shm/test") ["text"]
    & exists (Symlink  "~/.vimrc" "/dev/shm/test")

but could be reverted like this

    ! (submodule $ []
      & contains (File "/dev/shm/test") ["text"]
      & exists (Symlink  "~/.vimrc" "/dev/shm/test")
    )

which is equivalent to

    ! contains (File "/dev/shm/test") ["text"]
    ! exists (Symlink  "~/.vimrc" "/dev/shm/test")

### `requires`

is used to create dependencies like "first do *this*, and when everything is fine do *this*".
They make most sense with submodules

    & ((submodule $ []
       & exists (Symlink "~/.vim"   "~/.dot_vim")
       & exists (Symlink "~/.vimrc" "~/.vim/vimrc")
      ) 
      `requires` 
      (submodule $ []
       & exists (Git "git@github.com/myrepo/dot_vim.git" "~/.dot_vim" [Recursive])
      ))
      
If `requires` is called in a reverting context (e.g. using `!`) it will also create a dependency 
but twisted and the body will be reverted as well.

     ! ((submodule $ []
       & exists (Symlink "~/.vim"   "~/.dot_vim")
       & exists (Symlink "~/.vimrc" "~/.vim/vimrc")
      ) 
      `requires` 
      (submodule $ []
       & exists (Git "git@github.com/myrepo/dot_vim.git" "~/.dot_vim" [Recursive])
      ))
    
is equivalent to

     & ((submodule $ []
       ! exists (Git "git@github.com/myrepo/dot_vim.git" "~/.dot_vim" [Recursive])
      )
      `requires` 
      (submodule $ []
       ! exists (Symlink "~/.vim"   "~/.dot_vim")
       ! exists (Symlink "~/.vimrc" "~/.vim/vimrc")
      ))