135 lines
4.9 KiB
Markdown
135 lines
4.9 KiB
Markdown
---
|
|
title: "Extension of P2PRC to create your own modification"
|
|
summary: P2PRC as a abstraction
|
|
date: 2021-08-31
|
|
aliases: ["/P2PRC-Extending"]
|
|
tags: ["P2PRC","AST","Extend"]
|
|
author: "Akilan Selvacoumar"
|
|
draft: false
|
|
aliases: [/P2PRC-Extending]
|
|
weight: 2
|
|
---
|
|
|
|
# Generate Module
|
|
P2PRC is a great layer of abstraction. This means that in many cases it is not an end product but rather
|
|
a tool that customized as an end product. An example would be writing your own billing module to monetize
|
|
the computation power available. The generate module copies the current with the appropriate git histories
|
|
and keeps only the go files which would be useful to edit. To use the generate module the user will need
|
|
to have a go compiler present in his computer. Due to the introduction of this module there will 2 releases:
|
|
|
|
- Regular Release (Consists of only the build binary and cli command cannot access the generate module)
|
|
- Developer Release (Consists of important Go files and the cli can access the generate module)
|
|
|
|
## How does this work ?
|
|
|
|
### [Struct information](https://github.com/Akilan1999/p2p-rendering-computation/blob/9d69aed8ce0fe5273aaff2828f7d51c3d5ac2ce4/generate/generate.go#L19)
|
|
- ###```Generate.go```:
|
|
This file creates a local copy of P2PRC from where the CLI was called from.
|
|
This go file also does various stuff like instruction of file should be ignored when copying and
|
|
which of should not be. Now let's understand this. Below is a sample code which does the following:
|
|
|
|
```go
|
|
//----------------------------------------------------------------
|
|
// Action performed:
|
|
// - Ensuring main.go file exists
|
|
// - Skipping all .go files apart from the ones listed above
|
|
// - Skipping .idea/ directory
|
|
// - Skipping Makefile file
|
|
//----------------------------------------------------------------
|
|
Options.Skip = func(src string) (bool, error) {
|
|
switch {
|
|
case strings.HasSuffix(src, "main.go"):
|
|
return false, nil
|
|
case strings.HasSuffix(src, ".go"):
|
|
return true, nil
|
|
case strings.HasSuffix(src, ".idea"):
|
|
return true, nil
|
|
case strings.HasSuffix(src, "Makefile"):
|
|
return true, nil
|
|
default:
|
|
return false, nil
|
|
}
|
|
}
|
|
|
|
// Doing the copy
|
|
err = copy.Copy("<P2PRC folder you want to copy from>", "<PATH to the directory>", Options)
|
|
```
|
|
|
|
Unfortunately currently this will have to be manually edited in the ```Generate.go``` file. When using the generate
|
|
module the user also creates their own Go module which is the modified version of P2PRC. This means
|
|
if the 1 modified package is using another modified package then the appropriate import have to be modified
|
|
in the file where the import is called:
|
|
|
|
Ex:
|
|
```go
|
|
//Sample Project module name = Test
|
|
//Package names:
|
|
//- Test/Genius
|
|
//- Test/GeGeGenuis
|
|
//
|
|
// When we call the generate function with the new project with the module name = MicDrop
|
|
// The new package name would be:
|
|
// - MicDrop/Genius
|
|
// - MicDrop/GeGeGenuis
|
|
|
|
// Test/Genius code depends on the package Test/GeGeGenuis
|
|
import (
|
|
"Test/GeGeGenuis"
|
|
)
|
|
|
|
// When we create a new module with the copy of the
|
|
// existing project we need change:
|
|
import (
|
|
"MicDrop/GeGeGenuis"
|
|
)
|
|
```
|
|
|
|
To do this we have built functions which can modify import names in the Go file provided.
|
|
To customize the use case of your generate module you would need to manually add your own
|
|
imports which are supposed to be replaced and in which files they are supposed to be replaced
|
|
in.
|
|
|
|
```go
|
|
// 1.0 - Test/Genius.go -> GeGeGenuis module
|
|
// a is struct of type NewProject
|
|
a.FileNameAST = "<path to project to copy from>/Test/Genius.go"
|
|
// Get AST information of the file
|
|
err := a.GetASTGoFile()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// Change the appropriate Go file
|
|
err = a.ChangeImports("Test/GeGeGenuis", "MicDrop/GeGeGenuis")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// Writes the change to the appropriate file
|
|
err = a.WriteGoAst()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
```
|
|
|
|
Higher order of execution of ```Generate.go```:
|
|
1. Copy entire P2PRC project and ignores files which are not meant to be copied
|
|
2. The folder name will be based on the new project name and the module name based on the new
|
|
module name provided.
|
|
3. Modifies the appropriate imports in the project as instructed in the code.
|
|
4. Creates a commit with the new changes in the new project.
|
|
|
|
|
|
- ### ``` modifyGenerate.go```:
|
|
This a really simple implementation where we replace the imports
|
|
in certain files as instructed from ```generate.go```. To do we create an AST (i.e Abstract Syntax tree)
|
|
from new file we want to change the imports in. AST create a tree structure of expression. To change the
|
|
import we can just traverse to the appropriate expression and change the value of that expression in
|
|
the case of modifying imports. This approach is more simple than using templates.
|
|
|
|
|
|
|
|
## Cli command
|
|
```
|
|
p2prc --gen <project name> --mod <go module name>
|
|
```
|
|
|
|
#### based on PR: https://github.com/Akilan1999/p2p-rendering-computation/pull/69 |