Skip to content

Commit

Permalink
Merge pull request #135 from robyurkowski/b-129-dotenv-error-when-das…
Browse files Browse the repository at this point in the history
…herized-application-name

Add ApplicationName, fixing dasherized application names and prohibiting use of restricted words.
  • Loading branch information
jodosha committed Feb 4, 2015
2 parents 0e4952b + 9a7f741 commit 2b182ab
Show file tree
Hide file tree
Showing 8 changed files with 186 additions and 11 deletions.
99 changes: 99 additions & 0 deletions lib/lotus/application_name.rb
@@ -0,0 +1,99 @@
module Lotus
# An application name.
#
# @since x.x.x
class ApplicationName

# A list of words that are prohibited from forming the application name
#
# @since x.x.x
RESERVED_WORDS = %w(lotus).freeze


# Initialize and check against reserved words
#
# An application name needs to be translated in quite a few ways:
# First, it must be checked against a list of reserved words and rejected
# if it is invalid. Secondly, assuming it is not invalid, it must be able
# to be output roughly as given, but with the following changes:
#
# 1. downcased,
# 2. with surrounding spaces removed,
# 3. with internal whitespace rendered as underscores
# 4. with underscores de-duplicated
#
# which is the default output. It must also be transformable into an
# environment variable.
#
# @return [Lotus::ApplicationName] a new instance of the application name
#
# @since x.x.x
def initialize(name)
@name = sanitize(name)
ensure_validity!
end


# Returns the cleaned application name.
#
# @example
# ApplicationName.new("my-App ").to_s # => "my-app"
#
# @since x.x.x
def to_s
@name
end


# Returns the application name uppercased with non-alphanumeric characters
# as underscores.
#
# @example
# ApplicationName.new("my-app").to_env_s => "MY_APP"
#
# @since x.x.x
def to_env_s
@name.upcase.gsub(/\W/, '_')
end


# Returns true if a potential application name matches one of the reserved
# words.
#
# @example
# Lotus::ApplicationName.invalid?("lotus") # => true
#
# @since x.x.x
def self.invalid?(name)
RESERVED_WORDS.include?(name)
end


private

# Raises RuntimeError with explanation if the provided name is invalid.
#
# @api private
# @since x.x.x
def ensure_validity!
if self.class.invalid?(@name)
raise RuntimeError,
"application name must not be any one of the following: " +
RESERVED_WORDS.join(", ")
end
end


# Cleans a string to be a functioning application name.
#
# @api private
# @since x.x.x
def sanitize(name)
name
.downcase
.strip
.gsub(/\s/, '_')
.gsub(/_{2,}/, '_')
end
end
end
13 changes: 7 additions & 6 deletions lib/lotus/commands/new.rb
@@ -1,4 +1,5 @@
require 'pathname'
require 'lotus/application_name'
require 'lotus/utils/string'
require 'lotus/utils/class'

Expand All @@ -9,12 +10,12 @@ class New

attr_reader :app_name, :source, :target, :cli, :options

def initialize(app_name, environment, cli)
@app_name = _get_real_app_name(app_name)
def initialize(app_name_or_path, environment, cli)
@app_name = ApplicationName.new(_get_real_app_name(app_name_or_path))
@options = environment.to_options
@arch = @options.fetch(:architecture)

@target = Pathname.pwd.join(@options.fetch(:path, app_name))
@target = Pathname.pwd.join(@options.fetch(:path, app_name_or_path))
@source = Pathname.new(@options.fetch(:source) { ::File.dirname(__FILE__) + '/../generators/application/' }).join(@arch)

@cli = cli
Expand All @@ -29,12 +30,12 @@ def start
end

private
def _get_real_app_name(app_name)
if app_name.include?(::File::SEPARATOR)
def _get_real_app_name(app_name_or_path)
if app_name_or_path.include?(::File::SEPARATOR)
raise ArgumentError.new("Invalid application name. If you want to set application path, please use --path option")
end

