-
Notifications
You must be signed in to change notification settings - Fork 104
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #409 from DavidS/pdk-506-provider
(PDK-506) pdk new provider
- Loading branch information
Showing
8 changed files
with
251 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
module PDK::CLI | ||
@new_provider_cmd = @new_cmd.define_command do | ||
name 'provider' | ||
usage _('provider [options] <name>') | ||
summary _('[experimental] Create a new ruby provider named <name> using given options') | ||
|
||
PDK::CLI.template_url_option(self) | ||
|
||
run do |opts, args, _cmd| | ||
PDK::CLI::Util.ensure_in_module! | ||
|
||
provider_name = args[0] | ||
module_dir = Dir.pwd | ||
|
||
if provider_name.nil? || provider_name.empty? | ||
puts command.help | ||
exit 1 | ||
end | ||
|
||
unless Util::OptionValidator.valid_provider_name?(provider_name) | ||
raise PDK::CLI::ExitWithError, _("'%{name}' is not a valid provider name") % { name: provider_name } | ||
end | ||
|
||
PDK::Generate::Provider.new(module_dir, provider_name, opts).run | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
require 'pdk/generate/puppet_object' | ||
|
||
module PDK | ||
module Generate | ||
class Provider < PuppetObject | ||
OBJECT_TYPE = :provider | ||
|
||
# Prepares the data needed to render the new defined type template. | ||
# | ||
# @return [Hash{Symbol => Object}] a hash of information that will be | ||
# provided to the defined type and defined type spec templates during | ||
# rendering. | ||
def template_data | ||
data = { | ||
name: object_name, | ||
provider_class: Provider.class_name_from_object_name(object_name), | ||
} | ||
|
||
data | ||
end | ||
|
||
def raise_precondition_error(error) | ||
raise PDK::CLI::ExitWithError, _('%{error}: Creating a provider needs some local configuration in your module.' \ | ||
' Please follow the docs at https://github.com/puppetlabs/puppet-resource_api#getting-started.') % { error: error } | ||
end | ||
|
||
def check_preconditions | ||
super | ||
# These preconditions can be removed once the pdk-templates are carrying the puppet-resource_api gem by default, and have switched | ||
# the default mock_with value. | ||
sync_path = PDK::Util.find_upwards('.sync.yml') | ||
if sync_path.nil? | ||
raise_precondition_error(_('.sync.yml not found')) | ||
end | ||
sync = YAML.load_file(sync_path) | ||
if !sync.is_a? Hash | ||
raise_precondition_error(_('.sync.yml contents is not a Hash')) | ||
elsif !sync.key? 'Gemfile' | ||
raise_precondition_error(_('Gemfile configuration not found')) | ||
elsif !sync['Gemfile'].key? 'optional' | ||
raise_precondition_error(_('Gemfile.optional configuration not found')) | ||
elsif !sync['Gemfile']['optional'].key? ':development' | ||
raise_precondition_error(_('Gemfile.optional.:development configuration not found')) | ||
elsif sync['Gemfile']['optional'][':development'].none? { |g| g['gem'] == 'puppet-resource_api' } | ||
raise_precondition_error(_('puppet-resource_api not found in the Gemfile config')) | ||
elsif !sync.key? 'spec/spec_helper.rb' | ||
raise_precondition_error(_('spec/spec_helper.rb configuration not found')) | ||
elsif !sync['spec/spec_helper.rb'].key? 'mock_with' | ||
raise_precondition_error(_('spec/spec_helper.rb.mock_with configuration not found')) | ||
elsif !sync['spec/spec_helper.rb']['mock_with'] == ':rspec' | ||
raise_precondition_error(_('spec/spec_helper.rb.mock_with not set to \':rspec\'')) | ||
end | ||
end | ||
|
||
# @return [String] the path where the new type will be written. | ||
def target_object_path | ||
@target_object_path ||= File.join(module_dir, 'lib', 'puppet', 'type', object_name) + '.rb' | ||
end | ||
|
||
# @return [String] the path where the new provider will be written. | ||
def target_addon_path | ||
@target_addon_path ||= File.join(module_dir, 'lib', 'puppet', 'provider', object_name, object_name) + '.rb' | ||
end | ||
|
||
# Calculates the path to the file where the tests for the new defined | ||
# type will be written. | ||
# | ||
# @return [String] the path where the tests for the new defined type | ||
# will be written. | ||
def target_spec_path | ||
@target_spec_path ||= File.join(module_dir, 'spec', 'unit', 'puppet', 'provider', object_name, object_name) + '_spec.rb' | ||
end | ||
|
||
# transform a object name into a ruby class name | ||
def self.class_name_from_object_name(object_name) | ||
object_name.to_s.split('_').map(&:capitalize).join | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
require 'spec_helper_acceptance' | ||
|
||
describe 'pdk new provider foo', module_command: true do | ||
context 'in a new module' do | ||
include_context 'in a new module', 'new_provider' | ||
|
||
context 'when creating a provider' do | ||
before(:all) do | ||
File.open('.sync.yml', 'w') do |f| | ||
f.write(<<SYNC) | ||
--- | ||
Gemfile: | ||
optional: | ||
':development': | ||
- gem: 'puppet-resource_api' | ||
spec/spec_helper.rb: | ||
mock_with: ':rspec' | ||
SYNC | ||
end | ||
system('pdk convert --force') | ||
end | ||
|
||
describe command('pdk new provider test_provider') do | ||
its(:stderr) { is_expected.to match(%r{creating .* from template}i) } | ||
its(:stderr) { is_expected.not_to match(%r{WARN|ERR}) } | ||
its(:stdout) { is_expected.to match(%r{\A\Z}) } | ||
its(:exit_status) { is_expected.to eq(0) } | ||
end | ||
|
||
describe file('lib/puppet/type') do | ||
it { is_expected.to be_directory } | ||
end | ||
|
||
describe file('lib/puppet/type/test_provider.rb') do | ||
it { is_expected.to be_file } | ||
its(:content) { is_expected.to match(%r{Puppet::ResourceApi.register_type}) } | ||
its(:content) { is_expected.to match(%r{name: 'test_provider'}) } | ||
end | ||
|
||
describe file('lib/puppet/provider/test_provider') do | ||
it { is_expected.to be_directory } | ||
end | ||
|
||
describe file('lib/puppet/provider/test_provider/test_provider.rb') do | ||
it { is_expected.to be_file } | ||
its(:content) { is_expected.to match(%r{class Puppet::Provider::TestProvider::TestProvider}) } | ||
end | ||
|
||
describe file('spec/unit/puppet/provider/test_provider') do | ||
it { is_expected.to be_directory } | ||
end | ||
|
||
describe file('spec/unit/puppet/provider/test_provider/test_provider_spec.rb') do | ||
it { is_expected.to be_file } | ||
its(:content) { is_expected.to match(%r{RSpec.describe Puppet::Provider::TestProvider::TestProvider do}) } | ||
end | ||
|
||
context 'when validating the generated code' do | ||
describe command('pdk validate ruby') do | ||
its(:stdout) { is_expected.to be_empty } | ||
its(:stderr) { is_expected.to be_empty } | ||
its(:exit_status) { is_expected.to eq(0) } | ||
end | ||
end | ||
|
||
context 'when running the generated spec tests' do | ||
describe command('pdk test unit') do | ||
its(:stderr) { is_expected.to match(%r{0 failures}) } | ||
its(:stderr) { is_expected.not_to match(%r{no examples found}i) } | ||
its(:exit_status) { is_expected.to eq(0) } | ||
end | ||
end | ||
|
||
context 'without a .sync.yml' do | ||
before(:all) do | ||
FileUtils.mv('.sync.yml', 'sync.yml.orig') | ||
end | ||
|
||
describe command('pdk new provider test_provider2') do | ||
its(:stderr) { is_expected.to match(%r{pdk \(ERROR\): .sync.yml not found}i) } | ||
its(:stdout) { is_expected.to match(%r{\A\Z}) } | ||
its(:exit_status) { is_expected.not_to eq(0) } | ||
end | ||
end | ||
|
||
context 'with invalid .sync.yml' do | ||
before(:all) do | ||
File.open('.sync.yml', 'w') do |f| | ||
f.write(<<SYNC) | ||
--- | ||
Gemfile: | ||
optional: | ||
':wrong_group': | ||
- gem: 'puppet-resource_api' | ||
spec/spec_helper.rb: | ||
mock_with: ':rspec' | ||
SYNC | ||
end | ||
system('pdk convert --force') | ||
end | ||
|
||
describe command('pdk new provider test_provider2') do | ||
its(:stderr) { is_expected.to match(%r{pdk \(ERROR\): Gemfile.optional.:development configuration not found}i) } | ||
its(:stdout) { is_expected.to match(%r{\A\Z}) } | ||
its(:exit_status) { is_expected.not_to eq(0) } | ||
end | ||
end | ||
end | ||
end | ||
end |