onyx-devtools 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
cmd/cherry-pick.go ADDED
@@ -0,0 +1,235 @@
1
+ package cmd
2
+
3
+ import (
4
+ "fmt"
5
+ "os"
6
+ "os/exec"
7
+ "regexp"
8
+ "strings"
9
+
10
+ log "github.com/sirupsen/logrus"
11
+ "github.com/spf13/cobra"
12
+ )
13
+
14
+ // CherryPickOptions holds options for the cherry-pick command
15
+ type CherryPickOptions struct {
16
+ Releases []string
17
+ }
18
+
19
+ // NewCherryPickCommand creates a new cherry-pick command
20
+ func NewCherryPickCommand() *cobra.Command {
21
+ opts := &CherryPickOptions{}
22
+
23
+ cmd := &cobra.Command{
24
+ Use: "cherry-pick <commit-sha>",
25
+ Short: "Cherry-pick a commit to a release branch",
26
+ Long: `Cherry-pick a commit to a release branch and create a PR.
27
+
28
+ This command will:
29
+ 1. Find the nearest stable version tag (v*.*.* if --release not specified)
30
+ 2. Fetch the corresponding release branch (release/vMAJOR.MINOR)
31
+ 3. Create a hotfix branch with the cherry-picked commit
32
+ 4. Push and create a PR using the GitHub CLI
33
+ 5. Switch back to the original branch
34
+
35
+ The --release flag can be specified multiple times to cherry-pick to multiple release branches.`,
36
+ Args: cobra.ExactArgs(1),
37
+ Run: func(cmd *cobra.Command, args []string) {
38
+ runCherryPick(cmd, args, opts)
39
+ },
40
+ }
41
+
42
+ cmd.Flags().StringSliceVar(&opts.Releases, "release", []string{}, "Release version(s) to cherry-pick to (e.g., 1.0, v1.1). 'v' prefix is optional. Can be specified multiple times.")
43
+
44
+ return cmd
45
+ }
46
+
47
+ func runCherryPick(cmd *cobra.Command, args []string, opts *CherryPickOptions) {
48
+ commitSHA := args[0]
49
+ log.Debugf("Cherry-picking commit: %s", commitSHA)
50
+
51
+ // Save the current branch to switch back later
52
+ originalBranch, err := getCurrentBranch()
53
+ if err != nil {
54
+ log.Fatalf("Failed to get current branch: %v", err)
55
+ }
56
+ log.Debugf("Original branch: %s", originalBranch)
57
+
58
+ // Get the short SHA for branch naming
59
+ shortSHA := commitSHA
60
+ if len(shortSHA) > 8 {
61
+ shortSHA = shortSHA[:8]
62
+ }
63
+
64
+ // Determine which releases to target
65
+ var releases []string
66
+ if len(opts.Releases) > 0 {
67
+ // Normalize versions to ensure they have 'v' prefix
68
+ for _, rel := range opts.Releases {
69
+ releases = append(releases, normalizeVersion(rel))
70
+ }
71
+ log.Infof("Using specified release versions: %v", releases)
72
+ } else {
73
+ // Find the nearest stable tag
74
+ version, err := findNearestStableTag(commitSHA)
75
+ if err != nil {
76
+ log.Fatalf("Failed to find nearest stable tag: %v", err)
77
+ }
78
+ releases = []string{version}
79
+ log.Infof("Auto-detected release version: %s", version)
80
+ }
81
+
82
+ // Get commit message for PR title
83
+ commitMsg, err := getCommitMessage(commitSHA)
84
+ if err != nil {
85
+ log.Warnf("Failed to get commit message, using default title: %v", err)
86
+ commitMsg = fmt.Sprintf("Hotfix: cherry-pick %s", shortSHA)
87
+ }
88
+
89
+ // Process each release
90
+ prURLs := []string{}
91
+ for _, release := range releases {
92
+ log.Infof("\n--- Processing release %s ---", release)
93
+ prURL, err := cherryPickToRelease(commitSHA, shortSHA, release, commitMsg, originalBranch)
94
+ if err != nil {
95
+ // Switch back to original branch before exiting on error
96
+ runGitCommand("checkout", originalBranch)
97
+ log.Fatalf("Failed to cherry-pick to release %s: %v", release, err)
98
+ }
99
+ prURLs = append(prURLs, prURL)
100
+ }
101
+
102
+ // Switch back to the original branch
103
+ log.Infof("\nSwitching back to original branch: %s", originalBranch)
104
+ if err := runGitCommand("checkout", originalBranch); err != nil {
105
+ log.Warnf("Failed to switch back to original branch: %v", err)
106
+ }
107
+
108
+ // Print all PR URLs
109
+ log.Info("\n=== Summary ===")
110
+ for i, prURL := range prURLs {
111
+ log.Infof("PR %d: %s", i+1, prURL)
112
+ }
113
+ }
114
+
115
+ // cherryPickToRelease cherry-picks a commit to a specific release branch
116
+ func cherryPickToRelease(commitSHA, shortSHA, version, commitMsg, originalBranch string) (string, error) {
117
+ releaseBranch := fmt.Sprintf("release/%s", version)
118
+ hotfixBranch := fmt.Sprintf("hotfix/%s-%s", shortSHA, version)
119
+
120
+ // Fetch the release branch
121
+ log.Infof("Fetching release branch: %s", releaseBranch)
122
+ if err := runGitCommand("fetch", "origin", releaseBranch); err != nil {
123
+ return "", fmt.Errorf("failed to fetch release branch %s: %w", releaseBranch, err)
124
+ }
125
+
126
+ // Create the hotfix branch from the release branch
127
+ log.Infof("Creating hotfix branch: %s", hotfixBranch)
128
+ if err := runGitCommand("checkout", "-b", hotfixBranch, fmt.Sprintf("origin/%s", releaseBranch)); err != nil {
129
+ return "", fmt.Errorf("failed to create hotfix branch: %w", err)
130
+ }
131
+
132
+ // Cherry-pick the commit
133
+ log.Infof("Cherry-picking commit: %s", commitSHA)
134
+ if err := runGitCommand("cherry-pick", commitSHA); err != nil {
135
+ return "", fmt.Errorf("failed to cherry-pick commit: %w", err)
136
+ }
137
+
138
+ // Push the hotfix branch
139
+ log.Infof("Pushing hotfix branch: %s", hotfixBranch)
140
+ if err := runGitCommand("push", "-u", "origin", hotfixBranch); err != nil {
141
+ return "", fmt.Errorf("failed to push hotfix branch: %w", err)
142
+ }
143
+
144
+ // Create PR using GitHub CLI
145
+ log.Info("Creating PR...")
146
+ prURL, err := createPR(hotfixBranch, releaseBranch, commitMsg, commitSHA)
147
+ if err != nil {
148
+ return "", fmt.Errorf("failed to create PR: %w", err)
149
+ }
150
+
151
+ log.Infof("PR created successfully: %s", prURL)
152
+ return prURL, nil
153
+ }
154
+
155
+ // getCurrentBranch returns the name of the current git branch
156
+ func getCurrentBranch() (string, error) {
157
+ cmd := exec.Command("git", "rev-parse", "--abbrev-ref", "HEAD")
158
+ output, err := cmd.Output()
159
+ if err != nil {
160
+ return "", fmt.Errorf("git rev-parse failed: %w", err)
161
+ }
162
+ return strings.TrimSpace(string(output)), nil
163
+ }
164
+
165
+ // normalizeVersion ensures the version has a 'v' prefix
166
+ func normalizeVersion(version string) string {
167
+ if !strings.HasPrefix(version, "v") {
168
+ return "v" + version
169
+ }
170
+ return version
171
+ }
172
+
173
+ // findNearestStableTag finds the nearest tag matching v*.*.* pattern and returns major.minor
174
+ func findNearestStableTag(commitSHA string) (string, error) {
175
+ // Get tags that are ancestors of the commit, sorted by version
176
+ cmd := exec.Command("git", "describe", "--tags", "--abbrev=0", "--match", "v*.*.*", commitSHA)
177
+ output, err := cmd.Output()
178
+ if err != nil {
179
+ return "", fmt.Errorf("git describe failed: %w", err)
180
+ }
181
+
182
+ tag := strings.TrimSpace(string(output))
183
+ log.Debugf("Found tag: %s", tag)
184
+
185
+ // Extract major.minor with v prefix from tag (e.g., v1.2.3 -> v1.2)
186
+ re := regexp.MustCompile(`^(v\d+\.\d+)\.\d+`)
187
+ matches := re.FindStringSubmatch(tag)
188
+ if len(matches) < 2 {
189
+ return "", fmt.Errorf("tag %s does not match expected format v*.*.* ", tag)
190
+ }
191
+
192
+ return matches[1], nil
193
+ }
194
+
195
+ // runGitCommand executes a git command and returns any error
196
+ func runGitCommand(args ...string) error {
197
+ log.Debugf("Running: git %s", strings.Join(args, " "))
198
+ cmd := exec.Command("git", args...)
199
+ cmd.Stdout = os.Stdout
200
+ cmd.Stderr = os.Stderr
201
+ return cmd.Run()
202
+ }
203
+
204
+ // getCommitMessage gets the first line of a commit message
205
+ func getCommitMessage(commitSHA string) (string, error) {
206
+ cmd := exec.Command("git", "log", "-1", "--format=%s", commitSHA)
207
+ output, err := cmd.Output()
208
+ if err != nil {
209
+ return "", err
210
+ }
211
+ return strings.TrimSpace(string(output)), nil
212
+ }
213
+
214
+ // createPR creates a pull request using the GitHub CLI
215
+ func createPR(headBranch, baseBranch, title, commitSHA string) (string, error) {
216
+ body := fmt.Sprintf("Cherry-pick of commit %s to %s branch.", commitSHA, baseBranch)
217
+
218
+ cmd := exec.Command("gh", "pr", "create",
219
+ "--base", baseBranch,
220
+ "--head", headBranch,
221
+ "--title", title,
222
+ "--body", body,
223
+ )
224
+
225
+ output, err := cmd.Output()
226
+ if err != nil {
227
+ if exitErr, ok := err.(*exec.ExitError); ok {
228
+ return "", fmt.Errorf("%w: %s", err, string(exitErr.Stderr))
229
+ }
230
+ return "", err
231
+ }
232
+
233
+ prURL := strings.TrimSpace(string(output))
234
+ return prURL, nil
235
+ }
cmd/root.go ADDED
@@ -0,0 +1,48 @@
1
+ package cmd
2
+
3
+ import (
4
+ "fmt"
5
+
6
+ log "github.com/sirupsen/logrus"
7
+ "github.com/spf13/cobra"
8
+ )
9
+
10
+ var (
11
+ Version string
12
+ Commit string
13
+ )
14
+
15
+ // RootOptions holds options for the root command
16
+ type RootOptions struct {
17
+ Debug bool
18
+ }
19
+
20
+ // NewRootCommand creates the root command
21
+ func NewRootCommand() *cobra.Command {
22
+ opts := &RootOptions{}
23
+
24
+ cmd := &cobra.Command{
25
+ Use: "ods ",
26
+ Short: "Developer utilities for working on onyx.app",
27
+ Run: rootCmd,
28
+ PersistentPreRun: func(cmd *cobra.Command, args []string) {
29
+ if opts.Debug {
30
+ log.SetLevel(log.DebugLevel)
31
+ } else {
32
+ log.SetLevel(log.InfoLevel)
33
+ }
34
+ },
35
+ Version: fmt.Sprintf("%s\ncommit %s", Version, Commit),
36
+ }
37
+
38
+ cmd.PersistentFlags().BoolVar(&opts.Debug, "debug", false, "run in debug mode")
39
+
40
+ // Add subcommands
41
+ cmd.AddCommand(NewCherryPickCommand())
42
+
43
+ return cmd
44
+ }
45
+
46
+ func rootCmd(cmd *cobra.Command, args []string) {
47
+ log.Debug("Debug log in rootCmd")
48
+ }
go.mod ADDED
@@ -0,0 +1,14 @@
1
+ module github.com/onyx-dot-app/onyx/tools/ods
2
+
3
+ go 1.25.0
4
+
5
+ require (
6
+ github.com/sirupsen/logrus v1.9.3
7
+ github.com/spf13/cobra v1.10.1
8
+ )
9
+
10
+ require (
11
+ github.com/inconshreveable/mousetrap v1.1.0 // indirect
12
+ github.com/spf13/pflag v1.0.9 // indirect
13
+ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
14
+ )
go.sum ADDED
@@ -0,0 +1,24 @@
1
+ github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
2
+ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3
+ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
4
+ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
5
+ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
6
+ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
7
+ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
8
+ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
9
+ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
10
+ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
11
+ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
12
+ github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
13
+ github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
14
+ github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
15
+ github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
16
+ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
17
+ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
18
+ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
19
+ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
20
+ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
21
+ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
22
+ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
23
+ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
24
+ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
main.go ADDED
@@ -0,0 +1,26 @@
1
+ package main
2
+
3
+ import (
4
+ "fmt"
5
+ "os"
6
+
7
+ "github.com/onyx-dot-app/onyx/tools/ods/cmd"
8
+ )
9
+
10
+ var (
11
+ version = "dev"
12
+ commit = "none"
13
+ )
14
+
15
+ func main() {
16
+ // Set the version in the cmd package
17
+ cmd.Version = version
18
+ cmd.Commit = commit
19
+
20
+ rootCmd := cmd.NewRootCommand()
21
+
22
+ if err := rootCmd.Execute(); err != nil {
23
+ fmt.Fprintf(os.Stderr, "Error: %v\n", err)
24
+ os.Exit(2)
25
+ }
26
+ }
Binary file
@@ -0,0 +1,46 @@
1
+ Metadata-Version: 2.4
2
+ Name: onyx-devtools
3
+ Version: 0.0.1
4
+ Summary: Developer utilities for working on onyx.app
5
+ Project-URL: Repository, https://github.com/onyx-dot-app/onyx
6
+ Author-email: Onyx AI <founders@onyx.app>
7
+ License: Copyright (c) 2023-present DanswerAI, Inc.
8
+
9
+ Portions of this software are licensed as follows:
10
+
11
+ - All content that resides under "ee" directories of this repository, if that directory exists, is licensed under the license defined in "backend/ee/LICENSE". Specifically all content under "backend/ee" and "web/src/app/ee" is licensed under the license defined in "backend/ee/LICENSE".
12
+ - All third party components incorporated into the Onyx Software are licensed under the original license provided by the owner of the applicable component.
13
+ - Content outside of the above mentioned directories or restrictions above is available under the "MIT Expat" license as defined below.
14
+
15
+ Permission is hereby granted, free of charge, to any person obtaining a copy
16
+ of this software and associated documentation files (the "Software"), to deal
17
+ in the Software without restriction, including without limitation the rights
18
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19
+ copies of the Software, and to permit persons to whom the Software is
20
+ furnished to do so, subject to the following conditions:
21
+
22
+ The above copyright notice and this permission notice shall be included in all
23
+ copies or substantial portions of the Software.
24
+
25
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
+ SOFTWARE.
32
+ Keywords: cli,devtools,onyx,tooling,tools
33
+ Classifier: License :: OSI Approved :: MIT License
34
+ Classifier: Operating System :: OS Independent
35
+ Classifier: Programming Language :: Go
36
+ Requires-Python: >=3.9
37
+ Description-Content-Type: text/markdown
38
+
39
+ # Onyx Developer Script
40
+
41
+ `ods` is [onyx.app](https://github.com/onyx-dot-app/onyx)'s devtools utility script.
42
+
43
+ ## Installation
44
+
45
+ Build from source or install via the Python package.
46
+
@@ -0,0 +1,9 @@
1
+ go.mod,sha256=GPbxLNTCEDWbk2yqzPOhOVVdAdf7H_qSkVMBBUzV3lE,315
2
+ go.sum,sha256=mX46HcsYoWumvF-HizNUmnKMcO680dlGAVUjJKl2dNg,2152
3
+ main.go,sha256=7wEKb_3eC34OzWLOF3CFJ8ruCTntCcOpBSbj8lxnqtY,368
4
+ cmd/cherry-pick.go,sha256=L-E_MsNenJF-s4Nmg-nnYX4i3UyYHtigx0MrV9fxYZg,7468
5
+ cmd/root.go,sha256=5xOskFDSRhoK_rqB4MRFySH_-cdgSULdOSCGL690rSs,922
6
+ onyx_devtools-0.0.1.data/scripts/ods,sha256=K3rhRtouNNd6iYYEUWrKKZd5VpiFQLMEh2AYxiE2ytY,2695460
7
+ onyx_devtools-0.0.1.dist-info/METADATA,sha256=VmReZgA8v0tU2dQP0pvjYBZAYhd-6ga1HJfit95Zd1Y,2539
8
+ onyx_devtools-0.0.1.dist-info/WHEEL,sha256=kSJeMi9O0SUGxjx2EApEegNDQjzBxdRttB3CsW2Gfgw,88
9
+ onyx_devtools-0.0.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: false
4
+ Tag: py3-none-any