Skip to content

Commit 2f920c8

Browse files
committed
feat: bring up to speed with the repo
1 parent dea9599 commit 2f920c8

File tree

14 files changed

+3869
-0
lines changed

14 files changed

+3869
-0
lines changed

CLAUDE.md

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
This is a Go-based CLI tool for interacting with JuliaHub, a platform for Julia computing. The CLI provides commands for authentication, dataset management, project management, user information, Git integration, and Julia integration.
8+
9+
## Architecture
10+
11+
The application follows a command-line interface pattern using the Cobra library with a modular file structure:
12+
13+
- **main.go**: Core CLI structure with command definitions and configuration management
14+
- **auth.go**: OAuth2 device flow authentication with JWT token handling
15+
- **datasets.go**: Dataset operations (list, download, upload, status) with REST API integration
16+
- **projects.go**: Project management using GraphQL API with user filtering
17+
- **user.go**: User information retrieval using GraphQL API
18+
- **git.go**: Git integration (clone, push, fetch, pull) with JuliaHub authentication
19+
- **julia.go**: Julia installation and management
20+
- **run.go**: Julia execution with JuliaHub configuration
21+
- **Configuration**: Uses `~/.juliahub` file for server and token storage
22+
23+
### Key Components
24+
25+
1. **Authentication System** (`auth.go`):
26+
- Implements OAuth2 device flow for JuliaHub authentication
27+
- JWT token parsing and validation with automatic refresh
28+
- Supports multiple server environments (juliahub.com, custom servers)
29+
- Stores tokens securely in `~/.juliahub` with 0600 permissions
30+
31+
2. **API Integration**:
32+
- **REST API**: Used for dataset operations (`/api/v1/datasets`, `/datasets/{uuid}/url/{version}`)
33+
- **GraphQL API**: Used for projects and user info (`/v1/graphql`)
34+
- **Headers**: All GraphQL requests require `X-Hasura-Role: jhuser` header
35+
- **Authentication**: Uses ID tokens (`token.IDToken`) for API calls
36+
37+
3. **Command Structure**:
38+
- `jh auth`: Authentication commands (login, refresh, status, env)
39+
- `jh dataset`: Dataset operations (list, download, upload, status)
40+
- `jh project`: Project management (list with GraphQL, supports user filtering)
41+
- `jh user`: User information (info with GraphQL)
42+
- `jh clone`: Git clone with JuliaHub authentication and project name resolution
43+
- `jh push/fetch/pull`: Git operations with JuliaHub authentication
44+
- `jh git-credential`: Git credential helper for seamless authentication
45+
- `jh julia`: Julia installation management
46+
- `jh run`: Julia execution with JuliaHub configuration
47+
48+
4. **Data Models**:
49+
- UUID strings for most entity IDs (projects, datasets, resources)
50+
- Integer IDs for user-related entities
51+
- Custom JSON unmarshaling for flexible date parsing (`CustomTime`)
52+
- GraphQL request/response structures with proper operation names
53+
54+
## Development Commands
55+
56+
### Build and Run
57+
```bash
58+
go build -o jh
59+
./jh --help
60+
```
61+
62+
### Run directly
63+
```bash
64+
go run . --help
65+
```
66+
67+
### Code quality checks (always run before commits)
68+
```bash
69+
go fmt ./...
70+
go vet ./...
71+
go build
72+
```
73+
74+
### Test authentication flow
75+
```bash
76+
go run . auth login -s juliahub.com
77+
```
78+
79+
### Test dataset operations
80+
```bash
81+
go run . dataset list
82+
go run . dataset download <dataset-name>
83+
go run . dataset upload --new ./file.tar.gz
84+
```
85+
86+
### Test project and user operations
87+
```bash
88+
go run . project list
89+
go run . project list --user
90+
go run . project list --user john
91+
go run . user info
92+
```
93+
94+
### Test Git operations
95+
```bash
96+
go run . clone john/my-project
97+
go run . push
98+
go run . fetch
99+
go run . pull
100+
```
101+
102+
### Test Git credential helper
103+
```bash
104+
# Setup credential helper (one-time setup)
105+
go run . git-credential setup
106+
107+
# Test credential helper manually
108+
echo -e "protocol=https\nhost=juliahub.com\npath=git/projects/test/test\n" | go run . git-credential get
109+
110+
# After setup, standard Git commands work seamlessly
111+
git clone https://juliahub.com/git/projects/username/project.git
112+
```
113+
114+
## Dependencies
115+
116+
- `github.com/spf13/cobra`: CLI framework
117+
- Standard library packages for HTTP, JSON, file I/O, multipart uploads
118+
119+
## Server Configuration
120+
121+
The CLI supports multiple JuliaHub environments:
122+
- Default: `juliahub.com` (uses `auth.juliahub.com` for auth)
123+
- Custom servers: Direct server specification
124+
- Server normalization: Automatically appends `.juliahub.com` to short names
125+
126+
## Authentication Flow
127+
128+
The application uses OAuth2 device flow:
129+
1. Request device code from `/dex/device/code`
130+
2. Present verification URL to user
131+
3. Poll `/dex/token` endpoint until authorization complete
132+
4. Store tokens in configuration file with JWT claims extraction
133+
134+
## API Patterns
135+
136+
### GraphQL Integration
137+
- **Endpoint**: `https://server/v1/graphql`
138+
- **Required headers**: `Authorization: Bearer <id_token>`, `X-Hasura-Role: jhuser`
139+
- **Request structure**: `{operationName: "...", query: "...", variables: {...}}`
140+
- **User ID retrieval**: Projects use actual user ID from `getUserInfo()` call
141+
142+
### REST API Integration
143+
- **Dataset operations**: Use presigned URLs for upload/download
144+
- **Authentication**: Bearer token with ID token
145+
- **Upload workflow**: 3-step process (request presigned URL, upload to URL, close upload)
146+
147+
### Data Type Handling
148+
- Project/dataset IDs are UUID strings, not integers
149+
- User IDs are integers
150+
- Custom time parsing handles multiple date formats
151+
- Flexible dataset identifier resolution (UUID, name, user/name)
152+
153+
## Git Integration
154+
155+
The CLI provides seamless Git integration with JuliaHub authentication through two approaches:
156+
157+
### Method 1: JuliaHub CLI Wrapper Commands
158+
- **Clone**: `jh clone username/project` - resolves project names to UUIDs and clones with authentication
159+
- **Push/Fetch/Pull**: `jh push/fetch/pull [args...]` - wraps Git commands with authentication headers
160+
- **Authentication**: Uses `http.extraHeader="Authorization: Bearer <id_token>"` for Git operations
161+
- **Argument passthrough**: All Git arguments are passed through to underlying commands
162+
- **Folder naming**: Clone automatically renames UUID folders to project names
163+
- **Conflict resolution**: Handles folder naming conflicts with automatic numbering
164+
165+
### Method 2: Git Credential Helper (Recommended)
166+
- **Setup**: `jh git-credential setup` - configures Git to use JuliaHub CLI as credential helper
167+
- **Multi-server support**: Automatically handles different JuliaHub instances
168+
- **Automatic authentication**: Prompts for authentication when server doesn't match stored config
169+
- **Standard Git commands**: Use `git clone`, `git push`, `git pull`, etc. directly without `jh` wrapper
170+
- **Non-intrusive**: Only handles JuliaHub URLs, other URLs passed to other credential helpers
171+
- **Protocol compliance**: Follows Git credential helper protocol with `get`, `store`, `erase` actions
172+
173+
#### Git Credential Helper Usage:
174+
```bash
175+
# One-time setup
176+
jh git-credential setup
177+
178+
# Then use standard Git commands
179+
git clone https://juliahub.com/git/projects/username/project.git
180+
git push origin main
181+
git pull origin main
182+
183+
# Works with multiple JuliaHub servers automatically
184+
git clone https://internal.juliahub.com/git/projects/user/repo.git # Auto-prompts for auth
185+
git clone https://custom.juliahub.com/git/projects/user/repo.git # Auto-prompts for auth
186+
git clone https://github.com/user/repo.git # Ignored by helper
187+
```
188+
189+
#### Git Credential Helper Implementation:
190+
- **Domain detection**: Recognizes `*.juliahub.com` and configured custom servers
191+
- **Server matching**: Compares requested host against `~/.juliahub` server field
192+
- **Automatic login**: Runs OAuth2 device flow when server mismatch detected
193+
- **Token management**: Stores and refreshes tokens per server automatically
194+
- **Error handling**: Graceful fallback to other credential helpers for non-JuliaHub URLs
195+
196+
## Julia Integration
197+
198+
The CLI provides Julia installation and execution with JuliaHub configuration:
199+
- Cross-platform installation (Windows via winget, Unix via official installer)
200+
- Authentication file creation (`~/.julia/servers/<server>/auth.toml`)
201+
- Package server configuration (`JULIA_PKG_SERVER`)
202+
- Project activation (`--project=.`)
203+
204+
## Development Notes
205+
206+
- All ID fields in GraphQL responses should be typed correctly (string for UUIDs, int64 for user IDs)
207+
- GraphQL queries are embedded as strings (consider external .gql files for complex queries)
208+
- Error handling includes both HTTP and GraphQL error responses
209+
- Token refresh is automatic via `ensureValidToken()`
210+
- File uploads use multipart form data with proper content types
211+
- Julia auth files use TOML format with `preferred_username` from JWT claims
212+
- Git commands use `http.extraHeader` for authentication and pass through all arguments
213+
- Git credential helper provides seamless authentication for standard Git commands
214+
- Multi-server authentication handled automatically via credential helper
215+
- Project filtering supports `--user` parameter for showing specific user's projects or own projects
216+
- Clone command automatically resolves `username/project` format to project UUIDs
217+
- Folder naming conflicts are resolved with automatic numbering (project-1, project-2, etc.)
218+
- Credential helper follows Git protocol: responds only to JuliaHub URLs, ignores others

0 commit comments

Comments
 (0)