Skip to content

Commit 9a45908

Browse files
authored
Adding Get Repository.Contents functionality (#146)
Adds `Get-GitHubContent` and corresponding tests. Also adds formatting files for VS Code and EditorConfig.
1 parent e07d3fa commit 9a45908

File tree

8 files changed

+365
-14
lines changed

8 files changed

+365
-14
lines changed

.editorconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# editorconfig.org
2+
3+
# top-most EditorConfig file
4+
root = true
5+
6+
[*]
7+
8+
trim_trailing_whitespace = true

.vscode/settings.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"[powershell]": {
3+
"files.trimTrailingWhitespace": true
4+
},
5+
"powershell.codeFormatting.openBraceOnSameLine": false,
6+
"powershell.codeFormatting.alignPropertyValuePairs": false
7+
}

GitHubComments.ps1

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ function Get-GitHubComment
181181
'UriFragment' = $uriFragment
182182
'Description' = $description
183183
'AccessToken' = $AccessToken
184-
'AcceptHeader' = (Get-MediaAcceptHeader -MediaType $MediaType -AcceptHeader $squirrelAcceptHeader)
184+
'AcceptHeader' = (Get-MediaAcceptHeader -MediaType $MediaType -AsJson -AcceptHeader $squirrelAcceptHeader)
185185
'TelemetryEventName' = $MyInvocation.MyCommand.Name
186186
'TelemetryProperties' = $telemetryProperties
187187
'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -Name NoStatus -ConfigValueName DefaultNoStatus)
@@ -292,7 +292,7 @@ function New-GitHubComment
292292
'Method' = 'Post'
293293
'Description' = "Creating comment under issue $Issue for $RepositoryName"
294294
'AccessToken' = $AccessToken
295-
'AcceptHeader' = (Get-MediaAcceptHeader -MediaType $MediaType -AcceptHeader $squirrelAcceptHeader)
295+
'AcceptHeader' = (Get-MediaAcceptHeader -MediaType $MediaType -AsJson -AcceptHeader $squirrelAcceptHeader)
296296
'TelemetryEventName' = $MyInvocation.MyCommand.Name
297297
'TelemetryProperties' = $telemetryProperties
298298
'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -Name NoStatus -ConfigValueName DefaultNoStatus)
@@ -403,7 +403,7 @@ function Set-GitHubComment
403403
'Method' = 'Patch'
404404
'Description' = "Update comment $CommentID for $RepositoryName"
405405
'AccessToken' = $AccessToken
406-
'AcceptHeader' = (Get-MediaAcceptHeader -MediaType $MediaType -AcceptHeader $squirrelAcceptHeader)
406+
'AcceptHeader' = (Get-MediaAcceptHeader -MediaType $MediaType -AsJson -AcceptHeader $squirrelAcceptHeader)
407407
'TelemetryEventName' = $MyInvocation.MyCommand.Name
408408
'TelemetryProperties' = $telemetryProperties
409409
'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -Name NoStatus -ConfigValueName DefaultNoStatus)

