Skip to content

Commit 1338777

Browse files
authored
Merge pull request #9 from gitopia/dev
git-remote-gitopia v0.3.0
2 parents d73f643 + 966c759 commit 1338777

File tree

5 files changed

+219
-148
lines changed

5 files changed

+219
-148
lines changed

cmd/git-remote-gitopia/gitopia.go

Lines changed: 98 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,16 @@
11
package main
22

33
import (
4-
"bytes"
54
"context"
65
"encoding/json"
76
"fmt"
8-
"net/http"
97
"os"
8+
"strconv"
109
"strings"
1110

12-
clientTx "github.com/cosmos/cosmos-sdk/client/tx"
13-
"github.com/cosmos/cosmos-sdk/codec"
14-
"github.com/cosmos/cosmos-sdk/codec/types"
11+
"github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
1512
"github.com/cosmos/cosmos-sdk/crypto/hd"
16-
cosmoscryptoed "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
17-
cosmoscryptosecp "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
18-
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
1913
sdk "github.com/cosmos/cosmos-sdk/types"
20-
"github.com/cosmos/cosmos-sdk/types/tx"
21-
"github.com/cosmos/cosmos-sdk/types/tx/signing"
22-
xauthsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
23-
authTx "github.com/cosmos/cosmos-sdk/x/auth/tx"
24-
authType "github.com/cosmos/cosmos-sdk/x/auth/types"
2514
core "github.com/gitopia/git-remote-gitopia/core"
2615
gitopiaTypes "github.com/gitopia/gitopia/x/gitopia/types"
2716
"github.com/gitopia/gitopia/x/gitopia/utils"
@@ -34,11 +23,10 @@ import (
3423
)
3524

3625
const (
37-
chainID = "internal-4"
3826
AccountAddressPrefix = "gitopia"
39-
apiURL = "34.87.90.147:9090"
40-
objectsURL = "http://34.126.69.254:5000"
41-
saveToArweaveURL = "http://34.126.69.254:5000/save"
27+
apiURL = "34.126.183.252:9090"
28+
objectsURL = "http://34.87.64.22:5000"
29+
saveToArweaveURL = "http://34.87.64.22:5000/save"
4230
branchPrefix = "refs/heads/"
4331
tagPrefix = "refs/tags/"
4432
)
@@ -70,10 +58,10 @@ type SaveToArweavePostBody struct {
7058
}
7159

7260
type GitopiaHandler struct {
73-
queryClient gitopiaTypes.QueryClient
74-
accountQueryClient authType.QueryClient
75-
txClient tx.ServiceClient
61+
grpcConn *grpc.ClientConn
62+
queryClient gitopiaTypes.QueryClient
7663

64+
chainId string
7765
remoteUserId string
7866
remoteRepositoryName string
7967
remoteRepository gitopiaTypes.Repository
@@ -82,29 +70,41 @@ type GitopiaHandler struct {
8270
}
8371

8472
func (h *GitopiaHandler) Initialize(remote *core.Remote) error {
85-
grpcConn, err := grpc.Dial(apiURL,
73+
var err error
74+
75+
h.grpcConn, err = grpc.Dial(apiURL,
8676
grpc.WithInsecure(),
8777
)
8878
if err != nil {
8979
return err
9080
}
9181
// defer grpcConn.Close()
9282

93-
h.queryClient = gitopiaTypes.NewQueryClient(grpcConn)
94-
h.accountQueryClient = authType.NewQueryClient(grpcConn)
95-
h.txClient = tx.NewServiceClient(grpcConn)
83+
h.queryClient = gitopiaTypes.NewQueryClient(h.grpcConn)
84+
serviceClient := tmservice.NewServiceClient(h.grpcConn)
85+
86+
// Get chain id for signing transaction
87+
nodeInfoRes, err := serviceClient.GetNodeInfo(context.Background(), &tmservice.GetNodeInfoRequest{})
88+
if err != nil {
89+
return err
90+
}
91+
h.chainId = nodeInfoRes.DefaultNodeInfo.Network
9692

9793
// Get RepositoryId
9894
res, err := h.queryClient.AddressRepository(context.Background(), &gitopiaTypes.QueryGetAddressRepositoryRequest{
9995
Id: h.remoteUserId,
10096
RepositoryName: h.remoteRepositoryName,
10197
})
10298
if err != nil {
103-
return fmt.Errorf("fatal: repository 'gitopia://%s/%s' not found. Please create it from the gitopia webapp", h.remoteUserId, h.remoteRepositoryName)
99+
return err
104100
}
105101

106102
h.remoteRepository = *res.Repository
107103

104+
config := sdk.GetConfig()
105+
config.SetBech32PrefixForAccount(AccountAddressPrefix, AccountPubKeyPrefix)
106+
config.Seal()
107+
108108
return nil
109109
}
110110

@@ -164,18 +164,8 @@ func (h *GitopiaHandler) Fetch(remote *core.Remote, sha, ref string) error {
164164

165165
func (h *GitopiaHandler) Push(remote *core.Remote, local string, remoteRef string) (string, error) {
166166
h.didPush = true
167-
remoteURL := fmt.Sprintf("%v/%v.git", objectsURL, h.remoteRepository.Id)
168-
remoteConfig := &goGitConfig.RemoteConfig{
169-
Name: "gitopia-objects-store",
170-
URLs: []string{remoteURL},
171-
}
172-
173-
_, err := remote.Repo.CreateRemote(remoteConfig)
174-
if err != nil {
175-
return "", err
176-
}
177-
defer remote.Repo.DeleteRemote("gitopia-objects-store")
178167

168+
// Read wallet file
179169
gitopiaWalletPath := os.Getenv("GITOPIA_WALLET")
180170
if gitopiaWalletPath == "" {
181171
return "", fmt.Errorf("fatal: GITOPIA_WALLET environment variable is not set")
@@ -192,17 +182,14 @@ func (h *GitopiaHandler) Push(remote *core.Remote, local string, remoteRef strin
192182
return "", fmt.Errorf("fatal: error decoding wallet file")
193183
}
194184

195-
derivedPriv, err := hd.Secp256k1.Derive()(gitopiaWallet.Mnemonic, "", gitopiaWallet.HDpath)
185+
// Generate private key
186+
hdPath := gitopiaWallet.HDpath + strconv.Itoa(gitopiaWallet.PathIncrement)
187+
derivedPriv, err := hd.Secp256k1.Derive()(gitopiaWallet.Mnemonic, "", hdPath)
196188
if err != nil {
197189
return "", err
198190
}
199191

200192
privKey := hd.Secp256k1.Generate()(derivedPriv)
201-
202-
config := sdk.GetConfig()
203-
config.SetBech32PrefixForAccount(AccountAddressPrefix, AccountPubKeyPrefix)
204-
config.Seal()
205-
206193
walletAddress := sdk.AccAddress(privKey.PubKey().Address())
207194

208195
havePushPermission, err := h.havePushPermission(walletAddress.String())
@@ -213,36 +200,65 @@ func (h *GitopiaHandler) Push(remote *core.Remote, local string, remoteRef strin
213200
return "", fmt.Errorf("fatal: you don't have write permissions to this repository")
214201
}
215202

203+
var msg sdk.Msg
204+
205+
// Delete branch/tag
206+
if local == "" {
207+
if strings.HasPrefix(remoteRef, branchPrefix) {
208+
remoteBranchName := strings.TrimPrefix(remoteRef, branchPrefix)
209+
210+
// Check if it's the default branch
211+
if remoteBranchName == h.remoteRepository.DefaultBranch {
212+
return "", fmt.Errorf("fatal: cannot delete default branch, %v", remoteBranchName)
213+
}
214+
215+
msg = gitopiaTypes.NewMsgDeleteBranch(walletAddress.String(), h.remoteRepository.Id, remoteBranchName)
216+
} else if strings.HasPrefix(remoteRef, tagPrefix) {
217+
remoteTagName := strings.TrimPrefix(remoteRef, tagPrefix)
218+
msg = gitopiaTypes.NewMsgDeleteTag(walletAddress.String(), h.remoteRepository.Id, remoteTagName)
219+
}
220+
221+
err := signAndBroadcastTx(h.grpcConn, walletAddress.String(), h.chainId, privKey, msg)
222+
if err != nil {
223+
return "", err
224+
}
225+
226+
return local, nil
227+
}
228+
229+
remoteURL := fmt.Sprintf("%v/%v.git", objectsURL, h.remoteRepository.Id)
230+
remoteConfig := &goGitConfig.RemoteConfig{
231+
Name: "gitopia-objects-store",
232+
URLs: []string{remoteURL},
233+
}
234+
235+
_, err = remote.Repo.CreateRemote(remoteConfig)
236+
if err != nil {
237+
return "", err
238+
}
239+
defer remote.Repo.DeleteRemote("gitopia-objects-store")
240+
241+
force := false
242+
if strings.HasPrefix(local, "+") {
243+
local = strings.TrimPrefix(local, "+")
244+
force = true
245+
}
246+
216247
pushOptions := &git.PushOptions{
217248
RemoteName: "gitopia-objects-store",
218249
RefSpecs: []goGitConfig.RefSpec{goGitConfig.RefSpec(fmt.Sprintf("%s:%s", local, remoteRef))},
219250
Progress: os.Stdout,
251+
Force: force,
220252
}
221253

222254
err = remote.Repo.Push(pushOptions)
223255
if err != nil && err != git.NoErrAlreadyUpToDate {
224256
return "", fmt.Errorf("fatal: error pushing the git objects, %v", err.Error())
225257
}
226258

227-
// Update ref on gitopia
228-
interfaceRegistry := types.NewInterfaceRegistry()
229-
interfaceRegistry.RegisterInterface(
230-
"cosmos.auth.v1beta1.AccountI",
231-
(*authType.AccountI)(nil),
232-
&authType.BaseAccount{},
233-
&authType.ModuleAccount{},
234-
)
235-
interfaceRegistry.RegisterInterface("cosmos.crypto.PubKey", (*cryptotypes.PubKey)(nil))
236-
interfaceRegistry.RegisterImplementations((*cryptotypes.PubKey)(nil), &cosmoscryptosecp.PubKey{})
237-
interfaceRegistry.RegisterImplementations((*cryptotypes.PubKey)(nil), &cosmoscryptoed.PubKey{})
238-
marshaler := codec.NewProtoCodec(interfaceRegistry)
239-
txCfg := authTx.NewTxConfig(marshaler, authTx.DefaultSignModes)
240-
241-
txBuilder := txCfg.NewTxBuilder()
242-
243259
var newRemoteRefSha, prevRemoteRefSha string
244-
var msg sdk.Msg
245260

261+
// Update ref on gitopia
246262
if strings.HasPrefix(local, branchPrefix) {
247263
localCommitHash, err := remote.Repo.ResolveRevision(plumbing.Revision(local))
248264
if err != nil {
@@ -282,98 +298,35 @@ func (h *GitopiaHandler) Push(remote *core.Remote, local string, remoteRef strin
282298
return "", fmt.Errorf("fatal: not a valid branch/tag, %v", local)
283299
}
284300

285-
txBuilder.SetMsgs(msg)
286-
txBuilder.SetGasLimit(200000)
287-
288-
res, err := h.accountQueryClient.Account(context.Background(),
289-
&authType.QueryAccountRequest{
290-
Address: walletAddress.String(),
291-
},
292-
)
293-
var acc authType.AccountI
294-
if err := interfaceRegistry.UnpackAny(res.Account, &acc); err != nil {
295-
return "", err
296-
}
297-
298-
sigV2 := signing.SignatureV2{
299-
PubKey: privKey.PubKey(),
300-
Data: &signing.SingleSignatureData{
301-
SignMode: txCfg.SignModeHandler().DefaultMode(),
302-
Signature: nil,
303-
},
304-
Sequence: acc.GetSequence(),
305-
}
306-
err = txBuilder.SetSignatures(sigV2)
307-
if err != nil {
308-
return "", err
309-
}
310-
311-
signerData := xauthsigning.SignerData{
312-
ChainID: chainID,
313-
AccountNumber: acc.GetAccountNumber(),
314-
Sequence: acc.GetSequence(),
315-
}
316-
317-
sigV2, err = clientTx.SignWithPrivKey(txCfg.SignModeHandler().DefaultMode(), signerData,
318-
txBuilder, privKey, txCfg, acc.GetSequence())
319-
if err != nil {
320-
return "", err
321-
}
322-
323-
err = txBuilder.SetSignatures(sigV2)
301+
err = signAndBroadcastTx(h.grpcConn, walletAddress.String(), h.chainId, privKey, msg)
324302
if err != nil {
325303
return "", err
326304
}
327305

328-
err = txBuilder.GetTx().ValidateBasic()
329-
if err != nil {
330-
fmt.Fprintf(os.Stderr, "fatal: tx validation failed: %v", err.Error())
331-
}
332-
333-
var txBytes []byte
334-
txBytes, err = txCfg.TxEncoder()(txBuilder.GetTx())
335-
if err != nil {
336-
return "", err
337-
}
338-
339-
var grpcRes *tx.BroadcastTxResponse
340-
grpcRes, err = h.txClient.BroadcastTx(
341-
context.Background(),
342-
&tx.BroadcastTxRequest{
343-
Mode: tx.BroadcastMode_BROADCAST_MODE_SYNC,
344-
TxBytes: txBytes,
345-
},
346-
)
347-
if err != nil {
348-
return "", err
349-
}
350-
351-
if grpcRes.TxResponse.Code != 0 {
352-
return "", fmt.Errorf("fatal: failed to broadcast transaction, code: %v", grpcRes.TxResponse.Code)
353-
}
306+
_ = prevRemoteRefSha
354307

355308
// Queue task to upload objects to arweave
356-
saveToArweavePostBody := SaveToArweavePostBody{
357-
RepositoryID: h.remoteRepository.Id,
358-
RemoteRefName: remoteRef,
359-
NewRemoteRefSha: newRemoteRefSha,
360-
PrevRemoteRefSha: prevRemoteRefSha,
361-
}
362-
363-
postBody, err := json.Marshal(saveToArweavePostBody)
364-
if err != nil {
365-
return "", fmt.Errorf("fatal: failed to serialize post data: %v", err.Error())
366-
}
367-
responseBody := bytes.NewBuffer(postBody)
368-
resp, err := http.Post(saveToArweaveURL, "application/json", responseBody)
369-
if err != nil {
370-
return "", fmt.Errorf("fatal: error posting saveToArweave: %v", err.Error())
371-
}
372-
defer resp.Body.Close()
373-
374-
if resp.StatusCode != http.StatusOK {
375-
return "", fmt.Errorf("fatal: error saving to Arweave")
376-
}
309+
// saveToArweavePostBody := SaveToArweavePostBody{
310+
// RepositoryID: h.remoteRepository.Id,
311+
// RemoteRefName: remoteRef,
312+
// NewRemoteRefSha: newRemoteRefSha,
313+
// PrevRemoteRefSha: prevRemoteRefSha,
314+
// }
315+
316+
// postBody, err := json.Marshal(saveToArweavePostBody)
317+
// if err != nil {
318+
// return "", fmt.Errorf("fatal: failed to serialize post data: %v", err.Error())
319+
// }
320+
// responseBody := bytes.NewBuffer(postBody)
321+
// resp, err := http.Post(saveToArweaveURL, "application/json", responseBody)
322+
// if err != nil {
323+
// return "", fmt.Errorf("fatal: error posting saveToArweave: %v", err.Error())
324+
// }
325+
// defer resp.Body.Close()
326+
327+
// if resp.StatusCode != http.StatusOK {
328+
// return "", fmt.Errorf("fatal: error saving to Arweave")
329+
// }
377330

378331
return local, nil
379332
}

0 commit comments

Comments
 (0)