#!/usr/bin/env python """ This script (rcvs) executes cvs on a remote cvs client. Useful when cvs access is only allowed from one particular host. Definitions CVS server: host where CVS repository resides CVS client: host from which access to CVS server is allowed local host: host that must access CVS repository through CVS client Assumptions: 1:CVS client can be reached from local host without passwords using ssh and rsync 2:Usernames on CVS client and CVS server are the same 3:Details about CVS Host are supplied at the top of this script 4:CVSROOT environment variable point to CVS client so that username and CVS client can be inferred automatically 5:Each user has a directory called sandpit in their home directory on the CVS client 6:CVS client has a UNIX/Linux file structure 7:That user has performed a CVS login once from CVS client to CVS host Modus operandi: The rcvs script will do updates, add and commit plus download (unique to rcvs) Commands such as tag, remove etc mus be done on cvs client. Examples: rcvs checkout repository (checkout and download repository from cvs client) rcvs add [files...] (add named files to repository) rcvs update [files...] (update named files from cvs server) rcvs com -m "msg" [files...] (Commit changes with log message) rcvs log [files...] (List log history for files) rcvs download repository (download repository from cvs client) If files are omitted command will work on all files in repository. SSH Setup To get cgywin ssh working, wothout using passwords; 1) Set the environment variable CYGWIN = smbntsec 2) In windows explorer/permissions/security, make sure the private key has only 1 user Copyright 2004 Ole Nielsen and Duncan Gray Geoscience Australia """ #Details about CVS Host protocol = 'pserver' cvs_host = 'cuttlefish.anu.edu.au' cvs_dir = '/home/cvs' rsep = '/' #Separator on cvs client from os import sep #Separator on local machine import sys, os #Get Username and cvs client - assumed to be the same on cvs host and remote cvs client s = os.getenv('CVSROOT') username = '' cvs_client = '' if len(s) > 0: atsign = s.index('@') #Username i = atsign-1 while i > 0 and s[i] != ':': username = s[i] + username i -= 1 #CVS client i = atsign+1 while i < len(s) and s[i] != ':': cvs_client += s[i] i += 1 if len(username) == 0: msg = 'Could not infer user name from environment variable CVSROOT (%s)' %s raise msg if len(cvs_client) == 0: msg = 'Could not infer CVS client from environment variable CVSROOT (%s)' %s raise msg #CVSROOT = ':pserver:%s@cuttlefish.anu.edu.au:/home/cvs' %username CVSROOT = ':%s:%s@%s:%s' %(protocol, username, cvs_host, cvs_dir) #specify location of remote repositories (assuming UNIX separators) sandpit = '~' + rsep + 'sandpit' def run(cmd): import os print cmd os.system(cmd) def upload(dir): files=get_cvsfiles() #s = 'rsync --cvs-exclude -qavz %s %s@%s:%s'\ s = 'rsync -qavz %s %s@%s:%s' %(files, username, cvs_client, sandpit + rsep + dir) print '---------- UPLOADING -------------' run(s) def download(dir): import os s = 'rsync -qavz %s@%s:%s' %(username, cvs_client, sandpit) +\ rsep + dir + rsep + '* .' print '---------- DOWNLOADING -------------' run(s) def cvscmd(dir, cmd, args): x = '' for arg in args: x += str(arg) + ' ' s = 'ssh -X %s@%s "cd %s; cvs %s %s"' %(username, cvs_client, sandpit + rsep + dir, cmd, x) print '---------- CVS OUTPUT -------------' run(s) #FIXME: Not done yet and maybe it shouldn't def get_cvsfiles(): """Get files that are registered under CVS """ import os #Get name of local repository localdir = os.getcwd() if not 'CVS' in os.listdir(localdir): raise 'No CVS directory in current directory' FN = localdir + sep + 'CVS' + sep + 'Entries' try: fid = open(FN) except: msg = 'Could not open %s' %FN raise msg else: files = '' for entry in fid.readlines(): #print entry pass return '*' def get_repository(): """Get name of CVS repository from CVS directory """ import os #Get name of local repository localdir = os.getcwd() if not 'CVS' in os.listdir(localdir): raise 'No CVS directory in current directory' FN = localdir + sep + 'CVS' + sep + 'Repository' try: fid = open(FN) except: msg = 'Could not open %s' %FN raise msg else: repository = fid.readlines()[0].strip() #Get actual name of local repository local = os.path.split(localdir)[1] #if local != repository: # msg = 'Local directory (%s) and ' %local # msg += 'CVS repository (%s) must have the same name' %repository # raise msg return repository if len(sys.argv) > 1: arg = sys.argv[1] if arg.find('upd') == 0: dir = get_repository() upload(dir) cvscmd(dir, 'update', sys.argv[2:]) download(dir) if arg.find('com') == 0 or arg.find('ci') == 0: dir = get_repository() upload(dir) args = sys.argv[2:] try: i = args.index('-m') except: comment = 'None' remaining_args = args else: #We have a text argument for the log file comment = '%s' %(args[i+1]) if len(comment) == 0: comment = 'None' remaining_args = args[:i]+args[i+2:] command = 'commit -m """%s"""' %comment #cvscmd(dir, 'update', remaining_args) cvscmd(dir, command, remaining_args) download(dir) if arg.find('add') == 0: dir = get_repository() upload(dir) cvscmd(dir, 'add', sys.argv[2:]) download(dir) if arg.find('log') == 0: dir = get_repository() upload(dir) cvscmd(dir, 'log', sys.argv[2:]) if arg.find('diff') == 0: dir = get_repository() upload(dir) cvscmd(dir, 'diff', sys.argv[2:]) if arg.find('annotate') == 0: dir = get_repository() upload(dir) cvscmd(dir, 'annotate', sys.argv[2:]) #FIXME: Maybe Obsolete if arg.find('down') == 0: import os if len(sys.argv) == 3: arg = sys.argv[2] os.mkdir(arg) #Create local copy of repository os.chdir(arg) download(arg) if arg.find('co') == 0 or arg.find('checkout') == 0: import os if len(sys.argv) == 3: arg = sys.argv[2] #Create local copy of repository try: os.mkdir(arg) except OSError: pass #msg = 'Could not create directory %s' %arg #raise msg os.chdir(arg) #Check out from CVS host s = 'ssh -X %s@%s "cd %s;cvs -d %s checkout %s"'\ %(username, cvs_client, sandpit, CVSROOT, arg) print '---------- CVS OUTPUT -------------' run(s) #Download from CVS client download(arg) else: print 'Usage' print ''' rcvs checkout repository (checkout repository from cvs client) rcvs add [files...] (add named files to repository) rcvs update [files...] (update named files from cvs server) rcvs com -m "msg" [files...] (Commit changes with log message) rcvs log [files...] (List log history for files) rcvs diff [files...] (List diffs for files) rcvs annotate [files...] (List files with cvs annotations) rcvs download repository (download repository from cvs client)'''