Skip to content

Commit

Permalink
Merge pull request #6 from splaplapla/app-rb-for-pbm-cloud
Browse files Browse the repository at this point in the history
app.rb.erbを評価してapp.rbを生成する
  • Loading branch information
jiikko authored Jun 5, 2022
2 parents f043e78 + b9613b3 commit cadb80a
Show file tree
Hide file tree
Showing 18 changed files with 514 additions and 144 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## [0.1.10] - 2022-06-05
- project_template/app.rb.erbを評価してapp.rbを生成するようになりました

## [0.1.9] - 2022-02-18
- Pbmenv.installにenable_pbm_cloudオプションを追加しました
- Pbmenv.installにuse_optionオプションを追加しました
Expand Down
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
pbmenv (0.1.9)
pbmenv (0.1.10)

GEM
remote: https://rubygems.org/
Expand Down Expand Up @@ -40,4 +40,4 @@ DEPENDENCIES
rspec

BUNDLED WITH
2.2.31
2.3.7
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
* docker-compose build --no-cache
* docker-compose run app bash
* bin/rspec
* also `DISABLE_DEBUG_LOG=1 bin/rspec`
109 changes: 30 additions & 79 deletions lib/pbmenv.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
require_relative "pbmenv/version"
require_relative "pbmenv/cli"
require_relative "pbmenv/pbm"
require_relative "pbmenv/helper"
require_relative "pbmenv/version_pathname"
require_relative "pbmenv/create_version_service"
require_relative "pbmenv/destroy_version_service"
require_relative "pbmenv/use_version_service"
require_relative "pbmenv/download_src_service"

module Pbmenv
PBM_DIR = "/usr/share/pbm"
Expand All @@ -20,102 +26,47 @@ def self.versions

def self.install(version, use_option: false, enable_pbm_cloud: false)
raise "Need a version" if version.nil?
if version == 'latest'
version = available_versions.first
end

if File.exists?("/usr/share/pbm/v#{version}")
return false
end

download_src(version)
system_and_puts <<~SHELL
mkdir -p #{PBM_DIR}/v#{version} && cp -r procon_bypass_man-#{version}/project_template/* #{PBM_DIR}/v#{version}/
SHELL

