Skip to content

Commit

Permalink
Merge pull request #59 from Beniamiiin/feature/fixIssue52
Browse files Browse the repository at this point in the history
Fixed #52 - Incorrect behavior when generate module which already exists
  • Loading branch information
etolstoy committed Dec 29, 2015
2 parents 364caa0 + b21e677 commit a725e44
Show file tree
Hide file tree
Showing 12 changed files with 140 additions and 39 deletions.
14 changes: 13 additions & 1 deletion generamba/lib/generamba/cli/gen_command.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'thor'
require 'generamba/helpers/rambafile_validator.rb'
require 'generamba/helpers/xcodeproj_helper.rb'

module Generamba::CLI
class Application < Thor
Expand All @@ -20,7 +21,7 @@ def gen(module_name, template_name)

does_rambafile_exist = Dir[RAMBAFILE_NAME].count > 0

if (does_rambafile_exist == false)
unless does_rambafile_exist
puts('Rambafile not found! Run `generamba setup` in the working directory instead!'.red)
return
end
Expand All @@ -39,6 +40,17 @@ def gen(module_name, template_name)
template = ModuleTemplate.new(template_name)
code_module = CodeModule.new(module_name, module_description, rambafile, options)

project = XcodeprojHelper.obtain_project(code_module.xcodeproj_path)
module_group_already_exists = XcodeprojHelper.module_with_group_path_already_exists(project, code_module.module_group_path)

if module_group_already_exists
replace_exists_module = yes?("#{module_name} module already exists. Replace? (yes/no)")

unless replace_exists_module
return
end
end

