예제 #1
0
void onFileChanged(FilePath sourceFilePath)
{
   // ignore file changes while Packrat is running
   if (s_runningPackratAction != PACKRAT_ACTION_NONE)
      return;
   
   // we only care about mutations to files in the Packrat library directory
   // (and packrat.lock)
   FilePath libraryPath = 
      projects::projectContext().directory().complete(kPackratLibPath);

   if (sourceFilePath.filename() == kPackratLockfile)
   {
      PACKRAT_TRACE("detected change to lockfile " << sourceFilePath);
      checkHashes(HASH_TYPE_LOCKFILE, HASH_STATE_OBSERVED, onLockfileUpdate);
   }
   else if (sourceFilePath.isWithin(libraryPath) && 
            (sourceFilePath.isDirectory() || 
             sourceFilePath.filename() == "DESCRIPTION"))
   {
      // ignore changes in the RStudio-managed manipulate and rstudio 
      // directories and the files within them
      if (sourceFilePath.filename() == "manipulate" ||
          sourceFilePath.filename() == "rstudio" ||
          sourceFilePath.parent().filename() == "manipulate" || 
          sourceFilePath.parent().filename() == "rstudio")
      {
         return;
      }
      PACKRAT_TRACE("detected change to library file " << sourceFilePath);
      checkHashes(HASH_TYPE_LIBRARY, HASH_STATE_OBSERVED, onLibraryUpdate);
   }
}
예제 #2
0
FilePath projectFromDirectory(const FilePath& directoryPath)
{
   // first use simple heuristic of a case sentitive match between
   // directory name and project file name
   FilePath projectFile = directoryPath.childPath(
                                       directoryPath.filename() + ".Rproj");
   if (projectFile.exists())
      return projectFile;

   // didn't satisfy it with simple check so do scan of directory
   std::vector<FilePath> children;
   Error error = directoryPath.children(&children);
   if (error)
   {
      LOG_ERROR(error);
      return FilePath();
   }

   // build a vector of children with .rproj extensions. at the same
   // time allow for a case insensitive match with dir name and return that
   std::string projFileLower = string_utils::toLower(projectFile.filename());
   std::vector<FilePath> rprojFiles;
   for (std::vector<FilePath>::const_iterator it = children.begin();
        it != children.end();
        ++it)
   {
      if (!it->isDirectory() && (it->extensionLowerCase() == ".rproj"))
      {
         if (string_utils::toLower(it->filename()) == projFileLower)
            return *it;
         else
            rprojFiles.push_back(*it);
      }
   }

   // if we found only one rproj file then return it
   if (rprojFiles.size() == 1)
   {
      return rprojFiles.at(0);
   }
   // more than one, take most recent
   else if (rprojFiles.size() > 1 )
   {
      projectFile = rprojFiles.at(0);
      for (std::vector<FilePath>::const_iterator it = rprojFiles.begin();
           it != rprojFiles.end();
           ++it)
      {
         if (it->lastWriteTime() > projectFile.lastWriteTime())
            projectFile = *it;
      }

      return projectFile;
   }
   // didn't find one
   else
   {
      return FilePath();
   }
}
예제 #3
0
FilePath Options::urlopenerPath() const
{
   FilePath parentDir = scriptsPath();

   // detect dev configuration
   if (parentDir.filename() == "desktop")
      parentDir = parentDir.complete("urlopener");

   return parentDir.complete("urlopener.exe");
}
예제 #4
0
FilePath Options::rsinversePath() const
{
   FilePath parentDir = scriptsPath();

   // detect dev configuration
   if (parentDir.filename() == "desktop")
      parentDir = parentDir.complete("synctex/rsinverse");

   return parentDir.complete("rsinverse.exe");
}
예제 #5
0
void enqueueChunkOutput(const std::string& docId,
      const std::string& chunkId, int outputType, 
      const FilePath& path)
{
   json::Object output;
   output[kChunkOutputType]  = outputType;
   output[kChunkOutputValue] = kChunkOutputPath "/" + docId + "/" +
      chunkId + "/" + path.filename();

   json::Object result;
   result[kChunkId]         = chunkId;
   result[kChunkDocId]      = docId;
   result[kChunkOutputPath] = output;
   ClientEvent event(client_events::kChunkOutput, result);
   module_context::enqueClientEvent(event);
}
예제 #6
0
SEXP rs_pathInfo(SEXP pathSEXP)
{
   try
   {
      // validate
      if (r::sexp::length(pathSEXP) != 1)
      {
         throw r::exec::RErrorException(
                        "must pass a single file to get path info for");
      }

      std::string path;
      Error error = r::sexp::extract(pathSEXP, &path);
      if (error)
         throw r::exec::RErrorException(r::endUserErrorMessage(error));

      // resolve aliased path
      FilePath filePath = module_context::resolveAliasedPath(path);
      if (filePath.empty())
         throw r::exec::RErrorException("invalid path: " + path);

      // create path info vector (use json repsesentation to force convertion
      // to VECSXP rather than STRSXP)
      json::Object pathInfo;
      pathInfo["path"] = filePath.absolutePath();
      std::string parent = filePath.absolutePath();
      FilePath parentPath = filePath.parent();
      if (!parentPath.empty())
         parent = parentPath.absolutePath();
      pathInfo["directory"] = parent;
      pathInfo["name"] = filePath.filename();
      pathInfo["stem"] = filePath.stem();
      pathInfo["extension"] = filePath.extension();

      // return it
      r::sexp::Protect rProtect;
      return r::sexp::create(pathInfo, &rProtect);
   }
   catch(r::exec::RErrorException e)
   {
      r::exec::error(e.message());
   }
   CATCH_UNEXPECTED_EXCEPTION

   return R_NilValue;
}
예제 #7
0
Error enqueueChunkOutput(
      const std::string& docPath, const std::string& docId,
      const std::string& chunkId, const std::string& contextId)
{
   FilePath outputPath = chunkOutputPath(docPath, docId, chunkId, contextId);

   // scan the directory for output
   std::vector<FilePath> outputPaths;
   Error error = outputPath.children(&outputPaths);

   // non-fatal: if we can't list we'll safely return an empty array
   if (error) 
      LOG_ERROR(error);

   // arrange by filename (use FilePath's < operator)
   std::sort(outputPaths.begin(), outputPaths.end());

   // loop through each and build an array of the outputs
   json::Array outputs;
   BOOST_FOREACH(const FilePath& outputPath, outputPaths)
   {
      json::Object output;

      // ascertain chunk output type from file extension; skip if extension 
      // unknown
      int outputType = chunkOutputType(outputPath);
      if (outputType == kChunkOutputNone)
         continue;

      // format/parse chunk output for client consumption
      output[kChunkOutputType] = outputType;
      if (outputType == kChunkOutputText)
      {
         json::Array consoleOutput;
         error = chunkConsoleContents(outputPath, &consoleOutput);
         output[kChunkOutputValue] = consoleOutput;
      }
      else if (outputType == kChunkOutputPlot ||
               outputType == kChunkOutputHtml)
      {
         output[kChunkOutputValue] = kChunkOutputPath "/" + docId + "/" +
            chunkId + "/" + outputPath.filename();
      }

      outputs.push_back(output);
   }
예제 #8
0
///
/// オーディオリソース生成
AudioResourcePtr AudioResource::create(
    FilePath& filepath  ///< ファイルパス
) {
    //  未サポート判定
    T3_ASSERT_MSG(filepath.ext() == ".wav", "%s is not support. only supported .wav", filepath.filename().c_str());
    
    //  とりあえず.wavだけサポート
    Wav wav;
    wav.load(filepath);
    
    //  リソース生成
    AudioResourcePtr res;
    res.reset(T3_SYS_NEW AudioResource);
    res->setupBuffer(wav);
    res->resourceName(filepath.filename().c_str());
    res->createHandle();
    return res;
}
예제 #9
0
bool isHiddenFile(const FilePath& filePath) 
{
   std::string filename = filePath.filename() ;
   return (!filename.empty() && (filename[0] == '.')) ;
}  
예제 #10
0
   void runLatexCompiler(const rnw_concordance::Concordances& concordances =
                                            rnw_concordance::Concordances())
   {
      // configure pdflatex options
      pdflatex::PdfLatexOptions options;
      options.fileLineError = false;
      options.syncTex = true;
      options.shellEscape = userSettings().enableLaTeXShellEscape();

      // get back-end version info
      core::system::ProcessResult result;
      Error error = core::system::runProgram(
                  string_utils::utf8ToSystem(texProgramPath_.absolutePath()),
                  core::shell_utils::ShellArgs() << "--version",
                  "",
                  core::system::ProcessOptions(),
                  &result);
      if (error)
         LOG_ERROR(error);
      else if (result.exitStatus != EXIT_SUCCESS)
         LOG_ERROR_MESSAGE("Error probing for latex version: "+ result.stdErr);
      else
         options.versionInfo = result.stdOut;

      // compute tex file path
      FilePath texFilePath = targetFilePath_.parent().complete(
                                                targetFilePath_.stem() +
                                                ".tex");

      // remove log files if they exist (avoids confusion created by parsing
      // old log files for errors)
      removeExistingLogs(texFilePath);

      // setup cleanup context if clean was specified
      if (userSettings().cleanTexi2DviOutput())
         auxillaryFileCleanupContext_.init(texFilePath);

      // run latex compile


      // try to use texi2dvi if we can
      if (userSettings().useTexi2Dvi() && tex::texi2dvi::isAvailable())
      {
         enqueOutputEvent("Running texi2dvi on " +
                          texFilePath.filename() + "...");

         Error error = tex::texi2dvi::texToPdf(
                           texProgramPath_,
                           texFilePath,
                           options,
                           boost::bind(
                              &AsyncPdfCompiler::onLatexCompileCompleted,
                                 AsyncPdfCompiler::shared_from_this(),
                                 _1,
                                 texFilePath,
                                 concordances));
         if (error)
            terminateWithError("Unable to compile pdf: " + error.summary());
      }

      // call pdflatex directly (but still try to run bibtex as necessary)
      else
      {
         // this is our "simulated" texi2dvi -- this was originally
         // coded as a sequence of sync calls to pdflatex, bibtex, and
         // makeindex. re-coding it as async is going to be a bit
         // involved so considering that this is not the default
         // codepath we'll leave it sync for now (and then just call
         // the (typically) async callback function onLatexCompileCompleted
         // directly after the function returns

         enqueOutputEvent("Running " + texProgramPath_.filename() +
                          " on " + texFilePath.filename() + "...");

         Error error = tex::pdflatex::texToPdf(texProgramPath_,
                                               texFilePath,
                                               options,
                                               &result);

         if (error)
         {
            terminateWithError("Unable to compile pdf: " + error.summary());
         }
         else
         {
            onLatexCompileCompleted(result.exitStatus,
                                    texFilePath,
                                    concordances);
         }
      }
   }