Skip to content

Commit bd9ca37

Browse files
Add agent-readable docs, AGENTS.md, and restructure README
1 parent 9b2e9e0 commit bd9ca37

27 files changed

Lines changed: 3289 additions & 112 deletions

‎.gitignore‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,7 @@ cloudinary-android/src/androidTest/AndroidManifest.xml
4747
/tools/cloudinary_url.txt
4848
/tools/History.md
4949

50+
## Artifacts left behind by running examples/
51+
/example-video.mp4
52+
/out/
53+

‎AGENTS.md‎

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# Contributor guide for coding agents
2+
3+
This file is for agents contributing to this repository. If you are *using* the SDK in another
4+
project, read [`docs/`](docs/README.md) instead — task-oriented pages for agents using the SDK.
5+
6+
## Commands
7+
8+
Use JDK 8 or 11; CI runs on JDK 8. The Gradle 6.0.1 wrapper fails on JDK 17 and later before any
9+
task runs.
10+
11+
```bash
12+
./gradlew :cloudinary-core:jar :cloudinary-http5:jar :cloudinary-taglib:jar # build the published modules
13+
./gradlew :cloudinary-core:test # unit tests, no cloud needed
14+
./gradlew createTestSubAccount -PmoduleName=http5 # throwaway cloud -> tools/cloudinary_url.txt
15+
source tools/cloudinary_url.txt # sets CLOUDINARY_URL
16+
./gradlew ciTest -p cloudinary-http5 -DCLOUDINARY_URL="$CLOUDINARY_URL" # integration tests, as CI runs them
17+
```
18+
19+
Gradle passes `-DCLOUDINARY_URL` to the test JVM as the `CLOUDINARY_URL` environment variable
20+
(`java_shared.gradle`). `tools/cloudinary_url.txt` is git-ignored and contains live credentials;
21+
never commit it or paste its contents anywhere.
22+
23+
## Testing
24+
25+
- `cloudinary-core` tests run offline. `cloudinary-http5` tests need a live product environment.
26+
`cloudinary-taglib` has no tests.
27+
- Use a fresh sub-account for each integration run. Assets and metadata fields left by earlier
28+
runs can fail unrelated tests.
29+
- `java` snippets in `docs/` must compile against the built jars, and links in `docs/` must
30+
resolve.
31+
32+
## Project structure
33+
34+
| Path | Published | Purpose |
35+
|---|---|---|
36+
| `cloudinary-core/` | Yes | URL/transformation building, parameter serialisation. No HTTP client, no runtime dependencies. |
37+
| `cloudinary-http5/` | Yes | Apache HttpClient 5 transport. **This is what users depend on.** |
38+
| `cloudinary-taglib/` | Yes | JSP tags. Targets `javax.*`, not Jakarta EE 9+. |
39+
| `cloudinary-test-common/` | Yes | Shared test helpers. Not for application code. |
40+
| `docs/` | No | Task pages for agents *using* the SDK. |
41+
| `examples/` | No | One runnable program per doc page where the task is genuinely runnable. |
42+
| `samples/` | No | Legacy sample applications. Not in the build. |
43+
| `tools/` | No | Release and test-cloud scripts. |
44+
45+
`settings.gradle` includes the four modules above.
46+
47+
`org.cloudinary.json` inside `cloudinary-core` is a vendored JSON implementation. It exists to
48+
keep the core dependency-free. Do not replace it with Jackson or Gson.
49+
50+
`docs/` and `examples/` are not packaged into any jar; the published `-javadoc.jar` is the
51+
documentation attached to each artifact.
52+
53+
Keep examples uniform: one entry point taking no arguments, no CLI parsing, constants at the top,
54+
and one error-handling block mapping every failure to a non-zero exit with a readable message.
55+
56+
## Code style
57+
58+
- The build targets **Java 8** (`sourceCompatibility = 1.8` in `java_shared.gradle`). Do not use
59+
newer language features in `src/main`.
60+
- There is no linter, formatter, or static-analysis tool. Match the surrounding code.
61+
- Options are untyped `Map`s built with `ObjectUtils.asMap(k, v, ...)`; responses are `Map`s keyed
62+
by the raw API field names (`public_id`, `secure_url`, `asset_id`). There are no typed response
63+
objects.
64+
- `Cloudinary` is safe to share as a singleton. `Url` is a **mutable** builder and is not
65+
thread-safe; call `cloudinary.url()` per URL.
66+
67+
## Docs
68+
69+
- Docs describe this SDK. Link Cloudinary documentation in `.md` form
70+
(`https://cloudinary.com/documentation/<page>.md`); `README.md` may link HTML. Do not recommend
71+
third-party packages.
72+
- Prefer `asset_id` (immutable) over `public_id` (changes on rename) when showing how to store a
73+
reference. Five `Api` methods accept an asset ID; nothing in `Uploader` does.
74+
- `README.md` shows the released version, which the release script updates. Pages in `docs/` use
75+
`X.Y.Z`, because the release script does not touch them.
76+
77+
## Git workflow
78+
79+
- Branch from `master`; keep changes focused; one topic per pull request.
80+
- Do not edit `CHANGELOG.md` or bump the version. Releases run `tools/update_version.sh <version>`,
81+
which rewrites `Cloudinary.VERSION` in `Cloudinary.java`, `version=` in `gradle.properties`, and
82+
the version in `README.md`. It reads the `VERSION` line with a regex; do not reformat it.
83+
- Keep secrets out of everything — code, tests, fixtures, docs, commit messages. Grep the diff
84+
for `cloudinary://` with real values before pushing.
85+
- Never commit `tools/cloudinary_url.txt`, `/out/`, or media left behind by running examples.
86+
87+
## Boundaries
88+
89+
**Always**
90+
- Verify claims in `docs/` against the source and, where possible, by running them. Do not copy
91+
another Cloudinary SDK's docs; behaviour differs between the SDKs.
92+
- Keep `docs/` and `examples/` consistent with the code they document.
93+
- Keep API secrets out of examples, docs, tests, and fixtures.
94+
95+
**Ask first**
96+
- Changing the published artifact list, packaging, or what ships inside a jar.
97+
- Adding a dependency. `cloudinary-core` has no runtime dependencies.
98+
- Changing public API signatures or behaviour. Document current behaviour and raise an issue
99+
before changing it. This includes these behaviours, which `docs/` describes and callers may
100+
depend on:
101+
1. Error types differ by entry point: `java.lang.RuntimeException` carrying a message for
102+
uploads (`AbstractUploaderStrategy.processResponse`), typed `ApiException` subclasses for
103+
the Admin API, and `java.lang.UnknownError` (an `Error`, not an `Exception`) when no HTTP
104+
adapter is present.
105+
2. `EnumMetadataField` has a package-private constructor and no factory, unlike
106+
`SetMetadataField`. Application code uses `new MetadataField<String>(MetadataFieldType.ENUM)`.
107+
3. `ProgressCallback` overloads compile on `cloudinary-http5` and throw
108+
`IllegalArgumentException: Progress callback is not supported` when called.
109+
4. `Url.resourcType(String)` is retained alongside `resourceType(String)` for compatibility.
110+
- Touching `publish.gradle`, `gradle.properties`, `MAVEN_CENTRAL_PUBLISHING_GUIDE.md`, or the
111+
release script.
112+
- Adding a typed response object, a linter, or a formatter.
113+
- Modifying the legacy sample apps in `samples/`.
114+
115+
**Never**
116+
- Commit credentials or real account identifiers.
117+
- Document a Cloudinary platform capability as an SDK method unless this library implements it
118+
(see `docs/platform-capabilities.md`).

‎CLAUDE.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@AGENTS.md

0 commit comments

Comments
 (0)