From a7a09867edbd3377bac4f7560f4ac7d86f6248a6 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 14 Sep 2011 18:55:15 +0530 Subject: [PATCH] fixes in versions and making startup versionable --- js/core.min.js | 9 +- js/legacy/widgets/dialog.js | 8 +- js/legacy/wnf.compressed.js | 8 +- js/wn/assets.js | 10 ++ js/wn/require.js | 6 +- js/wn/xmlhttp.js | 9 +- py/build/version.py | 169 +++++++++++++++++++------------ py/webnotes/handler.py | 3 +- py/webnotes/model/doc.py | 10 +- py/webnotes/startup.py | 171 +++++++++++++++++++++++++++++++ py/webnotes/tests.py | 2 +- py/webnotes/utils/nestedset.py | 177 +++++++++++++++++++++++++++++---- wnf.py | 48 +++++---- 13 files changed, 510 insertions(+), 120 deletions(-) create mode 100644 py/webnotes/startup.py diff --git a/js/core.min.js b/js/core.min.js index 5eaed40bb7..2a626cb57a 100644 --- a/js/core.min.js +++ b/js/core.min.js @@ -5,19 +5,20 @@ parent=parent[n];}} wn.provide('wn.settings');wn.provide('wn.ui');wn.xmlhttp={request:function(){if(window.XMLHttpRequest) 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)}} -var u=args?(url+'?'+args):url;req.open('GET',u,async);req.send(null);if(!async){wn.xmlhttp.complete(req,callback,url)}}} +var sep=(args.indexOf('?')==-1?'?':'&');var u=args?(url+sep+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;i0) - self.vc.repo.commit() + self.vc.commit() p = edit_file() # add @@ -103,19 +97,18 @@ class TestVC(unittest.TestCase): def test_merge(self): self.vc.add_all() - self.vc.repo.commit() + self.vc.commit() # write the file self.vc.repo.conn.commit() # make master (copy) - os.system('cp %s %s' % (os.path.join(root_path, 'versions-local.db'), os.path.join(root_path, 'versions-master.db'))) self.vc.setup_master() p = edit_file() self.vc.add_all() - self.vc.repo.commit() + self.vc.commit() self.vc.merge(self.vc.repo, self.vc.master) @@ -124,39 +117,66 @@ class TestVC(unittest.TestCase): def tearDown(self): self.vc.close() - os.remove(self.vc.repo.db_path) - - - + if os.path.exists(self.vc.local_db_name()): + os.remove(self.vc.local_db_name()) + if os.path.exists(self.vc.master_db_name()): + os.remove(self.vc.master_db_name()) class VersionControl: - def __init__(self, root=None): - #self.master = Repository(self, 'versions-master.db') + def __init__(self, root=None, testing=False): + self.testing = testing + self.set_root(root) - self.repo = Repository(self, 'versions-local.db') + self.repo = Repository(self, self.local_db_name()) self.ignore_folders = ['.git', '.', '..'] self.ignore_files = ['py', 'pyc', 'DS_Store', 'txt', 'db-journal', 'db'] + def local_db_name(self): + """return local db name""" + return os.path.join(self.root_path, 'versions-local.db' + (self.testing and '.test' or '')) + + def master_db_name(self): + """return master db name""" + return os.path.join(self.root_path, 'versions-master.db' + (self.testing and '.test' or '')) + def setup_master(self): - self.master = Repository(self, 'versions-master.db') + """ + setup master db from local (if not present) + """ + import os + if not os.path.exists(self.master_db_name()): + os.system('cp %s %s' % (self.local_db_name(), self.master_db_name())) + + self.master = Repository(self, self.master_db_name()) def set_root(self, path=None): """ set / reset root and connect (the root path is the path of the folder) """ + import os if not path: - raise Exception, 'path must be given' + path = os.path.abspath(os.path.curdir) self.root_path = path + def relpath(self, fname): + """ + get relative path from root path + """ + import os + return os.path.relpath(fname, self.root_path) + def timestamp(self, path): """ returns timestamp """ import os - return int(os.stat(path).st_mtime) + if os.path.exists(path): + return int(os.stat(path).st_mtime) + else: + return 0 def add_all(self): """ @@ -182,7 +202,7 @@ class VersionControl: continue # file does not exist - if not self.repo.exists(fpath): + if not self.exists(fpath): if verbose: print "%s added" % fpath self.repo.add(fpath) @@ -217,16 +237,44 @@ class VersionControl: target.add(**f) target.commit(d[0]) + + """ + short hand + """ + def commit(self, version=None): + """commit to local""" + self.repo.commit(version) + + def add(self, **args): + """add to local""" + self.repo.add(**args) + def remove(self, fname): + """remove from local""" + self.repo.add(fname=fname, action='remove') + + def exists(self, fname): + """exists in local""" + return len(self.repo.sql("select fname from files where fname=?", (self.relpath(fname),))) + + def get_file(self, fname): + """return file""" + return self.repo.sql("select * from files where fname=?", (self.relpath(fname),), as_dict=1)[0] + + def close(self): self.repo.conn.commit() self.repo.conn.close() - + + + + class Repository: - def __init__(self, vc, fname = 'versions-local.db'): + def __init__(self, vc, fname): self.vc = vc import sqlite3 + self.db_path = os.path.join(self.vc.root_path, fname) self.conn = sqlite3.connect(self.db_path) self.cur = self.conn.cursor() @@ -238,7 +286,7 @@ class Repository: print "setting up %s..." % self.db_path self.cur.executescript(""" 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, action); create table files (fname primary key, ftype, content, timestamp, version); create table log (fname, ftype, version); create table versions (number integer primary key, version); @@ -277,22 +325,26 @@ class Repository: self.sql("insert or replace into properties(pkey, value) values (?, ?)", (key,value)) - def add(self, fname, ftype=None, timestamp=None, content=None, version=None): + def add(self, fname, ftype=None, timestamp=None, content=None, version=None, action=None): """ add to uncommitted """ import os + + if not timestamp: + timestamp = self.vc.timestamp(fname) + # commit relative path - fname = os.path.relpath(fname, self.vc.root_path) + fname = self.vc.relpath(fname) + if not action: + action = 'add' + if not ftype: ftype = fname.split('.')[-1] - - if not timestamp: - timestamp = self.vc.timestamp(fname) - - self.sql("insert or replace into uncommitted(fname, ftype, timestamp, content) values (?, ?, ?, ?)" \ - , (fname, ftype, timestamp, content)) + + self.sql("insert or replace into uncommitted(fname, ftype, timestamp, content, action) values (?, ?, ?, ?, ?)" \ + , (fname, ftype, timestamp, content, action)) def new_version(self): """ @@ -340,29 +392,28 @@ class Repository: added = self.sql("select * from uncommitted", as_dict=1) for f in added: + if f['action']=='add': + # move them to "files" + self.sql(""" + insert or replace into files + (fname, ftype, timestamp, content, version) + values (?,?,?,?,?) + """, (f['fname'], f['ftype'], f['timestamp'], f['content'], version)) + + elif f['action']=='remove': + self.sql("""delete from files where fname=?""", (f['fname'],)) + + else: + raise Exception, 'bad action %s' % action - # move them to "files" - self.sql(""" - insert or replace into files - (fname, ftype, timestamp, content, version) - values (?,?,?,?,?) - """, (f['fname'], f['ftype'], f['timestamp'], f['content'], version)) - # update log self.add_log(f['fname'], f['ftype'], version) - def exists(self, fname): - """ - true if exists - """ - fname = os.path.relpath(fname, self.vc.root_path) - return self.sql("select fname from files where fname=?", (fname,)) - def timestamp(self, fname): """ get timestamp """ - fname = os.path.relpath(fname, self.vc.root_path) + fname = self.vc.relpath(fname) return int(self.sql("select timestamp from files where fname=?", (fname,))[0][0] or 0) def diff(self, number): @@ -383,12 +434,6 @@ class Repository: """ return [f[0] for f in self.sql("select fname from uncommitted")] - def get_file(self, fname): - """ - return file info as dict - """ - return self.sql("select * from files where fname=?", (fname,), as_dict=1)[0] - def add_log(self, fname, ftype, version): """ add file to log diff --git a/py/webnotes/handler.py b/py/webnotes/handler.py index 6b0aa3ee87..0933bf4613 100755 --- a/py/webnotes/handler.py +++ b/py/webnotes/handler.py @@ -44,10 +44,9 @@ def logout(): # -------- 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) + webnotes.response['message'] = VersionControl().repo.diff(v) # DocType Mapper # ------------------------------------------------------------------------------------ diff --git a/py/webnotes/model/doc.py b/py/webnotes/model/doc.py index 38e4896227..6a6a15596f 100755 --- a/py/webnotes/model/doc.py +++ b/py/webnotes/model/doc.py @@ -95,8 +95,14 @@ class Document: def _loadfromdb(self, doctype = None, name = None): if name: self.name = name if doctype: self.doctype = doctype - - if webnotes.model.meta.is_single(self.doctype): + + is_single = False + try: + is_single = webnotes.model.meta.is_single(self.doctype) + except Exception, e: + pass + + if is_single: self._loadsingle() else: dataset = webnotes.conn.sql('select * from `%s%s` where name="%s"' % (self._prefix, self.doctype, self.name.replace('"', '\"'))) diff --git a/py/webnotes/startup.py b/py/webnotes/startup.py new file mode 100644 index 0000000000..dfb666135b --- /dev/null +++ b/py/webnotes/startup.py @@ -0,0 +1,171 @@ +""" + startup info for the app + + client needs info that is static across all users + and user specific info like roles and defaults + + so calling will be: + index.cgi?cmd=webnotes.startup.common_info + index.cgi?cmd=webnotes.startup.user_info&user=x@y.com + + to clear startup, + you must clear all files in the vcs starting with index.cgi?cmd=webnotes.startup +""" + +import webnotes + + +def get_letter_heads(): + """ + get letter head + """ + import webnotes + try: + lh = {} + ret = webnotes.conn.sql("select name, content from `tabLetter Head` where ifnull(disabled,0)=0") + for r in ret: + lh[r[0]] = r[1] + return lh + except Exception, e: + if e.args[0]==1146: + return {} + else: + raise Exception, e + + + + +def get_content_user(): + """ + get user specific content + """ + import webnotes + import webnotes.utils + import webnotes.widgets.page + import webnotes.widgets.menus + + user = webnotes.form_dict['user'] + doclist, ret = [], {} + + webnotes.conn.begin() + ret['profile'] = webnotes.user.load_profile() + home_page = webnotes.user.get_home_page() + if home_page: + doclist += webnotes.widgets.page.get(home_page) + + ret['sysdefaults'] = webnotes.utils.get_defaults() + ret['home_page'] = home_page or '' + + # role-wise menus + ret['start_items'] = webnotes.widgets.menus.get_menu_items() + + # bundle + webnotes.session['data']['profile'] = ret['profile'] + if webnotes.session['data'].get('ipinfo'): + ret['ipinfo'] = webnotes.session['data']['ipinfo'] + + webnotes.conn.commit() + + webnotes.response['docs'] = doclist + + return ret + +def get_content_common(): + """ + build common startup info + """ + + import webnotes + import webnotes.model.doc + import webnotes.model.doctype + import webnotes.model + + doclist, ret = [], {} + doclist += webnotes.model.doc.get('Control Panel') + doclist += webnotes.model.doctype.get('Event') + doclist += webnotes.model.doctype.get('Search Criteria') + + cp = doclist[0] + ret['account_name'] = cp.account_id or '' + ret['letter_heads'] = get_letter_heads() + ret['dt_labels'] = webnotes.model.get_dt_labels() + + webnotes.response['docs'] = doclist + + return ret + + +def common_info(): + """ + get common startup info (from version or live) + """ + get_info('index.cgi?cmd=webnotes.startup.common_info', 'common') + +def user_info(): + """ + get user info + """ + user = webnotes.form_dict['user'] + get_info('index.cgi?cmd=webnotes.startup.user_info&user='+user, 'user') + +def get_info(fname, key): + """ + get info from version or re-build + """ + from build.version import VersionControl + + vc = VersionControl() + + # from versions (same static) + + if vc.exists(fname): + content = vc.get_file(fname)['content'] + else: + content = globals().get('get_content_'+key)() + import json + content = json.dumps(content) + + # add in vcs + vc.add(fname=fname, content=content) + vc.commit() + + vc.close() + + webnotes.response['content'] = content + return + + + + + +def clear_info(info_type=None): + """ + clear startup info and force a new version + + parameter: info_type = 'user' or 'common' or 'all' + """ + if not info_type: + info_type = webnotes.form_dict.get('info_type') + + from build.version import VersionControl + vc = VersionControl() + + flist = [] + + if info_type=='common': + flist = ['index.cgi?cmd=webnotes.startup.common_info'] + elif info_type=='user': + flist = [f[0] for f in vc.repo.sql("""select fname from files where fname like ?""",\ + ('index.cgi?cmd=webnotes.startup.user_info%',))] + elif info_type=='all': + flist = [f[0] for f in vc.repo.sql("""select fname from files where fname like ?""",\ + ('index.cgi?cmd=webnotes.startup%',))] + else: + webnotes.msgprint("info_type not found: %s" % info_type) + + for f in flist: + print 'clearing %s' % f + vc.remove(f) + + vc.commit() + vc.close() \ No newline at end of file diff --git a/py/webnotes/tests.py b/py/webnotes/tests.py index 1506ef7ec8..bb75dd8561 100644 --- a/py/webnotes/tests.py +++ b/py/webnotes/tests.py @@ -15,7 +15,7 @@ import sys, os import unittest # webnotes path -sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) +sys.path.append('lib/py') # modules path import webnotes diff --git a/py/webnotes/utils/nestedset.py b/py/webnotes/utils/nestedset.py index 97cf156074..a80bec14ba 100644 --- a/py/webnotes/utils/nestedset.py +++ b/py/webnotes/utils/nestedset.py @@ -8,29 +8,149 @@ # ------------------------------------------ -import webnotes +import webnotes, unittest + +class TestNSM(unittest.TestCase): + + def setUp(self): + from webnotes.model.doc import Document + self.root = Document(fielddata={'doctype':'nsmtest', 'name':'T001', 'parent':None}) + self.first_child = Document(fielddata={'doctype':'nsmtest', 'name':'C001', 'parent_node':'T001'}) + self.first_sibling = Document(fielddata={'doctype':'nsmtest', 'name':'C002', 'parent_node':'T001'}) + self.grand_child = Document(fielddata={'doctype':'nsmtest', 'name':'GC001', 'parent_node':'C001'}) + + webnotes.conn.sql(""" + create table `tabnsmtest` ( + name varchar(120) not null primary key, + creation datetime, + modified datetime, + modified_by varchar(40), + owner varchar(40), + docstatus int(1) default '0', + parent varchar(120), + parentfield varchar(120), + parenttype varchar(120), + idx int(8), + parent_node varchar(180), + old_parent varchar(180), + lft int, + rgt int) ENGINE=InnoDB""") + + def test_root(self): + self.root.save(1) + update_nsm(self.root) + self.assertTrue(self.root.lft==1) + self.assertTrue(self.root.rgt==2) + + def test_first_child(self): + self.root.save(1) + update_nsm(self.root) + + self.first_child.save(1) + update_nsm(self.first_child) + + self.root._loadfromdb() + + self.assertTrue(self.root.lft==1) + self.assertTrue(self.first_child.lft==2) + self.assertTrue(self.first_child.rgt==3) + self.assertTrue(self.root.rgt==4) + + def test_sibling(self): + self.test_first_child() + + self.first_sibling.save(1) + update_nsm(self.first_sibling) + + self.root._loadfromdb() + self.first_child._loadfromdb() + + self.assertTrue(self.root.lft==1) + self.assertTrue(self.first_child.lft==2) + self.assertTrue(self.first_child.rgt==3) + self.assertTrue(self.first_sibling.lft==4) + self.assertTrue(self.first_sibling.rgt==5) + self.assertTrue(self.root.rgt==6) + + def test_remove_sibling(self): + self.test_sibling() + self.first_sibling.parent_node = '' + update_nsm(self.first_sibling) + + self.root._loadfromdb() + self.first_child._loadfromdb() + + self.assertTrue(self.root.lft==1) + self.assertTrue(self.first_child.lft==2) + self.assertTrue(self.first_child.rgt==3) + self.assertTrue(self.root.rgt==4) + self.assertTrue(self.first_sibling.lft==5) + self.assertTrue(self.first_sibling.rgt==6) + + def test_change_parent(self): + self.test_sibling() + + # add grand child + self.grand_child.save(1) + update_nsm(self.grand_child) + + # check lft rgt + self.assertTrue(self.grand_child.lft==3) + self.assertTrue(self.grand_child.rgt==4) + + # change parent + self.grand_child.parent_node = 'C002' + self.grand_child.save() + + # update + update_nsm(self.grand_child) + + # check lft rgt + self.assertTrue(self.grand_child.lft==5) + self.assertTrue(self.grand_child.rgt==6) + + + def tearDown(self): + webnotes.conn.sql("drop table tabnsmtest") + + # called in the on_update method def update_nsm(doc_obj): # get fields, data from the DocType - d = doc_obj.doc + pf, opf = 'parent_node', 'old_parent' - if hasattr(doc_obj,'nsm_parent_field'): - pf = doc_obj.nsm_parent_field - if hasattr(doc_obj,'nsm_oldparent_field'): - opf = doc_obj.nsm_oldparent_field - p, op = d.fields[pf], d.fields.get(opf, '') + + if str(doc_obj.__class__)=='webnotes.model.doc.Document': + # passed as a Document object + d = doc_obj + else: + # passed as a DocType object + d = doc_obj.doc + if hasattr(doc_obj,'nsm_parent_field'): + pf = doc_obj.nsm_parent_field + if hasattr(doc_obj,'nsm_oldparent_field'): + opf = doc_obj.nsm_oldparent_field + + p, op = d.fields.get(pf, ''), d.fields.get(opf, '') # has parent changed (?) or parent is None (root) - if not doc_obj.doc.lft and not doc_obj.doc.rgt: - update_add_node(doc_obj.doc.doctype, doc_obj.doc.name, p or '', pf) + if not d.lft and not d.rgt: + update_add_node(d.doctype, d.name, p or '', pf) elif op != p: - update_remove_node(doc_obj.doc.doctype, doc_obj.doc.name) - update_add_node(doc_obj.doc.doctype, doc_obj.doc.name, p or '', pf) + update_remove_node(d.doctype, d.name) + update_add_node(d.doctype, d.name, p or '', pf) + # set old parent webnotes.conn.set(d, opf, p or '') + + # reload + d._loadfromdb() def rebuild_tree(doctype, parent_field): + """ + call rebuild_node for all root nodes + """ # get all roots right = 1 result = webnotes.conn.sql("SELECT name FROM `tab%s` WHERE `%s`='' or `%s` IS NULL" % (doctype, parent_field, parent_field)) @@ -38,6 +158,12 @@ def rebuild_tree(doctype, parent_field): right = rebuild_node(doctype, r[0], right, parent_field) def rebuild_node(doctype, parent, left, parent_field): + """ + reset lft, rgt and recursive call for all children + """ + from webnotes.utils import now + n = now() + # the right value of this node is the left value + 1 right = left+1 @@ -48,37 +174,50 @@ def rebuild_node(doctype, parent, left, parent_field): # we've got the left value, and now that we've processed # the children of this node we also know the right value - webnotes.conn.sql('UPDATE `tab%s` SET lft=%s, rgt=%s WHERE name="%s"' % (doctype,left,right,parent)) + webnotes.conn.sql("UPDATE `tab%s` SET lft=%s, rgt=%s, modified='%s' WHERE name='%s'" % (doctype,left,right,n,parent)) #return the right value of this node + 1 return right+1 def update_add_node(doctype, name, parent, parent_field): + """ + insert a new node + """ + from webnotes.utils import now + n = now() + # get the last sibling of the parent if parent: right = webnotes.conn.sql("select rgt from `tab%s` where name='%s'" % (doctype, parent))[0][0] else: # root right = webnotes.conn.sql("select ifnull(max(rgt),0)+1 from `tab%s` where ifnull(`%s`,'') =''" % (doctype, parent_field))[0][0] right = right or 1 - + # update all on the right - webnotes.conn.sql("update `tab%s` set rgt = rgt+2 where rgt >= %s" %(doctype,right)) - webnotes.conn.sql("update `tab%s` set lft = lft+2 where lft >= %s" %(doctype,right)) + webnotes.conn.sql("update `tab%s` set rgt = rgt+2, modified='%s' where rgt >= %s" %(doctype,n,right)) + webnotes.conn.sql("update `tab%s` set lft = lft+2, modified='%s' where lft >= %s" %(doctype,n,right)) # update index of new node if webnotes.conn.sql("select * from `tab%s` where lft=%s or rgt=%s"% (doctype, right, right+1)): webnotes.msgprint("Nested set error. Please send mail to support") raise Exception - webnotes.conn.sql("update `tab%s` set lft=%s, rgt=%s where name='%s'" % (doctype,right,right+1,name)) + webnotes.conn.sql("update `tab%s` set lft=%s, rgt=%s, modified='%s' where name='%s'" % (doctype,right,right+1,n,name)) return right def update_remove_node(doctype, name): + """ + remove a node + """ + from webnotes.utils import now + n = now() + left = webnotes.conn.sql("select lft from `tab%s` where name='%s'" % (doctype,name)) if left[0][0]: # reset this node - webnotes.conn.sql("update `tab%s` set lft=0, rgt=0 where name='%s'" % (doctype,name)) + webnotes.conn.sql("update `tab%s` set lft=0, rgt=0, modified='%s' where name='%s'" % (doctype,n,name)) # update all on the right - webnotes.conn.sql("update `tab%s` set rgt = rgt-2 where rgt > %s" %(doctype,left[0][0])) - webnotes.conn.sql("update `tab%s` set lft = lft-2 where lft > %s" %(doctype,left[0][0])) + webnotes.conn.sql("update `tab%s` set rgt = rgt-2, modified='%s' where rgt > %s" %(doctype,n,left[0][0])) + webnotes.conn.sql("update `tab%s` set lft = lft-2, modified='%s' where lft > %s" %(doctype,n,left[0][0])) + diff --git a/wnf.py b/wnf.py index bd22f68be3..f31d3b04dd 100755 --- a/wnf.py +++ b/wnf.py @@ -9,7 +9,6 @@ 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" @@ -20,25 +19,13 @@ def run(): 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() - + build.run() + + vc = version.VersionControl() + print 'version %s' % vc.repo.get_value('last_version_number') + if cmd=='merge': + vc = version.VersionControl() vc.setup_master() if sys.argv[2]=='local': vc.merge(vc.repo, vc.master) @@ -47,11 +34,32 @@ def run(): else: print "usage: wnf merge local|master" print "help: parameter (local or master) is the source" + vc.close() if cmd=='setup': + vc = version.VersionControl() vc.repo.setup() + vc.close() + + if cmd=='clear_startup': + from webnotes import startup + startup.clear_info('all') - vc.close() + vc = version.VersionControl() + print 'version %s' % vc.repo.get_value('last_version_number') + + if cmd=='log': + vc = version.VersionControl() + for l in vc.repo.sql("select * from log order by rowid desc limit 10 ", as_dict =1): + print 'file:'+ l['fname'] + ' | version: ' + l['version'] + print 'version %s' % vc.repo.get_value('last_version_number') + vc.close() + + if cmd=='files': + vc = version.VersionControl() + for f in vc.repo.sql("select fname from files where fname like ?", ((sys.argv[2] + '%'),)): + print f[0] + vc.close() if __name__=='__main__': run() \ No newline at end of file