Procházet zdrojové kódy

versions 0.1

version-14
Rushabh Mehta před 14 roky
rodič
revize
30fca54f31
12 změnil soubory, kde provedl 234 přidání a 71 odebrání
  1. +1
    -0
      js/build.json
  2. +2
    -0
      js/core.js
  3. +9
    -4
      js/core.min.js
  4. +3
    -6
      js/wn/assets.js
  5. +42
    -0
      js/wn/versions.js
  6. +3
    -2
      js/wn/xmlhttp.js
  7. +2
    -5
      py/build/__init__.py
  8. +18
    -15
      py/build/bundle.py
  9. +18
    -11
      py/build/project.py
  10. +73
    -27
      py/build/version.py
  11. +9
    -0
      py/webnotes/handler.py
  12. +54
    -1
      wnf.py

+ 1
- 0
js/build.json Zobrazit soubor

@@ -2,6 +2,7 @@
"core.min.js": [ "core.min.js": [
"wn/provide.js", "wn/provide.js",
"wn/xmlhttp.js", "wn/xmlhttp.js",
"wn/versions.js",
"wn/assets.js", "wn/assets.js",
"wn/require.js", "wn/require.js",
"wn/dom.js", "wn/dom.js",


+ 2
- 0
js/core.js Zobrazit soubor

@@ -1,3 +1,5 @@
// find files changed since last version
wn.versions.check();


// load all critical libraries // load all critical libraries
wn.require("lib/js/lib/jquery.min.js"); wn.require("lib/js/lib/jquery.min.js");


+ 9
- 4
js/core.min.js Zobrazit soubor

@@ -5,9 +5,14 @@ parent=parent[n];}}
wn.provide('wn.settings');wn.provide('wn.ui');wn.xmlhttp={request:function(){if(window.XMLHttpRequest) wn.provide('wn.settings');wn.provide('wn.ui');wn.xmlhttp={request:function(){if(window.XMLHttpRequest)
return new XMLHttpRequest();else if(window.ActiveXObject) return new XMLHttpRequest();else if(window.ActiveXObject)
return new ActiveXObject("MsXml2.XmlHttp");},complete:function(req,callback,url){if(req.status==200||req.status==304){callback(req.responseText);}else{alert(url+' request error: '+req.statusText+' ('+req.status+')');}},get:function(url,callback,args,async){if(async===null)async=true;var req=wn.xmlhttp.request();req.onreadystatechange=function(){if(req.readyState==4){wn.xmlhttp.complete(req,callback,url)}} return new ActiveXObject("MsXml2.XmlHttp");},complete:function(req,callback,url){if(req.status==200||req.status==304){callback(req.responseText);}else{alert(url+' request error: '+req.statusText+' ('+req.status+')');}},get:function(url,callback,args,async){if(async===null)async=true;var req=wn.xmlhttp.request();req.onreadystatechange=function(){if(req.readyState==4){wn.xmlhttp.complete(req,callback,url)}}
req.open('GET',url,async);req.send(args?url+'?'+args:null);if(!async){wn.xmlhttp.complete(req,callback,url)}}}
wn.assets={executed_:{},exists:function(src){if('localStorage'in window&&localStorage.getItem(src)&&localStorage.getItem('[ts] '+src)==asset_timestamps_[src])
return true},add:function(src,txt){if('localStorage'in window){localStorage.setItem(src,txt);localStorage.setItem('[ts] '+src,asset_timestamps_[src]);}},get:function(src){return localStorage.getItem(src);},extn:function(src){return src.split('.').slice(-1)[0];},html_src:function(src){if(src.indexOf('/')!=-1){var t=src.split('/').slice(0,-1);t.push('src');t=t.join('/')+'/'+a.split('/').slice(-1)[0];}else{var t='src/'+src;}
var u=args?(url+'?'+args):url;req.open('GET',u,async);req.send(null);if(!async){wn.xmlhttp.complete(req,callback,url)}}}
wn.versions={is_latest:function(){if(window._version_number==(localStorage?localStorage['_version_number']:null)){return true;}
return false;},get_diff:function(){if(!localStorage)return;wn.xmlhttp.get('index.cgi',function(txt){r=JSON.parse(txt);if(r.exc){alert(r.exc);}
wn.versions.set(r.message);},'cmd=get_diff&version_number='+localStorage['_version_number'],false);},set:function(diff){for(var i=0;i<diff.length;i++){localStorage.removeItem(diff[i]);}
localStorage['_version_number']=_version_number;},check:function(){if(localStorage&&!localStorage['_version_number']){localStorage['_version_number']=_version_number;return;}
if(!wn.versions.is_latest())wn.versions.get_diff();}}
wn.assets={executed_:{},exists:function(src){if('localStorage'in window&&localStorage.getItem(src))
return true},add:function(src,txt){if('localStorage'in window){localStorage.setItem(src,txt);}},get:function(src){return localStorage.getItem(src);},extn:function(src){return src.split('.').slice(-1)[0];},html_src:function(src){if(src.indexOf('/')!=-1){var t=src.split('/').slice(0,-1);t.push('src');t=t.join('/')+'/'+a.split('/').slice(-1)[0];}else{var t='src/'+src;}
return t;},load:function(src){var t=wn.assets.extn(src)=='html'?wn.assets.html_src(src):src;wn.xmlhttp.get(t,function(txt){wn.assets.add(src,txt);},'q='&Math.floor(Math.random()*1000),false)},execute:function(src){if(!wn.assets.exists(src)){wn.assets.load(src);} return t;},load:function(src){var t=wn.assets.extn(src)=='html'?wn.assets.html_src(src):src;wn.xmlhttp.get(t,function(txt){wn.assets.add(src,txt);},'q='&Math.floor(Math.random()*1000),false)},execute:function(src){if(!wn.assets.exists(src)){wn.assets.load(src);}
var type=wn.assets.extn(src);if(wn.assets.handler[type]){wn.assets.handler[type](wn.assets.get(src),src);wn.assets.executed_[src]=1;}},handler:{js:function(txt,src){wn.dom.eval(txt);},css:function(txt,src){var se=document.createElement('style');se.type="text/css";if(se.styleSheet){se.styleSheet.cssText=txt;}else{se.appendChild(document.createTextNode(txt));} var type=wn.assets.extn(src);if(wn.assets.handler[type]){wn.assets.handler[type](wn.assets.get(src),src);wn.assets.executed_[src]=1;}},handler:{js:function(txt,src){wn.dom.eval(txt);},css:function(txt,src){var se=document.createElement('style');se.type="text/css";if(se.styleSheet){se.styleSheet.cssText=txt;}else{se.appendChild(document.createTextNode(txt));}
document.getElementsByTagName('head')[0].appendChild(se);},html:function(txt,src){var page=wn.dom.add($('.outer .inner').get(0),'div','content',null,txt);page.setAttribute("_src",src);}}} document.getElementsByTagName('head')[0].appendChild(se);},html:function(txt,src){var page=wn.dom.add($('.outer .inner').get(0),'div','content',null,txt);page.setAttribute("_src",src);}}}
@@ -52,4 +57,4 @@ return reviver.call(holder,key,value);}
text=String(text);cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return'\\u'+ text=String(text);cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return'\\u'+
('0000'+a.charCodeAt(0).toString(16)).slice(-4);});} ('0000'+a.charCodeAt(0).toString(16)).slice(-4);});}
if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof reviver==='function'?walk({'':j},''):j;} if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof reviver==='function'?walk({'':j},''):j;}
throw new SyntaxError('JSON.parse');};}}());wn.require("lib/js/lib/jquery.min.js");wn.require("lib/js/lib/history/history.min.js");$(document).bind('ready',function(){var base=window.location.href.split('#')[0];$.each($('a[softlink!="false"]'),function(i,v){if(v.href.substr(0,base.length)==base){var path=(v.href.substr(base.length));if(path.substr(0,1)!='#'){v.href=base+'#'+path;}}});if(!wn.settings.no_history&&window.location.hash){wn.page.set(window.location.hash.substr(1));}});
throw new SyntaxError('JSON.parse');};}}());wn.versions.check();wn.require("lib/js/lib/jquery.min.js");wn.require("lib/js/lib/history/history.min.js");$(document).bind('ready',function(){var base=window.location.href.split('#')[0];$.each($('a[softlink!="false"]'),function(i,v){if(v.href.substr(0,base.length)==base){var path=(v.href.substr(base.length));if(path.substr(0,1)!='#'){v.href=base+'#'+path;}}});if(!wn.settings.no_history&&window.location.hash){wn.page.set(window.location.hash.substr(1));}});

