惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
T
ThreatConnect
SecWiki News
SecWiki News
F
Future of Privacy Forum
AWS News Blog
AWS News Blog
C
Cisco Blogs
A
Arctic Wolf
Vercel News
Vercel News
The GitHub Blog
The GitHub Blog
Scott Helme
Scott Helme
V
V2EX
博客园 - 叶小钗
阮一峰的网络日志
阮一峰的网络日志
K
Kaspersky official blog
G
Google Developers Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
P
Privacy International News Feed
C
Cyber Attacks, Cyber Crime and Cyber Security
N
News | PayPal Newsroom
Schneier on Security
Schneier on Security
NISL@THU
NISL@THU
Microsoft Azure Blog
Microsoft Azure Blog
量子位
The Hacker News
The Hacker News
Stack Overflow Blog
Stack Overflow Blog
Security Latest
Security Latest
M
Microsoft Research Blog - Microsoft Research
Google Online Security Blog
Google Online Security Blog
博客园_首页
C
CXSECURITY Database RSS Feed - CXSecurity.com
I
InfoQ
Google DeepMind News
Google DeepMind News
Y
Y Combinator Blog
The Cloudflare Blog
Microsoft Security Blog
Microsoft Security Blog
Martin Fowler
Martin Fowler
Cisco Talos Blog
Cisco Talos Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Troy Hunt's Blog
F
Fox-IT International blog
S
Security @ Cisco Blogs
博客园 - 司徒正美
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
C
Comments on: Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
L
LINUX DO - 最新话题
GbyAI
GbyAI
Project Zero
Project Zero
腾讯CDC
T
Tailwind CSS Blog

Hacker News: Show HN

