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.
-
.init(folder) ⇒ Object
Create a coderunner repo, which consists of a twin set of a bare repo and a clone of that repo.
-
.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.
- .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
47 48 49 |
# File 'lib/coderunner/repository.rb', line 47 def self. /\.cr\.git$/ end |
.check_bare_ext(barefolder) ⇒ Object
Check that barefolder ends in .cr.git
234 235 236 237 238 |
# File 'lib/coderunner/repository.rb', line 234 def self.() unless =~ raise "Remotes must end in .cr.git for coderunnerrepo" end end |
.init(folder) ⇒ Object
Create a coderunner repo, which consists of a twin set of a bare repo and a clone of that repo. folder must end in ‘.cr.git’
55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/coderunner/repository.rb', line 55 def self.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(folder + '.cr.git', bare: true) repo = clone(folder + '.cr.git', 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.
83 84 85 86 87 |
# File 'lib/coderunner/repository.rb', line 83 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
70 71 72 73 74 75 76 77 78 79 |
# File 'lib/coderunner/repository.rb', line 70 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 |
.url_regex ⇒ Object
44 45 46 |
# File 'lib/coderunner/repository.rb', line 44 def self.url_regex (/(?:ssh:\/\/)?(?<namehost>[^\/:]+):?(?<folder>.*$)/) end |
Instance Method Details
#add_folder(folder) ⇒ Object
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/coderunner/repository.rb', line 115 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
224 225 226 227 228 229 230 231 |
# File 'lib/coderunner/repository.rb', line 224 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
135 136 137 |
# File 'lib/coderunner/repository.rb', line 135 def autocommit(*args) commit(*args) if [:autocommit] end |
#autocommit_all(*args) ⇒ Object
138 139 140 |
# File 'lib/coderunner/repository.rb', line 138 def autocommit_all(*args) commit_all(*args) if [:autocommit] end |
#bare_ext_reg ⇒ Object
240 241 242 |
# File 'lib/coderunner/repository.rb', line 240 def self.class. end |
#bare_repo ⇒ Object
Returns a Git::Base object referring to the bare twin repository.
90 91 92 |
# File 'lib/coderunner/repository.rb', line 90 def @bare_repo ||= Git::Base.open(dir.to_s + '.cr.git') end |
#deleted_in_folder(folder) ⇒ Object
183 184 185 |
# File 'lib/coderunner/repository.rb', line 183 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
141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/coderunner/repository.rb', line 141 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
104 105 106 107 108 109 110 111 |
# File 'lib/coderunner/repository.rb', line 104 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
99 100 101 102 103 |
# File 'lib/coderunner/repository.rb', line 99 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
112 113 114 |
# File 'lib/coderunner/repository.rb', line 112 def Hash.phoenix(repo_file('.code_runner_repo_metadata')) end |
#modified?(file) ⇒ Boolean
186 187 188 |
# File 'lib/coderunner/repository.rb', line 186 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
179 180 181 |
# File 'lib/coderunner/repository.rb', line 179 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).
250 251 252 253 254 255 |
# File 'lib/coderunner/repository.rb', line 250 def pull(remote) namehost, folder, = split_url(remote.name) try_system %[ssh #{namehost} "cd #{folder} && git push origin"] .pull(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.
268 269 270 271 272 273 |
# File 'lib/coderunner/repository.rb', line 268 def push(remote) namehost, folder, = split_url(remote.name) simple_push(remote('origin')) .push(remote) try_system %[ssh #{namehost} "cd #{folder} && git pull origin"] end |
#readme_text ⇒ Object
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/coderunner/repository.rb', line 155 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
93 94 95 |
# File 'lib/coderunner/repository.rb', line 93 def relative_path(folder=Dir.pwd) File.(folder).sub(File.(dir.to_s) + '/', '') end |
#repo_file(path) ⇒ Object
96 97 98 |
# File 'lib/coderunner/repository.rb', line 96 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).
192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/coderunner/repository.rb', line 192 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).
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/coderunner/repository.rb', line 208 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
244 |
# File 'lib/coderunner/repository.rb', line 244 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
258 |
# File 'lib/coderunner/repository.rb', line 258 alias :simple_push :push |
#split_url(remote_name) ⇒ Object
171 172 173 174 175 176 177 178 |
# File 'lib/coderunner/repository.rb', line 171 def split_url(remote_name) .remote(remote_name).url =~ Repository.url_regex namehost = $~[:namehost] = $~[:folder] self.class.() folder = .sub(/\.cr\.git$/, '') return [namehost, folder, ] end |
#try_system(str) ⇒ Object
274 275 276 |
# File 'lib/coderunner/repository.rb', line 274 def try_system(str) RepositoryManager.try_system(str) end |