github.com/bitrise-io/go-xamarin@v0.0.0-20211005113058-bf60a8bae851/tools/buildtools/xbuild/xbuild.go (about) 1 package xbuild 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 "path/filepath" 8 "strings" 9 10 "github.com/bitrise-io/go-utils/command" 11 "github.com/bitrise-io/go-utils/pathutil" 12 "github.com/bitrise-io/go-xamarin/constants" 13 ) 14 15 // Model ... 16 type Model struct { 17 BuildTool string 18 19 SolutionPth string 20 ProjectPth string 21 22 target string 23 configuration string 24 platform string 25 26 buildIpa bool 27 archiveOnBuild bool 28 29 customOptions []string 30 } 31 32 // New ... 33 func New(solutionPth, projectPth string) (*Model, error) { 34 absSolutionPth, err := pathutil.AbsPath(solutionPth) 35 if err != nil { 36 return nil, fmt.Errorf("Failed to expand path (%s), error: %s", solutionPth, err) 37 } 38 39 absProjectPth := "" 40 if projectPth != "" { 41 absPth, err := pathutil.AbsPath(projectPth) 42 if err != nil { 43 return nil, fmt.Errorf("Failed to expand path (%s), error: %s", projectPth, err) 44 } 45 absProjectPth = absPth 46 } 47 48 return &Model{SolutionPth: absSolutionPth, ProjectPth: absProjectPth, BuildTool: constants.XbuildPath}, nil 49 } 50 51 // SetTarget ... 52 func (xbuild *Model) SetTarget(target string) *Model { 53 xbuild.target = target 54 return xbuild 55 } 56 57 // SetConfiguration ... 58 func (xbuild *Model) SetConfiguration(configuration string) *Model { 59 xbuild.configuration = configuration 60 return xbuild 61 } 62 63 // SetPlatform ... 64 func (xbuild *Model) SetPlatform(platform string) *Model { 65 xbuild.platform = platform 66 return xbuild 67 } 68 69 // SetBuildIpa ... 70 func (xbuild *Model) SetBuildIpa(buildIpa bool) *Model { 71 xbuild.buildIpa = buildIpa 72 return xbuild 73 } 74 75 // SetArchiveOnBuild ... 76 func (xbuild *Model) SetArchiveOnBuild(archive bool) *Model { 77 xbuild.archiveOnBuild = archive 78 return xbuild 79 } 80 81 // SetCustomOptions ... 82 func (xbuild *Model) SetCustomOptions(options ...string) { 83 xbuild.customOptions = options 84 } 85 86 func (xbuild Model) buildCommands() []string { 87 cmdSlice := []string{xbuild.BuildTool} 88 89 if xbuild.ProjectPth != "" { 90 cmdSlice = append(cmdSlice, xbuild.ProjectPth) 91 } else { 92 cmdSlice = append(cmdSlice, xbuild.SolutionPth) 93 } 94 95 if xbuild.target != "" { 96 cmdSlice = append(cmdSlice, fmt.Sprintf("/target:%s", xbuild.target)) 97 } 98 99 // According to official docs this value should include the trailing backslash: 100 // https://docs.microsoft.com/en-us/cpp/build/reference/common-macros-for-build-commands-and-properties?view=vs-2019 101 solutionDirPth := ensureTrailingPathSeparator(filepath.Dir(xbuild.SolutionPth)) 102 cmdSlice = append(cmdSlice, "/p:SolutionDir="+solutionDirPth) 103 104 if xbuild.configuration != "" { 105 cmdSlice = append(cmdSlice, "/p:Configuration="+xbuild.configuration) 106 } 107 108 if xbuild.platform != "" { 109 cmdSlice = append(cmdSlice, "/p:Platform="+xbuild.platform) 110 } 111 112 if xbuild.archiveOnBuild { 113 cmdSlice = append(cmdSlice, "/p:ArchiveOnBuild=true") 114 } 115 116 if xbuild.buildIpa { 117 cmdSlice = append(cmdSlice, "/p:BuildIpa=true") 118 } 119 120 cmdSlice = append(cmdSlice, xbuild.customOptions...) 121 122 return cmdSlice 123 } 124 125 // String ... 126 func (xbuild Model) String() string { 127 cmdSlice := xbuild.buildCommands() 128 return command.PrintableCommandArgs(true, cmdSlice) 129 } 130 131 // Run ... 132 func (xbuild Model) Run(outWriter, errWriter io.Writer) error { 133 if outWriter == nil { 134 outWriter = os.Stdout 135 } 136 if errWriter == nil { 137 errWriter = os.Stderr 138 } 139 140 cmdSlice := xbuild.buildCommands() 141 142 command, err := command.NewFromSlice(cmdSlice) 143 if err != nil { 144 return err 145 } 146 147 command.SetStdout(outWriter) 148 command.SetStderr(errWriter) 149 150 return command.Run() 151 } 152 153 func ensureTrailingPathSeparator(path string) string { 154 slash := string(filepath.Separator) 155 return strings.TrimSuffix(path, slash) + slash 156 }