GitHub - rednakta/nilbox: Desktop sandbox for AI agents and MCP servers — with Zero Token Architecture so your API keys never touch the agent. GitHub - Dogacel/auto-gpu-kernel: Winner 🏆 (Agent-only) MLSys 2026 - FlashInfer AI Kernel Generation Contest for the DeepSeek Sparse Attention (DSA) track with an average speedup of 34.93x GitHub - p-raj/collab-sqlc: Self-hosted collaborative SQL editor for teams Lily Design System Show HN: AgentToolBench-Code – security benchmark for AI coding agents GitHub - redraw/rapel: chunked resumable downloads in unstable networks GitHub - lucasfrederico/pgcraft: lazygit-style TUI for Postgres. Navigate schemas, run queries, view explain plans — without leaving the terminal. 将 Notion 页面嵌入您的网站 | 免费试用! Show HN: Aigis – 43% of MCP servers have injection payloads; I built a firewall Audio to Video Converter AI Online Free GitHub - ClickHouse/nerve GitHub - highpost/tailscale-macos-vm: Using Tailscale with an OrbStack VM on macOS Show HN: OpenBrief – Local-first video downloader/summarizer Artifice Software | Synonym and Antonym Game GitHub - tomfunk/fungible: Terminal UI for personal finance — Plaid sync, CSV import, AI assistant, and MCP server Show HN: Unsiloed AI – #1 on OlmOCR-Bench,Beats Reducto, LlamaParse and GPT-5.5 Show HN: AI skills for program / project / delivery managers The Grid: The Largest Machine Ever Built | The Stepchange Show GerbDiff — Local-First Gerber Diff Tool for PCB Engineers Show HN: Built a tool to create brand-consistent images using AI GitHub - ndom91/macos-random-jellyfin-screensaver: Play a random Jellyfin item as your screensaver Bae — the AI companion who actually knows you Open Source Social Media Scheduler — TryPost GCal Sidebar Custom New Tab Dashboard with 50+ Widgets — Start Page HQ iPhone 版“Today” - App Store GitHub - ystepanoff/awo: AWO — Agent Worktree Orchestrator: a local Go CLI that coordinates Claude Code and Codex across isolated git worktrees with deterministic verification. HypeCheck — Is Your Supplement Legit or Just Hype? GitHub - rjpruitt16/aquifer: API Aqueduct — self-hosted request queue for inbound and outbound rate control GitHub - yamafaktory/hypergraph: Hypergraph is a data structure library to create a directed hypergraph in which a hyperedge can join any number of vertices. Show HN: YourMemory, persistent memory layer with temporal reasoning for agents CloudPostOffice — Simplest way to send and receive messages UUTA — A calm notebook for showing up AI API Pricing Calculator — Compare Costs Across Providers GitHub - scosman/cursed_browser: True AI-Native Browser — a VLM reads the HTML and hallucinates the page. Linear Chess Show HN: Browser-based Glider Sim Next Train GitHub - xfoa/Impatience: A library for instrumentation of event-to-event latency over a network GitHub - bitomule/musts: The validation loop that stops AI coding agents from claiming work is done before it actually is. Feynman - AI research assistant SynapCores — the AI-native database GitHub - erikshelley/complete-family-tree-viewer: A webpage for viewing all of a person's family tree at once GitHub - Noumenon-ai/AutoMaxFix: Controlled AI repair loop. Audit → Reproduce → Patch → Test → Report. Safety boundaries most AI agents skip. GitHub - JosephRedfern/plonk: Python interpreter at your fingertips Open Satchel — A free local-first PDF editor. Show HN: Hackobar – One feed for AI news GitHub - ghostchat-dev/widget: ~10KB chat widget. Zero cookies. Zero tracking. Fully open source. tiltbump X posts as clean Markdown for LLMs Symbol Combos — Cute Symbols, Kaomoji & Aesthetic Emojis to Copy GitHub - SellswordSoftware/justbookmarks: A simple desktop bookmark manager that uses the Netscape Bookmark HTML format so you can keep one browser-independent source of truth. SailWP. WordPress without the weight. Show HN: Widget Cast – Video Widgets for iOS PhoneDiffusion App - App Store Show HN: NanoApps: Run custom homebrew apps on iPod nano 7th generation Breadboard Knockout GitHub - elixir-volt/volt: Elixir-native frontend build tool — dev server, HMR, and production builds for JavaScript, TypeScript, Vue SFCs, and CSS. No Node.js required. Show HN: GuideOS – A radar-first, off-grid navigation kernel for edge robotics State lives on disk, not in chat Show HN: My biggest solo-project: Game engine with its own programming language MarketChacha | Stock Trading Community for Real Market Discussion GitHub - dmitryAQA/playwright-bdr-template Kubernetes, explained — interactive walkthroughs Show HN: Proj – organize your coding projects with categories and one-key CD Show HN: I made a compiler/VM for untrusted scripts Show HN: Stumpy – StumbleUpon Re-Created Show HN: Reward Is Not Reinforcement Until Admitted GitHub - dominikhei/cardamon: Cardamon is a cleanup tool for Prometheus that collects unused metrics from Grafana and Prometheus and generates drop statements for them. GitHub - NavodPeiris/grizzlars: High-performance DataFrame library written in C++ with Python bindings. Peakedin - LinkedIn's finest moments, curated weekly Planetensuche GitHub - cnemri/awesome-gemini-omni: A curated list of awesome Google Gemini Omni prompt guides, interactive platforms, and creative showcases. Show HN: An open-source, interactive AI engineering syllabus (1,100 papers) Show HN: I Built a Debugging Challenge for the AI Coding Age HTML Deployer: 1-Click AI Code To Website Publisher - Chrome 应用商店 GitHub - alkait/WhatsKept: Searchable, agent-queryable WhatsApp history from an iOS backup — a single Go binary. Geomatic | Tiny Volt Show HN: SenseCollect – Web data extraction made simple GitHub - feers77/iasql: A new implementation of SQL for IA purposes, using postgresSQL and Karpathy wiki-llm as inspiration. Kubernetes Study Path — From kubectl to a Production Cluster GitHub - octelium/cordium: Open-source sandbox platform with identity-based secretless infrastructure access for developers and AI agents on Kubernetes Play Doom with friends in your browser. You decide when you receive ForwardPass! (experimental) GitHub - jacksonsolid/Bytery fx.leftium.com GitHub - skorotkiewicz/cadence: $$hi Small marker tracking for source files. GitHub - nikitph/yieldos Show HN: Live AI music sequencing agent SaveNeighbor | Local help from people you trust drea: podcast ad blocker App - App Store JS Crossword GitHub - jake-stewart/tuie: A rich, performant TUI library for Rust. GitHub - AlexWasHeree/NoteCast: Local note engine that uses LLM to build and evolve a knowledge graph stocks.sjer.red — long PC parts RocketGraph — Never look at logs again Show HN: Replacing a 3.4MB video with 40kb of GSAP Show HN: Lightweight, OpenSource, zero-dependency App tour & user onboarding SDK Treasury — Personal Finance App | AI Insights & Budgeting
GitHub - cthing/versionparser: Parses versions in a wide range of formats and provides a canonical, comparable version object.
baron1405 · 2026-05-26 · via Hacker News: Show HN