if enable_pbm_cloud
text = File.read("#{PBM_DIR}/v#{version}/app.rb")
if text =~ /config\.api_servers\s+=\s+\['(https:\/\/.+)'\]/ && (url = $1)
text.gsub!(/#\s+config\.api_servers\s+=\s+.+$/, "config.api_servers = '#{url}'")
version =
if version == 'latest'
available_versions.first
else
Helper.normalize_version(version) or raise "mismatch version number!"
end
File.write("#{PBM_DIR}/v#{version}/app.rb", text)
end

unless File.exists?("#{PBM_DIR}/shared")
system_and_puts <<~SHELL
mkdir -p #{PBM_DIR}/shared
SHELL
end

unless File.exists?("#{PBM_DIR}/shared/device_id")
File.write("#{PBM_DIR}/shared/device_id", "d_#{SecureRandom.uuid}")
end

system_and_puts <<~SHELL
ln -s #{PBM_DIR}/shared/device_id #{PBM_DIR}/v#{version}/device_id
SHELL

# 初回だけinstall時にcurrentを作成する
if !File.exists?("#{PBM_DIR}/current") || use_option
use(version)
end
rescue => e
system_and_puts "rm -rf #{PBM_DIR}/v#{version}"
raise
ensure
if Dir.exists?("./procon_bypass_man-#{version}")
system_and_puts "rm -rf ./procon_bypass_man-#{version}"
begin
CreateVersionService.new(version: version, use_option: use_option, enable_pbm_cloud: enable_pbm_cloud).execute!
rescue CreateVersionService::AlreadyCreatedError
return false
rescue CreateVersionService::NotSupportVersionError
return false
end
end

# TODO currentが挿しているバージョンはどうする?
def self.uninstall(version)
raise "Need a version" if version.nil?
version = Helper.normalize_version(version) or raise "mismatch version number!"

unless File.exists?("/usr/share/pbm/v#{version}")
begin
DestroyVersionService.new(version: version).execute!
rescue DestroyVersionService::VersionNotFoundError
return false
end
system_and_puts "rm -rf #{PBM_DIR}/v#{version}"
end

def self.use(version)
raise "Need a version" if version.nil?
version = versions.last if version == "latest"
version =
if version == 'latest'
versions.last
else
Helper.normalize_version(version) or raise "mismatch version number!"
end

if !File.exists?("/usr/share/pbm/#{version}") && !File.exists?("/usr/share/pbm/v#{version}")
begin
UseVersionService.new(version: version).execute!
rescue UseVersionService::VersionNotFoundError
return false
end

if File.symlink?("#{PBM_DIR}/current")
system_and_puts "unlink #{PBM_DIR}/current"
end

if(version_number = version.match(/v?([\w.]+)/)[1])
system_and_puts "ln -s #{PBM_DIR}/v#{version_number} #{PBM_DIR}/current"
else
raise "mismatch version number!"
end
end

def self.download_src(version)
if ENV["DEBUG_INSTALL"]
shell = <<~SHELL
git clone https://github.com/splaplapla/procon_bypass_man.git procon_bypass_man-#{version}
SHELL
else
# TODO cache for testing
shell = <<~SHELL
curl -L https://github.com/splaplapla/procon_bypass_man/archive/refs/tags/v#{version}.tar.gz | tar xvz
SHELL
end
system_and_puts(shell)
unless File.exists?("procon_bypass_man-#{version}/project_template")
raise "This version is not support by pbmenv"
end
end

def self.system_and_puts(shell)
puts "[SHELL] #{shell}"
system(shell)
end
end
117 changes: 117 additions & 0 deletions lib/pbmenv/create_version_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# frozen_string_literal: true

module Pbmenv
class CreateVersionService
class AlreadyCreatedError < StandardError; end
class NotSupportVersionError < StandardError; end

attr_accessor :version, :use_option, :enable_pbm_cloud

def initialize(version: , use_option: , enable_pbm_cloud: )
self.version = version
self.use_option = use_option
self.enable_pbm_cloud = enable_pbm_cloud
end

def execute!
if File.exists?("/usr/share/pbm/v#{version}")
raise AlreadyCreatedError
end

begin
source_path = download_src(version)
build_app_file(source_path: source_path)
create_if_miss_shared_dir
create_if_miss_device_id_file
link_device_id_file(version: version)
create_if_miss_current_dir(version: version)
rescue DownloadSrcService::DownloadError
puts "Download failed. Check the version name."
raise NotSupportVersionError
rescue => e
Helper.system_and_puts "rm -rf #{VersionPathname.new(version).version_path}"
raise
ensure
if source_path && Dir.exists?(source_path)
Helper.system_and_puts "rm -rf #{source_path}"
end
end

return true
end

private

# @return [String]
def download_src(version)
Pbmenv::DownloadSrcService.new(version).execute!
return "procon_bypass_man-#{version}"
end

def build_app_file(source_path: )
pathname = VersionPathname.new(version)

if File.exists?(File.join(source_path, "project_template/app.rb.erb"))
Helper.system_and_puts <<~SHELL
mkdir -p #{pathname.version_path} &&
cp procon_bypass_man-#{version}/project_template/app.rb.erb #{pathname.version_path}/
cp procon_bypass_man-#{version}/project_template/README.md #{pathname.version_path}/
cp procon_bypass_man-#{version}/project_template/setting.yml #{pathname.version_path}/
cp -r procon_bypass_man-#{version}/project_template/systemd_units #{pathname.version_path}/
SHELL
require "./procon_bypass_man-#{version}/project_template/lib/app_generator"
AppGenerator.new(
prefix_path: pathname.version_path,
enable_integration_with_pbm_cloud: enable_pbm_cloud,
).generate
Helper.system_and_puts "rm #{pathname.app_rb_erb_path}"
else
Helper.system_and_puts <<~SHELL
mkdir -p #{pathname.version_path} &&
cp procon_bypass_man-#{version}/project_template/app.rb #{pathname.version_path}/
cp procon_bypass_man-#{version}/project_template/README.md #{pathname.version_path}/
cp procon_bypass_man-#{version}/project_template/setting.yml #{pathname.version_path}/
cp -r procon_bypass_man-#{version}/project_template/systemd_units #{pathname.version_path}/
SHELL
end

# 旧実装バージョン
if enable_pbm_cloud
text = File.read(pathname.app_rb_path)
if text =~ /config\.api_servers\s+=\s+\['(https:\/\/.+)'\]/ && (url = $1)
text.gsub!(/#\s+config\.api_servers\s+=\s+.+$/, "config.api_servers = '#{url}'")
end
File.write(pathname.app_rb_path, text)
end
end

def create_if_miss_shared_dir
unless File.exists?(VersionPathname.shared)
Helper.system_and_puts <<~SHELL
mkdir -p #{VersionPathname.shared}
SHELL
end
end

def create_if_miss_device_id_file
device_id_path_in_shared = VersionPathname.device_id_path_in_shared
unless File.exists?(device_id_path_in_shared)
File.write(device_id_path_in_shared, "d_#{SecureRandom.uuid}")
end
end

def link_device_id_file(version: )
pathname = VersionPathname.new(version)
Helper.system_and_puts <<~SHELL
ln -s #{pathname.device_id_path_in_shared} #{pathname.device_id_path_in_version}
SHELL
end

def create_if_miss_current_dir(version: )
# 初回だけinstall時にcurrentを作成する
if !File.exists?(VersionPathname.current) || use_option
UseVersionService.new(version: version).execute!
end
end
end
end
22 changes: 22 additions & 0 deletions lib/pbmenv/destroy_version_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

module Pbmenv
class DestroyVersionService
class VersionNotFoundError < StandardError; end

attr_accessor :version

def initialize(version: )
@version = version
end

def execute!
version_pathname = VersionPathname.new(version)

unless File.exists?(version_pathname.version_path)
raise VersionNotFoundError
end
Helper.system_and_puts "rm -rf #{version_pathname.version_path}"
end
end
end
32 changes: 32 additions & 0 deletions lib/pbmenv/download_src_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module Pbmenv
class DownloadSrcService
class DownloadError < StandardError; end

attr_accessor :version

def initialize(version)
self.version = version
end

def execute!
if ENV["DEBUG_INSTALL"]
shell = <<~SHELL
git clone https://github.com/splaplapla/procon_bypass_man.git procon_bypass_man-#{version}
SHELL
else
# TODO cache for testing
shell = <<~SHELL
curl -L https://github.com/splaplapla/procon_bypass_man/archive/refs/tags/v#{version}.tar.gz | tar xvz > /dev/null
SHELL
end

if Helper.system_and_puts(shell)
unless File.exists?("procon_bypass_man-#{version}/project_template")
raise NotSupportVersionError, "This version is not support by pbmenv"
end
else
raise DownloadError
end
end
end
end
16 changes: 16 additions & 0 deletions lib/pbmenv/helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module Pbmenv
class Helper
def self.system_and_puts(shell)
to_stdout "[SHELL] #{shell}"
system(shell)
end

def self.to_stdout(text)
puts text
end

def self.normalize_version(version)
/\Av?([\w.]*)\z/ =~ version && $1
end
end
end
38 changes: 38 additions & 0 deletions lib/pbmenv/use_version_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# frozen_string_literal: true

module Pbmenv
class UseVersionService
class VersionNotFoundError < StandardError; end

attr_accessor :version

def initialize(version: )
self.version = version
end

def execute!
throw_error_if_has_not_version
relink_current_path
end

private

def throw_error_if_has_not_version
version_pathname = VersionPathname.new(version)

if !File.exists?(version_pathname.version_path_without_v) && !File.exists?(version_pathname.version_path)
raise UseVersionService::VersionNotFoundError
end
end

def relink_current_path
version_pathname = VersionPathname.new(version)

if File.symlink?(VersionPathname.current)
Helper.system_and_puts "unlink #{VersionPathname.current}"
end

Helper.system_and_puts "ln -s #{version_pathname.version_path} #{VersionPathname.current}"
end
end
end
Loading

0 comments on commit cadb80a

Please sign in to comment.