Skip to content

Commit f20ee14

Browse files
authored
Merge pull request #85 from trinitronx/update-bashrc
Update lyraphase_workstation::bashrc
2 parents c303c51 + f778bb0 commit f20ee14

File tree

9 files changed

+718
-10
lines changed

9 files changed

+718
-10
lines changed

Gemfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ end
3838

3939
group :development do
4040
# gem 'ruby_gntp'
41+
gem 'pry'
42+
gem 'pry-byebug'
4143
gem 'growl'
4244
gem 'rb-fsevent'
4345
gem 'guard', '~> 2.15'

attributes/bashrc.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# -*- coding: utf-8 -*-
2+
# frozen_string_literal: true
3+
4+
default['lyraphase_workstation']['bashrc'] = {}
5+
default['lyraphase_workstation']['bashrc']['user_fullname'] = 'James Cuzella'
6+
default['lyraphase_workstation']['bashrc']['user_email'] = '[email protected]'
7+
default['lyraphase_workstation']['bashrc']['user_gpg_keyid'] = '0x2689A459B1568D09'

recipes/bashrc.rb

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# -*- coding: utf-8 -*-
2+
# frozen_string_literal: true
3+
#
4+
# Cookbook Name:: lyraphase_workstation
5+
# Recipe:: bashrc
6+
# Site:: https://www.gnu.org/software/bash/
7+
#
8+
# Copyright (C) © 🄯 2015-2022 James Cuzella
9+
#
10+
# This program is free software: you can redistribute it and/or modify
11+
# it under the terms of the GNU General Public License as published by
12+
# the Free Software Foundation, either version 3 of the License, or
13+
# (at your option) any later version.
14+
#
15+
# This program is distributed in the hope that it will be useful,
16+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
# GNU General Public License for more details.
19+
#
20+
# You should have received a copy of the GNU General Public License
21+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
22+
23+
24+
bashrc_path = Pathname.new(File.join(node['lyraphase_workstation']['home'], '.bashrc'))
25+
bash_logout_path = Pathname.new(File.join(node['lyraphase_workstation']['home'], '.bash_logout'))
26+
27+
homebrew_github_api_token = data_bag_item('lyraphase_workstation', 'bashrc')['homebrew_github_api_token'] rescue nil
28+
29+
if homebrew_github_api_token.nil? && ! node['lyraphase_workstation']['bashrc']['homebrew_github_api_token'].nil? && ! node['lyraphase_workstation']['bashrc']['homebrew_github_api_token'].nil?
30+
homebrew_github_api_token = node['lyraphase_workstation']['bashrc']['homebrew_github_api_token']
31+
end
32+
33+
34+
template bashrc_path do
35+
source "bashrc.erb"
36+
user node['lyraphase_workstation']['user']
37+
mode "0644"
38+
variables({ user_home: node['lyraphase_workstation']['home'],
39+
user_fullname: node['lyraphase_workstation']['bashrc']['user_fullname'],
40+
user_email: node['lyraphase_workstation']['bashrc']['user_email'],
41+
user_gpg_keyid: node['lyraphase_workstation']['bashrc']['user_gpg_keyid'],
42+
homebrew_github_api_token: homebrew_github_api_token
43+
})
44+
end
45+
46+
template bash_logout_path do
47+
source "bash_logout.erb"
48+
user node['lyraphase_workstation']['user']
49+
mode "0644"
50+
# No vars needed for now
51+
end

spec/spec_helper.rb

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
11
require 'chefspec'
22
require 'chefspec/berkshelf'
3-
4-
## Gets rid of const redefinition warnings
5-
def create_singleton_struct name, fields
6-
if Struct::const_defined? name
7-
Struct.const_get name
8-
else
9-
Struct.new name, *fields
10-
end
11-
end
3+
require 'spec_shared_contexts'
124

135
# Require all our libraries
146
Dir['libraries/*.rb'].each { |f| require File.expand_path(f) }
157