CI Maven Central Version javadoc

A Java library for parsing and working with versioning schemes. Features include:

  • Support for many common versioning schemes
  • Version ordering
  • Access to version components
  • Version constraint operations (e.g. membership, intersection)

The following versioning schemes are supported:

Usage

See the examples folder for complete working code demonstrating the usage of this library. The library is available from Maven Central using the following Maven dependency:

<dependency>
  <groupId>org.cthing</groupId>
  <artifactId>versionparser</artifactId>
  <version>5.2.0</version>
</dependency>

or the following Gradle dependency:

implementation("org.cthing:versionparser:5.2.0")

Versioning Overview

Scheme Version Factory Version Constraint Factory
Calendar CalendarVersionScheme.parse(String)1 N/A
Debian DebVersionScheme.parseVersion(String) DebVersionScheme.parseConstraint(String)
Gradle GradleVersionScheme.parseVersion(String) GradleVersionScheme.parseConstraint(String)
Java JavaVersionScheme.parseVersion(String) JavaVersionScheme.parseRange(String)
Maven MvnVersionScheme.parseVersion(String) MvnVersionScheme.parseConstraint(String)
Npm NpmVersionScheme.parseVersion(String) NpmVersionScheme.parseConstraint(String)
PyPA PypaVersionScheme.parseVersion(String) PypaVersionScheme.parseConstraint(String)
PypaVersionScheme.parseSpecifier(String)2
RubyGems GemVersionScheme.parseVersion(String) GemVersionScheme.parseConstraint(String)
Semantic SemanticVersion.parseVersion(String) N/A

1 A CalendarVersionScheme instance must be created to define the version format. Call the parse method on that instance to create a version instance.

2 The PypaVersionScheme.parseSpecifier(String) method is only required if the arbitrary equality specifier (===V) must be supported.

All version factories create an instance of a scheme-specific version class (e.g. MvnVersion) that implements the Version interface. All version constraint factories create an instance of the VersionConstraint class. A VersionConstraint class consists of one or more VersionRange instances. If desired, both the VersionConstraint and VersionRange classes can be directly constructed. Do not mix version schemes (e.g. do not use Maven version instances to create NPM version constraints).

Maven Versioning

Support is provided for parsing Maven style dependency versions and dependency version constraints.

// Parse versions
final MvnVersion version1 = MvnVersionScheme.parseVersion("1.2.3");
final Version version2 = MvnVersionScheme.parseVersion("2.0.7");

// Obtain information from the parsed version
assertThat(version1.getOriginalVersion()).isEqualTo("1.2.3");
assertThat(version1.isPreRelease()).isFalse();
assertThat(version1.getComponents()).containsExactly("1", "2", "3");

// Verify ordering
assertThat(version1.compareTo(version2)).isEqualTo(-1);

// Parse version constraints
final VersionConstraint constraint1 = MvnVersionScheme.parseConstraint("[1.0.0,2.0.0)");
final VersionConstraint constraint2 = MvnVersionScheme.parseConstraint("[1.5.0,3.0.0)");

// Perform constraint checking
assertThat(constraint1.allows(version1)).isTrue();
assertThat(constraint1.allows(version2)).isFalse();

