def _getProjenyDir(): if not MiscUtil.isRunningAsExe(): scriptDir = os.path.dirname(os.path.realpath(__file__)) return os.path.join(scriptDir, '../../..') return os.path.join(MiscUtil.getExecDirectory(), '../..')
def clearProjectGeneratedFiles(self, projectName): with self._log.heading('Clearing generated files for project {0}'.format(projectName)): self._junctionHelper.removeJunctionsInDirectory('[UnityProjectsDir]/{0}'.format(projectName), True) for platform in Platforms.All: self.setPathsForProjectPlatform(projectName, platform) if os.path.exists(self._varMgr.expandPath('[ProjectPlatformRoot]')): platformRootPath = self._varMgr.expand('[ProjectPlatformRoot]') try: shutil.rmtree(platformRootPath) except: self._log.warn('Unable to remove path {0}. Trying to kill adb.exe to see if that will help...'.format(platformRootPath)) MiscUtil.tryKillAdbExe(self._sys) try: shutil.rmtree(platformRootPath) except: self._log.error('Still unable to remove path {0}! A running process may have one of the files locked. Ensure you have closed down unity / visual studio / etc.'.format(platformRootPath)) raise self._log.debug('Removed project directory {0}'.format(platformRootPath)) self._log.good('Successfully deleted project {0} ({1})'.format(projectName, platform)) else: self._log.debug('Project {0} ({1}) already deleted'.format(projectName, platform)) # Remove the solution files and the suo files etc. self._sys.removeByRegex('[ProjectRoot]/[ProjectName]-[Platform].*')
def _getProjenyDir(): if not MiscUtil.isRunningAsExe(): scriptDir = os.path.dirname(os.path.realpath(__file__)) return os.path.join(scriptDir, '../../..') # This works for both exe builds (Bin/Prj/Data/Prj.exe) and running from source (Source/prj/_main/Prj.py) by coincidence return os.path.join(MiscUtil.getExecDirectory(), '../../..')
def _installReleaseInternal(self, projectName, packageRoot, releaseInfo, releaseSource, suppressPrompts = False): if not self._sys.directoryExists(packageRoot): self._sys.createDirectory(packageRoot) with self._log.heading("Installing release '{0}' (version {1})", releaseInfo.name, releaseInfo.version): installDirName = None for folderInfo in self._packageManager.getAllPackageFolderInfos(projectName): for packageInfo in folderInfo.packages: installInfo = packageInfo.installInfo if installInfo and installInfo.releaseInfo and installInfo.releaseInfo.id == releaseInfo.id: if installInfo.releaseInfo.versionCode == releaseInfo.versionCode: if not suppressPrompts: shouldContinue = MiscUtil.confirmChoice( "Release '{0}' (version {1}) is already installed. Would you like to re-install anyway? Note that this will overwrite any local changes you've made to it.".format(releaseInfo.name, releaseInfo.version)) assertThat(shouldContinue, 'User aborted') else: self._log.info("Found release '{0}' already installed with version '{1}'", installInfo.releaseInfo.name, installInfo.releaseInfo.version) installDirection = 'UPGRADE' if releaseInfo.versionCode > installInfo.releaseInfo.versionCode else 'DOWNGRADE' if not suppressPrompts: shouldContinue = MiscUtil.confirmChoice("Are you sure you want to {0} '{1}' from version '{2}' to version '{3}'? (y/n)".format(installDirection, releaseInfo.name, installInfo.releaseInfo.version, releaseInfo.version)) assertThat(shouldContinue, 'User aborted') existingDir = self._varMgr.expand(os.path.join(folderInfo.path, packageInfo.name)) self._sys.deleteDirectory(existingDir) # Retain original directory name in case it is referenced by other packages installDirName = packageInfo.name installDirName = releaseSource.installRelease(packageRoot, releaseInfo, installDirName) destDir = self._varMgr.expand(os.path.join(packageRoot, installDirName)) assertThat(self._sys.directoryExists(destDir), 'Expected dir "{0}" to exist', destDir) newInstallInfo = PackageInstallInfo() newInstallInfo.releaseInfo = releaseInfo newInstallInfo.installDate = datetime.utcnow() yamlStr = YamlSerializer.serialize(newInstallInfo) self._sys.writeFileAsText(os.path.join(destDir, InstallInfoFileName), yamlStr) self._log.info("Successfully installed '{0}' (version {1})", releaseInfo.name, releaseInfo.version)
def run(self, project, platform, requestId, param1, param2, param3): self._log.debug("Started EditorApi with arguments: {0}".format(" ".join(sys.argv[1:]))) self._project = project self._platform = platform self._requestId = requestId self._param1 = param1 self._param2 = param2 self._param3 = param3 succeeded = True # This is repeated in __main__ but this is better because # it will properly log detailed errors to the file log instead of to the console try: self._runInternal() except Exception as e: sys.stderr.write(str(e)) self._log.error(str(e)) if not MiscUtil.isRunningAsExe(): self._log.error('\n' + traceback.format_exc()) succeeded = False if not succeeded: sys.exit(1)
def runWrapper(self, runner): startTime = datetime.now() succeeded = False try: runner() succeeded = True except KeyboardInterrupt as e: self._log.error('Operation aborted by user by hitting CTRL+C') except Exception as e: self._log.error(str(e)) # Only print stack trace if it's a build-script error if not isinstance(e, ProcessErrorCodeException) and not isinstance(e, ProcessTimeoutException): if MiscUtil.isRunningAsExe(): self._log.noise('\n' + traceback.format_exc()) else: self._log.debug('\n' + traceback.format_exc()) totalSeconds = (datetime.now()-startTime).total_seconds() totalSecondsStr = Util.formatTimeDelta(totalSeconds) if succeeded: self._log.good('Operation completed successfully. Took ' + totalSecondsStr + '.\n') else: self._log.info('Operation completed with errors. Took ' + totalSecondsStr + '.\n') return succeeded
def run(self, project, platform, requestId, param1, param2, param3): self._log.debug("Started EditorApi with arguments: {0}".format( " ".join(sys.argv[1:]))) self._project = project self._platform = platform self._requestId = requestId self._param1 = param1 self._param2 = param2 self._param3 = param3 succeeded = True # This is repeated in __main__ but this is better because # it will properly log detailed errors to the file log instead of to the console try: self._runInternal() except Exception as e: sys.stderr.write(str(e)) self._log.error(str(e)) if not MiscUtil.isRunningAsExe(): self._log.error('\n' + traceback.format_exc()) succeeded = False if not succeeded: sys.exit(1)
def __init__(self, initialParams = None): self._params = initialParams if initialParams else {} self._params['StartCurrentDir'] = os.getcwd() self._params['ExecDir'] = MiscUtil.getExecDirectory().replace('\\', '/') # We could just call self._config.getDictionary('PathVars') here but # then we wouldn't be able to use fallback (?) and override (!) characters in # our config self._regex = re.compile('^([^\[]*)(\[[^\]]*\])(.*)$')
def _runPreBuild(self): if self._args.deleteProject: if not self._args.suppressPrompts: if not MiscUtil.confirmChoice( "Are you sure you want to delete project '{0}'? (y/n) \nNote that this will only delete your unity project settings and the {1} for this project. \nThe rest of the content for your project will remain in the UnityPackages folder " .format(self._args.project, ProjectConfigFileName)): assertThat(False, "User aborted operation") self._packageMgr.deleteProject(self._args.project) if self._args.createProject: self._packageMgr.createProject(self._args.project) if self._args.projectAddPackageAssets: self._projectConfigChanger.addPackage( self._args.project, self._args.projectAddPackageAssets, True) if self._args.projectAddPackagePlugins: self._projectConfigChanger.addPackage( self._args.project, self._args.projectAddPackagePlugins, False) if self._args.openDocumentation: self._openDocumentation() if self._args.clearProjectGeneratedFiles: self._packageMgr.clearProjectGeneratedFiles(self._args.project) if self._args.clearAllProjectGeneratedFiles: self._packageMgr.clearAllProjectGeneratedFiles() if self._args.deleteAllLinks: self._packageMgr.deleteAllLinks() if self._args.buildPrebuild: self.buildPrebuildProjects() if self._args.init: self._packageMgr.updateLinksForAllProjects() if self._args.initLinks: self._packageMgr.checkProjectInitialized(self._args.project, self._platform) if self._args.updateLinks: self._packageMgr.updateProjectJunctions(self._args.project, self._platform) if self._args.updateUnitySolution: self._projVsHelper.updateUnitySolution(self._args.project, self._platform) if self._args.updateCustomSolution: self._projVsHelper.updateCustomSolution(self._args.project, self._platform)
def openFile(self, filePath, lineNo, project, platform): if not lineNo or lineNo <= 0: lineNo = 1 if MiscUtil.doesProcessExist("^devenv\.exe$"): self.openFileInExistingVisualStudioInstance(filePath, lineNo) # This works too but doesn't allow going to a specific line # self._sys.executeNoWait('[VisualStudioCommandLinePath] /edit "{0}"'.format(filePath)) else: # Unfortunately, in this case we can't pass in the line number self.openCustomSolution(project, platform, filePath)
def openFile(self, filePath, lineNo, solutionPath): if not lineNo or lineNo <= 0: lineNo = 1 if MiscUtil.doesProcessExist('^devenv\.exe$'): self.openFileInExistingVisualStudioInstance(filePath, lineNo) # This works too but doesn't allow going to a specific line #self._sys.executeNoWait('[VisualStudioCommandLinePath] /edit "{0}"'.format(filePath)) else: # Unfortunately, in this case we can't pass in the line number self.openVisualStudioSolution(solutionPath, filePath)
def _runPreBuild(self): if self._args.deleteProject: if not self._args.suppressPrompts: if not MiscUtil.confirmChoice( "Are you sure you want to delete project '{0}'? (y/n) \nNote that this will only delete your unity project settings and the {1} for this project. \nThe rest of the content for your project will remain in the UnityPackages folder ".format( self._args.project, ProjectConfigFileName ) ): assertThat(False, "User aborted operation") self._packageMgr.deleteProject(self._args.project) if self._args.createProject: self._packageMgr.createProject(self._args.project) if self._args.projectAddPackageAssets: self._projectConfigChanger.addPackage(self._args.project, self._args.projectAddPackageAssets, True) if self._args.projectAddPackagePlugins: self._projectConfigChanger.addPackage(self._args.project, self._args.projectAddPackagePlugins, False) if self._args.openDocumentation: self._openDocumentation() if self._args.clearProjectGeneratedFiles: self._packageMgr.clearProjectGeneratedFiles(self._args.project) if self._args.clearAllProjectGeneratedFiles: self._packageMgr.clearAllProjectGeneratedFiles() if self._args.deleteAllLinks: self._packageMgr.deleteAllLinks() if self._args.buildPrebuild: self.buildPrebuildProjects() if self._args.init: self._packageMgr.updateLinksForAllProjects() if self._args.initLinks: self._packageMgr.checkProjectInitialized(self._args.project, self._platform) if self._args.updateLinks: self._packageMgr.updateProjectJunctions(self._args.project, self._platform) if self._args.updateUnitySolution: self._projVsHelper.updateUnitySolution(self._args.project, self._platform) if self._args.updateCustomSolution: self._projVsHelper.updateCustomSolution(self._args.project, self._platform)
def installPlugins(): if MiscUtil.isRunningAsExe(): # Must be running from source for plugins return import importlib pluginDir = _getPluginDirPath() for filePath in _findFilesByPattern(pluginDir, '*.py'): basePath = filePath[len(pluginDir) + 1:] basePath = os.path.splitext(basePath)[0] basePath = basePath.replace('\\', '.') importlib.import_module('prj.plugins.' + basePath)
def installBindings(mainConfigPath): assertIsNotNone(mainConfigPath) assertThat(os.path.isfile(mainConfigPath)) projenyDir = _getProjenyDir() projenyConfigPath = os.path.join(projenyDir, ConfigFileName) # Put the standard config first so it can be over-ridden by user settings configPaths = [projenyConfigPath, mainConfigPath] configPaths += _getExtraUserConfigPaths() Container.bind('Config').toSingle(Config, loadYamlFilesThatExist(*configPaths)) initialVars = { 'ProjenyDir': projenyDir, } initialVars['ConfigDir'] = os.path.dirname(mainConfigPath) if not MiscUtil.isRunningAsExe(): initialVars['PythonPluginDir'] = _getPluginDirPath() Container.bind('VarManager').toSingle(VarManager, initialVars) Container.bind('SystemHelper').toSingle(SystemHelper) Container.bind('Logger').toSingle(Logger) Container.bind('UnityHelper').toSingle(UnityHelper) Container.bind('ScriptRunner').toSingle(ScriptRunner) Container.bind('PackageManager').toSingle(PackageManager) Container.bind('ProcessRunner').toSingle(ProcessRunner) Container.bind('JunctionHelper').toSingle(JunctionHelper) Container.bind('VisualStudioSolutionGenerator').toSingle( VisualStudioSolutionGenerator) Container.bind('VisualStudioHelper').toSingle(VisualStudioHelper) Container.bind('ProjenyVisualStudioHelper').toSingle( ProjenyVisualStudioHelper) Container.bind('ProjectSchemaLoader').toSingle(ProjectSchemaLoader) Container.bind('CommonSettings').toSingle(CommonSettings) Container.bind('UnityPackageExtractor').toSingle(UnityPackageExtractor) Container.bind('ZipHelper').toSingle(ZipHelper) Container.bind('UnityPackageAnalyzer').toSingle(UnityPackageAnalyzer) Container.bind('ProjectConfigChanger').toSingle(ProjectConfigChanger) Container.bind('PrjRunner').toSingle(PrjRunner) Container.bind('UnityEditorMenuGenerator').toSingle( UnityEditorMenuGenerator) Container.bind('ReleaseSourceManager').toSingle(ReleaseSourceManager)
def installBindings(mainConfigPath): assertIsNotNone(mainConfigPath) assertThat(os.path.isfile(mainConfigPath)) projenyDir = _getProjenyDir() projenyConfigPath = os.path.join(projenyDir, ConfigFileName) # Put the standard config first so it can be over-ridden by user settings configPaths = [projenyConfigPath, mainConfigPath] configPaths += _getExtraUserConfigPaths() Container.bind('Config').toSingle(Config, loadYamlFilesThatExist(*configPaths)) initialVars = { 'ProjenyDir': projenyDir, } initialVars['ConfigDir'] = os.path.dirname(mainConfigPath) if not MiscUtil.isRunningAsExe(): initialVars['PythonPluginDir'] = _getPluginDirPath() Container.bind('VarManager').toSingle(VarManager, initialVars) Container.bind('SystemHelper').toSingle(SystemHelper) Container.bind('Logger').toSingle(Logger) Container.bind('UnityHelper').toSingle(UnityHelper) Container.bind('ScriptRunner').toSingle(ScriptRunner) Container.bind('PackageManager').toSingle(PackageManager) Container.bind('ProcessRunner').toSingle(ProcessRunner) Container.bind('JunctionHelper').toSingle(JunctionHelper) Container.bind('VisualStudioSolutionGenerator').toSingle(VisualStudioSolutionGenerator) Container.bind('VisualStudioHelper').toSingle(VisualStudioHelper) Container.bind('ProjenyVisualStudioHelper').toSingle(ProjenyVisualStudioHelper) Container.bind('ProjectSchemaLoader').toSingle(ProjectSchemaLoader) Container.bind('CommonSettings').toSingle(CommonSettings) Container.bind('UnityPackageExtractor').toSingle(UnityPackageExtractor) Container.bind('ZipHelper').toSingle(ZipHelper) Container.bind('UnityPackageAnalyzer').toSingle(UnityPackageAnalyzer) Container.bind('ProjectConfigChanger').toSingle(ProjectConfigChanger) Container.bind('PrjRunner').toSingle(PrjRunner) Container.bind('ReleaseSourceManager').toSingle(ReleaseSourceManager)
def _installReleaseInternal(self, projectName, packageRoot, releaseInfo, releaseSource, suppressPrompts=False): if not self._sys.directoryExists(packageRoot): self._sys.createDirectory(packageRoot) with self._log.heading("Installing release '{0}' (version {1})", releaseInfo.name, releaseInfo.version): installDirName = None for folderInfo in self._packageManager.getAllPackageFolderInfos( projectName): for packageInfo in folderInfo.packages: installInfo = packageInfo.installInfo if installInfo and installInfo.releaseInfo and installInfo.releaseInfo.id == releaseInfo.id: if installInfo.releaseInfo.versionCode == releaseInfo.versionCode: if not suppressPrompts: shouldContinue = MiscUtil.confirmChoice( "Release '{0}' (version {1}) is already installed. Would you like to re-install anyway? Note that this will overwrite any local changes you've made to it." .format(releaseInfo.name, releaseInfo.version)) assertThat(shouldContinue, 'User aborted') else: self._log.info( "Found release '{0}' already installed with version '{1}'", installInfo.releaseInfo.name, installInfo.releaseInfo.version) installDirection = 'UPGRADE' if releaseInfo.versionCode > installInfo.releaseInfo.versionCode else 'DOWNGRADE' if not suppressPrompts: shouldContinue = MiscUtil.confirmChoice( "Are you sure you want to {0} '{1}' from version '{2}' to version '{3}'? (y/n)" .format(installDirection, releaseInfo.name, installInfo.releaseInfo.version, releaseInfo.version)) assertThat(shouldContinue, 'User aborted') existingDir = self._varMgr.expand( os.path.join(folderInfo.path, packageInfo.name)) self._sys.deleteDirectory(existingDir) # Retain original directory name in case it is referenced by other packages installDirName = packageInfo.name installDirName = releaseSource.installRelease( packageRoot, releaseInfo, installDirName) destDir = self._varMgr.expand( os.path.join(packageRoot, installDirName)) assertThat(self._sys.directoryExists(destDir), 'Expected dir "{0}" to exist', destDir) newInstallInfo = PackageInstallInfo() newInstallInfo.releaseInfo = releaseInfo newInstallInfo.installDate = datetime.utcnow() yamlStr = YamlSerializer.serialize(newInstallInfo) self._sys.writeFileAsText( os.path.join(destDir, InstallInfoFileName), yamlStr) self._log.info("Successfully installed '{0}' (version {1})", releaseInfo.name, releaseInfo.version)
installPlugins() Container.resolve('PrjRunner').run(args) if __name__ == '__main__': if (sys.version_info < (3, 0)): print('Wrong version of python! Install python 3 and try again') sys.exit(2) succeeded = True try: _main() except KeyboardInterrupt as e: print('Operation aborted by user by hitting CTRL+C') succeeded = False except Exception as e: sys.stderr.write(str(e) + '\n') if "-vv" in sys.argv and not MiscUtil.isRunningAsExe(): sys.stderr.write('\n' + traceback.format_exc()) succeeded = False if not succeeded: sys.exit(1)
installBindings(args) Runner().run(args) if __name__ == '__main__': if (sys.version_info < (3, 0)): print('Wrong version of python! Install python 3 and try again') sys.exit(2) succeeded = True try: _main() except KeyboardInterrupt as e: print('Operation aborted by user by hitting CTRL+C') succeeded = False except Exception as e: sys.stderr.write(str(e) + '\n') if not MiscUtil.isRunningAsExe(): sys.stderr.write('\n' + traceback.format_exc()) succeeded = False if not succeeded: sys.exit(1)