Skip to content

Commit

Permalink
Add options to customize generated gemfiles (#191)
Browse files Browse the repository at this point in the history
  • Loading branch information
joe-sharp authored Jul 11, 2022
1 parent 97079f0 commit 40956d3
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 2 deletions.
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,46 @@ group :test do
end
```

Customization
-------------

It is possible to customize the generated Gemfiles by adding a `customize_gemfiles` block to
your `Appraisals` file. The block must contain a hash of key/value pairs. Currently supported
customizations include:
- heading: a string that by default adds "# This file was generated by Appraisal" to the top of each Gemfile, (the string will be commented for you)
- single_quotes: a boolean that controls if strings are single quoted in each Gemfile, defaults to false

### Example Usage

**Appraisals**
```ruby
customize_gemfiles do
{
single_quotes: true,
heading: <<~HEADING
frozen_string_literal: true
File has been generated by Appraisal, do NOT modify it directly!
See the conventions at https://example.com/
HEADING
}
end

appraise "rails-3" do
gem "rails", "3.2.14"
end
```

Using the `Appraisals` file defined above, this is what the resulting `Gemfile` will look like:
```ruby
# frozen_string_literal: true

# File has been generated by Appraisal, do NOT modify it directly!
# See the conventions at https://example.com/

gem 'rails', '3.2.14'
```

Version Control
---------------

Expand Down
21 changes: 19 additions & 2 deletions lib/appraisal/appraisal.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'appraisal/gemfile'
require 'appraisal/command'
require "appraisal/customize"
require 'appraisal/utils'
require 'fileutils'
require 'pathname'
Expand Down Expand Up @@ -62,8 +63,8 @@ def git_source(*args, &block)

def write_gemfile
File.open(gemfile_path, "w") do |file|
signature = "# This file was generated by Appraisal"
file.puts([signature, gemfile.to_s].join("\n\n"))
signature = Customize.heading || "This file was generated by Appraisal"
file.puts([comment_lines(signature), quoted_gemfile].join("\n\n"))
end
end

Expand Down Expand Up @@ -171,5 +172,21 @@ def bundle_options(options)

options_strings.join(" ") if options_strings != []
end

def comment_lines(heading)
heading.lines.map do |line|
if line.lstrip.empty?
line
else
"# #{line}"
end
end.join
end

def quoted_gemfile
return gemfile.to_s unless Customize.single_quotes

gemfile.to_s.tr('"', "'")
end
end
end
5 changes: 5 additions & 0 deletions lib/appraisal/appraisal_file.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'appraisal/appraisal'
require "appraisal/customize"
require 'appraisal/errors'
require 'appraisal/gemfile'

Expand Down Expand Up @@ -33,6 +34,10 @@ def appraise(name, &block)
@appraisals << appraisal
end

def customize_gemfiles(&_block)
Customize.new(yield)
end

private

def run(definitions)
Expand Down
16 changes: 16 additions & 0 deletions lib/appraisal/customize.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module Appraisal
class Customize
def initialize(heading: nil, single_quotes: false)
@@heading = heading
@@single_quotes = single_quotes
end

def self.heading
@@heading ||= nil
end

def self.single_quotes
@@single_quotes ||= false
end
end
end
57 changes: 57 additions & 0 deletions spec/appraisal/appraisal_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,63 @@
expect(output_file.read).to match(/[^\n]*\n\z/m)
end

context "gemfile customization" do
it "generates a gemfile with a custom heading" do
heading = "This file was generated with a custom heading!"
Appraisal::Customize.new(heading: heading)
output_file = Tempfile.new("gemfile")
appraisal = Appraisal::Appraisal.new("custom", "Gemfile")
allow(appraisal).to receive(:gemfile_path).and_return(output_file.path)

appraisal.write_gemfile

expected_output = "# #{heading}"
expect(output_file.read).to start_with(expected_output)
end

it "generates a gemfile with multiple lines of custom heading" do
heading = <<~HEADING
frozen_string_literal: true\n
This file was generated with a custom heading!
HEADING
Appraisal::Customize.new(heading: heading)
output_file = Tempfile.new("gemfile")
appraisal = Appraisal::Appraisal.new("custom", "Gemfile")
allow(appraisal).to receive(:gemfile_path).and_return(output_file.path)

appraisal.write_gemfile

expected_output = <<~HEADING
# frozen_string_literal: true\n
# This file was generated with a custom heading!
HEADING
expect(output_file.read).to start_with(expected_output)
end

it "generates a gemfile with single quotes rather than doubles" do
Appraisal::Customize.new(single_quotes: true)
output_file = Tempfile.new("gemfile")
appraisal = Appraisal::Appraisal.new("quotes", 'gem "foo"')
allow(appraisal).to receive(:gemfile_path).and_return(output_file.path)

appraisal.write_gemfile

expect(output_file.read).to match(/gem 'foo'/)
end

it "does not customize anything by default" do
Appraisal::Customize.new
output_file = Tempfile.new("gemfile")
appraisal = Appraisal::Appraisal.new("fake", 'gem "foo"')
allow(appraisal).to receive(:gemfile_path).and_return(output_file.path)

appraisal.write_gemfile

expected_file = %(# This file was generated by Appraisal\n\ngem "foo"\n)
expect(output_file.read).to eq(expected_file)
end
end

context 'parallel installation' do
include StreamHelpers

Expand Down
18 changes: 18 additions & 0 deletions spec/appraisal/customize_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
require "spec_helper"
require "appraisal/customize"

describe Appraisal::Customize do
it "has defaults" do
expect(described_class.heading).to eq nil
expect(described_class.single_quotes).to eq false
expect { described_class.new }.to_not(change do
[described_class.heading, described_class.single_quotes]
end)
end

it "can override defaults" do
described_class.new(single_quotes: true, heading: "foo")
expect(described_class.heading).to eq "foo"
expect(described_class.single_quotes).to eq true
end
end

0 comments on commit 40956d3

Please sign in to comment.