user2054013
user2054013

Reputation: 153

How do I locate the path of the folder in which the current script file is located?

How do I locate the path of the current folder? I just want to be able to get the path of the folder so that I can manipulate the files in the folder without typing the path into the scripts.

Upvotes: 6

Views: 17891

Answers (7)

Matt Conway
Matt Conway

Reputation: 1

Looking for a simple getPath, I went for a more generic approach with limitations:

    //simple test stub
    function test_getFilePath() {
      const scriptId = ScriptApp.getScriptId();
      const fullPath = getFilePath(scriptId);
      console.log(fullPath);
    }
    
    /**
     * getFilePath
     *  @fileId id of file to find path for
     * 
     *  NB: google allows for multiple parents, which is a PITA
     *  so I'm just taking the first one I find up the tree
     */
    function getFilePath(fileId) {
      const file = DriveApp.getFileById(fileId);
    
      const rootFolder = DriveApp.getRootFolder()
      const rootFolderId = rootFolder.getId();
      const rootFolderName = rootFolder.getName();
    
      let folder = file.getParents().next();
    
      let folderNames = [];
    
      while (folder.getId() !== rootFolderId){
          folderNames.unshift(folder.getName());
          folder = folder.getParents().next();
      }
    
      const fullPath = rootFolderName+'/'+folderNames.join().replace(/,/g,'/');
    
      return fullPath;
    
    }

console:

11:36:40 AM Info My Drive/GAS


Had I more time/inclination, I'd have writen a recursive function to capture and return an array of possible parent paths, but there's no use case for me and who the hell wants to keep a the same file in multiple folders anyway??

Upvotes: 0

James
James

Reputation: 51

I tweaked Serge's code to write a generic function

function getThisFilePath() {
  //let thisFile = DriveApp.getFileById(DocumentApp.getActiveDocument().getId());  // for a Doc
  let thisFile = DriveApp.getFileById(SpreadsheetApp.getActiveSpreadsheet().getId()); // for a Sheet
  let path = {name: '', folder: []};
  let folder = thisFile.getParents().hasNext() ? thisFile.getParents().next() : undefined;
  while (folder) {
    path.folder.unshift({name: folder.getName(), id: folder.getId()});
    folder = folder.getParents().hasNext() ? folder.getParents().next() : undefined; 
  }
  path.folder.forEach(folder => path.name += '/' + folder.name);
  Logger.log(path.name);
  return path;
}

Logging output

11:02:57 AM Info /My Drive/Technology/Development/2022

Upvotes: 2

Ross Watkins
Ross Watkins

Reputation: 21

I was able to get the folder containing the script that was running:

//
// PrintScriptFolder -- print the name of the folder in which the running script resides.
//
function PrintScriptFolder()
{
  var scriptId = ScriptApp.getScriptId();
  console.info('scriptId = ' + scriptId);
  
  var file = DriveApp.getFileById(scriptId);
  var folders = file.getParents();
  if (folders.hasNext())
  {
    var folder = folders.next();
    var name = folder.getName();
    console.info('script folder name = ' + name);    
  }  
}

The trick is using ScriptApp to get the ID of the running script. From there it's pretty straightforward: use DriveApp to get the file ID, getParents() to get a list of (one) parent folder, next() to get it, and getName() to get its name.

Upvotes: 2

Corey G
Corey G

Reputation: 7858

Add a function like this to your script

function getThisScriptInDrive() {
  return DriveApp.find("some unique string that wont be anywhere else")[0];
}

This will search Drive and find this script itself because it contains that string - right there in the function call! - no need to declare it anywhere else. As long as you use an obscure enough string - i'd recommend mashing a few hundred chars on your keyboard - it will be unique across drive and therefore just work.

Once you have a File for this script, you can call getParents() etc.

Upvotes: 3

hansvb
hansvb

Reputation: 188

For a Spreadsheet I found this to work:

thisFileId = SpreadsheetApp.getActive().getId();
var thisFile = DriveApp.getFileById(thisFileId);
var parentFolder = thisFile.getParents()[0].getName();

Upvotes: 9

Serge insas
Serge insas

Reputation: 46794

Thanks to Corey's answer and to Thomas'one, here is a "full featured" version that shows the folder tree in the logger and every parents id as well... just for fun ;-)

function getScriptFolderTree() {
  var thisScript = getThisScriptInDrive();
  var names = []
  var Ids = []
  var folder = thisScript.getParents()[0];
  while (folder.getName() != "Root"){
      names.unshift(folder.getName());
      Ids.unshift(folder.getId());
    var parents = folder.getParents();
       var folder = parents[0];
  }
Logger.log('Root/'+names.join().replace(/,/g,'/'))  
Ids.unshift(DriveApp.getRootFolder().getId())
Logger.log(Ids)  
}


function getThisScriptInDrive() {
  return DriveApp.getFileById("poiuytrezazertyujhgfdsdcvcxyydryfhchfh");
}

enter image description here

(ID's are truncated intentionally)

Note that this script is working nicely but it strangely stops working if the 'random string' is modified... I imagine that the search engine in drive doesn't like the change but I have no serious explanation (comments welcome) but after a few minutes it works again ;-)

Upvotes: 4

Thomas
Thomas

Reputation: 577

You could do this:

function myFunction() {
  var thisScript = getThisScriptInDrive();
  var folder = thisScript.getParents()[0];
  while (folder.getName() != "Root"){
    var parents = folder.getParents();
    for (var i in parents){
      var folder = parents[i];
      Logger.log(folder.getName());
    }
  }
}


function getThisScriptInDrive() {
  return DocsList.find("`<jj!?=(<DW+.W/m7SBF:sgu/@B(&Cs3:{ajA~ys@KmN4&]ujhpZ~z[Tv?+dk}MpK,8pY=w&dny8N'74:.9H:~uCgY=7pRt4[Tn5")[0];
}

This only works good if the folder has only 1 parent because it only takes 1 path.

edit: Thanks to Corey G

Upvotes: -1

Related Questions