168
RSpec.configure do |config|
179
config.platform = 'mac_os_x'
1810
config.version = '10.14'
11+
12+
config.alias_example_group_to :describe_recipe, type: :recipe
13+
config.alias_example_group_to :describe_helpers, type: :helpers
14+
config.alias_example_group_to :describe_resource, type: :resource
15+
1916
config.before { stub_const('ENV', ENV.to_hash.merge('SUDO_USER' => 'brubble')) }
2017
config.filter_run_when_matching :focus
2118
end

spec/spec_shared_contexts.rb

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
# -*- coding: utf-8 -*-
2+
# frozen_string_literal: true
3+
#
4+
# Cookbook Name:: lyraphase_workstation
5+
# Site:: https://github.com/LyraPhase/lyraphase_workstation/
6+
#
7+
# Copyright (C) © 🄯 2016-2022 James Cuzella
8+
#
9+
# This program is free software: you can redistribute it and/or modify
10+
# it under the terms of the GNU General Public License as published by
11+
# the Free Software Foundation, either version 3 of the License, or
12+
# (at your option) any later version.
13+
#
14+
# This program is distributed in the hope that it will be useful,
15+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
# GNU General Public License for more details.
18+
#
19+
# You should have received a copy of the GNU General Public License
20+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
21+
22+
## Helper Methods
23+
## Gets rid of const redefinition warnings
24+
def create_singleton_struct name, fields
25+
if Struct::const_defined? name
26+
Struct.const_get name
27+
else
28+
Struct.new name, *fields
29+
end
30+
end
31+
32+
def stringify_keys(hash)
33+
hash.each_with_object({}) do |(k, v), base|
34+
v = stringify_keys(v) if v.is_a? Hash
35+
base[k.to_s] = v
36+
base
37+
end
38+
end
39+
40+
# Note: Chef >= 15 no longer runs Ohai :Passwd plugin
41+
# Now you must manually enable this plugin because this cookbook depends on it
42+
# Add to client.rb:
43+
# ohai.optional_plugins = [ :Passwd ]
44+
45+
## RSpec Shared Contexts
46+
# D.R.Y. ChefSpec tests to mock Ohai /etc/passwd data
47+
# Source: https://github.com/sous-chefs/ark/blob/bcdf8108a3754a5c9c1257f9535dd1e6554bc998/spec/spec_helper.rb
48+
# References:
49+
# - https://www.chef.io/blog/watch-writing-elegant-tests
50+
# - https://www.rubydoc.info/github/rspec/rspec-core/RSpec%2FCore%2FConfiguration:alias_example_group_to
51+
# - https://github.com/chefspec/fauxhai#fauxhai-ng
52+
# - https://github.com/chef/chef/issues/8888
53+
# - https://docs.chef.io/ohai/#optional-plugins
54+
# - https://stackoverflow.com/a/57953198/645491
55+
RSpec.shared_context 'recipe tests', type: :recipe do
56+
57+
# Individual spec Example Groups can override this to inject node attributes
58+
let(:chefspec_options) {
59+
{
60+
default_attributes: {},
61+
normal_attributes: {},
62+
automatic_attributes: {}
63+
}
64+
}
65+
66+
let(:chef_run) {
67+
klass = ChefSpec.constants.include?(:SoloRunner) ? ChefSpec::SoloRunner : ChefSpec::Runner
68+
klass.new(chefspec_options) do |node|
69+
node.normal.merge!(node_attributes)
70+
end.converge(described_recipe)
71+
}
72+
73+
let(:node) { chef_run.node }
74+
75+
def lyraphase_workstation_user
76+
create_singleton_struct "EtcPasswd", [ :name, :passwd, :uid, :gid, :gecos, :dir, :shell, :change, :uclass, :expire ]
77+
Struct::EtcPasswd.new('brubble', '********', 501, 20, 'Barney Rubble', '/Users/brubble', '/bin/bash', 0, '', 0)
78+
end
79+
80+
# Global ChefSpec attributes for all Example Groups
81+
def node_attributes
82+
attributes = {
83+
'platform': 'mac_os_x',
84+
'version': '10.15',
85+
'etc': {
86+
'passwd': {
87+
'brubble': lyraphase_workstation_user
88+
}
89+
},
90+
'sprout': {
91+
'home': '/Users/brubble',
92+
'user': 'brubble'
93+
},
94+
'lyraphase_workstation': {
95+
'user': 'brubble',
96+
'home': '/Users/brubble'
97+
}
98+
}
99+
stringify_keys(attributes)
100+
end
101+
102+
def cookbook_recipe_names
103+
described_recipe.split('::', 2)
104+
end
105+
106+
def cookbook_name
107+
cookbook_recipe_names.first
108+
end
109+
110+
def recipe_name
111+
cookbook_recipe_names.last
112+
end
113+
114+
def default_cookbook_attribute(attribute_name)
115+
node[cookbook_name][attribute_name]
116+
end
117+
end
118+
119+
RSpec.shared_context 'helpers tests', type: :helpers do
120+
include described_class
121+
122+
let(:new_resource) { OpenStruct.new(resource_properties) }
123+
124+
def resource_properties
125+
@resource_properties || {}
126+
end
127+
128+
def with_resource_properties(properties)
129+
@resource_properties = properties
130+
end
131+
132+
let(:node) do
133+
Fauxhai.mock { |node| node.merge!(node_attributes) }.data
134+
end
135+
136+
def node_attributes
137+
stringify_keys(@node_attributes || {})
138+
end
139+
140+
def with_node_attributes(attributes)
141+
@node_attributes = attributes
142+
end
143+
end
144+
145+
RSpec.shared_context 'resource tests', type: :resource do
146+
let(:chef_run) do
147+
ChefSpec::SoloRunner.new(node_attributes.merge(step_into)).converge(example_recipe)
148+
end
149+
150+
let(:example_recipe) do
151+
raise %(
152+
Please specify the name of the test recipe that executes your recipe:
153+
let(:example_recipe) do
154+
"lyraphase_workstation::example_recipe"
155+
end
156+
)
157+
end
158+
159+
let(:node) { chef_run.node }
160+
161+
def node_attributes
162+
{}
163+
end
164+
165+
let(:step_into) do
166+
{ step_into: [cookbook_name] }
167+
end
168+
169+
def cookbook_recipe_names
170+
described_recipe.split('::', 2)
171+
end
172+
173+
def cookbook_name
174+
cookbook_recipe_names.first
175+
end
176+
177+
def recipe_name
178+
cookbook_recipe_names.last
179+
end
180+
end
181+
182+
shared_context 'Chef 14.x no EtcPasswd' do
183+
let(:chef_run) {
184+
## Note: We run chef_run.converge here to raise exceptions for RSpec to check
185+
ChefSpec::SoloRunner.new(node_attributes).converge(described_recipe)
186+
}
187+
let(:node) { chef_run.node }
188+
189+
let(:chef_log_warnings) {
190+
["Chef >= 14.x removed node['etc']['passwd'] Ohai attributes that sprout cookbooks depend on!",
191+
"Please manually enable Ohai Passwd plugin, or populate cookbook attributes!",
192+
"References: ",
193+
" https://docs.chef.io/ohai/#optional-plugins",
194+
" https://github.com/chef/chef/issues/8888",
195+
" https://stackoverflow.com/a/57953198/645491"
196+
]
197+
}
198+
199+
let(:chef_log_fatal_msgs) {
200+
['node[\'etc\'][\'passwd\'] Ohai attributes are nil!']
201+
}
202+
203+
def node_attributes
204+
{}
205+
end
206+
207+
let(:fake_chef_version) do
208+
fake_chef_version = double('Chef::VERSION')
209+
allow(fake_chef_version).to receive(:to_s).and_return('14.0.190')
210+
fake_chef_version
211+
end
212+
213+
before(:each) do
214+
chef_log_warnings.each do |warning_msg|
215+
allow(Chef::Log).to receive(:warn).with(warning_msg).and_return(nil)
216+
end
217+
chef_log_fatal_msgs.each do |fatal_msg|
218+
allow(Chef::Log).to receive(:fatal).with(fatal_msg).and_return(nil)
219+
end
220+
stub_const('::Chef::VERSION', fake_chef_version)
221+
end
222+
end

