Class: Kerbi::CodeGen::ProjectGenerator

Inherits:
Object
  • Object
show all
Defined in:
lib/main/code_gen.rb

Constant Summary collapse

ERB_EXT =
".erb"
BOILER_REL_PATH =
"/../code-gen/new-project"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(params = {}) ⇒ ProjectGenerator

Set accessors, no other side effects.



26
27
28
29
30
31
# File 'lib/main/code_gen.rb', line 26

def initialize(params={})
  self.project_name = params[:project_name]
  self.root_dir = params[:root_dir]
  self.ruby_version = params[:ruby_version]
  self.verbose = params[:verbose]
end

Instance Attribute Details

#project_nameObject

Serves as both the new project’s dir name and the mixer’s _module name



10
11
12
# File 'lib/main/code_gen.rb', line 10

def project_name
  @project_name
end

#root_dirObject

Mostly for testing, uses this dir as root instead of Dir.pwd



14
15
16
# File 'lib/main/code_gen.rb', line 14

def root_dir
  @root_dir
end

#ruby_versionObject

Optional ruby version to use in the Gemfile



18
19
20
# File 'lib/main/code_gen.rb', line 18

def ruby_version
  @ruby_version
end

#verboseObject

Print as you go?



22
23
24
# File 'lib/main/code_gen.rb', line 22

def verbose
  @verbose
end

Class Method Details

.boiler_file_abs_pathsObject



113
114
115
116
117
118
119
120
121
122
# File 'lib/main/code_gen.rb', line 113

def self.boiler_file_abs_paths
  boiler_dir_path = "#{__dir__}#{BOILER_REL_PATH}"

  is_boiler = ->(fname) { fname.end_with?(ERB_EXT) }
  to_abs = ->(fname) { "#{boiler_dir_path}/#{fname}" }

  boiler_fnames = Dir.entries(boiler_dir_path)
  actual_fnames = boiler_fnames.select(&is_boiler)
  Hash[actual_fnames.map { |f| [f, to_abs[f]] }]
end

.interpolate_file(src_path, data) ⇒ Object



124
125
126
127
128
# File 'lib/main/code_gen.rb', line 124

def self.interpolate_file(src_path, data)
  contents = File.read(src_path)
  binding.local_variable_set(:data, data)
  ERB.new(contents).result(binding)
end

.src_to_dest_file_name(src_file_name) ⇒ Object



102
103
104
# File 'lib/main/code_gen.rb', line 102

def self.src_to_dest_file_name(src_file_name)
  src_file_name[0..-(ERB_EXT.length + 1)]
end

Instance Method Details

#create_dirObject



43
44
45
46
47
48
49
50
51
52
# File 'lib/main/code_gen.rb', line 43

def create_dir
  begin
    Dir.mkdir(new_dir_path)
    print_created('Created project at', new_dir_path)
    true
  rescue Errno::EEXIST
    message = "Error dir already exists: #{new_dir_path}"
    $stderr.puts message.colorize(:red)
  end
end

#generate_dataHash{Symbol->String

Returns a dict with all the key value assignments the ERBs need to do their work.

Returns:

  • (Hash{Symbol->String)

    ] data bundle for interpolation



83
84
85
86
87
88
89
90
# File 'lib/main/code_gen.rb', line 83

def generate_data
  module_name = project_name.underscore.classify
  version = ruby_version || RUBY_VERSION
  {
    user_module_name: module_name,
    ruby_version: version
  }
end

#mk_dest_path(src_file_name) ⇒ String

Generates absolute path of destination file based on filename of source file. E.g Gemfile.erb -> /home/foo/Gemfile

Parameters:

  • src_file_name (String)

    src file name w/o path e.g Gemfile.erb

Returns:

  • (String)

    E.g Gemfile.erb -> /home/foo/Gemfile



97
98
99
100
# File 'lib/main/code_gen.rb', line 97

def mk_dest_path(src_file_name)
  new_fname = self.class.src_to_dest_file_name(src_file_name)
  "#{new_dir_path}/#{new_fname}"
end

#new_dir_pathString

Returns the absolute path of the new project directory based on the constructor arguments

Returns:

  • (String)

    e.g /home/john/hello-kerbi



109
110
111
# File 'lib/main/code_gen.rb', line 109

def new_dir_path
  "#{root_dir || Dir.pwd}/#{project_name}"
end

noinspection RubyResolve



74
75
76
77
# File 'lib/main/code_gen.rb', line 74

def print_created(bold_part, colored_part)
  return unless verbose
  puts "#{bold_part.bold} #{colored_part.colorize(:blue)}"
end


67
68
69
70
71
# File 'lib/main/code_gen.rb', line 67

def print_file_processed(src_file_name)
  pretty_fname = "#{self.class.src_to_dest_file_name(src_file_name)}"
  pretty_name = "#{project_name}/#{pretty_fname}"
  self.print_created("Created file", pretty_name)
end

#process_file(src_file_name, src_file_path) ⇒ Object

Root function for processing a single file, e.g reading its original un-interpolated form, interpolating it, and finally writing the new content to destination directory.

Parameters:

  • src_file_name (String)

    src file name w/o path e.g Gemfile.erb

  • src_file_path (String)

    src file name including abs path



59
60
61
62
63
64
65
# File 'lib/main/code_gen.rb', line 59

def process_file(src_file_name, src_file_path)
  data = generate_data
  new_file_content = self.class.interpolate_file(src_file_path, data)
  new_file_path = mk_dest_path(src_file_name)
  File.write(new_file_path, new_file_content)
  print_file_processed(src_file_name)
end

#runObject

Creates a new directory, writes new interpolated files to it.



35
36
37
38
39
40
41
# File 'lib/main/code_gen.rb', line 35

def run
  return false unless create_dir
  self.class.boiler_file_abs_paths.each do |src_name, src_path|
    process_file(src_name, src_path)
  end
  true
end