Source code for nxpy.msvs.assembly_info
# nxpy.msvs package ----------------------------------------------------------
# Copyright Nicola Musatti 2010 - 2014
# Use, modification, and distribution are subject to the Boost Software
# License, Version 1.0. (See accompanying file LICENSE.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
# See http://nxpy.sourceforge.net for library home page. ---------------------
r"""
A C# or Visual Basic.NET source file that conventionally contains information about its containing
assembly, such as its version number.
"""
from __future__ import absolute_import
import encodings.utf_8_sig
import logging
import os.path
import re
import six
import nxpy.core.backup_file
import nxpy.core.file
import nxpy.core._impl.log
_log = logging.getLogger(__name__)
[docs]class BadFileExtensionError(Exception):
r"Raised when an unknown file extension is found"
class _LineRep(object):
def __init__(self, start, ai):
self._start = start
self._ai = ai
self.found = -1
def __call__(self, match):
_log.debug("ai: " + str(match.start()) + " cm: " + str(self._start))
if self._start > -1 and match.start() > self._start:
return match.group(0)
if match.group(3) == "AssemblyVersion":
s = self._ai._version
self.found = 0
elif match.group(3) == "AssemblyFileVersion":
s = self._ai._file_version
self.found = 1
elif match.group(3) == "AssemblyInformationalVersion":
s = self._ai._product_version
self.found = 2
else:
return match.group(0)
return ( match.group(1) + match.group(2) + match.group(3) + "(\"" + s + "\")" +
match.group(5) )
[docs]class AssemblyInfo(object):
_ai_re = re.compile(r"([<[])([Aa]ssembly:\s+)(\w+)\(\"([^\"]+)\"\)([>\]])")
_cm_re = re.compile(r"(?:')|(?://)|(/\*)")
[docs] def __init__(self, path):
self.path = path
self._ext = os.path.splitext(path)[1].lower()
self._version = None
self._file_version = None
self._product_version = None
self._modified = False
comment = False
ebc = -1
for l in nxpy.core.file.open_(path, "r", encoding="utf-8"):
if comment:
ebc = l.find("*/")
if not comment or ebc != -1:
ai_match = self._ai_re.search(l)
cm_match = self._cm_re.search(l)
if ai_match and ( ( comment and ebc < ai_match.start() ) or ( not cm_match or
ai_match.start() < cm_match.start() ) ):
_log.debug("ai: " + str(ai_match.start()) + " cm: " +
str(cm_match.start() if cm_match else -1))
if ai_match.group(3) == "AssemblyVersion":
self._version = ai_match.group(4)
elif ai_match.group(3) == "AssemblyFileVersion":
self._file_version = ai_match.group(4)
elif ai_match.group(3) == "AssemblyInformationalVersion":
self._product_version = ai_match.group(4)
if cm_match and cm_match.group(1) and ebc < cm_match.start(1):
comment = True
elif ebc != -1:
comment = False
ebc = -1
def _get_version(self):
return self._version
def _set_version(self, v):
self._version = v
self._modified = True
version = property(_get_version, _set_version)
def _get_file_version(self):
return self._file_version
def _set_file_version(self, v):
self._file_version = v
self._modified = True
file_version = property(_get_file_version, _set_file_version)
def _get_product_version(self):
return self._product_version
def _set_product_version(self, v):
self._product_version = v
self._modified = True
product_version = property(_get_product_version, _set_product_version)
def _attr_fmt(self):
if self._ext == ".vb":
return r'<Assembly: %s("%s")>'
elif self._ext == ".cs":
return r'[assembly: %s("%s")]'
else:
raise BadFileExtensionError(self._ext)
[docs] def write(self, dest):
src = None
bck = None
if not dest:
dest = self.path
bck = nxpy.core.backup_file.BackupFile(self.path,
mode=nxpy.core.backup_file.BackupFile.MOVE)
bck.save()
bck.open(mode=nxpy.core.backup_file.BackupFile.BINARY)
src = encodings.utf_8_sig.StreamReader(bck)
else:
src = encodings.utf_8_sig.StreamReader(open(self.path, "rb"))
if isinstance(dest, six.string_types):
dest = encodings.utf_8_sig.StreamWriter(open(dest, "wb+"))
else:
dest = encodings.utf_8_sig.StreamWriter(dest)
dest.seek(0)
try:
comment = False
ebc = -1
found = [ False, False, False ]
for l in src:
if comment:
ebc = l.find("*/")
if not comment or ebc != -1:
cm_match = self._cm_re.search(l)
lr = _LineRep(cm_match.start() if cm_match else -1, self)
l = self._ai_re.sub(lr, l)
if lr.found != -1:
found[lr.found] = True
if cm_match and cm_match.group(1) and ebc < cm_match.start(1):
comment = True
elif ebc != -1:
comment = False
ebc = -1
dest.write(l)
if not found[0]:
dest.write(self._attr_fmt() % ( "AssemblyVersion", self.version ))
if not found[1]:
dest.write(self._attr_fmt() % ( "AssemblyFileVersion", self.file_version ))
if not found[2]:
dest.write(self._attr_fmt() % ( "AssemblyInformationalVersion",
self.product_version ))
if bck:
bck.commit()
except:
if bck:
bck.rollback()
raise
finally:
dest.close()
[docs] def save(self):
if self._modified:
self.write(None)
return True
return False