Exemple #1
0
    def _SetupServer(self):
        server_port = utils.GetUnusedLocalhostPort()
        with tempfile.NamedTemporaryFile(delete=False) as options_file:
            self._temp_options_filename = options_file.name
            json.dump(dict(self._user_options), options_file)
            args = [
                utils.PathToPythonInterpreter(),
                _PathToServerScript(), '--port={0}'.format(server_port),
                '--options_file={0}'.format(options_file.name),
                '--log={0}'.format(self._user_options['server_log_level']),
                '--idle_suicide_seconds={0}'.format(
                    self._user_options['server_idle_suicide_seconds'])
            ]

            BaseRequest.server_location = 'http://localhost:' + str(
                server_port)

            if self._user_options['server_use_vim_stdout']:
                self._server_popen = subprocess.Popen(args)
            else:
                filename_format = os.path.join(utils.PathToTempDir(),
                                               'server_{port}_{std}.log')

                self._server_stdout = filename_format.format(port=server_port,
                                                             std='stdout')
                self._server_stderr = filename_format.format(port=server_port,
                                                             std='stderr')
                # We need this on Windows otherwise bad things happen. See issue #637.
                stdin = subprocess.PIPE if utils.OnWindows() else None

                with open(self._server_stderr, 'w') as fstderr:
                    with open(self._server_stdout, 'w') as fstdout:
                        self._server_popen = subprocess.Popen(args,
                                                              stdin=stdin,
                                                              stdout=fstdout,
                                                              stderr=fstderr)
        self._NotifyUserIfServerCrashed()
Exemple #2
0
  def _StartServer( self, request_data ):
    """ Start the OmniSharp server """
    self._logger.info( 'startup' )

    self._omnisharp_port = utils.GetUnusedLocalhostPort()
    solution_files, folder = _FindSolutionFiles( request_data[ 'filepath' ] )

    if len( solution_files ) == 0:
      raise RuntimeError(
        'Error starting OmniSharp server: no solutionfile found' )
    elif len( solution_files ) == 1:
      solutionfile = solution_files[ 0 ]
    else:
      # multiple solutions found : if there is one whose name is the same
      # as the folder containing the file we edit, use this one
      # (e.g. if we have bla/Project.sln and we are editing
      # bla/Project/Folder/File.cs, use bla/Project.sln)
      filepath_components = _PathComponents( request_data[ 'filepath' ] )
      solutionpath = _PathComponents( folder )
      foldername = ''
      if len( filepath_components ) > len( solutionpath ):
          foldername = filepath_components[ len( solutionpath ) ]
      solution_file_candidates = [ solutionfile for solutionfile in solution_files
        if _GetFilenameWithoutExtension( solutionfile ) == foldername ]
      if len( solution_file_candidates ) == 1:
        solutionfile = solution_file_candidates[ 0 ]
      else:
        raise RuntimeError(
          'Found multiple solution files instead of one!\n{0}'.format(
            solution_files ) )

    omnisharp = os.path.join(
      os.path.abspath( os.path.dirname( __file__ ) ),
      'OmniSharpServer/OmniSharp/bin/Debug/OmniSharp.exe' )

    if not os.path.isfile( omnisharp ):
      raise RuntimeError( SERVER_NOT_FOUND_MSG.format( omnisharp ) )

    path_to_solutionfile = os.path.join( folder, solutionfile )
    # we need to pass the command to Popen as a string since we're passing
    # shell=True (as recommended by Python's doc)
    command = ( omnisharp + ' -p ' + str( self._omnisharp_port ) + ' -s ' +
                path_to_solutionfile )

    if not utils.OnWindows():
      command = 'mono ' + command

    filename_format = os.path.join( utils.PathToTempDir(),
                                   'omnisharp_{port}_{sln}_{std}.log' )

    self._filename_stdout = filename_format.format(
        port=self._omnisharp_port, sln=solutionfile, std='stdout' )
    self._filename_stderr = filename_format.format(
        port=self._omnisharp_port, sln=solutionfile, std='stderr' )

    with open( self._filename_stderr, 'w' ) as fstderr:
      with open( self._filename_stdout, 'w' ) as fstdout:
        # shell=True is needed for Windows so OmniSharp does not spawn
        # in a new visible window
        utils.SafePopen( command, stdout=fstdout, stderr=fstderr, shell=True )

    self._logger.info( 'Starting OmniSharp server' )
Exemple #3
0
def Main():
  parser = argparse.ArgumentParser()
  parser.add_argument( '--host', type = str, default = 'localhost',
                       help = 'server hostname')
  # Default of 0 will make the OS pick a free port for us
  parser.add_argument( '--port', type = int, default = 0,
                       help = 'server port')
  parser.add_argument( '--log', type = str, default = 'info',
                       help = 'log level, one of '
                              '[debug|info|warning|error|critical]' )
  parser.add_argument( '--idle_suicide_seconds', type = int, default = 0,
                       help = 'num idle seconds before server shuts down')
  parser.add_argument( '--options_file', type = str, default = '',
                       help = 'file with user options, in JSON format' )
  parser.add_argument( '--stdout', type = str, default = None,
                       help = 'optional file to use for stdout' )
  parser.add_argument( '--stderr', type = str, default = None,
                       help = 'optional file to use for stderr' )
  parser.add_argument( '--keep_logfiles', action = 'store_true', default = None,
                       help = 'retain logfiles after the server exits' )
  args = parser.parse_args()

  if args.stdout is not None:
    sys.stdout = open(args.stdout, "w")
  if args.stderr is not None:
    sys.stderr = open(args.stderr, "w")

  numeric_level = getattr( logging, args.log.upper(), None )
  if not isinstance( numeric_level, int ):
    raise ValueError( 'Invalid log level: %s' % args.log )

  # Has to be called before any call to logging.getLogger()
  logging.basicConfig( format = '%(asctime)s - %(levelname)s - %(message)s',
                       level = numeric_level )

  options = ( json.load( open( args.options_file, 'r' ) )
              if args.options_file
              else user_options_store.DefaultOptions() )
  utils.RemoveIfExists( args.options_file )
  options[ 'hmac_secret' ] = base64.b64decode( options[ 'hmac_secret' ] )
  user_options_store.SetAll( options )

  # This ensures that ycm_core is not loaded before extra conf
  # preload was run.
  YcmCoreSanityCheck()
  extra_conf_store.CallGlobalExtraConfYcmCorePreloadIfExists()

  # If not on windows, detach from controlling terminal to prevent
  # SIGINT from killing us.
  if not utils.OnWindows():
    try:
      os.setsid()
    # setsid() can fail if the user started ycmd directly from a shell.
    except OSError:
      pass

  # This can't be a top-level import because it transitively imports
  # ycm_core which we want to be imported ONLY after extra conf
  # preload has executed.
  from ycm.server import handlers
  handlers.UpdateUserOptions( options )
  SetUpSignalHandler(args.stdout, args.stderr, args.keep_logfiles)
  handlers.app.install( WatchdogPlugin( args.idle_suicide_seconds ) )
  handlers.app.install( HmacPlugin( options[ 'hmac_secret' ] ) )
  waitress.serve( handlers.app,
                  host = args.host,
                  port = args.port,
                  threads = 30 )