예제 #1
0
bool copySourceFile(const FilePath& sourceDir, 
                    const FilePath& destDir,
                    int level,
                    const FilePath& sourceFilePath)
{
   // compute the target path
   std::string relativePath = sourceFilePath.relativePath(sourceDir);
   FilePath targetPath = destDir.complete(relativePath);
   
   // if the copy item is a directory just create it
   if (sourceFilePath.isDirectory())
   {
      Error error = targetPath.ensureDirectory();
      if (error)
         LOG_ERROR(error);
   }
   // otherwise copy it
   else
   {
      Error error = sourceFilePath.copy(targetPath);
      if (error)
         LOG_ERROR(error);
   }
   return true;
}
 ExecuteChunkOperation(const std::string& docId,
                       const std::string& chunkId,
                       const std::string& nbCtxId,
                       const ShellCommand& command,
                       const core::FilePath& scriptPath)
    : terminationRequested_(false),
      docId_(docId),
      chunkId_(chunkId),
      nbCtxId_(nbCtxId),
      command_(command),
      scriptPath_(scriptPath)
 {
    using namespace core;
    Error error = Success();
    
    // ensure regular directory
    FilePath outputPath = chunkOutputPath(
             docId_,
             chunkId_,
             ContextExact);
    
    error = outputPath.removeIfExists();
    if (error)
       LOG_ERROR(error);
    
    error = outputPath.ensureDirectory();
    if (error)
       LOG_ERROR(error);
    
    // clean old chunk output
    error = cleanChunkOutput(docId_, chunkId_, nbCtxId_, true);
    if (error)
       LOG_ERROR(error);
 }
