Source code for nxpy.msvs.project

# nxpy.msvs package ----------------------------------------------------------

# Copyright Nicola Musatti 2010 - 2017
# 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"""
Manipulation of Microsoft Visual Studio project files.

Currently supports Visual Studio 2008 (9.0) only.

Requires at least Python 2.6

"""

from __future__ import absolute_import

import os.path
import re

import nxpy.xml.util
import nxpy.msvs.assembly_info


_ns = nxpy.xml.util.Namespace("http://schemas.microsoft.com/developer/msbuild/2003")


[docs]class BadProjectFileError(Exception): pass
[docs]class MissingConfigurationError(Exception): pass
[docs]class UnknownOutputTypeError(Exception): pass
[docs]class Reference(object):
[docs] def __init__(self, element): self.element = element name = element.get("Include") i = name.find(",") if i != -1: self.name = name[0:i] else: self.name = name
@property def hint_path(self): return _ns.findtext(self.element, "HintPath")
[docs] def __str__(self): s = self.name if self.hint_path: s = s + "\t" + self.hint_path return s
[docs]class Satellite(object):
[docs] def __init__(self, name, lang, build_path): self.name = name self.lang = lang self.build_path = build_path
@property def target(self): return os.path.join(self.build_path, self.lang, self.name)
[docs] def __str__(self): return self.target
[docs]class Project(object): _app_conf_re = re.compile(r"[^.]+\.config", re.IGNORECASE) _emb_res_re = re.compile(r"[^.]+\.([^.]+)\.resx", re.IGNORECASE)
[docs] def __init__(self, path): self.path = os.path.realpath(path) self.dir, name = os.path.split(self.path) self.name, self.extension = os.path.splitext(name) try: self.tree = nxpy.xml.util.parse(path) except IOError: raise BadProjectFileError(path) self.root = self.tree.getroot() pgs = [ pg for pg in _ns.findall(self.root, "PropertyGroup") ] self.configuration = _ns.findtext(pgs[0], "Configuration") self.platform = _ns.findtext(pgs[0], "Platform") self.output_type = _ns.findtext(pgs[0], "OutputType") self.assembly_name = _ns.findtext(pgs[0], "AssemblyName") self.assembly_file = self.assembly_name + self._extension() for pg in pgs[1:]: cond = pg.get("Condition") if ( cond and ( cond.find("Configuration") == -1 or cond.find(self.configuration) != -1 ) and ( cond.find("Platform") == -1 or cond.find(self.platform) != -1 ) ): self.output_path = _ns.findtext(pg, "OutputPath") self.assembly_dir = os.path.join(self.dir, self.output_path) break else: raise MissingConfigurationError() self.assembly = os.path.join(self.assembly_dir, self.assembly_file) self.references = [] self.sources = [] self.satellites = [] self.app_config = None self.assembly_info = None for ig in _ns.findall(self.root, "ItemGroup"): for ref in _ns.findall(ig, "Reference"): self.references.append(Reference(ref)) for tag in ( "ApplicationDefinition", "Page", "Resource" ): for src in _ns.findall(ig, tag): self._add_source(src) for src in _ns.findall(ig, "Compile"): self._add_source(src) if src.get("Include").find("AssemblyInfo") != -1: self.assembly_info = nxpy.msvs.assembly_info.AssemblyInfo( os.path.join(self.dir, *src.get("Include").split("\\"))) for res in _ns.findall(ig, "EmbeddedResource"): self._add_source(res) match = self._emb_res_re.match(res.get("Include")) if match and match.group(1) not in [ l.lang for l in self.satellites ]: self.satellites.append(Satellite(self.assembly_name + ".resources.dll", match.group(1), self.assembly_dir)) for f in _ns.findall(ig, "None"): match = self._app_conf_re.match(f.get("Include")) if match: self._add_source(f) self.app_config = os.path.join(self.assembly_dir, self.assembly_file + ".config")
def _add_source(self, src): self.sources.append(os.path.join(self.dir, src.get("Include"))) def _extension(self): t = self.output_type.lower() if t == "library": return ".dll" elif t == "winexe": return ".exe" else: raise UnknownOutputTypeError(self.output_type)
[docs] def __str__(self): s = ( "Project: " + self.path + "\nConfiguration: " + self.configuration + "\nPlatform: " + self.platform + "\nAssembly: " + self.assembly + "\nVersion: " + self.assembly_info.version + "\nApp.config: " + str(self.app_config) + "\nReferences:" ) return ( "\n\t".join([ s ] + [ str(r) for r in self.references ]) + "\n\t".join([ "\nSatellites:" ] + [ str(sat) for sat in self.satellites ]) + "\n\t".join([ "\nSources:" ] + [ str(src) for src in self.sources ]) )