var path = function() { var root = that.root() , args = [].slice.call(arguments); return Object.create({ absolute : os.path.apply(null, util.cons(root, args)), relative : os.path.apply(null, arguments), path : function() { return path.apply( null, util.cons(this.relative, [].slice.call(arguments))); } }); };
var is_invalid = function() { if (!os.path.exists(storage)) return { msg : "Can't find .git", path: path}; if (!os.path.exists(blob_storage)) return { msg : "Can't find blobs storage", path: path}; if (!os.path.isfile(files.version.tree)) { try_reset_master(); if (!os.path.isfile(files.version.tree)) return { msg : "Can't find .vault anchor", path: path}; } return false; };
var exec_script = function(action) { debug.info('SCRIPT>>>', config.script, 'action', action); if (!os.path.isexec(config.script)) error.raise({msg : "Should be executable" , script : config.script}); var args = ['--action', action, '--dir', data_dir.absolute, '--bin-dir', blobs_dir.absolute, '--home-dir', home ]; var ps = subprocess.system(config.script, args); var trace_res = debug.info; if (ps.rc()) trace_res = debug.error; trace_res("RC", ps.rc()); trace_res("STDOUT", ps.stdout().toString()); trace_res("<<STDOUT"); trace_res("STDERR", ps.stderr().toString()); trace_res("<<STDERR"); trace_res('<<<SCRIPT', config.script, 'action', action, "is done"); if (ps.rc()) { var msg = "Backup script " + config.script + " exited with rc=" + ps.rc(); error.raise({msg: msg, stdout: ps.stdout().toString() , stderr: ps.stderr().toString()}); } };
var backup = function(home, options, on_progress) { if (options) debug.debug(util.dump("Backup", options)); if (!os.path.isDir(home)) error.raise({msg: "Home is not a dir", path: home }); if (typeof(on_progress) !== 'function') on_progress = function(status) { debug.debug(util.dump("Progress", status)); }; options = options || {}; var res = { succeeded :[], failed : [] }; var config = vault_config(); var start_time_tag = sys.date().toGitTag(); var name, message; var backup_unit = function(name) { var head_before = vcs.rev_parse('HEAD'); var unit = mk_unit(config.units()[name], home); try { on_progress({ unit: name, status: "begin" }); unit.backup(); on_progress({ unit: name, status: "ok" }); res.succeeded.push(name); } catch (err) { err.unit = name; debug.error("Can't backup " + name + util.dump("Reason:", err)); on_progress({ unit: name, status: err.reason || "fail" }); res.failed.push(name); unit.reset(head_before); } }; reset(); vcs.checkout('master', ['-f']); if (options.units) { options.units.each(backup_unit); } else { config.units().each(function(name, value) { return backup_unit(name); }); } message = (options.message ? [start_time_tag, options.message].join('\n') : start_time_tag); os.write_file(files.message, message); vcs.add(".message"); vcs.commit([start_time_tag, message].join('\n')); snapshots.tag(start_time_tag); vcs.notes.add(options.message || ""); return res; };
var init_versions = function() { init_version("tree"); vcs.add(files.version.tree); vcs.commit('anchor'); vcs.tag(['anchor']); os.path.isdir(blob_storage) || os.mkdir(blob_storage); init_version("repository"); };
get_version = function(name) { var fname = files.version[name]; var res = 0; if (os.path.isFile(fname)) { var data = os.read_file(fname).toString(); res = (data.isDecimal() ? parseInt(data, 10) : 0); } return res; };
util.forEach(vcs.status(blobs_dir.relative), function(status) { var git_path = status.src; if (status.index === ' ' && status.tree === 'D') return vcs.rm(git_path); // service files are not blobs var fname = os.path.fileName(git_path); var service_prefix = cfg.prefix, len = service_prefix.length; if (fname.length >= len && fname.substr(0, len) == service_prefix) return vcs.add(git_path); return blob(git_path).add(); });
var create_repo = function() { if (vcs.init()) error.raise({ msg : "Can't init git", path : path, stderr : vcs.stderr()}); if (!os.path.exists(storage)) error.raise({ msg : "Can't find .git", path : path, stderr : vcs.stderr()}); };
exclude.read = function() { var exists = false, fname = exclude_path.absolute; if (os.path.isFile(fname)) { var txt = os.read_file(fname).toString(); var lines = string.removeEmpty(txt.split('\n')); lines = _fn.filter(function(line) { return !/ *#/.test(line); }, lines); patterns = _fn.arrayToSet(lines); exists = true; } return exists; };
var restore = function(home, options, on_progress) { if (options) debug.debug(util.dump("Restore", options)); if (!os.path.isDir(home)) error.raise({msg: "Home is not a dir", path: home }); if (typeof(on_progress) !== 'function') on_progress = function(status) { debug.debug(util.dump("Progress", status)); }; options = options || {}; var config = vault_config(); var res = { succeeded :[], failed : [] }; var name; var restore_unit = function(name) { var unit = mk_unit(config.units()[name], home); try { on_progress({ unit: name, status: "begin" }); unit.restore(); on_progress({ unit: name, status: "ok" }); res.succeeded.push(name); } catch (err) { err.unit = name; debug.error("Can't restore " + name + util.dump("Reason:", err)); on_progress({ unit: name, status: err.reason || "fail" }); res.failed.push(name); } }; if (options.units) { options.units.each(restore_unit); } else { config.units().each(function(name, value) { restore_unit(name); }); } };
var add = function() { var origTime; os.path.isDir(blob_dir) || os.mkdir(blob_dir); origTime = os.path.lastModified(link_fname); if (os.path.isFile(blob_fname)) { os.unlink(link_fname); } else { os.rename(link_fname, blob_fname); } os.path.setLastModified(blob_fname, origTime); var target = os.path.relative(blob_fname, os.path.dirname(link_fname)); os.symlink(target, link_fname); if (!(os.path.isSymLink(link_fname) && os.path.isFile(blob_fname))) { error.raise({ msg: "Blob should be symlinked", link: link_fname, target: target }); } vcs.add(git_path); };
var restore_unit = function() { if (!os.path.isDir(root_dir.absolute)) error.raise({reason: "absent", name: name}); exec_script('import'); };
res.exists = function() { return os.path.isDir(res()); };
var exists = function() { return os.path.isdir(path); };
get_state = function() { var fname = files.state; return os.path.isFile() ? os.read_file(files.state).toString() : "unknown"; };