// Perform constraint set operations
assertThat(constraint1.intersect(constraint2)).isEqualTo(MvnVersionScheme.parseConstraint("[1.5.0,2.0.0)"));
assertThat(constraint1.union(constraint2)).isEqualTo(MvnVersionScheme.parseConstraint("[1.0.0,3.0.0)"));

Gradle Versioning

Support is provided for parsing Gradle style dependency versions and ranges.

// Parse versions
final GradleVersion version1 = GradleVersionScheme.parseVersion("1.2.3-SNAPSHOT");
final Version version2 = GradleVersionScheme.parseVersion("2.0.7");

// Obtain information from the parsed version
assertThat(version1.getOriginalVersion()).isEqualTo("1.2.3-SNAPSHOT");
assertThat(version1.isPreRelease()).isTrue();
assertThat(version1.getComponents()).containsExactly("1", "2", "3", "SNAPSHOT");

// Verify ordering
assertThat(version1.compareTo(version2)).isEqualTo(-1);

// Parse version constraints
final VersionConstraint constraint1 = GradleVersionScheme.parseConstraint("[1.0.0,2.0.0[");
final VersionConstraint constraint2 = GradleVersionScheme.parseConstraint("[1.5.0,2.+]");

// Perform constraint checking
assertThat(constraint1.allows(version1)).isTrue();
assertThat(constraint1.allows(version2)).isFalse();

// Perform constraint set operations
assertThat(constraint1.intersect(constraint2)).isEqualTo(GradleVersionScheme.parseConstraint("[1.5.0,2.+]"));
assertThat(constraint1.union(constraint2)).isEqualTo(GradleVersionScheme.parseConstraint("[1.0.0,2.0.0)"));

Java Versioning

Support is provided for parsing versions of the Java programming language and creating constraints based on those versions. During its long history, Java has used different versioning schemes (e.g. 1.4.2_151, 17.0.12+34). This library can accommodate all of them.

// Parse versions
final JavaVersion version1 = JavaVersionScheme.parseVersion("17.0.11+9");
final Version version2 = JavaVersionScheme.parseVersion("1.4.2_151");

// Obtain information from the parsed version
assertThat(version1.getOriginalVersion()).isEqualTo("17.0.11+9");
assertThat(version1.isPreRelease()).isFalse();
assertThat(version1.getFeature()).isEqualTo(17);
assertThat(version1.getInterim()).isEqualTo(0);
assertThat(version1.getUpdate()).isEqualTo(11);
assertThat(version1.getBuild()).contains(9);

// Verify ordering
assertThat(version1.compareTo(version2)).isEqualTo(1);

// Parse version constraints
final VersionConstraint constraint1 = GradleVersionScheme.parseConstraint("[11,21)");
final VersionConstraint constraint2 = GradleVersionScheme.parseConstraint("[1.5,1.7]");

// Perform constraint checking
assertThat(constraint1.allows(version1)).isTrue();
assertThat(constraint1.allows(version2)).isFalse();

// Perform constraint set operations
assertThat(constraint1.union(constraint2)).isEqualTo(GradleVersionScheme.parseConstraint("[1.5,1.7],[11,21)"));

// Test current runtime Java version
assertThat(JavaVersionScheme.isVersion(JavaVersionScheme.JAVA_17, JavaVersion.RUNTIME_VERSION)).isTrue();

// Test a Java version is greater than or equal to Java 17
assertThat(JavaVersionScheme.isVersion(JavaVersionScheme.JAVA_17_PLUS, "21")).isTrue();

NPM Versioning

Support is provided for parsing semantic versions and NPM style dependency version ranges.

// Parse versions
final SemanticVersion version1 = NpmVersionScheme.parseVersion("1.2.3");
final Version version2 = NpmVersionScheme.parseVersion("2.0.7");

// Obtain information from the parsed version
assertThat(version1.getOriginalVersion()).isEqualTo("1.2.3");
assertThat(version1.isPreRelease()).isFalse();
assertThat(version1.getMajor()).isEqualTo(1);
assertThat(version1.getMinor()).isEqualTo(2);
assertThat(version1.getPatch()).isEqualTo(3);

