65 lines
1.6 KiB
Ruby
65 lines
1.6 KiB
Ruby
require "yaml"
|
|
require "digest"
|
|
|
|
module Picop
|
|
class SourceFile
|
|
attr_reader :file_path, :content
|
|
|
|
METADATA_PATTERN = /^\s*#\s*@META_START\n(.*?)^\s*#\s*@META_END/m
|
|
|
|
def initialize(file_path)
|
|
@file_path = file_path
|
|
@content = File.read(file_path)
|
|
end
|
|
|
|
def metadata
|
|
@metadata ||= begin
|
|
return {} unless content =~ METADATA_PATTERN
|
|
|
|
yaml_content = $1.lines.map do |line|
|
|
line.sub(/^\s*#\s?/, '').rstrip
|
|
end.join("\n")
|
|
|
|
YAML.safe_load(yaml_content)
|
|
end
|
|
end
|
|
|
|
def file_content = content.sub(/^\s*#\s*@META_START\n.*?^\s*#\s*@META_END\n*/m, '')
|
|
|
|
def checksum = "sha256:#{Digest::SHA256.hexdigest(file_content)}"
|
|
|
|
def show = puts(metadata.merge({checksum: checksum}))
|
|
|
|
def save = File.write(file_path, content)
|
|
|
|
def add_metadata(metadata_hash)
|
|
yaml_content = metadata_hash.to_yaml.strip
|
|
metadata_block = [
|
|
"# @META_START",
|
|
yaml_content.lines.map { |line| "# #{line}" }.join,
|
|
"# @META_END"
|
|
].join("\n")
|
|
|
|
if content =~ METADATA_PATTERN
|
|
@content = content.sub(METADATA_PATTERN, metadata_block)
|
|
else
|
|
@content = [metadata_block, content].join("\n\n")
|
|
end
|
|
end
|
|
|
|
def sign
|
|
hash = checksum
|
|
meta = metadata || {}
|
|
return puts "File already signed" if meta['content_checksum'] == hash
|
|
|
|
meta['content_checksum'] = "#{hash}"
|
|
add_metadata(meta)
|
|
save
|
|
end
|
|
|
|
def verify
|
|
return false unless metadata.key? 'content_checksum'
|
|
checksum == metadata['content_checksum']
|
|
end
|
|
end
|
|
end |