[meta] clean up ansible files
change
commit c4d5b5202bfddfaa3cc568e1fe439cee29634a09
author Alpha Chen <alpha.chen@gmail.com>
date
parent a0a650ce
diff --git a/.github/ISSUE_TEMPLATE/setup.md b/.github/ISSUE_TEMPLATE/setup.md
index 59b757d5..83664b11 100644
--- a/.github/ISSUE_TEMPLATE/setup.md
+++ b/.github/ISSUE_TEMPLATE/setup.md
@@ -30,11 +30,15 @@
   ansible-playbook main.yml --ask-pass --ask-become-pass
   ```
 
-- [ ] Set Keyboard preferences
-  - [ ] Modifiers
-  - [ ] Function keys
+- [ ] macOS preferences
+  - [ ] Displays
+    - [ ] Enable Night Shift
+  - [ ] Keyboard
+    - [ ] Modifiers
+    - [ ] Function keys
 
 - [ ] Setup programs
   - [ ] 1Password
   - [ ] Firefox
+  - [ ] Fantastical
   - [ ] Arq
diff --git a/README.md b/README.md
index 2dada3d7..6135ba6d 100644
--- a/README.md
+++ b/README.md
@@ -16,19 +16,11 @@ provision new machines.
 
 # Usage
 
-First, some steps need to be performed on the remote machine that I couldn't
-figure out how to automate:
+Use a [tracking issue][tracking-issue] as a checklist for local provisioning.
 
-- [ ] Enable Remote Login in System Preferences -> Sharing.
-- [ ] Install [Xcode][xcode]: `open 'https://itunes.apple.com/us/app/xcode/id497799835?mt=12'`
-- [ ] Accept the Xcode license: `sudo xcodebuild -license`
-- [ ] Open Xcode
-- [ ] Install the command line developer tools: `xcode-select --install`. (It looks like the
-  Homebrew installer [_should_][xcode-select-cli] be able to handle this, but I haven't been able to
-  get it to work headless.)
+[tracking-issue]: https://github.com/kejadlen/dotfiles/issues/new?template=setup.md
 
-[xcode]: https://itunes.apple.com/us/app/xcode/id497799835?mt=12
-[xcode-select-cli]: https://github.com/Homebrew/install/blob/master/install#L207-L216
+## Remote provisioning
 
 On the control machine:
 
@@ -50,34 +42,6 @@ manually run post-provisioning:
 # Symlink ~/.dotfiles to Dropbox
 rm -rf ~/.dotfiles
 ln -s ~/Dropbox/dotfiles ~/.dotfiles
-
-# Add private SSH keys
-ruby ~/.dotfiles/scripts/setup_ssh_keys.rb
-
-# Install apps from the Mac App Store
-open 'https://itunes.apple.com/us/app/reeder-3/id880001334?ls=1&mt=12'
-open 'https://itunes.apple.com/us/app/paprika-recipe-manager/id451907568?mt=12'
-```
-
-## Provisioning Locally
-
-You can also use this to provision a machine by itself, although this won't
-be able to copy over OS X application settings, for obvious reasons.
-
-``` shell
-# Install Homebrew
-ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
-
-# Install ansible
-brew install ansible
-
-# Clone dotfiles
-git clone --recursive https://github.com/kejadlen/dotfiles.git ~/.dotfiles
-
-# Run Ansible
-cd ~/.dotfiles/ansible
-echo "localhost ansible_connection=local" > hosts.private
-ansible-playbook main.yml --ask-pass --ask-become-pass
 ```
 
 # Development
diff --git a/ansible/macbook_pro.yml b/ansible/macbook_pro.yml
deleted file mode 100644
index bfd8be1c..00000000
--- a/ansible/macbook_pro.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-- hosts: all
-  tasks:
-    - name: register keyboard_id
-      shell: ioreg -n IOHIDKeyboard -r | grep -e VendorID\" -e ProductID | ruby -e 'print ARGF.read.scan(/\d+/).join(?-)'
-      register: keyboard_id
-
-    - name: s/caps lock/ctrl/
-      command: defaults -currentHost write -g com.apple.keyboard.modifiermapping.{{ keyboard_id.stdout }}-0 -array-add '<dict><key>HIDKeyboardModifierMappingDst</key><integer>2</integer><key>HIDKeyboardModifierMappingSrc</key><integer>0</integer></dict>'
-
-    - name: install logitech options
-      homebrew_cask: name=logitech-options state=installed
diff --git a/ansible/main.yml b/ansible/main.yml
index 24ef6d33..280fc6da 100644
--- a/ansible/main.yml
+++ b/ansible/main.yml
@@ -1,4 +1,3 @@
----
 - hosts: all
   tasks:
     - group_by: key=os_{{ ansible_distribution }}