// Verify ordering
assertThat(version1.compareTo(version2)).isEqualTo(-1);

// Parse version constraints
final VersionConstraint constraint1 = NpmVersionScheme.parseConstraint("^1.0.0");
final VersionConstraint constraint2 = NpmVersionScheme.parseConstraint(">=1.5.0 <3.0.0");

// Perform constraint checking
assertThat(constraint1.allows(version1)).isTrue();
assertThat(constraint1.allows(version2)).isFalse();

// Perform constraint set operations
assertThat(constraint1.intersect(constraint2)).isEqualTo(NpmVersionScheme.parseConstraint(">=1.5.0 <2.0.0-0"));
assertThat(constraint1.union(constraint2)).isEqualTo(NpmVersionScheme.parseConstraint(">=1.0.0 <3.0.0"));

Python Packaging Authority Versioning

Support is provided for parsing Python Packaging Authority (PyPA) compliant versions and version specifiers.

// Parse versions
final PypaVersion version1 = PypaVersionScheme.parseVersion("1.2.3rc1");
final Version version2 = PypaVersionScheme.parseVersion("2.0.7");

// Obtain information from the parsed version
assertThat(version1.getOriginalVersion()).isEqualTo("1.2.3rc1");
assertThat(version1.getEpoch()).isEqualTo(0);
assertThat(version1.getRelease()).containsExactly(1, 2, 3);
assertThat(version1.getPrePhase()).contains(PypaVersion.PrePhase.rc);
assertThat(version1.getPre()).contains(1);
assertThat(version1.getPost()).isEmpty();
assertThat(version1.getDev()).isEmpty();
assertThat(version1.getLocal()).isEmpty();
assertThat(version1.isPreRelease()).isTrue();
assertThat(version1.isPostRelease()).isFalse();
assertThat(version1.isDevRelease()).isFalse();

// Verify ordering
assertThat(version1.compareTo(version2)).isEqualTo(-1);

// Perform specifier checking
final PypaSpecifierSet specifier1 = PypaVersionScheme.parseSpecifier("<2.0.0");
final PypaSpecifierSet specifier2 = PypaVersionScheme.parseSpecifier(">2.0,<3.0");
assertThat(specifier1.allows(version1)).isTrue();
assertThat(specifier2.allows(version1)).isFalse();

// Perform constraint checking
final VersionConstraint constraint1 = PypaVersionScheme.parseConstraint("<2.0.0");
final VersionConstraint constraint2 = PypaVersionScheme.parseConstraint(">2.0,>3.0");
assertThat(constraint1.allows(version1)).isTrue();
assertThat(constraint1.allows(version2)).isFalse();
assertThat(constraint2.allows(version1)).isFalse();
assertThat(constraint2.allows(version2)).isTrue();

RubyGems Versioning

Support is provided for parsing RubyGems style versions and dependency version requirements.

// Parse versions
final GemVersion version1 = GemVersionScheme.parseVersion("1.2.3");
final Version version2 = GemVersionScheme.parseVersion("2.0.7");

// Obtain information from the parsed version
assertThat(version1.getOriginalVersion()).isEqualTo("1.2.3");
assertThat(version1.isPreRelease()).isFalse();
assertThat(version1.getComponents()).containsExactly("1", "2", "3");

// Verify ordering
assertThat(version1.compareTo(version2)).isEqualTo(-1);

// Parse version constraints
final VersionConstraint constraint1 = GemVersionScheme.parseConstraint("~>1.0");
final VersionConstraint constraint2 = GemVersionScheme.parseConstraint(">=1.5.0", "<3.0.0");

// Perform constraint checking
assertThat(constraint1.allows(version1)).isTrue();
assertThat(constraint1.allows(version2)).isFalse();

// Perform constraint set operations
assertThat(constraint1.intersect(constraint2)).isEqualTo(GemVersionScheme.parseConstraint(">=1.5.0", "<2.ZZZ"));
assertThat(constraint1.union(constraint2)).isEqualTo(GemVersionScheme.parseConstraint(">=1.0.0", "<3.0.0"));

Semantic Versioning

