Back to Main Documentation
- Desktop Development: See CLAUDE_DESKTOP.md
- Android Development: See CLAUDE_ANDROID.md
- iOS/macOS Development: See CLAUDE_IOS.md
- Testing: See TEST_COVERAGE.md
- CI/CD: See CI-CD.md
- Security: See SECURITY.md
Requirements:
- Java 21 JDK (OpenJDK or Oracle)
- Maven 3.6+
- Git
Setup:
# Clone repository
git clone https://github.com/FlossWare/nexus-java.git
cd nexus-java
# Build
./mvnw clean package
# Run tests
./mvnw test
# Run CLI
java -jar target/jnexus-1.0-jar-with-dependencies.jar --helpRequirements:
- Android Studio Arctic Fox or later
- Android SDK 34
- Gradle 8.0+
- Java 11+ (for Gradle)
Setup:
# Clone repository
git clone https://github.com/FlossWare/nexus-java.git
cd nexus-java
# Build from command line
gradle :jnexus-android:assembleDebug
# Or open in Android Studio
# File → Open → select jnexus-android/Requirements:
- macOS 13.0+ (Ventura or later)
- Xcode 15+ (includes Swift 5.9+)
- Apple Developer account (for device testing)
Setup:
# Clone repository
git clone https://github.com/FlossWare/nexus-java.git
cd nexus-java/jnexus-ios
# Open in Xcode
open JNexus.xcodeproj
# Or build from command line
xcodebuild -scheme JNexus-iOS -configuration DebugJava/Kotlin:
- Classes: PascalCase (e.g.,
NexusClient,RepositoryStats) - Methods: camelCase (e.g.,
listComponents(),calculateStatistics()) - Constants: UPPER_SNAKE_CASE (e.g.,
DEFAULT_TIMEOUT,CACHE_TTL) - Variables: camelCase (e.g.,
componentId,totalSize) - Commands: verb form (e.g.,
list,delete, notListCommand)
Swift:
- Types: PascalCase (e.g.,
NexusService,RepoRecord) - Functions/methods: camelCase (e.g.,
listComponents(),saveCredentials()) - Constants: camelCase (e.g.,
defaultTimeout,cacheTTL) - Variables: camelCase (e.g.,
componentId,totalSize)
Java:
@Test
void testMethodName_whenCondition_thenExpectedBehavior() {
// Arrange
// Act
// Assert
}Kotlin:
@Test
fun `method name - when condition - then expected behavior`() {
// Arrange
// Act
// Assert
}Swift:
func testMethodName_whenCondition_thenExpectedBehavior() {
// Arrange
// Act
// Assert
}No magic numbers; use named constants:
Java:
private static final int DEFAULT_HTTP_TIMEOUT_SECONDS = 30;
private static final long CACHE_TTL_SECONDS = 300;
private static final int MAX_RETRIES = 3;Swift:
private let defaultHttpTimeout: TimeInterval = 30
private let cacheTTL: TimeInterval = 300
private let maxRetries = 3Use constants and platform-appropriate path handling:
Java:
private static final Path CONFIG_DIR = Paths.get(System.getProperty("user.home"), ".flossware", "nexus");
private static final Path CONFIG_FILE = CONFIG_DIR.resolve("nexus.properties");Swift:
private let configDir = FileManager.default.homeDirectoryForCurrentUser
.appendingPathComponent(".flossware")
.appendingPathComponent("nexus")User-facing: Simple, actionable
throw new IllegalStateException("Nexus URL not configured. Set NEXUS_URL environment variable or create ~/.flossware/nexus/nexus.properties");Developer-facing: Include context
throw new IOException("Failed to fetch components from repository '" + repository + "': HTTP " + statusCode);-
Add field to SearchCriteria (jnexus-core/SearchCriteria.java):
private final String newFilter;
-
Update Builder:
public Builder newFilter(String newFilter) { this.newFilter = newFilter; return this; }
-
Update NexusService.searchComponents():
if (criteria.getNewFilter() != null) { components = components.stream() .filter(c -> c.someField().matches(criteria.getNewFilter())) .collect(Collectors.toList()); }
-
Add tests:
@Test void testSearchComponents_withNewFilter() { // Test implementation }
-
Update platform-specific UIs:
- Desktop: Add field to Swing/AWT/Terminal/CLI
- Android: Add field to SearchScreen.kt
- iOS: Add field to SearchView.swift
-
Update documentation: README.md, CHANGELOG.md
-
Create command class in JNexus.java:
@Command(name = "newcmd", description = "New command description") static class NewCommand implements Callable<Integer> { @ParentCommand private JNexus parent; @Option(names = {"-o", "--option"}, description = "Option description") private String option; @Override public Integer call() throws Exception { // Implementation return 0; } }
-
Add to subcommands:
@Command(subcommands = { ListCommand.class, DeleteCommand.class, StatsCommand.class, NewCommand.class // Add here })
-
Add business logic to NexusService.java:
public void newCommandOperation(String param) { // Implementation }
-
Add tests in NexusServiceTest.java
-
Update documentation: README.md, CHANGELOG.md
-
Create new Composable in ui/screens/:
@Composable fun NewScreen( appState: AppState = LocalAppState.current ) { Scaffold( topBar = { /* TopAppBar */ } ) { padding -> // Content } }
-
Add navigation in MainActivity.kt:
NavigationBar { NavigationBarItem( icon = { Icon(Icons.Default.NewIcon, "New") }, label = { Text("New") }, selected = selectedTab == 4, onClick = { selectedTab = 4 } ) }
-
Test on different screen sizes (phone, tablet, landscape)
-
Update documentation: README.md, CHANGELOG.md
-
Add to interface (jnexus-core/Credentials.java):
String getNewFeature();
-
Implement in all platforms:
- Desktop: src/Credentials.java
- Android: jnexus-android/CredentialsAndroid.java
- iOS: jnexus-ios/Shared/Platform/CredentialsKeychain.swift
-
Add tests for each platform
-
Update UI to expose the feature (if user-configurable)
-
Update documentation: README.md, CHANGELOG.md
Remote Debugging:
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 \
-jar target/jnexus-1.0-jar-with-dependencies.jar list my-repoAttach from IDE: Connect to localhost:5005
Verbose Output:
System.out.println("DEBUG: fetching page with token: " + token);HTTP Request Inspection:
System.out.println("Request Headers: " + request.headers());
System.out.println("Response Body: " + response.body());Logcat Filtering:
adb logcat | grep JNexusLog Levels:
Log.d("JNexus", "Debug message");
Log.i("JNexus", "Info message");
Log.w("JNexus", "Warning message");
Log.e("JNexus", "Error message");HTTP Logging (OkHttp):
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
client = new OkHttpClient.Builder()
.addInterceptor(logging)
.build();Charles Proxy/Proxyman: Configure device proxy for HTTP inspection
Database Inspection:
adb shell
run-as com.flossware.jnexus
cat shared_prefs/nexus_credentials.xml # Encrypted, won't be readableConsole Output:
print("Debug: Fetching page with token: \(token ?? "nil")")Network Debugging:
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = ["X-Debug": "true"]Charles Proxy/Proxyman: Configure Mac proxy for HTTP inspection
Keychain Inspection:
# On macOS
open /Applications/Utilities/Keychain\ Access.app
# Search for service: com.flossware.jnexusSwiftUI View Debugging:
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.environmentObject(AppState())
}
}Instruments: Use for performance profiling (Xcode → Product → Profile)
See TEST_COVERAGE.md for comprehensive testing documentation.
Desktop:
./mvnw testAndroid Unit Tests:
gradle :jnexus-android:testDebugUnitTestAndroid Instrumented Tests:
gradle :jnexus-android:connectedDebugAndroidTestiOS/macOS:
xcodebuild test -scheme JNexus-iOS -destination 'platform=iOS Simulator,name=iPhone 15'
xcodebuild test -scheme JNexus-macOSDesktop (JaCoCo):
./mvnw test jacoco:report
open target/site/jacoco/index.htmlAndroid:
gradle :jnexus-android:testDebugUnitTestCoverage
open jnexus-android/build/reports/coverage/test/debug/index.htmlmain: Stable release branchdevelop: Integration branch (not currently used)- Feature branches:
feature/description - Bug fix branches:
bugfix/description - Release branches:
release/v1.2
Follow conventional commits format:
type(scope): subject
body (optional)
footer (optional)
Types:
feat: New featurefix: Bug fixdocs: Documentation onlystyle: Formatting, missing semicolons, etc.refactor: Code change that neither fixes a bug nor adds a featuretest: Adding missing testschore: Changes to build process or auxiliary tools
Examples:
feat(android): add search screen with advanced filters
Add SearchScreen.kt with collapsible filter panel for size range,
date range, file extension, and regex filters.
Closes #123
fix(desktop): correct cache expiration logic
Cache was not expiring after TTL due to incorrect timestamp comparison.
Changed to use Instant.now().isAfter(cacheTimestamp.plus(ttl)).
Fixes #456
- Create feature branch from main
- Implement changes with tests
- Update documentation (README.md, CHANGELOG.md, platform docs)
- Run tests locally
- Push to GitHub
- Create PR with description of changes
- Wait for CI to pass (GitHub Actions)
- Address review comments if any
- Squash and merge to main
PR Title Format:
[Platform] Brief description
Examples:
[Desktop] Add statistics command with JSON output
[Android] Implement credential encryption
[iOS] Add swipe-to-delete gesture
[All] Update to Java 21 and Swift 5.9
- Unit tests - Verify existing tests still pass, add new tests for new functionality
- Documentation - Update relevant docs:
- README.md for user-facing changes
- CLAUDE.md or platform-specific docs for architectural changes
- DEVELOPMENT_GUIDE.md for new development patterns
- Javadoc/KDoc/Swift comments for public API changes
- CHANGELOG.md - Add entry in "Unreleased" section
- Version numbers - Bump version if making a release (follow semantic versioning)
- Break backward compatibility without major version bump
- Add heavy frameworks (Spring, etc.) - keep dependencies minimal
- Commit credentials or sensitive data - use .gitignore
- Modify behavior without adding tests - maintain test coverage
- Push directly to main - use pull requests for code review
- Ignore CI failures - fix failing tests before merging
Follow SemVer 2.0.0:
- MAJOR (1.x.x): Incompatible API changes
- MINOR (x.1.x): Add functionality in backward-compatible manner
- PATCH (x.x.1): Backward-compatible bug fixes
Examples:
1.0.0→1.0.1: Fix cache expiration bug1.0.0→1.1.0: Add statistics command1.0.0→2.0.0: Change NexusHttpClient interface (breaking)
- Code follows project conventions
- No compiler warnings
- No magic numbers (use named constants)
- Error handling is appropriate
- No hardcoded credentials or sensitive data
- Documentation is updated
- Unit tests added for new functionality
- Unit tests pass locally
- Integration tests pass (if applicable)
- Edge cases are tested
- Test coverage maintained or improved
- README.md updated (if user-facing)
- CHANGELOG.md updated
- Platform-specific docs updated (if architectural)
- Javadoc/KDoc/Swift comments added (if public API)
- Code comments explain "why" not "what"
- No unnecessary object creation in loops
- Caching used appropriately
- Database/network calls minimized
- Memory leaks checked (Android/iOS)
- Input validation on user data
- No SQL injection vulnerabilities
- No XSS vulnerabilities
- Credentials stored securely
- HTTPS enforced for network calls
- Main Documentation
- Desktop Guide
- Android Guide
- iOS/macOS Guide
- Test Coverage
- CI/CD
- Security
- Contributing
- Nexus Repository REST API
- Picocli Documentation
- Jetpack Compose Docs
- SwiftUI Documentation
- OkHttp Documentation
- URLSession Documentation
Back to Main Documentation