Class: Fones::Builder

Inherits:
Object
  • Object
show all
Defined in:
lib/fones/builder.rb

Instance Method Summary collapse

Constructor Details

#initialize(project) ⇒ Builder

Returns a new instance of Builder.



8
9
10
11
12
13
14
15
16
17
18
# File 'lib/fones/builder.rb', line 8

def initialize(project)
  @project = project
  @task    = project.task
  @templates_path = @project.templates_path
  @assets_path = @project.assets_path
  @functions_path = @project.functions_path
  @includes_path = @project.includes_path
  @package_path = @project.package_path

  init_sprockets
end

Instance Method Details

#buildObject

Runs all the methods necessary to build a completed project



21
22
23
24
25
26
27
# File 'lib/fones/builder.rb', line 21

def build
  clean_build_directory
  copy_templates
  copy_functions
  copy_includes
  build_assets
end

#build_assetsObject



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/fones/builder.rb', line 143

def build_assets
  [['style.css'], ['css', 'ie.css'], ['css', 'login.css'], ['js', 'theme.js'], ['js', 'admin.js']].each do |asset|
    destination = File.join(@project.build_path, asset)

    sprocket = @sprockets.find_asset(asset.last)

    # Catch any sprockets errors and continue the process
    begin
      @task.shell.mute do
        FileUtils.mkdir_p(File.dirname(destination)) unless File.directory?(File.dirname(destination))
        sprocket.write_to(destination) unless sprocket.nil?

        if @project.config[:compress_js] && destination.end_with?('.js')
          require "yui/compressor"

          # Grab the initial sprockets output
          sprockets_output = File.open(destination, 'r').read

          # Re-write the file, minified
          File.open(destination, 'w') do |file|
            file.write(YUI::JavaScriptCompressor.new.compress(sprockets_output))
          end
        end
      end
    rescue Exception => e
      @task.say "Error while building #{asset.last}:"
      @task.say e.message, Thor::Shell::Color::RED
      File.open(destination, 'w') do |file|
        file.puts(e.message)
      end

      # Re-initializing sprockets to prevent further errors
      # TODO: This is done for lack of a better solution
      init_sprockets
    end
  end

  # Copy the images directory over
  FileUtils.cp_r(File.join(@assets_path, 'img'), @project.build_path) if File.exists?(File.join(@assets_path, 'img'))

  # Check for screenshot and move it into main build directory
  Dir.glob(File.join(@project.build_path, 'img', '*')).each do |filename|
    if filename.index(/(screenshot|favicon)\.(png|jpg|jpeg|gif|ico)/)
      FileUtils.mv(filename, @project.build_path + File::SEPARATOR )
    end
  end
end

#clean_build_directoryObject

Empty out the build directory



65
66
67
# File 'lib/fones/builder.rb', line 65

def clean_build_directory
  FileUtils.rm_rf Dir.glob(File.join(@project.build_path, '*'))
end

#clean_functionsObject



93
94
95
96
# File 'lib/fones/builder.rb', line 93

def clean_functions
  FileUtils.rm File.join(@project.build_path, 'functions.php')
  FileUtils.rm_rf File.join(@project.build_path, 'library')
end

#clean_imagesObject



139
140
141
# File 'lib/fones/builder.rb', line 139

def clean_images
  FileUtils.rm_rf File.join(@project.build_path, 'img')
end

#clean_includesObject



124
125
126
# File 'lib/fones/builder.rb', line 124

def clean_includes
  FileUtils.rm_rf File.join(@project.build_path, 'includes')
end

#clean_templatesObject



69
70
71
72
73
74
# File 'lib/fones/builder.rb', line 69

def clean_templates
  # TODO: cleaner way of removing templates only?
  Dir.glob(File.join(@project.build_path, '*.php')).each do |path|
    FileUtils.rm path unless path.include?('functions.php')
  end
end

#copy_functionsObject



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/fones/builder.rb', line 98

def copy_functions
  functions_erb_path = File.join(@functions_path, 'functions.php.erb')
  functions_php_path = File.join(@functions_path, 'functions.php')

  if File.exists?(functions_erb_path)
    destination = File.join(@project.build_path, 'functions.php')
    write_erb(functions_erb_path, destination)
  elsif File.exists?(functions_php_path)
    FileUtils.cp functions_php_path, @project.build_path
  end

  library_paths = Dir.glob(File.join(@functions_path, '*')).reject do |filename|
    [functions_erb_path, functions_php_path].include?(filename)
  end

  unless library_paths.empty?

    # Iterate over all files in source/library, skipping the actual functions.php file
    paths = Dir.glob(File.join(@functions_path, '**', '*')).reject do |filename|
      [functions_erb_path, functions_php_path].include?(filename)
    end

    copy_paths_with_erb(paths, @functions_path, @project.build_path)
  end
end

#copy_includesObject



128
129
130
131
132
133
134
135
136
137
# File 'lib/fones/builder.rb', line 128

def copy_includes
  unless Dir.glob(File.join(@includes_path, '*')).empty?
    # Create the includes folder in the build directory
    FileUtils.mkdir(File.join(@project.build_path, 'includes'))

    # Iterate over all files in source/includes, so we can exclude if necessary
    paths = Dir.glob(File.join(@includes_path, '**', '*'))
    copy_paths_with_erb(paths, @includes_path, File.join(@project.build_path, 'includes'))
  end
end

#copy_templatesObject



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/fones/builder.rb', line 76

def copy_templates
  template_paths.each do |template_path|
    # Skip directories
    next if File.directory?(template_path)

    if template_path.end_with?('.erb')
      # Chop the .erb extension off the filename
      destination = File.join(@project.build_path, File.basename(template_path).slice(0..-5))

      write_erb(template_path, destination)
    else
      # Regular old copy of PHP-only files
      FileUtils.cp template_path, @project.build_path
    end
  end
end

#zip(filename = nil) ⇒ Object

Use the rubyzip library to build a zip from the generated source



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/fones/builder.rb', line 30

def zip(filename=nil)
  filename = filename || File.basename(@project.root)
  project_base = File.basename(@project.root)

  zip_filename = File.join(File.basename(@package_path), "#{filename}.zip")
  # Create a temporary file for RubyZip to write to
  temp_filename = "#{zip_filename}.tmp"

  File.delete(temp_filename) if File.exists?(temp_filename)

  # Wrapping the zip creation in Thor's create_file to get "overwrite" prompts
  # Note: I could be overcomplicating this
  @task.create_file(zip_filename) do
    Zip::ZipFile.open(temp_filename, Zip::ZipFile::CREATE) do |zip|
      # Get all filenames in the build directory recursively
      filenames = Dir[File.join(@project.build_path, '**', '*')]

      # Remove the build directory path from the filename
      filenames.collect! {|path| path.gsub(/#{@project.build_path}\//, '')}

      # Add each file in the build directory to the zip file
      filenames.each do |filename|
        zip.add File.join(project_base, filename), File.join(@project.build_path, filename)
      end
    end

    # Give Thor contents of zip file for "overwrite" prompt
    File.open(temp_filename, 'rb') { |f| f.read }
  end

  # Clean up the temp file
  File.delete(temp_filename)
end