diff --git a/.rspec b/.rspec
new file mode 100644
index 0000000..16f9cdb
--- /dev/null
+++ b/.rspec
@@ -0,0 +1,2 @@
+--color
+--format documentation
diff --git a/.travis.yml b/.travis.yml
index 6b10af5..f398abf 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,12 +5,30 @@ python: "2.7"
before_install:
- sudo apt-get update -qq
- sudo apt-get remove --purge zsh
+ - sudo apt-get install ruby rubygems
+ - sudo useradd mtester -m -d /home/mtester -s /bin/bash
+ - sudo chgrp ```id -gn``` /home/mtester
+ - sudo chmod g+s /home/mtester
+ - sudo rm -rf /home/mtester/.zfunctions
+ - sudo rm -f /home/mtester/.zshrc
+ - umask 002
+ - gem install serverspec
install:
- pip install ansible
- "{ echo '[defaults]'; echo 'roles_path = ../'; } >> ansible.cfg"
script:
- - ansible-playbook -i ./tests/inventory ./tests/test_install.yml --syntax-check
- - ansible-playbook -i ./tests/inventory ./tests/test_zshrc.yml --connection=local --sudo
- - ansible-playbook -i ./tests/inventory ./tests/test_prompt.yml --connection=local --sudo
+ # Check machine pre-test state.
+ - rspec tests/spec/before_test_spec.rb
+
+ # Check syntax
+ - ansible-playbook -i tests/inventory ./tests/playbooks/install.yml --syntax-check --list-tasks
+
+ # Check install
+ - ansible-playbook -i ./tests/inventory tests/playbooks/install.yml --connection=local --sudo
+ - rspec tests/spec/install_spec.rb
+
+ # Check configuration
+ - ansible-playbook -i ./tests/inventory tests/playbooks/configure.yml --connection=local --sudo
+ - rspec tests/spec/configure_spec.rb
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..0a61937
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,3 @@
+source 'https://rubygems.org'
+
+gem 'serverspec'
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 0000000..2492f94
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,41 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ diff-lcs (1.2.5)
+ multi_json (1.11.1)
+ net-scp (1.2.1)
+ net-ssh (>= 2.6.5)
+ net-ssh (2.9.2)
+ rspec (3.3.0)
+ rspec-core (~> 3.3.0)
+ rspec-expectations (~> 3.3.0)
+ rspec-mocks (~> 3.3.0)
+ rspec-core (3.3.1)
+ rspec-support (~> 3.3.0)
+ rspec-expectations (3.3.0)
+ diff-lcs (>= 1.2.0, < 2.0)
+ rspec-support (~> 3.3.0)
+ rspec-its (1.2.0)
+ rspec-core (>= 3.0.0)
+ rspec-expectations (>= 3.0.0)
+ rspec-mocks (3.3.1)
+ diff-lcs (>= 1.2.0, < 2.0)
+ rspec-support (~> 3.3.0)
+ rspec-support (3.3.0)
+ serverspec (2.19.0)
+ multi_json
+ rspec (~> 3.0)
+ rspec-its
+ specinfra (~> 2.35)
+ specinfra (2.36.6)
+ net-scp
+ net-ssh
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ serverspec
+
+BUNDLED WITH
+ 1.10.5
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..686981e
--- /dev/null
+++ b/README.md
@@ -0,0 +1,81 @@
+# Ansible Role: ZSH
+
+[![Build Status](https://travis-ci.org/loliee/ansible-zsh.svg?branch=master)](https://travis-ci.org/loliee/ansible-zsh)
+
+Install and set up [ZSH](http://www.zsh.org/).
+This role can also configure `~./zshrc` file and download and set up `prompt`.
+
+## Requirements
+
+- RedHat family
+- Debian family
+- OSX (Configuration part)
+
+## Role Variables
+
+### `__users__`
+
+Unset by default, dictionary should defined like this:
+
+```yaml
+__users__:
+ [username]:
+ [option]: [value]
+```
+**Options**
+
+| Option | Type | Comments |
+|---------------------------|----------|---------------------------------------------------------------|
+| zsh_default_shell | bool | Configure as default shell. Create `.zshrc`and `.zfunctions`. |
+| zsh_prompt_install | bool | Install prompt ?, default value is `No` |
+| zsh_prompt_name | string | Prompt name to load in `.zshrc`. |
+| zsh_prompt_download_url | string | Prompt download url, e.g [pure](https://github.com/sindresorhus/pure) |
+| zsh_prompt_additional_url | string | Prompt additional download url to put in `.zfunctions`. |
+| zsh_zfunctions_directory | string | Directory of files to upload on remote `.zfunctions`. |
+| zsh_zshrc_content | text | Lines to append in `~/.zshrc`. |
+
+
+### Defaults
+
+Check [defaults/main.yml](defaults/main.yml) for default values.
+
+
+| Variable | Type | Comments |
+|-----------------------------------|----------|-----------------------------------------------------|
+| zsh_default_prompt_name | string | Default prompt_name, `mlpure`. |
+| zsh_default_prompt_download_url | string | Prompt download url, [mlpure](https://github.com/loliee/mlpure) |
+| zsh_default_prompt_additional_url | text | `mlpure` async lib. |Ó
+
+
+## Example Playbook
+
+The following playbook will ensure zsh is present for root user and will setup pure as prompt. This playbook will also append an alias in zshrc file.
+
+```yaml
+# ./test/playbooks/configuration.yml
+- hosts: localhost
+ remote_user: root
+ vars:
+ __users__:
+ root:
+ zsh_prompt_install: Yes
+ zsh_prompt_name: pure
+ zsh_prompt_download_url: https://raw.githubusercontent.com/sindresorhus/pure/master/pure.zsh
+ zsh_prompt_additional_url: https://raw.githubusercontent.com/sindresorhus/pure/master/async.zsh
+ zfunctions_directory: ./files/zfunctions
+ zshrc_content: |
+ alias ls='ls -lah'
+
+ # Run
+ roles:
+ - zsh
+```
+
+## Run Tests
+
+Require [serverspec](http://serverspec.org/).
+Check [.travis.yml](.travis.yml) for details.
+
+## Licence
+
+MIT © [Maxime Loliée](https://github.com/loliee.com/)
diff --git a/README.rst b/README.rst
deleted file mode 100644
index 80a63d8..0000000
--- a/README.rst
+++ /dev/null
@@ -1,86 +0,0 @@
-Ansible Role: ZSH
-#################
-
-.. image:: https://travis-ci.org/loliee/ansible-zsh.svg?branch=master
- :target: https://travis-ci.org/loliee/ansible-zsh
-
-
-Install and set up `ZSH `_.
-This role can also configure `~./zshrc` file and configure nice prompt (check `mlpure `_ for a nice, fast and customizable one !)
-
-Requirements
-============
-
-- RedHat family
-- Debian family
-
-Role Variables
-==============
-
-`zsh_users_config`
-------------------
-
-Unset by default, dictionary should defined like this:
-
-.. code:: yaml
-
- zsh_users_config:
- [username]:
- [option]: [value]
-
-**Options**
-
-+---------------------+----------+-----------------------------------------------+
-| parameter | type | comments |
-+=====================+==========+===============================================+
-| default_shell | bool | Configure as default shell |
-+---------------------+----------+-----------------------------------------------+
-| prompt_install | bool | Install prompt in ~/zfunctions/ ? |
-+---------------------+----------+-----------------------------------------------+
-| prompt_name | string | Prompt name |
-+---------------------+----------+-----------------------------------------------+
-| prompt_download_url | string | Prompt download url |
-+---------------------+----------+-----------------------------------------------+
-| file_zshrc | text | Lines to append in ~/.zshrc |
-+---------------------+----------+-----------------------------------------------+
-
-
-Example Playbook
-================
-
-The following playbook will ensure zsh is present for root user and will setup pure as prompt. This playbook will also append an alias in zshrc file.
-
-
-.. code:: yaml
-
- # ./test/test_prompt.yml
-
- - hosts: localhost
- remote_user: root
- vars:
- zsh_users_config:
- root:
- prompt_install: Yes
- prompt_name: pure
- prompt_download_url: >
- https://raw.githubusercontent.com/sindresorhus/pure/master/pure.zsh
- file_zshrc: |
- alias ls='ls -lah'
-
- # Run
- roles:
- - zsh
-
-Run test, make sure ansible-zsh role is in your role path
-
-.. code:: bash
-
- sudo ansible-playbook -i ./tests/inventory ./tests/test_prompt.yml --connection=local
-
-
-Check `.travis.yml <.travis.yml>`_ for detail
-
-Licence
-=======
-
-MIT © `Maxime Loliée `_
diff --git a/defaults/main.yml b/defaults/main.yml
new file mode 100644
index 0000000..b3232a9
--- /dev/null
+++ b/defaults/main.yml
@@ -0,0 +1,5 @@
+---
+
+zsh_default_prompt_name: mlpure
+zsh_default_prompt_download_url: https://raw.githubusercontent.com/loliee/mlpure/master/pure.zsh
+zsh_default_prompt_additional_url: https://raw.githubusercontent.com/loliee/mlpure/master/async.zsh
diff --git a/tasks/Config.yml b/tasks/Config.yml
deleted file mode 100644
index 7a03442..0000000
--- a/tasks/Config.yml
+++ /dev/null
@@ -1,53 +0,0 @@
----
-# Setup zshrc and prompt
-
-- name: Set as default shell
- user: name={{ item.key }} shell=/bin/zsh
- with_dict: zsh_users_config | default({})
- when: >
- (ansible_os_family == 'RedHat' or ansible_os_family == 'Debian') and
- (item.value.has_key('default_shell') and item.value.default_shell)
-
-- name: Generate ~.zshrc.
- template:
- mode=0644
- src=zshrc.j2
- owner={{ item.key }}
- dest=~{{ item.key }}/.zshrc
- with_dict: zsh_users_config | default({})
- when: >
- (item.value.has_key('prompt_install') and item.value.prompt_install) or
- (item.value.has_key('file_zshrc') and item.value.file_zshrc)
-
-- name: Check for .zsfunctions directory.
- always_run: Yes
- file:
- state=directory
- mode=0755
- owner={{ item.key }}
- dest=~{{ item.key }}/.zfunctions
- with_dict: zsh_users_config | default({})
- when: >
- item.value.has_key('prompt_install') and item.value.prompt_install
-
-- fail: msg='Check user "{{ item.key }}" config dict ! "prompt_name" and "prompt_download_url" must set up if prompt_install is True.'
- always_run: Yes
- with_dict: zsh_users_config | default({})
- when: >
- item.value.has_key('prompt_install') and item.value.prompt_install and
- (
- (not item.value.has_key('prompt_name') and item.value.has_key('prompt_download_url')) or
- (item.value.has_key('prompt_name') and not item.value.has_key('prompt_download_url'))
- )
-
-- name: Download zsh prompt file.
- get_url:
- mode=0744
- owner={{ item.key }}
- url={{ item.value.prompt_download_url }}
- dest=~{{ item.key }}/.zfunctions/prompt_{{ item.value.prompt_name }}_setup
-
- with_dict: zsh_users_config | default({})
- when: >
- item.value.has_key('prompt_name') and
- item.value.has_key('prompt_download_url')
diff --git a/tasks/configure.yml b/tasks/configure.yml
new file mode 100644
index 0000000..44133ed
--- /dev/null
+++ b/tasks/configure.yml
@@ -0,0 +1,70 @@
+---
+# Setup zshrc and prompt
+
+- name: Set as default shell
+ user: name={{ item.key }} shell=/bin/zsh
+ with_dict: __users__ | default({})
+ when: >
+ (ansible_os_family == 'RedHat' or ansible_os_family == 'Debian') and
+ (item.value.has_key('zsh_default_shell') and item.value.zsh_default_shell)
+
+- name: Generate ~.zshrc.
+ template:
+ mode=0644
+ src=zshrc.j2
+ owner={{ item.key }}
+ dest=~{{ item.key }}/.zshrc
+ with_dict: __users__ | default({})
+ when: (item.value.has_key('zsh_default_shell') and item.value.zsh_default_shell)
+
+- name: Check for .zfunctions directory.
+ file:
+ state=directory
+ mode=0755
+ owner={{ item.key }}
+ dest=~{{ item.key }}/.zfunctions
+ with_dict: __users__ | default({})
+ when: (item.value.has_key('zsh_default_shell') and item.value.zsh_default_shell)
+
+- name: Upload zfunctions files
+ copy:
+ src=./{{ item.value.zsh_zfunctions_directory }}/
+ dest=~{{ item.key }}/.zfunctions/
+ owner={{ item.key }}
+ directory_mode=yes
+ force=yes
+ mode=0755
+ with_dict: __users__ | default({})
+ when: >
+ item.value.has_key('zsh_zfunctions_directory')
+
+- name: Download zsh prompt file.
+ get_url:
+ mode=0744
+ owner={{ item.key }}
+ url={{ item.value.zsh_prompt_download_url | default(zsh_default_prompt_download_url) }}
+ dest=~{{ item.key }}/.zfunctions/prompt_{{ item.value.zsh_prompt_name | default(zsh_default_prompt_name) }}_setup
+ with_dict: __users__ | default({})
+ when: item.value.has_key('zsh_prompt_install') and item.value.zsh_prompt_install
+
+- name: Download zsh prompt additional file.
+ get_url:
+ mode=0744
+ owner={{ item.key }}
+ url={{ item.value.zsh_prompt_additional_url }}
+ dest=~{{ item.key }}/.zfunctions/{{ zsh_prompt_additional_url | basename | replace('.zsh', '') }}
+ with_dict: __users__ | default({})
+ when: >
+ item.value.has_key('zsh_prompt_install') and item.value.zsh_prompt_install and
+ item.value.has_key('zsh_prompt_additional_url') and item.value.zsh_prompt_additional_url
+
+- name: Download zsh additional file if install default prompt.
+ get_url:
+ mode=0744
+ owner={{ item.key }}
+ url={{ zsh_default_prompt_additional_url }}
+ dest=~{{ item.key }}/.zfunctions/{{ zsh_default_prompt_additional_url | basename | replace('.zsh', '') }}
+ with_dict: __users__ | default({})
+ when: >
+ item.value.has_key('zsh_prompt_install') and item.value.zsh_prompt_install and not
+ item.value.has_key('zsh_prompt_name')
diff --git a/tasks/main.yml b/tasks/main.yml
index 3b536b8..a45d710 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -1,10 +1,10 @@
---
# Install and zsh package, set up zshrc.
-- include: RedHat.yml
- when: ansible_os_family == 'RedHat'
- tags:
- - packages
+#- include: RedHat.yml
+# when: ansible_os_family == 'RedHat'
+# tags:
+# - packages
- include: Debian.yml
when: ansible_os_family == 'Debian'
@@ -17,6 +17,6 @@
tags:
- test
-- include: Config.yml
+- include: configure.yml
tags:
- config
diff --git a/templates/zshrc.j2 b/templates/zshrc.j2
index ca32df2..fb370a2 100644
--- a/templates/zshrc.j2
+++ b/templates/zshrc.j2
@@ -1,22 +1,21 @@
-# File managed by ansible, should not be modified.
+# {{ ansible_managed }}
-{% for username, options in zsh_users_config.iteritems() %}
- {% if username == item.key %}
+fpath=("$HOME/.zfunctions" $fpath)
- {%- if options.has_key('prompt_install') and options.prompt_install %}
+{%- for username, options in __users__.iteritems() %}
+ {%- if username == item.key %}
+ {# Install prompt #}
+ {%- if options.has_key('zsh_prompt_install') and options.zsh_prompt_install %}
-fpath=( "$HOME/.zfunctions" $fpath )
autoload -U promptinit && promptinit
-prompt {{ options.prompt_name }}
+prompt {{ options.zsh_prompt_name | default(zsh_default_prompt_name) }}
{%- endif %}
+ {# Add custom lines #}
+ {%- if options.has_key('zsh_zshrc_content') and options.zsh_zshrc_content %}
- {%- if options.has_key('file_zshrc') and options.file_zshrc %}
-
-# Customs
-{{ options.file_zshrc }}
+{{ options.zsh_zshrc_content }}
{%- endif %}
-
{% endif %}
{% endfor %}
diff --git a/tests/files/zfunctions/test.zsh b/tests/files/zfunctions/test.zsh
new file mode 100644
index 0000000..1100654
--- /dev/null
+++ b/tests/files/zfunctions/test.zsh
@@ -0,0 +1 @@
+# Tests functions
diff --git a/tests/playbooks/configure.yml b/tests/playbooks/configure.yml
new file mode 100644
index 0000000..ef841a5
--- /dev/null
+++ b/tests/playbooks/configure.yml
@@ -0,0 +1,17 @@
+---
+# Test playbook: configure zsh.
+
+- hosts: localhost
+ remote_user: root
+ vars:
+ __users__:
+ mtester:
+ zsh_default_shell: Yes
+ zsh_prompt_install: Yes
+ zsh_zshrc_content: |
+ alias ll='ls -la'
+
+
+ # Run
+ roles:
+ - ansible-zsh
diff --git a/tests/playbooks/install.yml b/tests/playbooks/install.yml
new file mode 100644
index 0000000..8e9a9bd
--- /dev/null
+++ b/tests/playbooks/install.yml
@@ -0,0 +1,7 @@
+---
+# Test playbook: package install
+
+- hosts: localhost
+ remote_user: root
+ roles:
+ - ansible-zsh
diff --git a/tests/spec/before_test_spec.rb b/tests/spec/before_test_spec.rb
new file mode 100644
index 0000000..3163f11
--- /dev/null
+++ b/tests/spec/before_test_spec.rb
@@ -0,0 +1,38 @@
+require 'serverspec'
+
+set :backend, :exec
+
+describe package('zsh') do
+ it { should_not be_installed }
+end
+
+describe file('/home/mtester/.zfunctions/') do
+ it { should_not be_directory }
+end
+
+describe file('/home/mtester/.zfunctions/prompt_mlpure_setup') do
+ it { should_not be_file }
+end
+
+describe file('/home/mtester/.zfunctions/async') do
+ it { should_not be_file }
+end
+
+describe file('/home/mtester/.zfunctions/prompt_mlpure_setup') do
+ it { should_not be_file }
+end
+
+describe file('/home/mtester/.zshrc') do
+ its(:content) { should_not contain /# Ansible managed:/ }
+ its(:content) { should_not contain /autoload -U promptinit && promptinit/ }
+ its(:content) { should_not contain /prompt mlpure/ }
+ its(:content) { should_not contain /alias ll='ls -la'/ }
+end
+
+describe user('mtester') do
+ it { should have_home_directory '/home/mtester' }
+end
+
+describe user('mtester') do
+ it { should have_login_shell '/bin/bash' }
+end
diff --git a/tests/spec/configure_spec.rb b/tests/spec/configure_spec.rb
new file mode 100644
index 0000000..cdad975
--- /dev/null
+++ b/tests/spec/configure_spec.rb
@@ -0,0 +1,26 @@
+require 'serverspec'
+
+set :backend, :exec
+
+describe file('/home/mtester/.zfunctions/') do
+ it { should be_directory }
+end
+
+describe file('/home/mtester/.zfunctions/async') do
+ it { should be_file }
+end
+
+describe file('/home/mtester/.zfunctions/prompt_mlpure_setup') do
+ it { should be_file }
+end
+
+describe file('/home/mtester/.zshrc') do
+ its(:content) { should contain /# Ansible managed:/ }
+ its(:content) { should contain /autoload -U promptinit && promptinit/ }
+ its(:content) { should contain /prompt mlpure/ }
+ its(:content) { should contain /alias ll='ls -la'/ }
+end
+
+describe user('mtester') do
+ it { should have_login_shell '/bin/zsh' }
+end
diff --git a/tests/spec/install_spec.rb b/tests/spec/install_spec.rb
new file mode 100644
index 0000000..1fb5438
--- /dev/null
+++ b/tests/spec/install_spec.rb
@@ -0,0 +1,7 @@
+require 'serverspec'
+
+set :backend, :exec
+
+describe package('zsh') do
+ it { should be_installed }
+end
diff --git a/tests/test_install.yml b/tests/test_install.yml
deleted file mode 100644
index 82965d6..0000000
--- a/tests/test_install.yml
+++ /dev/null
@@ -1,20 +0,0 @@
----
-# Test playbook: package install
-
-- hosts: localhost
- remote_user: root
- roles:
- - ansible-zsh
-
- tasks:
- - name: Get zsh version
- command: 'zsh --version'
- ignore_errors: yes
- register: zsh_version
-
- - name: Check zsh version
- fail: msg="zsh install failed"
- when: zsh_version.stdout.find('zsh 5') == -1 and zsh_version.stderr == ''
-
- - name: Display "zsh --version" results
- debug: var=zsh_version.stdout
diff --git a/tests/test_prompt.yml b/tests/test_prompt.yml
deleted file mode 100644
index 30d1ada..0000000
--- a/tests/test_prompt.yml
+++ /dev/null
@@ -1,33 +0,0 @@
----
-# Test playbook: Prompt install
-
-- hosts: localhost
- remote_user: root
- vars:
- zsh_users_config:
- root:
- prompt_install: Yes
- prompt_name: pure
- prompt_download_url: >
- https://raw.githubusercontent.com/sindresorhus/pure/master/pure.zsh
- file_zshrc: |
- alias ls='ls -lah'
- # Run
- roles:
- - ansible-zsh
-
- # Test Result
- tasks:
- - name: Check if zfunctions was successfully created, just ls ...
- shell: ls ~{{ item.key }}/.zfunctions
- with_dict: zsh_users_config
- register: ls_result
- failed_when: ls_result.rc != 0
- always_run: True
-
- - name: Check if zsh_file_zshrc was correctly appended.
- shell: 'grep "prompt {{ item.value.prompt_name }}" ~{{ item.key }}/.zshrc'
- with_dict: zsh_users_config
- register: grep_result
- failed_when: grep_result.rc != 0
- always_run: True
diff --git a/tests/test_zshrc.yml b/tests/test_zshrc.yml
deleted file mode 100644
index 000f369..0000000
--- a/tests/test_zshrc.yml
+++ /dev/null
@@ -1,35 +0,0 @@
----
-# Test playbook: Configuration ~/.zshrc
-
-- hosts: localhost
- remote_user: root
- vars:
- zsh_users_config:
- root:
- file_zshrc: |
- alias ll='ls -lah'
-
- roles:
- - ansible-zsh
-
- tasks:
- - name: Check if zshrc was successfully created, just ls ...
- shell: ls ~{{ item.key }}/.zshrc
- with_dict: zsh_users_config
- register: ls_result
- failed_when: ls_result.rc != 0
- always_run: True
-
- - name: Check if lines was correctly appended in .zshrc.
- shell: grep "alias ll='ls -lah'" ~{{ item.key }}/.zshrc
- with_dict: zsh_users_config
- register: grep_result
- failed_when: grep_result.rc != 0
- always_run: True
-
- - name: Check if no prompt config added in zshrc.
- shell: 'grep "autoload -U promptinit && promptinit" ~{{ item.key }}/.zshrc'
- with_dict: zsh_users_config
- register: grep_result
- failed_when: grep_result.rc == 0
- always_run: True