Class: CodeRunner::Repository
- Defined in:
- lib/coderunner/repository.rb
Overview
This is a class which implements methods for managing a CodeRunner repository, which is a slightly customised git repository. It contains methods for initializing standard files, and maintains a small amount of metadata about the repository. In addition, every clone of coderunner repository comes in a pair: one bare repository, and one local repository, which is a clone of the bare repository. This allows easy synchronisation of working directories without the need for a central server which all working directories have access to.
Class Method Summary collapse
- .bare_ext_reg ⇒ Object
-
.check_bare_ext(barefolder) ⇒ Object
Check that barefolder ends in .cr.git.
- .clone(url, name) ⇒ Object
- .init(folder) ⇒ Object
-
.open_in_subfolder(folder = Dir.pwd) ⇒ Object
Open a git object from within a subfolder of a repository Checks to see if the subfolder actually is inside a CodeRunner repository.
-
.repo_folder(folder = Dir.pwd) ⇒ Object
If the folder is within a coderunner repository return the root folder of the repository; else return nil.
- .simple_clone ⇒ Object
- .simple_init ⇒ Object
- .split_url(url) ⇒ Object
- .try_system(str) ⇒ Object
- .url_regex ⇒ Object
Instance Method Summary collapse
- #add_folder(folder) ⇒ Object
- #add_remote(name, url) ⇒ Object
- #autocommit(*args) ⇒ Object
- #autocommit_all(*args) ⇒ Object
- #bare_ext_reg ⇒ Object
-
#bare_repo ⇒ Object
Returns a Git::Base object referring to the bare twin repository.
- #deleted_in_folder(folder) ⇒ Object
- #init_defaults_folder ⇒ Object
- #init_metadata ⇒ Object
- #init_readme ⇒ Object
- #metadata ⇒ Object
- #modified?(file) ⇒ Boolean
- #modified_in_folder(folder) ⇒ Object (also: #changed_in_folder)
-
#pull(remote) ⇒ Object
Pull from the given remote object.
-
#push(remote) ⇒ Object
Push to the given remote object.
- #readme_text ⇒ Object
- #relative_path(folder = Dir.pwd) ⇒ Object
- #repo_file(path) ⇒ Object
-
#rsyncd(remote_name, folder) ⇒ Object
Bring all files in the given folder from the given remote.
-
#rsyncu(remote_name, folder) ⇒ Object
Send all files in the given folder to the given remote.
- #simple_pull ⇒ Object
-
#simple_push ⇒ Object
A simple git push…
- #split_url(remote_name) ⇒ Object
- #try_system(str) ⇒ Object
Class Method Details
.bare_ext_reg ⇒ Object
51 52 53 |
# File 'lib/coderunner/repository.rb', line 51 def self. /\.cr\.git$/ end |
.check_bare_ext(barefolder) ⇒ Object
Check that barefolder ends in .cr.git
253 254 255 256 257 |
# File 'lib/coderunner/repository.rb', line 253 def self.() unless =~ raise "Remotes must end in .cr.git for coderunnerrepo" end end |
.clone(url, name) ⇒ Object
74 75 76 77 78 79 |
# File 'lib/coderunner/repository.rb', line 74 def clone(url, name) namehost, folder, = split_url(url) try_system %[ssh #{namehost} "cd #{folder} && git push origin"] simple_clone(url, bflocal=name+'.cr.git', bare: true, repository: bflocal) return simple_clone(bflocal, name) end |
.init(folder) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/coderunner/repository.rb', line 61 def init(folder) if folder =~ /\.git$/ raise "Please do not add '.git' to the end of #{folder}. Two repositories will be created: a bare repo ending in .cr.git and a clone of this bare repo" end super(bflocal = folder + '.cr.git', bare: true, repository: bflocal) repo = simple_clone(bflocal, folder) repo. repo.init_readme repo.init_defaults_folder p 'remotes', repo.remotes.map{|r| r.name} repo.simple_push(repo.remote("origin")) end |
.open_in_subfolder(folder = Dir.pwd) ⇒ Object
Open a git object from within a subfolder of a repository Checks to see if the subfolder actually is inside a CodeRunner repository.
98 99 100 101 102 |
# File 'lib/coderunner/repository.rb', line 98 def self.open_in_subfolder(folder = Dir.pwd) f2 = repo_folder(folder) raise "#{folder} is not a coderunner repository " if not f2 return open(f2) end |
.repo_folder(folder = Dir.pwd) ⇒ Object
If the folder is within a coderunner repository return the root folder of the repository; else return nil
85 86 87 88 89 90 91 92 93 94 |
# File 'lib/coderunner/repository.rb', line 85 def self.repo_folder(folder = Dir.pwd) f2 = File.(folder) while not (Dir.entries(f2).include?('.git') and Dir.entries(f2).include?('.code_runner_repo_metadata')) f2 = File.(f2 + '/..') (f2=nil; break) if f2 == '/' #p 'f2 is ', f2 end return f2 end |
.simple_clone ⇒ Object
73 |
# File 'lib/coderunner/repository.rb', line 73 alias :simple_clone :clone |
.simple_init ⇒ Object
60 |
# File 'lib/coderunner/repository.rb', line 60 alias :simple_init :init |
.split_url(url) ⇒ Object
187 188 189 190 191 192 193 194 |
# File 'lib/coderunner/repository.rb', line 187 def self.split_url(url) url =~ Repository.url_regex namehost = $~[:namehost] = $~[:folder] () folder = .sub(/\.cr\.git$/, '') return [namehost, folder, ] end |
.try_system(str) ⇒ Object
301 302 303 |
# File 'lib/coderunner/repository.rb', line 301 def self.try_system(str) RepositoryManager.try_system(str) end |
.url_regex ⇒ Object
48 49 50 |
# File 'lib/coderunner/repository.rb', line 48 def self.url_regex (/(?:ssh:\/\/)?(?<namehost>[^\/:]+):?(?<folder>.*$)/) end |
Instance Method Details
#add_folder(folder) ⇒ Object
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/coderunner/repository.rb', line 131 def add_folder(folder) Dir.chdir(folder) do require 'find' #files = [] Find.find('.') { |e| (puts e; add(e)) if e =~ /code_runner_info.rb/ or e =~ /code_runner_results.rb/ or e =~ /.code-runner-irb-save-history/ or e =~ /.code_runner_script_defaults.rb/ or (Dir.entries(Dir.pwd).include?('.code_runner_script_defaults') and (repo_file_match = ( rcp = CodeRunner.fetch_runner(Y: folder, U: true).run_class.rcp; rcp.repo_file_match? ? rcp.repo_file_match : false); repo_file_match =~ m ) ) } end autocommit_all("Added folder #{relative_path(folder)}") end |
#add_remote(name, url) ⇒ Object
243 244 245 246 247 248 249 250 |
# File 'lib/coderunner/repository.rb', line 243 def add_remote(name, url) url =~ Repository.url_regex = $~[:folder] unless =~ Repository. raise "All remotes must end in .cr.git for coderunnerrepo" end super(name, url) end |
#autocommit(*args) ⇒ Object
151 152 153 |
# File 'lib/coderunner/repository.rb', line 151 def autocommit(*args) commit(*args) if [:autocommit] end |
#autocommit_all(*args) ⇒ Object
154 155 156 |
# File 'lib/coderunner/repository.rb', line 154 def autocommit_all(*args) commit_all(*args) if [:autocommit] end |
#bare_ext_reg ⇒ Object
259 260 261 |
# File 'lib/coderunner/repository.rb', line 259 def self.class. end |
#bare_repo ⇒ Object
Returns a Git::Base object referring to the bare twin repository.
105 106 107 108 |
# File 'lib/coderunner/repository.rb', line 105 def #puts 'bare_repo', dir.to_s + '.cr.git' @bare_repo ||= Git::Base.(dir.to_s + '.cr.git') end |
#deleted_in_folder(folder) ⇒ Object
202 203 204 |
# File 'lib/coderunner/repository.rb', line 202 def deleted_in_folder(folder) (status.deleted).find_all{|k,f| File.(dir.to_s + '/' + f.path).include?(File.(folder))} end |
#init_defaults_folder ⇒ Object
157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/coderunner/repository.rb', line 157 def init_defaults_folder FileUtils.makedirs(repo_file("defaults_files")) File.open(repo_file("defaults_files/README"), "w"){|f| f.puts <<EOF This folder is where defaults files for codes should be placed, with paths such as defaults_files/<code>crmod/my_defaults.rb. This folder will automatically be checked for defaults files when submitting simulations within this repository. EOF } add(repo_file("defaults_files/README")) autocommit_all('Added defaults folder') end |
#init_metadata ⇒ Object
120 121 122 123 124 125 126 127 |
# File 'lib/coderunner/repository.rb', line 120 def Hash.phoenix(repo_file('.code_runner_repo_metadata')) do |hash| hash[:creation_time] = Time.now.to_i hash[:autocommit] = true end add(repo_file('.code_runner_repo_metadata')) autocommit_all('Added metadata') end |
#init_readme ⇒ Object
115 116 117 118 119 |
# File 'lib/coderunner/repository.rb', line 115 def init_readme File.open(repo_file("README.md"), "w"){|f| f.puts readme_text} add(repo_file("README.md")) autocommit_all('Added README.md') end |
#metadata ⇒ Object
128 129 130 |
# File 'lib/coderunner/repository.rb', line 128 def Hash.phoenix(repo_file('.code_runner_repo_metadata')) end |
#modified?(file) ⇒ Boolean
205 206 207 |
# File 'lib/coderunner/repository.rb', line 205 def modified?(file) (status.changed + status.added).find{|k,f| File.(dir.to_s + '/' + f.path).include?(File.(file))} end |
#modified_in_folder(folder) ⇒ Object Also known as: changed_in_folder
198 199 200 |
# File 'lib/coderunner/repository.rb', line 198 def modified_in_folder(folder) (status.changed + status.added + status.deleted).find_all{|k,f| File.(dir.to_s + '/' + f.path).include?(File.(folder))} end |
#pull(remote) ⇒ Object
Pull from the given remote object. remote must be a remote object from the twin bare repo, i.e. a member of bare_repo.remotes NOT a remote from the coderunner repo (which only ever has one remote: origin, corresponding to the bare repo).
269 270 271 272 273 274 275 276 277 |
# File 'lib/coderunner/repository.rb', line 269 def pull(remote) namehost, folder, = split_url(remote.name) try_system %[ssh #{namehost} "cd #{folder} && git push origin"] Dir.chdir(.repo.to_s) do try_system("git fetch #{remote.name} master:master") end #bare_repo.fetch(remote) simple_pull(remote('origin')) end |
#push(remote) ⇒ Object
Push to the given remote object. remote must be a remote object from the twin bare repo, i.e. a member of bare_repo.remotes NOT a remote from the coderunner repo (which only ever has one remote: origin, corresponding to the bare repo).
First push to the bare ‘.git’ twin repo, then push that bare repo to the remote, then pull remote repos from the remote bare repos.
290 291 292 293 294 295 296 297 |
# File 'lib/coderunner/repository.rb', line 290 def push(remote) namehost, folder, = split_url(remote.name) puts 'simple_push' simple_push(remote('origin')) puts 'bare_repo.push' .push(remote) try_system %[ssh #{namehost} "cd #{folder} && git pull origin"] end |
#readme_text ⇒ Object
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/coderunner/repository.rb', line 171 def readme_text return <<EOF #{File.basename(dir.path)} CodeRunner Repository ================================================ This is a coderunner repository, which consists of a managed set of simulation folders and defaults files which are synchronised across systems using git. This readme is a stub which was created automatically... feel free to modify this and describe this repo. Created on: #{Time.now.to_s} EOF end |
#relative_path(folder = Dir.pwd) ⇒ Object
109 110 111 |
# File 'lib/coderunner/repository.rb', line 109 def relative_path(folder=Dir.pwd) File.(folder).sub(File.(dir.to_s) + '/', '') end |
#repo_file(path) ⇒ Object
112 113 114 |
# File 'lib/coderunner/repository.rb', line 112 def repo_file(path) "#{dir}/#{path}" end |
#rsyncd(remote_name, folder) ⇒ Object
Bring all files in the given folder from the given remote. (Obviously folder must be a subfolder within the repository).
211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/coderunner/repository.rb', line 211 def rsyncd(remote_name, folder) namehost, remote_folder, = split_url(remote_name) rpath = relative_path(folder) if File.(folder) == File.(dir.to_s) raise "Cannot run rsyncd in the top level of a repository" end string = "rsync -av #{namehost}:#{remote_folder}/#{rpath}/ #{folder}/" if changed_in_folder(folder).size > 0 raise "You have some uncommitted changes in the folder #{folder}. Please commit these changes before calling rsyncd" end puts string system string end |
#rsyncu(remote_name, folder) ⇒ Object
Send all files in the given folder to the given remote. (Obviously folder must be a subfolder within the repository).
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/coderunner/repository.rb', line 227 def rsyncu(remote_name, folder) namehost, remote_folder, = split_url(remote_name) rpath = relative_path(folder) if File.(folder) == File.(dir.to_s) raise "Cannot run rsyncd in the top level of a repository" end string = "rsync -av #{folder}/ #{namehost}:#{remote_folder}/#{rpath}/" cif = `ssh #{namehost} "cd #{remote_folder}/#{rpath} && echo "START" && git status"` if cif =~ /START.*modified/m raise "You have some uncommitted changes in the remote folder #{rpath}. Please commit these changes before calling rsyncu" end puts string system string end |
#simple_pull ⇒ Object
263 |
# File 'lib/coderunner/repository.rb', line 263 alias :simple_pull :pull |
#simple_push ⇒ Object
A simple git push… does not try to push to local bare repo or pull remote working repos
280 |
# File 'lib/coderunner/repository.rb', line 280 alias :simple_push :push |
#split_url(remote_name) ⇒ Object
195 196 197 |
# File 'lib/coderunner/repository.rb', line 195 def split_url(remote_name) return self.class.split_url(.remote(remote_name).url) end |
#try_system(str) ⇒ Object
298 299 300 |
# File 'lib/coderunner/repository.rb', line 298 def try_system(str) RepositoryManager.try_system(str) end |