1ba991379Sopenharmony_ci/* 2ba991379Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3ba991379Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4ba991379Sopenharmony_ci * you may not use this file except in compliance with the License. 5ba991379Sopenharmony_ci * You may obtain a copy of the License at 6ba991379Sopenharmony_ci * 7ba991379Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8ba991379Sopenharmony_ci * 9ba991379Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10ba991379Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11ba991379Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12ba991379Sopenharmony_ci * See the License for the specific language governing permissions and 13ba991379Sopenharmony_ci * limitations under the License. 14ba991379Sopenharmony_ci */ 15ba991379Sopenharmony_ci 16ba991379Sopenharmony_cipackage gitee_common 17ba991379Sopenharmony_ci 18ba991379Sopenharmony_ciimport ( 19ba991379Sopenharmony_ci "code.cloudfoundry.org/archiver/extractor" 20ba991379Sopenharmony_ci "context" 21ba991379Sopenharmony_ci "fmt" 22ba991379Sopenharmony_ci "fotff/utils" 23ba991379Sopenharmony_ci "github.com/sirupsen/logrus" 24ba991379Sopenharmony_ci "os" 25ba991379Sopenharmony_ci "path/filepath" 26ba991379Sopenharmony_ci "strings" 27ba991379Sopenharmony_ci "time" 28ba991379Sopenharmony_ci) 29ba991379Sopenharmony_ci 30ba991379Sopenharmony_citype Manager struct { 31ba991379Sopenharmony_ci Component string 32ba991379Sopenharmony_ci Branch string 33ba991379Sopenharmony_ci ManifestBranch string 34ba991379Sopenharmony_ci ArchiveDir string 35ba991379Sopenharmony_ci Workspace string 36ba991379Sopenharmony_ci WatchCI bool 37ba991379Sopenharmony_ci} 38ba991379Sopenharmony_ci 39ba991379Sopenharmony_cifunc NewManager(component string, branch string, manifestBranch string, archiveDir string, workspace string, watchCI bool) *Manager { 40ba991379Sopenharmony_ci var ret = Manager{ 41ba991379Sopenharmony_ci Component: component, 42ba991379Sopenharmony_ci Branch: branch, 43ba991379Sopenharmony_ci ManifestBranch: manifestBranch, 44ba991379Sopenharmony_ci ArchiveDir: archiveDir, 45ba991379Sopenharmony_ci Workspace: workspace, 46ba991379Sopenharmony_ci WatchCI: watchCI, 47ba991379Sopenharmony_ci } 48ba991379Sopenharmony_ci go ret.cleanupOutdated() 49ba991379Sopenharmony_ci return &ret 50ba991379Sopenharmony_ci} 51ba991379Sopenharmony_ci 52ba991379Sopenharmony_cifunc (m *Manager) cleanupOutdated() { 53ba991379Sopenharmony_ci t := time.NewTicker(24 * time.Hour) 54ba991379Sopenharmony_ci for { 55ba991379Sopenharmony_ci <-t.C 56ba991379Sopenharmony_ci es, err := os.ReadDir(m.Workspace) 57ba991379Sopenharmony_ci if err != nil { 58ba991379Sopenharmony_ci logrus.Errorf("can not read %s: %v", m.Workspace, err) 59ba991379Sopenharmony_ci continue 60ba991379Sopenharmony_ci } 61ba991379Sopenharmony_ci for _, e := range es { 62ba991379Sopenharmony_ci if !e.IsDir() { 63ba991379Sopenharmony_ci continue 64ba991379Sopenharmony_ci } 65ba991379Sopenharmony_ci path := filepath.Join(m.Workspace, e.Name()) 66ba991379Sopenharmony_ci info, err := e.Info() 67ba991379Sopenharmony_ci if err != nil { 68ba991379Sopenharmony_ci logrus.Errorf("can not read %s info: %v", path, err) 69ba991379Sopenharmony_ci continue 70ba991379Sopenharmony_ci } 71ba991379Sopenharmony_ci if time.Now().Sub(info.ModTime()) > 7*24*time.Hour { 72ba991379Sopenharmony_ci logrus.Warnf("%s outdated, cleanning up its contents...", path) 73ba991379Sopenharmony_ci m.cleanupPkgFiles(path) 74ba991379Sopenharmony_ci } 75ba991379Sopenharmony_ci } 76ba991379Sopenharmony_ci } 77ba991379Sopenharmony_ci} 78ba991379Sopenharmony_ci 79ba991379Sopenharmony_cifunc (m *Manager) cleanupPkgFiles(path string) { 80ba991379Sopenharmony_ci es, err := os.ReadDir(path) 81ba991379Sopenharmony_ci if err != nil { 82ba991379Sopenharmony_ci logrus.Errorf("can not read %s: %v", path, err) 83ba991379Sopenharmony_ci return 84ba991379Sopenharmony_ci } 85ba991379Sopenharmony_ci for _, e := range es { 86ba991379Sopenharmony_ci if e.Name() == "manifest_tag.xml" || e.Name() == "__last_issue__" { 87ba991379Sopenharmony_ci continue 88ba991379Sopenharmony_ci } 89ba991379Sopenharmony_ci if err := os.RemoveAll(filepath.Join(path, e.Name())); err != nil { 90ba991379Sopenharmony_ci logrus.Errorf("remove %s fail: %v", filepath.Join(path, e.Name()), err) 91ba991379Sopenharmony_ci } 92ba991379Sopenharmony_ci } 93ba991379Sopenharmony_ci} 94ba991379Sopenharmony_ci 95ba991379Sopenharmony_ci// Flash function implements pkg.Manager. Flash images in the 'pkg' directory to the given device. 96ba991379Sopenharmony_cifunc (m *Manager) Flash(device string, pkg string, ctx context.Context) error { 97ba991379Sopenharmony_ci logrus.Warnf("not implemented yet") 98ba991379Sopenharmony_ci return nil 99ba991379Sopenharmony_ci} 100ba991379Sopenharmony_ci 101ba991379Sopenharmony_cifunc (m *Manager) Steps(from, to string) (pkgs []string, err error) { 102ba991379Sopenharmony_ci if from == to { 103ba991379Sopenharmony_ci return nil, fmt.Errorf("steps err: 'from' %s and 'to' %s are the same", from, to) 104ba991379Sopenharmony_ci } 105ba991379Sopenharmony_ci if c, found := utils.CacheGet(fmt.Sprintf("%s_steps", m.Component), from+"__to__"+to); found { 106ba991379Sopenharmony_ci logrus.Infof("steps from %s to %s are cached", from, to) 107ba991379Sopenharmony_ci logrus.Infof("steps: %v", c.([]string)) 108ba991379Sopenharmony_ci return c.([]string), nil 109ba991379Sopenharmony_ci } 110ba991379Sopenharmony_ci if pkgs, err = m.stepsFromGitee(from, to); err != nil { 111ba991379Sopenharmony_ci logrus.Errorf("failed to gen steps from gitee, err: %v", err) 112ba991379Sopenharmony_ci logrus.Warnf("fallback to getting steps from CI...") 113ba991379Sopenharmony_ci if pkgs, err = m.stepsFromCI(from, to); err != nil { 114ba991379Sopenharmony_ci return pkgs, err 115ba991379Sopenharmony_ci } 116ba991379Sopenharmony_ci return pkgs, nil 117ba991379Sopenharmony_ci } 118ba991379Sopenharmony_ci utils.CacheSet(fmt.Sprintf("%s_steps", m.Component), from+"__to__"+to, pkgs) 119ba991379Sopenharmony_ci return pkgs, nil 120ba991379Sopenharmony_ci} 121ba991379Sopenharmony_ci 122ba991379Sopenharmony_cifunc (m *Manager) LastIssue(pkg string) (string, error) { 123ba991379Sopenharmony_ci data, err := os.ReadFile(filepath.Join(m.Workspace, pkg, "__last_issue__")) 124ba991379Sopenharmony_ci return string(data), err 125ba991379Sopenharmony_ci} 126ba991379Sopenharmony_ci 127ba991379Sopenharmony_cifunc (m *Manager) GetNewer(cur string) (string, error) { 128ba991379Sopenharmony_ci var newFile string 129ba991379Sopenharmony_ci if m.WatchCI { 130ba991379Sopenharmony_ci newFile = m.getNewerFromCI(cur + ".tar.gz") 131ba991379Sopenharmony_ci } else { 132ba991379Sopenharmony_ci newFile = m.getNewerFileFromDir(cur+".tar.gz", func(files []os.DirEntry, i, j int) bool { 133ba991379Sopenharmony_ci ti, _ := parseTime(files[i].Name()) 134ba991379Sopenharmony_ci tj, _ := parseTime(files[j].Name()) 135ba991379Sopenharmony_ci return ti.Before(tj) 136ba991379Sopenharmony_ci }) 137ba991379Sopenharmony_ci } 138ba991379Sopenharmony_ci ex := extractor.NewTgz() 139ba991379Sopenharmony_ci dirName := strings.TrimSuffix(newFile, ".tar.gz") 140ba991379Sopenharmony_ci dir := filepath.Join(m.Workspace, dirName) 141ba991379Sopenharmony_ci if _, err := os.Stat(dir); err == nil { 142ba991379Sopenharmony_ci return dirName, nil 143ba991379Sopenharmony_ci } 144ba991379Sopenharmony_ci logrus.Infof("extracting %s to %s...", filepath.Join(m.ArchiveDir, newFile), dir) 145ba991379Sopenharmony_ci if err := ex.Extract(filepath.Join(m.ArchiveDir, newFile), dir); err != nil { 146ba991379Sopenharmony_ci return dirName, err 147ba991379Sopenharmony_ci } 148ba991379Sopenharmony_ci return dirName, nil 149ba991379Sopenharmony_ci} 150ba991379Sopenharmony_ci 151ba991379Sopenharmony_cifunc (m *Manager) PkgDir(pkg string) string { 152ba991379Sopenharmony_ci return filepath.Join(m.Workspace, pkg) 153ba991379Sopenharmony_ci} 154