需求
由于开发的应用体积较大,在公司内部分发同事下载不方便,写了个简单的包管理工具。
架构逻辑
- 使用go搭建一个支持下载的服务。
- 将构建好的包上传到和部署服务的同一个路径下。
- 将上传apk的逻辑包在脚本文件中。
- 在网页端访问指定的页面,该页面展示目录中所有的包文件。
服务端开发
- 扫描当前目录中文件以.apk的文件。
- 使用交叉编译为linux的执行文件。
注意
列表现实中我对文件名根据我构建的包名做了处理。
// 使用交叉编译到对应的平台应用
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build ApkManager.go
package main
import (
"fmt"
"io/ioutil"
"math/rand"
"net/http"
"os"
"strings"
"time"
)
const TIME_FORMAT = "2006-01-02 15:04:05"
func FormatTime() string {
t := time.Now().Format(TIME_FORMAT)
return t
}
func main() {
http.HandleFunc("/download", Download)
http.HandleFunc("/", fileList)
http.ListenAndServe(":8090", nil)
}
func Download(w http.ResponseWriter, r *http.Request) {
if "GET" == r.Method {
apkName := r.URL.Query().Get("apkName")
fmt.Println("apkName=", apkName)
isApk := strings.Contains(apkName, ".apk")
if isApk {
file, err := os.Open("./" + apkName)
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
buf, err := ioutil.ReadAll(file)
if err != nil {
w.Write([]byte("文件不存在:" + err.Error()))
return
}
w.Header().Add("Content-Type", "application/octet-stream")
w.Header().Add("Content-Disposition", "attachment; filename=\""+apkName+"\"")
w.Write(buf)
} else {
file, err := os.Open("./" + apkName)
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
buf, err := ioutil.ReadAll(file)
if err != nil {
w.Write([]byte("文件不存在:" + err.Error()))
return
}
w.Header().Add("Content-Type", "application/octet-stream")
w.Header().Add("Content-Disposition", "attachment; filename=\""+apkName+"\"")
w.Write(buf)
}
}
}
func fileList(w http.ResponseWriter, r *http.Request) {
imgUrl := "https://picsum.photos/720/1080/?" + string(rune(rand.Int()))
files, _ := ioutil.ReadDir("./")
html := "<html style='background:url(" + imgUrl + ") no-repeat;background-size:cover'><head>" +
"<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" />" +
"<title>android 端apk全部版本</title></head><body style=\"text-align:center;\">"
baseUrl := "http://192.168.1.192:8090/download?apkName="
for i := len(files) - 1; i >= 0; i-- {
fmt.Println(files[i].Name())
isApk := strings.Contains(files[i].Name(), ".apk")
if isApk {
isRelease := strings.Contains(files[i].Name(), "final")
if isRelease {
arr := strings.Split(files[i].Name(), ".")
if len(arr) > 4 {
html += "<a href=" + baseUrl + files[i].Name() + "><font color=\"red\">" + "正式发布版本 版本号:" + arr[4] + "</font></a></br>"
} else {
html += "<a href=" + baseUrl + files[i].Name() + ">" + "测试版本 " + "</a></br>"
}
} else {
arr := strings.Split(files[i].Name(), ".")
if len(arr) > 4 {
html += "<a href=" + baseUrl + files[i].Name() + ">" + "测试版本 版本号:" + arr[4] + "</a></br>"
} else {
html += "<a href=" + baseUrl + files[i].Name() + ">" + "测试版本 " + "</a></br>"
}
}
html += "</br>"
}
}
html += "</body></html>"
_, err := w.Write([]byte(html))
if err != nil {
return
}
}
APK上传脚本
// 文件名 uploadAPK.sh
#!/bin/bash
scp cp ./app/release/*.apk root@192.168.1.192:/home/apk/apkManager