@@ -125,9 +125,51 @@ func NewGitService(cfg *config.Scheme, blockchain *ethclient.Client) (*GitServic
125125 }, nil
126126}
127127
128+ // TODO move events listeners to separate package
129+
128130func (g * GitService ) StartListener () {
129- if err := g .ListenRepositoryCreation (); err != nil {
130- logger .Log ().Error (err )
131+ go func () {
132+ if err := g .ListenRepositoryCreation (); err != nil {
133+ logger .Log ().Error (err )
134+ }
135+ }()
136+
137+ go func () {
138+ if err := g .ListenRepositoryForks (); err != nil {
139+ logger .Log ().Error (err )
140+ }
141+ }()
142+ }
143+
144+ func (g * GitService ) ListenRepositoryForks () error {
145+ repos := make (chan * contract.ContractRepositoryForked )
146+ opts := & bind.WatchOpts {Context : context .Background ()}
147+
148+ Subscribe:
149+ repositoryForksSubscriptions , err := g .contract .WatchRepositoryForked (opts , repos )
150+ if err != nil {
151+ return fmt .Errorf ("failed subscribe to watch transfers event: %w" , err )
152+ }
153+ defer repositoryForksSubscriptions .Unsubscribe ()
154+
155+ logger .Log ().Infof ("listen contract repository fork events on %s" , g .contractAddress .Hex ())
156+
157+ for {
158+ select {
159+ case <- g .stop :
160+ logger .Log ().Warning ("stop listen contract repository forks events" )
161+ close (repos )
162+ return nil
163+ case err := <- repositoryForksSubscriptions .Err ():
164+ logger .Log ().Error (fmt .Errorf ("repository forks subscription error: %w" , err ))
165+ goto Subscribe
166+ case r := <- repos :
167+ logger .Log ().Infof ("catch repository forks event: repository %s with ID %d forked from %s created with owner %s" , r .RepName , r .RepId , r .Url , r .Owner .Hex ())
168+
169+ if err := g .CloneRepo (r .RepName , r .Description , r .Url , int (r .RepId .Int64 ()), r .Owner ); err != nil {
170+ logger .Log ().Error (fmt .Errorf ("error to fork repository: %w" , err ))
171+ }
172+ }
131173 }
132174}
133175
@@ -147,7 +189,7 @@ Subscribe:
147189 for {
148190 select {
149191 case <- g .stop :
150- logger .Log ().Warning ("stop listen contract transfers events" )
192+ logger .Log ().Warning ("stop listen contract repository creation events" )
151193 close (repos )
152194 return nil
153195 case err := <- repositoryCreationSubscriptions .Err ():
@@ -163,12 +205,37 @@ Subscribe:
163205 }
164206}
165207
208+ func (g * GitService ) CloneRepo (name , description , forkFrom string , id int , owner common.Address ) error {
209+ repo , err := models .NewRepo (name , description , g .baseGitPath , forkFrom , id , owner , g .fs )
210+ if err != nil {
211+ return fmt .Errorf ("failed to create new repo: %w" , err )
212+ }
213+
214+ if err := g .processNewRepo (repo ); err != nil {
215+ return fmt .Errorf ("process new repo: %w" , err )
216+ }
217+
218+ if err := g .updateRepositoryMeta (repo ); err != nil {
219+ return fmt .Errorf ("failed to update repository meta: %w" , err )
220+ }
221+
222+ return nil
223+ }
224+
166225func (g * GitService ) CreateRepo (name , description string , id int , owner common.Address ) error {
167- repo , err := models .NewRepo (name , description , g .baseGitPath , id , owner , g .fs )
226+ repo , err := models .NewRepo (name , description , g .baseGitPath , "" , id , owner , g .fs )
168227 if err != nil {
169228 return fmt .Errorf ("failed to create new repo: %w" , err )
170229 }
171230
231+ if err := g .processNewRepo (repo ); err != nil {
232+ return fmt .Errorf ("process new repo: %w" , err )
233+ }
234+
235+ return nil
236+ }
237+
238+ func (g * GitService ) processNewRepo (repo * models.Repo ) error {
172239 meta , err := repo .GenMeta ()
173240 if err != nil {
174241 return fmt .Errorf ("failed to generate repository meta: %w" , err )
@@ -179,12 +246,12 @@ func (g *GitService) CreateRepo(name, description string, id int, owner common.A
179246 return fmt .Errorf ("marshal repository metadata: %w" , err )
180247 }
181248
182- hash , err := g .pinner .Pin (name + "-meta.json" , bytes .NewReader (metaJson ))
249+ hash , err := g .pinner .Pin (repo . Name + "-meta.json" , bytes .NewReader (metaJson ))
183250 if err != nil {
184251 return fmt .Errorf ("pin repository metadata to ipfs: %w" , err )
185252 }
186253
187- logger .Log ().Infof ("repository %s metadata %s pinned to IPFS" , name , hash )
254+ logger .Log ().Infof ("repository %s metadata %s pinned to IPFS" , repo . Name , hash )
188255
189256 repo .Metadata = hash
190257
@@ -204,13 +271,7 @@ func (g *GitService) CreateRepo(name, description string, id int, owner common.A
204271 return fmt .Errorf ("failed to send transaction: %w" , err )
205272 }
206273
207- logger .Log ().Infof ("transaction %s to update repository %s ID %d metadata %s send to blockchan" , tx .Hash ().Hex (), name , repo .ID , hash )
208-
209- rewrewr := & models.Repo {Name : name }
210-
211- if err := g .repository .GetRepo (rewrewr ); err != nil {
212- return err
213- }
274+ logger .Log ().Infof ("transaction %s to update repository %s ID %d metadata %s send to blockchan" , tx .Hash ().Hex (), repo .Name , repo .ID , hash )
214275
215276 return nil
216277}
@@ -291,60 +352,68 @@ func (g *GitService) ReceivePack(ctx context.Context, req io.Reader, repositoryN
291352
292353 logger .Log ().Infof ("recieve pack handled in %s" , time .Since (start ))
293354
355+ if err := g .updateRepositoryMeta (repo ); err != nil {
356+ return nil , fmt .Errorf ("failed to update repository meta: %w" , err )
357+ }
358+
359+ return res , nil
360+ }
361+
362+ func (g * GitService ) updateRepositoryMeta (repo * models.Repo ) error {
294363 head , err := repo .Head ()
295364 if err != nil {
296- return nil , fmt .Errorf ("failed to get repo head: %w" , err )
365+ return fmt .Errorf ("failed to get repo head: %w" , err )
297366 }
298367
299368 tree , err := repo .Tree (head .Hash ())
300369 if err != nil {
301- return nil , fmt .Errorf ("failed to get repo tree: %w" , err )
370+ return fmt .Errorf ("failed to get repo tree: %w" , err )
302371 }
303372
304373 meta , err := repo .GenMeta ()
305374 if err != nil {
306- return nil , fmt .Errorf ("failed to generate repository meta: %w" , err )
375+ return fmt .Errorf ("failed to generate repository meta: %w" , err )
307376 }
308377
309378 if err := meta .FillContent (tree ); err != nil {
310- return nil , fmt .Errorf ("failed to fill metadata content: %w" , err )
379+ return fmt .Errorf ("failed to fill metadata content: %w" , err )
311380 }
312381
313382 if err := meta .FillCommit (repo ); err != nil {
314- return nil , fmt .Errorf ("failed to fill metadata tree commits: %w" , err )
383+ return fmt .Errorf ("failed to fill metadata tree commits: %w" , err )
315384 }
316385
317386 if err := g .StoreMetaTree (meta , repo ); err != nil {
318- return nil , fmt .Errorf ("failed to store metadata content: %w" , err )
387+ return fmt .Errorf ("failed to store metadata content: %w" , err )
319388 }
320389
321390 metaBytes , err := json .Marshal (meta )
322391 if err != nil {
323- return nil , fmt .Errorf ("marshal repository metadata: %w" , err )
392+ return fmt .Errorf ("marshal repository metadata: %w" , err )
324393 }
325394
326- hash , err := g .pinner .Pin (fmt .Sprintf ("%s-%d-meta.json" , repositoryName , time .Now ().Unix ()), bytes .NewReader (metaBytes ))
395+ hash , err := g .pinner .Pin (fmt .Sprintf ("%s-%d-meta.json" , repo . Name , time .Now ().Unix ()), bytes .NewReader (metaBytes ))
327396 if err != nil {
328- return nil , fmt .Errorf ("pin repository metadata to ipfs: %w" , err )
397+ return fmt .Errorf ("pin repository metadata to ipfs: %w" , err )
329398 }
330399
331- logger .Log ().Infof ("repository %s metadata %s pinned to IPFS" , repositoryName , hash )
400+ logger .Log ().Infof ("repository %s metadata %s pinned to IPFS" , repo . Name , hash )
332401
333402 repo .Metadata = hash
334403
335404 sign , err := g .signer .Sign (g .chainId )
336405 if err != nil {
337- return nil , fmt .Errorf ("prepare tx signing: %w" , err )
406+ return fmt .Errorf ("prepare tx signing: %w" , err )
338407 }
339408
340409 tx , err := g .contract .UpdateIPFS (sign , big .NewInt (int64 (repo .ID )), hash )
341410 if err != nil {
342- return nil , fmt .Errorf ("failed to send transaction: %w" , err )
411+ return fmt .Errorf ("failed to send transaction: %w" , err )
343412 }
344413
345- logger .Log ().Infof ("transaction %s to update repository %s ID %d metadata %s send to blockchan" , tx .Hash ().Hex (), repositoryName , repo .ID , hash )
414+ logger .Log ().Infof ("transaction %s to update repository %s ID %d metadata %s send to blockchan" , tx .Hash ().Hex (), repo . Name , repo .ID , hash )
346415
347- return res , nil
416+ return nil
348417}
349418
350419func (g * GitService ) StoreMetaTree (meta * models.RepoMetadata , repo * models.Repo ) error {
0 commit comments