vcpkg_pipeline 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/vpl +20 -0
- data/lib/vcpkg_pipeline/command/new.rb +56 -0
- data/lib/vcpkg_pipeline/command/publish.rb +45 -0
- data/lib/vcpkg_pipeline/command/scan/all.rb +42 -0
- data/lib/vcpkg_pipeline/command/scan/branch.rb +38 -0
- data/lib/vcpkg_pipeline/command/scan/name.rb +38 -0
- data/lib/vcpkg_pipeline/command/scan/release.rb +38 -0
- data/lib/vcpkg_pipeline/command/scan/remote.rb +38 -0
- data/lib/vcpkg_pipeline/command/scan/version.rb +38 -0
- data/lib/vcpkg_pipeline/command/scan.rb +25 -0
- data/lib/vcpkg_pipeline/command/update/all.rb +43 -0
- data/lib/vcpkg_pipeline/command/update/cmake.rb +41 -0
- data/lib/vcpkg_pipeline/command/update/git.rb +38 -0
- data/lib/vcpkg_pipeline/command/update/spec.rb +39 -0
- data/lib/vcpkg_pipeline/command/update/vcport.rb +38 -0
- data/lib/vcpkg_pipeline/command/update.rb +23 -0
- data/lib/vcpkg_pipeline/command.rb +122 -0
- data/lib/vcpkg_pipeline/core/log.rb +20 -0
- data/lib/vcpkg_pipeline/core/scanner.rb +29 -0
- data/lib/vcpkg_pipeline/core/spec.rb +89 -0
- data/lib/vcpkg_pipeline/core/updater.rb +69 -0
- data/lib/vcpkg_pipeline/extension/cmake_vpl.rb +78 -0
- data/lib/vcpkg_pipeline/extension/dir_vpl.rb +33 -0
- data/lib/vcpkg_pipeline/extension/git_vpl.rb +43 -0
- data/lib/vcpkg_pipeline/extension/string_vpl.rb +8 -0
- data/lib/vcpkg_pipeline/extension/vcpkg_vpl.rb +41 -0
- data/lib/vcpkg_pipeline/extension/vcport_vpl.rb +128 -0
- data/lib/vcpkg_pipeline.rb +6 -0
- metadata +131 -0
@@ -0,0 +1,122 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'claide'
|
4
|
+
|
5
|
+
module VPL
|
6
|
+
# VPL::Command
|
7
|
+
class Command < CLAide::Command
|
8
|
+
require 'vcpkg_pipeline/command/new'
|
9
|
+
require 'vcpkg_pipeline/command/scan'
|
10
|
+
require 'vcpkg_pipeline/command/update'
|
11
|
+
require 'vcpkg_pipeline/command/publish'
|
12
|
+
|
13
|
+
self.abstract_command = true
|
14
|
+
self.command = 'vpl'
|
15
|
+
self.description = 'vcpkg-Pipeline 是 vcpkg 的流水线工具'
|
16
|
+
|
17
|
+
def self.options
|
18
|
+
[
|
19
|
+
['--help', '展示改命令的介绍面板']
|
20
|
+
]
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.options_extension
|
24
|
+
options = []
|
25
|
+
options_extension_hash.each do |key, options_extension|
|
26
|
+
options_extension.each do |option_extension|
|
27
|
+
options << [option_extension.first.gsub(/(--)(.*)/, "\\1#{key}-\\2"), option_extension.last]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
options
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.options_extension_hash
|
34
|
+
Hash[]
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.run(argv)
|
38
|
+
ensure_not_root_or_allowed! argv
|
39
|
+
verify_minimum_git_version!
|
40
|
+
verify_xcode_license_approved!
|
41
|
+
|
42
|
+
super(argv)
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# 确保root用户
|
47
|
+
#
|
48
|
+
# @return [void]
|
49
|
+
#
|
50
|
+
def self.ensure_not_root_or_allowed!(argv, uid = Process.uid, is_windows = Gem.win_platform?)
|
51
|
+
root_allowed = argv.include?('--allow-root')
|
52
|
+
help! 'You cannot run vcpkg-Pipeline as root' unless root_allowed || uid != 0 || is_windows
|
53
|
+
end
|
54
|
+
|
55
|
+
# 读取Git版本号, 返回一个新的 {Gem::Version} 实例
|
56
|
+
#
|
57
|
+
# @return [Gem::Version]
|
58
|
+
#
|
59
|
+
def self.git_version
|
60
|
+
raw_version = `git version`
|
61
|
+
unless (match = raw_version.scan(/\d+\.\d+\.\d+/).first)
|
62
|
+
raise "Failed to extract git version from `git --version` (#{raw_version.inspect})"
|
63
|
+
end
|
64
|
+
|
65
|
+
Gem::Version.new(match)
|
66
|
+
end
|
67
|
+
|
68
|
+
# 检查Git版本号是否低于 1.8.5
|
69
|
+
#
|
70
|
+
# @raise Git版本号低于 1.8.5
|
71
|
+
#
|
72
|
+
# @return [void]
|
73
|
+
#
|
74
|
+
def self.verify_minimum_git_version!
|
75
|
+
return unless git_version < Gem::Version.new('1.8.5')
|
76
|
+
|
77
|
+
raise 'You need at least git version 1.8.5 to use vcpkg-Pipeline'
|
78
|
+
end
|
79
|
+
|
80
|
+
#
|
81
|
+
# 检查xcode许可是否被批准
|
82
|
+
#
|
83
|
+
# @return [void]
|
84
|
+
#
|
85
|
+
def self.verify_xcode_license_approved!
|
86
|
+
return unless `/usr/bin/xcrun clang 2>&1` =~ /license/ && !$?.success?
|
87
|
+
|
88
|
+
raise 'You have not agreed to the Xcode license, which ' \
|
89
|
+
'you must do to use vcpkg. Agree to the license by running: ' \
|
90
|
+
'`xcodebuild -license`'
|
91
|
+
end
|
92
|
+
|
93
|
+
def initialize(argv)
|
94
|
+
@argv_extension = {}
|
95
|
+
self.class.options_extension_hash.each_key do |key|
|
96
|
+
@argv_extension[key] = []
|
97
|
+
self.class.options.each do |option|
|
98
|
+
name = option.first
|
99
|
+
next unless name.include?(key)
|
100
|
+
|
101
|
+
is_option = name.include? '='
|
102
|
+
if is_option
|
103
|
+
option = name.gsub(/(--)(.*)(=.*)/, '\\2')
|
104
|
+
value = argv.option(option, '')
|
105
|
+
unless value.empty?
|
106
|
+
@argv_extension[key] << name.gsub(/(--.*=)(.*)/, "\\1#{value}").gsub("#{key}-",
|
107
|
+
'')
|
108
|
+
end
|
109
|
+
else
|
110
|
+
flag = name.gsub(/(--)(.*)/, '\\2')
|
111
|
+
value = argv.flag?(flag)
|
112
|
+
@argv_extension[key] << name.gsub("#{key}-", '') if value
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
super
|
118
|
+
end
|
119
|
+
|
120
|
+
attr_reader :argv_extension
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# VPL
|
4
|
+
module VPL
|
5
|
+
def self.attribute_str(msg, type)
|
6
|
+
"\n\033[#{type}m#{msg}\033[0m\n"
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.title(msg)
|
10
|
+
puts attribute_str("-- #{msg} --", 44)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.info(msg)
|
14
|
+
puts attribute_str(msg, 46)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.error(msg)
|
18
|
+
raise attribute_str("Error: #{msg}!", 41)
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'git'
|
4
|
+
|
5
|
+
require 'vcpkg_pipeline/extension/cmake_vpl'
|
6
|
+
require 'vcpkg_pipeline/extension/vcport_vpl'
|
7
|
+
require 'vcpkg_pipeline/extension/vcpkg_vpl'
|
8
|
+
require 'vcpkg_pipeline/extension/git_vpl'
|
9
|
+
|
10
|
+
require 'vcpkg_pipeline/core/spec'
|
11
|
+
|
12
|
+
module VPL
|
13
|
+
# VPL::Scanner
|
14
|
+
class Scanner
|
15
|
+
attr_accessor :path, :spec, :git, :cmake, :vcport
|
16
|
+
|
17
|
+
def initialize(path)
|
18
|
+
@path = path
|
19
|
+
@spec = Spec.load(path)
|
20
|
+
@cmake = CMake.open(path)
|
21
|
+
@vcport = VCPort.open(path)
|
22
|
+
@git = Git.open(path)
|
23
|
+
end
|
24
|
+
|
25
|
+
def scan_spec
|
26
|
+
@spec = Spec.load(path)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'vcpkg_pipeline/extension/vcpkg_vpl'
|
4
|
+
|
5
|
+
require 'vcpkg_pipeline/core/log'
|
6
|
+
|
7
|
+
module VPL
|
8
|
+
# VPL::Spec
|
9
|
+
class Spec
|
10
|
+
# spec file
|
11
|
+
attr_accessor :path, :content_path, :content
|
12
|
+
|
13
|
+
# port info
|
14
|
+
attr_accessor :name, :version, :user, :homepage, :description, :dependencies
|
15
|
+
|
16
|
+
# dist info
|
17
|
+
attr_accessor :sources, :disturl
|
18
|
+
|
19
|
+
def self.eval_vplspec(content, content_path)
|
20
|
+
instance_eval(content)
|
21
|
+
rescue RescueException => e
|
22
|
+
VPL.error("Invalid `#{content_path.basename}` file: #{e.message}")
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.load(path)
|
26
|
+
content_path_list = Dir["#{path}/*.vplspec"]
|
27
|
+
VPL.error('未找到或存在多个 *.vplspec 文件') if content_path_list.empty? || content_path_list.count > 1
|
28
|
+
content_path = content_path_list.first
|
29
|
+
content = File.read(content_path)
|
30
|
+
|
31
|
+
spec = eval_vplspec(content, content_path)
|
32
|
+
spec.path = path
|
33
|
+
spec.content_path = content_path
|
34
|
+
spec.content = content
|
35
|
+
spec
|
36
|
+
end
|
37
|
+
|
38
|
+
def initialize
|
39
|
+
yield self if block_given?
|
40
|
+
end
|
41
|
+
|
42
|
+
def distfile_name
|
43
|
+
"#{name}-#{version}.zip"
|
44
|
+
end
|
45
|
+
|
46
|
+
def distfile_package(output_path = nil)
|
47
|
+
output_path ||= '.'
|
48
|
+
distfile_path = "#{output_path}/#{distfile_name}"
|
49
|
+
`zip #{distfile_path} #{sources.join(' ')}`
|
50
|
+
if File.exist? distfile_path
|
51
|
+
VPL.info("Dist包 打包成功: #{distfile_path}")
|
52
|
+
else
|
53
|
+
VPL.error("Dist包 打包失败: #{distfile_path}")
|
54
|
+
end
|
55
|
+
VCPkg.hash(distfile_path)
|
56
|
+
end
|
57
|
+
|
58
|
+
def write(property, value)
|
59
|
+
VPL.info("写入 #{File.basename(@content_path)} : #{property} = #{value}")
|
60
|
+
|
61
|
+
new_content = @content.gsub!(/(.*.#{property}.*=.*)('.*')/, "\\1'#{value}'")
|
62
|
+
File.write(@content_path, new_content)
|
63
|
+
end
|
64
|
+
|
65
|
+
def version_increased
|
66
|
+
versions = @version.split('.')
|
67
|
+
|
68
|
+
new_version_last = (versions.last.to_i + 1).to_s
|
69
|
+
versions.pop
|
70
|
+
versions.push(new_version_last)
|
71
|
+
|
72
|
+
versions.join('.')
|
73
|
+
end
|
74
|
+
|
75
|
+
def version_update(new_version = nil)
|
76
|
+
new_version ||= version_increased
|
77
|
+
write('version', new_version)
|
78
|
+
end
|
79
|
+
|
80
|
+
def to_s
|
81
|
+
"#{@name} (#{@version})\
|
82
|
+
\nuser: #{@user}\
|
83
|
+
\nhomepage: #{@homepage}\
|
84
|
+
\ndescription: #{@description}\
|
85
|
+
\nsources: #{@sources}\
|
86
|
+
\ndependencies: #{@dependencies}"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'vcpkg_pipeline/extension/vcpkg_vpl'
|
4
|
+
|
5
|
+
require 'vcpkg_pipeline/core/scanner'
|
6
|
+
|
7
|
+
module VPL
|
8
|
+
# VPL::Updater
|
9
|
+
class Updater
|
10
|
+
attr_accessor :path, :scanner
|
11
|
+
|
12
|
+
def initialize(path)
|
13
|
+
@path = path
|
14
|
+
@scanner = Scanner.new(path)
|
15
|
+
end
|
16
|
+
|
17
|
+
def update_spec(version = nil)
|
18
|
+
@scanner.spec.version_update(version)
|
19
|
+
@scanner.scan_spec
|
20
|
+
end
|
21
|
+
|
22
|
+
def update_cmake
|
23
|
+
@scanner.cmake.version_update(
|
24
|
+
@scanner.spec.version
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
def update_vcport_vcpkg
|
29
|
+
vcpkg = @scanner.vcport.vcpkg
|
30
|
+
vcpkg.version_update(@scanner.spec.version)
|
31
|
+
VCPkg.format(vcpkg.content_path)
|
32
|
+
end
|
33
|
+
|
34
|
+
def update_vcport_portfile(output_path = nil)
|
35
|
+
distfile_hash = @scanner.spec.distfile_package(output_path)
|
36
|
+
@scanner.vcport.portfile.download_distfile_update(
|
37
|
+
@scanner.spec.disturl,
|
38
|
+
@scanner.spec.distfile_name,
|
39
|
+
distfile_hash
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def update_vcport(output_path = nil)
|
44
|
+
update_vcport_vcpkg
|
45
|
+
update_vcport_portfile(output_path)
|
46
|
+
end
|
47
|
+
|
48
|
+
def update_git
|
49
|
+
@scanner.git.quick_push(
|
50
|
+
@scanner.spec.version
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
def update_all(version = nil, output_path = nil)
|
55
|
+
@scanner.git.reset
|
56
|
+
|
57
|
+
update_spec(version)
|
58
|
+
@scanner.git.add('*.vplspec')
|
59
|
+
update_cmake
|
60
|
+
@scanner.git.add('CMakeLists.txt')
|
61
|
+
update_vcport(output_path)
|
62
|
+
@scanner.git.add('vcport')
|
63
|
+
|
64
|
+
@scanner.git.commit(@scanner.cmake.version)
|
65
|
+
|
66
|
+
update_git
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'vcpkg_pipeline/extension/string_vpl'
|
4
|
+
require 'vcpkg_pipeline/extension/dir_vpl'
|
5
|
+
|
6
|
+
require 'vcpkg_pipeline/core/log'
|
7
|
+
|
8
|
+
# CMake
|
9
|
+
module CMake
|
10
|
+
def self.open(path)
|
11
|
+
CMake::Base.new(path)
|
12
|
+
end
|
13
|
+
|
14
|
+
# CMake::Base
|
15
|
+
class Base
|
16
|
+
attr_accessor :path, :content_path, :content, :project, :name, :version
|
17
|
+
|
18
|
+
def initialize(path)
|
19
|
+
@path = path
|
20
|
+
@content_path = "#{path}/CMakeLists.txt"
|
21
|
+
|
22
|
+
VPL.error("#{@content_path} Not Found") unless File.exist? @content_path
|
23
|
+
@content = File.read(@content_path)
|
24
|
+
|
25
|
+
parse_content(@content)
|
26
|
+
end
|
27
|
+
|
28
|
+
def parse_content(content)
|
29
|
+
content.each_line(')') { |piece| parse_project(piece) }
|
30
|
+
end
|
31
|
+
|
32
|
+
def parse_project(piece)
|
33
|
+
return unless piece.include? 'project'
|
34
|
+
|
35
|
+
@project = piece
|
36
|
+
|
37
|
+
clean_project = piece.clean
|
38
|
+
parse_project_name(clean_project)
|
39
|
+
parse_project_version(clean_project)
|
40
|
+
end
|
41
|
+
|
42
|
+
def parse_project_name(clean_project)
|
43
|
+
regex_name = /project \( ([^ ]*) /
|
44
|
+
regex_name.match(clean_project)
|
45
|
+
@name = Regexp.last_match(1)
|
46
|
+
end
|
47
|
+
|
48
|
+
def parse_project_version(clean_project)
|
49
|
+
regex_version = /VERSION ([^ ]*) /
|
50
|
+
regex_version.match(clean_project)
|
51
|
+
@version = Regexp.last_match(1)
|
52
|
+
end
|
53
|
+
|
54
|
+
def version_increased
|
55
|
+
regex_version = /([^.]*)\.([^.]*)\.([^.]*)\.*([^.]*)/
|
56
|
+
regex_version.match(@version)
|
57
|
+
|
58
|
+
new_patch = Regexp.last_match(3).to_i + 1
|
59
|
+
"#{Regexp.last_match(1)}.#{Regexp.last_match(2)}.#{new_patch}#{Regexp.last_match(4)}"
|
60
|
+
end
|
61
|
+
|
62
|
+
def version_update(new_version = nil)
|
63
|
+
new_version ||= version_increased
|
64
|
+
|
65
|
+
new_project = @project.sub(@version, new_version)
|
66
|
+
new_content = @content.sub(@project, new_project)
|
67
|
+
File.write(@content_path, new_content)
|
68
|
+
|
69
|
+
@content = new_content
|
70
|
+
@project = new_project
|
71
|
+
@version = new_version
|
72
|
+
end
|
73
|
+
|
74
|
+
def to_s
|
75
|
+
"#{name}-#{version}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Dir
|
4
|
+
class Dir
|
5
|
+
def reset(path)
|
6
|
+
return unless File.directory? path
|
7
|
+
|
8
|
+
`rm -fr #{path}`
|
9
|
+
`mkdir #{path}`
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.replace_content(path, replacements)
|
13
|
+
content = File.read(path)
|
14
|
+
replacements.each do |find, replace|
|
15
|
+
content = content.gsub(find, replace)
|
16
|
+
end
|
17
|
+
File.write(path, content)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.replace_all(path, replacements)
|
21
|
+
Dir["#{path}/*"].each do |subpath|
|
22
|
+
subpath_rpl = subpath
|
23
|
+
replacements.each { |find, replace| subpath_rpl = subpath_rpl.gsub(find, replace)}
|
24
|
+
File.rename(subpath, subpath_rpl)
|
25
|
+
|
26
|
+
if File.directory? subpath_rpl
|
27
|
+
replace_all(subpath_rpl, replacements)
|
28
|
+
else
|
29
|
+
replace_content(subpath_rpl, replacements)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'git'
|
4
|
+
|
5
|
+
require 'vcpkg_pipeline/core/log'
|
6
|
+
|
7
|
+
module Git
|
8
|
+
# Git::Base
|
9
|
+
class Base
|
10
|
+
def current_branch
|
11
|
+
branches.current.first
|
12
|
+
end
|
13
|
+
|
14
|
+
def quick_push_tag(has_tag)
|
15
|
+
push(remote, current_branch, has_tag)
|
16
|
+
VPL.info("Git上传 #{remote} #{current_branch} #{new_version}")
|
17
|
+
end
|
18
|
+
|
19
|
+
def quick_push(new_tag = nil)
|
20
|
+
return unless ENV['Release']
|
21
|
+
|
22
|
+
has_tag = !new_tag.empty?
|
23
|
+
if has_tag
|
24
|
+
tags.each { |tag| VPL.error("当前版本 #{new_tag} 已发布, 请尝试其他版本号") if tag.name.eql? new_tag }
|
25
|
+
|
26
|
+
add_tag(new_tag)
|
27
|
+
VPL.info("Git提交Tag: #{new_tag}")
|
28
|
+
end
|
29
|
+
quick_push_tag(has_tag)
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_s
|
33
|
+
"#{remote}-#{branches.current.first}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Git::Branches
|
38
|
+
class Branches
|
39
|
+
def current
|
40
|
+
local.select { :current }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'vcpkg_pipeline/extension/vcport_vpl'
|
4
|
+
|
5
|
+
require 'vcpkg_pipeline/core/log'
|
6
|
+
|
7
|
+
# VCPkg
|
8
|
+
module VCPkg
|
9
|
+
def self.root
|
10
|
+
`echo $VCPKG_ROOT`
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.ports
|
14
|
+
"#{root}/ports"
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.hash(zip_path)
|
18
|
+
`vcpkg hash #{zip_path}`.sub(/\n/, '')
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.format(vcpkg_json_path)
|
22
|
+
`vcpkg format-manifest #{vcpkg_json_path}`
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.publish(vcport)
|
26
|
+
name = vcport.vcpkg.name
|
27
|
+
version = vcport.vcpkg.version
|
28
|
+
|
29
|
+
git_vcpkg = Git.open(root)
|
30
|
+
git_vcpkg.stashes.all
|
31
|
+
|
32
|
+
port_exist = File.directory? "#{VCPkg.root}/ports/#{name}"
|
33
|
+
|
34
|
+
`cp -fr #{vcport.port_path} #{ports}`
|
35
|
+
`vcpkg x-add-version #{name}`
|
36
|
+
|
37
|
+
git_vcpkg.add('.')
|
38
|
+
git_vcpkg.commit("[#{name}] #{port_exist ? 'Update' : 'Add'} #{version}")
|
39
|
+
git_vcpkg.quick_push
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
require 'vcpkg_pipeline/extension/string_vpl'
|
6
|
+
|
7
|
+
require 'vcpkg_pipeline/core/log'
|
8
|
+
|
9
|
+
# VCPort
|
10
|
+
module VCPort
|
11
|
+
def self.open(path)
|
12
|
+
VCPort::Base.new(path)
|
13
|
+
end
|
14
|
+
|
15
|
+
# VCPort::Base
|
16
|
+
class Base
|
17
|
+
attr_accessor :path, :port_path, :vcpkg, :portfile
|
18
|
+
|
19
|
+
def initialize(path)
|
20
|
+
@path = path
|
21
|
+
@port_path = "#{path}/vcport"
|
22
|
+
VPL.error("#{@port_path} Not Found") unless File.directory? @port_path
|
23
|
+
|
24
|
+
@vcpkg = VCPkg.new(@port_path)
|
25
|
+
@portfile = Portfile.new(@port_path)
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_s
|
29
|
+
"#{vcpkg}\n#{portfile}"
|
30
|
+
end
|
31
|
+
|
32
|
+
# VCPort::Base::VCPkg
|
33
|
+
class VCPkg
|
34
|
+
attr_accessor :path, :content_path, :content, :json, :name, :version
|
35
|
+
|
36
|
+
def initialize(path)
|
37
|
+
@path = path
|
38
|
+
@content_path = "#{path}/vcpkg.json"
|
39
|
+
|
40
|
+
VPL.error("#{@content_path} Not Found") unless File.exist? @content_path
|
41
|
+
@content = File.read(@content_path)
|
42
|
+
|
43
|
+
parse_content(@content)
|
44
|
+
end
|
45
|
+
|
46
|
+
def parse_content(content)
|
47
|
+
@json = JSON.parse(content)
|
48
|
+
@name = @json['name']
|
49
|
+
@version = @json['version']
|
50
|
+
end
|
51
|
+
|
52
|
+
def version_update(new_version)
|
53
|
+
@json['version'] = new_version
|
54
|
+
File.write(@content_path, JSON.dump(@json))
|
55
|
+
VPL.info("Port 版本号更新: #{@version} -> #{new_version}")
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_s
|
59
|
+
"#{json['name']}-#{json['version']}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# VCPort::Base::Portfile
|
64
|
+
class Portfile
|
65
|
+
attr_accessor :path, :content_path, :content, :download_distfile, :url, :filename, :hash
|
66
|
+
|
67
|
+
def initialize(path)
|
68
|
+
@path = path
|
69
|
+
@content_path = "#{path}/portfile.cmake"
|
70
|
+
|
71
|
+
VPL.error("#{@content_path} Not Found") unless File.exist? @content_path
|
72
|
+
@content = File.read(@content_path)
|
73
|
+
|
74
|
+
parse_content(@content)
|
75
|
+
end
|
76
|
+
|
77
|
+
def parse_content(content)
|
78
|
+
content.each_line(')') { |piece| parse_download_distfile(piece) }
|
79
|
+
end
|
80
|
+
|
81
|
+
def parse_download_distfile(piece)
|
82
|
+
return unless piece.include? 'vcpkg_download_distfile'
|
83
|
+
|
84
|
+
@download_distfile = piece
|
85
|
+
|
86
|
+
clean_download_distfile = piece.clean
|
87
|
+
parse_download_distfile_url(clean_download_distfile)
|
88
|
+
parse_download_distfile_filename(clean_download_distfile)
|
89
|
+
parse_download_distfile_hash(clean_download_distfile)
|
90
|
+
end
|
91
|
+
|
92
|
+
def parse_download_distfile_url(clean_download_distfile)
|
93
|
+
regex_url = /URLS "([^ ]*)" /
|
94
|
+
regex_url.match(clean_download_distfile)
|
95
|
+
@url = Regexp.last_match(1)
|
96
|
+
end
|
97
|
+
|
98
|
+
def parse_download_distfile_filename(clean_download_distfile)
|
99
|
+
regex_filename = /FILENAME "([^ ]*)" /
|
100
|
+
regex_filename.match(clean_download_distfile)
|
101
|
+
@filename = Regexp.last_match(1)
|
102
|
+
end
|
103
|
+
|
104
|
+
def parse_download_distfile_hash(clean_download_distfile)
|
105
|
+
regex_hash = /SHA512 ([^ ]*) /
|
106
|
+
regex_hash.match(clean_download_distfile)
|
107
|
+
@hash = Regexp.last_match(1)
|
108
|
+
end
|
109
|
+
|
110
|
+
def download_distfile_update(new_url, new_filename, new_hash)
|
111
|
+
new_download_distfile = @download_distfile
|
112
|
+
new_download_distfile = new_download_distfile.sub("URLS \"#{@url}\"", "URLS \"#{new_url}\"")
|
113
|
+
new_download_distfile = new_download_distfile.sub("FILENAME \"#{@filename}\"", "FILENAME \"#{new_filename}\"")
|
114
|
+
new_download_distfile = new_download_distfile.sub("SHA512 #{@hash}", "SHA512 #{new_hash}")
|
115
|
+
File.write(@content_path, @content.sub(@download_distfile, new_download_distfile))
|
116
|
+
VPL.info("Port 下载文件信息更新: \
|
117
|
+
\n URLS #{@url} -> #{new_url}\
|
118
|
+
\n FILENAME #{@filename} -> #{new_filename}\
|
119
|
+
\n SHA512 #{@hash} -> #{new_hash}\
|
120
|
+
")
|
121
|
+
end
|
122
|
+
|
123
|
+
def to_s
|
124
|
+
"#{@url} -> #{@filename}"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|