generator = Generamba::ModuleGenerator.new()
generator.generate_module(module_name, code_module, template)
end
Expand Down
2 changes: 1 addition & 1 deletion generamba/lib/generamba/cli/setup_username_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class SetupUsernameCommand < Thor
no_commands {
def setup_username
username = Generamba::UserPreferences.obtain_username
if username == nil
unless username
puts('The author name is not configured!'.red)
git_username = Git.init.config['user.name']
if git_username != nil && yes?("Your name in git is configured as #{git_username}. Do you want to use it in code headers? (yes/no)")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class Template < Thor
def install
does_rambafile_exist = Dir[RAMBAFILE_NAME].count > 0

if (does_rambafile_exist == false)
unless does_rambafile_exist
puts('Rambafile not found! Run `generamba setup` in the working directory instead!'.red)
return
end
Expand Down
4 changes: 2 additions & 2 deletions generamba/lib/generamba/code_generation/content_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ class ContentGenerator
# @return [String] The generated body
def self.create_file_content(file, code_module, template)
file_template = Tilt.new(template.template_path.join(file[TEMPLATE_FILE_PATH_KEY]))
file_name = File.basename(file[TEMPLATE_FILE_NAME_KEY])
file_name = File.basename(file[TEMPLATE_FILE_NAME_KEY])
module_info = {
'name' => code_module.name,
'file_name' => file_name,
'description' => code_module.description,
'project_name' => code_module.project_name
'project_name' => code_module.project_name
}

developer = {
Expand Down
4 changes: 2 additions & 2 deletions generamba/lib/generamba/configuration/user_preferences.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ def self.obtain_user_preferences_path

path_exists = Dir.exist?(home_path)

if path_exists == false
unless path_exists
FileUtils.mkdir_p home_path
end

preferences_path = home_path.join(USER_PREFERENCES_FILE)
preferences_exist = File.file?(preferences_path)

if preferences_exist == false
unless preferences_exist
File.open(preferences_path, 'w+') { |f| f.write('') }
end

Expand Down
6 changes: 3 additions & 3 deletions generamba/lib/generamba/helpers/rambafile_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def validate(path)
interchangable_fields = [[PROJECT_TARGETS_KEY, PROJECT_TARGET_KEY]]

mandatory_fields.each do |field|
if preferences.has_key?(field) == false
unless preferences.has_key?(field)
error_description = "Rambafile is broken! Cannot find #{field} field, which is mandatory. Either add it manually, or run *generamba setup*.".red
raise StandardError.new(error_description)
end
Expand All @@ -31,13 +31,13 @@ def validate(path)
has_value = preferences.has_key?(field) || has_value
end

if has_value == false
unless has_value
error_description = "Rambafile is broken! Cannot find any of #{fields_array} fields, one of them is mandatory. Either add it manually, or run *generamba setup*.".red
raise StandardError.new(error_description)
end
end

if preferences[TEMPLATES_KEY] == nil
unless preferences[TEMPLATES_KEY]
error_description = "You can't run *generamba gen* without any templates installed. Add their declarations to a Rambafile and run *generamba template install*.".red
raise StandardError.new(error_description)
end
Expand Down
2 changes: 1 addition & 1 deletion generamba/lib/generamba/helpers/template_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def self.obtain_path(template_name)
.join(template_name)

error_description = "Cannot find template named #{template_name}! Add it to the Rambafile and run *generamba template install*".red
raise StandardError.new(error_description) if path.exist? == false
raise StandardError.new(error_description) unless path.exist?

return path
end
Expand Down
115 changes: 106 additions & 9 deletions generamba/lib/generamba/helpers/xcodeproj_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@ def self.obtain_project(project_name)

# Adds a provided file to a specific Project and Target
# @param project [Xcodeproj::Project] The target xcodeproj file
# @param targets [AbstractTarget] Array of tatgets
# @param targets_name [String] Array of targets name
# @param group_path [Pathname] The Xcode group path for current file
# @param file_path [Pathname] The file path for current file
#
# @return [void]
def self.add_file_to_project_and_targets(project, targets, group_path, file_path)
module_group = self.retreive_or_create_group(group_path, project)
def self.add_file_to_project_and_targets(project, targets_name, group_path, file_path)
module_group = self.retreive_group_or_create_if_needed(group_path, project, true)
xcode_file = module_group.new_file(File.absolute_path(file_path))

file_name = File.basename(file_path)
if File.extname(file_name) == '.m'
targets.each do |target|
targets_name.each do |target|
xcode_target = self.obtain_target(target, project)
xcode_target.add_file_references([xcode_file])
end
Expand All @@ -36,27 +36,52 @@ def self.add_file_to_project_and_targets(project, targets, group_path, file_path
# @param group_path [Pathname] The full group path
#
# @return [Void]
def self.clear_group(project, group_path)
module_group = self.retreive_or_create_group(group_path, project)
def self.clear_group(project, targets_name, group_path)
module_group = self.retreive_group_or_create_if_needed(group_path, project, false)
return unless module_group

files_path = self.files_path_from_group(module_group, project)
return unless files_path

files_path.each do |file_path|
self.remove_file_by_file_path(file_path, targets_name, project)
end

module_group.clear
end

# Finds a group in a xcodeproj file with a given path
# @param project [Xcodeproj::Project] The working Xcode project file
# @param group_path [Pathname] The full group path
#
# @return [TrueClass or FalseClass]
def self.module_with_group_path_already_exists(project, group_path)
module_group = self.retreive_group_or_create_if_needed(group_path, project, false)
return module_group == nil ? false : true
end

private

# Finds or creates a group in a xcodeproj file with a given path
# @param group_path [Pathname] The full group path
# @param project [Xcodeproj::Project] The working Xcode project file
# @param create_group_if_not_exists [TrueClass or FalseClass] If true notexistent group will be created
#
# @return [PBXGroup]
def self.retreive_or_create_group(group_path, project)
def self.retreive_group_or_create_if_needed(group_path, project, create_group_if_not_exists)
group_names = group_names_from_group_path(group_path)

final_group = project

group_names.each do |group_name|
next_group = final_group[group_name]
if (next_group == nil)
next_group = final_group.new_group(group_name, group_name)
unless next_group
unless create_group_if_not_exists
return nil
end

new_group_path = group_name
next_group = final_group.new_group(group_name, new_group_path)
end

final_group = next_group
Expand Down Expand Up @@ -89,5 +114,77 @@ def self.group_names_from_group_path(group_path)
groups = group_path.to_s.split('/')
return groups
end

# Remove build file from target build phase
# @param file_path [String] The path of the file
# @param targets_name [String] Array of targets
# @param project [Xcodeproj::Project] The target xcodeproj file
#
# @return [Void]
def self.remove_file_by_file_path(file_path, targets_name, project)
build_phases = self.build_phases_from_targets(targets_name, project)

build_phases.each do |build_phase|
build_phase.files.each do |build_file|
next if build_file.nil? || build_file.file_ref.nil?

build_file_path = self.configure_file_ref_path(build_file.file_ref)

if build_file_path == file_path
build_phase.remove_build_file(build_file)
end
end
end
end

# Find and return target build phases
# @param targets_name [String] Array of targets
# @param project [Xcodeproj::Project] The target xcodeproj file
#
# @return [[PBXSourcesBuildPhase]]
def self.build_phases_from_targets(targets_name, project)
build_phases = []

targets_name.each do |target_name|
xcode_target = self.obtain_target(target_name, project)
xcode_target.build_phases.each do |build_phase|
if build_phase.isa == 'PBXSourcesBuildPhase'
build_phases.push(build_phase)
end
end
end

return build_phases
end

# Get configure file full path
# @param file_ref [PBXFileReference] Build file
#
# @return [String]
def self.configure_file_ref_path(file_ref)
build_file_ref_path = file_ref.hierarchy_path.to_s
build_file_ref_path[0] = ''

return build_file_ref_path
end

# Get all files path from group path
# @param module_group [PBXGroup] The module group
# @param project [Xcodeproj::Project] The target xcodeproj file
#
# @return [[String]]
def self.files_path_from_group(module_group, project)
files_path = []

module_group.recursive_children.each do |file_ref|
if file_ref.isa == 'PBXFileReference'
file_ref_path = self.configure_file_ref_path(file_ref)
files_path.push(file_ref_path)
end
end

return files_path
end

end
end
16 changes: 4 additions & 12 deletions generamba/lib/generamba/module_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ module Generamba

# Responsible for creating the whole code module using information from the CLI
class ModuleGenerator

def generate_module(name, code_module, template)
# Setting up Xcode objects
project = XcodeprojHelper.obtain_project(code_module.xcodeproj_path)
Expand Down Expand Up @@ -57,7 +56,7 @@ def process_files_if_needed(files, name, code_module, template, project, targets
return
end

XcodeprojHelper.clear_group(project, group_path)
XcodeprojHelper.clear_group(project, targets, group_path)
files.each do |file|
# The target file's name consists of three parameters: project prefix, module name and template file name.
# E.g. RDS + Authorization + Presenter.h = RDSAuthorizationPresenter.h
Expand All @@ -68,12 +67,8 @@ def process_files_if_needed(files, name, code_module, template, project, targets
file_group = File.dirname(file[TEMPLATE_NAME_KEY])

# Generating the content of the code file
file_content = ContentGenerator.create_file_content(file,
code_module,
template)
file_path = dir_path
.join(file_group)
.join(file_name)
file_content = ContentGenerator.create_file_content(file, code_module, template)
file_path = dir_path.join(file_group).join(file_name)

# Creating the file in the filesystem
FileUtils.mkdir_p File.dirname(file_path)
Expand All @@ -82,10 +77,7 @@ def process_files_if_needed(files, name, code_module, template, project, targets
end

# Creating the file in the Xcode project
XcodeprojHelper.add_file_to_project_and_targets(project,
targets,
group_path.join(file_group),
file_path)
XcodeprojHelper.add_file_to_project_and_targets(project, targets, group_path.join(file_group), file_path)
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,19 @@ def install_template(template_declaration)

rambaspec_exist = Generamba::RambaspecValidator.validate_spec_existance(template_name, template_path)

if rambaspec_exist == false
unless rambaspec_exist
error_description = "Cannot find #{template_name + RAMBASPEC_EXTENSION} in the template catalog. Try another name.".red
raise StandardError.new(error_description)
end

rambaspec_valid = Generamba::RambaspecValidator.validate_spec(template_name, template_path)
if rambaspec_valid == false
unless rambaspec_valid
error_description = "#{template_name + RAMBASPEC_EXTENSION} is not valid.".red
raise StandardError.new(error_description)
end

install_path = Pathname.new(TEMPLATES_FOLDER)
.join(template_name)
.join(template_name)
FileUtils.mkdir_p install_path
FileUtils.copy_entry(template_path, install_path)
end
Expand Down
4 changes: 2 additions & 2 deletions generamba/lib/generamba/template/installer/local_installer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ def install_template(template_declaration)
local_path = template_declaration.local
rambaspec_exist = Generamba::RambaspecValidator.validate_spec_existance(template_name, local_path)

if rambaspec_exist == false
unless rambaspec_exist
error_description = "Cannot find #{template_name + RAMBASPEC_EXTENSION} in the specified directory. Try another path or name.".red
raise StandardError.new(error_description)
end

rambaspec_valid = Generamba::RambaspecValidator.validate_spec(template_name, local_path)
if rambaspec_valid == false
unless rambaspec_valid
error_description = "#{template_name + RAMBASPEC_EXTENSION} is not valid.".red
raise StandardError.new(error_description)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ def install_template(template_declaration)
Git.clone(repo_url, template_name, :path => temp_path)

rambaspec_exist = Generamba::RambaspecValidator.validate_spec_existance(template_name, template_dir)
if rambaspec_exist == false
unless rambaspec_exist
FileUtils.rm_rf(temp_path)
error_description = "Cannot find #{template_name + RAMBASPEC_EXTENSION} in the root directory of specified repository.".red
raise StandardError.new(error_description)
end

rambaspec_valid = Generamba::RambaspecValidator.validate_spec(template_name, template_dir)
if rambaspec_valid == false
unless rambaspec_valid
error_description = "#{template_name + RAMBASPEC_EXTENSION} is not valid.".red
raise StandardError.new(error_description)
end
Expand Down

0 comments on commit a725e44

Please sign in to comment.