app_name == '.' ? ::File.basename(Dir.getwd) : app_name
app_name_or_path == '.' ? ::File.basename(Dir.getwd) : app_name_or_path
end
end
end
Expand Down
@@ -1,2 +1,2 @@
# Define ENV variables for development environment
<%= config[:app_name].upcase %>_DATABASE_URL="file:///db/<%= config[:app_name] %>_development"
<%= config[:app_name].to_env_s %>_DATABASE_URL="file:///db/<%= config[:app_name] %>_development"
@@ -1,2 +1,2 @@
# Define ENV variables for test environment
<%= config[:app_name].upcase %>_DATABASE_URL="file:///db/<%= config[:app_name] %>_test"
<%= config[:app_name].to_env_s %>_DATABASE_URL="file:///db/<%= config[:app_name] %>_test"
Expand Up @@ -14,7 +14,7 @@ Lotus::Model.configure do
# adapter type: :sql, uri: 'postgres://localhost/<%= config[:app_name] %>_development'
# adapter type: :sql, uri: 'mysql://localhost/<%= config[:app_name] %>_development'
#
adapter type: :file_system, uri: ENV['<%= config[:app_name].upcase %>_DATABASE_URL']
adapter type: :file_system, uri: ENV['<%= config[:app_name].to_env_s %>_DATABASE_URL']

##
# Database mapping
Expand Down
6 changes: 4 additions & 2 deletions lib/lotus/generators/slice.rb
@@ -1,15 +1,17 @@
require 'securerandom'
require 'lotus/generators/abstract'
require 'lotus/utils/string'
require 'lotus/application_name'

module Lotus
module Generators
class Slice < Abstract
def initialize(command)
super

@slice_name = options.fetch(:application)
@upcase_slice_name = @slice_name.upcase
application_name = ApplicationName.new(options.fetch(:application))
@slice_name = application_name.to_s
@upcase_slice_name = application_name.to_env_s
@classified_slice_name = Utils::String.new(@slice_name).classify

@source = Pathname.new(::File.dirname(__FILE__) + '/../generators/slice')
Expand Down
45 changes: 45 additions & 0 deletions test/application_name_test.rb
@@ -0,0 +1,45 @@
require 'test_helper'
require 'lotus/application_name'

describe Lotus::ApplicationName do

describe "formats" do

describe "#to_s" do
it "renders downcased" do
application_name = Lotus::ApplicationName.new("MY-APP")
application_name.to_s.must_equal "my-app"
end

it "renders trimmed" do
application_name = Lotus::ApplicationName.new(" my-app ")
application_name.to_s.must_equal "my-app"
end

it "renders internal spaces as underscores" do
application_name = Lotus::ApplicationName.new("my app")
application_name.to_s.must_equal "my_app"
end

it "renders with underscores de-duplicated" do
application_name = Lotus::ApplicationName.new("my _app")
application_name.to_s.must_equal "my_app"
end
end


describe "to_env_s" do
it "renders uppercased with non-alphanumeric characters as underscores" do
application_name = Lotus::ApplicationName.new("my-app")
application_name.to_env_s.must_equal "MY_APP"
end
end
end


describe "reserved words" do
it "prohibits 'lotus'" do
-> { Lotus::ApplicationName.new("lotus") }.must_raise RuntimeError
end
end
end
28 changes: 28 additions & 0 deletions test/commands/new_test.rb
Expand Up @@ -149,6 +149,15 @@ def container_options
content.must_match %(# Define ENV variables for development environment)
content.must_match %(CHIRP_DATABASE_URL="file:///db/chirp_development")
end

describe "with non-simple application name" do
let(:app_name) { "chirp-two" }

it "sanitizes application names for env variables" do
content = @root.join('config/.env.development').read
content.must_match %(CHIRP_TWO_DATABASE_URL="file:///db/chirp-two_development")
end
end
end

describe 'config/.env.test' do
Expand All @@ -157,6 +166,15 @@ def container_options
content.must_match %(# Define ENV variables for test environment)
content.must_match %(CHIRP_DATABASE_URL="file:///db/chirp_test")
end

describe "with non-simple application name" do
let(:app_name) { "chirp-two" }

it "sanitizes application names for env variables" do
content = @root.join('config/.env.test').read
content.must_match %(CHIRP_TWO_DATABASE_URL="file:///db/chirp-two_test")
end
end
end

describe 'lib/chirp.rb' do
Expand All @@ -169,6 +187,16 @@ def container_options
content.must_match %(mapping do)
content.must_match %(mapping "\#{__dir__}/config/mapping")
end

describe "with non-simple application name" do
let(:app_name) { "chirp-two" }

it "sanitizes application names for env variables" do
content = @root.join('lib/chirp-two.rb').read
content.must_match 'Dir["#{ __dir__ }/chirp-two/**/*.rb"].each { |file| require_relative file }'
content.must_match %(adapter type: :file_system, uri: ENV['CHIRP_TWO_DATABASE_URL'])
end
end
end

describe 'lib/config/mapping.rb' do
Expand Down

0 comments on commit 2b182ab

Please sign in to comment.