GitHubContents.ps1

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
function Get-GitHubContent
2+
{
3+
<#
4+
.SYNOPSIS
5+
Retrieve the contents of a file or directory in a repository on GitHub.
6+
7+
.DESCRIPTION
8+
Retrieve content from files on GitHub.
9+
The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub
10+
11+
.PARAMETER OwnerName
12+
Owner of the repository.
13+
If not supplied here, the DefaultOwnerName configuration property value will be used.
14+
15+
.PARAMETER RepositoryName
16+
Name of the repository.
17+
If not supplied here, the DefaultRepositoryName configuration property value will be used.
18+
19+
.PARAMETER Uri
20+
Uri for the repository.
21+
The OwnerName and RepositoryName will be extracted from here instead of needing to provide
22+
them individually.
23+
24+
.PARAMETER Path
25+
The file path for which to retrieve contents
26+
27+
.PARAMETER MediaType
28+
The format in which the API will return the body of the issue.
29+
Object - Return a json object representation a file or folder. This is the default if you do not pass any specific media type.
30+
Raw - Return the raw contents of a file.
31+
Html - For markup files such as Markdown or AsciiDoc, you can retrieve the rendered HTML using the Html media type.
32+
33+
.PARAMETER ResultAsString
34+
If this switch is specified and the MediaType is either Raw or Html then the resulting bytes will be decoded the result will be
35+
returned as a string instead of bytes. If the MediaType is Object, then an additional property on the object is returned 'contentAsString'
36+
which will be the decoded base64 result as a string.
37+
38+
.PARAMETER AccessToken
39+
If provided, this will be used as the AccessToken for authentication with the
40+
REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated.
41+
42+
.PARAMETER NoStatus
43+
If this switch is specified, long-running commands will run on the main thread
44+
with no commandline status update. When not specified, those commands run in
45+
the background, enabling the command prompt to provide status information.
46+
If not supplied here, the DefaultNoStatus configuration property value will be used.
47+
48+
.EXAMPLE
49+
Get-GitHubContent -OwnerName microsoft -RepositoryName PowerShellForGitHub -Path README.md -MediaType Html
50+
51+
Get the Html output for the README.md file
52+
53+
.EXAMPLE
54+
Get-GitHubContent -OwnerName microsoft -RepositoryName PowerShellForGitHub -Path LICENSE
55+
56+
Get the Binary file output for the LICENSE file
57+
58+
.EXAMPLE
59+
Get-GitHubContent -OwnerName microsoft -RepositoryName PowerShellForGitHub -Path Tests
60+
61+
List the files within the "Tests" path of the repository
62+
#>
63+
[CmdletBinding(
64+
SupportsShouldProcess,
65+
DefaultParametersetName = 'Elements')]
66+
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "", Justification = "Methods called within here make use of PSShouldProcess, and the switch is passed on to them inherently.")]
67+
param(
68+
[Parameter(Mandatory, ParameterSetName = 'Elements')]
69+
[string] $OwnerName,
70+
71+
[Parameter(Mandatory, ParameterSetName = 'Elements')]
72+
[string] $RepositoryName,
73+
74+
[Parameter(
75+
Mandatory,
76+
ParameterSetName='Uri')]
77+
[string] $Uri,
78+
79+
[string] $Path,
80+
81+
[ValidateSet('Raw', 'Html', 'Object')]
82+
[string] $MediaType = 'Object',
83+
84+
[switch] $ResultAsString,
85+
86+
[string] $AccessToken,
87+
88+
[switch] $NoStatus
89+
)
90+
91+
Write-InvocationLog
92+
93+
$elements = Resolve-RepositoryElements -DisableValidation
94+
$OwnerName = $elements.ownerName
95+
$RepositoryName = $elements.repositoryName
96+
97+
$telemetryProperties = @{
98+
'OwnerName' = (Get-PiiSafeString -PlainText $OwnerName)
99+
'RepositoryName' = (Get-PiiSafeString -PlainText $RepositoryName)
100+
}
101+
102+
$description = [String]::Empty
103+
104+
$uriFragment = "/repos/$OwnerName/$RepositoryName/contents"
105+
106+
if ($PSBoundParameters.ContainsKey('Path'))
107+
{
108+
$Path = $Path.TrimStart("\", "/")
109+
$uriFragment += "/$Path"
110+
$description = "Getting content for $Path in $RepositoryName"
111+
}
112+
else
113+
{
114+
$description = "Getting all content for in $RepositoryName"
115+
}
116+
117+
$params = @{
118+
'UriFragment' = $uriFragment
119+
'Description' = $description
120+
'AcceptHeader' = (Get-MediaAcceptHeader -MediaType $MediaType)
121+
'AccessToken' = $AccessToken
122+
'TelemetryEventName' = $MyInvocation.MyCommand.Name
123+
'TelemetryProperties' = $telemetryProperties
124+
'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -Name NoStatus -ConfigValueName DefaultNoStatus)
125+
}
126+
127+
$result = Invoke-GHRestMethodMultipleResult @params
128+
129+
if ($ResultAsString)
130+
{
131+
if ($MediaType -eq 'Raw' -or $MediaType -eq 'Html')
132+
{
133+
# Decode bytes to string
134+
$result = [System.Text.Encoding]::UTF8.GetString($result)
135+
}
136+
elseif ($MediaType -eq 'Object')
137+
{
138+
# Convert from base64
139+
$decoded = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($result.content))
140+
Add-Member -InputObject $result -NotePropertyName "contentAsString" -NotePropertyValue $decoded
141+
}
142+
}
143+
144+
return $result
145+
}

GitHubCore.ps1

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ function Invoke-GHRestMethod
127127
# be coming from the Location header in a previous response. Either way, we don't want there
128128
# to be a leading "/" or trailing '/'
129129
if ($UriFragment.StartsWith('/')) { $UriFragment = $UriFragment.Substring(1) }
130-
if ($UriFragment.EndsWIth('/')) { $UriFragment = $UriFragment.Substring(0, $UriFragment.Length - 1) }
130+
if ($UriFragment.EndsWith('/')) { $UriFragment = $UriFragment.Substring(0, $UriFragment.Length - 1) }
131131

