"兄弟"

李奔腾: “我现在都自身难保,跟我一起创业的老兄弟不会放过我的”

李奔腾: “我有可能…”

李奔腾: “要被迫放弃麒麟”

李奔腾: “不过也挺好的,一无所有也是一个新的开始

罗 维: “所以…对于你来说,到底是生意更重要,还是兄弟更重要?”

李奔腾: “ 不做一个梦,就不算兄弟

李奔腾: “生意,一点都不重要”

……

git-sync同步所有git库

同步指定目录中所有git库的一个简单shell脚本。

$ git sync -maxdepth 3
> Found 89 repositories.

> Synching gin 1% (1/89)
Already up to date.
> Synching gin finish.

> Synching yj 2% (2/89)
Already up to date.
> Synching yj finish.

> Synching go-cmp 3% (3/89)
Already up to date.
> Synching go-cmp finish.

> Synching opentelemetry-go-contrib 4% (4/89)
remote: Enumerating objects: 775, done.
remote: Counting objects: 100% (363/363), done.
remote: Compressing objects: 100% (117/117), done.
remote: Total 775 (delta 264), reused 307 (delta 240), pack-reused 412 (from 3)
Receiving objects: 100% (775/775), 351.23 KiB | 636.00 KiB/s, done.
Resolving deltas: 100% (448/448), completed with 79 local objects.

TL在Go如何实现oneof语义

TL的Type是一个总类型Class包含不同的结构子类型实例Object,类似于Protubuf中MessageOneof的关系。

Telegram的RPC TL片段1:

peerUser#9db1bc6d user_id:int = Peer;
peerChat#bad0e5bb chat_id:int = Peer;
peerChannel#bddde532 channel_id:int = Peer;

folderPeer#e9baa668 peer:Peer folder_id:int = FolderPeer;

在go库包中包含main包的方式

// file: golang.org/x/tools/go/cfg/cfg.go
package cfg

import (
	"bytes"
	"fmt"
	"go/ast"
	"go/format"
	"go/token"
)

// A CFG represents the control-flow graph of a single function.
//
// The entry point is Blocks[0]; there may be multiple return blocks.
type CFG struct {
	Blocks []*Block // block[0] is entry; order otherwise undefined
	noreturn bool // function body lacks a reachable return statement
}
// ...

使用Test来生成代码

一般我们会起一个main函数的go主文件来写逻辑用于生成代码,但有的时候不太方便在一个包里面有main函数,而生成代码的逻辑又是必须的且最好是就在同一个包内或临近包中,此时,可以利用Test的编译机制,将我们需要的代码生成逻辑写在TestAbc函数中。

辅助脚本

// file: github.com/cloudwego/frugal/internal/reflect/append_gen.sh
#!/bin/bash

FRUGAL_GEN_APPEND_MAP_FILE="append_map_gen.go"
FRUGAL_GEN_APPEND_LIST_FILE="append_list_gen.go"

rm -f $FRUGAL_GEN_APPEND_MAP_FILE
rm -f $FRUGAL_GEN_APPEND_LIST_FILE

exec go test -v -run=TestGenAppend -gencode=true

Kitex: Thrift-HTTP 映射的 IDL 规范

本规范是 ThriftHTTP 接口映射的 IDL 定义标准,包括服务、接口以及请求 requestresponse 参数定义规范和错误码定义规范。Kitex 部分实现了该规范,注解说明有标注支持情况。

规范说明

(1)本规范采用注解方式来描述接口信息,包括接口的 method, path 以及接口请求参数,返回参数位置(如 headercookie )、名称等信息

(2)本规范所述注解采用 api.{key}={value} 的形式,其中key通常用于指定该字段出现的位置如(headercookiequerybody 等), value 用于指定该字段在对应位置的实际名称, 一些功能性注解(如api.none, api.js_conv, api.http_code) 除外

(3)本规范中定义的IDL注解如 api.get, api.header 等,只支持小写,不支持大写或者大小写混用如api.GET, api.Header

文件整体规范

  • 一个服务 service 对应一个 thrift 主文件,主文件里的 method 都是针对当前服务对应接口,主文件可以引用其它 thrift 文件定义
  • 每个 Method 原则上对应一个 RequestResponse 定义
  • 原则上不建议 Request 复用,可以复用 Response

Add commits to another person's PR on Github repo

TLDR;

git push git@github.com:remoteUser/remoteRepo localBranch:remoteBranch

Explanation

The normal git push command usually looks like this:

git push origin branch

Pushing to another developer’s branch follows a similar pattern: origin is the other person’s repo, and branch maps your local branch to the same branch on their remote repo.

origin = git@github.com:remoteUser/remoteRepo

branch = localBranch:remoteBranch

Breaking down each variable:

remoteUser refers to the username of the developer who made the pr on your repo

remoteRepo refers to the name of the repo that the other developer is creating the PR from, usually, this is the same name as your repo.

localBranch refers to the branch name of your local copy of their remote branch

remoteBranch refers to the branch name of that their PR is originating from on their remoteRepo

Keep in mind, that you can only push to PRs from other developers on your repo if that developer selected “Allow edits from maintainers” when they created their PR.

Yesql - Sqlx的好搭挡

Yesql 解析一个SQL文件,提取出查询语句,自动生成对应的Go结构体,实现查询语句与代码分离,方便编写数据库查询逻辑。

安装

go get github.com/alimy/yesql

使用 GoDoc

创建sql文件

-- sql file yesql.sql

-- name: newest_tags@topic
-- get newest tag information
SELECT t.id id, t.user_id user_id, t.tag tag, t.quote_num quote_num, u.id, u.nickname, u.username, u.status, u.avatar, u.is_admin 
FROM @tag t JOIN @user u ON t.user_id = u.id 
WHERE t.is_del = 0 AND t.quote_num > 0 
ORDER BY t.id DESC 
LIMIT ? OFFSET ?;

-- name: hot_tags@topic
-- get get host tag information
SELECT t.id id, t.user_id user_id, t.tag tag, t.quote_num quote_num, u.id, u.nickname, u.username, u.status, u.avatar, u.is_admin 
FROM @tag t JOIN @user u ON t.user_id = u.id 
WHERE t.is_del = 0 AND t.quote_num > 0 
ORDER BY t.quote_num DESC 
LIMIT ? OFFSET ?;

-- name: tags_by_keyword_a@topic
-- get tags by keyword
SELECT id, user_id, tag, quote_num FROM @tag WHERE is_del = 0 ORDER BY quote_num DESC LIMIT 6;

-- name: tags_by_keyword_b@topic
SELECT id, user_id, tag, quote_num FROM @tag WHERE is_del = 0 AND tag LIKE ? ORDER BY quote_num DESC LIMIT 6;

-- name: insert_tag@topic
INSERT INTO @tag (user_id, tag, created_on, modified_on, quote_num) VALUES (?, ?, ?, ?, 1);

-- name: tags_by_id_a@topic
-- clause: in
SELECT id FROM @tag WHERE id IN (?) AND is_del = 0 AND quote_num > 0;

-- name: tags_by_id_b@topic
-- clause: in
SELECT id, user_id, tag, quote_num FROM @tag WHERE id IN (?);

-- name: decr_tags_by_id@topic
-- clause: in
UPDATE @tag SET quote_num=quote_num-1, modified_on=? WHERE id IN (?);

-- name: tags_for_incr@topic
-- clause: in
SELECT id, user_id, tag, quote_num FROM @tag WHERE tag IN (?);

-- name: incr_tags_by_id@topic
-- clause: in
UPDATE @tag SET quote_num=quote_num+1, is_del=0, modified_on=? WHERE id IN (?);