diff --git a/ansible/playbooks/homebrew.yml b/ansible/playbooks/homebrew.yml
index 3e6d25d0..f79b59ff 100644
--- a/ansible/playbooks/homebrew.yml
+++ b/ansible/playbooks/homebrew.yml
@@ -14,7 +14,7 @@
       - homebrew/cask-versions
       - homebrew/core
       - homebrew/services
-      - kejadlen/personal
+      - kejadlen/tap
       - seattle-beach/tap
 
   - name: install formulae
@@ -87,6 +87,7 @@
     with_items:
     - 1028916583 # iPulse
     - 451907568  # Paprika Recipe Manager
+    - 497799835  # Xcode
     - 880001334  # Reeder
     - 904280696  # Things3
     - 585829637  # Todoist
diff --git a/ansible/playbooks/rust.yml b/ansible/playbooks/rust.yml
new file mode 100644
index 00000000..fcc5ad27
--- /dev/null
+++ b/ansible/playbooks/rust.yml
@@ -0,0 +1,5 @@
+# - hosts: os_MacOSX
+- hosts: all
+  tasks:
+  - name: install rustup
+    shell: curl https://sh.rustup.rs -sSf | sh -s -- -y --no-modify-path --default-toolchain nightly
diff --git a/ansible/roles/osx/library/my_defaults.py b/ansible/roles/osx/library/my_defaults.py
deleted file mode 100644
index 9ff179c7..00000000
--- a/ansible/roles/osx/library/my_defaults.py
+++ /dev/null
@@ -1,354 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# (c) 2014, GeekChimp - Franck Nijhof <franck@geekchimp.com>
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
-
-DOCUMENTATION = '''
----
-module: osx_defaults
-author: Franck Nijhof (@frenck)
-short_description: osx_defaults allows users to read, write, and delete Mac OS X user defaults from Ansible
-description:
-  - osx_defaults allows users to read, write, and delete Mac OS X user defaults from Ansible scripts.
-    Mac OS X applications and other programs use the defaults system to record user preferences and other
-    information that must be maintained when the applications aren't running (such as default font for new
-    documents, or the position of an Info panel).
-version_added: "2.0"
-options:
-  domain:
-    description:
-      - The domain is a domain name of the form com.companyname.appname.
-    required: false
-    default: NSGlobalDomain
-  key:
-    description:
-      - The key of the user preference
-    required: true
-  type:
-    description:
-      - The type of value to write.
-    required: false
-    default: string
-    choices: [ "array", "bool", "boolean", "date", "float", "int", "integer", "string" ]
-  array_add:
-    description:
-      - Add new elements to the array for a key which has an array as its value.
-    required: false
-    default: false
-    choices: [ "true", "false" ]
-  value:
-    description:
-      - The value to write. Only required when state = present.
-    required: false
-    default: null
-  state:
-    description:
-      - The state of the user defaults
-    required: false
-    default: present
-    choices: [ "present", "absent" ]
-notes:
-    - Apple Mac caches defaults. You may need to logout and login to apply the changes.
-'''
-
-EXAMPLES = '''
-- osx_defaults: domain=com.apple.Safari key=IncludeInternalDebugMenu type=bool value=true state=present
-- osx_defaults: domain=NSGlobalDomain key=AppleMeasurementUnits type=string value=Centimeters state=present
-- osx_defaults: key=AppleMeasurementUnits type=string value=Centimeters
-- osx_defaults:
-    key: AppleLanguages
-    type: array
-    value: ["en", "nl"]
-- osx_defaults: domain=com.geekchimp.macable key=ExampleKeyToRemove state=absent
-'''
-
-from datetime import datetime
-
-# exceptions --------------------------------------------------------------- {{{
-class OSXDefaultsException(Exception):
-    pass
-# /exceptions -------------------------------------------------------------- }}}
-
-# class MacDefaults -------------------------------------------------------- {{{
-class OSXDefaults(object):
-
-    """ Class to manage Mac OS user defaults """
-
-    # init ---------------------------------------------------------------- {{{
-    """ Initialize this module. Finds 'defaults' executable and preps the parameters """
-    def __init__(self, **kwargs):
-
-        # Initial var for storing current defaults value
-        self.current_value = None
-
-        # Just set all given parameters
-        for key, val in kwargs.iteritems():
-            setattr(self, key, val)
-
-        # Try to find the defaults executable
-        self.executable = self.module.get_bin_path(
-            'defaults',
-            required=False,
-            opt_dirs=self.path.split(':'),
-        )
-
-        if not self.executable:
-            raise OSXDefaultsException("Unable to locate defaults executable.")
-
-        # When state is present, we require a parameter
-        if self.state == "present" and self.value is None:
-            raise OSXDefaultsException("Missing value parameter")
-
-        # Ensure the value is the correct type
-        self.value = self._convert_type(self.type, self.value)
-
-    # /init --------------------------------------------------------------- }}}
-
-    # tools --------------------------------------------------------------- {{{
-    """ Converts value to given type """
-    def _convert_type(self, type, value):
-
-        if type == "string":
-            return str(value)
-        elif type in ["bool", "boolean"]:
-            if isinstance(value, basestring):
-                value = value.lower()
-            if value in [True, 1, "true", "1", "yes"]:
-                return True
-            elif value in [False, 0, "false", "0", "no"]:
-                return False
-            raise OSXDefaultsException("Invalid boolean value: {0}".format(repr(value)))
-        elif type == "date":
-            try:
-                return datetime.strptime(value.split("+")[0].strip(), "%Y-%m-%d %H:%M:%S")
-            except ValueError:
-                raise OSXDefaultsException(
-                    "Invalid date value: {0}. Required format yyy-mm-dd hh:mm:ss.".format(repr(value))
-                )
-        elif type in ["int", "integer"]:
-            if not str(value).isdigit():
-                raise OSXDefaultsException("Invalid integer value: {0}".format(repr(value)))
-            return int(value)
-        elif type == "float":
-            try:
-                value = float(value)
-            except ValueError:
-                raise OSXDefaultsException("Invalid float value: {0}".format(repr(value)))
-            return value
-        elif type == "array":
-            if not isinstance(value, list):
-                raise OSXDefaultsException("Invalid value. Expected value to be an array")
-            return value
-
-        raise OSXDefaultsException('Type is not supported: {0}'.format(type))
-
-    """ Converts array output from defaults to an list """
-    @staticmethod
-    def _convert_defaults_str_to_list(value):
-
-        # Split output of defaults. Every line contains a value
-        value = value.splitlines()
-
-        # Remove first and last item, those are not actual values
-        value.pop(0)
-        value.pop(-1)
-
-        # Remove extra spaces and comma (,) at the end of values
-        value = [re.sub(',$', '', x.strip(' ')) for x in value]
-
-        return value
-    # /tools -------------------------------------------------------------- }}}
-
-    # commands ------------------------------------------------------------ {{{
-    """ Reads value of this domain & key from defaults """
-    def read(self):
-        # First try to find out the type
-        rc, out, err = self.module.run_command([self.executable, "read-type", self.domain, self.key])
-
-        # If RC is 1, the key does not exists
-        if rc == 1:
-            return None
-
-        # If the RC is not 0, then terrible happened! Ooooh nooo!
-        if rc != 0:
-            raise OSXDefaultsException("An error occurred while reading key type from defaults: " + out)
-
-        # Ok, lets parse the type from output
-        type = out.strip().replace('Type is ', '')
-
-        # Now get the current value
-        rc, out, err = self.module.run_command([self.executable, "read", self.domain, self.key])
-
-        # Strip output
-        out = out.strip()
-
-        # An non zero RC at this point is kinda strange...
-        if rc != 0:
-            raise OSXDefaultsException("An error occurred while reading key value from defaults: " + out)
-
-        # Convert string to list when type is array
-        if type == "array":
-            out = self._convert_defaults_str_to_list(out)
-
-        # Store the current_value
-        self.current_value = self._convert_type(type, out)
-
-    """ Writes value to this domain & key to defaults """
-    def write(self):
-
-        # We need to convert some values so the defaults commandline understands it
-        if type(self.value) is bool:
-            if self.value:
-                value = "TRUE"
-            else:
-                value = "FALSE"
-        elif type(self.value) is int or type(self.value) is float:
-            value = str(self.value)
-        elif self.array_add and self.current_value is not None:
-            value = list(set(self.value) - set(self.current_value))
-        # elif isinstance(self.value, datetime):
-        #     value = self.value.strftime('%Y-%m-%d %H:%M:%S')
-        else:
-            value = self.value
-
-        # When the type is array and array_add is enabled, morph the type :)
-        if self.type == "array" and self.array_add:
-            self.type = "array-add"
-
-        # All values should be a list, for easy passing it to the command
-        if not isinstance(value, list):
-            value = [value]
-
-        rc, out, err = self.module.run_command([self.executable, 'write', self.domain, self.key, '-' + self.type] + value)
-
-        if rc != 0:
-            raise OSXDefaultsException('An error occurred while writing value to defaults: ' + out)
-
-    """ Deletes defaults key from domain """
-    def delete(self):
-        rc, out, err = self.module.run_command([self.executable, 'delete', self.domain, self.key])
-        if rc != 0:
-            raise OSXDefaultsException("An error occurred while deleting key from defaults: " + out)
-
-    # /commands ----------------------------------------------------------- }}}
-
-    # run ----------------------------------------------------------------- {{{
-    """ Does the magic! :) """
-    def run(self):
-
-        # Get the current value from defaults
-        self.read()
-
-        # Handle absent state
-        if self.state == "absent":
-            print "Absent state detected!"
-            if self.current_value is None:
-                return False
-            self.delete()
-            return True
-
-        # There is a type mismatch! Given type does not match the type in defaults
-        if self.current_value is not None and type(self.current_value) is not type(self.value):
-            raise OSXDefaultsException("Type mismatch. Type in defaults: " + type(self.current_value).__name__)
-
-        # Current value matches the given value. Nothing need to be done. Arrays need extra care
-        if self.type == "array" and self.current_value is not None and not self.array_add and \
-                set(self.current_value) == set(self.value):
-                return False
-        elif self.type == "array" and self.current_value is not None and self.array_add and \
-                len(list(set(self.value) - set(self.current_value))) == 0:
-                return False
-        elif self.current_value == self.value:
-            return False
-
-        # Change/Create/Set given key/value for domain in defaults
-        self.write()
-        return True
-
-    # /run ---------------------------------------------------------------- }}}
-
-# /class MacDefaults ------------------------------------------------------ }}}
-
-
-# main -------------------------------------------------------------------- {{{
-def main():
-    module = AnsibleModule(
-        argument_spec=dict(
-            domain=dict(
-                default="NSGlobalDomain",
-                required=False,
-            ),
-            key=dict(
-                default=None,
-            ),
-            type=dict(
-                default="string",
-                required=False,
-                choices=[
-                    "array",
-                    "bool",
-                    "boolean",
-                    "date",
-                    "float",
-                    "int",
-                    "integer",
-                    "string",
-                ],
-            ),
-            array_add=dict(
-                default=False,
-                required=False,
-                type='bool',
-            ),
-            value=dict(
-                default=None,
-                required=False,
-            ),
-            state=dict(
-                default="present",
-                required=False,
-                choices=[
-                    "absent", "present"
-                ],
-            ),
-            path=dict(
-                default="/usr/bin:/usr/local/bin",
-                required=False,
-            )
-        ),
-        supports_check_mode=True,
-    )
-
-    domain = module.params['domain']
-    key = module.params['key']
-    type = module.params['type']
-    array_add = module.params['array_add']
-    value = module.params['value']
-    state = module.params['state']
-    path = module.params['path']
-
-    try:
-        defaults = OSXDefaults(module=module, domain=domain, key=key, type=type,
-                               array_add=array_add, value=value, state=state, path=path)
-        changed = defaults.run()
-        module.exit_json(changed=changed)
-    except OSXDefaultsException, e:
-        module.fail_json(msg=e.message)
-
-# /main ------------------------------------------------------------------- }}}
-
-from ansible.module_utils.basic import *
-main()