From d10111b0125064a12b49587f9efab13dcc8261f1 Mon Sep 17 00:00:00 2001 From: kendall Date: Sat, 30 Jul 2022 13:00:39 -0700 Subject: [PATCH] Add a way to mirror the directory struture when uploading a file. --- README.md | 17 ++++++++++++ action.yml | 3 ++ main.go | 81 ++++++++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 92 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 80cc0ee..a0c53c1 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,11 @@ Required: **NO** If true, the target file name will be the complete source filename and `name` parameter will be ignored. +## ``mirrorDirectoryStructure`` +Required: **NO** + +If true, the directory structure of the source file will be recreated relative to ``folderId``. + ## ``namePrefix`` Required: **NO** @@ -90,5 +95,17 @@ jobs: folderId: ${{ secrets.folderId }} name: "documentation.zip" # optional string overwrite: "true" # optional boolean + - name: Make Directory Structure + run: | + mkdir -p w/x/y + date +%s > w/x/y/z + - name: Mirror Directory Structure + uses: adityak74/google-drive-upload-git-action@main + with: + credentials: ${{ secrets.DRIVE_CREDENTIALS }} + filename: w/x/y/z + folderId: ${{ secrets.folderId }} + overwrite: "true" + mirrorDirectoryStructure: "true" ``` diff --git a/action.yml b/action.yml index 0a7bb47..e9b6c29 100644 --- a/action.yml +++ b/action.yml @@ -26,6 +26,9 @@ inputs: useCompleteSourceFilenameAsName: description: 'If true, the target file name will be the source filename and name parameter will be ignored' required: false + mirrorDirectoryStructure: + description: 'If true, recreate the directory structure of the source file relative to the folderId' + required: false namePrefix: description: 'Prefix to be added to target filename' required: false diff --git a/main.go b/main.go index aa748b0..26d4d51 100644 --- a/main.go +++ b/main.go @@ -24,18 +24,27 @@ import ( ) const ( - scope = "https://www.googleapis.com/auth/drive.file" - filenameInput = "filename" - nameInput = "name" - folderIdInput = "folderId" - credentialsInput = "credentials" - overwrite = "false" - mimeTypeInput = "mimeType" - useCompleteSourceName = "useCompleteSourceFilenameAsName" - namePrefixInput = "namePrefix" + scope = "https://www.googleapis.com/auth/drive.file" + filenameInput = "filename" + nameInput = "name" + folderIdInput = "folderId" + credentialsInput = "credentials" + overwrite = "false" + mimeTypeInput = "mimeType" + useCompleteSourceName = "useCompleteSourceFilenameAsName" + mirrorDirectoryStructure = "mirrorDirectoryStructure" + namePrefixInput = "namePrefix" ) func uploadToDrive(svc *drive.Service, filename string, folderId string, driveFile *drive.File, name string, mimeType string) { + fi, err := os.Lstat(filename) + if err != nil { + githubactions.Fatalf(fmt.Sprintf("lstat of file with filename: %v failed with error: %v", filename, err)) + } + if fi.IsDir() { + fmt.Printf("%s is a directory. skipping upload.", filename) + return + } file, err := os.Open(filename) if err != nil { githubactions.Fatalf(fmt.Sprintf("opening file with filename: %v failed with error: %v", filename, err)) @@ -109,6 +118,14 @@ func main() { useCompleteSourceFilenameAsNameFlag, _ = strconv.ParseBool(useCompleteSourceFilenameAsName) } + var mirrorDirectoryStructureFlag bool + mirrorDirectoryStructure := githubactions.GetInput(mirrorDirectoryStructure) + if mirrorDirectoryStructure == "" { + fmt.Println("mirrorDirectoryStructure is disabled.") + mirrorDirectoryStructureFlag = false + } else { + mirrorDirectoryStructureFlag, _ = strconv.ParseBool(mirrorDirectoryStructure) + } // get filename prefix filenamePrefix := githubactions.GetInput(namePrefixInput) @@ -146,8 +163,19 @@ func main() { useSourceFilename := len(files) > 1 + // Save the folderId because it might get overwritten by createDriveDirectory + originalFolderId := folderId for _, file := range files { + folderId = originalFolderId var targetName string + fmt.Printf("Processing file %s\n", file) + if mirrorDirectoryStructureFlag { + directoryStructure := strings.Split(filepath.Dir(file), string(os.PathSeparator)) + fmt.Printf("Mirroring directory structure: %v\n", directoryStructure) + for _, dir := range directoryStructure { + folderId, err = createDriveDirectory(svc, folderId, dir) + } + } if useCompleteSourceFilenameAsNameFlag { targetName = file } else if useSourceFilename || name == "" { @@ -164,6 +192,41 @@ func main() { } } +func createDriveDirectory(svc *drive.Service, folderId string, name string) (string, error) { + fmt.Printf("Checking for existing folder %s\n", name) + r, err := svc.Files.List().Fields("files(name,id,mimeType,parents)").Q("name='" + name + "'" + " and mimeType='application/vnd.google-apps.folder'").IncludeItemsFromAllDrives(true).Corpora("allDrives").SupportsAllDrives(true).Do() + if err != nil { + log.Fatalf("Unable to check for folder : %v", err) + fmt.Println("Unable to check for folder") + } + foundFolders := 0 + var nextFolderId string + for _, i := range r.Files { + for _, p := range i.Parents { + if p == folderId { + foundFolders++ + fmt.Printf("Found existing folder %s.\n", name) + nextFolderId = i.Id + } + } + } + if foundFolders == 0 { + fmt.Printf("Creating folder: %s\n", name) + f := &drive.File{ + Name: name, + MimeType: "application/vnd.google-apps.folder", + Parents: []string{folderId}, + } + d, err := svc.Files.Create(f).Fields("id").SupportsAllDrives(true).Do() + if err != nil { + log.Fatalf("Unable to create folder : %v", err) + fmt.Println("Unable to create folder") + } + nextFolderId = d.Id + } + return nextFolderId, nil +} + func uploadFile(svc *drive.Service, filename string, folderId string, name string, mimeType string, overwriteFlag bool) { fmt.Printf("target file name: %s\n", name)