alpacabuildtool 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +48 -0
- data/.rubocop.yml +12 -0
- data/.semver +6 -0
- data/.travis.yml +10 -0
- data/CHANGELOG +18 -0
- data/Gemfile +7 -0
- data/LICENSE +22 -0
- data/README.md +235 -0
- data/README.rdoc +39 -0
- data/Rakefile +74 -0
- data/alpacabuildtool.gemspec +34 -0
- data/alpacabuildtool.rdoc +5 -0
- data/alpacabuildtool.todo +9 -0
- data/bin/alpaca +142 -0
- data/features/alpaca.feature +8 -0
- data/features/step_definitions/alpaca_steps.rb +13 -0
- data/features/step_definitions/visual_studio_solutions_steps.rb +47 -0
- data/features/support/env.rb +10 -0
- data/features/visual_studio_solutions.feature +43 -0
- data/lib/alpacabuildtool.rb +4 -0
- data/lib/alpacabuildtool/application.rb +195 -0
- data/lib/alpacabuildtool/configuration.rb +209 -0
- data/lib/alpacabuildtool/data/.alpaca.conf +148 -0
- data/lib/alpacabuildtool/data/doom.flf +826 -0
- data/lib/alpacabuildtool/data/logo.jpg +0 -0
- data/lib/alpacabuildtool/entities/nuspec.rb +107 -0
- data/lib/alpacabuildtool/entities/project.rb +54 -0
- data/lib/alpacabuildtool/entities/solution.rb +104 -0
- data/lib/alpacabuildtool/entities/xml.rb +41 -0
- data/lib/alpacabuildtool/entities/xml_node.rb +75 -0
- data/lib/alpacabuildtool/log/font.rb +92 -0
- data/lib/alpacabuildtool/log/log.rb +15 -0
- data/lib/alpacabuildtool/log/rainbowify_formatter.rb +70 -0
- data/lib/alpacabuildtool/log/rainbowify_logger.rb +47 -0
- data/lib/alpacabuildtool/managers/build_manager.rb +32 -0
- data/lib/alpacabuildtool/managers/package_manager.rb +136 -0
- data/lib/alpacabuildtool/managers/report_manager.rb +33 -0
- data/lib/alpacabuildtool/managers/test_manager.rb +35 -0
- data/lib/alpacabuildtool/os.rb +29 -0
- data/lib/alpacabuildtool/package_types/project_package.rb +44 -0
- data/lib/alpacabuildtool/package_types/tool_package.rb +53 -0
- data/lib/alpacabuildtool/tools/git.rb +22 -0
- data/lib/alpacabuildtool/tools/msbuild.rb +29 -0
- data/lib/alpacabuildtool/tools/nuget.rb +49 -0
- data/lib/alpacabuildtool/tools/nunit.rb +28 -0
- data/lib/alpacabuildtool/tools/nunit_orange.rb +18 -0
- data/lib/alpacabuildtool/tools/open_cover.rb +29 -0
- data/lib/alpacabuildtool/tools/report_generator.rb +25 -0
- data/lib/alpacabuildtool/tools/tool.rb +84 -0
- data/lib/alpacabuildtool/tools/wrapper.rb +66 -0
- data/lib/alpacabuildtool/versioning/version.rb +163 -0
- data/lib/alpacabuildtool/versioning/versioning.rb +84 -0
- data/spec/lib/alpacabuildtool/configuration_spec.rb +201 -0
- data/spec/lib/alpacabuildtool/entities/xml_spec.rb +39 -0
- data/spec/lib/alpacabuildtool/versioning/version_spec.rb +86 -0
- data/spec/lib/alpacabuildtool/versioning/versioning_spec.rb +194 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/support/coverage.rb +26 -0
- data/test_data/sln1/.alpaca.conf +11 -0
- data/test_data/sln1/.semver +6 -0
- data/test_data/sln1/TestSolution.sln +22 -0
- data/test_data/sln1/TestSolution/App.config +6 -0
- data/test_data/sln1/TestSolution/Program.cs +16 -0
- data/test_data/sln1/TestSolution/Properties/AssemblyInfo.cs +36 -0
- data/test_data/sln1/TestSolution/TestSolution.csproj +59 -0
- data/test_data/sln2/.alpaca.conf +8 -0
- data/test_data/sln2/.semver +6 -0
- data/test_data/sln2/ProjectName/ProjectName.csproj +54 -0
- data/test_data/sln2/ProjectName/Properties/AssemblyInfo.cs +36 -0
- data/test_data/sln2/ProjectName/SomeFolderInProject/SomeClass.cs +16 -0
- data/test_data/sln2/ProjectName2/ProjectName2.csproj +58 -0
- data/test_data/sln2/ProjectName2/Properties/AssemblyInfo.cs +37 -0
- data/test_data/sln2/SolutionName.sln +34 -0
- data/test_data/sln2/Unit.Tests/Properties/AssemblyInfo.cs +36 -0
- data/test_data/sln2/Unit.Tests/SomeClassTests.cs +21 -0
- data/test_data/sln2/Unit.Tests/Unit.Tests.csproj +65 -0
- data/test_data/sln2/Unit.Tests/packages.config +4 -0
- data/test_data/sln3/TestSolution.nobuild.sln +22 -0
- data/test_data/sln3/TestSolution/App.config +6 -0
- data/test_data/sln3/TestSolution/Program.cs +16 -0
- data/test_data/sln3/TestSolution/Properties/AssemblyInfo.cs +36 -0
- data/test_data/sln3/TestSolution/TestSolution.nobuild.csproj +59 -0
- metadata +309 -0
Binary file
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'alpacabuildtool/entities/xml'
|
2
|
+
|
3
|
+
module AlpacaBuildTool
|
4
|
+
##
|
5
|
+
# Nuspec creates *.nuspec file content
|
6
|
+
#
|
7
|
+
# Nuspec.new(id: 'Cool.Package',
|
8
|
+
# version: '0.0.1',
|
9
|
+
# description: 'something',
|
10
|
+
# authors: ['Vasyl', 'Kate'],
|
11
|
+
# false).to_s
|
12
|
+
# # => <?xml version="1.0"?>
|
13
|
+
# # <package>
|
14
|
+
# # <metadata>
|
15
|
+
# # <id>Cool.Package</id>
|
16
|
+
# # <version>0.0.1</version>
|
17
|
+
# # <authors>Vasyl,Kate</authors>
|
18
|
+
# # <description>something</description>
|
19
|
+
# # </metadata>
|
20
|
+
# # </package>
|
21
|
+
class Nuspec
|
22
|
+
OPTIONAL = %w(title licenseUrl projectUrl copyright iconUrl
|
23
|
+
requireLicenseAcceptance releaseNotes)
|
24
|
+
|
25
|
+
##
|
26
|
+
# Creates instance and generate content from *package* config
|
27
|
+
#
|
28
|
+
# +package+:: package configuration
|
29
|
+
# +add_common_files+:: flag to add files like README and CHANGELOG
|
30
|
+
def initialize(package, add_common_files = true)
|
31
|
+
@content = generate(package, add_common_files)
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Overrides to_s method to create string content from inner Xml object
|
36
|
+
def to_s
|
37
|
+
@content.to_s
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Returns Xml object representation of package nuspec
|
42
|
+
#
|
43
|
+
# +config+:: package configuration
|
44
|
+
# +add_common_files+:: flag to add common files or not
|
45
|
+
def generate(config, add_common_files)
|
46
|
+
Xml.new '1.0' do
|
47
|
+
node 'package' do |package|
|
48
|
+
Nuspec.add_metadata(package, config)
|
49
|
+
Nuspec.add_files(package, config) if add_common_files
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# Adds metadata entry to nuspec
|
56
|
+
#
|
57
|
+
# +package+:: XmlNode where to add metadata
|
58
|
+
# +config+:: package configuration
|
59
|
+
def self.add_metadata(package, config)
|
60
|
+
package.node 'metadata' do |metadata|
|
61
|
+
Nuspec.add_mandatory_fields(metadata, config)
|
62
|
+
Nuspec.add_optional_fields(metadata, config)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# Adds mandatory entries to nuspec like id, version, authors and description
|
68
|
+
#
|
69
|
+
# +metadata+:: XmlNode where to add entries
|
70
|
+
# +config+:: package configuration
|
71
|
+
def self.add_mandatory_fields(metadata, config)
|
72
|
+
metadata.node 'id', config['id']
|
73
|
+
metadata.node 'version', config['version']
|
74
|
+
metadata.node 'authors', config['authors'].join(',')
|
75
|
+
metadata.node 'description', config['description']
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# Adds optional entries to nuspec like owners, tags and so on
|
80
|
+
#
|
81
|
+
# +metadata+:: XmlNode where to add entries
|
82
|
+
# +config+:: package configuration
|
83
|
+
def self.add_optional_fields(metadata, config)
|
84
|
+
OPTIONAL.each { |name| metadata.node(name, config[name]) if config[name] }
|
85
|
+
metadata.node 'owners', config['owners'].join(',') if config['owners']
|
86
|
+
metadata.node 'tags', config['tags'].join(' ') if config['tags']
|
87
|
+
end
|
88
|
+
|
89
|
+
##
|
90
|
+
# Adds README.txt and CHANGES.txt files
|
91
|
+
#
|
92
|
+
# +package+:: XmlNode where to add files entry
|
93
|
+
# +config+:: package configuration
|
94
|
+
def self.add_files(package, config)
|
95
|
+
package.node 'files' do
|
96
|
+
node 'file' do
|
97
|
+
attribute 'src', 'README.txt'
|
98
|
+
attribute 'target', ''
|
99
|
+
end if config['readme']
|
100
|
+
node 'file' do
|
101
|
+
attribute 'src', 'CHANGES.txt'
|
102
|
+
attribute 'target', ''
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module AlpacaBuildTool
|
2
|
+
##
|
3
|
+
# VisualStudioProject provides project representation and methods
|
4
|
+
# to modify it's AssemblyVersion.cs file
|
5
|
+
class Project
|
6
|
+
attr_accessor :name, :file, :dir
|
7
|
+
|
8
|
+
##
|
9
|
+
# Creates instance of class
|
10
|
+
#
|
11
|
+
# +line+:: line from .sln file with project information
|
12
|
+
# +dir+:: solution directory
|
13
|
+
#
|
14
|
+
# s = AlpacaBuildTool::VisualStudioProject.new(
|
15
|
+
# 'Project("{FAE04EC0...5254043711}"'
|
16
|
+
# 'd:\')
|
17
|
+
# # => #<**:VisualStudioProject:** @file="d:/sln1/some.csproj" **>
|
18
|
+
def initialize(line, dir)
|
19
|
+
items = line.gsub(/".*?"/).to_a
|
20
|
+
_, @name, file, _ = items.map { |item| item.to_s.gsub('"', '') }
|
21
|
+
dir = File.expand_path(dir)
|
22
|
+
@dir = File.dirname(File.join(dir, file))
|
23
|
+
@file = File.join(dir, file)
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# Overrides *to_s* method to provide nice convertion to string
|
28
|
+
def to_s
|
29
|
+
"{#{@name};#{@file}}"
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# Updates AssemblyInfo.cs file under the project with new_version
|
34
|
+
#
|
35
|
+
# +new_version+:: version that need to be used as assembly version
|
36
|
+
# and assembly file version
|
37
|
+
def update_version(new_version)
|
38
|
+
info_file = File.join(@dir, 'Properties', 'AssemblyInfo.cs')
|
39
|
+
content = IO.readlines(info_file)
|
40
|
+
open(info_file, 'w') do |io|
|
41
|
+
content.each { |line| io.write replace_version(line, new_version) }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def replace_version(line, new_version)
|
48
|
+
line = line.gsub(/AssemblyVersion\("(.*?)"\)/,
|
49
|
+
"AssemblyVersion(\"#{new_version}\")")
|
50
|
+
line.gsub(/AssemblyFileVersion\("(.*?)"\)/,
|
51
|
+
"AssemblyFileVersion(\"#{new_version}\")")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'alpacabuildtool/log/log'
|
2
|
+
require 'alpacabuildtool/configuration'
|
3
|
+
require 'alpacabuildtool/entities/project'
|
4
|
+
require 'alpacabuildtool/versioning/versioning'
|
5
|
+
|
6
|
+
module AlpacaBuildTool
|
7
|
+
##
|
8
|
+
# Solution provides solution representation and it's configuration storage
|
9
|
+
class Solution
|
10
|
+
include Log
|
11
|
+
|
12
|
+
attr_reader :file, :dir, :projects
|
13
|
+
|
14
|
+
##
|
15
|
+
# Creates instance from *.sln file
|
16
|
+
# Initializes solution's semantic version and absolute path to it's file
|
17
|
+
#
|
18
|
+
# +file+:: absolute or relative path to *.sln file
|
19
|
+
def initialize(file)
|
20
|
+
@file = File.expand_path(file)
|
21
|
+
@dir = File.dirname(@file)
|
22
|
+
@semver = Versioning.find(@dir)
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Overrides string representation. Spawned to multiple lines
|
27
|
+
def to_s
|
28
|
+
s = '------------'
|
29
|
+
s += "\nFile: #{@file}"
|
30
|
+
s += "\nVersion: #{build_version}"
|
31
|
+
s += "\nProjects:" unless projects.empty?
|
32
|
+
projects.each { |p| s += "\n\t#{p}" }
|
33
|
+
s + "\n------------"
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Returns Configuration object for current solution (initialized only once)
|
38
|
+
def configuration
|
39
|
+
@configuration ||= Configuration.new(self)
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
# Returns array of it's projects (initialized only once)
|
44
|
+
def projects
|
45
|
+
return @projects if @projects
|
46
|
+
@projects = []
|
47
|
+
IO.readlines(@file).each do |line|
|
48
|
+
@projects << Project.new(line, @dir) if /^Project.*\.csproj/ =~ line
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
# Returns specific project by it's name
|
54
|
+
#
|
55
|
+
# +name+:: project's name
|
56
|
+
def project(name)
|
57
|
+
@projects.find { |p| p.name == name }
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# Updates all projects AssemblyInfo.cs files with specific version
|
62
|
+
#
|
63
|
+
# +version+:: version to be stored in AssemblyInfo.cs files
|
64
|
+
def update_projects_version(version)
|
65
|
+
projects.each do |project|
|
66
|
+
project.update_version version
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# Returns array of projects that correspondes to specific type
|
72
|
+
#
|
73
|
+
# +type+:: type of project defined in configuration project_types
|
74
|
+
def specific_projects(type)
|
75
|
+
types = configuration['project_types'].dup
|
76
|
+
types.select! { |t| t['type'] == type } unless type == 'all'
|
77
|
+
projects.select do |project|
|
78
|
+
types.any? { |t| project.name.include? t['name'] }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
##
|
83
|
+
# Returns true if solution is marked as *nobuild*
|
84
|
+
def no_build?
|
85
|
+
solution_name = File.basename(@file, '.*')
|
86
|
+
(configuration['no_build'] || []).each do |tag|
|
87
|
+
return true if solution_name.include?(tag)
|
88
|
+
end
|
89
|
+
false
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# Returns current build version
|
94
|
+
def build_version
|
95
|
+
@semver.to_s '%M.%m.%p'
|
96
|
+
end
|
97
|
+
|
98
|
+
##
|
99
|
+
# Returns current package version
|
100
|
+
def package_version
|
101
|
+
@semver.to_s '%M.%m.%p%s'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'alpacabuildtool/entities/xml_node'
|
2
|
+
|
3
|
+
module AlpacaBuildTool
|
4
|
+
##
|
5
|
+
# Xml represents simple xml document with one root node
|
6
|
+
#
|
7
|
+
# doc = Xml.new '1.0' do
|
8
|
+
# node 'a', 'b'
|
9
|
+
# end
|
10
|
+
# doc.to_s
|
11
|
+
# # => <?xml version="1.0"?>
|
12
|
+
# # <a>b</a>
|
13
|
+
class Xml
|
14
|
+
##
|
15
|
+
# Creates instance
|
16
|
+
#
|
17
|
+
# +version+:: xml version
|
18
|
+
# accepts &block
|
19
|
+
def initialize(version, &block)
|
20
|
+
@version, @root_node = version, nil
|
21
|
+
instance_eval(&block) if block_given?
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# Set/override root node
|
26
|
+
#
|
27
|
+
# +name+:: node name
|
28
|
+
# +content+:: node content
|
29
|
+
# accepts &block
|
30
|
+
def node(name, content = nil, &block)
|
31
|
+
@root = XmlNode.new(name, content, &block)
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Overrides string representation to generate xml document content from
|
36
|
+
# stored objects
|
37
|
+
def to_s
|
38
|
+
"<?xml version=\"#{@version}\"?>\n#{@root}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
module AlpacaBuildTool
|
4
|
+
##
|
5
|
+
# XmlNode represents simple xml node that can contain attributes and other
|
6
|
+
# nodes or string as a content
|
7
|
+
class XmlNode
|
8
|
+
attr_reader :name, :content
|
9
|
+
|
10
|
+
##
|
11
|
+
# Creates an instance
|
12
|
+
#
|
13
|
+
# +name+:: name of node
|
14
|
+
# +content+:: content of node (if set, block is ignored)
|
15
|
+
# accepts &block to set content to array of nodes
|
16
|
+
def initialize(name, content = nil, &block)
|
17
|
+
@name = name
|
18
|
+
return @content = content unless content.nil?
|
19
|
+
return unless block_given?
|
20
|
+
@arity = block.arity
|
21
|
+
if @arity <= 0
|
22
|
+
@context = eval('self', block.binding)
|
23
|
+
instance_eval(&block)
|
24
|
+
else
|
25
|
+
yield self
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Adds new node into content
|
31
|
+
#
|
32
|
+
# +name+:: node name
|
33
|
+
# +content+:: node content
|
34
|
+
# accepts &block for this new node
|
35
|
+
#
|
36
|
+
# XmlNode.new 'a' do
|
37
|
+
# node 'b' do
|
38
|
+
# node 'c' do
|
39
|
+
# ...
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
def node(name, content = nil, &block)
|
44
|
+
(@content ||= []) << XmlNode.new(name, content, &block)
|
45
|
+
end
|
46
|
+
|
47
|
+
##
|
48
|
+
# Adds attribute to node
|
49
|
+
#
|
50
|
+
# +name+:: attribute name
|
51
|
+
# +value+:: attribute value
|
52
|
+
def attribute(name, value)
|
53
|
+
(@attributes ||= {})[name] = value
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# Overrides string representation to populate xml pretty formatted content
|
58
|
+
def to_s
|
59
|
+
return "<#{@name}#{attributes_to_s}/>" if @content.nil?
|
60
|
+
content = @content.is_a?(Array) ? array_to_s : CGI.escape_html(@content)
|
61
|
+
"<#{@name}#{attributes_to_s}>#{content}</#{@name}>"
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def attributes_to_s
|
67
|
+
(@attributes || {}).map { |n, v| " #{n}=\"#{v}\"" }.reduce(&:+)
|
68
|
+
end
|
69
|
+
|
70
|
+
def array_to_s
|
71
|
+
nodes = @content.map { |n| "\t#{n}".gsub(/\n/, "\n\t") }
|
72
|
+
"\n#{nodes.join("\n")}\n"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module AlpacaBuildTool
|
2
|
+
##
|
3
|
+
# Font class provides representation of .flf fonts so they can be used
|
4
|
+
class Font
|
5
|
+
attr_reader :height, :hard_blank
|
6
|
+
|
7
|
+
##
|
8
|
+
# Absolute path to data folder where *.flf fonts stored
|
9
|
+
FONTPATH = File.expand_path(File.dirname(__FILE__) + '/../data')
|
10
|
+
|
11
|
+
##
|
12
|
+
# Creates instance of class
|
13
|
+
#
|
14
|
+
# +name+:: font name(currently 'doom' or 'lean' exist)
|
15
|
+
def initialize(name)
|
16
|
+
@filename = File.join FONTPATH, name + '.flf'
|
17
|
+
File.open(@filename, 'rb') do |f|
|
18
|
+
header = f.gets.strip.split(/ /)
|
19
|
+
@hard_blank = header[0]
|
20
|
+
@height = header[1].to_i
|
21
|
+
load_characters f
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Returns true if font have representation for char.ord
|
27
|
+
#
|
28
|
+
# +ord+:: character code(char.ord)
|
29
|
+
def char?(ord)
|
30
|
+
@characters.key? ord
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Returns array of lines that represent current character
|
35
|
+
#
|
36
|
+
# +ord+:: character code(char.ord)
|
37
|
+
def [](ord)
|
38
|
+
@characters[ord]
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def load_characters(file)
|
44
|
+
@characters = {}
|
45
|
+
load_ascii_characters file
|
46
|
+
load_german_characters file
|
47
|
+
load_extended_characters file
|
48
|
+
end
|
49
|
+
|
50
|
+
def load_ascii_characters(file)
|
51
|
+
(32..126).each { |i| @characters[i] = load_char(file) }
|
52
|
+
end
|
53
|
+
|
54
|
+
def load_german_characters(file)
|
55
|
+
[91, 92, 93, 123, 124, 125, 126].each do |i|
|
56
|
+
char = load_char(file)
|
57
|
+
break unless char
|
58
|
+
@characters[i] = char
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def load_extended_characters(file)
|
63
|
+
until file.eof?
|
64
|
+
i = file.gets.strip.split(/ /).first
|
65
|
+
if i && i.empty?
|
66
|
+
next
|
67
|
+
else
|
68
|
+
char = load_char(file)
|
69
|
+
return unless char
|
70
|
+
@characters[i] = char
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def load_char(file)
|
76
|
+
char = []
|
77
|
+
@height.times do
|
78
|
+
return false if file.eof?
|
79
|
+
char << load_line(file)
|
80
|
+
end
|
81
|
+
char
|
82
|
+
end
|
83
|
+
|
84
|
+
def load_line(file)
|
85
|
+
line = file.gets.rstrip
|
86
|
+
match = /(.){1,2}$/.match(line)
|
87
|
+
line.gsub!(match[1], '') if match
|
88
|
+
line << "\x00"
|
89
|
+
line
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|