Skip to content

Commit

Permalink
Added support for VS Code Insiders builds (#151)
Browse files Browse the repository at this point in the history
For those who want to help test the latest features.
  • Loading branch information
freemanjp authored Jun 15, 2019
1 parent ebe78fd commit 918c8fc
Show file tree
Hide file tree
Showing 22 changed files with 205 additions and 22 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ are shown below):
# Visual Studio Code version number (defaults to the latest version)
visual_studio_code_version: ''

# Build (either 'stable' or 'insiders') https://code.visualstudio.com/insiders/
# Ubuntu only (code-insiders isn't in Microsoft's RPM repo)
visual_studio_code_build: stable

# Users to install extensions for and/or write settings.json
users: []
```
Expand Down
4 changes: 4 additions & 0 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
# Visual Studio Code version number (defaults to the latest version)
visual_studio_code_version: ''

# Build (either 'stable' or 'insiders') https://code.visualstudio.com/insiders/
# Ubuntu only (code-insiders isn't in Microsoft's RPM repo)
visual_studio_code_build: stable

# Directory to store files downloaded for Visual Studio Code installation
visual_studio_code_download_dir: "{{ x_ansible_download_dir | default(ansible_env.HOME + '/.ansible/tmp/downloads') }}"

Expand Down
31 changes: 20 additions & 11 deletions library/visual_studio_code_install_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
__metaclass__ = type


def is_extension_installed(module, name):
rc, out, err = module.run_command(['code', '--list-extensions', name])
def is_extension_installed(module, executable, name):
rc, out, err = module.run_command([executable, '--list-extensions', name])
if rc != 0 or err:
module.fail_json(
msg='Error querying installed extensions [%s]: %s' % (name,
Expand All @@ -21,35 +21,39 @@ def is_extension_installed(module, name):
return match is not None


def list_extension_dirs(module):
def list_extension_dirs(module, executable):
dirname = '.vscode'
if executable == 'code-insiders':
dirname += '-insiders'

ext_dir = os.path.expanduser(
os.path.join('~', '.vscode', 'extensions'))
os.path.join('~', dirname, 'extensions'))

ext_dirs = [f for f in os.listdir(
ext_dir) if os.path.isdir(os.path.join(ext_dir, f))]
ext_dirs.sort()
return ext_dirs


def install_extension(module, name):
if is_extension_installed(module, name):
def install_extension(module, executable, name):
if is_extension_installed(module, executable, name):
# Use the fact that extension directories names contain the version number
before_ext_dirs = list_extension_dirs(module)
before_ext_dirs = list_extension_dirs(module, executable)
# Unfortunately `--force` suppresses errors (such as extension not found)
rc, out, err = module.run_command(
['code', '--install-extension', name, '--force'])
[executable, '--install-extension', name, '--force'])
# Whitelist: [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues.
if rc != 0 or (err and '[DEP0005]' not in err):
module.fail_json(
msg='Error while upgrading extension [%s]: (%d) %s' % (name,
rc,
out + err))
after_ext_dirs = list_extension_dirs(module)
after_ext_dirs = list_extension_dirs(module, executable)
changed = before_ext_dirs != after_ext_dirs
return changed, 'upgrade'
else:
rc, out, err = module.run_command(
['code', '--install-extension', name])
[executable, '--install-extension', name])
# Whitelist: [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues.
if rc != 0 or (err and '[DEP0005]' not in err):
module.fail_json(
Expand All @@ -63,14 +67,19 @@ def install_extension(module, name):
def run_module():

module_args = dict(
executable=dict(type='str', required=False, choices=['code', 'code-insiders'], default='code'),
name=dict(type='str', required=True))

module = AnsibleModule(argument_spec=module_args,
supports_check_mode=False)

executable = module.params['executable']
if executable != 'code-insiders':
executable = 'code'

name = module.params['name']

changed, change = install_extension(module, name)
changed, change = install_extension(module, executable, name)

if changed:
if change == 'upgrade':
Expand Down
4 changes: 2 additions & 2 deletions molecule/centos/molecule.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ platforms:
provisioner:
name: ansible
playbooks:
converge: ../default/playbook.yml
converge: ../code-only/playbook.yml
lint:
name: ansible-lint

Expand All @@ -25,6 +25,6 @@ scenario:

verifier:
name: testinfra
directory: ../default/tests
directory: ../code-only/tests
lint:
name: flake8
63 changes: 63 additions & 0 deletions molecule/code-only/playbook.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
- name: Converge
hosts: all

pre_tasks:
- name: create test users
become: yes
user:
name: '{{ item }}'
state: present
home: '/home/{{ item }}'
createhome: yes
with_items:
- test_usr
- test_usr2
- test_usr3

- name: install gnupg2 (apt)
become: yes
apt:
name: gnupg2
state: present
when: ansible_pkg_mgr == 'apt'

- name: install extension cli dependencies (zypper)
become: yes
zypper:
name: libX11-xcb1
state: present
when: ansible_pkg_mgr == 'zypper'

- name: install extension cli dependencies (apt)
become: yes
apt:
name: libx11-xcb1
state: present
when: ansible_pkg_mgr == 'apt'

roles:
- role: ansible-role-visual-studio-code
users:
- username: test_usr
visual_studio_code_extensions:
- ms-python.python
- wholroyd.jinja
visual_studio_code_settings: {
"editor.rulers": [80, 100, 120],
"editor.renderWhitespace": true,
"files.associations": {
"Vagrantfile": "ruby"
}
}
- username: test_usr2
visual_studio_code_extensions: []
visual_studio_code_settings: {}
- username: test_usr3

post_tasks:
- name: install which
package:
name: which
state: present
when: ansible_pkg_mgr in ('yum', 'dnf', 'zypper')
10 changes: 10 additions & 0 deletions molecule/code-only/tests/test_install.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import os

import testinfra.utils.ansible_runner

testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all')


def test_visual_studio_code(host):
assert host.run('which code').rc == 0
17 changes: 17 additions & 0 deletions molecule/code-only/tests/test_install_extensions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import os
import pytest

import testinfra.utils.ansible_runner

testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all')


@pytest.mark.parametrize('extension', [
'ms-python.python',
'wholroyd.jinja'
])
def test_visual_studio_code(host, extension):
output = host.check_output('sudo --user test_usr -H code %s %s',
'--install-extension', extension)
assert 'already installed' in output
17 changes: 17 additions & 0 deletions molecule/code-only/tests/test_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import os

import testinfra.utils.ansible_runner

testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all')


def test_settings(host):
settings_file = host.file('/home/test_usr/.config/Code/User/settings.json')

assert settings_file.exists
assert settings_file.is_file
assert settings_file.user == 'test_usr'
assert settings_file.group == 'test_usr'
assert settings_file.mode == 0o600
assert settings_file.contains('"Vagrantfile": "ruby"')
18 changes: 18 additions & 0 deletions molecule/default/playbook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,24 @@
visual_studio_code_extensions: []
visual_studio_code_settings: {}
- username: test_usr3
- role: ansible-role-visual-studio-code
visual_studio_code_build: 'insiders'
users:
- username: test_usr
visual_studio_code_extensions:
- ms-python.python
- wholroyd.jinja
visual_studio_code_settings: {
"editor.rulers": [80, 100, 120],
"editor.renderWhitespace": true,
"files.associations": {
"Vagrantfile": "ruby"
}
}
- username: test_usr2
visual_studio_code_extensions: []
visual_studio_code_settings: {}
- username: test_usr3

post_tasks:
- name: install which
Expand Down
4 changes: 4 additions & 0 deletions molecule/default/tests/test_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@

def test_visual_studio_code(host):
assert host.run('which code').rc == 0


def test_visual_studio_code_insiders(host):
assert host.run('which code-insiders').rc == 0
10 changes: 10 additions & 0 deletions molecule/default/tests/test_install_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,13 @@ def test_visual_studio_code(host, extension):
output = host.check_output('sudo --user test_usr -H code %s %s',
'--install-extension', extension)
assert 'already installed' in output


@pytest.mark.parametrize('extension', [
'ms-python.python',
'wholroyd.jinja'
])
def test_visual_studio_code_insiders(host, extension):
output = host.check_output('sudo --user test_usr -H code-insiders %s %s',
'--install-extension', extension)
assert 'already installed' in output
12 changes: 12 additions & 0 deletions molecule/default/tests/test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,15 @@ def test_settings(host):
assert settings_file.group == 'test_usr'
assert settings_file.mode == 0o600
assert settings_file.contains('"Vagrantfile": "ruby"')


def test_settings_insiders(host):
settings_file = host.file(
'/home/test_usr/.config/Code-Insiders/User/settings.json')

assert settings_file.exists
assert settings_file.is_file
assert settings_file.user == 'test_usr'
assert settings_file.group == 'test_usr'
assert settings_file.mode == 0o600
assert settings_file.contains('"Vagrantfile": "ruby"')
4 changes: 2 additions & 2 deletions molecule/fedora/molecule.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ platforms:
provisioner:
name: ansible
playbooks:
converge: ../default/playbook.yml
converge: ../code-only/playbook.yml
lint:
name: ansible-lint

Expand All @@ -25,6 +25,6 @@ scenario:

verifier:
name: testinfra
directory: ../default/tests
directory: ../code-only/tests
lint:
name: flake8
2 changes: 1 addition & 1 deletion molecule/opensuse/molecule.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ platforms:
provisioner:
name: ansible
playbooks:
converge: ../default/playbook.yml
converge: ../code-only/playbook.yml
lint:
name: ansible-lint

Expand Down
2 changes: 1 addition & 1 deletion tasks/install-apt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@
- name: install VS Code (apt)
become: yes
apt:
name: "code{{ (visual_studio_code_version | length > 0) | ternary('=' + visual_studio_code_version, '') }}"
name: "{{ visual_studio_code_package }}{{ (visual_studio_code_version | length > 0) | ternary('=' + visual_studio_code_version, '') }}"
state: present
2 changes: 1 addition & 1 deletion tasks/install-dnf.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@
- name: install VS Code (dnf)
become: yes
dnf:
name: "code{{ (visual_studio_code_version | length > 0) | ternary('-' + visual_studio_code_version, '') }}"
name: "{{ visual_studio_code_package }}{{ (visual_studio_code_version | length > 0) | ternary('-' + visual_studio_code_version, '') }}"
state: present
1 change: 1 addition & 0 deletions tasks/install-extensions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
become: yes
become_user: '{{ item.0.username }}'
visual_studio_code_install_extension:
executable: '{{ visual_studio_code_exe }}'
name: '{{ item.1 }}'
with_subelements:
- '{{ users }}'
Expand Down
2 changes: 1 addition & 1 deletion tasks/install-homebrew.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
- name: install VS Code (brew-cask)
homebrew_cask:
name: visual-studio-code
name: visual-studio-{{ visual_studio_code_package }}
state: present
2 changes: 1 addition & 1 deletion tasks/install-yum.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@
- name: install VS Code (yum)
become: yes
yum:
name: "code{{ (visual_studio_code_version | length > 0) | ternary('-' + visual_studio_code_version, '') }}"
name: "{{ visual_studio_code_package }}{{ (visual_studio_code_version | length > 0) | ternary('-' + visual_studio_code_version, '') }}"
state: present
2 changes: 1 addition & 1 deletion tasks/install-zypper.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@
- name: install VS Code (zypper)
become: yes
zypper:
name: "code{{ (visual_studio_code_version | length > 0) | ternary('=' + visual_studio_code_version, '') }}"
name: "{{ visual_studio_code_package }}{{ (visual_studio_code_version | length > 0) | ternary('=' + visual_studio_code_version, '') }}"
state: present
5 changes: 5 additions & 0 deletions tasks/install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,10 @@
that:
- "ansible_pkg_mgr in ('apt', 'yum', 'dnf', 'zypper', 'homebrew')"

- name: assert supported build
assert:
that:
- "visual_studio_code_build in ('stable', 'insiders')"

- name: 'install ({{ ansible_pkg_mgr }})'
include_tasks: 'install-{{ ansible_pkg_mgr }}.yml'
11 changes: 10 additions & 1 deletion vars/main.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
---
# The name of the directory where the config is stored for this build
visual_studio_code_config_dirname: "{{ (visual_studio_code_build == 'insiders') | ternary('Code-Insiders', 'Code') }}"

# Directory under $HOME where where VS Code config is stored
visual_studio_code_config_path: "{{ (ansible_distribution == 'MacOSX') | ternary('Library/Application Support', '.config') }}/Code"
visual_studio_code_config_path: "{{ (ansible_distribution == 'MacOSX') | ternary('Library/Application Support', '.config') }}/{{ visual_studio_code_config_dirname }}"

# The package name to install
visual_studio_code_package: "{{ (visual_studio_code_build == 'insiders') | ternary('code-insiders', 'code') }}"

# The CLI executable
visual_studio_code_exe: "{{ (visual_studio_code_build == 'insiders') | ternary('code-insiders', 'code') }}"

0 comments on commit 918c8fc

Please sign in to comment.