1+ using Octokit . Helpers ;
2+ using Octokit ;
3+
4+ namespace DevExcelerateApi . Core . Extensions ;
5+
6+ public static class GitHubClientExtensions
7+ {
8+ public static async Task CopyFilesAsync ( this IGitHubClient gitHubClient , string sourceOwner , string sourceRepo , string sourcePath , string targetOwner , string targetRepo , string targetPath )
9+ {
10+ if ( gitHubClient == null )
11+ {
12+ throw new InvalidOperationException ( "GitHub client is not configured." ) ;
13+ }
14+
15+ var sourceFiles = await gitHubClient . Repository . Content . GetAllContents ( sourceOwner , sourceRepo , sourcePath ) ;
16+
17+ foreach ( var file in sourceFiles )
18+ {
19+ if ( file . Type == ContentType . File )
20+ {
21+ var fileContent = await gitHubClient . Repository . Content . GetRawContent ( sourceOwner , sourceRepo , file . Path ) ;
22+ var fileContentString = System . Text . Encoding . UTF8 . GetString ( fileContent ) ;
23+ var createFileRequest = new CreateFileRequest ( $ "Copying { file . Name } from { sourceRepo } ", fileContentString ) ;
24+
25+ var targetFilePath = $ "{ targetPath } /{ file . Name } ";
26+ await gitHubClient . Repository . Content . CreateFile ( targetOwner , targetRepo , targetFilePath , createFileRequest ) ;
27+ }
28+ }
29+ }
30+
31+ public static async Task < string > GetFileContentAsync ( this IGitHubClient gitHubClient , string owner , string repo , string path )
32+ {
33+ if ( gitHubClient == null )
34+ {
35+ throw new InvalidOperationException ( "GitHub client is not configured." ) ;
36+ }
37+
38+ var fileContent = await gitHubClient . Repository . Content . GetRawContent ( owner , repo , path ) ;
39+ var fileContentString = System . Text . Encoding . UTF8 . GetString ( fileContent ) ;
40+ return fileContentString ;
41+ }
42+
43+ public static async Task < RepositoryContentChangeSet ? > SaveFileAsync (
44+ this IGitHubClient gitHubClient ,
45+ string owner ,
46+ string repo ,
47+ string defaultBranchName ,
48+ string branch ,
49+ string path ,
50+ string content )
51+ {
52+ if ( gitHubClient == null )
53+ {
54+ throw new InvalidOperationException ( "GitHub client is not configured." ) ;
55+ }
56+
57+ try
58+ {
59+ await ReferenceExtensions . CreateBranch ( gitHubClient . Git . Reference , owner , repo , branch , defaultBranchName ) ;
60+ }
61+ catch ( ApiValidationException ex )
62+ {
63+ // 422: Reference already exists
64+ if ( ex . StatusCode == System . Net . HttpStatusCode . UnprocessableEntity )
65+ {
66+ // Ignore the exception if the branch already exists
67+ }
68+ else
69+ {
70+ throw ;
71+ }
72+ }
73+
74+ try
75+ {
76+ // Check if the file already exists
77+ var existingFile = await gitHubClient . Repository . Content . GetAllContentsByRef ( owner , repo , path , branch ) ;
78+
79+ if ( existingFile != null && existingFile . Count > 0 )
80+ {
81+ var updateFileRequest = new UpdateFileRequest ( $ "Updating file { path } ", content , existingFile [ 0 ] . Sha , branch ) ;
82+ return await gitHubClient . Repository . Content . UpdateFile ( owner , repo , path , updateFileRequest ) ;
83+ }
84+ }
85+ catch ( NotFoundException )
86+ {
87+ var createFileRequest = new CreateFileRequest ( $ "Adding file { path } ", content , branch ) ;
88+
89+ return await gitHubClient . Repository . Content . CreateFile ( owner , repo , path , createFileRequest ) ;
90+ }
91+
92+ return null ;
93+ }
94+
95+ public static async Task < PullRequest > CreatePullRequestAsync ( this IGitHubClient gitHubClient , string owner , string repo , string headBranch , string baseBranch , string title , string body )
96+ {
97+ if ( gitHubClient == null )
98+ {
99+ throw new InvalidOperationException ( "GitHub client is not configured." ) ;
100+ }
101+
102+ // Step 1: Check if a pull request already exists for the head branch
103+ var pullRequests = await gitHubClient . PullRequest . GetAllForRepository ( owner , repo , new PullRequestRequest
104+ {
105+ State = ItemStateFilter . Open , // Only check open pull requests
106+ Head = $ "{ owner } :{ headBranch } " // Filter by the head branch
107+ } ) ;
108+
109+ if ( pullRequests . Any ( ) )
110+ {
111+ // If a pull request already exists, return the first one
112+ return pullRequests [ 0 ] ;
113+ }
114+
115+ // Step 2: Create a new pull request if none exists
116+ var newPullRequest = new NewPullRequest ( title , headBranch , baseBranch )
117+ {
118+ Body = body
119+ } ;
120+
121+ return await gitHubClient . PullRequest . Create ( owner , repo , newPullRequest ) ;
122+ }
123+
124+ public static async Task < IReadOnlyList < GitHubCommitFile > > GetCommitFilesAsync ( this IGitHubClient gitHubClient , string owner , string repo , string commitSha )
125+ {
126+ if ( gitHubClient == null )
127+ {
128+ throw new InvalidOperationException ( "GitHub client is not configured." ) ;
129+ }
130+
131+ // Fetch the commit details using the commit SHA
132+ var commit = await gitHubClient . Repository . Commit . Get ( owner , repo , commitSha ) ;
133+
134+ // Return the list of files associated with the commit
135+ return commit . Files ;
136+ }
137+
138+ public static async Task < Dictionary < string , string > > GetCommitFilesWithContentAsync ( this IGitHubClient gitHubClient , string owner , string repo , string commitSha )
139+ {
140+ if ( gitHubClient == null )
141+ {
142+ throw new InvalidOperationException ( "GitHub client is not configured." ) ;
143+ }
144+
145+ // Dictionary to store file paths and their content
146+ var fileContents = new Dictionary < string , string > ( ) ;
147+
148+ var files = await GetCommitFilesAsync ( gitHubClient , owner , repo , commitSha ) ;
149+
150+ foreach ( var file in files )
151+ {
152+ if ( file . Status == "added" || file . Status == "modified" ) // Only fetch content for added/modified files
153+ {
154+ try
155+ {
156+ // Fetch the raw content of the file
157+ var rawContent = await gitHubClient . Repository . Content . GetRawContent ( owner , repo , file . Filename ) ;
158+ var contentString = System . Text . Encoding . UTF8 . GetString ( rawContent ) ;
159+
160+ // Add the file path and content to the dictionary
161+ fileContents . Add ( file . Filename , contentString ) ;
162+ }
163+ catch ( NotFoundException )
164+ {
165+ // Handle cases where the file content is not accessible
166+ fileContents . Add ( file . Filename , "Content not accessible" ) ;
167+ }
168+ }
169+ }
170+
171+ return fileContents ;
172+ }
173+ }
0 commit comments