+ 3
- 6
js/wn/assets.js Zobrazit soubor

@@ -1,19 +1,17 @@
// library to mange assets (js, css, models, html) etc in the app. // library to mange assets (js, css, models, html) etc in the app.
// will try and get from localStorge if latest are available // will try and get from localStorge if latest are available
// or will load them via xmlhttp // or will load them via xmlhttp
// depends on asset_timestamps_ loaded via boot
// depends on wn.versions to manage versioning


wn.assets = { wn.assets = {
// keep track of executed assets // keep track of executed assets
executed_ : {}, executed_ : {},
// check if the asset exists in // check if the asset exists in
// localstorage and if the timestamp
// matches with the loaded timestamp
// localstorage
exists: function(src) { exists: function(src) {
if('localStorage' in window if('localStorage' in window
&& localStorage.getItem(src)
&& localStorage.getItem('[ts] '+src) == asset_timestamps_[src])
&& localStorage.getItem(src))
return true return true
}, },
@@ -22,7 +20,6 @@ wn.assets = {
add: function(src, txt) { add: function(src, txt) {
if('localStorage' in window) { if('localStorage' in window) {
localStorage.setItem(src, txt); localStorage.setItem(src, txt);
localStorage.setItem('[ts] ' + src, asset_timestamps_[src]);
} }
}, },


+ 42
- 0
js/wn/versions.js Zobrazit soubor

@@ -0,0 +1,42 @@
// manage app versioning
// get the last_version_number from the server (loaded)
// and update based on it

wn.versions = {
is_latest: function() {
if(window._version_number == (localStorage ? localStorage['_version_number'] : null)) {
return true;
}
return false;
},
// get the change list of all files
// from current version and local version
get_diff: function() {
if(!localStorage) return;
wn.xmlhttp.get('index.cgi', function(txt) {
// add it to localstorage
r = JSON.parse(txt);
if(r.exc) { alert(r.exc); }
wn.versions.set(r.message);
}, 'cmd=get_diff&version_number=' + localStorage['_version_number'], false);
},
// set will clear all changes since the last update
set: function(diff) {
for(var i=0; i<diff.length; i++) {
localStorage.removeItem(diff[i]);
}
localStorage['_version_number'] = _version_number;
},
check: function() {
if(localStorage && !localStorage['_version_number']) {
// first load
localStorage['_version_number'] = _version_number;
return;
}
if(!wn.versions.is_latest()) wn.versions.get_diff();
}
}

+ 3
- 2
js/wn/xmlhttp.js Zobrazit soubor

@@ -25,8 +25,9 @@ wn.xmlhttp = {
wn.xmlhttp.complete(req, callback, url) wn.xmlhttp.complete(req, callback, url)
} }
} }
req.open('GET', url, async);
req.send(args ? url + '?' + args : null);
var u = args ? (url + '?' + args) : url;
req.open('GET', u, async);
req.send(null);
// for sync // for sync
if(!async) { if(!async) {


+ 2
- 5
py/build/__init__.py Zobrazit soubor

@@ -2,20 +2,17 @@ verbose = True
force_rebuild = False force_rebuild = False
no_minify = False no_minify = False


def run():
def run(path):
""" """
Run the builder Run the builder
""" """
global verbose global verbose
import sys, os import sys, os


sys.path.append('py')
sys.path.append('lib/py')

from build.project import Project from build.project import Project


verbose = True verbose = True
Project().build()
Project().build(path)
if __name__=='__main__': if __name__=='__main__':
run() run()

+ 18
- 15
py/build/bundle.py Zobrazit soubor

@@ -40,7 +40,9 @@ class Bundle:
f = open(outfile, 'w') f = open(outfile, 'w')
f.write(temp.getvalue()) f.write(temp.getvalue())
f.close() f.close()
self.timestamps.update(outfile)

self.vc.repo.add(outfile)

if verbose: print 'Wrote %s' % outfile if verbose: print 'Wrote %s' % outfile


return temp return temp
@@ -50,13 +52,15 @@ class Bundle:
Returns true if the files are changed since last build Returns true if the files are changed since last build
""" """
import os import os
from build import force_rebuild
from build import force_rebuild, verbose


if force_rebuild: if force_rebuild:
return True return True
for f in files: for f in files:
if f in self.timestamps.dirty:
if f in self.dirty:
if verbose:
print '*** %s changed' % f
return True return True
return False return False


@@ -82,7 +86,7 @@ class Bundle:
jsm.minify(temp, out) jsm.minify(temp, out)


out.close() out.close()
self.timestamps.update(outfile)
self.vc.repo.add(outfile)


new_size = os.path.getsize(outfile) new_size = os.path.getsize(outfile)


@@ -92,7 +96,7 @@ class Bundle:
print 'Compressed: %.2f kB' % (new_size / 1024.0) print 'Compressed: %.2f kB' % (new_size / 1024.0)
print 'Reduction: %.1f%%' % (float(org_size - new_size) / org_size * 100) print 'Reduction: %.1f%%' % (float(org_size - new_size) / org_size * 100)


def make(self, path):
def make(self, bpath):
""" """
Build (stitch + compress) the file defined in build.json Build (stitch + compress) the file defined in build.json
""" """
@@ -101,10 +105,12 @@ class Bundle:
# open the build.json file and read # open the build.json file and read
# the dict # the dict
bfile = open(os.path.join(path, 'build.json'), 'r')
bfile = open(bpath, 'r')
bdata = json.loads(bfile.read()) bdata = json.loads(bfile.read())
bfile.close() bfile.close()
path = os.path.dirname(bpath)
for outfile in bdata: for outfile in bdata:
prefix, fname = False, outfile prefix, fname = False, outfile


@@ -115,8 +121,6 @@ class Bundle:
# build the file list relative to the main folder # build the file list relative to the main folder
fl = [os.path.relpath(os.path.join(path, f), os.curdir) for f in bdata[outfile]] fl = [os.path.relpath(os.path.join(path, f), os.curdir) for f in bdata[outfile]]


self.timestamps.bundled += fl

if self.changed(fl): if self.changed(fl):
# js files are minified by default unless explicitly # js files are minified by default unless explicitly
# mentioned in the prefix. # mentioned in the prefix.
@@ -127,16 +131,15 @@ class Bundle:
else: else:
self.concat(fl, os.path.relpath(os.path.join(path, fname), os.curdir)) self.concat(fl, os.path.relpath(os.path.join(path, fname), os.curdir))
def bundle(self, timestamps):
def bundle(self, vc):
""" """
Build js files from "build.json"
Build js files from "build.json" found in version control
""" """
import os import os
self.timestamps = timestamps
self.dirty = vc.repo.uncommitted()
self.vc = vc


# walk the parent folder and build all files as defined in the build.json files # walk the parent folder and build all files as defined in the build.json files
for wt in os.walk('.', followlinks=True):
if 'build.json' in wt[2]:
# found build file
self.make(os.path.abspath(wt[0]))
for b in vc.repo.sql("select fname from bundles"):
self.make(os.path.abspath(os.path.join(vc.root_path, b[0])))



+ 18
- 11
py/build/project.py Zobrazit soubor

@@ -14,11 +14,9 @@ class Project:
""" """
load libraries load libraries
""" """
from build.timestamps import Timestamps
from build.bundle import Bundle from build.bundle import Bundle
from nav import Nav from nav import Nav
self.timestamps = Timestamps()
self.bundle = Bundle() self.bundle = Bundle()
self.nav = Nav() self.nav = Nav()


@@ -29,11 +27,13 @@ class Project:
import json import json


corejs = open('lib/js/core.min.js', 'r') corejs = open('lib/js/core.min.js', 'r')
v = int(self.vc.repo.get_value('last_version_number') or 0) + 1
boot = 'var asset_timestamps_=' + self.timestamps.get('json', ('js', 'html', 'css')) \
+ '\n' + corejs.read()
boot = ('window._version_number="%s"' % str(v)) + \
'\n' + corejs.read()
corejs.close() corejs.close()
return boot return boot


def render_templates(self): def render_templates(self):
@@ -69,15 +69,22 @@ class Project:
print "Rendered %s | %.2fkb" % (fpath, os.path.getsize(fpath) / 1024.0) print "Rendered %s | %.2fkb" % (fpath, os.path.getsize(fpath) / 1024.0)


def build(self):
def build(self, root_path):
""" """
Build all js files, timestamps.js, index.html and template.html
Build all js files, index.html and template.html
""" """
from build.version import VersionControl
# make bundles
self.bundle.bundle(self.timestamps)
self.vc = VersionControl(root_path)
self.vc.add_all()
# index, template if framework is dirty # index, template if framework is dirty
if self.timestamps.dirty:
if self.vc.repo.uncommitted():
self.bundle.bundle(self.vc)
self.render_templates() self.render_templates()
self.timestamps.write()

# again add all bundles
self.vc.add_all()
self.vc.repo.commit()
self.vc.close()

+ 73
- 27
py/build/version.py Zobrazit soubor

@@ -7,6 +7,7 @@
uncommitted (fname, ftype, content, timestamp) uncommitted (fname, ftype, content, timestamp)
files (fname, ftype, content, timestamp, version) files (fname, ftype, content, timestamp, version)
log (fname, ftype, version) log (fname, ftype, version)
bundle_files (fname primary key)
Discussion: Discussion:
@@ -27,23 +28,29 @@ TODO
import unittest import unittest
import os import os


root_path = os.path.abspath(os.path.join(os.path.abspath(os.path.dirname(__file__)), '..', '..'))
test_file = {'fname':'test.js', 'ftype':'js', 'content':'test_code', 'timestamp':'1100'} test_file = {'fname':'test.js', 'ftype':'js', 'content':'test_code', 'timestamp':'1100'}
root_path = os.path.abspath(os.curdir)


def edit_file(): def edit_file():
# edit a file # edit a file
p = os.path.join(root_path, 'js/core.min.js')
content = open(p, 'r').read()
p = os.path.join(root_path, 'lib/js/core.js')

# read
f1 = open(p, 'r')
content = f1.read()
f1.close()
# write
f = open(p, 'w') f = open(p, 'w')
f.write(content) f.write(content)
f.close() f.close()
return p
return os.path.relpath(p, root_path)
verbose = False verbose = False


class TestVC(unittest.TestCase): class TestVC(unittest.TestCase):
def setUp(self): def setUp(self):
self.vc = VersionControl(root_path)
self.vc = VersionControl()
self.vc.repo.setup() self.vc.repo.setup()
def test_add(self): def test_add(self):
@@ -86,13 +93,12 @@ class TestVC(unittest.TestCase):
self.vc.repo.commit() self.vc.repo.commit()


p = edit_file() p = edit_file()

# add # add
self.vc.add_all() self.vc.add_all()


# check if added # check if added
ret = self.vc.repo.sql("select * from uncommitted", as_dict=1) ret = self.vc.repo.sql("select * from uncommitted", as_dict=1)
self.assertTrue(ret[0]['fname']==p)
self.assertTrue(p in [r['fname'] for r in ret])


def test_merge(self): def test_merge(self):
self.vc.add_all() self.vc.add_all()
@@ -114,7 +120,7 @@ class TestVC(unittest.TestCase):
self.vc.merge(self.vc.repo, self.vc.master) self.vc.merge(self.vc.repo, self.vc.master)
log = self.vc.master.diff(int(self.vc.master.get_value('last_version_number'))-1) log = self.vc.master.diff(int(self.vc.master.get_value('last_version_number'))-1)
self.assertTrue(log, [p])
self.assertTrue(p in log)
def tearDown(self): def tearDown(self):
self.vc.close() self.vc.close()
@@ -124,25 +130,26 @@ class TestVC(unittest.TestCase):




class VersionControl: class VersionControl:
def __init__(self, root):
def __init__(self, root=None):
#self.master = Repository(self, 'versions-master.db') #self.master = Repository(self, 'versions-master.db')
self.root(root)
self.set_root(root)


self.repo = Repository(self, 'versions-local.db') self.repo = Repository(self, 'versions-local.db')
self.ignore_folders = ['.git', '.', '..'] self.ignore_folders = ['.git', '.', '..']
self.ignore_files = ['pyc', 'DS_Store', 'txt', 'db-journal', 'db']
self.ignore_files = ['py', 'pyc', 'DS_Store', 'txt', 'db-journal', 'db']
def setup_master(self): def setup_master(self):
self.master = Repository(self, 'versions-master.db') self.master = Repository(self, 'versions-master.db')
def root(self, path=None):
def set_root(self, path=None):
""" """
set / reset root and connect set / reset root and connect
(the root path is the path of the folder)
""" """
if path:
self.root_path = path
else:
return self.root_path
if not path:
raise Exception, 'path must be given'
self.root_path = path
def timestamp(self, path): def timestamp(self, path):
""" """
@@ -164,12 +171,16 @@ class VersionControl:
wt[1].remove(folder) wt[1].remove(folder)
for fname in wt[2]: for fname in wt[2]:
fpath = os.path.join(wt[0], fname)

if fname.endswith('build.json'):
self.repo.add_bundle(fpath)
continue
if fname.split('.')[-1] in self.ignore_files: if fname.split('.')[-1] in self.ignore_files:
# nothing to do # nothing to do
continue continue
fpath = os.path.join(wt[0], fname)
# file does not exist # file does not exist
if not self.repo.exists(fpath): if not self.repo.exists(fpath):
if verbose: if verbose:
@@ -208,6 +219,7 @@ class VersionControl:
target.commit(d[0]) target.commit(d[0])


def close(self): def close(self):
self.repo.conn.commit()
self.repo.conn.close() self.repo.conn.close()
class Repository: class Repository:
@@ -223,12 +235,14 @@ class Repository:
""" """
setup the schema setup the schema
""" """
print "setting up %s..." % self.db_path
self.cur.executescript(""" self.cur.executescript("""
create table properties(pkey primary key, value); create table properties(pkey primary key, value);
create table uncommitted(fname primary key, ftype, content, timestamp); create table uncommitted(fname primary key, ftype, content, timestamp);
create table files (fname primary key, ftype, content, timestamp, version); create table files (fname primary key, ftype, content, timestamp, version);
create table log (fname, ftype, version); create table log (fname, ftype, version);
create table versions (number integer primary key, version); create table versions (number integer primary key, version);
create table bundles(fname primary key);
""") """)
def sql(self, query, values=(), as_dict=None): def sql(self, query, values=(), as_dict=None):
@@ -267,13 +281,17 @@ class Repository:
""" """
add to uncommitted add to uncommitted
""" """
import os
# commit relative path
fname = os.path.relpath(fname, self.vc.root_path)
if not ftype: if not ftype:
ftype = fname.split('.')[-1] ftype = fname.split('.')[-1]
if not timestamp: if not timestamp:
timestamp = self.vc.timestamp(fname) timestamp = self.vc.timestamp(fname)
self.sql("insert into uncommitted(fname, ftype, timestamp, content) values (?, ?, ?, ?)" \
self.sql("insert or replace into uncommitted(fname, ftype, timestamp, content) values (?, ?, ?, ?)" \
, (fname, ftype, timestamp, content)) , (fname, ftype, timestamp, content))
def new_version(self): def new_version(self):
@@ -296,15 +314,30 @@ class Repository:
def commit(self, version=None): def commit(self, version=None):
""" """
rebuild bundles if necessary
copy uncommitted files to repository, update the log and add the change copy uncommitted files to repository, update the log and add the change
""" """
# make bundles
from bundle import Bundle
Bundle().bundle(self.vc)
# get a new version number # get a new version number
if not version:
version = self.new_version()
if not version: version = self.new_version()


self.update_number(version) self.update_number(version)


# find added files to commit # find added files to commit
self.add_from_uncommitted(version)
# clear uncommitted
self.sql("delete from uncommitted")
def add_from_uncommitted(self, version):
"""
move files from uncommitted table to files table
"""
added = self.sql("select * from uncommitted", as_dict=1) added = self.sql("select * from uncommitted", as_dict=1)
for f in added: for f in added:
@@ -316,21 +349,20 @@ class Repository:
""", (f['fname'], f['ftype'], f['timestamp'], f['content'], version)) """, (f['fname'], f['ftype'], f['timestamp'], f['content'], version))
# update log # update log
self.add_log(f['fname'], f['ftype'], version)
# clear uncommitted
self.sql("delete from uncommitted")
self.add_log(f['fname'], f['ftype'], version)
def exists(self, fname): def exists(self, fname):
""" """
true if exists true if exists
""" """
fname = os.path.relpath(fname, self.vc.root_path)
return self.sql("select fname from files where fname=?", (fname,)) return self.sql("select fname from files where fname=?", (fname,))


def timestamp(self, fname): def timestamp(self, fname):
""" """
get timestamp get timestamp
""" """
fname = os.path.relpath(fname, self.vc.root_path)
return int(self.sql("select timestamp from files where fname=?", (fname,))[0][0] or 0) return int(self.sql("select timestamp from files where fname=?", (fname,))[0][0] or 0)


def diff(self, number): def diff(self, number):
@@ -345,6 +377,12 @@ class Repository:
return list(set([f[0] for f in ret])) return list(set([f[0] for f in ret]))
def uncommitted(self):
"""
return list of uncommitted files
"""
return [f[0] for f in self.sql("select fname from uncommitted")]
def get_file(self, fname): def get_file(self, fname):
""" """
return file info as dict return file info as dict
@@ -356,7 +394,15 @@ class Repository:
add file to log add file to log
""" """
self.sql("insert into log(fname, ftype, version) values (?,?,?)", (fname, ftype, version)) self.sql("insert into log(fname, ftype, version) values (?,?,?)", (fname, ftype, version))
def add_bundle(self, fname):
"""
add to bundles
"""
self.sql("insert or replace into bundles(fname) values (?)", (fname,))
if __name__=='__main__': if __name__=='__main__':
import os, sys
sys.path.append('py')
sys.path.append('lib/py')
unittest.main() unittest.main()

+ 9
- 0
py/webnotes/handler.py Zobrazit soubor

@@ -40,6 +40,15 @@ def runserverobj(arg=None):
def logout(): def logout():
webnotes.login_manager.logout() webnotes.login_manager.logout()


# versions
# --------

def get_diff():
import os
v = webnotes.form_dict.get('version_number')
from build.version import VersionControl
webnotes.response['message'] = VersionControl(os.path.abspath(os.path.curdir)).repo.diff(v)

# DocType Mapper # DocType Mapper
# ------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------




+ 54
- 1
wnf.py Zobrazit soubor

@@ -1,4 +1,57 @@
#!/usr/bin/env python #!/usr/bin/env python


print 'hello'
import os, sys


from py.build import version
version.verbose = True


def run():
sys.path.append('lib')
sys.path.append('lib/py')
vc = version.VersionControl(os.path.abspath(os.curdir))

if len(sys.argv)<2:
print "wnframework version control utility"
print
print "Usage: wnf build|add|commit|diff|merge|setup"

cmd = sys.argv[1]

if cmd=='build':
from py import build
build.run(os.path.abspath(os.curdir))
if cmd=='add':
if not len(sys.argv)>1:
print 'usage: wnf add path/to/file'
return
vc.repo.add(sys.argv[2])
if cmd=='commit':
if len(sys.argv>2) and sys.argv[2]=='-a':
vc.add_all()
vc.repo.commit()
if cmd=='diff':
vc.repo.uncommitted()
if cmd=='merge':
vc.setup_master()
if sys.argv[2]=='local':
vc.merge(vc.repo, vc.master)
elif sys.argv[2]=='master':
vc.merge(vc.master, vc.repo)
else:
print "usage: wnf merge local|master"
print "help: parameter (local or master) is the source"

if cmd=='setup':
vc.repo.setup()

vc.close()

if __name__=='__main__':
run()

Načítá se…
Zrušit
Uložit