这篇文章介绍怎么修改主题,以及完善官方代码中不支持更新远程主题的实现。

发现问题

官方的代码中,首次添加远程主题仓库时可以成功,但是如果远程仓库主题文件更新了,想在后台更新同步却不支持(not supported),先删除重新下载也不行(already exists)。
theme_update

修改代码

通过查看源码,发现更新主题的方法(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仓库和一件部署脚本

上面代码修改并在本地调试完成后,还需要部署到服务器上,不过现在服务器上面使用的是官方镜像,所以我们需要用自己的代码,所以需要重新自己打包镜像,下篇再说。