pdk 1.9.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG.md +744 -711
- data/README.md +23 -21
- data/lib/pdk/answer_file.rb +3 -112
- data/lib/pdk/bolt.rb +20 -0
- data/lib/pdk/cli/build.rb +51 -54
- data/lib/pdk/cli/bundle.rb +33 -29
- data/lib/pdk/cli/console.rb +148 -0
- data/lib/pdk/cli/convert.rb +46 -37
- data/lib/pdk/cli/env.rb +51 -0
- data/lib/pdk/cli/errors.rb +4 -3
- data/lib/pdk/cli/exec/command.rb +285 -0
- data/lib/pdk/cli/exec/interactive_command.rb +109 -0
- data/lib/pdk/cli/exec.rb +32 -201
- data/lib/pdk/cli/exec_group.rb +79 -43
- data/lib/pdk/cli/get/config.rb +26 -0
- data/lib/pdk/cli/get.rb +22 -0
- data/lib/pdk/cli/new/class.rb +20 -22
- data/lib/pdk/cli/new/defined_type.rb +21 -21
- data/lib/pdk/cli/new/fact.rb +27 -0
- data/lib/pdk/cli/new/function.rb +27 -0
- data/lib/pdk/cli/new/module.rb +40 -29
- data/lib/pdk/cli/new/provider.rb +18 -18
- data/lib/pdk/cli/new/task.rb +23 -22
- data/lib/pdk/cli/new/test.rb +52 -0
- data/lib/pdk/cli/new/transport.rb +27 -0
- data/lib/pdk/cli/new.rb +15 -9
- data/lib/pdk/cli/release/prep.rb +39 -0
- data/lib/pdk/cli/release/publish.rb +46 -0
- data/lib/pdk/cli/release.rb +185 -0
- data/lib/pdk/cli/remove/config.rb +83 -0
- data/lib/pdk/cli/remove.rb +22 -0
- data/lib/pdk/cli/set/config.rb +121 -0
- data/lib/pdk/cli/set.rb +22 -0
- data/lib/pdk/cli/test/unit.rb +71 -69
- data/lib/pdk/cli/test.rb +9 -8
- data/lib/pdk/cli/update.rb +38 -21
- data/lib/pdk/cli/util/command_redirector.rb +13 -3
- data/lib/pdk/cli/util/interview.rb +25 -9
- data/lib/pdk/cli/util/option_normalizer.rb +6 -6
- data/lib/pdk/cli/util/option_validator.rb +19 -9
- data/lib/pdk/cli/util/spinner.rb +13 -0
- data/lib/pdk/cli/util/update_manager_printer.rb +82 -0
- data/lib/pdk/cli/util.rb +105 -48
- data/lib/pdk/cli/validate.rb +96 -111
- data/lib/pdk/cli.rb +134 -87
- data/lib/pdk/config/errors.rb +5 -0
- data/lib/pdk/config/ini_file.rb +184 -0
- data/lib/pdk/config/ini_file_setting.rb +35 -0
- data/lib/pdk/config/json.rb +35 -0
- data/lib/pdk/config/json_schema_namespace.rb +137 -0
- data/lib/pdk/config/json_schema_setting.rb +51 -0
- data/lib/pdk/config/json_with_schema.rb +47 -0
- data/lib/pdk/config/namespace.rb +362 -0
- data/lib/pdk/config/setting.rb +134 -0
- data/lib/pdk/config/task_schema.json +116 -0
- data/lib/pdk/config/validator.rb +31 -0
- data/lib/pdk/config/yaml.rb +41 -0
- data/lib/pdk/config/yaml_with_schema.rb +51 -0
- data/lib/pdk/config.rb +304 -0
- data/lib/pdk/context/control_repo.rb +61 -0
- data/lib/pdk/context/module.rb +28 -0
- data/lib/pdk/context/none.rb +22 -0
- data/lib/pdk/context.rb +98 -0
- data/lib/pdk/control_repo.rb +89 -0
- data/lib/pdk/generate/defined_type.rb +27 -33
- data/lib/pdk/generate/fact.rb +26 -0
- data/lib/pdk/generate/function.rb +49 -0
- data/lib/pdk/generate/module.rb +160 -153
- data/lib/pdk/generate/provider.rb +16 -69
- data/lib/pdk/generate/puppet_class.rb +27 -32
- data/lib/pdk/generate/puppet_object.rb +100 -159
- data/lib/pdk/generate/task.rb +34 -51
- data/lib/pdk/generate/transport.rb +34 -0
- data/lib/pdk/generate.rb +21 -8
- data/lib/pdk/logger.rb +24 -6
- data/lib/pdk/module/build.rb +125 -37
- data/lib/pdk/module/convert.rb +146 -65
- data/lib/pdk/module/metadata.rb +72 -71
- data/lib/pdk/module/release.rb +255 -0
- data/lib/pdk/module/update.rb +48 -37
- data/lib/pdk/module/update_manager.rb +75 -39
- data/lib/pdk/module.rb +10 -2
- data/lib/pdk/monkey_patches.rb +268 -0
- data/lib/pdk/report/event.rb +36 -48
- data/lib/pdk/report.rb +35 -22
- data/lib/pdk/template/fetcher/git.rb +84 -0
- data/lib/pdk/template/fetcher/local.rb +29 -0
- data/lib/pdk/template/fetcher.rb +100 -0
- data/lib/pdk/template/renderer/v1/legacy_template_dir.rb +108 -0
- data/lib/pdk/template/renderer/v1/renderer.rb +131 -0
- data/lib/pdk/template/renderer/v1/template_file.rb +100 -0
- data/lib/pdk/template/renderer/v1.rb +25 -0
- data/lib/pdk/template/renderer.rb +97 -0
- data/lib/pdk/template/template_dir.rb +67 -0
- data/lib/pdk/template.rb +52 -0
- data/lib/pdk/tests/unit.rb +101 -51
- data/lib/pdk/util/bundler.rb +44 -42
- data/lib/pdk/util/changelog_generator.rb +138 -0
- data/lib/pdk/util/env.rb +48 -0
- data/lib/pdk/util/filesystem.rb +139 -2
- data/lib/pdk/util/git.rb +108 -8
- data/lib/pdk/util/json_finder.rb +86 -0
- data/lib/pdk/util/puppet_strings.rb +125 -0
- data/lib/pdk/util/puppet_version.rb +71 -87
- data/lib/pdk/util/ruby_version.rb +49 -25
- data/lib/pdk/util/template_uri.rb +283 -0
- data/lib/pdk/util/vendored_file.rb +34 -42
- data/lib/pdk/util/version.rb +11 -10
- data/lib/pdk/util/windows/api_types.rb +74 -44
- data/lib/pdk/util/windows/file.rb +31 -27
- data/lib/pdk/util/windows/process.rb +74 -0
- data/lib/pdk/util/windows/string.rb +19 -12
- data/lib/pdk/util/windows.rb +2 -0
- data/lib/pdk/util.rb +111 -124
- data/lib/pdk/validate/control_repo/control_repo_validator_group.rb +23 -0
- data/lib/pdk/validate/control_repo/environment_conf_validator.rb +98 -0
- data/lib/pdk/validate/external_command_validator.rb +213 -0
- data/lib/pdk/validate/internal_ruby_validator.rb +101 -0
- data/lib/pdk/validate/invokable_validator.rb +238 -0
- data/lib/pdk/validate/metadata/metadata_json_lint_validator.rb +84 -0
- data/lib/pdk/validate/metadata/metadata_syntax_validator.rb +76 -0
- data/lib/pdk/validate/metadata/metadata_validator_group.rb +20 -0
- data/lib/pdk/validate/puppet/puppet_epp_validator.rb +131 -0
- data/lib/pdk/validate/puppet/puppet_lint_validator.rb +66 -0
- data/lib/pdk/validate/puppet/puppet_plan_syntax_validator.rb +38 -0
- data/lib/pdk/validate/puppet/puppet_syntax_validator.rb +135 -0
- data/lib/pdk/validate/puppet/puppet_validator_group.rb +22 -0
- data/lib/pdk/validate/ruby/ruby_rubocop_validator.rb +79 -0
- data/lib/pdk/validate/ruby/ruby_validator_group.rb +19 -0
- data/lib/pdk/validate/tasks/tasks_metadata_lint_validator.rb +83 -0
- data/lib/pdk/validate/tasks/tasks_name_validator.rb +45 -0
- data/lib/pdk/validate/tasks/tasks_validator_group.rb +20 -0
- data/lib/pdk/validate/validator.rb +120 -0
- data/lib/pdk/validate/validator_group.rb +107 -0
- data/lib/pdk/validate/yaml/yaml_syntax_validator.rb +86 -0
- data/lib/pdk/validate/yaml/yaml_validator_group.rb +19 -0
- data/lib/pdk/validate.rb +86 -12
- data/lib/pdk/version.rb +2 -2
- data/lib/pdk.rb +60 -10
- metadata +138 -100
- data/lib/pdk/cli/module/build.rb +0 -14
- data/lib/pdk/cli/module/generate.rb +0 -45
- data/lib/pdk/cli/module.rb +0 -14
- data/lib/pdk/i18n.rb +0 -4
- data/lib/pdk/module/templatedir.rb +0 -321
- data/lib/pdk/template_file.rb +0 -95
- data/lib/pdk/validate/base_validator.rb +0 -215
- data/lib/pdk/validate/metadata/metadata_json_lint.rb +0 -86
- data/lib/pdk/validate/metadata/metadata_syntax.rb +0 -109
- data/lib/pdk/validate/metadata_validator.rb +0 -30
- data/lib/pdk/validate/puppet/puppet_lint.rb +0 -67
- data/lib/pdk/validate/puppet/puppet_syntax.rb +0 -112
- data/lib/pdk/validate/puppet_validator.rb +0 -30
- data/lib/pdk/validate/ruby/rubocop.rb +0 -77
- data/lib/pdk/validate/ruby_validator.rb +0 -29
- data/lib/pdk/validate/tasks/metadata_lint.rb +0 -126
- data/lib/pdk/validate/tasks/name.rb +0 -88
- data/lib/pdk/validate/tasks_validator.rb +0 -33
- data/lib/pdk/validate/yaml/syntax.rb +0 -109
- data/lib/pdk/validate/yaml_validator.rb +0 -31
- data/locales/config.yaml +0 -21
- data/locales/pdk.pot +0 -1291
data/lib/pdk/util/env.rb
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require 'pdk'
|
|
2
|
+
require 'forwardable'
|
|
3
|
+
|
|
4
|
+
module PDK
|
|
5
|
+
module Util
|
|
6
|
+
class Env
|
|
7
|
+
class WindowsEnv
|
|
8
|
+
extend Forwardable
|
|
9
|
+
|
|
10
|
+
# Note, these delegators may not have case insensitive keys
|
|
11
|
+
def_delegators :env_hash, :fetch, :select, :reject
|
|
12
|
+
|
|
13
|
+
def []=(key, value)
|
|
14
|
+
PDK::Util::Windows::Process.set_environment_variable(key, value)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def key?(key)
|
|
18
|
+
!env_hash.keys.find { |item| key.casecmp(item).zero? }.nil?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def [](key)
|
|
22
|
+
env_hash.each do |item, value|
|
|
23
|
+
next unless key.casecmp(item).zero?
|
|
24
|
+
|
|
25
|
+
return value
|
|
26
|
+
end
|
|
27
|
+
nil
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def env_hash
|
|
33
|
+
PDK::Util::Windows::Process.environment_hash
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class << self
|
|
38
|
+
extend Forwardable
|
|
39
|
+
|
|
40
|
+
def_delegators :implementation, :key?, :[], :[]=, :fetch, :select, :reject
|
|
41
|
+
|
|
42
|
+
def implementation
|
|
43
|
+
@implementation ||= Gem.win_platform? ? WindowsEnv.new : ENV
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
data/lib/pdk/util/filesystem.rb
CHANGED
|
@@ -1,12 +1,149 @@
|
|
|
1
|
+
require 'pdk'
|
|
2
|
+
autoload :FileUtils, 'fileutils'
|
|
3
|
+
|
|
1
4
|
module PDK
|
|
2
5
|
module Util
|
|
3
6
|
module Filesystem
|
|
4
7
|
def write_file(path, content)
|
|
5
|
-
raise ArgumentError unless
|
|
8
|
+
raise ArgumentError, 'content must be a String' unless content.is_a?(String)
|
|
9
|
+
raise ArgumentError, 'path must be a String or Pathname' unless path.is_a?(String) || path.respond_to?(:to_path)
|
|
10
|
+
|
|
11
|
+
# Harmonize newlines across platforms.
|
|
12
|
+
content = content.encode(universal_newline: true)
|
|
13
|
+
|
|
14
|
+
# Make sure all written files have a trailing newline.
|
|
15
|
+
content += "\n" unless content[-1] == "\n"
|
|
6
16
|
|
|
7
|
-
File.
|
|
17
|
+
File.binwrite(path, content)
|
|
8
18
|
end
|
|
9
19
|
module_function :write_file
|
|
20
|
+
|
|
21
|
+
def read_file(file, nil_on_error: false, open_args: 'r')
|
|
22
|
+
File.read(file, open_args: Array(open_args))
|
|
23
|
+
rescue StandardError => e
|
|
24
|
+
raise e unless nil_on_error
|
|
25
|
+
|
|
26
|
+
nil
|
|
27
|
+
end
|
|
28
|
+
module_function :read_file
|
|
29
|
+
|
|
30
|
+
def make_executable(file)
|
|
31
|
+
FileUtils.chmod('a+x', file)
|
|
32
|
+
end
|
|
33
|
+
module_function :make_executable
|
|
34
|
+
|
|
35
|
+
# :nocov:
|
|
36
|
+
# These methods just wrap core Ruby functionality and
|
|
37
|
+
# can be ignored for code coverage
|
|
38
|
+
def directory?(*args)
|
|
39
|
+
File.directory?(*args)
|
|
40
|
+
end
|
|
41
|
+
module_function :directory?
|
|
42
|
+
|
|
43
|
+
def mkdir_p(*args, **kwargs)
|
|
44
|
+
FileUtils.mkdir_p(*args, **kwargs)
|
|
45
|
+
end
|
|
46
|
+
module_function :mkdir_p
|
|
47
|
+
|
|
48
|
+
def file?(*args)
|
|
49
|
+
File.file?(*args)
|
|
50
|
+
end
|
|
51
|
+
module_function :file?
|
|
52
|
+
|
|
53
|
+
def expand_path(*args)
|
|
54
|
+
File.expand_path(*args)
|
|
55
|
+
end
|
|
56
|
+
module_function :expand_path
|
|
57
|
+
|
|
58
|
+
def glob(*args)
|
|
59
|
+
Dir.glob(*args)
|
|
60
|
+
end
|
|
61
|
+
module_function :glob
|
|
62
|
+
|
|
63
|
+
def fnmatch(*args)
|
|
64
|
+
File.fnmatch(*args)
|
|
65
|
+
end
|
|
66
|
+
module_function :fnmatch
|
|
67
|
+
|
|
68
|
+
def fnmatch?(*args)
|
|
69
|
+
File.fnmatch?(*args)
|
|
70
|
+
end
|
|
71
|
+
module_function :fnmatch?
|
|
72
|
+
|
|
73
|
+
def readable?(*args)
|
|
74
|
+
File.readable?(*args)
|
|
75
|
+
end
|
|
76
|
+
module_function :readable?
|
|
77
|
+
|
|
78
|
+
def exist?(*args)
|
|
79
|
+
File.exist?(*args)
|
|
80
|
+
end
|
|
81
|
+
module_function :exist?
|
|
82
|
+
|
|
83
|
+
def rm(*args, **kwargs)
|
|
84
|
+
FileUtils.rm(*args, **kwargs)
|
|
85
|
+
end
|
|
86
|
+
module_function :rm
|
|
87
|
+
|
|
88
|
+
def rm_f(*args, **kwargs)
|
|
89
|
+
FileUtils.rm_f(*args, **kwargs)
|
|
90
|
+
end
|
|
91
|
+
module_function :rm_f
|
|
92
|
+
|
|
93
|
+
def rm_rf(*args, **kwargs)
|
|
94
|
+
FileUtils.rm_rf(*args, **kwargs)
|
|
95
|
+
end
|
|
96
|
+
module_function :rm_rf
|
|
97
|
+
|
|
98
|
+
def remove_entry_secure(*args)
|
|
99
|
+
FileUtils.remove_entry_secure(*args)
|
|
100
|
+
end
|
|
101
|
+
module_function :remove_entry_secure
|
|
102
|
+
|
|
103
|
+
def zero?(*args)
|
|
104
|
+
File.empty?(*args)
|
|
105
|
+
end
|
|
106
|
+
module_function :zero?
|
|
107
|
+
|
|
108
|
+
def stat(*args)
|
|
109
|
+
File.stat(*args)
|
|
110
|
+
end
|
|
111
|
+
module_function :stat
|
|
112
|
+
|
|
113
|
+
def symlink?(*args)
|
|
114
|
+
File.symlink?(*args)
|
|
115
|
+
end
|
|
116
|
+
module_function :symlink?
|
|
117
|
+
|
|
118
|
+
def cp(*args, **kwargs)
|
|
119
|
+
FileUtils.cp(*args, **kwargs)
|
|
120
|
+
end
|
|
121
|
+
module_function :cp
|
|
122
|
+
|
|
123
|
+
def mv(*args, **kwargs)
|
|
124
|
+
FileUtils.mv(*args, **kwargs)
|
|
125
|
+
rescue Errno::ENOENT
|
|
126
|
+
# PDK-1169 - FileUtils.mv raises Errno::ENOENT when moving files inside
|
|
127
|
+
# VMWare shared folders on Windows. So we need to catch this
|
|
128
|
+
# case, check if the file exists to see if the exception is
|
|
129
|
+
# legit and "move" the file with cp & rm.
|
|
130
|
+
src, dest, opts = args
|
|
131
|
+
raise unless File.exist?(src)
|
|
132
|
+
|
|
133
|
+
FileUtils.cp(src, dest, preserve: true)
|
|
134
|
+
if (opts ||= {})[:secure]
|
|
135
|
+
FileUtils.remove_entry_secure(src, opts[:force])
|
|
136
|
+
else
|
|
137
|
+
FileUtils.remove_entry(src, opts[:force])
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
module_function :mv
|
|
141
|
+
|
|
142
|
+
def executable?(*args)
|
|
143
|
+
File.executable?(*args)
|
|
144
|
+
end
|
|
145
|
+
module_function :executable?
|
|
146
|
+
# :nocov:
|
|
10
147
|
end
|
|
11
148
|
end
|
|
12
149
|
end
|
data/lib/pdk/util/git.rb
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
|
+
require 'pdk'
|
|
2
|
+
|
|
1
3
|
module PDK
|
|
2
4
|
module Util
|
|
5
|
+
class GitError < StandardError
|
|
6
|
+
attr_reader :stdout, :stderr, :exit_code, :args
|
|
7
|
+
|
|
8
|
+
def initialze(args, result)
|
|
9
|
+
@args = args
|
|
10
|
+
@stdout = result[:stdout]
|
|
11
|
+
@stderr = result[:stderr]
|
|
12
|
+
@exit_code = result[:exit_code]
|
|
13
|
+
|
|
14
|
+
super(format('Git command failed: git %{args}', args: args.join(' ')))
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
3
18
|
module Git
|
|
19
|
+
GIT_QUERY_CACHE_TTL = 10
|
|
20
|
+
|
|
4
21
|
def self.git_bindir
|
|
5
22
|
@git_dir ||= File.join('private', 'git', Gem.win_platform? ? 'cmd' : 'bin')
|
|
6
23
|
end
|
|
@@ -20,6 +37,8 @@ module PDK
|
|
|
20
37
|
end
|
|
21
38
|
|
|
22
39
|
def self.git_bin
|
|
40
|
+
require 'pdk/cli/exec'
|
|
41
|
+
|
|
23
42
|
git_bin = Gem.win_platform? ? 'git.exe' : 'git'
|
|
24
43
|
vendored_bin_path = File.join(git_bindir, git_bin)
|
|
25
44
|
|
|
@@ -27,21 +46,33 @@ module PDK
|
|
|
27
46
|
end
|
|
28
47
|
|
|
29
48
|
def self.git(*args)
|
|
49
|
+
require 'pdk/cli/exec'
|
|
50
|
+
|
|
30
51
|
PDK::CLI::Exec.ensure_bin_present!(git_bin, 'git')
|
|
31
52
|
|
|
32
53
|
PDK::CLI::Exec.execute(git_bin, *args)
|
|
33
54
|
end
|
|
34
55
|
|
|
35
56
|
def self.git_with_env(env, *args)
|
|
57
|
+
require 'pdk/cli/exec'
|
|
58
|
+
|
|
36
59
|
PDK::CLI::Exec.ensure_bin_present!(git_bin, 'git')
|
|
37
60
|
|
|
38
61
|
PDK::CLI::Exec.execute_with_env(env, git_bin, *args)
|
|
39
62
|
end
|
|
40
63
|
|
|
41
64
|
def self.repo?(maybe_repo)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
65
|
+
result = cached_git_query(maybe_repo, :repo?)
|
|
66
|
+
return result unless result.nil?
|
|
67
|
+
|
|
68
|
+
result = if PDK::Util::Filesystem.directory?(maybe_repo)
|
|
69
|
+
# Use boolean shortcircuiting here. The mostly likely type of git repo
|
|
70
|
+
# is a "normal" repo with a working tree. Bare repos do not have work tree
|
|
71
|
+
work_tree?(maybe_repo) || bare_repo?(maybe_repo)
|
|
72
|
+
else
|
|
73
|
+
remote_repo?(maybe_repo)
|
|
74
|
+
end
|
|
75
|
+
cache_query_result(maybe_repo, :repo?, result)
|
|
45
76
|
end
|
|
46
77
|
|
|
47
78
|
def self.bare_repo?(maybe_repo)
|
|
@@ -55,20 +86,89 @@ module PDK
|
|
|
55
86
|
git('ls-remote', '--exit-code', maybe_repo)[:exit_code].zero?
|
|
56
87
|
end
|
|
57
88
|
|
|
89
|
+
def self.work_tree?(path)
|
|
90
|
+
return false unless PDK::Util::Filesystem.directory?(path)
|
|
91
|
+
|
|
92
|
+
result = cached_git_query(path, :work_tree?)
|
|
93
|
+
return result unless result.nil?
|
|
94
|
+
|
|
95
|
+
Dir.chdir(path) do
|
|
96
|
+
rev_parse = git('rev-parse', '--is-inside-work-tree')
|
|
97
|
+
cache_query_result(path, :work_tree?, rev_parse[:exit_code].zero? && rev_parse[:stdout].strip == 'true')
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def self.work_dir_clean?(repo)
|
|
102
|
+
raise PDK::CLI::ExitWithError, format('Unable to locate git work dir "%{workdir}"', workdir: repo) unless PDK::Util::Filesystem.directory?(repo)
|
|
103
|
+
raise PDK::CLI::ExitWithError, format('Unable to locate git dir "%{gitdir}"', gitdir: repo) unless PDK::Util::Filesystem.directory?(File.join(repo, '.git'))
|
|
104
|
+
|
|
105
|
+
git('--work-tree', repo, '--git-dir', File.join(repo, '.git'), 'status', '--untracked-files=no', '--porcelain', repo)[:stdout].empty?
|
|
106
|
+
end
|
|
107
|
+
|
|
58
108
|
def self.ls_remote(repo, ref)
|
|
109
|
+
repo = "file://#{repo}" if PDK::Util::Filesystem.directory?(repo)
|
|
110
|
+
|
|
59
111
|
output = git('ls-remote', '--refs', repo, ref)
|
|
60
112
|
|
|
61
113
|
unless output[:exit_code].zero?
|
|
62
114
|
PDK.logger.error output[:stdout]
|
|
63
115
|
PDK.logger.error output[:stderr]
|
|
64
|
-
raise PDK::CLI::ExitWithError,
|
|
65
|
-
|
|
66
|
-
|
|
116
|
+
raise PDK::CLI::ExitWithError, format('Unable to access the template repository "%{repository}"', repository: repo)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
matching_refs = output[:stdout].split(/\r?\n/).map { |r| r.split("\t") }
|
|
120
|
+
matching_ref = matching_refs.find { |_sha, remote_ref| ["refs/tags/#{ref}", "refs/remotes/origin/#{ref}", "refs/heads/#{ref}"].include?(remote_ref) }
|
|
121
|
+
raise PDK::CLI::ExitWithError, format('Unable to find a branch or tag named "%{ref}" in %{repo}', ref: ref, repo: repo) if matching_ref.nil?
|
|
122
|
+
|
|
123
|
+
matching_ref.first
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def self.describe(path, ref = nil)
|
|
127
|
+
args = ['--git-dir', path, 'describe', '--all', '--long', '--always', ref].compact
|
|
128
|
+
result = git(*args)
|
|
129
|
+
raise PDK::Util::GitError, args, result unless result[:exit_code].zero?
|
|
130
|
+
|
|
131
|
+
result[:stdout].strip
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def self.tag?(git_remote, tag_name)
|
|
135
|
+
git('ls-remote', '--tags', '--exit-code', git_remote, tag_name)[:exit_code].zero?
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Clears any cached information for git queries
|
|
139
|
+
# Should only be used during testing
|
|
140
|
+
# @api private
|
|
141
|
+
def self.clear_cached_information
|
|
142
|
+
@git_repo_expire_cache = nil
|
|
143
|
+
@git_repo_cache = nil
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def self.cached_git_query(repo, query)
|
|
147
|
+
# TODO: Not thread safe
|
|
148
|
+
if @git_repo_expire_cache.nil? || Time.now > @git_repo_expire_cache
|
|
149
|
+
@git_repo_expire_cache = Time.now + GIT_QUERY_CACHE_TTL # Expire the cache every GIT_QUERY_CACHE_TTL seconds
|
|
150
|
+
@git_repo_cache = {}
|
|
67
151
|
end
|
|
152
|
+
return nil if @git_repo_cache[repo].nil?
|
|
68
153
|
|
|
69
|
-
|
|
70
|
-
|
|
154
|
+
@git_repo_cache[repo][query]
|
|
155
|
+
end
|
|
156
|
+
private_class_method :cached_git_query
|
|
157
|
+
|
|
158
|
+
def self.cache_query_result(repo, query, result)
|
|
159
|
+
# TODO: Not thread safe?
|
|
160
|
+
if @git_repo_expire_cache.nil?
|
|
161
|
+
@git_repo_expire_cache = Time.now + GIT_QUERY_CACHE_TTL
|
|
162
|
+
@git_repo_cache = {}
|
|
163
|
+
end
|
|
164
|
+
if @git_repo_cache[repo].nil?
|
|
165
|
+
@git_repo_cache[repo] = { query => result }
|
|
166
|
+
else
|
|
167
|
+
@git_repo_cache[repo][query] = result
|
|
168
|
+
end
|
|
169
|
+
result
|
|
71
170
|
end
|
|
171
|
+
private_class_method :cache_query_result
|
|
72
172
|
end
|
|
73
173
|
end
|
|
74
174
|
end
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
module PDK
|
|
2
|
+
module Util
|
|
3
|
+
# Processes a given string, looking for JSON objects and parsing them.
|
|
4
|
+
#
|
|
5
|
+
# @example A string with a JSON object and some junk characters
|
|
6
|
+
# PDK::Util::JSONFinder.new('foo{"bar":1}').objects
|
|
7
|
+
# => [{ 'bar' => 1 }]
|
|
8
|
+
#
|
|
9
|
+
# @example A string with mulitple JSON objects
|
|
10
|
+
# PDK::Util::JSONFinder.new('foo{"bar":1}baz{"gronk":2}').objects
|
|
11
|
+
# => [{ 'bar' => 1 }, { 'gronk' => 2 }]
|
|
12
|
+
class JSONFinder
|
|
13
|
+
# Creates a new instance of PDK::Util::JSONFinder.
|
|
14
|
+
#
|
|
15
|
+
# @param string [String] the string to find JSON objects inside of.
|
|
16
|
+
#
|
|
17
|
+
# @return [PDK::Util::JSONFinder] a new PDK::Util::JSONFinder object.
|
|
18
|
+
def initialize(string)
|
|
19
|
+
require 'strscan'
|
|
20
|
+
|
|
21
|
+
@scanner = StringScanner.new(string)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Returns the parsed JSON objects from the string.
|
|
25
|
+
#
|
|
26
|
+
# @return [Array[Hash]] the parsed JSON objects present in the string.
|
|
27
|
+
def objects
|
|
28
|
+
return @objects unless @objects.nil?
|
|
29
|
+
|
|
30
|
+
require 'json'
|
|
31
|
+
|
|
32
|
+
until @scanner.eos?
|
|
33
|
+
@scanner.getch until @scanner.peek(1) == '{' || @scanner.eos?
|
|
34
|
+
|
|
35
|
+
(@objects ||= []) << begin
|
|
36
|
+
JSON.parse(read_object(true) || '')
|
|
37
|
+
rescue JSON::ParserError
|
|
38
|
+
nil
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
return [] if @objects.nil?
|
|
43
|
+
|
|
44
|
+
@objects = @objects.compact
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
# Recursively process the string to extract a complete JSON object.
|
|
50
|
+
#
|
|
51
|
+
# @param new_object [Boolean] Set to true if processing a new object to
|
|
52
|
+
# capture the opening brace. Set to false if being called recursively
|
|
53
|
+
# where the opening brace has already been captured.
|
|
54
|
+
#
|
|
55
|
+
# @return [String] The matched substring containing a JSON object.
|
|
56
|
+
def read_object(new_object = false)
|
|
57
|
+
matched_text = new_object ? @scanner.getch : ''
|
|
58
|
+
|
|
59
|
+
until @scanner.eos?
|
|
60
|
+
text = @scanner.scan_until(/(?:(?<!\\)"|\{|\})/)
|
|
61
|
+
unless text
|
|
62
|
+
@scanner.terminate
|
|
63
|
+
return nil
|
|
64
|
+
end
|
|
65
|
+
matched_text += text
|
|
66
|
+
|
|
67
|
+
case @scanner.matched
|
|
68
|
+
when '}'
|
|
69
|
+
break
|
|
70
|
+
when '"'
|
|
71
|
+
text = @scanner.scan_until(/(?<!\\)"/)
|
|
72
|
+
unless text
|
|
73
|
+
@scanner.terminate
|
|
74
|
+
return nil
|
|
75
|
+
end
|
|
76
|
+
matched_text += text
|
|
77
|
+
else
|
|
78
|
+
matched_text += read_object
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
matched_text
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
require 'pdk'
|
|
2
|
+
|
|
3
|
+
module PDK
|
|
4
|
+
module Util
|
|
5
|
+
module PuppetStrings
|
|
6
|
+
class NoObjectError < StandardError; end
|
|
7
|
+
class RunError < StandardError; end
|
|
8
|
+
class NoGeneratorError < StandardError; end
|
|
9
|
+
|
|
10
|
+
# Runs Puppet for the purposes of generating puppet-strings output.
|
|
11
|
+
#
|
|
12
|
+
# @param *args [String] additional parameters to pass to puppet.
|
|
13
|
+
#
|
|
14
|
+
# @return [Hash{Symbol=>Object}] the result of the command execution.
|
|
15
|
+
def self.puppet(*args)
|
|
16
|
+
require 'pdk/cli/exec/command'
|
|
17
|
+
|
|
18
|
+
PDK::Util::Bundler.ensure_binstubs!('puppet')
|
|
19
|
+
|
|
20
|
+
argv = [File.join(PDK::Util.module_root, 'bin', 'puppet')] + args
|
|
21
|
+
argv.unshift(File.join(PDK::Util::RubyVersion.bin_path, 'ruby.exe')) if Gem.win_platform?
|
|
22
|
+
|
|
23
|
+
command = PDK::CLI::Exec::Command.new(*argv).tap do |c|
|
|
24
|
+
c.context = :module
|
|
25
|
+
c.add_spinner('Examining module contents')
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
command.execute!
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Generates and parses the JSON output from puppet-strings.
|
|
32
|
+
#
|
|
33
|
+
# @returns [Hash{String=>Object}] the parsed puppet-strings output.
|
|
34
|
+
#
|
|
35
|
+
# @raises [PDK::Util::PuppetStrings::RunError] if the puppet-strings
|
|
36
|
+
# command exits non-zero.
|
|
37
|
+
# @raises [PDK::Util::PuppetStrings::RunError] if the puppet-strings
|
|
38
|
+
# command outputs invalid JSON.
|
|
39
|
+
def self.generate_hash
|
|
40
|
+
result = puppet('strings', 'generate', '--format', 'json')
|
|
41
|
+
|
|
42
|
+
raise RunError, result[:stderr] unless result[:exit_code].zero?
|
|
43
|
+
|
|
44
|
+
JSON.parse(result[:stdout])
|
|
45
|
+
rescue JSON::ParserError => e
|
|
46
|
+
PDK.logger.debug(e)
|
|
47
|
+
raise RunError, 'Unable to parse puppet-strings output'
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Searches the puppet-strings result to find the definition of the named
|
|
51
|
+
# object.
|
|
52
|
+
#
|
|
53
|
+
# @param name [String] the name of the object definition to search for.
|
|
54
|
+
# If the object name is not prepended with the module name,
|
|
55
|
+
# "#{module_name}::#{object_name}" will also be search for.
|
|
56
|
+
#
|
|
57
|
+
# @returns [Array[PDK::Generate::PuppetObject, Hash{String=>Object}]] the
|
|
58
|
+
# appropriate generator class for the object as the first element and
|
|
59
|
+
# the puppet-strings description hash for the definition.
|
|
60
|
+
#
|
|
61
|
+
# @raises [PDK::Util::PuppetStrings::NoObjectError] if the named object
|
|
62
|
+
# can not be found in the puppet-strings output.
|
|
63
|
+
# @raises [PDK::Util::PuppetStrings::NoGeneratorError] if the named
|
|
64
|
+
# object does not have a corresponding PDK generator class.
|
|
65
|
+
def self.find_object(name)
|
|
66
|
+
module_name = PDK::Util.module_metadata['name'].rpartition('-').last
|
|
67
|
+
|
|
68
|
+
object_names = [name]
|
|
69
|
+
object_names << "#{module_name}::#{name}" unless name.start_with?("#{module_name}::")
|
|
70
|
+
|
|
71
|
+
known_objects = generate_hash
|
|
72
|
+
object_type = known_objects.keys.find do |obj_type|
|
|
73
|
+
known_objects[obj_type].any? { |obj| object_names.include?(obj['name']) }
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
raise NoObjectError if object_type.nil?
|
|
77
|
+
|
|
78
|
+
generator = find_generator(object_type)
|
|
79
|
+
|
|
80
|
+
raise NoGeneratorError, object_type if generator.nil?
|
|
81
|
+
|
|
82
|
+
[generator, known_objects[object_type].find { |obj| object_names.include?(obj['name']) }]
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Generate a list of all objects that PDK has a generator for.
|
|
86
|
+
#
|
|
87
|
+
# @returns [Array[Array[PDK::Generate::PuppetObject,
|
|
88
|
+
# Array[Hash{String=>Object}]]]] an associative array where the first
|
|
89
|
+
# element of each pair is the generator class and the second element of
|
|
90
|
+
# each pair is an array of description hashes from puppet-strings.
|
|
91
|
+
def self.all_objects
|
|
92
|
+
require 'pdk/generate'
|
|
93
|
+
|
|
94
|
+
generators = PDK::Generate.generators.select do |gen|
|
|
95
|
+
gen.const_defined?(:PUPPET_STRINGS_TYPE) && !gen::PUPPET_STRINGS_TYPE.nil?
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
known_objects = generate_hash
|
|
99
|
+
|
|
100
|
+
generators.map { |gen| [gen, known_objects[gen::PUPPET_STRINGS_TYPE]] }.reject do |_, obj|
|
|
101
|
+
obj.nil? || obj.empty?
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Evaluates the mapping of puppet-strings object type to PDK generator
|
|
106
|
+
# class.
|
|
107
|
+
#
|
|
108
|
+
# @param type [String] the object type as returned from puppet-strings.
|
|
109
|
+
#
|
|
110
|
+
# @returns [PDK:Generate::PuppetObject,nil] a child of
|
|
111
|
+
# PDK::Generate::PuppetObject or nil a suitable generator is not found.
|
|
112
|
+
#
|
|
113
|
+
# @example
|
|
114
|
+
# PDK::Util::PuppetStrings.find_generator('puppet_classes')
|
|
115
|
+
# => PDK::Generate::PuppetClass
|
|
116
|
+
def self.find_generator(type)
|
|
117
|
+
require 'pdk/generate'
|
|
118
|
+
|
|
119
|
+
PDK::Generate.generators.find do |gen|
|
|
120
|
+
gen.const_defined?(:PUPPET_STRINGS_TYPE) && type == gen::PUPPET_STRINGS_TYPE
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|