forked from bitrise-steplib/steps-recreate-user-schemes
/
step.go
163 lines (134 loc) · 4.13 KB
/
step.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package main
import (
"fmt"
"path/filepath"
"github.com/bitrise-io/go-steputils/v2/stepconf"
"github.com/bitrise-io/go-utils/colorstring"
"github.com/bitrise-io/go-utils/log"
"github.com/bitrise-io/go-utils/pathutil"
"github.com/bitrise-io/go-xcode/xcodeproject/xcscheme"
)
// Input ...
type Input struct {
ProjectPath string `env:"project_path,file"`
}
type Config struct {
ContainerPath string
}
type SchemeGenerator struct {
inputParser stepconf.InputParser
}
func NewSchemeGenerator(inputParser stepconf.InputParser) SchemeGenerator {
return SchemeGenerator{
inputParser: inputParser,
}
}
func (g SchemeGenerator) ProcessConfig() (Config, error) {
var input Input
err := g.inputParser.Parse(&input)
if err != nil {
return Config{}, err
}
stepconf.Print(input)
containerPath, err := pathutil.AbsPath(input.ProjectPath)
if err != nil {
return Config{}, fmt.Errorf("failed to get absolute path for: %s: %w", input.ProjectPath, err)
}
return Config{
ContainerPath: containerPath,
}, nil
}
func (g SchemeGenerator) Run(cfg Config) error {
container, err := openContainer(cfg.ContainerPath)
if err != nil {
return fmt.Errorf("opening container failed: %w", err)
}
fmt.Println()
log.Infof("Collecting existing Schemes...")
containerToSchemes, err := container.schemes()
if err != nil {
return fmt.Errorf("getting schemes failed: %w", err)
}
log.Printf("Schemes:")
printSchemes(true, containerToSchemes, cfg.ContainerPath)
preexistingSharedSchemes := numberOfSharedSchemes(containerToSchemes)
if preexistingSharedSchemes > 0 {
fmt.Println()
log.Donef("There are %d shared Scheme(s).", preexistingSharedSchemes)
return nil
}
// Generate schemes
fmt.Println()
log.Errorf("No shared Schemes found...")
log.Errorf("The newly generated Schemes may differ from the ones in your Project.")
log.Errorf("Make sure to share your Schemes, to prevent unexpected behaviour.")
fmt.Println()
log.Infof("Generating Schemes...")
projects, missingProjects, err := container.projects()
if err != nil {
return fmt.Errorf("getting projects failed: %w", err)
}
for _, missingProject := range missingProjects {
log.Warnf("Skipping project (%s), as it is not present", pathRelativeToWorkspace(missingProject, cfg.ContainerPath))
}
for _, project := range projects {
log.Printf("Recreating Schemes for: %s", filepath.Base(project.Path))
schemes := project.ReCreateSchemes()
for _, scheme := range schemes {
if err := project.SaveSharedScheme(scheme); err != nil {
return fmt.Errorf("saving scheme %s failed: %w", scheme.Name, err)
}
}
}
container, err = openContainer(cfg.ContainerPath)
if err != nil {
return fmt.Errorf("opening the updated container failed: %w", err)
}
containerToSchemesNew, err := container.schemes()
if err != nil {
return fmt.Errorf("getting new schemes failed: %w", err)
}
numberOfNewSchemes := numberOfSharedSchemes(containerToSchemesNew)
if numberOfNewSchemes == 0 {
fmt.Println()
return fmt.Errorf("no schemes generated")
}
fmt.Println()
log.Printf("Created Schemes:")
printSchemes(false, containerToSchemesNew, cfg.ContainerPath)
fmt.Println()
log.Donef("Generated %d shared Scheme(s).", numberOfNewSchemes)
return nil
}
func pathRelativeToWorkspace(project, workspace string) string {
parentDir, _ := filepath.Split(workspace)
relPath, err := filepath.Rel(filepath.Join(parentDir), project)
if err != nil {
log.Warnf("%s", err)
return project
}
return relPath
}
func numberOfSharedSchemes(containerToSchemes map[string][]xcscheme.Scheme) int {
var count int
for _, schemes := range containerToSchemes {
for _, scheme := range schemes {
if scheme.IsShared {
count++
}
}
}
return count
}
func printSchemes(includeUserSchemes bool, containerToSchemes map[string][]xcscheme.Scheme, containerPath string) {
for container, schemes := range containerToSchemes {
log.Printf("- %s", pathRelativeToWorkspace(container, containerPath))
for _, scheme := range schemes {
if scheme.IsShared {
log.Printf(" - %s (Shared)", scheme.Name)
} else if includeUserSchemes {
log.Printf(colorstring.Yellow(fmt.Sprintf(" - %s (User)", scheme.Name)))
}
}
}
}