1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
//! Version resolution and dependency propagation module.
//!
//! **What**: Provides comprehensive version management for Node.js packages, including version
//! resolution, dependency propagation, snapshot version generation, and version application with
//! support for both independent and unified versioning strategies.
//!
//! **How**: This module analyzes package dependencies, builds a dependency graph, resolves version
//! conflicts, propagates version changes through dependent packages, and applies versions to
//! package.json files. It supports dry-run mode for previewing changes before applying them.
//!
//! **Why**: To automate complex version management in monorepos and single-package projects,
//! ensuring that version changes are correctly propagated through the dependency graph while
//! avoiding circular dependencies and version conflicts.
//!
//! # Features
//!
//! - **Version Resolution**: Calculate next versions for packages based on changesets
//! - **Dependency Propagation**: Automatically update dependent packages when dependencies change
//! - **Versioning Strategies**: Support independent and unified versioning approaches
//! - **Circular Dependency Detection**: Detect and report circular dependencies
//! - **Snapshot Versions**: Generate snapshot versions for pre-release testing
//! - **Dry-Run Mode**: Preview version changes without modifying files
//! - **Version Spec Management**: Handle workspace:, file:, link:, and portal: protocols
//! - **Monorepo Support**: Handle both monorepo and single-package configurations
//!
//! # Versioning Strategies
//!
//! ## Independent Strategy
//!
//! Each package maintains its own version, incremented only when that specific package changes.
//! This is the default and most flexible strategy.
//!
//! ## Unified Strategy
//!
//! All packages share the same version number and are incremented together, even if only
//! one package changes. This is simpler but may result in more version bumps.
//!
//! # Example
//!
//! ```rust,ignore
//! use sublime_pkg_tools::version::{VersionResolver, VersioningStrategy};
//! use sublime_pkg_tools::types::{Changeset, VersionBump};
//! use sublime_pkg_tools::config::PackageToolsConfig;
//! use sublime_standard_tools::filesystem::FileSystemManager;
//! use std::path::PathBuf;
//!
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
//! let workspace_root = PathBuf::from(".");
//! let fs = FileSystemManager::new();
//! let config = PackageToolsConfig::default();
//!
//! // Story 5.1 - Create resolver (implemented)
//! let resolver = VersionResolver::new(workspace_root, config).await?;
//!
//! // Create a changeset
//! let mut changeset = Changeset::new("main", VersionBump::Minor, vec!["production".to_string()]);
//! changeset.add_package("my-package");
//!
//! // Story 5.4 - Resolve versions (implemented)
//! let resolution = resolver.resolve_versions(&changeset).await?;
//! for update in &resolution.updates {
//! println!("{}: {} -> {}", update.name, update.current_version, update.next_version);
//! }
//!
//! // Story 5.7 - Apply versions (implemented)
//! let result = resolver.apply_versions(&changeset, false).await?;
//! println!("Updated {} packages", result.resolution.updates.len());
//! # Ok(())
//! # }
//! ```
//!
//! # Dependency Propagation
//!
//! When a package's version changes, all packages that depend on it are also updated:
//!
//! ```rust,ignore
//! use sublime_pkg_tools::version::VersionResolver;
//! use sublime_pkg_tools::types::Changeset;
//!
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
//! # let resolver: VersionResolver = todo!();
//! # let changeset: Changeset = todo!();
//! // Story 5.4 - Version resolution works
//! let resolution = resolver.resolve_versions(&changeset).await?;
//!
//! for update in &resolution.updates {
//! println!("Package: {}", update.name);
//! println!(" Version: {} -> {}", update.current_version, update.next_version);
//!
//! // Story 5.5 - Dependency propagation is now implemented
//! if !update.dependency_updates.is_empty() {
//! println!(" Dependency updates:");
//! for dep in &update.dependency_updates {
//! println!(" {}: {} -> {}",
//! dep.dependency_name,
//! dep.old_version_spec,
//! dep.new_version_spec
//! );
//! }
//! }
//! }
//! # Ok(())
//! # }
//! ```
//!
//! # Snapshot Versions
//!
//! Generate snapshot versions for testing:
//!
//! ```rust,ignore
//! use sublime_pkg_tools::version::{SnapshotGenerator, SnapshotContext};
//! use sublime_pkg_tools::types::Version;
//!
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
//! // Story 5.6 - Snapshot versions (implemented)
//! // Create a generator with a format template
//! let generator = SnapshotGenerator::new("{version}-{branch}.{commit}")?;
//!
//! // Create context with version and git information
//! let context = SnapshotContext {
//! version: Version::parse("1.2.3")?,
//! branch: "feat/oauth".to_string(),
//! commit: "abc123def456",
//! timestamp: 1640000000,
//! };
//!
//! // Generate snapshot version
//! let snapshot = generator.generate(&context)?;
//! // Output: 1.2.3-feat-oauth.abc123d
//! # Ok(())
//! # }
//! ```
//!
//! # Circular Dependency Detection
//!
//! Detect circular dependencies in the dependency graph:
//!
//! ```rust,ignore
//! use sublime_pkg_tools::version::VersionResolver;
//!
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
//! # let resolver: VersionResolver = todo!();
//! # let changeset: Changeset = todo!();
//! // Story 5.3 & 5.4 - Circular dependency detection (implemented)
//! let resolution = resolver.resolve_versions(&changeset).await?;
//!
//! if !resolution.circular_dependencies.is_empty() {
//! println!("Warning: Circular dependencies detected!");
//! for circular in &resolution.circular_dependencies {
//! println!(" Cycle: {:?}", circular.cycle);
//! }
//! }
//! # Ok(())
//! # }
//! ```
//!
//! # Configuration
//!
//! Configure version resolution behavior:
//!
//! ```toml
//! [package_tools.version]
//! strategy = "independent"
//! default_bump = "patch"
//! snapshot_format = "{version}-{branch}.{timestamp}"
//!
//! [package_tools.dependency]
//! propagation_bump = "patch"
//! propagate_dependencies = true
//! propagate_dev_dependencies = false
//! propagate_peer_dependencies = true
//! max_depth = 10
//! fail_on_circular = true
//! skip_workspace_protocol = true
//! skip_file_protocol = true
//! skip_link_protocol = true
//! skip_portal_protocol = true
//! ```
//!
//! # Module Structure
//!
//! This module will contain:
//! - `resolver`: The main `VersionResolver` for orchestrating version operations
//! - `strategy`: Versioning strategy implementations (independent, unified)
//! - `graph`: Dependency graph construction and analysis
//! - `propagation`: Dependency propagation logic
//! - `resolution`: Version resolution results and types
//! - `snapshot`: Snapshot version generation
//! - `application`: Version application to package.json files
pub use ;
pub use DependencyGraph;
pub use DependencyPropagator;
pub use ;
pub use VersionResolver;
pub use ;