Module: Dorkbox

Included in:
TestCreation, TestCrontabAdding, TestSync
Defined in:
lib/dorkbox.rb

Constant Summary collapse

CONFLICT_STRING =
'CONFLICT_MUST_MANUALLY_MERGE'
GITIGNORE =
'.gitignore'
DORKBOX_CONFIG_PATH =
File.join(Dir.home, ".dorkbox.yml")
DORKBOX_CRONTAB_COMMENT =
'# dorkbox sync cronjob'

Instance Method Summary collapse

Instance Method Details

#align_client_ref_to_master(dorkbox_client_id) ⇒ Object



106
107
108
# File 'lib/dorkbox.rb', line 106

def align_client_ref_to_master(dorkbox_client_id)
  `git update-ref refs/heads/#{dorkbox_client_id} master`
end

#cleanup_trackedObject



148
149
150
151
152
153
154
155
156
157
# File 'lib/dorkbox.rb', line 148

def cleanup_tracked
  begin
    cfg = YAML.load_file(DORKBOX_CONFIG_PATH)
  rescue Errno::ENOENT
    return
  end
  # TODO: check for dorkbox-enabled dir, e.g. try retrieving client id
  cfg[:track].select! { |d| Dir.exists?(d) }
  File.open(DORKBOX_CONFIG_PATH, 'w') { |f| f.write(cfg.to_yaml) }
end

#configure_client_id(dorkbox_client_id) ⇒ Object



110
111
112
# File 'lib/dorkbox.rb', line 110

def configure_client_id(dorkbox_client_id)
  `git config --local dorkbox.client-id #{dorkbox_client_id}`
end

#connect(dorkbox_remote) ⇒ Object



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/dorkbox.rb', line 190

def connect(dorkbox_remote)
  log "Will create new git repo in local directory and connect to remote existing dorkbox repository #{dorkbox_remote}"
  if Dir.exists?('.git')
    raise StandardError.new("git repository found.")
  end
  `git init`
  `git remote add dorkbox #{dorkbox_remote}`
  `git fetch --all`
  `git checkout master`
  # TODO: check for hostname duplication and/or autogenerate client ids
  dorkbox_client_id = create_new_client_id
  configure_client_id(dorkbox_client_id)
  align_client_ref_to_master(dorkbox_client_id)
  `git push -u dorkbox master #{dorkbox_client_id}`
  track()
  dorkbox_client_id
end

#create(dorkbox_remote) ⇒ Object



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/dorkbox.rb', line 169

def create(dorkbox_remote)
  log "Will create new dorkbox-enabled repository in local directory. Remote #{dorkbox_remote} should exist and be empty."
  if Dir.exists?('.git')
    raise StandardError.new("git repository found.")
  end
  `git init`
  File.open(GITIGNORE, 'a') { |f|
    f.puts(CONFLICT_STRING)
  }
  `git remote add dorkbox #{dorkbox_remote}`
  `git add #{GITIGNORE}`
  `git commit -m 'enabling dorkbox'`
  dorkbox_client_id = create_new_client_id
  configure_client_id(dorkbox_client_id)
  align_client_ref_to_master(dorkbox_client_id)
  `git push -u dorkbox master #{dorkbox_client_id}`
  track()
  log "New dorkbox enabled with remote #{dorkbox_remote}"
  dorkbox_client_id
end

#create_new_client_idObject



102
103
104
# File 'lib/dorkbox.rb', line 102

def create_new_client_id
  'dorkbox-' + Socket.gethostname() + "-" + SecureRandom.urlsafe_base64(5)
end

#enable_dorkbox_cronjob(current_path = File.expand_path(__FILE__)) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/dorkbox.rb', line 118

def enable_dorkbox_cronjob(current_path=File.expand_path(__FILE__))
  cron_start = "#{DORKBOX_CRONTAB_COMMENT} start\n"
  cron_end = "#{DORKBOX_CRONTAB_COMMENT} end\n"
  old_crontab = c('crontab -l 2>/dev/null || /bin/true')
  old_crontab.sub!(/#{cron_start}.*?#{cron_end}/m, '')

  tmp = Tempfile.new("dorkbox-temp")
  if (old_crontab.size > 0) && (old_crontab[-1] != "\n")
    old_crontab.concat("\n")
  end

  old_crontab.concat(cron_start).concat("*/5 * * * * #{current_path}\n").concat(cron_end)
  tmp.puts(old_crontab)
  tmp.flush()
  `crontab #{tmp.path}`
  tmp.close()
end

#retrieve_client_idObject



114
115
116
# File 'lib/dorkbox.rb', line 114

def retrieve_client_id
  dorkbox_client_id = c("git config --get dorkbox.client-id").strip()
end

#syncObject



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/dorkbox.rb', line 209

def sync
  if File.exists?(CONFLICT_STRING)
    log "Conflict found, not syncing."
    raise StandardError.new("Conflict found, not syncing.")
  end
  `git fetch --all`
  `git add -A`
  any_change = c("git diff --staged").strip()
  if !any_change.empty?
    `git commit -m "Automatic dorkbox commit"`
  end
  begin
    dorkbox_client_id = retrieve_client_id
    `git merge --ff-only dorkbox/master`
    align_client_ref_to_master(dorkbox_client_id)
    `git push dorkbox master #{dorkbox_client_id}`
  rescue
    # TODO: check which error actually happens and think about
    # a solving strategy.
    log "Error while syncing, stopping until solved."
    FileUtils.touch(CONFLICT_STRING)
    raise StandardError.new("Conflict found, syncing stopped.")
  end
  log "sync succeeded"
end

#sync_trackedObject



159
160
161
162
163
164
165
166
# File 'lib/dorkbox.rb', line 159

def sync_tracked
  begin
    cfg = YAML.load_file(DORKBOX_CONFIG_PATH)
  rescue Errno::ENOENT
    return
  end
  cfg[:track].each { |d| Dir.chdir(d) { sync() } }
end

#trackObject

we should lock the config file on this.



137
138
139
140
141
142
143
144
145
146
# File 'lib/dorkbox.rb', line 137

def track
  begin
    cfg = YAML.load_file(DORKBOX_CONFIG_PATH)
  rescue Errno::ENOENT
    cfg = {:track => []}
  end
  cfg[:track].push(File.expand_path(Dir.pwd))
  cfg[:track].uniq!
  File.open(DORKBOX_CONFIG_PATH, 'w') { |f| f.write(cfg.to_yaml) }
end