132132
if ([String]::IsNullOrEmpty($Description))
133133
{
@@ -645,7 +645,8 @@ function Invoke-GHRestMethodMultipleResult
645645

646646
try
647647
{
648-
do {
648+
do
649+
{
649650
$params = @{
650651
'UriFragment' = $nextLink
651652
'Method' = 'Get'
@@ -949,6 +950,10 @@ function Get-MediaAcceptHeader
949950
Text - Return a text only representation of the markdown body. Response will include body_text.
950951
Html - Return HTML rendered from the body's markdown. Response will include body_html.
951952
Full - Return raw, text and HTML representations. Response will include body, body_text, and body_html.
953+
Object - Return a json object representation a file or folder.
954+
955+
.PARAMETER AsJson
956+
If this switch is specified as +json value is appended to the MediaType header.
952957
953958
.PARAMETER AcceptHeader
954959
The accept header that should be included with the MediaType accept header.
@@ -960,16 +965,24 @@ function Get-MediaAcceptHeader
960965
#>
961966
[CmdletBinding()]
962967
param(
963-
[ValidateSet('Raw', 'Text', 'Html', 'Full')]
968+
[ValidateSet('Raw', 'Text', 'Html', 'Full', 'Object')]
964969
[string] $MediaType = 'Raw',
965970

966-
[Parameter(Mandatory)]
971+
[switch] $AsJson,
972+
967973
[string] $AcceptHeader
968974
)
969975

970-
$acceptHeaders = @(
971-
$AcceptHeader,
972-
"application/vnd.github.$mediaTypeVersion.$($MediaType.ToLower())+json")
976+
$resultHeaders = "application/vnd.github.$mediaTypeVersion.$($MediaType.ToLower())"
977+
if ($AsJson)
978+
{
979+
$resultHeaders = $resultHeaders + "+json"
980+
}
981+
982+
if (-not [String]::IsNullOrEmpty($AcceptHeader))
983+
{
984+
$resultHeaders = "$AcceptHeader,$resultHeaders"
985+
}
973986

974-
return ($acceptHeaders -join ',')
987+
return $resultHeaders
975988
}

GitHubIssues.ps1

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ function Get-GitHubIssue
315315
$params = @{
316316
'UriFragment' = $uriFragment + '?' + ($getParams -join '&')
317317
'Description' = $description
318-
'AcceptHeader' = (Get-MediaAcceptHeader -MediaType $MediaType -AcceptHeader $symmetraAcceptHeader)
318+
'AcceptHeader' = (Get-MediaAcceptHeader -MediaType $MediaType -AsJson -AcceptHeader $symmetraAcceptHeader)
319319
'AccessToken' = $AccessToken
320320
'TelemetryEventName' = $MyInvocation.MyCommand.Name
321321
'TelemetryProperties' = $telemetryProperties
@@ -543,7 +543,7 @@ function New-GitHubIssue
543543
'Body' = (ConvertTo-Json -InputObject $hashBody)
544544
'Method' = 'Post'
545545
'Description' = "Creating new Issue ""$Title"" on $RepositoryName"
546-
'AcceptHeader' = (Get-MediaAcceptHeader -MediaType $MediaType -AcceptHeader $symmetraAcceptHeader)
546+
'AcceptHeader' = (Get-MediaAcceptHeader -MediaType $MediaType -AsJson -AcceptHeader $symmetraAcceptHeader)
547547
'AccessToken' = $AccessToken
548548
'TelemetryEventName' = $MyInvocation.MyCommand.Name
549549
'TelemetryProperties' = $telemetryProperties
@@ -694,7 +694,7 @@ function Update-GitHubIssue
694694
'Body' = (ConvertTo-Json -InputObject $hashBody)
695695
'Method' = 'Patch'
696696
'Description' = "Updating Issue #$Issue on $RepositoryName"
697-
'AcceptHeader' = (Get-MediaAcceptHeader -MediaType $MediaType -AcceptHeader $symmetraAcceptHeader)
697+
'AcceptHeader' = (Get-MediaAcceptHeader -MediaType $MediaType -AsJson -AcceptHeader $symmetraAcceptHeader)
698698
'AccessToken' = $AccessToken
699699
'TelemetryEventName' = $MyInvocation.MyCommand.Name
700700
'TelemetryProperties' = $telemetryProperties

PowerShellForGitHub.psd1

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
'GitHubBranches.ps1',
2626
'GitHubCore.ps1',
2727
'GitHubComments.ps1',
28+
'GitHubContents.ps1',
2829
'GitHubEvents.ps1',
2930
'GitHubIssues.ps1',
3031
'GitHubLabels.ps1',
@@ -55,6 +56,7 @@
5556
'Get-GitHubCodeOfConduct',
5657
'Get-GitHubComment',
5758
'Get-GitHubConfiguration',
59+
'Get-GitHubContent',
5860
'Get-GitHubEmoji',
5961
'Get-GitHubEvent',
6062
'Get-GitHubGitIgnore',

0 commit comments

Comments
 (0)