Class: Gjp::Project
Overview
encapsulates a Gjp project directory
Instance Attribute Summary collapse
-
#full_path ⇒ Object
Returns the value of attribute full_path.
-
#git ⇒ Object
Returns the value of attribute git.
Class Method Summary collapse
-
.find_project_dir(starting_dir) ⇒ Object
finds the project directory up in the tree, like git does.
-
.init(dir) ⇒ Object
inits a new project directory structure.
-
.is_project(dir) ⇒ Object
returns true if the specified directory is a valid gjp project.
Instance Method Summary collapse
-
#dry_run ⇒ Object
starts a dry running phase: files added to kit/ will be added to the kit package, src/ will be reset at the current state when finished.
-
#finish(abort) ⇒ Object
ends a dry-run.
-
#from_directory(subdirectory = "") ⇒ Object
runs a block from the project directory or a subdirectory.
-
#get_package_name(dir) ⇒ Object
returns the package name corresponding to the specified dir, if any raises NoPackageDirectoryError if dir is not a (sub)directory of a package.
-
#get_produced_files(package) ⇒ Object
returns a list of files produced during dry-runs in a certain package.
-
#initialize(path) ⇒ Project
constructor
A new instance of Project.
-
#is_dry_running ⇒ Object
returns true iff we are currently dry-running.
-
#latest_dry_run_directory ⇒ Object
returns the latest dry run start directory.
-
#latest_tag(prefix) ⇒ Object
returns the tag with maximum count for a given tag prefix.
-
#latest_tag_count(prefix) ⇒ Object
returns the maximum tag count for a given tag prefix.
-
#merge_new_content(new_content, path, snapshot_message, tag_prefix) ⇒ Object
replaces content in path with new_content, takes a snapshot using snapshot_message and tag_prefix and 3-way merges new and old content with a previous snapshotted file same path tag_prefix, if it exists.
- #name ⇒ Object
-
#purge_jars ⇒ Object
moves any .jar from src/ to kit/ and links it back.
-
#take_snapshot(message, tag_prefix = nil, tag_message = nil) ⇒ Object
takes a revertable snapshot of this project.
- #version ⇒ Object
Methods included from Logging
Constructor Details
#initialize(path) ⇒ Project
Returns a new instance of Project.
13 14 15 16 |
# File 'lib/gjp/project.rb', line 13 def initialize(path) @full_path = Gjp::Project.find_project_dir(File.(path)) @git = Gjp::Git.new(@full_path) end |
Instance Attribute Details
#full_path ⇒ Object
Returns the value of attribute full_path.
10 11 12 |
# File 'lib/gjp/project.rb', line 10 def full_path @full_path end |
#git ⇒ Object
Returns the value of attribute git.
11 12 13 |
# File 'lib/gjp/project.rb', line 11 def git @git end |
Class Method Details
.find_project_dir(starting_dir) ⇒ Object
finds the project directory up in the tree, like git does
27 28 29 30 31 32 33 34 35 36 |
# File 'lib/gjp/project.rb', line 27 def self.find_project_dir(starting_dir) result = starting_dir while is_project(result) == false && result != "/" result = File.("..", result) end raise NoProjectDirectoryError.new(starting_dir) if result == "/" result end |
.init(dir) ⇒ Object
inits a new project directory structure
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/gjp/project.rb', line 62 def self.init(dir) Dir.chdir(dir) do Gjp::Git.new(".").init FileUtils.mkdir_p "src" FileUtils.mkdir_p "kit" # populate the project with templates and take a snapshot project = Project.new(".") template_manager = Gjp::TemplateManager.new template_manager.copy "output", "." template_manager.copy "kit", "." template_manager.copy "src", "." template_manager.copy "gitignore", ".gitignore" project.take_snapshot "Template files added", :init end end |
.is_project(dir) ⇒ Object
returns true if the specified directory is a valid gjp project
39 40 41 42 43 |
# File 'lib/gjp/project.rb', line 39 def self.is_project(dir) File.directory?(File.join(dir, "src")) && File.directory?(File.join(dir, "kit")) && File.directory?(File.join(dir, ".git")) end |
Instance Method Details
#dry_run ⇒ Object
starts a dry running phase: files added to kit/ will be added to the kit package, src/ will be reset at the current state when finished
85 86 87 88 89 90 91 92 93 94 |
# File 'lib/gjp/project.rb', line 85 def dry_run if is_dry_running return false end current_directory = Pathname.new(Dir.pwd).relative_path_from Pathname.new(@full_path) take_snapshot("Dry-run started", :dry_run_started, current_directory) true end |
#finish(abort) ⇒ Object
ends a dry-run. if abort is true, reverts the whole directory if abort is false, reverts sources and updates output file lists
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/gjp/project.rb', line 104 def finish(abort) if is_dry_running if abort @git.revert_whole_directory(".", latest_tag(:dry_run_started)) @git.delete_tag(latest_tag(:dry_run_started)) else take_snapshot "Changes during dry-run", :dry_run_changed @git.revert_whole_directory("src", latest_tag(:dry_run_started)) take_snapshot "Dry run finished", :dry_run_finished end return true end false end |
#from_directory(subdirectory = "") ⇒ Object
runs a block from the project directory or a subdirectory
180 181 182 183 184 |
# File 'lib/gjp/project.rb', line 180 def from_directory(subdirectory = "") Dir.chdir(File.join(@full_path, subdirectory)) do yield end end |
#get_package_name(dir) ⇒ Object
returns the package name corresponding to the specified dir, if any raises NoPackageDirectoryError if dir is not a (sub)directory of a package
47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/gjp/project.rb', line 47 def get_package_name(dir) dir_path = Pathname.new(File.(dir)).relative_path_from(Pathname.new(@full_path)) components = dir_path.to_s.split(File::SEPARATOR) if components.count >= 2 && components.first == "src" && Dir.exist?(File.join(@full_path, components[0], components[1])) components[1] else raise NoPackageDirectoryError end rescue ArgumentError, NoProjectDirectoryError raise NoPackageDirectoryError.new(dir) end |
#get_produced_files(package) ⇒ Object
returns a list of files produced during dry-runs in a certain package
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/gjp/project.rb', line 192 def get_produced_files(package) dry_run_count = latest_tag_count(:dry_run_changed) log.debug "Getting produced files from #{dry_run_count} dry runs" if dry_run_count >= 1 package_dir = File.join("src", package) (1..dry_run_count).map do |i| @git.changed_files_between("dry_run_started_#{i}", "dry_run_changed_#{i}", package_dir) end .flatten .uniq .sort .map { |file| Pathname.new(file).relative_path_from(Pathname.new(package_dir)).to_s } else [] end end |
#is_dry_running ⇒ Object
returns true iff we are currently dry-running
97 98 99 |
# File 'lib/gjp/project.rb', line 97 def is_dry_running latest_tag_count(:dry_run_started) > latest_tag_count(:dry_run_finished) end |
#latest_dry_run_directory ⇒ Object
returns the latest dry run start directory
187 188 189 |
# File 'lib/gjp/project.rb', line 187 def latest_dry_run_directory @git.(latest_tag(:dry_run_started)) end |
#latest_tag(prefix) ⇒ Object
returns the tag with maximum count for a given tag prefix
170 171 172 |
# File 'lib/gjp/project.rb', line 170 def latest_tag(prefix) "#{prefix}_#{latest_tag_count(prefix)}" end |
#latest_tag_count(prefix) ⇒ Object
returns the maximum tag count for a given tag prefix
175 176 177 |
# File 'lib/gjp/project.rb', line 175 def latest_tag_count(prefix) @git.get_tag_maximum_suffix(prefix) end |
#merge_new_content(new_content, path, snapshot_message, tag_prefix) ⇒ Object
replaces content in path with new_content, takes a snapshot using snapshot_message and tag_prefix and 3-way merges new and old content with a previous snapshotted file same path tag_prefix, if it exists. returns the number of conflicts
138 139 140 141 142 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 |
# File 'lib/gjp/project.rb', line 138 def merge_new_content(new_content, path, , tag_prefix) from_directory do log.debug "merging new content to #{path} with prefix #{tag_prefix}" already_existing = File.exist? path previous_tag = latest_tag(tag_prefix) if already_existing log.debug "moving #{path} to #{path}.gjp_user_edited" File.rename path, "#{path}.gjp_user_edited" end File.open(path, "w") { |io| io.write(new_content) } log.debug "taking snapshot with new content: #{snapshot_message}" take_snapshot(, tag_prefix) if already_existing if previous_tag == "" previous_tag = latest_tag(tag_prefix) log.debug "there was no tag with prefix #{tag_prefix} before snapshot" log.debug "defaulting to #{previous_tag} after snapshot" end # 3-way merge conflict_count = @git.merge_with_tag("#{path}", "#{path}.gjp_user_edited", previous_tag) File.delete "#{path}.gjp_user_edited" return conflict_count end return 0 end end |
#name ⇒ Object
18 19 20 |
# File 'lib/gjp/project.rb', line 18 def name File.basename(@full_path) end |
#purge_jars ⇒ Object
moves any .jar from src/ to kit/ and links it back
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/gjp/project.rb', line 210 def purge_jars from_directory do result = [] Find.find("src") do |file| if file =~ /.jar$/ && !File.symlink?(file) new_location = File.join("kit", "jars", Pathname.new(file).split[1]) FileUtils.mv(file, new_location) link_target = Pathname.new(new_location) .relative_path_from(Pathname.new(file).split.first) .to_s File.symlink(link_target, file) result << [file, new_location] end end result end end |
#take_snapshot(message, tag_prefix = nil, tag_message = nil) ⇒ Object
takes a revertable snapshot of this project
122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/gjp/project.rb', line 122 def take_snapshot(, tag_prefix = nil, = nil) tag = ( if tag_prefix "#{tag_prefix}_#{latest_tag_count(tag_prefix) + 1}" else nil end ) @git.commit_whole_directory(, tag, ) end |
#version ⇒ Object
22 23 24 |
# File 'lib/gjp/project.rb', line 22 def version latest_tag_count(:dry_run_finished) end |