Created
April 4, 2015 01:40
-
-
Save wtfcarlos/e61da516dca638d88c4b to your computer and use it in GitHub Desktop.
Simple VCS Implementation (Incomplete WIP)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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