예제 #3
0
FilePath getProjectUserDataDir(const ErrorLocation& location)
{
   // get the project directory
   FilePath projectDir = projects::projectContext().directory();

   // presume that the project dir is the data dir then check
   // for a .Ruserdata directory as an alternative
   FilePath dataDir = projectDir;

   FilePath ruserdataDir = projectDir.childPath(".Ruserdata");
   if (ruserdataDir.exists())
   {
      // create user-specific subdirectory if necessary
      FilePath userDir = ruserdataDir.childPath(core::system::username());
      Error error = userDir.ensureDirectory();
      if (!error)
      {
         dataDir = userDir;
      }
      else
      {
         core::log::logError(error, location);
      }
   }

   // return the data dir
   return dataDir;
}
예제 #4
0
// IN: String sourcePath, String targetPath
Error copyFile(const ::core::json::JsonRpcRequest& request,
               json::JsonRpcResponse* pResponse)
{
   // read params
   std::string sourcePath, targetPath;
   bool overwrite;
   Error error = json::readParams(request.params,
                                  &sourcePath,
                                  &targetPath,
                                  &overwrite);
   if (error)
      return error;
   FilePath targetFilePath = module_context::resolveAliasedPath(targetPath);
   
   // make sure the target path doesn't exist
   if (targetFilePath.exists())
   {
      if (overwrite)
      {
         Error error = targetFilePath.remove();
         if (error)
         {
            LOG_ERROR(error);
            return fileExistsError(ERROR_LOCATION);
         }
      }
      else
      {
         return fileExistsError(ERROR_LOCATION);
      }
   }

   // compute the source file path
   FilePath sourceFilePath = module_context::resolveAliasedPath(sourcePath);
   
   // copy directories recursively
   Error copyError ;
   if (sourceFilePath.isDirectory())
   {
      // create the target directory
      Error error = targetFilePath.ensureDirectory();
      if (error)
         return error ;
      
      // iterate over the source
      copyError = sourceFilePath.childrenRecursive(
        boost::bind(copySourceFile, sourceFilePath, targetFilePath, _1, _2));
   }
   else
   {
      copyError = sourceFilePath.copy(targetFilePath);
   }
   
   // check quota after copies
   quotas::checkQuotaStatus();
   
   // return error status
   return copyError;
}
예제 #5
0
FilePath historySerializationPath()
{
   FilePath historyPath = module_context::sessionScratchPath()
                                    .childPath("viewer_history");
   Error error = historyPath.ensureDirectory();
   if (error)
      LOG_ERROR(error);
   return historyPath;
}
예제 #6
0
FileLogWriter::FileLogWriter(const std::string& programIdentity,
                             int logLevel,
                             const FilePath& logDir)
                                : programIdentity_(programIdentity),
                                  logLevel_(logLevel)
{
   logDir.ensureDirectory();

   logFile_ = logDir.childPath(programIdentity + ".log");
}
예제 #7
0
FilePath RestartContext::createSessionStatePath(const FilePath& scopePath,
                                                const std::string& contextId)
{
   FilePath contextsPath = restartContextsPath(scopePath);
   FilePath statePath = contextsPath.complete(kContext + contextId);

   Error error = statePath.ensureDirectory();
   if (error)
      LOG_ERROR(error);
   return statePath;
}
예제 #8
0
inline Error initializeStreamDir(const FilePath& streamDir)
{
   Error error = streamDir.ensureDirectory();
   if (error)
      return error;
      
   error = changeFileMode(streamDir.parent(),
                          system::EveryoneReadWriteExecuteMode);
   if (error)
      return error;
      
   return changeFileMode(streamDir,
                         system::EveryoneReadWriteExecuteMode);
}
예제 #9
0
FilePath userSettingsPath(const FilePath& userHomeDirectory,
                          const std::string& appName)
{
   std::string lower = appName;
   boost::to_lower(lower);

   FilePath path = userHomeDirectory.childPath("." + lower);
   Error error = path.ensureDirectory();
   if (error)
   {
      LOG_ERROR(error);
   }
   return path;
}
예제 #10
0
FileLogWriter::FileLogWriter(const std::string& programIdentity,
                             int logLevel,
                             const FilePath& logDir)
                                : programIdentity_(programIdentity),
                                  logLevel_(logLevel)
{
   logDir.ensureDirectory();

   logFile_ = logDir.childPath(programIdentity + ".log");

   if (!logFile_.exists())
   {
      // swallow errors -- we can't log so it doesn't matter
      core::appendToFile(logFile_, "");
   }
}
예제 #11
0
FilePath viewInBrowserPath()
{
   if (s_presentationState.viewInBrowserPath.empty())
   {
      FilePath viewDir = module_context::tempFile("view", "dir");
      Error error = viewDir.ensureDirectory();
      if (!error)
      {
         s_presentationState.viewInBrowserPath =
                                    viewDir.childPath("presentation.html");
      }
      else
      {
         LOG_ERROR(error);
      }
   }

   return s_presentationState.viewInBrowserPath;
}
예제 #12
0
void initSaveContext(const FilePath& statePath,
                     Settings* pSettings,
                     bool* pSaved)
{
   // ensure the context exists
   Error error = statePath.ensureDirectory();
   if (error)
   {
      reportError(kSaving, "creating directory", error, ERROR_LOCATION);
      *pSaved = false;
   }

   // init session settings
   error = pSettings->initialize(statePath.complete(kSettingsFile));
   if (error)
   {
      reportError(kSaving, kSettingsFile, error, ERROR_LOCATION);
      *pSaved = false;
   }
}
예제 #13
0
// IN: String path
core::Error createFolder(const core::json::JsonRpcRequest& request,
                         json::JsonRpcResponse* pResponse)
{
   std::string path;
   Error error = json::readParam(request.params, 0, &path);
   if (error)
      return error ;   
   
   // create the directory
   FilePath folderPath = module_context::resolveAliasedPath(path) ;
   if (folderPath.exists())
   {
      return fileExistsError(ERROR_LOCATION);
   }
   else
   {
      Error createError = folderPath.ensureDirectory() ;
      if (createError)
         return createError ;
   }

   return Success() ;
}
예제 #14
0
void onDocSaved(FilePath &path)
{
   Error error;
   // ignore non-R Markdown saves
   if (!path.hasExtensionLowerCase(".rmd"))
      return;

   // find cache folder (bail out if it doesn't exist)
   FilePath cache = chunkCacheFolder(path, "", notebookCtxId());
   if (!cache.exists())
      return;

   FilePath saved = chunkCacheFolder(path, "", kSavedCtx);
   if (saved.exists())
   {
      // tidy up: remove any saved chunks that no longer exist
      error = removeStaleSavedChunks(path, saved);
      if (error)
         LOG_ERROR(error);
   }
   else
   {
      // no saved context yet; ensure we have a place to put it
      saved.ensureDirectory();
   }

   // move all the chunk definitions over to the saved context
   std::vector<FilePath> children;
   error = cache.children(&children);
   if (error)
   {
      LOG_ERROR(error);
      return;
   }
   BOOST_FOREACH(const FilePath source, children)
   {
      // compute the target path 
      FilePath target = saved.complete(source.filename());

      if (source.filename() == kNotebookChunkDefFilename) 
      {
         // the definitions should be copied (we always want them in both
         // contexts)
         error = target.removeIfExists();
         if (!error)
            error = source.copy(target);
      }
      else if (source.isDirectory())
      {
         // library folders should be merged and then removed, so we don't
         // lose library contents 
         if (source.filename() == kChunkLibDir)
         {
            error = mergeLib(source, target);
            if (!error)
               error = source.remove();
         }
         else
         {
            // the chunk output folders should be moved; destroy the old copy
            error = target.removeIfExists();
            if (!error)
               error = source.move(target);
         }
      }
      else
      {
         // nothing besides the chunks.json and chunk folders should be here,
         // so ignore other files/content
         continue;
      }

      if (error)
         LOG_ERROR(error);
   }
예제 #15
0
Error createProject(const json::JsonRpcRequest& request,
                    json::JsonRpcResponse* pResponse)
{
   // read params
   std::string projectFile;
   json::Value newPackageJson, newShinyAppJson;
   Error error = json::readParams(request.params,
                                  &projectFile,
                                  &newPackageJson,
                                  &newShinyAppJson);
   if (error)
      return error;
   FilePath projectFilePath = module_context::resolveAliasedPath(projectFile);

   // package project
   if (!newPackageJson.is_null())
   {
      // build list of code files
      bool usingRcpp;
      json::Array codeFilesJson;
      Error error = json::readObject(newPackageJson.get_obj(),
                                     "using_rcpp", &usingRcpp,
                                     "code_files", &codeFilesJson);
      if (error)
         return error;
      std::vector<FilePath> codeFiles;
      BOOST_FOREACH(const json::Value codeFile, codeFilesJson)
      {
         if (!json::isType<std::string>(codeFile))
         {
            BOOST_ASSERT(false);
            continue;
         }

         FilePath codeFilePath =
                     module_context::resolveAliasedPath(codeFile.get_str());
         codeFiles.push_back(codeFilePath);
      }

      // error if the package dir already exists
      FilePath packageDir = projectFilePath.parent();
      if (packageDir.exists())
         return core::fileExistsError(ERROR_LOCATION);

      // create a temp dir (so we can import the list of code files)
      FilePath tempDir = module_context::tempFile("newpkg", "dir");
      error = tempDir.ensureDirectory();
      if (error)
         return error;

      // copy the code files into the tempDir and build up a
      // list of the filenames for passing to package.skeleton
      std::vector<std::string> rFileNames, cppFileNames;
      BOOST_FOREACH(const FilePath& codeFilePath, codeFiles)
      {
         FilePath targetPath = tempDir.complete(codeFilePath.filename());
         Error error = codeFilePath.copy(targetPath);
         if (error)
            return error;

         std::string ext = targetPath.extensionLowerCase();
         std::string file = string_utils::utf8ToSystem(targetPath.filename());
         if (boost::algorithm::starts_with(ext,".c"))
            cppFileNames.push_back(file);
         else
            rFileNames.push_back(file);
      }
예제 #16
0
Error createProject(const json::JsonRpcRequest& request,
                    json::JsonRpcResponse* pResponse)
{
   // read params
   std::string projectFile;
   json::Value newPackageJson;
   json::Value newShinyAppJson;
   Error error = json::readParams(request.params,
                                  &projectFile,
                                  &newPackageJson,
                                  &newShinyAppJson);
   if (error)
      return error;
   FilePath projectFilePath = module_context::resolveAliasedPath(projectFile);

   if (!newShinyAppJson.is_null())
   {
      // error if the shiny app dir already exists
      FilePath appDir = projectFilePath.parent();
      if (appDir.exists())
         return core::fileExistsError(ERROR_LOCATION);

      // now create it
      Error error = appDir.ensureDirectory();
      if (error)
         return error;

      // copy ui.R and server.R into the project
      const char * const kUI = "ui.R";
      const char * const kServer = "server.R";
      std::string shinyVer;
      if (module_context::isPackageVersionInstalled("shiny", "0.9"))
         shinyVer = "shiny-0.9";
      else
         shinyVer = "shiny";
      FilePath shinyDir = session::options().rResourcesPath().childPath(
                                                     "templates/" + shinyVer);
      error = shinyDir.childPath(kUI).copy(appDir.childPath(kUI));
      if (error)
         LOG_ERROR(error);
      error = shinyDir.childPath(kServer).copy(appDir.childPath(kServer));
      if (error)
         LOG_ERROR(error);

      // add first run actions for the source files
      addFirstRunDoc(projectFilePath, kUI);
      addFirstRunDoc(projectFilePath, kServer);

      // create the project file
      return r_util::writeProjectFile(projectFilePath,
                                      ProjectContext::buildDefaults(),
                                      ProjectContext::defaultConfig());
   }

   // default project
   else
   {
      // create the project directory if necessary
      error = projectFilePath.parent().ensureDirectory();
      if (error)
         return error;

      // create the project file
      if (!projectFilePath.exists())
      {
         return r_util::writeProjectFile(projectFilePath,
                                         ProjectContext::buildDefaults(),
                                         ProjectContext::defaultConfig());
      }
      else
      {
         return Success();
      }
   }
}
예제 #17
0
Error createProject(const json::JsonRpcRequest& request,
                    json::JsonRpcResponse* pResponse)
{
   // read params
   std::string projectFile;
   json::Value newPackageJson;
   Error error = json::readParams(request.params,
                                  &projectFile,
                                  &newPackageJson);
   if (error)
      return error;
   FilePath projectFilePath = module_context::resolveAliasedPath(projectFile);

   // default project
   if (newPackageJson.is_null())
   {
      // create the project directory if necessary
      error = projectFilePath.parent().ensureDirectory();
      if (error)
         return error;

      // create the project file
      if (!projectFilePath.exists())
      {
         return r_util::writeProjectFile(projectFilePath,
                                         ProjectContext::defaultConfig());
      }
      else
      {
         return Success();
      }
   }

   // package project
   else
   {
      // build list of code files
      bool usingRcpp;
      json::Array codeFilesJson;
      Error error = json::readObject(newPackageJson.get_obj(),
                                     "using_rcpp", &usingRcpp,
                                     "code_files", &codeFilesJson);
      if (error)
         return error;
      std::vector<FilePath> codeFiles;
      BOOST_FOREACH(const json::Value codeFile, codeFilesJson)
      {
         if (!json::isType<std::string>(codeFile))
         {
            BOOST_ASSERT(false);
            continue;
         }

         FilePath codeFilePath =
                     module_context::resolveAliasedPath(codeFile.get_str());
         codeFiles.push_back(codeFilePath);
      }

      // error if the package dir already exists
      FilePath packageDir = projectFilePath.parent();
      if (packageDir.exists())
         return core::fileExistsError(ERROR_LOCATION);

      // create a temp dir (so we can import the list of code files)
      FilePath tempDir = module_context::tempFile("newpkg", "dir");
      error = tempDir.ensureDirectory();
      if (error)
         return error;

      // copy the code files into the tempDir and build up a
      // list of the filenames for passing to package.skeleton
      std::vector<std::string> rFileNames, cppFileNames;
      BOOST_FOREACH(const FilePath& codeFilePath, codeFiles)
      {
         FilePath targetPath = tempDir.complete(codeFilePath.filename());
         Error error = codeFilePath.copy(targetPath);
         if (error)
            return error;

         std::string ext = targetPath.extensionLowerCase();
         std::string file = string_utils::utf8ToSystem(targetPath.filename());
         if (boost::algorithm::starts_with(ext,".c"))
            cppFileNames.push_back(file);
         else
            rFileNames.push_back(file);
      }


      // if the list of code files is empty then add an empty file
      // with the same name as the package (but don't do this for
      // Rcpp since it generates a hello world file)
      if (codeFiles.empty() && !usingRcpp)
      {
         std::string srcFileName = packageDir.filename() + ".R";
         FilePath srcFilePath = tempDir.complete(srcFileName);
         Error error = core::writeStringToFile(srcFilePath, "");
         if (error)
            return error;
         rFileNames.push_back(string_utils::utf8ToSystem(srcFileName));
      }

      // temporarily switch to the tempDir for package creation
      RestoreCurrentPathScope pathScope(module_context::safeCurrentPath());
      tempDir.makeCurrentPath();

      // call package.skeleton

      r::exec::RFunction pkgSkeleton(usingRcpp ?
                                       "Rcpp:::Rcpp.package.skeleton" :
                                       "utils:::package.skeleton");
      pkgSkeleton.addParam("name",
                           string_utils::utf8ToSystem(packageDir.filename()));
      pkgSkeleton.addParam("path",
               string_utils::utf8ToSystem(packageDir.parent().absolutePath()));
      pkgSkeleton.addParam("code_files", rFileNames);
      if (usingRcpp && module_context::haveRcppAttributes())
      {
         if (!cppFileNames.empty())
         {
            pkgSkeleton.addParam("example_code", false);
            pkgSkeleton.addParam("cpp_files", cppFileNames);
         }
         else
         {
            pkgSkeleton.addParam("attributes", true);
         }
      }
      error = pkgSkeleton.call();
      if (error)
         return error;

      // create the project file (allow auto-detection of the package
      // to setup the package build type & default options)
      r_util::RProjectConfig projConfig = ProjectContext::defaultConfig();
      return r_util::writeProjectFile(projectFilePath, projConfig);
   }