GoogleCloudPlatform / google-cloud-powershell

PowerShell cmdlets for the Google Cloud Platform
http://googlecloudplatform.github.io/google-cloud-powershell/
Apache License 2.0
135 stars 61 forks source link

Read-GcsObject and related cmdlets do not support full paths that include the bucket name #645

Open chilversc opened 4 years ago

chilversc commented 4 years ago

Wanting to copy an item from a bucket I initially tried the obvious Copy-Item gs:\bucket\path\object C:\target, which obviously failed due to different providers. At this point it isn't immediately obvious what command is required to download from a bucket, the obvious Copy-GcsObject doesn't support local files.

After a while I find Read-GcsObject -OutFile, however when I try and use that it doesn't directly support paths in the format of gs:\bucket\path\object or gs://bucket/path/object.

Steps to reproduce

Try to download a file from a bucket

Set-Location $env:TEMP

Read-GcsObject -ObjectName gs://bucket/path/object -OutFile .\result
Read-GcsObject -ObjectName gs:\bucket\path\object -OutFile .\result

# Some other variations attempted
Read-GcsObject gs:\bucket\path\object -OutFile .\result
Read-GcsObject gs://bucket/path/object -OutFile .\result

Read-GcsObject -InputObject gs:\bucket\path\object -OutFile .\result
Read-GcsObject -InputObject gs://bucket/path/object -OutFile .\result

Expected result

Both those formats should be supported (perhaps using a different parameter names such as -Path and -Uri).

The first format should be supported because its the standard format provided in the Google Cloud Console, thus is easy to copy.

The second format should be supported because it matches the gs provider path. I shouldn't have to use Set-Location to my current working directory just download an object from a bucket.

Actual result

In both cases I get the error Bucket name could not be determined.

Related issues

I noticed similar issues with other cmdlets, for example Get-GcsObject doesn't support a gs: path, while Get-Item does.

Workarounds

Fetch the object's metadata first

Get-Item gs://bucket/path/object | Read-GcsObject -Outfile .\result

Note: This supports both gs://bucket style URIs and gs:\bucket paths because the gs://bucket format will is mapped to the same path by the GoogleCloudStorage provider.

Temporarily change location

function Copy-GcsObjectToFile {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true)] $Path,
        [Parameter(Mandatory=$true)] $Destination,
        [switch] $Force
    )

    # The destination is most likely a relative path, and probably doesn't exist
    # so resolve it to an absolute path.
    $Destination = $PSCmdlet.GetUnresolvedProviderPathFromPSPath($Destination)

    Push-Location (Split-Path -Parent $Path)
    try {
        Read-GcsObject -ObjectName (Split-Path -Leaf $Path) -OutFile $Destination -Force:$Force
    } finally {
        Pop-Location
    }
}