Skip to content

Commit 089e282

Browse files
authored
chore: merge pull request #21 from cvigilv/ci-minimal-version
ci!: update testing, formatting and docgen
2 parents 3f3d0f4 + 36d0300 commit 089e282

File tree

18 files changed

+466
-140
lines changed

18 files changed

+466
-140
lines changed

.github/workflows/CI.yml

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,31 @@ on:
66
tags: ['*']
77
pull_request:
88
concurrency:
9-
# Skip intermediate builds: always.
10-
# Cancel intermediate builds: only if it is a pull request build.
119
group: ${{ github.workflow }}-${{ github.ref }}
1210
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
1311
jobs:
12+
format:
13+
name: Code formatting
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
- uses: julia-actions/setup-julia@v1
18+
with:
19+
version: '1'
20+
- uses: julia-actions/cache@v1
21+
- name: Install Runic
22+
run: julia -e 'using Pkg; Pkg.add("Runic")'
23+
- name: Check formatting
24+
run: julia -e 'using Runic; Runic.main(["--check", "src/", "test/", "docs/"])'
25+
1426
test:
15-
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
27+
name: Test (${{ matrix.version }}; ${{ matrix.os }} ${{ matrix.arch }})
1628
runs-on: ${{ matrix.os }}
1729
strategy:
1830
fail-fast: false
1931
matrix:
2032
version:
21-
- '1.9'
33+
- '1.10'
2234
- 'nightly'
2335
os:
2436
- ubuntu-latest
@@ -33,8 +45,11 @@ jobs:
3345
- uses: julia-actions/cache@v1
3446
- uses: julia-actions/julia-buildpkg@v1
3547
- uses: julia-actions/julia-runtest@v1
48+
timeout-minutes: 10
3649
- uses: julia-actions/julia-processcoverage@v1
50+
if: matrix.version == '1.10' && matrix.os == 'ubuntu-latest'
3751
- uses: codecov/codecov-action@v3
52+
if: matrix.version == '1.10' && matrix.os == 'ubuntu-latest'
3853
with:
3954
files: lcov.info
4055
docs:

