parseProjectURL parses a GitHub Project V2 URL
(projectURL string)
| 413 | |
| 414 | // parseProjectURL parses a GitHub Project V2 URL |
| 415 | func parseProjectURL(projectURL string) (projectURLInfo, error) { |
| 416 | // Extract scope, owner, and project number from URL |
| 417 | // Expected format: https://github.com/orgs/myorg/projects/123 or https://github.com/users/myuser/projects/123 |
| 418 | parts := strings.Split(projectURL, "/") |
| 419 | if len(parts) < 6 { |
| 420 | return projectURLInfo{}, errors.New("invalid project URL format") |
| 421 | } |
| 422 | |
| 423 | var scope, ownerLogin, numberStr string |
| 424 | for i, part := range parts { |
| 425 | if part == "orgs" || part == "users" { |
| 426 | if i+2 < len(parts) && parts[i+2] == "projects" && i+3 < len(parts) { |
| 427 | scope = part |
| 428 | ownerLogin = parts[i+1] |
| 429 | numberStr = parts[i+3] |
| 430 | break |
| 431 | } |
| 432 | } |
| 433 | } |
| 434 | |
| 435 | if scope == "" { |
| 436 | return projectURLInfo{}, errors.New("invalid project URL: could not find orgs/users segment") |
| 437 | } |
| 438 | |
| 439 | projectNumber, err := strconv.Atoi(numberStr) |
| 440 | if err != nil { |
| 441 | return projectURLInfo{}, fmt.Errorf("invalid project number: %w", err) |
| 442 | } |
| 443 | |
| 444 | return projectURLInfo{ |
| 445 | scope: scope, |
| 446 | ownerLogin: ownerLogin, |
| 447 | projectNumber: projectNumber, |
| 448 | }, nil |
| 449 | } |
| 450 | |
| 451 | // createStandardViews creates the standard project views |
| 452 | func createStandardViews(ctx context.Context, projectURL string, verbose bool) error { |