这篇文章介绍怎么修改主题,以及完善官方代码中不支持更新远程主题的实现。
发现问题
官方的代码中,首次添加远程主题仓库时可以成功,但是如果远程仓库主题文件更新了,想在后台更新同步却不支持(not supported),先删除重新下载也不行(already exists)。
修改代码
通过查看源码,发现更新主题的方法(handler/admin/theme.go)未实现,应该是觉得用户可能通过外观-》主题编辑修改文件,直接更新覆盖会存在不好吧。
func (t *ThemeHandler) UpdateThemeByFetching(ctx *gin.Context) (interface{}, error) {
return nil, xerr.WithMsg(nil, "not support").WithStatus(xerr.StatusInternalServerError)
}
因为我的需求是需要远程主题文件覆盖本地以应用最新效果,所以增加了更新主题的方法,先fork一份代码到自己仓库,这里建议使用gitee或者其他国内仓库,不然国内访问github可能会失败。
修改sonic/service/impl/theme.go文件,然后在handler/admin/theme.go调用一下。
func (t *themeServiceImpl) UpdateThemeByFetching(ctx *gin.Context, id string) (interface{}, error) {
theme, err := t.GetThemeByID(ctx, id)
if err != nil {
return nil, err
}
fetchTheme, err := t.ThemeFetchers.GitRepoThemeFetcher.FetchTheme(ctx, theme.Repo)
if err != nil {
return nil, xerr.WithStatus(err, xerr.StatusBadRequest).WithMsg(err.Error())
}
return t.updateThem(ctx, fetchTheme)
}
func (t *themeServiceImpl) updateThem(ctx context.Context, themeProperty *dto.ThemeProperty) (*dto.ThemeProperty, error) {
err := util.CopyDir(themeProperty.ThemePath, filepath.Join(t.Config.Sonic.ThemeDir, themeProperty.FolderName))
if err != nil {
return nil, xerr.WithStatus(err, xerr.StatusBadRequest)
}
return t.PropertyScanner.ReadThemeProperty(ctx, filepath.Join(t.Config.Sonic.ThemeDir, themeProperty.FolderName))
}
以及修改克隆git文件的方法(service/theme/git_fetcher.go),原方法如果已经克隆过了,再次克隆会报错 ,所以先删除原有的文件
func (g gitThemeFetcherImpl) FetchTheme(ctx context.Context, file interface{}) (*dto.ThemeProperty, error) {
gitURL := file.(string)
splits := strings.Split(gitURL, "/")
lastSplit := splits[len(splits)-1]
tempDir := os.TempDir()
themeDirName := lastSplit
path := filepath.Join(tempDir, themeDirName)
//if file path exist, delete it
if _, err := os.Stat(path); err == nil {
err = os.RemoveAll(path)
if err != nil {
return nil, xerr.WithStatus(err, xerr.StatusBadRequest).WithMsg(err.Error())
}
}
_, err := git.PlainClone(path, false, &git.CloneOptions{
URL: gitURL,
})
if err != nil {
return nil, xerr.WithStatus(err, xerr.StatusBadRequest).WithMsg(err.Error())
}
themeProperty, err := g.PropertyScanner.ReadThemeProperty(ctx, path)
if err != nil {
return nil, err
}
// delete themeProperty.FolderName .git stuff
themeProperty.FolderName = strings.TrimSuffix(themeProperty.FolderName, ".git")
return themeProperty, nil
}
设置gitee仓库和一件部署脚本
上面代码修改并在本地调试完成后,还需要部署到服务器上,不过现在服务器上面使用的是官方镜像,所以我们需要用自己的代码,所以需要重新自己打包镜像,下篇再说。