AGENTS.md

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
# AGENTS.md - Development Guide for KEGGAPI.jl
2+
3+
## Project Overview
4+
5+
KEGGAPI.jl is a Julia package providing programmatic access to the KEGG (Kyoto Encyclopedia of Genes and Genomes) REST API. This package offers functions to retrieve biological data including pathways, compounds, genes, and genomic information.
6+
7+
## Build, Test & Development Commands
8+
9+
### Basic Commands
10+
```bash
11+
# Install package dependencies
12+
julia --project -e "using Pkg; Pkg.instantiate()"
13+
14+
# Run all tests
15+
julia --project -e "using Pkg; Pkg.test()"
16+
17+
# Build package
18+
julia --project -e "using Pkg; Pkg.build()"
19+
20+
# Run single test file
21+
julia --project test/runtests.jl
22+
23+
# Start Julia REPL with project
24+
julia --project
25+
26+
# Generate documentation
27+
julia --project=docs docs/make.jl
28+
```
29+
30+
### Development Setup
31+
```bash
32+
# Activate development environment
33+
julia --project=dev -e "using Pkg; Pkg.develop(PackageSpec(path=pwd()))"
34+
35+
# Add development dependencies
36+
julia --project -e "using Pkg; Pkg.add([\"Test\", \"Runic\", \"Aqua\"])"
37+
38+
# Format code with Runic.jl
39+
julia --project -e "using Runic; Runic.format(\".\")"
40+
```
41+
42+
### Testing Strategy
43+
44+
**Unit Tests (Mocked):** Test wrapper functions without API calls
45+
- `kegg_get()`, `list()`, `info()`, `get_image()`, `conv()`, `find()`, `link()`
46+
47+
**Integration Tests (Real API):** Test core request functionality
48+
- `KEGGAPI.request()` - Must test with actual KEGG API endpoints
49+
50+
**Test Organization:**
51+
- All tests in `test/runtests.jl`
52+
- Use `@testset` for logical groupings
53+
- Test both success and failure scenarios
54+
55+
## Code Style Guidelines
56+
57+
### Formatting
58+
- **Formatter:** Runic.jl (enforced in CI)
59+
- **Line Length:** No strict limit, but prefer readability
60+
- **Indentation:** 4 spaces (no tabs)
61+
62+
### Imports & Dependencies
63+
```julia
64+
# Qualified imports preferred
65+
import HTTP: get
66+
67+
# Standard library imports
68+
using Test
69+
70+
# Export public API clearly
71+
export request, info, list, find, get_image, kegg_get, conv, link, save_image
72+
```
73+
74+
### Function & Variable Naming
75+
```julia
76+
# Functions: snake_case
77+
function kegg_get(query::Vector{String})
78+
function request_other(url::String)
79+
80+
# Types: PascalCase
81+
struct RequestError <: Exception
82+
struct KeggTupleList
83+
84+
# Constants: UPPER_SNAKE_CASE
85+
const DEFAULT_CHUNK_SIZE = 10
86+
87+
# Variables: snake_case
88+
chunk_size = 10
89+
response_text = request(url)
90+
```
91+
92+
### Type Annotations
93+
```julia
94+
# Always annotate function parameters
95+
function request(url::String)
96+
function kegg_get(query::Vector{String}, option::String = "")
97+
98+
# Use concrete types in structs
99+
struct RequestError <: Exception
100+
message::String
101+
end
102+
103+
# Return type annotations for public API
104+
function info(database::String)::String
105+
```
106+
107+
### Documentation
108+
```julia
109+
"""
110+
KEGGAPI.function_name(param1, param2) -> ReturnType
111+
112+
Brief description of what the function does.
113+
114+
Longer description if needed, explaining parameters,
115+
behavior, and any important details.
116+
117+
# Examples
118+
```julia-repl
119+
julia> KEGGAPI.function_name("example")
120+
"result"
121+
```
122+
123+
# Arguments
124+
- `param1::String`: Description of parameter
125+
- `param2::Int`: Description with default value
126+
127+
# Returns
128+
- `String`: Description of return value
129+
130+
# Throws
131+
- `RequestError`: When API request fails
132+
"""
133+
```
134+
135+
### Error Handling
136+
```julia
137+
# Custom exception types
138+
struct RequestError <: Exception
139+
message::String
140+
end
141+
142+
# Explicit error throwing
143+
if response.status != 200
144+
throw(RequestError("Request failed with status $(response.status)"))
145+
end
146+
147+
# Error testing in tests
148+
@test_throws RequestError KEGGAPI.info("invalid_db")
149+
```
150+
151+
### Control Flow & Logic
152+
```julia
153+
# Clear conditional structure
154+
if condition
155+
action()
156+
elseif other_condition
157+
other_action()
158+
else
159+
default_action()
160+
end
161+
162+
# Prefer early returns to reduce nesting
163+
function process_data(data)
164+
if isempty(data)
165+
return nothing
166+
end
167+
168+
# Main logic here
169+
return processed_data
170+
end
171+
```
172+
173+
### Comments
174+
```julia
175+
# Use comments to explain WHY, not WHAT
176+
chunk_size = 10 # KEGG API optimal batch size
177+
178+
# Complex logic deserves explanation
179+
# Split queries into chunks to respect API rate limits
180+
for i in 1:query_chunks
181+
# Process each chunk...
182+
end
183+
184+
# TODO comments for future improvements
185+
# TODO: Add retry logic for failed requests
186+
```
187+
188+
### File Organization
189+
```julia
190+
# Main module (src/KEGGAPI.jl)
191+
module KEGGAPI
192+
import HTTP: get
193+
export functions...
194+
include("Structures.jl") # Types first
195+
include("Requests.jl") # Core functionality
196+
include("specialized_functions.jl")
197+
end
198+
199+
# Each file should have focused responsibility
200+
# Structures.jl - Type definitions
201+
# Requests.jl - HTTP request handling
202+
# Info.jl - Info-related functions
203+
```
204+
205+
### Testing Patterns
206+
```julia
207+
@testset "Function Group" begin
208+
@testset "specific_function" begin
209+
# Test successful case
210+
result = KEGGAPI.specific_function("valid_input")
211+
@test isa(result, ExpectedType)
212+
@test length(result) > 0
213+
214+
# Test error case
215+
@test_throws RequestError KEGGAPI.specific_function("invalid")
216+
end
217+
end
218+
219+
# Integration test patterns (for KEGGAPI.request only)
220+
@testset "Integration Tests" begin
221+
@testset "real API calls" begin
222+
# Test with known working endpoint
223+
result = KEGGAPI.request("https://rest.kegg.jp/info/kegg")
224+
@test isa(result, String)
225+
@test !isempty(result)
226+
end
227+
end
228+
```
229+
230+
## CI/CD Pipeline
231+
232+
### Current Status
233+
- **Testing:** Julia 1.9 + nightly on Ubuntu
234+
- **Documentation:** Auto-builds and deploys
235+
- **Dependencies:** CompatHelper for automated updates
236+
- **Releases:** TagBot for automated tagging
237+
238+
### Planned Enhancements
239+
- **Formatting:** Runic.jl enforcement (blocks PRs)
240+
- **Extended Testing:** Julia 1.10, nightly
241+
- **Code Quality:** Aqua.jl integration
242+
- **Real API Tests:** For `KEGGAPI.request()` function
243+
- **Semantic Versioning:** Automated enforcement
244+
- **Release Notes:** Automated generation
245+
246+
### Development Workflow
247+
1. Format code with Runic.jl before committing
248+
2. Ensure all tests pass locally
249+
3. Write tests for new functionality
250+
4. Update documentation for public API changes
251+
5. Breaking changes are acceptable with proper notification
252+
253+
## Common Patterns & Examples
254+
255+
### Making API Requests
256+
```julia
257+
# Always use the request() function for HTTP calls
258+
response_text = request("https://rest.kegg.jp/info/$database")
259+
260+
# Handle errors appropriately
261+
try
262+
data = request(url)
263+
return parse_response(data)
264+
catch e
265+
if e isa RequestError
266+
# Handle API errors
267+
return default_value
268+
else
269+
rethrow(e)
270+
end
271+
end
272+
```
273+
274+
### Processing API Responses
275+
```julia
276+
# Split responses consistently
277+
for datum in split(response_text, "\n///\n")
278+
push!(data, datum)
279+
end
280+
281+
# Clean up response text
282+
response_text2 = replace(response_text, r"\n///([^/]*)$" => "")
283+
```
284+
285+
### Rate Limiting
286+
```julia
287+
# Always include delays between API calls
288+
sleep(0.1) # 100ms delay between requests
289+
```
290+
291+
This guide ensures consistent, maintainable code that follows Julia best practices while respecting the KEGG API's requirements and limitations.

Project.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
name = "KEGGAPI"
22
uuid = "e8256861-d17c-4800-bf17-838497555b93"
3-
authors = ["Nicholas Geoffrion", "Maria Victoria Aguilar Pontes"]
43
version = "1.0.0-DEV"
4+
authors = ["Nicholas Geoffrion", "Maria Victoria Aguilar Pontes", "Carlos Vigil-Vásquez"]
55

66
[deps]
77
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
88

99
[compat]
1010
HTTP = "1"
11-
julia = "1"
11+
julia = "1.10"
1212

1313
[extras]
14+
Runic = "62bfec6d-59d7-401d-8490-b29ee721c001"
1415
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
1516

1617
[targets]
17-
test = ["Test"]
18+
test = ["Test", "Runic"]

0 commit comments

Comments
 (0)