Support is provided for parsing semantic versions.

// Parse versions
final SemanticVersion version1 = NpmVersionScheme.parseVersion("1.2.3");
final SemanticVersion version2 = NpmVersionScheme.parseVersion("2.0.7");

// Obtain information from the parsed version
assertThat(version1.getOriginalVersion()).isEqualTo("1.2.3");
assertThat(version1.isPreRelease()).isFalse();
assertThat(version1.getMajor()).isEqualTo(1);
assertThat(version1.getMinor()).isEqualTo(2);
assertThat(version1.getPatch()).isEqualTo(3);

// Verify ordering
assertThat(version1.compareTo(version2)).isEqualTo(-1);

Pre-release and build metadata is supported, and a "v" prefix is ignored.

final SemanticVersion version = SemanticVersion.parse("v1.2.3-beta.1+56709");
        
assertThat(version.getOriginalVersion()).isEqualTo("v1.2.3-beta.1+56709");
assertThat(version).hasToString("v1.2.3-beta.1+56709");
assertThat(version.getNormalizedVersion()).isEqualTo("1.2.3-beta.1+56709");
assertThat(version.getCoreVersion()).isEqualTo("1.2.3");
assertThat(version.isPreRelease()).isTrue();
assertThat(version.getMajor()).isEqualTo(1);
assertThat(version.getMinor()).isEqualTo(2);
assertThat(version.getPatch()).isEqualTo(3);
assertThat(version.getPreReleaseIdentifiers()).containsExactly("beta", "1");
assertThat(version.getBuild()).containsExactly("56709");

A convenience parsing method is provided for the common case of specifying a core version and a separate pre-release identifier.

final SemanticVersion version = SemanticVersion.parse("1.2.3", "beta.1");

assertThat(version.getOriginalVersion()).isEqualTo("1.2.3-beta.1");
assertThat(version).hasToString("1.2.3-beta.1");
assertThat(version.getNormalizedVersion()).isEqualTo("1.2.3-beta.1");
assertThat(version.getCoreVersion()).isEqualTo("1.2.3");
assertThat(version.isPreRelease()).isTrue();
assertThat(version.getMajor()).isEqualTo(1);
assertThat(version.getMinor()).isEqualTo(2);
assertThat(version.getPatch()).isEqualTo(3);
assertThat(version.getPreReleaseIdentifiers()).containsExactly("beta", "1");

Another convenience parsing method is provided to accommodate snapshot builds. This method takes a core version and a flag to indicate whether the version represents a snapshot. Snapshot versions are given a pre-release component which is the number of milliseconds since the Unix Epoch.

final SemanticVersion version1 = SemanticVersion("1.2.3", true);

assertThat(version1.getOriginalVersion()).isEqualTo("1.2.3-1717386681940");
assertThat(version1).hasToString("1.2.3-1717386681940");
assertThat(version1.getNormalizedVersion()).isEqualTo("1.2.3-1717386681940");
assertThat(version1.getCoreVersion()).isEqualTo("1.2.3");
assertThat(version1.isPreRelease()).isTrue();
assertThat(version1.getMajor()).isEqualTo(1);
assertThat(version1.getMinor()).isEqualTo(2);
assertThat(version1.getPatch()).isEqualTo(3);
assertThat(version1.getPreReleaseIdentifiers()).containsExactly("1717386681940");

final SemanticVersion version2 = SemanticVersion("1.2.3", false);

assertThat(version2.getOriginalVersion()).isEqualTo("1.2.3");
assertThat(version2).hasToString("1.2.3");
assertThat(version2.getNormalizedVersion()).isEqualTo("1.2.3");
assertThat(version2.getCoreVersion()).isEqualTo("1.2.3");
assertThat(version2.isPreRelease()).isFalse();
assertThat(version2.getMajor()).isEqualTo(1);
assertThat(version2.getMinor()).isEqualTo(2);
assertThat(version2.getPatch()).isEqualTo(3);
assertThat(version2.getPreReleaseIdentifiers()).isEmpty();

Calendar Versioning

Support is provided for parsing calendar versions.

