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
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
require 'pdk'
|
|
2
|
+
|
|
3
|
+
module PDK
|
|
4
|
+
module Util
|
|
5
|
+
class TemplateURI
|
|
6
|
+
SCP_PATTERN = %r{\A(?!\w+://)(?:(?<user>.+?)@)?(?<host>[^:/]+):(?<path>.+)\z}.freeze
|
|
7
|
+
|
|
8
|
+
PACKAGED_TEMPLATE_KEYWORD = 'pdk-default'.freeze
|
|
9
|
+
DEPRECATED_TEMPLATE_URL = 'https://github.com/puppetlabs/pdk-module-template'.freeze
|
|
10
|
+
PDK_TEMPLATE_URL = 'https://github.com/puppetlabs/pdk-templates'.freeze
|
|
11
|
+
|
|
12
|
+
LEGACY_PACKAGED_TEMPLATE_PATHS = {
|
|
13
|
+
'windows' => 'file:///C:/Program Files/Puppet Labs/DevelopmentKit/share/cache/pdk-templates.git',
|
|
14
|
+
'macos' => 'file:///opt/puppetlabs/pdk/share/cache/pdk-templates.git',
|
|
15
|
+
'linux' => 'file:///opt/puppetlabs/pdk/share/cache/pdk-templates.git'
|
|
16
|
+
}.freeze
|
|
17
|
+
|
|
18
|
+
# XXX Previously
|
|
19
|
+
# - template_uri used to get the string form of the uri when generating the module and written to pdk answers and metadata
|
|
20
|
+
# - template_path or deuri_path used for humans to see and commands to run
|
|
21
|
+
# - uri_path used only internally by the template selection code; move out
|
|
22
|
+
# - template_ref used by git checkout
|
|
23
|
+
attr_reader :uri
|
|
24
|
+
|
|
25
|
+
# input/output formats:
|
|
26
|
+
#
|
|
27
|
+
# file:///c:/foo (git clone location)
|
|
28
|
+
# c:/foo (shell paths)
|
|
29
|
+
# file:///c:/foo#main (only for metadata)
|
|
30
|
+
# c:/foo#main (only for metadata)
|
|
31
|
+
#
|
|
32
|
+
# non output formats:
|
|
33
|
+
#
|
|
34
|
+
# /c:/foo (internal use only)
|
|
35
|
+
# /c:/foo#main (internal use only)
|
|
36
|
+
#
|
|
37
|
+
def initialize(opts_or_uri)
|
|
38
|
+
require 'addressable'
|
|
39
|
+
# If a uri string is passed, skip the valid uri finding code.
|
|
40
|
+
@uri = case opts_or_uri
|
|
41
|
+
when self.class
|
|
42
|
+
opts_or_uri.uri
|
|
43
|
+
when String
|
|
44
|
+
begin
|
|
45
|
+
uri, ref = opts_or_uri.split('#', 2)
|
|
46
|
+
if PDK::Util::TemplateURI.packaged_template?(uri)
|
|
47
|
+
PDK::Util::TemplateURI.default_template_addressable_uri.tap { |default| default.fragment = ref unless ref.nil? || ref.empty? }
|
|
48
|
+
else
|
|
49
|
+
Addressable::URI.parse(opts_or_uri)
|
|
50
|
+
end
|
|
51
|
+
rescue Addressable::URI::InvalidURIError
|
|
52
|
+
raise PDK::CLI::FatalError, "PDK::Util::TemplateURI attempted initialization with a non-uri string: #{opts_or_uri}"
|
|
53
|
+
end
|
|
54
|
+
when Addressable::URI
|
|
55
|
+
opts_or_uri.dup
|
|
56
|
+
else
|
|
57
|
+
PDK::Util::TemplateURI.first_valid_uri(PDK::Util::TemplateURI.templates(opts_or_uri))
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def ==(other)
|
|
62
|
+
@uri == other.uri
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def bare_uri
|
|
66
|
+
PDK::Util::TemplateURI.bare_uri(@uri)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# This is the URI represented in a format suitable for writing to
|
|
70
|
+
# metadata.
|
|
71
|
+
#
|
|
72
|
+
# @returns String
|
|
73
|
+
def metadata_format
|
|
74
|
+
@metadata_format ||= if PDK::Util::TemplateURI.packaged_template?(bare_uri)
|
|
75
|
+
PDK::Util::TemplateURI.human_readable("pdk-default##{uri_fragment}")
|
|
76
|
+
else
|
|
77
|
+
PDK::Util::TemplateURI.human_readable(@uri.to_s)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
alias to_s metadata_format
|
|
81
|
+
alias to_str metadata_format
|
|
82
|
+
|
|
83
|
+
# Returns the fragment of the URI, of the default template's ref if one does not exist
|
|
84
|
+
# @returns String
|
|
85
|
+
# @api private
|
|
86
|
+
def uri_fragment
|
|
87
|
+
@uri.fragment || self.class.default_template_ref(self)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def uri_fragment=(fragment)
|
|
91
|
+
@uri.fragment = fragment
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def default?
|
|
95
|
+
bare_uri == PDK::Util::TemplateURI.bare_uri(PDK::Util::TemplateURI.default_template_addressable_uri)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def default_ref?
|
|
99
|
+
uri_fragment == self.class.default_template_ref(self)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def puppetlabs_template?
|
|
103
|
+
self.class.packaged_template?(bare_uri) || bare_uri == PDK_TEMPLATE_URL
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Class Methods
|
|
107
|
+
|
|
108
|
+
# Remove the fragment off of URI. Useful for removing the branch
|
|
109
|
+
# for Git based URIs
|
|
110
|
+
def self.bare_uri(uri)
|
|
111
|
+
require 'addressable'
|
|
112
|
+
|
|
113
|
+
if uri.is_a?(Addressable::URI) && uri.fragment
|
|
114
|
+
human_readable(uri.to_s.chomp("##{uri.fragment}"))
|
|
115
|
+
else
|
|
116
|
+
human_readable(uri.to_s)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# This is the path of the URI, suitable for accessing directly from the shell.
|
|
121
|
+
# @returns String
|
|
122
|
+
def shell_path
|
|
123
|
+
self.class.human_readable(@uri.path)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# @returns PDK::Util::TemplateURI
|
|
127
|
+
def self.default_template_uri
|
|
128
|
+
require 'pdk/util'
|
|
129
|
+
require 'addressable'
|
|
130
|
+
|
|
131
|
+
PDK::Util::TemplateURI.new(default_template_addressable_uri)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# @returns Addressable::URI
|
|
135
|
+
# @api private
|
|
136
|
+
def self.default_template_addressable_uri
|
|
137
|
+
require 'pdk/util'
|
|
138
|
+
require 'addressable'
|
|
139
|
+
|
|
140
|
+
if PDK::Util.package_install?
|
|
141
|
+
Addressable::URI.new(scheme: 'file', host: '', path: File.join(PDK::Util.package_cachedir, 'pdk-templates.git'))
|
|
142
|
+
else
|
|
143
|
+
Addressable::URI.parse(PDK_TEMPLATE_URL)
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# `C:...` urls are not URI-safe. They should be of the form `/C:...` to
|
|
148
|
+
# be URI-safe. scp-like urls like `user@host:/path` are not URI-safe
|
|
149
|
+
# either and so are subsequently converted to ssh:// URIs.
|
|
150
|
+
#
|
|
151
|
+
# @returns String
|
|
152
|
+
def self.uri_safe(string)
|
|
153
|
+
url = Gem.win_platform? && string =~ /^[a-zA-Z][|:]/ ? "/#{string}" : string
|
|
154
|
+
parse_scp_url(url)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# If the passed value is a URI-safe windows path such as `/C:...` then it
|
|
158
|
+
# should be changed to a human-friendly `C:...` form. Otherwise the
|
|
159
|
+
# passed value is left alone.
|
|
160
|
+
#
|
|
161
|
+
# @returns String
|
|
162
|
+
def self.human_readable(string)
|
|
163
|
+
Gem.win_platform? && string =~ %r{^/[a-zA-Z][|:]} ? string[1..] : string
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def self.parse_scp_url(url)
|
|
167
|
+
require 'pathname'
|
|
168
|
+
require 'addressable'
|
|
169
|
+
|
|
170
|
+
# Valid URIs to avoid catching:
|
|
171
|
+
# - absolute local paths
|
|
172
|
+
# - have :'s in paths when preceeded by a slash
|
|
173
|
+
# - have only digits following the : and preceeding a / or end-of-string that is 0-65535
|
|
174
|
+
# The last item is ambiguous in the case of scp/git paths vs. URI port
|
|
175
|
+
# numbers, but can be made unambiguous by making the form to
|
|
176
|
+
# ssh://git@github.com/1234/repo.git or
|
|
177
|
+
# ssh://git@github.com:1234/user/repo.git
|
|
178
|
+
scp_url = url.match(SCP_PATTERN)
|
|
179
|
+
return url unless Pathname.new(url).relative? && scp_url
|
|
180
|
+
|
|
181
|
+
uri = Addressable::URI.new(scheme: 'ssh', user: scp_url[:user], host: scp_url[:host], path: scp_url[:path])
|
|
182
|
+
PDK.logger.warn format('%{scp_uri} appears to be an SCP style URL; it will be converted to an RFC compliant URI: %{rfc_uri}', scp_uri: url, rfc_uri: uri.to_s)
|
|
183
|
+
|
|
184
|
+
uri.to_s
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# @return [Array<Hash{Symbol => Object}>] an array of hashes. Each hash
|
|
188
|
+
# contains 3 keys: :type contains a String that describes the template
|
|
189
|
+
# directory, :url contains a String with the URL to the template
|
|
190
|
+
# directory, and :allow_fallback contains a Boolean that specifies if
|
|
191
|
+
# the lookup process should proceed to the next template directory if
|
|
192
|
+
# the template file is not in this template directory.
|
|
193
|
+
def self.templates(opts)
|
|
194
|
+
require 'pdk/answer_file'
|
|
195
|
+
require 'pdk/util'
|
|
196
|
+
require 'addressable'
|
|
197
|
+
|
|
198
|
+
explicit_url = opts.fetch(:'template-url', nil)
|
|
199
|
+
explicit_ref = opts.fetch(:'template-ref', nil)
|
|
200
|
+
|
|
201
|
+
# 1. Get the CLI, metadata (or answers if no metadata), and default URIs
|
|
202
|
+
# 2. Construct the hash
|
|
203
|
+
if explicit_url
|
|
204
|
+
explicit_uri = Addressable::URI.parse(uri_safe(explicit_url))
|
|
205
|
+
explicit_uri.fragment = explicit_ref || default_template_ref(new(explicit_uri))
|
|
206
|
+
else
|
|
207
|
+
explicit_uri = nil
|
|
208
|
+
end
|
|
209
|
+
metadata_uri = if PDK::Util.module_root && PDK::Util::Filesystem.file?(File.join(PDK::Util.module_root, 'metadata.json')) && PDK::Util.module_metadata['template-url']
|
|
210
|
+
new(uri_safe(PDK::Util.module_metadata['template-url'])).uri
|
|
211
|
+
end
|
|
212
|
+
default_template_url = PDK.config.get_within_scopes('module_defaults.template-url')
|
|
213
|
+
answers_uri = if [PACKAGED_TEMPLATE_KEYWORD, DEPRECATED_TEMPLATE_URL].include?(default_template_url)
|
|
214
|
+
Addressable::URI.parse(default_template_uri)
|
|
215
|
+
elsif default_template_url
|
|
216
|
+
new(uri_safe(default_template_url)).uri
|
|
217
|
+
end
|
|
218
|
+
default_uri = default_template_uri.uri
|
|
219
|
+
default_uri.fragment = default_template_ref(default_template_uri)
|
|
220
|
+
|
|
221
|
+
ary = []
|
|
222
|
+
ary << { type: '--template-url', uri: explicit_uri, allow_fallback: false } if explicit_url
|
|
223
|
+
ary << { type: 'metadata.json', uri: metadata_uri, allow_fallback: true } if metadata_uri
|
|
224
|
+
ary << { type: 'PDK answers', uri: answers_uri, allow_fallback: true } if answers_uri
|
|
225
|
+
ary << { type: 'default', uri: default_uri, allow_fallback: false }
|
|
226
|
+
ary
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# @returns String
|
|
230
|
+
def self.default_template_ref(uri = nil)
|
|
231
|
+
require 'pdk/util'
|
|
232
|
+
require 'pdk/version'
|
|
233
|
+
|
|
234
|
+
return 'main' if PDK::Util.development_mode?
|
|
235
|
+
return PDK::TEMPLATE_REF if uri.nil?
|
|
236
|
+
|
|
237
|
+
uri = new(uri) unless uri.is_a?(self)
|
|
238
|
+
uri.default? ? PDK::TEMPLATE_REF : 'main'
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# @returns Addressable::URI
|
|
242
|
+
def self.first_valid_uri(templates_array)
|
|
243
|
+
# 1. Get the four sources of URIs
|
|
244
|
+
# 2. Pick the first non-nil URI
|
|
245
|
+
# 3. Error if the URI is not a valid git repo (missing directory or http 404)
|
|
246
|
+
# 4. Leave updating answers/metadata to other code
|
|
247
|
+
found_template = templates_array.find { |t| valid_template?(t) }
|
|
248
|
+
|
|
249
|
+
raise PDK::CLI::FatalError, 'Unable to find a valid module template to use.' if found_template.nil?
|
|
250
|
+
|
|
251
|
+
found_template[:uri]
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def self.valid_template?(template, context = PDK.context)
|
|
255
|
+
require 'addressable'
|
|
256
|
+
|
|
257
|
+
return false if template.nil? || !template.is_a?(Hash)
|
|
258
|
+
return false if template[:uri].nil? || !template[:uri].is_a?(Addressable::URI)
|
|
259
|
+
|
|
260
|
+
return true if PDK::Util::Git.repo?(bare_uri(template[:uri]))
|
|
261
|
+
|
|
262
|
+
path = human_readable(template[:uri].path)
|
|
263
|
+
if PDK::Util::Filesystem.directory?(path)
|
|
264
|
+
# We know that it's not a git repository, but it's a valid path on disk
|
|
265
|
+
begin
|
|
266
|
+
renderer = PDK::Template::Renderer.instance(path, template[:uri], context)
|
|
267
|
+
return !renderer.nil?
|
|
268
|
+
rescue StandardError
|
|
269
|
+
nil
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
raise PDK::CLI::FatalError, format('Unable to find a valid template at %{uri}', uri: template[:uri].to_s) unless template[:allow_fallback]
|
|
274
|
+
|
|
275
|
+
false
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def self.packaged_template?(path)
|
|
279
|
+
path == PACKAGED_TEMPLATE_KEYWORD || LEGACY_PACKAGED_TEMPLATE_PATHS.value?(path)
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
end
|
|
@@ -1,29 +1,11 @@
|
|
|
1
|
-
require 'pdk
|
|
2
|
-
require 'net/https'
|
|
3
|
-
require 'openssl'
|
|
4
|
-
require 'fileutils'
|
|
5
|
-
require 'pdk/util/filesystem'
|
|
1
|
+
require 'pdk'
|
|
6
2
|
|
|
7
3
|
module PDK
|
|
8
4
|
module Util
|
|
9
5
|
class VendoredFile
|
|
10
6
|
class DownloadError < StandardError; end
|
|
11
7
|
|
|
12
|
-
|
|
13
|
-
EOFError,
|
|
14
|
-
Errno::ECONNRESET,
|
|
15
|
-
Errno::EINVAL,
|
|
16
|
-
Errno::ECONNREFUSED,
|
|
17
|
-
Net::HTTPBadResponse,
|
|
18
|
-
Net::HTTPHeaderSyntaxError,
|
|
19
|
-
Net::ProtocolError,
|
|
20
|
-
Timeout::Error,
|
|
21
|
-
].freeze
|
|
22
|
-
|
|
23
|
-
attr_reader :file_name
|
|
24
|
-
attr_reader :url
|
|
25
|
-
|
|
26
|
-
include PDK::Util::Filesystem
|
|
8
|
+
attr_reader :file_name, :url
|
|
27
9
|
|
|
28
10
|
def initialize(file_name, url)
|
|
29
11
|
@file_name = file_name
|
|
@@ -31,56 +13,66 @@ module PDK
|
|
|
31
13
|
end
|
|
32
14
|
|
|
33
15
|
def read
|
|
34
|
-
|
|
35
|
-
|
|
16
|
+
require 'pdk/util'
|
|
17
|
+
require 'pdk/util/filesystem'
|
|
18
|
+
|
|
19
|
+
return PDK::Util::Filesystem.read_file(package_vendored_path) if PDK::Util.package_install?
|
|
20
|
+
return PDK::Util::Filesystem.read_file(gem_vendored_path) if PDK::Util::Filesystem.file?(gem_vendored_path)
|
|
36
21
|
|
|
37
22
|
content = download_file
|
|
38
23
|
|
|
39
24
|
# TODO: should only write if it's valid JSON
|
|
40
25
|
# TODO: need a way to invalidate if out of date
|
|
41
|
-
|
|
42
|
-
write_file(gem_vendored_path, content)
|
|
26
|
+
PDK::Util::Filesystem.mkdir_p(File.dirname(gem_vendored_path))
|
|
27
|
+
PDK::Util::Filesystem.write_file(gem_vendored_path, content)
|
|
43
28
|
content
|
|
44
29
|
end
|
|
45
30
|
|
|
46
31
|
private
|
|
47
32
|
|
|
48
33
|
def download_file
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
34
|
+
require 'uri'
|
|
35
|
+
require 'net/https'
|
|
36
|
+
require 'openssl'
|
|
37
|
+
|
|
38
|
+
http_errors = [
|
|
39
|
+
EOFError,
|
|
40
|
+
Errno::ECONNRESET,
|
|
41
|
+
Errno::EINVAL,
|
|
42
|
+
Errno::ECONNREFUSED,
|
|
43
|
+
Net::HTTPBadResponse,
|
|
44
|
+
Net::HTTPHeaderSyntaxError,
|
|
45
|
+
Net::ProtocolError,
|
|
46
|
+
Timeout::Error
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
PDK.logger.debug format('%{file_name} was not found in the cache, downloading it from %{url}.', file_name: file_name, url: url)
|
|
53
50
|
|
|
54
51
|
uri = URI.parse(url)
|
|
55
52
|
http = Net::HTTP.new(uri.host, uri.port)
|
|
56
53
|
http.use_ssl = true
|
|
57
|
-
# TODO: Get rid of this
|
|
58
|
-
# https://github.com/glennsarti/dev-tools/blob/master/RubyCerts.ps1
|
|
54
|
+
# TODO: Get rid of this
|
|
59
55
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if Gem.win_platform?
|
|
60
56
|
request = Net::HTTP::Get.new(uri.request_uri)
|
|
61
57
|
response = http.request(request)
|
|
62
58
|
|
|
63
|
-
unless response.code == '200'
|
|
64
|
-
raise DownloadError, _('Unable to download %{url}. %{code}: %{message}.') % {
|
|
65
|
-
url: url,
|
|
66
|
-
code: response.code,
|
|
67
|
-
message: response.message,
|
|
68
|
-
}
|
|
69
|
-
end
|
|
59
|
+
raise DownloadError, format('Unable to download %{url}. %{code}: %{message}.', url: url, code: response.code, message: response.message) unless response.code == '200'
|
|
70
60
|
|
|
71
61
|
response.body
|
|
72
|
-
rescue *
|
|
73
|
-
raise DownloadError,
|
|
74
|
-
url: url,
|
|
75
|
-
error: e,
|
|
76
|
-
}
|
|
62
|
+
rescue *http_errors => e
|
|
63
|
+
raise DownloadError, format('Unable to download %{url}. Check internet connectivity and try again. %{error}', url: url, error: e)
|
|
77
64
|
end
|
|
78
65
|
|
|
79
66
|
def package_vendored_path
|
|
67
|
+
require 'pdk/util'
|
|
68
|
+
|
|
80
69
|
@package_vendored_path ||= File.join(PDK::Util.package_cachedir, file_name)
|
|
81
70
|
end
|
|
82
71
|
|
|
83
72
|
def gem_vendored_path
|
|
73
|
+
require 'pdk/util'
|
|
74
|
+
require 'pdk/version'
|
|
75
|
+
|
|
84
76
|
@gem_vendored_path ||= File.join(PDK::Util.cachedir, PDK::VERSION, file_name)
|
|
85
77
|
end
|
|
86
78
|
end
|
data/lib/pdk/util/version.rb
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
require 'pdk
|
|
2
|
-
require 'pdk/cli/exec'
|
|
3
|
-
require 'pdk/util/git'
|
|
4
|
-
require 'pdk/logger'
|
|
1
|
+
require 'pdk'
|
|
5
2
|
|
|
6
3
|
module PDK
|
|
7
4
|
module Util
|
|
8
5
|
module Version
|
|
9
6
|
def self.version_string
|
|
7
|
+
require 'pdk/version'
|
|
8
|
+
|
|
10
9
|
"#{PDK::VERSION} #{pdk_ref}".strip.freeze
|
|
11
10
|
end
|
|
12
11
|
|
|
@@ -16,8 +15,8 @@ module PDK
|
|
|
16
15
|
end
|
|
17
16
|
|
|
18
17
|
def self.pkg_sha
|
|
19
|
-
if version_file &&
|
|
20
|
-
ver =
|
|
18
|
+
if version_file && PDK::Util::Filesystem.exist?(version_file)
|
|
19
|
+
ver = PDK::Util::Filesystem.read_file(version_file)
|
|
21
20
|
sha = ver.strip.split('.')[5] unless ver.nil?
|
|
22
21
|
end
|
|
23
22
|
|
|
@@ -25,15 +24,17 @@ module PDK
|
|
|
25
24
|
end
|
|
26
25
|
|
|
27
26
|
def self.git_ref
|
|
28
|
-
|
|
27
|
+
require 'pdk/util/git'
|
|
28
|
+
source_git_dir = File.join(PDK::Util::Filesystem.expand_path('../../..', File.dirname(__FILE__)), '.git')
|
|
29
29
|
|
|
30
|
-
return
|
|
30
|
+
return unless PDK::Util::Filesystem.directory?(source_git_dir)
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
return ref_result[:stdout].strip if ref_result[:exit_code].zero?
|
|
32
|
+
PDK::Util::Git.describe(source_git_dir)
|
|
34
33
|
end
|
|
35
34
|
|
|
36
35
|
def self.version_file
|
|
36
|
+
require 'pdk/util'
|
|
37
|
+
|
|
37
38
|
# FIXME: this gets called a LOT and doesn't currently get cached
|
|
38
39
|
PDK::Util.find_upwards('PDK_VERSION', File.dirname(__FILE__))
|
|
39
40
|
end
|
|
@@ -1,57 +1,87 @@
|
|
|
1
1
|
require 'ffi'
|
|
2
2
|
require 'pdk/util/windows/string'
|
|
3
3
|
|
|
4
|
-
module PDK
|
|
5
|
-
module
|
|
6
|
-
|
|
4
|
+
module PDK
|
|
5
|
+
module Util
|
|
6
|
+
module Windows
|
|
7
|
+
module APITypes
|
|
8
|
+
module ::FFI
|
|
9
|
+
module Library
|
|
10
|
+
def attach_function_private(*args)
|
|
11
|
+
attach_function(*args)
|
|
12
|
+
private args[0]
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
7
16
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
17
|
+
module ::FFI
|
|
18
|
+
class Pointer
|
|
19
|
+
def self.from_string_to_wide_string(str, &_block)
|
|
20
|
+
str = PDK::Util::Windows::String.wide_string(str)
|
|
21
|
+
FFI::MemoryPointer.new(:byte, str.bytesize) do |ptr|
|
|
22
|
+
# uchar here is synonymous with byte
|
|
23
|
+
ptr.put_array_of_uchar(0, str.bytes.to_a)
|
|
11
24
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
str = PDK::Util::Windows::String.wide_string(str)
|
|
15
|
-
FFI::MemoryPointer.new(:byte, str.bytesize) do |ptr|
|
|
16
|
-
# uchar here is synonymous with byte
|
|
17
|
-
ptr.put_array_of_uchar(0, str.bytes.to_a)
|
|
25
|
+
yield ptr
|
|
26
|
+
end
|
|
18
27
|
|
|
19
|
-
|
|
20
|
-
|
|
28
|
+
# ptr has already had free called, so nothing to return
|
|
29
|
+
nil
|
|
30
|
+
end
|
|
21
31
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
32
|
+
def read_wide_string(char_length, dst_encoding = Encoding::UTF_8, encode_options = {})
|
|
33
|
+
# char_length is number of wide chars (typically excluding NULLs), *not* bytes
|
|
34
|
+
str = get_bytes(0, char_length * 2).force_encoding('UTF-16LE')
|
|
35
|
+
str.encode(dst_encoding, str.encoding, **encode_options)
|
|
36
|
+
rescue StandardError => e
|
|
37
|
+
PDK.logger.debug format('Unable to convert value %{string} to encoding %{encoding} due to %{error}', string: str.dump, encoding: dst_encoding, error: e.inspect)
|
|
38
|
+
raise
|
|
39
|
+
end
|
|
25
40
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
error: e.inspect,
|
|
35
|
-
}
|
|
36
|
-
raise
|
|
37
|
-
end
|
|
38
|
-
end
|
|
41
|
+
def read_arbitrary_wide_string_up_to(max_char_length = 512, null_terminator = :single_null, encode_options = {})
|
|
42
|
+
unless [:single_null, :double_null].include?(null_terminator)
|
|
43
|
+
raise ArgumentError,
|
|
44
|
+
format('Unable to read wide strings with %{null_terminator} terminal nulls', null_terminator: null_terminator)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
terminator_width = null_terminator == :single_null ? 1 : 2
|
|
48
|
+
reader_method = null_terminator == :single_null ? :get_uint16 : :get_uint32
|
|
39
49
|
|
|
40
|
-
|
|
41
|
-
|
|
50
|
+
# Look for the null_terminator; if found, read up to that null
|
|
51
|
+
# (exclusive)
|
|
52
|
+
(0...max_char_length - terminator_width).each do |i|
|
|
53
|
+
return read_wide_string(i, Encoding::UTF_8, encode_options) if send(reader_method, (i * 2)).zero?
|
|
54
|
+
end
|
|
42
55
|
|
|
43
|
-
|
|
44
|
-
|
|
56
|
+
# String is longer than the max, read just up to the max
|
|
57
|
+
read_wide_string(max_char_length, Encoding::UTF_8, encode_options)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
45
61
|
|
|
46
|
-
|
|
47
|
-
|
|
62
|
+
# FFI Types
|
|
63
|
+
# https://github.com/ffi/ffi/wiki/Types
|
|
48
64
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
65
|
+
# Windows - Common Data Types
|
|
66
|
+
# https://msdn.microsoft.com/en-us/library/cc230309.aspx
|
|
67
|
+
|
|
68
|
+
# Windows Data Types
|
|
69
|
+
# https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx
|
|
70
|
+
|
|
71
|
+
FFI.typedef :uint32, :dword
|
|
72
|
+
# buffer_inout is similar to pointer (platform specific), but optimized for buffers
|
|
73
|
+
FFI.typedef :buffer_inout, :lpwstr
|
|
74
|
+
# buffer_in is similar to pointer (platform specific), but optimized for CONST read only buffers
|
|
75
|
+
FFI.typedef :buffer_in, :lpcwstr
|
|
76
|
+
# 8 bits per byte
|
|
77
|
+
FFI.typedef :uchar, :byte
|
|
78
|
+
FFI.typedef :uint16, :wchar
|
|
79
|
+
|
|
80
|
+
# FFI bool can be only 1 byte at times,
|
|
81
|
+
# Win32 BOOL is a signed int, and is always 4 bytes, even on x64
|
|
82
|
+
# https://blogs.msdn.com/b/oldnewthing/archive/2011/03/28/10146459.aspx
|
|
83
|
+
FFI.typedef :int32, :win32_bool
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
57
87
|
end
|
|
@@ -1,36 +1,40 @@
|
|
|
1
1
|
require 'pdk/util/windows'
|
|
2
2
|
|
|
3
|
-
module PDK
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
module PDK
|
|
4
|
+
module Util
|
|
5
|
+
module Windows
|
|
6
|
+
module File
|
|
7
|
+
require 'ffi'
|
|
8
|
+
extend FFI::Library
|
|
9
|
+
extend PDK::Util::Windows::String
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
def get_long_pathname(path)
|
|
12
|
+
converted = ''
|
|
13
|
+
FFI::Pointer.from_string_to_wide_string(path) do |path_ptr|
|
|
14
|
+
# includes terminating NULL
|
|
15
|
+
buffer_size = GetLongPathNameW(path_ptr, FFI::Pointer::NULL, 0)
|
|
16
|
+
FFI::MemoryPointer.new(:wchar, buffer_size) do |converted_ptr|
|
|
17
|
+
raise 'Failed to call GetLongPathName' if GetLongPathNameW(path_ptr, converted_ptr, buffer_size) == PDK::Util::Windows::WIN32_FALSE
|
|
18
|
+
|
|
19
|
+
converted = converted_ptr.read_wide_string(buffer_size - 1)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
converted
|
|
16
24
|
end
|
|
25
|
+
module_function :get_long_pathname
|
|
26
|
+
|
|
27
|
+
ffi_convention :stdcall
|
|
17
28
|
|
|
18
|
-
|
|
29
|
+
# https://msdn.microsoft.com/en-us/library/windows/desktop/aa364980(v=vs.85).aspx
|
|
30
|
+
# DWORD WINAPI GetLongPathName(
|
|
31
|
+
# _In_ LPCTSTR lpszShortPath,
|
|
32
|
+
# _Out_ LPTSTR lpszLongPath,
|
|
33
|
+
# _In_ DWORD cchBuffer
|
|
34
|
+
# );
|
|
35
|
+
ffi_lib :kernel32
|
|
36
|
+
attach_function :GetLongPathNameW, [:lpcwstr, :lpwstr, :dword], :dword
|
|
19
37
|
end
|
|
20
38
|
end
|
|
21
|
-
|
|
22
|
-
converted
|
|
23
39
|
end
|
|
24
|
-
module_function :get_long_pathname
|
|
25
|
-
|
|
26
|
-
ffi_convention :stdcall
|
|
27
|
-
|
|
28
|
-
# https://msdn.microsoft.com/en-us/library/windows/desktop/aa364980(v=vs.85).aspx
|
|
29
|
-
# DWORD WINAPI GetLongPathName(
|
|
30
|
-
# _In_ LPCTSTR lpszShortPath,
|
|
31
|
-
# _Out_ LPTSTR lpszLongPath,
|
|
32
|
-
# _In_ DWORD cchBuffer
|
|
33
|
-
# );
|
|
34
|
-
ffi_lib :kernel32
|
|
35
|
-
attach_function :GetLongPathNameW, [:lpcwstr, :lpwstr, :dword], :dword
|
|
36
40
|
end
|