[bin] publish.py: bugfix: automating Appy's deployment on pypi.python.org.

This commit is contained in:
Gaetan Delannay 2013-02-22 16:17:04 +01:00
parent 1fc19469eb
commit 1522cfdb6f

View file

@ -43,6 +43,7 @@ class FtpFolder:
self.files = [] self.files = []
self.isComplete = False # Is True if all contained files and direct self.isComplete = False # Is True if all contained files and direct
# subFolders were analysed. # subFolders were analysed.
def getFullName(self): def getFullName(self):
if not self.parent: if not self.parent:
res = '.' res = '.'
@ -52,11 +53,13 @@ class FtpFolder:
def addSubFolder(self, subFolder): def addSubFolder(self, subFolder):
self.subFolders.append(subFolder) self.subFolders.append(subFolder)
subFolder.parent = self subFolder.parent = self
def isFullyComplete(self): def isFullyComplete(self):
res = self.isComplete res = self.isComplete
for subFolder in self.subFolders: for subFolder in self.subFolders:
res = res and subFolder.isFullyComplete() res = res and subFolder.isFullyComplete()
return res return res
def getIncompleteSubFolders(self): def getIncompleteSubFolders(self):
res = [] res = []
for subFolder in self.subFolders: for subFolder in self.subFolders:
@ -65,6 +68,7 @@ class FtpFolder:
elif not subFolder.isFullyComplete(): elif not subFolder.isFullyComplete():
res += subFolder.getIncompleteSubFolders() res += subFolder.getIncompleteSubFolders()
return res return res
def __str__(self): def __str__(self):
res = 'Folder %s' % self.getFullName() res = 'Folder %s' % self.getFullName()
if self.files: if self.files:
@ -76,9 +80,11 @@ class FtpFolder:
for subFolder in self.subFolders: for subFolder in self.subFolders:
res += str(subFolder) res += str(subFolder)
return res return res
def clean(self, site): def clean(self, site):
'''Cleans this folder''' '''Cleans this folder'''
# First, clean subFolders if they exist # First, clean subFolders if they exist
print 'Cleaning', self.getFullName(), len(self.subFolders), 'subFolders'
for subFolder in self.subFolders: for subFolder in self.subFolders:
subFolder.clean(site) subFolder.clean(site)
# Remove the subFolder # Remove the subFolder
@ -87,6 +93,7 @@ class FtpFolder:
for f in self.files: for f in self.files:
fileName = '%s/%s' % (self.getFullName(), f) fileName = '%s/%s' % (self.getFullName(), f)
site.delete(fileName) site.delete(fileName)
print fileName, 'removed.'
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
class AppySite: class AppySite:
@ -104,16 +111,19 @@ class AppySite:
self.site.login(userId, userPassword) self.site.login(userId, userPassword)
self.rootFolder = None # Root folder of appy site ~FtpFolder~ self.rootFolder = None # Root folder of appy site ~FtpFolder~
self.currentFolder = None # Currently visited folder ~FtpFolder~ self.currentFolder = None # Currently visited folder ~FtpFolder~
def analyseFolderEntry(self, folderEntry): def analyseFolderEntry(self, folderEntry):
'''p_line corresponds to a 'ls' entry.''' '''p_line corresponds to a 'ls' entry.'''
elems = folderEntry.split(' ') elems = folderEntry.split(' ')
elemName = elems[len(elems)-1] elemName = elems[len(elems)-1]
if (not elemName.startswith('.')) and \ if (elemName.startswith('.') or elemName.startswith('_')) and \
(not elemName.startswith('_')): (not elemName.startswith('__init__.py')):
return
if elems[0].startswith('d'): if elems[0].startswith('d'):
self.currentFolder.addSubFolder(FtpFolder(elemName)) self.currentFolder.addSubFolder(FtpFolder(elemName))
else: else:
self.currentFolder.files.append(elemName) self.currentFolder.files.append(elemName)
def createFolderProxies(self): def createFolderProxies(self):
'''Creates a representation of the FTP folders of the appy site in the '''Creates a representation of the FTP folders of the appy site in the
form of FtpFolder instances.''' form of FtpFolder instances.'''
@ -128,6 +138,7 @@ class AppySite:
self.site.dir(self.currentFolder.getFullName(), self.site.dir(self.currentFolder.getFullName(),
self.analyseFolderEntry) self.analyseFolderEntry)
self.currentFolder.isComplete = True self.currentFolder.isComplete = True
def copyFile(self, fileName): def copyFile(self, fileName):
'''Copies a file on the FTP server.''' '''Copies a file on the FTP server.'''
localFile = file(fileName) localFile = file(fileName)
@ -141,6 +152,7 @@ class AppySite:
# Make a transfer in binary mode # Make a transfer in binary mode
print 'Transfer file %s (binary mode)' % fileName print 'Transfer file %s (binary mode)' % fileName
self.site.storbinary(cmd, localFile) self.site.storbinary(cmd, localFile)
def publish(self): def publish(self):
# Delete the existing content of the distant site # Delete the existing content of the distant site
self.createFolderProxies() self.createFolderProxies()
@ -307,17 +319,16 @@ class Publisher:
name = 'appy-%s.tar.gz' % self.versionShort name = 'appy-%s.tar.gz' % self.versionShort
os.rename('%s/dist/%s' % (distFolder, name), os.rename('%s/dist/%s' % (distFolder, name),
'%s/versions/%s' % (appyPath, name)) '%s/versions/%s' % (appyPath, name))
os.rmdir('%s/dist' % distFolder)
# Upload the package on Pypi?
if self.askQuestion('Upload %s on PyPI?' % name, default='no'):
self.executeCommand('python setup.py sdist upload')
# Clean temp files # Clean temp files
os.chdir(curdir) os.chdir(curdir)
# Keep the Appy source for building the Debian package afterwards # Keep the Appy source for building the Debian package afterwards
os.rename(os.path.join(self.genFolder, 'dist', 'appy'), \ os.rename(os.path.join(self.genFolder, 'dist', 'appy'), \
os.path.join(self.genFolder, 'appy')) os.path.join(self.genFolder, 'appy'))
FolderDeleter.delete(os.path.join(self.genFolder, 'dist')) FolderDeleter.delete(os.path.join(self.genFolder, 'dist'))
return name
def uploadOnPypi(self, name):
print 'Uploading %s on PyPI...' % name
#self.executeCommand('python setup.py sdist upload')
def createZipRelease(self): def createZipRelease(self):
'''Creates a zip file with the appy sources.''' '''Creates a zip file with the appy sources.'''
@ -489,10 +500,10 @@ class Publisher:
self.createDocToc() self.createDocToc()
self.applyTemplate() self.applyTemplate()
self.createZipRelease() self.createZipRelease()
tarball = self.createDistRelease() self.createDistRelease()
self.createDebianRelease() self.createDebianRelease()
if self.askQuestion('Upload %s on PyPI?' % tarball, default='no'): # Remove folder 'appy', in order to avoid copying it on the website
self.uploadOnPypi(tarball) FolderDeleter.delete(os.path.join(self.genFolder, 'appy'))
if self.askQuestion('Publish on appyframework.org?', default='no'): if self.askQuestion('Publish on appyframework.org?', default='no'):
AppySite().publish() AppySite().publish()
if self.askQuestion('Delete locally generated site ?', default='no'): if self.askQuestion('Delete locally generated site ?', default='no'):