// Parse a single version
final CalendarVersion version1 = CalendarVersionScheme.parse("YYYY.MM.0D-MAJOR", "2023.2.03-4");

// Parse multiple versions using the same format
final CalendarVersionScheme scheme = new CalendarVersionScheme("yyyy.major.minor");
final Version version2 = scheme.parse("2022.1.0");
final Version version3 = scheme.parse("2022.1.1");

// Obtain information from the parsed version
assertThat(version1.getOriginalVersion()).isEqualTo("2023.2.03-4");
assertThat(version1.isPreRelease()).isFalse();

// Obtain information about the first component of the version
final Component component1 = version1.getComponents().get(0);
assertThat(component1.getValueStr()).isEqualTo("2023");
assertThat(component1.getValue()).isEqualTo(2023);
assertThat(component1.getCategory()).isEqualTo(ComponentCategory.YEAR);

// Verify ordering
assertThat(version2.compareTo(version3)).isEqualTo(-1);

Debian Package Versioning

Support is provided for parsing Debian package versions and version constraints.

// Parse versions
final DebVersion version1 = DebVersionScheme.parseVersion("22.07.5-2ubuntu1.5");
final Version version2 = DebVersionScheme.parseVersion("20.01.2-1ubuntu1.5");

// Obtain information from the parsed version
assertThat(version1.getOriginalVersion()).isEqualTo("22.07.5-2ubuntu1.5");
assertThat(version1.isPreRelease()).isFalse();
assertThat(version1.getEpoch()).isEqualTo(0);
assertThat(version1.getUpstream()).isEqualTo("22.07.5");
assertThat(version1.getRevision()).isEqualTo("2ubuntu1.5");

// Verify ordering
assertThat(version1.compareTo(version2)).isEqualTo(1);

// Parse version constraints
final VersionConstraint constraint1 = DebVersionScheme.parseConstraint(">20");
final VersionConstraint constraint2 = DebVersionScheme.parseConstraint(">21 <=23");

// Perform constraint checking
assertThat(constraint1.allows(version2)).isTrue();
assertThat(constraint2.allows(version1)).isTrue();
assertThat(constraint2.allows(version2)).isFalse();

Additional Information

In preparation for creating this library, a survey of many popular versioning schemes was conducted. Among other things, this lead to the recognition that most version constraint specifications could be expressed using a single notation. This in turn allows version constraints to be handled in a version scheme independent manner. To work with a constraint, the only requirement of a version is that it be ordered. Note that one exception to this is the Python Packaging Authority (PyPA) arbitrary equality version specifier (===V), whose use is heavily discouraged by the PyPA. Parsing this specifier requires the use of the PypaVersionScheme.parseSpecifier(String) method and the PypaSpecifierSet class.

Building

The library is compiled for Java 17. If a Java 17 toolchain is not available, one will be downloaded.

Gradle is used to build the library:

./gradlew build

The Javadoc for the library can be generated by running:

./gradlew javadoc

Releasing

This project is released on the Maven Central repository. Perform the following steps to create a release.

  • Commit all changes for the release
  • In the build.gradle.kts file, edit the ProjectVersion object
    • Set the version for the release. The project follows semantic versioning.
    • Set the build type to BuildType.release
  • Commit the changes
  • Wait until CI builds the release candidate
  • Run the command mkrelease versionparser <version>
  • In a browser go to the Maven Central Repository
  • Log in
  • Select Publish from the menubar
  • Press Publish Component
  • Enter a name for the deployment
  • Choose the file versionparser-bundle-<version>.zip
  • Press Publish Component
  • Refresh the page until the deployment has been validated
  • Press Publish
  • Refresh the page until the status is Published
  • Log out
  • Delete the file versionparser-bundle-<version>.zip
  • In a browser, go to the project on GitHub
  • Generate a release with the tag <version>
  • In the build.gradle.kts file, edit the ProjectVersion object
    • Increment the version patch number
    • Set the build type to BuildType.snapshot
  • Update the CHANGELOG.md with the changes in the release and prepare for next release changes
  • Update the Usage section in the README.md with the latest artifact release version
  • Commit these changes