| Age | Commit message (Collapse) | Author |
|
|
|
Add an `IoInterface` trait in mozart-core::console that mirrors
`\Composer\IO\IOInterface`, implement it for `Console`, and switch
commands, the auditor, and the suggested-packages reporter to accept
the abstracted IO (typically `Arc<Mutex<Box<dyn IoInterface>>>` at the
command boundary, `&dyn IoInterface` deeper down) instead of
`&Console`. The console_writeln\!/write\! macros now go through
`IoInterface::verbosity()` via the lock so any implementor works.
|
|
Move AuditConfig, AuditFormat/AbandonedHandling enums, and stub types
(SecurityAdvisory, PartialSecurityAdvisory, IgnoredSecurityAdvisory)
into their own files under advisory/. Public API is preserved via
wildcard re-exports.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Mirrors Composer\Package\Loader\RootPackageLoader::load(): converts the
parsed RawPackageData into fully typed RootPackageData with Link objects,
defaulted fields, and trait-based accessors. Composer::package() now
returns RootPackageData instead of RawPackageData, eliminating the
pre-normalised JSON workaround noted in the previous comment.
|
|
Merged mozart-archiver, mozart-autoload, mozart-registry,
mozart-sat-resolver, and mozart-vcs into mozart-core to align
the source layout with Composer's structure.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- Rename `local_changes` → `get_local_changes` to match Composer's
`getLocalChanges`
- Add `is_change_report`, `is_vcs_capable_downloader`,
`is_dvcs_downloader` trait methods to replace PHP `instanceof` checks
- Add `VersionParser` stub to keep `VersionGuesser::new` signature
compatible with Composer's constructor
- Add `ArrayDumper` in status.rs mirroring
`Composer\Package\Dumper\ArrayDumper`; expand `build_package_config`
to include all fields that `VersionGuesser` inspects
|
|
Composer needs DownloadManager (from mozart-registry), but mozart-core
sits below mozart-registry in the dependency graph — adding the field
would create a dependency cycle. Moving Composer and create_composer to
the mozart CLI crate breaks the cycle and lets the root state container
hold a DownloadManager.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
module
Removes the per-command duplicate implementations of
get_platform_requirement_filter from dump_autoload and reinstall,
and lifts a single canonical version into commands.rs.
|
|
Replace `Option<String>` with `String` + `default_value = "text"` and
derive `Default` on `ShowArgs`, eliminating local `as_deref().unwrap_or`
bindings. outdated.rs switches to `..Default::default()` for the fields
it doesn't set.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Eliminate the nested &console_format!(...) boilerplate at every call site
by teaching console_writeln!, console_write!, console_writeln_error!, and
console_write_error! to accept a format literal + variadic args directly,
matching the println!/eprintln! ergonomics. Propagate the format string
span into generated code so rustc errors point to the right location.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
pipeline
- Rename ChangeKind::Remove → Uninstall, drop Unchanged variant (propagate
to remove.rs / require.rs); mirrors Composer's UninstallOperation naming
- Fix magic-keyword mirrors detection: use Composer's count-diff semantic
(any keyword triggers mirrors mode) instead of all-are-magic; mutex check
now fires correctly for mixed lists like `update foo lock`
- Add --patch-only pre-solve lock-presence check (previously missing;
Composer throws InvalidArgumentException when no lock exists)
- Add --patch-only pre-solve constraint injection: inject >=M.N.P.0,<M.(N+1).0.0
into temporary_constraints before the resolver runs, mirroring
UpdateCommand::execute 177-195
- Delegate --bump-after-update to bump::do_bump (mirrors Composer's
BumpCommand::doBump delegate); add \!--lock guard per Composer 280-282
- Drop parse_minimum_stability wrapper; call package::Stability::parse directly
- Replace is_platform_dep with is_platform_package from mozart_core::platform
(the local variant was incomplete: missed hhvm and composer pseudo-packages)
- Wrap "Lock file operations" and "Writing lock file" in <info> tags
- Update --no-suggest deprecation wording to match Composer 3 message
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- A3: wire --major-only/--minor-only/--patch-only version constraint filtering
in fetch_latest_for_package (mirrors ShowCommand::findLatestPackage 1500-1515)
- A4: implement --sort-by-age ordering by release date
- A5: add abandoned-package warning after each list row
- A6: print color legend before list when --latest is on; ASCII markers
(\! ~ =) in non-decorated mode
- A7: split list into "Direct dependencies" / "Transitive dependencies"
sections when --latest && \!--direct (mirrors Composer 671-695)
- A8: replace local is_platform_package with mozart_core::platform::is_platform_package
- A9: emit --installed deprecation warning (mirrors Composer 143-145)
- A10: apply --strict exit-code check in both installed and locked paths
- A11: fetch and display latest: line in single-package detail view
- A12: add conflict/provide/replace link sections to detail view
- A13: add released/names/support/autoload fields to detail view
- A14: use "locked" JSON key for --locked output (was incorrectly "installed")
- A15: unify show_installed_package_detail + show_locked_package_detail into
a single PackageDetail struct + print_package_detail function
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
InstallCommand pipeline
- Match Composer's deprecation wording for --dev and --no-suggest (A1)
- Add missing URL to lock-fallback warning (A2)
- Reorder arg validation to match InstallCommand::execute order (A3)
- Rename collect_install_* helpers to verify_lock_* and consolidate
into a single verify_lock() entry point (A4)
- Couple classmap_authoritative=true → optimize_autoloader=true,
mirroring Composer's setter side-effects (Installer.php 1263-1272) (A5)
- Centralise is_platform_package in mozart_core::platform, removing
divergent local copies from install.rs and update.rs (A6)
- Move compute_operations, topological_sort, alias helpers, and
locked_to_installed_entry into mozart-registry::installer_executor::
transaction, re-exported from the parent module (A8)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- A1: stub auth keys (bitbucket-oauth.X etc.) with actionable error
- A2: audit.ignore / audit.ignore-abandoned writers with --json/--merge
- A3: scripts.X writer (scalar vs array) and --unset support
- A4: top-level --unset fallback for unknown single-segment keys
- A5: bare --unset extra / suggest / audit support
- A6/A13: disable-tls enable/disable user-visible messages
- A7: editor fallback chain (editor/vim/vi/nano/pico/ed)
- A8: --editor --auth opens auth.json
- A9: silent exit 0 when no setting-key and no --list
- A10: cache-files-maxsize regex validation
- A11: cafile/capath existence check + "null" clearing
- A14: merge_json_values object merge uses existing-wins (PHP `+`)
- A16: repositories.<name>.url sub-path support
- A17: wording "cannot" → "can not" to match Composer exactly
- A19: add_repository normalizes assoc repos, injects name field,
strips stale disable entries
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- Wire Composer::try_load_from_file so validate uses typed Config.lock
instead of a raw JSON read for the should-check-lock decision
- Surface LockFile::get_missing_requirement_info in check_lock_freshness,
mirroring Composer's locker->getMissingRequirementInfo call
- Replace inline per-dep error/warning printing with output_result calls
so each dependency gets the same header format as the root file
- Switch --with-dependencies to RepositoryManager + InstallationManager;
skip metapackages; fall back to vendor walk when Composer unavailable
- Move license wrong-type from warnings to errors (divergence #10),
matching ValidatingArrayLoader's classification
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Implement std::str::FromStr for AuditFormat and AbandonedHandling
instead of ad-hoc from_str methods (resolves should_implement_trait).
Group Auditor::audit() parameters into AuditOptions to resolve
too_many_arguments.
|
|
- Add mozart-registry::version_selector::VersionSelector mirroring
Composer\Package\Version\VersionSelector; wraps find_best_candidate
and find_recommended_require_version_string for per-arg resolution
- Decompose execute() into named helpers matching Composer's structure:
CommandState, revert_composer_file, get_inconsistent_require_keys,
get_packages_by_require_key, update_file, update_file_cleanly (stub
for PR 3), do_update, update_requirements_after_resolution (stub for PR 2)
- Fix firstRequire gating: compute first_require from the original file
before applying changes; apply setUpdateAllowList only when
!first_require and lock exists (prevents over-pinning on fresh projects)
- Add --fixed gate: bail when fixed && !dev && type != "project",
matching Composer L173-189 wording verbatim
- Wire --no-security-blocking + COMPOSER_NO_SECURITY_BLOCKING env var
into block_insecure in ResolveRequest (was always false)
- Wire COMPOSER_NO_AUDIT env var to skip audit step (tracked)
- Match Composer's revertComposerFile messaging: "deleting <file>" for
newly-created, "reverting <file> and <lock> to their" / "to its" for
existing files; also removes lock file on newly-created revert
- Auto-create "{\n}\n" when composer.json is missing or empty, mirroring
Composer L138-152; delete file on dry-run cleanup (finally block)
- Add resolution-failure hint: "You can also try re-running mozart
require with an explicit version constraint…" for unversioned packages
- Update deprecated-flag warnings to stderr (write_error) with
Composer-matching wording for --no-suggest
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- Add mozart-core::advisory::{AuditFormat, AbandonedHandling, AuditConfig}
mirroring Composer\Advisory\AuditConfig; reads audit.ignore,
audit.ignore-severity, audit.ignore-abandoned, audit.abandoned,
audit.block-insecure, audit.block-abandoned, audit.ignore-unreachable
from composer.json config with full apply-scope support
- Add mozart-registry::advisory::Auditor mirroring Composer\Advisory\Auditor;
process_advisories() filters by package name, advisory ID, CVE, source
remote ID, and severity; filter_abandoned_packages() respects ignore-abandoned
- Add RepositorySet::get_matching_security_advisories() wrapping
fetch_security_advisories with version-matching and unreachable-repo tracking
- JSON output now includes ignored-advisories and unreachable-repositories keys
- --abandoned falls back to audit.abandoned config (was hardcoded to "fail")
- --ignore-severity merges with audit.ignore-severity config
- --ignore-unreachable ORs with audit.ignore-unreachable config
- Move normalize_or_separator into repository/mod.rs alongside version matching
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Introduce JsonConfigSource in mozart-core mirroring Composer's
JsonConfigSource fallback logic (add/insert/set-url/remove repository),
and BaseConfigContext mirroring BaseConfigCommand's initialize().
Key behaviour fixes:
- list: synthesise [packagist.org] <disabled> only when no composer-type
repo with a packagist.org host is present (was: always show enabled default)
- disable: idempotent via add_repository(false) matching Composer's branch;
now requires a name (no silent default to packagist.org)
- enable: calls remove_repository only, no extra empty-array cleanup
- set-url: preserves assoc-keyed format instead of converting to list
- get-url: assoc fast-path + unquoted error message matching Composer
- add: use regex pre-check (starts_with '{') instead of trial-parse
- error messages reworded to match Composer verbatim (mozart brand kept)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- Match exact deprecation wording for --update-with-dependencies and
drop the false deprecation warning for -W/--update-with-all-dependencies
- Append --with-all-dependencies / --with-dependencies flag suffix to the
"Running composer update" echo (mirrors PHP's \$flags variable)
- Drop validate_package_name bail so glob-style names fall through to the
"not required in your composer.json" warning, matching Composer
- Always run the install pipeline after the JSON edit even when nothing
changed (removes the if !any_removed short-circuit)
- Capture composer_backup before any mutation and restore it on pipeline
failure with the "Removal failed, reverting" error message
- After install, read vendor/composer/installed.json and return exit 2
if any removed package is still present (mirrors Composer's local-repo
query at RemoveCommand.php L303-311)
- Fix remove_unused: bail with Composer's exact error when no lock file
present; use "No unused packages to remove" (no period) for empty case
- Rename raw -> composer, any_removed -> packages_removed to mirror PHP
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Extract script-event constants into mozart_core::script_events, fix
dev_mode to `--dev || \!--no-dev` (PHP wins-on---dev), route the --list
header to stderr with empty-list silent return, validate --timeout with
ctype_digit semantics, and reorder execute() so the cannot-be-run check
runs before requireComposer(). Drops the spurious --no-scripts
short-circuit (Composer honors that flag in the dispatcher, not the
command).
|
|
Mirror `CheckPlatformReqsCommand::execute` end-to-end: build an
`InstalledRepoLite` from lock/installed plus the root and the real
PlatformRepository, ksort the combined `$requires`, and run the
candidate matching loop with `findPackagesWithReplacersAndProviders`
so an installed package that `provide`s or `replace`s a platform name
(e.g. `symfony/polyfill-mbstring` providing `ext-mbstring`) is now
recognised as satisfying the requirement.
Fixes the JSON output schema to match Composer:
`failed_requirement` is the `{source, type, target, constraint}`
object (or null), `provider` is the bare "provided by …" string (or
null), and `status` is the unwrapped `success`/`failed`/`missing`.
Also switches `--format` to a clap `value_parser` and replaces the
"No installed packages found" hard error with Composer's warn-then-
proceed path so an empty lock yields `[]` and exit 0.
Adds `mozart_core::installer::InstalledCandidate` plus
`InstalledRepoLite::add_candidate` /
`find_with_replacers_and_providers` as the shared substrate for
future commands (`depends`, `prohibits`, `audit`) that need the same
provider/replacer index.
|
|
Port `Composer\Installer\SuggestedPackagesReporter` to
`mozart_core::installer` (modes, add_package, add_suggestions_from_package,
output, output_minimalistic, escape_output) and slim
`commands/suggests.rs` to mirror `SuggestsCommand::execute`. Defines
`HasSuggests`, `InstalledRepoLite`, `RootInfo` as the minimal stand-ins
for Composer's `PackageInterface` / `InstalledRepository` /
`onlyDependentsOf`.
Also fixes a latent bug where `provide`/`replace` virtuals were read
from `extra_fields` (always empty after a serde round-trip into
LockedPackage's typed fields) and moves the "additional suggestions
... --all" hint to fire after the rendered sections, matching
Composer's order.
|
|
Splits execute() into execute → do_bump → update_file_cleanly mirroring
Composer's structure, switches state loading to Composer::require, adds
the no-lock fallback to vendor/composer/installed.json, routes warnings
and errors through stderr, and matches Composer's wording verbatim.
JsonManipulator is deferred — update_file_cleanly always falls back to
a full structured rewrite for now, documented in known-incompatibilities.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|
Split the inline 370-line execute() into execute / install_project /
install_root_package, mirroring Composer's three-method shape and argument
order. Replace the bespoke caret/tilde/wildcard semver helpers with
mozart_semver::VersionConstraint, harden stability inference (handle the
@stability suffix and reject invalid values), and align user-facing wording
("Creating a ...", "Cannot create project directory ...", "Could not find
package ...") with Composer's strings. Add the --ask directory prompt, the
interactive VCS-removal prompt, the empty-target-directory bail, and the
COMPOSER_ROOT_VERSION / COMPOSER env-var handling that the PHP command does
after extraction.
Custom repositories, the canonical Installer pathway, the signal handler,
and script events are still deferred — see .ken/command_compat_plan/create_project.md.
|
|
Restructures diagnose to mirror Composer's 17-step DiagnoseCommand:
adds composer.json schema validation, custom composer-repo
connectivity, COMPOSER_IPRESOLVE warning, and the
checkConnectivityAndComposerNetworkHttpEnablement preflight; drops
Mozart-only extras (cache-dir, lock freshness, trailing summary).
Extracts the manifest validator into mozart-core::config_validator
so both ValidateCommand and DiagnoseCommand depend on the shared
module rather than each other -- the same shape Composer uses with
Util\\ConfigValidator. Adds a thin HttpDownloader wrapper in
mozart-core::http, shadowing Composer's Util\\HttpDownloader.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|
Composer's OutdatedCommand (isProxyCommand = true) just remaps options
and re-invokes `show --latest [--outdated]`; Mozart's outdated.rs was a
~700-line parallel reimplementation of show's outdated logic with its
own classifier, renderer, JSON shape, and platform predicate. Collapse
it into a thin proxy that builds a ShowArgs from OutdatedArgs and calls
show::execute, mirroring OutdatedCommand::execute field-for-field.
This restores show as the single source of truth for rendering, JSON
fields, --strict, and the mutual-exclusion checks. Surfaced gaps in
show.rs (--major-only/--minor-only/--patch-only filtering, --sort-by-age,
JSON enrichment with homepage/source/time/abandoned) are deferred per
the plan.
|
|
Drive the command from Composer::require() and route the
(installed | locked) branch through the ported PackageSorter,
RepositoryUtils::filterRequiredPackages, and PackageInfo helpers
in mozart-core. --no-dev for installed packages now filters via
root.require closure instead of dev_package_names membership;
text output annotates the name cell with an OSC 8 hyperlink to
the view-source/homepage URL; summary ties resolve in first-seen
order via IndexMap + stable sort_by_key(Reverse(count)) to mirror
PHP's arsort().
|
|
Switch to Composer::require() for the entrypoint, drop the Mozart-only
--dry-run / --no-dev flags, mirror selection inline using a port of
BasePackage::packageNameToRegexp, read autoloader options from
composer.config(), and route the autoload dump through
composer.autoload_generator(). Empty-result and unmatched-pattern
warnings now emit on stderr with <warning> markup, matching
$io->writeError. Plugin/script-event dispatch and Transaction-based
operation building remain TODO until the installer_executor lands.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|
Replace the dist-hash tree-diff implementation with Composer's VCS-level
status flow: three buckets (errors / unpushed_changes / vcs_version_changes)
populated via ChangeReportInterface / DvcsDownloaderInterface /
VcsCapableDownloaderInterface, and a bitfield exit code (1|2|4) instead
of always 1.
Supporting work:
- mozart-semver: add normalize_branch (VersionParser::normalizeBranch).
- mozart-vcs: extend VcsDownloader trait with unpushed_changes /
vcs_reference; port GitDownloader::getUnpushedChanges (HEAD-ref
discovery + git diff --name-status remote...branch + two-pass fetch);
fix git status invocation to use --untracked-files=no (Composer parity);
add hasMetadataRepository preconditions to git/hg/svn local_changes;
port VersionGuesser (git/hg/svn dispatch — Fossil omitted, feature
branch detection runs sequentially instead of via async promises).
- mozart-core: extend LocalPackage with pretty_version, package_type,
installation_source, source, dist, extra; add InstallationSource and
PackageReference. factory.rs reads them from installed.json.
- mozart-registry: new download_manager mirroring
DownloadManager::getDownloaderForPackage.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|
Mirror Composer's two-pass pipeline: load default-branch metadata from
remote repos first, then fall back to installed.json funding only for
packages whose default branch had nothing. Also fix the prev-line
dedup (was reset inside the inner loop), emit OSC 8 hyperlinks for
URLs, route format errors through console.error + bail_silent with
Composer's wording, and emit `[]` for empty JSON output to match
PHP's json_encode of an empty array. Drop the lockfile-preferred
heuristic — Composer reads only installed.json via the local
repository.
|
|
Replace the HTTP-only post-filtered implementation with a Repository::search
trait dispatch that mirrors ComposerRepository::search semantics for all
three modes (FULLTEXT/NAME/VENDOR). --only-name now does an OR-of-tokens
regex match against the full Packagist list.json index instead of a
substring match against a fulltext page, so e.g. \`mozart search --only-name
mono log\` matches \`monolog/monolog\` like Composer does. Other parity
fixes: regex::escape on non-fulltext queries, format check before mutex
check, 4-space JSON indent, OSC 8 terminal hyperlink emission when a
result has a url, <warning>\! Abandoned \!</warning> styling on abandoned
rows, and the Mozart-only "No packages found" warning is dropped to match
Composer's silent empty-result behavior.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|
Replace the hand-rolled composer.json -> composer.lock -> Packagist
fallback with a BrowseRepos composite that dispatches via a uniform
find_packages(name) over the root package, the local installed
repository, and the Packagist remote -- matching HomeCommand's
initializeRepos() + findPackages() loop.
- Extend InstalledPackageEntry with homepage/support so the local repo
carries the same fields HomeCommand reads off
CompletePackageInterface; propagate them through
locked_to_installed_entry.
- Collapse three extract_url_from_* helpers into a single
handle_package mirror.
- Relax is_valid_url to a filter_var(FILTER_VALIDATE_URL) analog (drop
the http/https scheme allowlist).
- Route warnings and "No package specified" notices to stderr; match
HomeCommand's exact wording.
- Merge the macOS/Linux open_browser branches; add the literal "web"
window-title argument on Windows.
|
|
Move source acquisition (root or remote dist download/extract),
composer.json archive metadata reading, filename generation, self-
exclusion, filter aggregation, and archive creation from the archive
command into a new ArchiveManager in mozart-archiver, mirroring
Composer's ArchiveCommand <-> ArchiveManager split. The command becomes
a thin wrapper that selects the package and delegates archiving.
Adds a one-way mozart-archiver -> mozart-registry dep since
ArchiveManager::archive() handles dist downloading internally (the
analog of Composer's injected DownloadManager).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|
archive and diagnose were not honoring $COMPOSER_HOME/config.json
because they bypassed Factory::createConfig() — archive used literal
"tar"/"." defaults when no composer.json was present, and diagnose
reimplemented cache-dir resolution from environment variables.
Mirror Composer's tryComposer + Factory::createConfig() fallback so
global config (archive-format, archive-dir, cache-dir) applies in both
commands.
|
|
|
|
The StatusArgs struct redefined `verbose` as bool while Cli defines a
global `verbose: u8` with ArgAction::Count. clap's runtime type check
panicked on access. Drop the local field and rely on cli.verbose, which
matches Composer's StatusCommand treating -v|-vv|-vvv as a single flag.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|
Add the Composer state-container types (LocalRepository,
RepositoryManager, InstallationManager, AutoloadGenerator,
AutoloadDumpOptions, PlatformRequirementFilter, Locker) plus the
factory wiring that builds them from composer.json and
vendor/composer/installed.json.
AutoloadGenerator::dump lives in mozart-autoload as an extension
trait so the orchestrating algorithm sits next to the classmap
scanner while the state container stays in mozart-core. Rework
dump-autoload to drive both, mirroring
$composer->getAutoloadGenerator()->dump(...).
|
|
Composer's ClearCacheCommand uses $io->writeError() for the per-cache
status lines and the final summary; Mozart was writing them to stdout
via console.info(). Switch to console_writeln_error\! so the output
stream matches Composer.
|
|
console_format!
The six tag-style color functions (info, comment, error, question,
highlight, warning) are pub only so that console_format! can call them
from generated code; they are not part of the public API. Rename them
to __format_*_message to make that intent visible, add a doc-comment
saying not to call them directly, and replace every remaining direct
call site with console_format!.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
|
|
--no-cache redirects COMPOSER_CACHE_DIR to /dev/null (mirrors Application::doRun).
cache_files_maxsize is now u64 with a "300MiB"-style string deserializer.
Cache::new() takes readonly instead of enabled; is_usable() detects null devices.
|
|
Adds crates/mozart-core/src/factory.rs with get_cache_dir(),
get_data_dir(), and create_config() — a Rust port of
Composer\Factory::createConfig() (auth loading and htaccess creation
are out of scope for now).
Also fixes a correctness bug on Linux: the previous Config::default()
resolved cache-dir to $XDG_CONFIG_HOME/composer/cache via the
{$home}/cache placeholder, whereas Composer uses the XDG cache base
($XDG_CACHE_HOME or ~/.cache), giving ~/.cache/composer.
Callers updated:
- Composer::load() uses create_config() as the global baseline before
merging project-level config.
- config command execute_read() builds the global baseline with
create_config() and overlays local config on top when not --global,
matching Composer's actual layering order.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Config uses serde with kebab-case field mapping; known properties are
strongly-typed fields and unknown keys flow into an extra BTreeMap.
resolve_references is moved to the new config module.
|
|
|
|
Mirror Composer's DumpAutoloadCommand by scanning the local repository
for packages whose install path is absent on disk, emitting the same
"Not all dependencies are installed" warning, and returning exit code 1
when any are missing. Also reorders the surrounding flow to follow
Composer's command sequence.
|
|
|
|
Introduce mozart_core::composer::Composer with require()/try_load()
constructors and a config() accessor, modelled on PHP Composer's
BaseCommand::requireComposer / tryComposer. ComposerConfig and
composer_home move into mozart-core so Composer::load can resolve
placeholders consistently.
Migrate dump-autoload, archive, exec and run-script away from ad-hoc
composer.json reads. exec and run-script now fail when composer.json
is missing instead of silently falling back to "vendor/bin",
matching the upstream requireComposer contract.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|
|
|
Previously each VCS mirror was keyed by sha1(url), which made
cache directories opaque and incompatible with Composer's layout.
Composer's GitDriver and GitDownloader both use the form
Preg::replace('{[^a-z0-9.]}i', '-', Url::sanitize(\$url)), so a
Mozart user migrating from Composer (or vice versa) could not
share an existing cache.
Reimplement GitUtil::sanitize_url to follow that pattern: redact
credentials and access tokens (Url::sanitize semantics, including
the GitHub token regex), then replace every byte outside [a-zA-Z0-9.]
with '-'. The credential redaction also collapses URLs that differ
only in their access_token to the same key.
|