spec/unit/recipes/bash4_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
end.converge(described_recipe)
4747
}
4848

49-
it 'installs gnugpg21 via homebrew' do
49+
it 'installs bash & bash-completion@2 via homebrew' do
5050
[
5151
'bash',
5252
'bash-completion@2'

spec/unit/recipes/bashrc_spec.rb

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# -*- coding: utf-8 -*-
2+
# frozen_string_literal: true
3+
#
4+
# Cookbook Name:: lyraphase_workstation
5+
# Recipe:: bashrc
6+
# Site:: https://www.gnu.org/software/bash/
7+
#
8+
# Copyright (C) © 🄯 2016-2022 James Cuzella
9+
#
10+
# This program is free software: you can redistribute it and/or modify
11+
# it under the terms of the GNU General Public License as published by
12+
# the Free Software Foundation, either version 3 of the License, or
13+
# (at your option) any later version.
14+
#
15+
# This program is distributed in the hope that it will be useful,
16+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
# GNU General Public License for more details.
19+
#
20+
# You should have received a copy of the GNU General Public License
21+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
22+
23+
require 'spec_helper'
24+
25+
describe_recipe 'lyraphase_workstation::bashrc' do
26+
# Override ChefSpec attributes from spec_shared_contexts
27+
let(:chefspec_options) {
28+
require 'securerandom'
29+
{
30+
default_attributes: {},
31+
normal_attributes: { 'lyraphase_workstation': {
32+
'bashrc': {
33+
'homebrew_github_api_token': "gh_#{SecureRandom.hex(20)}",
34+
'user_fullname': 'Barney Rubble',
35+
'user_email': '[email protected]',
36+
'user_gpg_keyid': "0x#{SecureRandom.hex(8)}"
37+
}
38+
}
39+
},
40+
automatic_attributes: {}
41+
}
42+
}
43+
44+
let(:bashrc_path) { '/Users/brubble/.bashrc' }
45+
let(:bash_logout_path) { '/Users/brubble/.bash_logout' }
46+
47+
it 'installs custom .bashrc into user homedir' do
48+
expect(chef_run).to create_template(bashrc_path).with(
49+
user: 'brubble',
50+
mode: '0644'
51+
)
52+
53+
[ "export HOMEBREW_GITHUB_API_TOKEN='#{chef_run.node['lyraphase_workstation']['bashrc']['homebrew_github_api_token']}'",
54+
"export DEBFULLNAME='#{chef_run.node['lyraphase_workstation']['bashrc']['user_fullname']}'",
55+
"export DEBEMAIL='#{chef_run.node['lyraphase_workstation']['bashrc']['user_email']}'",
56+
"export DEBSIGN_KEYID='#{chef_run.node['lyraphase_workstation']['bashrc']['user_gpg_keyid']}'",
57+
].each do |expected_regex|
58+
expect(chef_run).to render_file(bashrc_path).with_content(Regexp.new("^\s*#{expected_regex}\s*(#.*)?$"))
59+
end
60+
end
61+
62+
it 'installs custom .bash_logout into user homedir' do
63+
expect(chef_run).to create_template(bash_logout_path).with(
64+
user: 'brubble',
65+
mode: '0644'
66+
)
67+
end
68+
end
69+

0 commit comments

Comments
 (0)