Skip to content

Instantly share code, notes, and snippets.

@wtfcarlos
Created April 4, 2015 01:40
Show Gist options
  • Save wtfcarlos/e61da516dca638d88c4b to your computer and use it in GitHub Desktop.
Save wtfcarlos/e61da516dca638d88c4b to your computer and use it in GitHub Desktop.
Simple VCS Implementation (Incomplete WIP)
#!/usr/local/bin/python
# -*- coding: utf-8 -*-
from __future__ import with_statement
import os
import json
import docopt
from shutil import rmtree, copytree
VCS_DIR_NAME = '.myvcs'
META_FILENAME = 'META'
SNAPSHOT_COUNTER_KEY = 'snapshot_counter'
META_DEFAULT = {
SNAPSHOT_COUNTER_KEY: 1,
}
def vcs_ignore(curdir, contents):
# Ignore all files / dirs called like VCS_DIR_NAME
return [VCS_DIR_NAME]
def get_meta(path):
try:
with open(path, 'r') as meta_file:
try:
return json.load(meta_file)
except ValueError:
return META_DEFAULT
except IOError:
# The file does not exist. We'll create it when we're over.
return META_DEFAULT
def set_meta(meta, path):
try:
with open(path, 'w+') as meta_file:
json.dump(meta, meta_file)
except IOError:
print "There's no MyVCS repo here! Create one by running ./myvcs.py snap"
def main():
"""MyVCS
Usage:
myvcs.py snap
myvcs.py revert-to <snapshot_id>
"""
# We need these.
cwd = os.getcwd()
vcs_path = os.path.join(cwd, VCS_DIR_NAME)
meta_path = os.path.join(vcs_path, META_FILENAME)
# Parse the docstring to generate a docopt dict.
options = docopt.docopt(main.__doc__)
# Read metadata from file
meta = get_meta(meta_path)
if options['snap']:
# Snap will likely change the metadata.
# This same architecture will remain throughout the application
meta = snap(meta, cwd, vcs_path)
elif options['revert-to']:
# Get snapshot_id from options dict
snapshot_id = options['<snapshot_id>']
meta = revert_to(snapshot_id, meta, cwd, vcs_path)
# Save metadata to file
set_meta(meta, meta_path)
# Gracefully exit.
exit()
def snap(meta, cwd, vcs_path):
"""
This method will read from metadata,
This method must return a new meta dict.
"""
# This snapshot's folder name is governed by what the META file says.
snapshot_id = meta[SNAPSHOT_COUNTER_KEY]
# The absolute path of the new snapshot's tree
snapshot_path = os.path.join(vcs_path, str(snapshot_id))
# The next time, it won't be the same id
meta[SNAPSHOT_COUNTER_KEY] += 1
# Use copytree to snapshot this dir
copytree(cwd, snapshot_path, ignore=vcs_ignore)
return meta
def revert_to(snapshot_id, meta, cwd, vcs_path):
"""
All methods have a 1-1 mapping to console options, for now.
Expects a snapshot_id as str.
Like the method before it, it must return a new meta dict.
"""
# Get the path of the snapshot we're retrieving
snapshot_path = os.path.join(vcs_path, snapshot_id)
# Let's check if it does exist, otherwise, complain.
if os.path.isdir(snapshot_path):
print "There it is!"
else:
print "MyVCS ERROR: No such snapshot [snapshot_id = {}]".format(snapshot_id)
return meta
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment