aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock29
-rw-r--r--crates/shirabe-class-map-generator/src/class_map.rs17
-rw-r--r--crates/shirabe-class-map-generator/src/class_map_generator.rs47
-rw-r--r--crates/shirabe-class-map-generator/src/php_file_cleaner.rs10
-rw-r--r--crates/shirabe-class-map-generator/src/php_file_parser.rs48
-rw-r--r--crates/shirabe-external-packages/src/composer/pcre/preg.rs15
-rw-r--r--crates/shirabe-external-packages/src/composer/util/composer_mirror.rs9
-rw-r--r--crates/shirabe-external-packages/src/react/promise/mod.rs2
-rw-r--r--crates/shirabe-external-packages/src/react/promise/promise.rs6
-rw-r--r--crates/shirabe-external-packages/src/seld/signal/signal_handler.rs5
-rw-r--r--crates/shirabe-external-packages/src/symfony/component/console/application.rs8
-rw-r--r--crates/shirabe-external-packages/src/symfony/component/console/command/command.rs21
-rw-r--r--crates/shirabe-external-packages/src/symfony/component/console/formatter/output_formatter.rs6
-rw-r--r--crates/shirabe-external-packages/src/symfony/component/console/formatter/output_formatter_style.rs6
-rw-r--r--crates/shirabe-external-packages/src/symfony/component/console/helper/question_helper.rs2
-rw-r--r--crates/shirabe-external-packages/src/symfony/component/console/helper/table.rs2
-rw-r--r--crates/shirabe-external-packages/src/symfony/component/console/input/array_input.rs76
-rw-r--r--crates/shirabe-external-packages/src/symfony/component/console/input/input_interface.rs12
-rw-r--r--crates/shirabe-external-packages/src/symfony/component/console/input/string_input.rs71
-rw-r--r--crates/shirabe-external-packages/src/symfony/component/console/output/console_output.rs56
-rw-r--r--crates/shirabe-external-packages/src/symfony/component/console/question/choice_question.rs2
-rw-r--r--crates/shirabe-external-packages/src/symfony/component/console/question/question.rs5
-rw-r--r--crates/shirabe-external-packages/src/symfony/component/console/single_command_application.rs5
-rw-r--r--crates/shirabe-external-packages/src/symfony/component/filesystem/filesystem.rs29
-rw-r--r--crates/shirabe-external-packages/src/symfony/component/process/process.rs7
-rw-r--r--crates/shirabe-external-packages/src/symfony/console/formatter/output_formatter_style.rs6
-rw-r--r--crates/shirabe-external-packages/src/symfony/console/input/array_input.rs65
-rw-r--r--crates/shirabe-external-packages/src/symfony/console/input/input_argument.rs7
-rw-r--r--crates/shirabe-external-packages/src/symfony/console/input/input_interface.rs9
-rw-r--r--crates/shirabe-external-packages/src/symfony/console/input/string_input.rs65
-rw-r--r--crates/shirabe-external-packages/src/symfony/console/output/stream_output.rs42
-rw-r--r--crates/shirabe-external-packages/src/symfony/console/question/question.rs5
-rw-r--r--crates/shirabe-external-packages/src/symfony/console/style/symfony_style.rs24
-rw-r--r--crates/shirabe-php-shim/src/lib.rs57
-rw-r--r--crates/shirabe-semver/src/compiling_matcher.rs12
-rw-r--r--crates/shirabe-semver/src/constraint.rs6
-rw-r--r--crates/shirabe-semver/src/constraint/constraint.rs22
-rw-r--r--crates/shirabe-semver/src/constraint/multi_constraint.rs13
-rw-r--r--crates/shirabe-semver/src/intervals.rs74
-rw-r--r--crates/shirabe-semver/src/lib.rs7
-rw-r--r--crates/shirabe-semver/src/version_parser.rs205
-rw-r--r--crates/shirabe/src/advisory/audit_config.rs11
-rw-r--r--crates/shirabe/src/advisory/auditor.rs54
-rw-r--r--crates/shirabe/src/advisory/ignored_security_advisory.rs14
-rw-r--r--crates/shirabe/src/advisory/mod.rs5
-rw-r--r--crates/shirabe/src/advisory/partial_security_advisory.rs40
-rw-r--r--crates/shirabe/src/autoload/autoload_generator.rs596
-rw-r--r--crates/shirabe/src/autoload/class_loader.rs14
-rw-r--r--crates/shirabe/src/autoload/class_map_generator.rs21
-rw-r--r--crates/shirabe/src/autoload/mod.rs3
-rw-r--r--crates/shirabe/src/cache.rs39
-rw-r--r--crates/shirabe/src/command/about_command.rs4
-rw-r--r--crates/shirabe/src/command/archive_command.rs140
-rw-r--r--crates/shirabe/src/command/audit_command.rs99
-rw-r--r--crates/shirabe/src/command/base_command.rs49
-rw-r--r--crates/shirabe/src/command/base_config_command.rs13
-rw-r--r--crates/shirabe/src/command/base_dependency_command.rs51
-rw-r--r--crates/shirabe/src/command/bump_command.rs18
-rw-r--r--crates/shirabe/src/command/check_platform_reqs_command.rs172
-rw-r--r--crates/shirabe/src/command/clear_cache_command.rs64
-rw-r--r--crates/shirabe/src/command/completion_trait.rs115
-rw-r--r--crates/shirabe/src/command/config_command.rs936
-rw-r--r--crates/shirabe/src/command/create_project_command.rs153
-rw-r--r--crates/shirabe/src/command/depends_command.rs6
-rw-r--r--crates/shirabe/src/command/diagnose_command.rs381
-rw-r--r--crates/shirabe/src/command/dump_autoload_command.rs77
-rw-r--r--crates/shirabe/src/command/exec_command.rs80
-rw-r--r--crates/shirabe/src/command/fund_command.rs102
-rw-r--r--crates/shirabe/src/command/global_command.rs55
-rw-r--r--crates/shirabe/src/command/home_command.rs85
-rw-r--r--crates/shirabe/src/command/init_command.rs117
-rw-r--r--crates/shirabe/src/command/install_command.rs50
-rw-r--r--crates/shirabe/src/command/licenses_command.rs156
-rw-r--r--crates/shirabe/src/command/mod.rs38
-rw-r--r--crates/shirabe/src/command/outdated_command.rs31
-rw-r--r--crates/shirabe/src/command/package_discovery_trait.rs106
-rw-r--r--crates/shirabe/src/command/prohibits_command.rs6
-rw-r--r--crates/shirabe/src/command/reinstall_command.rs88
-rw-r--r--crates/shirabe/src/command/remove_command.rs144
-rw-r--r--crates/shirabe/src/command/repository_command.rs126
-rw-r--r--crates/shirabe/src/command/require_command.rs186
-rw-r--r--crates/shirabe/src/command/run_script_command.rs104
-rw-r--r--crates/shirabe/src/command/script_alias_command.rs81
-rw-r--r--crates/shirabe/src/command/search_command.rs77
-rw-r--r--crates/shirabe/src/command/self_update_command.rs139
-rw-r--r--crates/shirabe/src/command/show_command.rs316
-rw-r--r--crates/shirabe/src/command/status_command.rs134
-rw-r--r--crates/shirabe/src/command/suggests_command.rs42
-rw-r--r--crates/shirabe/src/command/update_command.rs96
-rw-r--r--crates/shirabe/src/command/validate_command.rs164
-rw-r--r--crates/shirabe/src/compiler.rs62
-rw-r--r--crates/shirabe/src/composer.rs4
-rw-r--r--crates/shirabe/src/config.rs167
-rw-r--r--crates/shirabe/src/config/config_source_interface.rs15
-rw-r--r--crates/shirabe/src/config/json_config_source.rs18
-rw-r--r--crates/shirabe/src/console/application.rs376
-rw-r--r--crates/shirabe/src/console/github_action_error.rs10
-rw-r--r--crates/shirabe/src/console/html_output_formatter.rs16
-rw-r--r--crates/shirabe/src/console/input/input_option.rs12
-rw-r--r--crates/shirabe/src/console/input/mod.rs2
-rw-r--r--crates/shirabe/src/console/mod.rs4
-rw-r--r--crates/shirabe/src/dependency_resolver/decisions.rs70
-rw-r--r--crates/shirabe/src/dependency_resolver/default_policy.rs54
-rw-r--r--crates/shirabe/src/dependency_resolver/generic_rule.rs39
-rw-r--r--crates/shirabe/src/dependency_resolver/local_repo_transaction.rs7
-rw-r--r--crates/shirabe/src/dependency_resolver/lock_transaction.rs58
-rw-r--r--crates/shirabe/src/dependency_resolver/mod.rs26
-rw-r--r--crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs32
-rw-r--r--crates/shirabe/src/dependency_resolver/operation/mod.rs7
-rw-r--r--crates/shirabe/src/dependency_resolver/operation/update_operation.rs48
-rw-r--r--crates/shirabe/src/dependency_resolver/policy_interface.rs14
-rw-r--r--crates/shirabe/src/dependency_resolver/pool.rs34
-rw-r--r--crates/shirabe/src/dependency_resolver/pool_builder.rs298
-rw-r--r--crates/shirabe/src/dependency_resolver/pool_optimizer.rs50
-rw-r--r--crates/shirabe/src/dependency_resolver/problem.rs155
-rw-r--r--crates/shirabe/src/dependency_resolver/request.rs2
-rw-r--r--crates/shirabe/src/dependency_resolver/rule.rs86
-rw-r--r--crates/shirabe/src/dependency_resolver/rule2_literals.rs13
-rw-r--r--crates/shirabe/src/dependency_resolver/rule_set.rs13
-rw-r--r--crates/shirabe/src/dependency_resolver/rule_set_generator.rs58
-rw-r--r--crates/shirabe/src/dependency_resolver/rule_set_iterator.rs2
-rw-r--r--crates/shirabe/src/dependency_resolver/rule_watch_graph.rs35
-rw-r--r--crates/shirabe/src/dependency_resolver/rule_watch_node.rs6
-rw-r--r--crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs79
-rw-r--r--crates/shirabe/src/dependency_resolver/solver.rs46
-rw-r--r--crates/shirabe/src/dependency_resolver/solver_problems_exception.rs29
-rw-r--r--crates/shirabe/src/dependency_resolver/transaction.rs32
-rw-r--r--crates/shirabe/src/downloader/archive_downloader.rs68
-rw-r--r--crates/shirabe/src/downloader/download_manager.rs27
-rw-r--r--crates/shirabe/src/downloader/downloader_interface.rs42
-rw-r--r--crates/shirabe/src/downloader/file_downloader.rs42
-rw-r--r--crates/shirabe/src/downloader/fossil_downloader.rs83
-rw-r--r--crates/shirabe/src/downloader/git_downloader.rs176
-rw-r--r--crates/shirabe/src/downloader/gzip_downloader.rs29
-rw-r--r--crates/shirabe/src/downloader/hg_downloader.rs61
-rw-r--r--crates/shirabe/src/downloader/mod.rs23
-rw-r--r--crates/shirabe/src/downloader/path_downloader.rs31
-rw-r--r--crates/shirabe/src/downloader/perforce_downloader.rs49
-rw-r--r--crates/shirabe/src/downloader/phar_downloader.rs13
-rw-r--r--crates/shirabe/src/downloader/rar_downloader.rs35
-rw-r--r--crates/shirabe/src/downloader/svn_downloader.rs35
-rw-r--r--crates/shirabe/src/downloader/tar_downloader.rs13
-rw-r--r--crates/shirabe/src/downloader/vcs_downloader.rs61
-rw-r--r--crates/shirabe/src/downloader/xz_downloader.rs17
-rw-r--r--crates/shirabe/src/downloader/zip_downloader.rs201
-rw-r--r--crates/shirabe/src/event_dispatcher/event_dispatcher.rs822
-rw-r--r--crates/shirabe/src/event_dispatcher/mod.rs4
-rw-r--r--crates/shirabe/src/exception/mod.rs2
-rw-r--r--crates/shirabe/src/factory.rs236
-rw-r--r--crates/shirabe/src/filter/mod.rs1
-rw-r--r--crates/shirabe/src/filter/platform_requirement_filter/ignore_list_platform_requirement_filter.rs12
-rw-r--r--crates/shirabe/src/filter/platform_requirement_filter/mod.rs5
-rw-r--r--crates/shirabe/src/filter/platform_requirement_filter/platform_requirement_filter_factory.rs14
-rw-r--r--crates/shirabe/src/installed_versions.rs36
-rw-r--r--crates/shirabe/src/installer.rs236
-rw-r--r--crates/shirabe/src/installer/binary_installer.rs39
-rw-r--r--crates/shirabe/src/installer/installation_manager.rs82
-rw-r--r--crates/shirabe/src/installer/installer_event.rs9
-rw-r--r--crates/shirabe/src/installer/installer_interface.rs47
-rw-r--r--crates/shirabe/src/installer/library_installer.rs9
-rw-r--r--crates/shirabe/src/installer/metapackage_installer.rs99
-rw-r--r--crates/shirabe/src/installer/noop_installer.rs79
-rw-r--r--crates/shirabe/src/installer/package_event.rs2
-rw-r--r--crates/shirabe/src/installer/plugin_installer.rs85
-rw-r--r--crates/shirabe/src/installer/project_installer.rs71
-rw-r--r--crates/shirabe/src/installer/suggested_packages_reporter.rs47
-rw-r--r--crates/shirabe/src/io/base_io.rs27
-rw-r--r--crates/shirabe/src/io/buffer_io.rs21
-rw-r--r--crates/shirabe/src/io/console_io.rs53
-rw-r--r--crates/shirabe/src/io/io_interface.rs29
-rw-r--r--crates/shirabe/src/io/mod.rs5
-rw-r--r--crates/shirabe/src/io/null_io.rs37
-rw-r--r--crates/shirabe/src/json/json_file.rs28
-rw-r--r--crates/shirabe/src/json/json_formatter.rs2
-rw-r--r--crates/shirabe/src/json/json_manipulator.rs293
-rw-r--r--crates/shirabe/src/json/mod.rs4
-rw-r--r--crates/shirabe/src/lib.rs28
-rw-r--r--crates/shirabe/src/package/alias_package.rs2
-rw-r--r--crates/shirabe/src/package/archiver/archivable_files_filter.rs2
-rw-r--r--crates/shirabe/src/package/archiver/archivable_files_finder.rs11
-rw-r--r--crates/shirabe/src/package/archiver/archive_manager.rs17
-rw-r--r--crates/shirabe/src/package/archiver/base_exclude_filter.rs5
-rw-r--r--crates/shirabe/src/package/archiver/git_exclude_filter.rs11
-rw-r--r--crates/shirabe/src/package/archiver/mod.rs9
-rw-r--r--crates/shirabe/src/package/archiver/phar_archiver.rs26
-rw-r--r--crates/shirabe/src/package/archiver/zip_archiver.rs35
-rw-r--r--crates/shirabe/src/package/base_package.rs2
-rw-r--r--crates/shirabe/src/package/comparer/comparer.rs30
-rw-r--r--crates/shirabe/src/package/comparer/mod.rs1
-rw-r--r--crates/shirabe/src/package/complete_alias_package.rs10
-rw-r--r--crates/shirabe/src/package/complete_package.rs4
-rw-r--r--crates/shirabe/src/package/dumper/array_dumper.rs352
-rw-r--r--crates/shirabe/src/package/dumper/mod.rs1
-rw-r--r--crates/shirabe/src/package/link.rs10
-rw-r--r--crates/shirabe/src/package/loader/array_loader.rs38
-rw-r--r--crates/shirabe/src/package/loader/invalid_package_exception.rs7
-rw-r--r--crates/shirabe/src/package/loader/json_loader.rs8
-rw-r--r--crates/shirabe/src/package/loader/loader_interface.rs8
-rw-r--r--crates/shirabe/src/package/loader/mod.rs6
-rw-r--r--crates/shirabe/src/package/loader/root_package_loader.rs89
-rw-r--r--crates/shirabe/src/package/loader/validating_array_loader.rs169
-rw-r--r--crates/shirabe/src/package/locker.rs79
-rw-r--r--crates/shirabe/src/package/mod.rs17
-rw-r--r--crates/shirabe/src/package/package.rs7
-rw-r--r--crates/shirabe/src/package/root_package.rs4
-rw-r--r--crates/shirabe/src/package/version/mod.rs5
-rw-r--r--crates/shirabe/src/package/version/stability_filter.rs2
-rw-r--r--crates/shirabe/src/package/version/version_bumper.rs47
-rw-r--r--crates/shirabe/src/package/version/version_guesser.rs40
-rw-r--r--crates/shirabe/src/package/version/version_parser.rs16
-rw-r--r--crates/shirabe/src/package/version/version_selector.rs30
-rw-r--r--crates/shirabe/src/phpstan/mod.rs2
-rw-r--r--crates/shirabe/src/platform/hhvm_detector.rs28
-rw-r--r--crates/shirabe/src/platform/mod.rs3
-rw-r--r--crates/shirabe/src/platform/runtime.rs6
-rw-r--r--crates/shirabe/src/platform/version.rs35
-rw-r--r--crates/shirabe/src/plugin/capability/mod.rs2
-rw-r--r--crates/shirabe/src/plugin/command_event.rs9
-rw-r--r--crates/shirabe/src/plugin/mod.rs11
-rw-r--r--crates/shirabe/src/plugin/plugin_manager.rs325
-rw-r--r--crates/shirabe/src/plugin/pre_command_run_event.rs2
-rw-r--r--crates/shirabe/src/plugin/pre_pool_create_event.rs4
-rw-r--r--crates/shirabe/src/question/mod.rs1
-rw-r--r--crates/shirabe/src/question/strict_confirmation_question.rs5
-rw-r--r--crates/shirabe/src/repository/advisory_provider_interface.rs10
-rw-r--r--crates/shirabe/src/repository/array_repository.rs29
-rw-r--r--crates/shirabe/src/repository/artifact_repository.rs27
-rw-r--r--crates/shirabe/src/repository/canonical_packages_trait.rs2
-rw-r--r--crates/shirabe/src/repository/composer_repository.rs271
-rw-r--r--crates/shirabe/src/repository/composite_repository.rs26
-rw-r--r--crates/shirabe/src/repository/filesystem_repository.rs124
-rw-r--r--crates/shirabe/src/repository/filter_repository.rs113
-rw-r--r--crates/shirabe/src/repository/installed_repository.rs16
-rw-r--r--crates/shirabe/src/repository/mod.rs31
-rw-r--r--crates/shirabe/src/repository/path_repository.rs81
-rw-r--r--crates/shirabe/src/repository/platform_repository.rs165
-rw-r--r--crates/shirabe/src/repository/repository_factory.rs148
-rw-r--r--crates/shirabe/src/repository/repository_interface.rs18
-rw-r--r--crates/shirabe/src/repository/repository_manager.rs59
-rw-r--r--crates/shirabe/src/repository/repository_set.rs35
-rw-r--r--crates/shirabe/src/repository/repository_utils.rs19
-rw-r--r--crates/shirabe/src/repository/vcs/forgejo_driver.rs191
-rw-r--r--crates/shirabe/src/repository/vcs/fossil_driver.rs22
-rw-r--r--crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs118
-rw-r--r--crates/shirabe/src/repository/vcs/git_driver.rs43
-rw-r--r--crates/shirabe/src/repository/vcs/github_driver.rs175
-rw-r--r--crates/shirabe/src/repository/vcs/gitlab_driver.rs123
-rw-r--r--crates/shirabe/src/repository/vcs/hg_driver.rs117
-rw-r--r--crates/shirabe/src/repository/vcs/mod.rs11
-rw-r--r--crates/shirabe/src/repository/vcs/perforce_driver.rs66
-rw-r--r--crates/shirabe/src/repository/vcs/svn_driver.rs139
-rw-r--r--crates/shirabe/src/repository/vcs/vcs_driver.rs58
-rw-r--r--crates/shirabe/src/repository/vcs/vcs_driver_interface.rs9
-rw-r--r--crates/shirabe/src/repository/vcs_repository.rs117
-rw-r--r--crates/shirabe/src/repository/writable_array_repository.rs8
-rw-r--r--crates/shirabe/src/repository/writable_repository_interface.rs2
-rw-r--r--crates/shirabe/src/script/event.rs4
-rw-r--r--crates/shirabe/src/script/mod.rs2
-rw-r--r--crates/shirabe/src/self_update/mod.rs2
-rw-r--r--crates/shirabe/src/self_update/versions.rs34
-rw-r--r--crates/shirabe/src/util/auth_helper.rs28
-rw-r--r--crates/shirabe/src/util/bitbucket.rs138
-rw-r--r--crates/shirabe/src/util/composer_mirror.rs21
-rw-r--r--crates/shirabe/src/util/config_validator.rs79
-rw-r--r--crates/shirabe/src/util/error_handler.rs42
-rw-r--r--crates/shirabe/src/util/filesystem.rs202
-rw-r--r--crates/shirabe/src/util/forgejo.rs7
-rw-r--r--crates/shirabe/src/util/forgejo_url.rs25
-rw-r--r--crates/shirabe/src/util/git.rs41
-rw-r--r--crates/shirabe/src/util/github.rs24
-rw-r--r--crates/shirabe/src/util/gitlab.rs59
-rw-r--r--crates/shirabe/src/util/hg.rs72
-rw-r--r--crates/shirabe/src/util/http/curl_downloader.rs221
-rw-r--r--crates/shirabe/src/util/http/mod.rs6
-rw-r--r--crates/shirabe/src/util/http/proxy_item.rs25
-rw-r--r--crates/shirabe/src/util/http/proxy_manager.rs10
-rw-r--r--crates/shirabe/src/util/http/request_proxy.rs40
-rw-r--r--crates/shirabe/src/util/http/response.rs6
-rw-r--r--crates/shirabe/src/util/http_downloader.rs93
-rw-r--r--crates/shirabe/src/util/loop.rs17
-rw-r--r--crates/shirabe/src/util/mod.rs33
-rw-r--r--crates/shirabe/src/util/no_proxy_pattern.rs48
-rw-r--r--crates/shirabe/src/util/package_info.rs4
-rw-r--r--crates/shirabe/src/util/package_sorter.rs24
-rw-r--r--crates/shirabe/src/util/perforce.rs37
-rw-r--r--crates/shirabe/src/util/platform.rs29
-rw-r--r--crates/shirabe/src/util/process_executor.rs67
-rw-r--r--crates/shirabe/src/util/remote_filesystem.rs64
-rw-r--r--crates/shirabe/src/util/silencer.rs13
-rw-r--r--crates/shirabe/src/util/stream_context_factory.rs77
-rw-r--r--crates/shirabe/src/util/svn.rs21
-rw-r--r--crates/shirabe/src/util/sync_helper.rs60
-rw-r--r--crates/shirabe/src/util/tar.rs10
-rw-r--r--crates/shirabe/src/util/tls_helper.rs18
-rw-r--r--crates/shirabe/src/util/url.rs126
-rw-r--r--crates/shirabe/src/util/zip.rs9
296 files changed, 11928 insertions, 5978 deletions
diff --git a/Cargo.lock b/Cargo.lock
index f5484af..96c6990 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -892,11 +892,32 @@ dependencies = [
"serde",
"serde_json",
"sha1 0.10.6",
+ "shirabe-external-packages",
"shirabe-php-shim",
+ "shirabe-semver",
"url",
]
[[package]]
+name = "shirabe-class-map-generator"
+version = "0.0.1"
+dependencies = [
+ "anyhow",
+ "indexmap",
+ "shirabe-external-packages",
+ "shirabe-php-shim",
+]
+
+[[package]]
+name = "shirabe-external-packages"
+version = "0.0.1"
+dependencies = [
+ "anyhow",
+ "indexmap",
+ "shirabe-php-shim",
+]
+
+[[package]]
name = "shirabe-php-shim"
version = "0.0.1"
dependencies = [
@@ -905,6 +926,14 @@ dependencies = [
]
[[package]]
+name = "shirabe-semver"
+version = "0.0.1"
+dependencies = [
+ "anyhow",
+ "shirabe-php-shim",
+]
+
+[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/crates/shirabe-class-map-generator/src/class_map.rs b/crates/shirabe-class-map-generator/src/class_map.rs
index 51d2bef..311924b 100644
--- a/crates/shirabe-class-map-generator/src/class_map.rs
+++ b/crates/shirabe-class-map-generator/src/class_map.rs
@@ -1,8 +1,10 @@
//! ref: composer/vendor/composer/class-map-generator/src/ClassMap.php
use indexmap::IndexMap;
-use shirabe_php_shim::{Countable, InvalidArgumentException, OutOfBoundsException, rtrim, strpos, strtr};
use shirabe_external_packages::composer::pcre::preg::Preg;
+use shirabe_php_shim::{
+ Countable, InvalidArgumentException, OutOfBoundsException, rtrim, strpos, strtr,
+};
#[derive(Debug, Clone)]
pub struct PsrViolationEntry {
@@ -105,20 +107,25 @@ impl ClassMap {
self.psr_violations
.entry(path)
.or_default()
- .push(PsrViolationEntry { warning, class_name });
+ .push(PsrViolationEntry {
+ warning,
+ class_name,
+ });
}
pub fn clear_psr_violations_by_path(&mut self, path_prefix: &str) {
let path_prefix = rtrim(&strtr(path_prefix, "\\", "/"), Some("/"));
self.psr_violations.retain(|path, _| {
- path != &path_prefix
- && strpos(path, &format!("{}/", path_prefix)) != Some(0)
+ path != &path_prefix && strpos(path, &format!("{}/", path_prefix)) != Some(0)
});
}
pub fn add_ambiguous_class(&mut self, class_name: String, path: String) {
- self.ambiguous_classes.entry(class_name).or_default().push(path);
+ self.ambiguous_classes
+ .entry(class_name)
+ .or_default()
+ .push(path);
}
/// Get the raw psr violations
diff --git a/crates/shirabe-class-map-generator/src/class_map_generator.rs b/crates/shirabe-class-map-generator/src/class_map_generator.rs
index af3abb4..1d2084d 100644
--- a/crates/shirabe-class-map-generator/src/class_map_generator.rs
+++ b/crates/shirabe-class-map-generator/src/class_map_generator.rs
@@ -1,19 +1,17 @@
//! ref: composer/vendor/composer/class-map-generator/src/ClassMapGenerator.php
-use shirabe_php_shim::{
- DIRECTORY_SEPARATOR, PATHINFO_EXTENSION, PHP_INT_MAX,
- InvalidArgumentException, LogicException, RuntimeException,
- explode, getcwd, implode, in_array, is_dir, is_file, is_string,
- pathinfo, preg_quote, realpath, str_replace, str_starts_with,
- stream_get_wrappers, strlen, strrpos, strpos, strtr, substr,
- sprintf, PhpMixed,
-};
-use shirabe_external_packages::composer::pcre::preg::Preg;
-use shirabe_external_packages::symfony::component::finder::finder::Finder;
-use shirabe_external_packages::symfony::component::finder::spl_file_info::SplFileInfo;
use crate::class_map::ClassMap;
use crate::file_list::FileList;
use crate::php_file_parser::PhpFileParser;
+use shirabe_external_packages::composer::pcre::preg::Preg;
+use shirabe_external_packages::symfony::component::finder::finder::Finder;
+use shirabe_external_packages::symfony::component::finder::spl_file_info::SplFileInfo;
+use shirabe_php_shim::{
+ DIRECTORY_SEPARATOR, InvalidArgumentException, LogicException, PATHINFO_EXTENSION, PHP_INT_MAX,
+ PhpMixed, RuntimeException, explode, getcwd, implode, in_array, is_dir, is_file, is_string,
+ pathinfo, preg_quote, realpath, sprintf, str_replace, str_starts_with, stream_get_wrappers,
+ strlen, strpos, strrpos, strtr, substr,
+};
#[derive(Debug)]
pub struct ClassMapGenerator {
@@ -29,10 +27,8 @@ impl ClassMapGenerator {
.iter()
.map(|w| preg_quote(w, None))
.collect();
- let stream_wrappers_regex = sprintf(
- "{^(?:%s)://}",
- &[PhpMixed::String(implode("|", &wrappers))],
- );
+ let stream_wrappers_regex =
+ sprintf("{^(?:%s)://}", &[PhpMixed::String(implode("|", &wrappers))]);
ClassMapGenerator {
extensions,
@@ -82,7 +78,8 @@ impl ClassMapGenerator {
true,
) {
return Err(anyhow::anyhow!(InvalidArgumentException {
- message: "$autoloadType must be one of: \"psr-0\", \"psr-4\" or \"classmap\"".to_string(),
+ message: "$autoloadType must be one of: \"psr-0\", \"psr-4\" or \"classmap\""
+ .to_string(),
code: 0,
}));
}
@@ -91,7 +88,9 @@ impl ClassMapGenerator {
if autoload_type != "classmap" {
if !is_string(&path) {
return Err(anyhow::anyhow!(InvalidArgumentException {
- message: "$path must be a string when specifying a psr-0 or psr-4 autoload type".to_string(),
+ message:
+ "$path must be a string when specifying a psr-0 or psr-4 autoload type"
+ .to_string(),
code: 0,
}));
}
@@ -115,7 +114,11 @@ impl ClassMapGenerator {
"/\\.(?:{})$/",
implode(
"|",
- &self.extensions.iter().map(|e| preg_quote(e, None)).collect::<Vec<_>>(),
+ &self
+ .extensions
+ .iter()
+ .map(|e| preg_quote(e, None))
+ .collect::<Vec<_>>(),
)
);
Finder::create()
@@ -137,7 +140,9 @@ impl ClassMapGenerator {
}
} else {
// $path is already an array or Traversable of SplFileInfo
- todo!("non-string path (Traversable/array of SplFileInfo) is not yet handled in Phase A")
+ todo!(
+ "non-string path (Traversable/array of SplFileInfo) is not yet handled in Phase A"
+ )
};
let cwd = realpath(&getcwd().unwrap_or_default()).unwrap_or_default();
@@ -164,8 +169,8 @@ impl ClassMapGenerator {
file_path = format!("{}/{}", cwd, file_path);
file_path = Self::normalize_path(&file_path);
} else {
- file_path = Preg::replace(r"{(?<!:)[\\/]{2,}}", "/", &file_path)
- .unwrap_or(file_path);
+ file_path =
+ Preg::replace(r"{(?<!:)[\\/]{2,}}", "/", &file_path).unwrap_or(file_path);
}
if file_path.is_empty() {
diff --git a/crates/shirabe-class-map-generator/src/php_file_cleaner.rs b/crates/shirabe-class-map-generator/src/php_file_cleaner.rs
index 9f7d781..1a33533 100644
--- a/crates/shirabe-class-map-generator/src/php_file_cleaner.rs
+++ b/crates/shirabe-class-map-generator/src/php_file_cleaner.rs
@@ -1,9 +1,9 @@
//! ref: composer/vendor/composer/class-map-generator/src/PhpFileCleaner.php
-use std::sync::Mutex;
use indexmap::IndexMap;
-use shirabe_php_shim::preg_quote;
use shirabe_external_packages::composer::pcre::preg::Preg;
+use shirabe_php_shim::preg_quote;
+use std::sync::Mutex;
#[derive(Debug, Clone)]
struct TypeConfigEntry {
@@ -90,7 +90,7 @@ impl PhpFileCleaner {
if char == '<' && self.peek('<') {
let mut r#match: Vec<String> = vec![];
if self.r#match(
- r"{<<<[ \t]*+(['\"]?)([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*+)\1(?:\r\n|\n|\r)}A",
+ r#"{<<<[ \t]*+(['\"]?)([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*+)\1(?:\r\n|\n|\r)}A"#,
Some(&mut r#match),
) {
self.index += r#match[0].len();
@@ -120,9 +120,7 @@ impl PhpFileCleaner {
};
if let Some(entry) = type_entry {
let end = self.index + entry.length;
- if end <= self.len
- && &self.contents[self.index..end] == entry.name
- {
+ if end <= self.len && &self.contents[self.index..end] == entry.name {
let offset = if self.index > 0 { self.index - 1 } else { 0 };
let mut r#match: Vec<String> = vec![];
if Preg::is_match_at(
diff --git a/crates/shirabe-class-map-generator/src/php_file_parser.rs b/crates/shirabe-class-map-generator/src/php_file_parser.rs
index b68a33a..9bc7c5c 100644
--- a/crates/shirabe-class-map-generator/src/php_file_parser.rs
+++ b/crates/shirabe-class-map-generator/src/php_file_parser.rs
@@ -1,17 +1,15 @@
//! ref: composer/vendor/composer/class-map-generator/src/PhpFileParser.php
-use std::sync::OnceLock;
+use crate::php_file_cleaner::PhpFileCleaner;
use anyhow::anyhow;
use indexmap::IndexMap;
+use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- PHP_EOL, PHP_VERSION_ID, HHVM_VERSION,
- RuntimeException,
- error_get_last, file_exists, file_get_contents, function_exists,
- is_file, is_readable, ltrim, php_strip_whitespace, sprintf,
+ HHVM_VERSION, PHP_EOL, PHP_VERSION_ID, RuntimeException, error_get_last, file_exists,
+ file_get_contents, function_exists, is_file, is_readable, ltrim, php_strip_whitespace, sprintf,
str_replace_array, strrpos, substr, trim, version_compare,
};
-use shirabe_external_packages::composer::pcre::preg::Preg;
-use crate::php_file_cleaner::PhpFileCleaner;
+use std::sync::OnceLock;
pub struct PhpFileParser;
@@ -38,11 +36,15 @@ impl PhpFileParser {
// The input file was really empty and thus contains no classes
return Ok(vec![]);
} else {
- message = "File at \"%s\" could not be parsed as PHP, it may be binary or corrupted";
+ message =
+ "File at \"%s\" could not be parsed as PHP, it may be binary or corrupted";
}
let error = error_get_last();
- let mut message = sprintf(message, &[shirabe_php_shim::PhpMixed::String(path.to_string())]);
+ let mut message = sprintf(
+ message,
+ &[shirabe_php_shim::PhpMixed::String(path.to_string())],
+ );
if let Some(error) = error {
if let Some(err_msg) = error.get("message") {
message = format!(
@@ -87,16 +89,33 @@ impl PhpFileParser {
let len = matches.get("type").map(|v| v.len()).unwrap_or(0);
for i in 0..len {
- let ns = matches.get("ns").and_then(|v| v.get(i)).map(|s| s.as_str()).unwrap_or("");
+ let ns = matches
+ .get("ns")
+ .and_then(|v| v.get(i))
+ .map(|s| s.as_str())
+ .unwrap_or("");
if !ns.is_empty() {
- let nsname = matches.get("nsname").and_then(|v| v.get(i)).map(|s| s.as_str()).unwrap_or("");
+ let nsname = matches
+ .get("nsname")
+ .and_then(|v| v.get(i))
+ .map(|s| s.as_str())
+ .unwrap_or("");
namespace = str_replace_array(
- &[" ".to_string(), "\t".to_string(), "\r".to_string(), "\n".to_string()],
+ &[
+ " ".to_string(),
+ "\t".to_string(),
+ "\r".to_string(),
+ "\n".to_string(),
+ ],
&["".to_string()],
nsname,
) + "\\";
} else {
- let name = matches.get("name").and_then(|v| v.get(i)).map(|s| s.as_str()).unwrap_or("");
+ let name = matches
+ .get("name")
+ .and_then(|v| v.get(i))
+ .map(|s| s.as_str())
+ .unwrap_or("");
// skip anon classes extending/implementing
if name == "extends" {
continue;
@@ -151,8 +170,7 @@ impl PhpFileParser {
let mut extra_types = String::new();
let mut extra_types_array: Vec<String> = vec![];
if PHP_VERSION_ID >= 80100
- || (HHVM_VERSION.is_some()
- && version_compare(HHVM_VERSION.unwrap(), "3.3", ">="))
+ || (HHVM_VERSION.is_some() && version_compare(HHVM_VERSION.unwrap(), "3.3", ">="))
{
extra_types += "|enum";
extra_types_array = vec!["enum".to_string()];
diff --git a/crates/shirabe-external-packages/src/composer/pcre/preg.rs b/crates/shirabe-external-packages/src/composer/pcre/preg.rs
index 1b2d675..2f675cd 100644
--- a/crates/shirabe-external-packages/src/composer/pcre/preg.rs
+++ b/crates/shirabe-external-packages/src/composer/pcre/preg.rs
@@ -37,10 +37,7 @@ impl Preg {
}
/// Returns captures as a flat Vec indexed by group number (index 0 = full match).
- pub fn is_match_strict_groups(
- pattern: &str,
- subject: &str,
- ) -> Option<Vec<String>> {
+ pub fn is_match_strict_groups(pattern: &str, subject: &str) -> Option<Vec<String>> {
todo!()
}
@@ -54,10 +51,7 @@ impl Preg {
}
/// Returns all matches; outer Vec indexed by group number, inner Vec by match occurrence.
- pub fn is_match_all_strict_groups(
- pattern: &str,
- subject: &str,
- ) -> Option<Vec<Vec<String>>> {
+ pub fn is_match_all_strict_groups(pattern: &str, subject: &str) -> Option<Vec<Vec<String>>> {
todo!()
}
@@ -79,10 +73,7 @@ impl Preg {
}
/// Like is_match_strict_groups but returns named captures as IndexMap.
- pub fn match_strict_groups(
- pattern: &str,
- subject: &str,
- ) -> Option<IndexMap<String, String>> {
+ pub fn match_strict_groups(pattern: &str, subject: &str) -> Option<IndexMap<String, String>> {
todo!()
}
}
diff --git a/crates/shirabe-external-packages/src/composer/util/composer_mirror.rs b/crates/shirabe-external-packages/src/composer/util/composer_mirror.rs
index 767ff36..21d0fdf 100644
--- a/crates/shirabe-external-packages/src/composer/util/composer_mirror.rs
+++ b/crates/shirabe-external-packages/src/composer/util/composer_mirror.rs
@@ -2,7 +2,14 @@
pub struct ComposerMirror;
impl ComposerMirror {
- pub fn process_url(mirror: &str, package_name: &str, version: &str, reference: Option<&str>, url: &str, custom_filename: Option<&str>) -> String {
+ pub fn process_url(
+ mirror: &str,
+ package_name: &str,
+ version: &str,
+ reference: Option<&str>,
+ url: &str,
+ custom_filename: Option<&str>,
+ ) -> String {
todo!()
}
diff --git a/crates/shirabe-external-packages/src/react/promise/mod.rs b/crates/shirabe-external-packages/src/react/promise/mod.rs
index 602cee2..9961b99 100644
--- a/crates/shirabe-external-packages/src/react/promise/mod.rs
+++ b/crates/shirabe-external-packages/src/react/promise/mod.rs
@@ -1,8 +1,8 @@
pub mod promise;
pub mod promise_interface;
-use shirabe_php_shim::PhpMixed;
use self::promise::Promise;
+use shirabe_php_shim::PhpMixed;
pub fn resolve(value: Option<PhpMixed>) -> Promise {
todo!()
diff --git a/crates/shirabe-external-packages/src/react/promise/promise.rs b/crates/shirabe-external-packages/src/react/promise/promise.rs
index 36770b6..756a58a 100644
--- a/crates/shirabe-external-packages/src/react/promise/promise.rs
+++ b/crates/shirabe-external-packages/src/react/promise/promise.rs
@@ -4,7 +4,11 @@ use shirabe_php_shim::PhpMixed;
pub struct Promise;
impl Promise {
- pub fn new(resolver: Box<dyn FnOnce(Box<dyn FnOnce(Option<PhpMixed>)>, Box<dyn FnOnce(Option<PhpMixed>)>)>) -> Self {
+ pub fn new(
+ resolver: Box<
+ dyn FnOnce(Box<dyn FnOnce(Option<PhpMixed>)>, Box<dyn FnOnce(Option<PhpMixed>)>),
+ >,
+ ) -> Self {
todo!()
}
diff --git a/crates/shirabe-external-packages/src/seld/signal/signal_handler.rs b/crates/shirabe-external-packages/src/seld/signal/signal_handler.rs
index c592fc5..04aae27 100644
--- a/crates/shirabe-external-packages/src/seld/signal/signal_handler.rs
+++ b/crates/shirabe-external-packages/src/seld/signal/signal_handler.rs
@@ -6,10 +6,7 @@ impl SignalHandler {
pub const SIGTERM: &'static str = "SIGTERM";
pub const SIGHUP: &'static str = "SIGHUP";
- pub fn create(
- signals: Vec<String>,
- callback: Box<dyn Fn(String, &SignalHandler)>,
- ) -> Self {
+ pub fn create(signals: Vec<String>, callback: Box<dyn Fn(String, &SignalHandler)>) -> Self {
todo!()
}
diff --git a/crates/shirabe-external-packages/src/symfony/component/console/application.rs b/crates/shirabe-external-packages/src/symfony/component/console/application.rs
index 760e609..f9495bb 100644
--- a/crates/shirabe-external-packages/src/symfony/component/console/application.rs
+++ b/crates/shirabe-external-packages/src/symfony/component/console/application.rs
@@ -1,6 +1,6 @@
-use shirabe_php_shim::PhpMixed;
use crate::symfony::component::console::input::input_interface::InputInterface;
use crate::symfony::component::console::output::output_interface::OutputInterface;
+use shirabe_php_shim::PhpMixed;
#[derive(Debug)]
pub struct Application;
@@ -78,7 +78,11 @@ impl Application {
todo!()
}
- pub fn set_default_command(&mut self, command_name: &str, is_single_command: bool) -> &mut Self {
+ pub fn set_default_command(
+ &mut self,
+ command_name: &str,
+ is_single_command: bool,
+ ) -> &mut Self {
todo!()
}
diff --git a/crates/shirabe-external-packages/src/symfony/component/console/command/command.rs b/crates/shirabe-external-packages/src/symfony/component/console/command/command.rs
index cf18378..3c18be5 100644
--- a/crates/shirabe-external-packages/src/symfony/component/console/command/command.rs
+++ b/crates/shirabe-external-packages/src/symfony/component/console/command/command.rs
@@ -1,7 +1,7 @@
-use shirabe_php_shim::PhpMixed;
+use crate::symfony::component::console::input::input_definition::InputDefinition;
use crate::symfony::component::console::input::input_interface::InputInterface;
use crate::symfony::component::console::output::output_interface::OutputInterface;
-use crate::symfony::component::console::input::input_definition::InputDefinition;
+use shirabe_php_shim::PhpMixed;
#[derive(Debug)]
pub struct Command;
@@ -39,11 +39,24 @@ impl Command {
todo!()
}
- pub fn add_argument(&mut self, name: &str, mode: Option<i64>, description: &str, default: PhpMixed) -> &mut Self {
+ pub fn add_argument(
+ &mut self,
+ name: &str,
+ mode: Option<i64>,
+ description: &str,
+ default: PhpMixed,
+ ) -> &mut Self {
todo!()
}
- pub fn add_option(&mut self, name: &str, shortcut: Option<&str>, mode: Option<i64>, description: &str, default: PhpMixed) -> &mut Self {
+ pub fn add_option(
+ &mut self,
+ name: &str,
+ shortcut: Option<&str>,
+ mode: Option<i64>,
+ description: &str,
+ default: PhpMixed,
+ ) -> &mut Self {
todo!()
}
diff --git a/crates/shirabe-external-packages/src/symfony/component/console/formatter/output_formatter.rs b/crates/shirabe-external-packages/src/symfony/component/console/formatter/output_formatter.rs
index 1f51e46..b698d92 100644
--- a/crates/shirabe-external-packages/src/symfony/component/console/formatter/output_formatter.rs
+++ b/crates/shirabe-external-packages/src/symfony/component/console/formatter/output_formatter.rs
@@ -26,7 +26,11 @@ impl OutputFormatter {
todo!()
}
- pub fn set_style(&mut self, name: &str, style: crate::symfony::component::console::formatter::output_formatter_style::OutputFormatterStyle) {
+ pub fn set_style(
+ &mut self,
+ name: &str,
+ style: crate::symfony::component::console::formatter::output_formatter_style::OutputFormatterStyle,
+ ) {
todo!()
}
}
diff --git a/crates/shirabe-external-packages/src/symfony/component/console/formatter/output_formatter_style.rs b/crates/shirabe-external-packages/src/symfony/component/console/formatter/output_formatter_style.rs
index 8be111d..c82cf35 100644
--- a/crates/shirabe-external-packages/src/symfony/component/console/formatter/output_formatter_style.rs
+++ b/crates/shirabe-external-packages/src/symfony/component/console/formatter/output_formatter_style.rs
@@ -2,7 +2,11 @@
pub struct OutputFormatterStyle;
impl OutputFormatterStyle {
- pub fn new(foreground: Option<&str>, background: Option<&str>, options: Option<Vec<String>>) -> Self {
+ pub fn new(
+ foreground: Option<&str>,
+ background: Option<&str>,
+ options: Option<Vec<String>>,
+ ) -> Self {
todo!()
}
}
diff --git a/crates/shirabe-external-packages/src/symfony/component/console/helper/question_helper.rs b/crates/shirabe-external-packages/src/symfony/component/console/helper/question_helper.rs
index ade7c06..2f2acf8 100644
--- a/crates/shirabe-external-packages/src/symfony/component/console/helper/question_helper.rs
+++ b/crates/shirabe-external-packages/src/symfony/component/console/helper/question_helper.rs
@@ -1,7 +1,7 @@
-use shirabe_php_shim::PhpMixed;
use crate::symfony::component::console::input::input_interface::InputInterface;
use crate::symfony::component::console::output::output_interface::OutputInterface;
use crate::symfony::component::console::question::question::Question;
+use shirabe_php_shim::PhpMixed;
#[derive(Debug)]
pub struct QuestionHelper;
diff --git a/crates/shirabe-external-packages/src/symfony/component/console/helper/table.rs b/crates/shirabe-external-packages/src/symfony/component/console/helper/table.rs
index 0244c73..c24a19e 100644
--- a/crates/shirabe-external-packages/src/symfony/component/console/helper/table.rs
+++ b/crates/shirabe-external-packages/src/symfony/component/console/helper/table.rs
@@ -1,5 +1,5 @@
-use shirabe_php_shim::PhpMixed;
use crate::symfony::component::console::output::output_interface::OutputInterface;
+use shirabe_php_shim::PhpMixed;
#[derive(Debug)]
pub struct Table;
diff --git a/crates/shirabe-external-packages/src/symfony/component/console/input/array_input.rs b/crates/shirabe-external-packages/src/symfony/component/console/input/array_input.rs
index c70e798..b09762c 100644
--- a/crates/shirabe-external-packages/src/symfony/component/console/input/array_input.rs
+++ b/crates/shirabe-external-packages/src/symfony/component/console/input/array_input.rs
@@ -1,31 +1,69 @@
-use shirabe_php_shim::PhpMixed;
-use indexmap::IndexMap;
-use crate::symfony::component::console::input::input_interface::InputInterface;
use crate::symfony::component::console::input::input_definition::InputDefinition;
+use crate::symfony::component::console::input::input_interface::InputInterface;
+use indexmap::IndexMap;
+use shirabe_php_shim::PhpMixed;
#[derive(Debug)]
pub struct ArrayInput;
impl ArrayInput {
- pub fn new(parameters: IndexMap<String, PhpMixed>, definition: Option<InputDefinition>) -> Self {
+ pub fn new(
+ parameters: IndexMap<String, PhpMixed>,
+ definition: Option<InputDefinition>,
+ ) -> Self {
todo!()
}
}
impl InputInterface for ArrayInput {
- fn get_first_argument(&self) -> Option<String> { todo!() }
- fn has_parameter_option(&self, _values: &[&str], _only_params: bool) -> bool { todo!() }
- fn get_parameter_option(&self, _values: &[&str], _default: PhpMixed, _only_params: bool) -> PhpMixed { todo!() }
- fn bind(&mut self, _definition: &InputDefinition) -> anyhow::Result<()> { todo!() }
- fn validate(&self) -> anyhow::Result<()> { todo!() }
- fn get_arguments(&self) -> IndexMap<String, PhpMixed> { todo!() }
- fn get_argument(&self, _name: &str) -> PhpMixed { todo!() }
- fn set_argument(&mut self, _name: &str, _value: PhpMixed) -> anyhow::Result<()> { todo!() }
- fn has_argument(&self, _name: &str) -> bool { todo!() }
- fn get_options(&self) -> IndexMap<String, PhpMixed> { todo!() }
- fn get_option(&self, _name: &str) -> PhpMixed { todo!() }
- fn set_option(&mut self, _name: &str, _value: PhpMixed) -> anyhow::Result<()> { todo!() }
- fn has_option(&self, _name: &str) -> bool { todo!() }
- fn is_interactive(&self) -> bool { todo!() }
- fn set_interactive(&mut self, _interactive: bool) { todo!() }
+ fn get_first_argument(&self) -> Option<String> {
+ todo!()
+ }
+ fn has_parameter_option(&self, _values: &[&str], _only_params: bool) -> bool {
+ todo!()
+ }
+ fn get_parameter_option(
+ &self,
+ _values: &[&str],
+ _default: PhpMixed,
+ _only_params: bool,
+ ) -> PhpMixed {
+ todo!()
+ }
+ fn bind(&mut self, _definition: &InputDefinition) -> anyhow::Result<()> {
+ todo!()
+ }
+ fn validate(&self) -> anyhow::Result<()> {
+ todo!()
+ }
+ fn get_arguments(&self) -> IndexMap<String, PhpMixed> {
+ todo!()
+ }
+ fn get_argument(&self, _name: &str) -> PhpMixed {
+ todo!()
+ }
+ fn set_argument(&mut self, _name: &str, _value: PhpMixed) -> anyhow::Result<()> {
+ todo!()
+ }
+ fn has_argument(&self, _name: &str) -> bool {
+ todo!()
+ }
+ fn get_options(&self) -> IndexMap<String, PhpMixed> {
+ todo!()
+ }
+ fn get_option(&self, _name: &str) -> PhpMixed {
+ todo!()
+ }
+ fn set_option(&mut self, _name: &str, _value: PhpMixed) -> anyhow::Result<()> {
+ todo!()
+ }
+ fn has_option(&self, _name: &str) -> bool {
+ todo!()
+ }
+ fn is_interactive(&self) -> bool {
+ todo!()
+ }
+ fn set_interactive(&mut self, _interactive: bool) {
+ todo!()
+ }
}
diff --git a/crates/shirabe-external-packages/src/symfony/component/console/input/input_interface.rs b/crates/shirabe-external-packages/src/symfony/component/console/input/input_interface.rs
index 04e302e..ef4b009 100644
--- a/crates/shirabe-external-packages/src/symfony/component/console/input/input_interface.rs
+++ b/crates/shirabe-external-packages/src/symfony/component/console/input/input_interface.rs
@@ -3,8 +3,16 @@ use shirabe_php_shim::PhpMixed;
pub trait InputInterface {
fn get_first_argument(&self) -> Option<String>;
fn has_parameter_option(&self, values: &[&str], only_params: bool) -> bool;
- fn get_parameter_option(&self, values: &[&str], default: PhpMixed, only_params: bool) -> PhpMixed;
- fn bind(&mut self, definition: &crate::symfony::component::console::input::input_definition::InputDefinition) -> anyhow::Result<()>;
+ fn get_parameter_option(
+ &self,
+ values: &[&str],
+ default: PhpMixed,
+ only_params: bool,
+ ) -> PhpMixed;
+ fn bind(
+ &mut self,
+ definition: &crate::symfony::component::console::input::input_definition::InputDefinition,
+ ) -> anyhow::Result<()>;
fn validate(&self) -> anyhow::Result<()>;
fn get_arguments(&self) -> indexmap::IndexMap<String, PhpMixed>;
fn get_argument(&self, name: &str) -> PhpMixed;
diff --git a/crates/shirabe-external-packages/src/symfony/component/console/input/string_input.rs b/crates/shirabe-external-packages/src/symfony/component/console/input/string_input.rs
index 3c401eb..248782d 100644
--- a/crates/shirabe-external-packages/src/symfony/component/console/input/string_input.rs
+++ b/crates/shirabe-external-packages/src/symfony/component/console/input/string_input.rs
@@ -1,7 +1,7 @@
-use shirabe_php_shim::PhpMixed;
-use indexmap::IndexMap;
-use crate::symfony::component::console::input::input_interface::InputInterface;
use crate::symfony::component::console::input::input_definition::InputDefinition;
+use crate::symfony::component::console::input::input_interface::InputInterface;
+use indexmap::IndexMap;
+use shirabe_php_shim::PhpMixed;
#[derive(Debug)]
pub struct StringInput;
@@ -13,19 +13,54 @@ impl StringInput {
}
impl InputInterface for StringInput {
- fn get_first_argument(&self) -> Option<String> { todo!() }
- fn has_parameter_option(&self, _values: &[&str], _only_params: bool) -> bool { todo!() }
- fn get_parameter_option(&self, _values: &[&str], _default: PhpMixed, _only_params: bool) -> PhpMixed { todo!() }
- fn bind(&mut self, _definition: &InputDefinition) -> anyhow::Result<()> { todo!() }
- fn validate(&self) -> anyhow::Result<()> { todo!() }
- fn get_arguments(&self) -> IndexMap<String, PhpMixed> { todo!() }
- fn get_argument(&self, _name: &str) -> PhpMixed { todo!() }
- fn set_argument(&mut self, _name: &str, _value: PhpMixed) -> anyhow::Result<()> { todo!() }
- fn has_argument(&self, _name: &str) -> bool { todo!() }
- fn get_options(&self) -> IndexMap<String, PhpMixed> { todo!() }
- fn get_option(&self, _name: &str) -> PhpMixed { todo!() }
- fn set_option(&mut self, _name: &str, _value: PhpMixed) -> anyhow::Result<()> { todo!() }
- fn has_option(&self, _name: &str) -> bool { todo!() }
- fn is_interactive(&self) -> bool { todo!() }
- fn set_interactive(&mut self, _interactive: bool) { todo!() }
+ fn get_first_argument(&self) -> Option<String> {
+ todo!()
+ }
+ fn has_parameter_option(&self, _values: &[&str], _only_params: bool) -> bool {
+ todo!()
+ }
+ fn get_parameter_option(
+ &self,
+ _values: &[&str],
+ _default: PhpMixed,
+ _only_params: bool,
+ ) -> PhpMixed {
+ todo!()
+ }
+ fn bind(&mut self, _definition: &InputDefinition) -> anyhow::Result<()> {
+ todo!()
+ }
+ fn validate(&self) -> anyhow::Result<()> {
+ todo!()
+ }
+ fn get_arguments(&self) -> IndexMap<String, PhpMixed> {
+ todo!()
+ }
+ fn get_argument(&self, _name: &str) -> PhpMixed {
+ todo!()
+ }
+ fn set_argument(&mut self, _name: &str, _value: PhpMixed) -> anyhow::Result<()> {
+ todo!()
+ }
+ fn has_argument(&self, _name: &str) -> bool {
+ todo!()
+ }
+ fn get_options(&self) -> IndexMap<String, PhpMixed> {
+ todo!()
+ }
+ fn get_option(&self, _name: &str) -> PhpMixed {
+ todo!()
+ }
+ fn set_option(&mut self, _name: &str, _value: PhpMixed) -> anyhow::Result<()> {
+ todo!()
+ }
+ fn has_option(&self, _name: &str) -> bool {
+ todo!()
+ }
+ fn is_interactive(&self) -> bool {
+ todo!()
+ }
+ fn set_interactive(&mut self, _interactive: bool) {
+ todo!()
+ }
}
diff --git a/crates/shirabe-external-packages/src/symfony/component/console/output/console_output.rs b/crates/shirabe-external-packages/src/symfony/component/console/output/console_output.rs
index 98133df..150c8ae 100644
--- a/crates/shirabe-external-packages/src/symfony/component/console/output/console_output.rs
+++ b/crates/shirabe-external-packages/src/symfony/component/console/output/console_output.rs
@@ -1,12 +1,16 @@
use crate::symfony::component::console::formatter::output_formatter::OutputFormatter;
-use crate::symfony::component::console::output::output_interface::OutputInterface;
use crate::symfony::component::console::output::console_output_interface::ConsoleOutputInterface;
+use crate::symfony::component::console::output::output_interface::OutputInterface;
#[derive(Debug)]
pub struct ConsoleOutput;
impl ConsoleOutput {
- pub fn new(verbosity: i64, decorated: Option<bool>, formatter: Option<OutputFormatter>) -> Self {
+ pub fn new(
+ verbosity: i64,
+ decorated: Option<bool>,
+ formatter: Option<OutputFormatter>,
+ ) -> Self {
todo!()
}
@@ -16,16 +20,40 @@ impl ConsoleOutput {
}
impl OutputInterface for ConsoleOutput {
- fn write(&mut self, _messages: &str, _newline: bool, _type: i64) { todo!() }
- fn writeln(&mut self, _messages: &str, _type: i64) { todo!() }
- fn set_verbosity(&mut self, _level: i64) { todo!() }
- fn get_verbosity(&self) -> i64 { todo!() }
- fn is_quiet(&self) -> bool { todo!() }
- fn is_verbose(&self) -> bool { todo!() }
- fn is_very_verbose(&self) -> bool { todo!() }
- fn is_debug(&self) -> bool { todo!() }
- fn set_decorated(&mut self, _decorated: bool) { todo!() }
- fn is_decorated(&self) -> bool { todo!() }
- fn set_formatter(&mut self, _formatter: OutputFormatter) { todo!() }
- fn get_formatter(&self) -> &OutputFormatter { todo!() }
+ fn write(&mut self, _messages: &str, _newline: bool, _type: i64) {
+ todo!()
+ }
+ fn writeln(&mut self, _messages: &str, _type: i64) {
+ todo!()
+ }
+ fn set_verbosity(&mut self, _level: i64) {
+ todo!()
+ }
+ fn get_verbosity(&self) -> i64 {
+ todo!()
+ }
+ fn is_quiet(&self) -> bool {
+ todo!()
+ }
+ fn is_verbose(&self) -> bool {
+ todo!()
+ }
+ fn is_very_verbose(&self) -> bool {
+ todo!()
+ }
+ fn is_debug(&self) -> bool {
+ todo!()
+ }
+ fn set_decorated(&mut self, _decorated: bool) {
+ todo!()
+ }
+ fn is_decorated(&self) -> bool {
+ todo!()
+ }
+ fn set_formatter(&mut self, _formatter: OutputFormatter) {
+ todo!()
+ }
+ fn get_formatter(&self) -> &OutputFormatter {
+ todo!()
+ }
}
diff --git a/crates/shirabe-external-packages/src/symfony/component/console/question/choice_question.rs b/crates/shirabe-external-packages/src/symfony/component/console/question/choice_question.rs
index 5b32ced..e134de2 100644
--- a/crates/shirabe-external-packages/src/symfony/component/console/question/choice_question.rs
+++ b/crates/shirabe-external-packages/src/symfony/component/console/question/choice_question.rs
@@ -1,5 +1,5 @@
-use shirabe_php_shim::PhpMixed;
use crate::symfony::component::console::question::question::Question;
+use shirabe_php_shim::PhpMixed;
#[derive(Debug)]
pub struct ChoiceQuestion(pub Question);
diff --git a/crates/shirabe-external-packages/src/symfony/component/console/question/question.rs b/crates/shirabe-external-packages/src/symfony/component/console/question/question.rs
index cfbdd25..d749fce 100644
--- a/crates/shirabe-external-packages/src/symfony/component/console/question/question.rs
+++ b/crates/shirabe-external-packages/src/symfony/component/console/question/question.rs
@@ -8,7 +8,10 @@ impl Question {
todo!()
}
- pub fn set_validator(&mut self, validator: Option<Box<dyn Fn(Option<PhpMixed>) -> anyhow::Result<PhpMixed>>>) {
+ pub fn set_validator(
+ &mut self,
+ validator: Option<Box<dyn Fn(Option<PhpMixed>) -> anyhow::Result<PhpMixed>>>,
+ ) {
todo!()
}
diff --git a/crates/shirabe-external-packages/src/symfony/component/console/single_command_application.rs b/crates/shirabe-external-packages/src/symfony/component/console/single_command_application.rs
index 9642aa0..cce75db 100644
--- a/crates/shirabe-external-packages/src/symfony/component/console/single_command_application.rs
+++ b/crates/shirabe-external-packages/src/symfony/component/console/single_command_application.rs
@@ -16,7 +16,10 @@ impl SingleCommandApplication {
todo!()
}
- pub fn set_code(&mut self, code: Box<dyn Fn(&dyn std::any::Any, &dyn std::any::Any) -> i64>) -> &mut Self {
+ pub fn set_code(
+ &mut self,
+ code: Box<dyn Fn(&dyn std::any::Any, &dyn std::any::Any) -> i64>,
+ ) -> &mut Self {
todo!()
}
diff --git a/crates/shirabe-external-packages/src/symfony/component/filesystem/filesystem.rs b/crates/shirabe-external-packages/src/symfony/component/filesystem/filesystem.rs
index 9999419..ef48c3d 100644
--- a/crates/shirabe-external-packages/src/symfony/component/filesystem/filesystem.rs
+++ b/crates/shirabe-external-packages/src/symfony/component/filesystem/filesystem.rs
@@ -8,7 +8,12 @@ impl Filesystem {
todo!()
}
- pub fn copy(&self, origin_file: &str, target_file: &str, override_file: bool) -> anyhow::Result<()> {
+ pub fn copy(
+ &self,
+ origin_file: &str,
+ target_file: &str,
+ override_file: bool,
+ ) -> anyhow::Result<()> {
todo!()
}
@@ -20,7 +25,12 @@ impl Filesystem {
todo!()
}
- pub fn touch(&self, files: PhpMixed, time: Option<i64>, atime: Option<i64>) -> anyhow::Result<()> {
+ pub fn touch(
+ &self,
+ files: PhpMixed,
+ time: Option<i64>,
+ atime: Option<i64>,
+ ) -> anyhow::Result<()> {
todo!()
}
@@ -28,7 +38,13 @@ impl Filesystem {
todo!()
}
- pub fn chmod(&self, files: PhpMixed, mode: u32, umask: u32, recursive: bool) -> anyhow::Result<()> {
+ pub fn chmod(
+ &self,
+ files: PhpMixed,
+ mode: u32,
+ umask: u32,
+ recursive: bool,
+ ) -> anyhow::Result<()> {
todo!()
}
@@ -44,7 +60,12 @@ impl Filesystem {
todo!()
}
- pub fn symlink(&self, origin_dir: &str, target_dir: &str, copy_on_windows: bool) -> anyhow::Result<()> {
+ pub fn symlink(
+ &self,
+ origin_dir: &str,
+ target_dir: &str,
+ copy_on_windows: bool,
+ ) -> anyhow::Result<()> {
todo!()
}
diff --git a/crates/shirabe-external-packages/src/symfony/component/process/process.rs b/crates/shirabe-external-packages/src/symfony/component/process/process.rs
index 7572f3b..c955790 100644
--- a/crates/shirabe-external-packages/src/symfony/component/process/process.rs
+++ b/crates/shirabe-external-packages/src/symfony/component/process/process.rs
@@ -1,5 +1,5 @@
-use shirabe_php_shim::PhpMixed;
use indexmap::IndexMap;
+use shirabe_php_shim::PhpMixed;
#[derive(Debug)]
pub struct Process;
@@ -44,7 +44,10 @@ impl Process {
todo!()
}
- pub fn must_run(&mut self, callback: Option<Box<dyn FnMut(&str, &str)>>) -> anyhow::Result<&mut Self> {
+ pub fn must_run(
+ &mut self,
+ callback: Option<Box<dyn FnMut(&str, &str)>>,
+ ) -> anyhow::Result<&mut Self> {
todo!()
}
diff --git a/crates/shirabe-external-packages/src/symfony/console/formatter/output_formatter_style.rs b/crates/shirabe-external-packages/src/symfony/console/formatter/output_formatter_style.rs
index 8be111d..c82cf35 100644
--- a/crates/shirabe-external-packages/src/symfony/console/formatter/output_formatter_style.rs
+++ b/crates/shirabe-external-packages/src/symfony/console/formatter/output_formatter_style.rs
@@ -2,7 +2,11 @@
pub struct OutputFormatterStyle;
impl OutputFormatterStyle {
- pub fn new(foreground: Option<&str>, background: Option<&str>, options: Option<Vec<String>>) -> Self {
+ pub fn new(
+ foreground: Option<&str>,
+ background: Option<&str>,
+ options: Option<Vec<String>>,
+ ) -> Self {
todo!()
}
}
diff --git a/crates/shirabe-external-packages/src/symfony/console/input/array_input.rs b/crates/shirabe-external-packages/src/symfony/console/input/array_input.rs
index 1eb3883..68c589e 100644
--- a/crates/shirabe-external-packages/src/symfony/console/input/array_input.rs
+++ b/crates/shirabe-external-packages/src/symfony/console/input/array_input.rs
@@ -1,6 +1,6 @@
-use shirabe_php_shim::PhpMixed;
-use indexmap::IndexMap;
use crate::symfony::console::input::input_interface::InputInterface;
+use indexmap::IndexMap;
+use shirabe_php_shim::PhpMixed;
#[derive(Debug)]
pub struct ArrayInput;
@@ -12,18 +12,51 @@ impl ArrayInput {
}
impl InputInterface for ArrayInput {
- fn get_first_argument(&self) -> Option<String> { todo!() }
- fn has_parameter_option(&self, _values: &[&str], _only_params: bool) -> bool { todo!() }
- fn get_parameter_option(&self, _values: &[&str], _default: PhpMixed, _only_params: bool) -> PhpMixed { todo!() }
- fn validate(&self) -> anyhow::Result<()> { todo!() }
- fn get_arguments(&self) -> IndexMap<String, PhpMixed> { todo!() }
- fn get_argument(&self, _name: &str) -> PhpMixed { todo!() }
- fn set_argument(&mut self, _name: &str, _value: PhpMixed) -> anyhow::Result<()> { todo!() }
- fn has_argument(&self, _name: &str) -> bool { todo!() }
- fn get_options(&self) -> IndexMap<String, PhpMixed> { todo!() }
- fn get_option(&self, _name: &str) -> PhpMixed { todo!() }
- fn set_option(&mut self, _name: &str, _value: PhpMixed) -> anyhow::Result<()> { todo!() }
- fn has_option(&self, _name: &str) -> bool { todo!() }
- fn is_interactive(&self) -> bool { todo!() }
- fn set_interactive(&mut self, _interactive: bool) { todo!() }
+ fn get_first_argument(&self) -> Option<String> {
+ todo!()
+ }
+ fn has_parameter_option(&self, _values: &[&str], _only_params: bool) -> bool {
+ todo!()
+ }
+ fn get_parameter_option(
+ &self,
+ _values: &[&str],
+ _default: PhpMixed,
+ _only_params: bool,
+ ) -> PhpMixed {
+ todo!()
+ }
+ fn validate(&self) -> anyhow::Result<()> {
+ todo!()
+ }
+ fn get_arguments(&self) -> IndexMap<String, PhpMixed> {
+ todo!()
+ }
+ fn get_argument(&self, _name: &str) -> PhpMixed {
+ todo!()
+ }
+ fn set_argument(&mut self, _name: &str, _value: PhpMixed) -> anyhow::Result<()> {
+ todo!()
+ }
+ fn has_argument(&self, _name: &str) -> bool {
+ todo!()
+ }
+ fn get_options(&self) -> IndexMap<String, PhpMixed> {
+ todo!()
+ }
+ fn get_option(&self, _name: &str) -> PhpMixed {
+ todo!()
+ }
+ fn set_option(&mut self, _name: &str, _value: PhpMixed) -> anyhow::Result<()> {
+ todo!()
+ }
+ fn has_option(&self, _name: &str) -> bool {
+ todo!()
+ }
+ fn is_interactive(&self) -> bool {
+ todo!()
+ }
+ fn set_interactive(&mut self, _interactive: bool) {
+ todo!()
+ }
}
diff --git a/crates/shirabe-external-packages/src/symfony/console/input/input_argument.rs b/crates/shirabe-external-packages/src/symfony/console/input/input_argument.rs
index 1f70581..f5c29e8 100644
--- a/crates/shirabe-external-packages/src/symfony/console/input/input_argument.rs
+++ b/crates/shirabe-external-packages/src/symfony/console/input/input_argument.rs
@@ -8,7 +8,12 @@ impl InputArgument {
pub const OPTIONAL: i64 = 2;
pub const IS_ARRAY: i64 = 4;
- pub fn new(name: &str, mode: Option<i64>, description: &str, default: Option<PhpMixed>) -> Self {
+ pub fn new(
+ name: &str,
+ mode: Option<i64>,
+ description: &str,
+ default: Option<PhpMixed>,
+ ) -> Self {
todo!()
}
diff --git a/crates/shirabe-external-packages/src/symfony/console/input/input_interface.rs b/crates/shirabe-external-packages/src/symfony/console/input/input_interface.rs
index 2e25dea..d1c11c2 100644
--- a/crates/shirabe-external-packages/src/symfony/console/input/input_interface.rs
+++ b/crates/shirabe-external-packages/src/symfony/console/input/input_interface.rs
@@ -1,10 +1,15 @@
-use shirabe_php_shim::PhpMixed;
use indexmap::IndexMap;
+use shirabe_php_shim::PhpMixed;
pub trait InputInterface {
fn get_first_argument(&self) -> Option<String>;
fn has_parameter_option(&self, values: &[&str], only_params: bool) -> bool;
- fn get_parameter_option(&self, values: &[&str], default: PhpMixed, only_params: bool) -> PhpMixed;
+ fn get_parameter_option(
+ &self,
+ values: &[&str],
+ default: PhpMixed,
+ only_params: bool,
+ ) -> PhpMixed;
fn validate(&self) -> anyhow::Result<()>;
fn get_arguments(&self) -> IndexMap<String, PhpMixed>;
fn get_argument(&self, name: &str) -> PhpMixed;
diff --git a/crates/shirabe-external-packages/src/symfony/console/input/string_input.rs b/crates/shirabe-external-packages/src/symfony/console/input/string_input.rs
index d552380..12c6d9d 100644
--- a/crates/shirabe-external-packages/src/symfony/console/input/string_input.rs
+++ b/crates/shirabe-external-packages/src/symfony/console/input/string_input.rs
@@ -1,6 +1,6 @@
-use shirabe_php_shim::PhpMixed;
-use indexmap::IndexMap;
use crate::symfony::console::input::input_interface::InputInterface;
+use indexmap::IndexMap;
+use shirabe_php_shim::PhpMixed;
#[derive(Debug)]
pub struct StringInput;
@@ -12,18 +12,51 @@ impl StringInput {
}
impl InputInterface for StringInput {
- fn get_first_argument(&self) -> Option<String> { todo!() }
- fn has_parameter_option(&self, _values: &[&str], _only_params: bool) -> bool { todo!() }
- fn get_parameter_option(&self, _values: &[&str], _default: PhpMixed, _only_params: bool) -> PhpMixed { todo!() }
- fn validate(&self) -> anyhow::Result<()> { todo!() }
- fn get_arguments(&self) -> IndexMap<String, PhpMixed> { todo!() }
- fn get_argument(&self, _name: &str) -> PhpMixed { todo!() }
- fn set_argument(&mut self, _name: &str, _value: PhpMixed) -> anyhow::Result<()> { todo!() }
- fn has_argument(&self, _name: &str) -> bool { todo!() }
- fn get_options(&self) -> IndexMap<String, PhpMixed> { todo!() }
- fn get_option(&self, _name: &str) -> PhpMixed { todo!() }
- fn set_option(&mut self, _name: &str, _value: PhpMixed) -> anyhow::Result<()> { todo!() }
- fn has_option(&self, _name: &str) -> bool { todo!() }
- fn is_interactive(&self) -> bool { todo!() }
- fn set_interactive(&mut self, _interactive: bool) { todo!() }
+ fn get_first_argument(&self) -> Option<String> {
+ todo!()
+ }
+ fn has_parameter_option(&self, _values: &[&str], _only_params: bool) -> bool {
+ todo!()
+ }
+ fn get_parameter_option(
+ &self,
+ _values: &[&str],
+ _default: PhpMixed,
+ _only_params: bool,
+ ) -> PhpMixed {
+ todo!()
+ }
+ fn validate(&self) -> anyhow::Result<()> {
+ todo!()
+ }
+ fn get_arguments(&self) -> IndexMap<String, PhpMixed> {
+ todo!()
+ }
+ fn get_argument(&self, _name: &str) -> PhpMixed {
+ todo!()
+ }
+ fn set_argument(&mut self, _name: &str, _value: PhpMixed) -> anyhow::Result<()> {
+ todo!()
+ }
+ fn has_argument(&self, _name: &str) -> bool {
+ todo!()
+ }
+ fn get_options(&self) -> IndexMap<String, PhpMixed> {
+ todo!()
+ }
+ fn get_option(&self, _name: &str) -> PhpMixed {
+ todo!()
+ }
+ fn set_option(&mut self, _name: &str, _value: PhpMixed) -> anyhow::Result<()> {
+ todo!()
+ }
+ fn has_option(&self, _name: &str) -> bool {
+ todo!()
+ }
+ fn is_interactive(&self) -> bool {
+ todo!()
+ }
+ fn set_interactive(&mut self, _interactive: bool) {
+ todo!()
+ }
}
diff --git a/crates/shirabe-external-packages/src/symfony/console/output/stream_output.rs b/crates/shirabe-external-packages/src/symfony/console/output/stream_output.rs
index 8728fa6..e5d83fb 100644
--- a/crates/shirabe-external-packages/src/symfony/console/output/stream_output.rs
+++ b/crates/shirabe-external-packages/src/symfony/console/output/stream_output.rs
@@ -1,5 +1,5 @@
-use shirabe_php_shim::PhpMixed;
use crate::symfony::console::output::output_interface::OutputInterface;
+use shirabe_php_shim::PhpMixed;
#[derive(Debug)]
pub struct StreamOutput;
@@ -11,14 +11,34 @@ impl StreamOutput {
}
impl OutputInterface for StreamOutput {
- fn write(&mut self, _messages: &str, _newline: bool, _type: i64) { todo!() }
- fn writeln(&mut self, _messages: &str, _type: i64) { todo!() }
- fn set_verbosity(&mut self, _level: i64) { todo!() }
- fn get_verbosity(&self) -> i64 { todo!() }
- fn is_quiet(&self) -> bool { todo!() }
- fn is_verbose(&self) -> bool { todo!() }
- fn is_very_verbose(&self) -> bool { todo!() }
- fn is_debug(&self) -> bool { todo!() }
- fn set_decorated(&mut self, _decorated: bool) { todo!() }
- fn is_decorated(&self) -> bool { todo!() }
+ fn write(&mut self, _messages: &str, _newline: bool, _type: i64) {
+ todo!()
+ }
+ fn writeln(&mut self, _messages: &str, _type: i64) {
+ todo!()
+ }
+ fn set_verbosity(&mut self, _level: i64) {
+ todo!()
+ }
+ fn get_verbosity(&self) -> i64 {
+ todo!()
+ }
+ fn is_quiet(&self) -> bool {
+ todo!()
+ }
+ fn is_verbose(&self) -> bool {
+ todo!()
+ }
+ fn is_very_verbose(&self) -> bool {
+ todo!()
+ }
+ fn is_debug(&self) -> bool {
+ todo!()
+ }
+ fn set_decorated(&mut self, _decorated: bool) {
+ todo!()
+ }
+ fn is_decorated(&self) -> bool {
+ todo!()
+ }
}
diff --git a/crates/shirabe-external-packages/src/symfony/console/question/question.rs b/crates/shirabe-external-packages/src/symfony/console/question/question.rs
index 2fc7368..34bb6a4 100644
--- a/crates/shirabe-external-packages/src/symfony/console/question/question.rs
+++ b/crates/shirabe-external-packages/src/symfony/console/question/question.rs
@@ -8,7 +8,10 @@ impl Question {
todo!()
}
- pub fn set_validator(&mut self, validator: Option<Box<dyn Fn(Option<PhpMixed>) -> anyhow::Result<PhpMixed>>>) {
+ pub fn set_validator(
+ &mut self,
+ validator: Option<Box<dyn Fn(Option<PhpMixed>) -> anyhow::Result<PhpMixed>>>,
+ ) {
todo!()
}
diff --git a/crates/shirabe-external-packages/src/symfony/console/style/symfony_style.rs b/crates/shirabe-external-packages/src/symfony/console/style/symfony_style.rs
index 288a79d..7f7acd6 100644
--- a/crates/shirabe-external-packages/src/symfony/console/style/symfony_style.rs
+++ b/crates/shirabe-external-packages/src/symfony/console/style/symfony_style.rs
@@ -1,6 +1,6 @@
-use shirabe_php_shim::PhpMixed;
-use crate::symfony::console::output::output_interface::OutputInterface;
use crate::symfony::console::input::input_interface::InputInterface;
+use crate::symfony::console::output::output_interface::OutputInterface;
+use shirabe_php_shim::PhpMixed;
#[derive(Debug)]
pub struct SymfonyStyle;
@@ -50,11 +50,20 @@ impl SymfonyStyle {
todo!()
}
- pub fn ask(&mut self, question: &str, default: Option<&str>, validator: Option<Box<dyn Fn(Option<PhpMixed>) -> anyhow::Result<PhpMixed>>>) -> PhpMixed {
+ pub fn ask(
+ &mut self,
+ question: &str,
+ default: Option<&str>,
+ validator: Option<Box<dyn Fn(Option<PhpMixed>) -> anyhow::Result<PhpMixed>>>,
+ ) -> PhpMixed {
todo!()
}
- pub fn ask_hidden(&mut self, question: &str, validator: Option<Box<dyn Fn(Option<PhpMixed>) -> anyhow::Result<PhpMixed>>>) -> PhpMixed {
+ pub fn ask_hidden(
+ &mut self,
+ question: &str,
+ validator: Option<Box<dyn Fn(Option<PhpMixed>) -> anyhow::Result<PhpMixed>>>,
+ ) -> PhpMixed {
todo!()
}
@@ -62,7 +71,12 @@ impl SymfonyStyle {
todo!()
}
- pub fn choice(&mut self, question: &str, choices: Vec<PhpMixed>, default: Option<PhpMixed>) -> PhpMixed {
+ pub fn choice(
+ &mut self,
+ question: &str,
+ choices: Vec<PhpMixed>,
+ default: Option<PhpMixed>,
+ ) -> PhpMixed {
todo!()
}
diff --git a/crates/shirabe-php-shim/src/lib.rs b/crates/shirabe-php-shim/src/lib.rs
index 5575a79..323d8f8 100644
--- a/crates/shirabe-php-shim/src/lib.rs
+++ b/crates/shirabe-php-shim/src/lib.rs
@@ -194,7 +194,12 @@ pub fn array_search_in_vec(needle: &str, haystack: &[String]) -> Option<usize> {
todo!()
}
-pub fn array_splice<T: Clone>(array: &mut Vec<T>, offset: usize, length: usize, replacement: &[T]) -> Vec<T> {
+pub fn array_splice<T: Clone>(
+ array: &mut Vec<T>,
+ offset: usize,
+ length: usize,
+ replacement: &[T],
+) -> Vec<T> {
todo!()
}
@@ -500,7 +505,11 @@ impl PharData {
todo!()
}
- pub fn build_from_iterator(&self, iter: &mut dyn Iterator<Item = std::path::PathBuf>, base: &str) {
+ pub fn build_from_iterator(
+ &self,
+ iter: &mut dyn Iterator<Item = std::path::PathBuf>,
+ base: &str,
+ ) {
todo!()
}
@@ -687,7 +696,10 @@ pub fn substr_count(haystack: &str, needle: &str) -> i64 {
todo!()
}
-pub fn openssl_x509_parse(certificate: &str, short_names: bool) -> Option<IndexMap<String, Box<PhpMixed>>> {
+pub fn openssl_x509_parse(
+ certificate: &str,
+ short_names: bool,
+) -> Option<IndexMap<String, Box<PhpMixed>>> {
todo!()
}
@@ -736,9 +748,7 @@ pub fn spl_autoload_register(
todo!()
}
-pub fn spl_autoload_unregister(
- callback: Box<dyn Fn(&str) -> PhpMixed + Send + Sync>,
-) -> bool {
+pub fn spl_autoload_unregister(callback: Box<dyn Fn(&str) -> PhpMixed + Send + Sync>) -> bool {
let _ = callback;
todo!()
}
@@ -1129,11 +1139,7 @@ pub fn feof(stream: PhpMixed) -> bool {
todo!()
}
-pub fn str_replace_array(
- search: &[String],
- replace: &[String],
- subject: &str,
-) -> String {
+pub fn str_replace_array(search: &[String], replace: &[String], subject: &str) -> String {
todo!()
}
@@ -1160,7 +1166,11 @@ pub fn copy(source: &str, dest: &str) -> bool {
todo!()
}
-pub fn exec(command: &str, output: Option<&mut Vec<String>>, exit_code: Option<&mut i64>) -> Option<String> {
+pub fn exec(
+ command: &str,
+ output: Option<&mut Vec<String>>,
+ exit_code: Option<&mut i64>,
+) -> Option<String> {
todo!()
}
@@ -1168,7 +1178,12 @@ pub fn tempnam(dir: &str, prefix: &str) -> Option<String> {
todo!()
}
-pub fn openssl_verify(data: &str, signature: &[u8], pub_key_id: PhpMixed, algorithm: PhpMixed) -> i64 {
+pub fn openssl_verify(
+ data: &str,
+ signature: &[u8],
+ pub_key_id: PhpMixed,
+ algorithm: PhpMixed,
+) -> i64 {
todo!()
}
@@ -1219,11 +1234,13 @@ pub fn reset<T: Clone>(array: &[T]) -> Option<T> {
todo!()
}
-
pub const OPENSSL_ALGO_SHA384: i64 = 9;
pub const PHP_VERSION_ID: i64 = 80100;
-pub fn array_intersect_key(array1: &IndexMap<String, Box<PhpMixed>>, array2: &IndexMap<String, Box<PhpMixed>>) -> IndexMap<String, Box<PhpMixed>> {
+pub fn array_intersect_key(
+ array1: &IndexMap<String, Box<PhpMixed>>,
+ array2: &IndexMap<String, Box<PhpMixed>>,
+) -> IndexMap<String, Box<PhpMixed>> {
todo!()
}
@@ -1239,7 +1256,10 @@ pub fn serialize(value: &PhpMixed) -> String {
todo!()
}
-pub fn stream_context_create(options: &IndexMap<String, PhpMixed>, params: Option<&IndexMap<String, PhpMixed>>) -> PhpMixed {
+pub fn stream_context_create(
+ options: &IndexMap<String, PhpMixed>,
+ params: Option<&IndexMap<String, PhpMixed>>,
+) -> PhpMixed {
todo!()
}
@@ -1258,7 +1278,10 @@ where
todo!()
}
-pub fn array_replace_recursive(base: IndexMap<String, PhpMixed>, replacement: IndexMap<String, PhpMixed>) -> IndexMap<String, PhpMixed> {
+pub fn array_replace_recursive(
+ base: IndexMap<String, PhpMixed>,
+ replacement: IndexMap<String, PhpMixed>,
+) -> IndexMap<String, PhpMixed> {
todo!()
}
diff --git a/crates/shirabe-semver/src/compiling_matcher.rs b/crates/shirabe-semver/src/compiling_matcher.rs
index 7fb17ec..f6a3689 100644
--- a/crates/shirabe-semver/src/compiling_matcher.rs
+++ b/crates/shirabe-semver/src/compiling_matcher.rs
@@ -27,8 +27,8 @@ static TRANS_OP_INT: &[(i64, &str)] = &[
pub struct CompilingMatcher;
impl CompilingMatcher {
- fn compiled_checker_cache(
- ) -> &'static Mutex<IndexMap<String, Box<dyn Fn(String, bool) -> bool + Send + Sync>>> {
+ fn compiled_checker_cache()
+ -> &'static Mutex<IndexMap<String, Box<dyn Fn(String, bool) -> bool + Send + Sync>>> {
COMPILED_CHECKER_CACHE.get_or_init(|| Mutex::new(IndexMap::new()))
}
@@ -42,8 +42,7 @@ impl CompilingMatcher {
}
pub fn r#match(constraint: &dyn ConstraintInterface, operator: i64, version: String) -> bool {
- let result_cache_key =
- format!("{}{};{}", operator, constraint.__to_string(), version);
+ let result_cache_key = format!("{}{};{}", operator, constraint.__to_string(), version);
{
let cache = Self::result_cache().lock().unwrap();
@@ -59,7 +58,10 @@ impl CompilingMatcher {
.expect("unknown operator");
let result = constraint.matches(&Constraint::new(trans_op.to_string(), version));
- Self::result_cache().lock().unwrap().insert(result_cache_key, result);
+ Self::result_cache()
+ .lock()
+ .unwrap()
+ .insert(result_cache_key, result);
result
}
}
diff --git a/crates/shirabe-semver/src/constraint.rs b/crates/shirabe-semver/src/constraint.rs
new file mode 100644
index 0000000..8410b61
--- /dev/null
+++ b/crates/shirabe-semver/src/constraint.rs
@@ -0,0 +1,6 @@
+pub mod bound;
+pub mod constraint;
+pub mod constraint_interface;
+pub mod match_all_constraint;
+pub mod match_none_constraint;
+pub mod multi_constraint;
diff --git a/crates/shirabe-semver/src/constraint/constraint.rs b/crates/shirabe-semver/src/constraint/constraint.rs
index e35b3e4..b0c937c 100644
--- a/crates/shirabe-semver/src/constraint/constraint.rs
+++ b/crates/shirabe-semver/src/constraint/constraint.rs
@@ -131,26 +131,17 @@ impl Constraint {
if self.version.starts_with("dev-") {
if Self::OP_EQ == self.operator {
if Self::OP_EQ == other_operator {
- return format!(
- "$b && $v === {}",
- php::var_export_str(&self.version, true)
- );
+ return format!("$b && $v === {}", php::var_export_str(&self.version, true));
}
if Self::OP_NE == other_operator {
- return format!(
- "!$b || $v !== {}",
- php::var_export_str(&self.version, true)
- );
+ return format!("!$b || $v !== {}", php::var_export_str(&self.version, true));
}
return "false".to_string();
}
if Self::OP_NE == self.operator {
if Self::OP_EQ == other_operator {
- return format!(
- "!$b || $v !== {}",
- php::var_export_str(&self.version, true)
- );
+ return format!("!$b || $v !== {}", php::var_export_str(&self.version, true));
}
if Self::OP_NE == other_operator {
return "true".to_string();
@@ -276,7 +267,12 @@ impl Constraint {
};
if self
- .version_compare(version1, version2, Self::trans_op_int(operator), compare_branches)
+ .version_compare(
+ version1,
+ version2,
+ Self::trans_op_int(operator),
+ compare_branches,
+ )
.expect("valid operator")
{
return !(Self::trans_op_int(provider.operator) == provider_no_equal_op
diff --git a/crates/shirabe-semver/src/constraint/multi_constraint.rs b/crates/shirabe-semver/src/constraint/multi_constraint.rs
index ff7fbfb..86afa8d 100644
--- a/crates/shirabe-semver/src/constraint/multi_constraint.rs
+++ b/crates/shirabe-semver/src/constraint/multi_constraint.rs
@@ -108,7 +108,9 @@ impl MultiConstraint {
conjunctive: bool,
) -> anyhow::Result<Box<dyn ConstraintInterface>> {
if constraints.is_empty() {
- return Ok(Box::new(MatchAllConstraint { pretty_string: None }));
+ return Ok(Box::new(MatchAllConstraint {
+ pretty_string: None,
+ }));
}
if constraints.len() == 1 {
@@ -170,7 +172,8 @@ impl MultiConstraint {
true,
)
.unwrap(),
- ) as Box<dyn ConstraintInterface>)
+ )
+ as Box<dyn ConstraintInterface>)
} else {
None
}
@@ -280,11 +283,7 @@ impl ConstraintInterface for MultiConstraint {
return s.clone();
}
- let parts: Vec<String> = self
- .constraints
- .iter()
- .map(|c| c.__to_string())
- .collect();
+ let parts: Vec<String> = self.constraints.iter().map(|c| c.__to_string()).collect();
let sep = if self.conjunctive { " " } else { " || " };
let result = format!("[{}]", parts.join(sep));
diff --git a/crates/shirabe-semver/src/intervals.rs b/crates/shirabe-semver/src/intervals.rs
index 9da98de..be7466e 100644
--- a/crates/shirabe-semver/src/intervals.rs
+++ b/crates/shirabe-semver/src/intervals.rs
@@ -45,21 +45,29 @@ impl Intervals {
candidate: &dyn ConstraintInterface,
constraint: &dyn ConstraintInterface,
) -> anyhow::Result<bool> {
- if constraint.as_any().downcast_ref::<MatchAllConstraint>().is_some() {
+ if constraint
+ .as_any()
+ .downcast_ref::<MatchAllConstraint>()
+ .is_some()
+ {
return Ok(true);
}
- if candidate.as_any().downcast_ref::<MatchNoneConstraint>().is_some()
- || constraint.as_any().downcast_ref::<MatchNoneConstraint>().is_some()
+ if candidate
+ .as_any()
+ .downcast_ref::<MatchNoneConstraint>()
+ .is_some()
+ || constraint
+ .as_any()
+ .downcast_ref::<MatchNoneConstraint>()
+ .is_some()
{
return Ok(false);
}
// Phase B: ConstraintInterface needs clone_box() to create owned copies from references.
- let multi = MultiConstraint::new(
- vec![candidate.clone_box(), constraint.clone_box()],
- true,
- )?;
+ let multi =
+ MultiConstraint::new(vec![candidate.clone_box(), constraint.clone_box()], true)?;
let intersection_intervals = Self::get(&multi)?;
let candidate_intervals = Self::get(candidate)?;
@@ -128,7 +136,11 @@ impl Intervals {
pub fn compact_constraint(
constraint: &dyn ConstraintInterface,
) -> anyhow::Result<Box<dyn ConstraintInterface>> {
- if constraint.as_any().downcast_ref::<MultiConstraint>().is_none() {
+ if constraint
+ .as_any()
+ .downcast_ref::<MultiConstraint>()
+ .is_none()
+ {
return Ok(constraint.clone_box());
}
@@ -137,8 +149,7 @@ impl Intervals {
let mut has_numeric_match_all = false;
if intervals.numeric.len() == 1
- && intervals.numeric[0].get_start().__to_string()
- == Interval::from_zero().__to_string()
+ && intervals.numeric[0].get_start().__to_string() == Interval::from_zero().__to_string()
&& intervals.numeric[0].get_end().__to_string()
== Interval::until_positive_infinity().__to_string()
{
@@ -190,10 +201,8 @@ impl Intervals {
// count is 1 if entire constraint is just one != expression
if un_equal_constraints.len() > 1 {
- constraints.push(Box::new(MultiConstraint::new(
- un_equal_constraints,
- true,
- )?));
+ constraints
+ .push(Box::new(MultiConstraint::new(un_equal_constraints, true)?));
} else {
constraints.push(un_equal_constraints.into_iter().next().unwrap());
}
@@ -240,7 +249,9 @@ impl Intervals {
if intervals.branches.names.is_empty() {
if intervals.branches.exclude && has_numeric_match_all {
- return Ok(Box::new(MatchAllConstraint { pretty_string: None }));
+ return Ok(Box::new(MatchAllConstraint {
+ pretty_string: None,
+ }));
// otherwise constraint should contain a != operator and already cover this
}
} else {
@@ -262,12 +273,11 @@ impl Intervals {
// > 2.0 != dev-foo must return a conjunctive constraint
if intervals.branches.exclude {
if constraints.len() > 1 {
- let merged: Vec<Box<dyn ConstraintInterface>> = std::iter::once(
- Box::new(MultiConstraint::new(constraints, false)?)
- as Box<dyn ConstraintInterface>,
- )
- .chain(dev_constraints)
- .collect();
+ let merged: Vec<Box<dyn ConstraintInterface>> =
+ std::iter::once(Box::new(MultiConstraint::new(constraints, false)?)
+ as Box<dyn ConstraintInterface>)
+ .chain(dev_constraints)
+ .collect();
return Ok(Box::new(MultiConstraint::new(merged, true)?));
}
@@ -298,7 +308,9 @@ impl Intervals {
return Ok(constraints.into_iter().next().unwrap());
}
- Ok(Box::new(MatchNoneConstraint { pretty_string: None }))
+ Ok(Box::new(MatchNoneConstraint {
+ pretty_string: None,
+ }))
}
pub fn get(constraint: &dyn ConstraintInterface) -> anyhow::Result<IntervalCollection> {
@@ -325,7 +337,11 @@ impl Intervals {
constraint: &dyn ConstraintInterface,
stop_on_first_valid_interval: bool,
) -> anyhow::Result<IntervalCollection> {
- if constraint.as_any().downcast_ref::<MatchAllConstraint>().is_some() {
+ if constraint
+ .as_any()
+ .downcast_ref::<MatchAllConstraint>()
+ .is_some()
+ {
return Ok(IntervalCollection {
numeric: vec![Interval::new(
Interval::from_zero().clone(),
@@ -335,7 +351,11 @@ impl Intervals {
});
}
- if constraint.as_any().downcast_ref::<MatchNoneConstraint>().is_some() {
+ if constraint
+ .as_any()
+ .downcast_ref::<MatchNoneConstraint>()
+ .is_some()
+ {
return Ok(IntervalCollection {
numeric: vec![],
branches: Interval::no_dev(),
@@ -560,7 +580,8 @@ impl Intervals {
});
}
- if op.starts_with('>') { // > & >=
+ if op.starts_with('>') {
+ // > & >=
return Ok(IntervalCollection {
numeric: vec![Interval::new(
constraint.clone(),
@@ -569,7 +590,8 @@ impl Intervals {
branches: Interval::no_dev(),
});
}
- if op.starts_with('<') { // < & <=
+ if op.starts_with('<') {
+ // < & <=
return Ok(IntervalCollection {
numeric: vec![Interval::new(
Interval::from_zero().clone(),
diff --git a/crates/shirabe-semver/src/lib.rs b/crates/shirabe-semver/src/lib.rs
new file mode 100644
index 0000000..04c3e96
--- /dev/null
+++ b/crates/shirabe-semver/src/lib.rs
@@ -0,0 +1,7 @@
+pub mod comparator;
+pub mod compiling_matcher;
+pub mod constraint;
+pub mod interval;
+pub mod intervals;
+pub mod semver;
+pub mod version_parser;
diff --git a/crates/shirabe-semver/src/version_parser.rs b/crates/shirabe-semver/src/version_parser.rs
index eefc65e..95149af 100644
--- a/crates/shirabe-semver/src/version_parser.rs
+++ b/crates/shirabe-semver/src/version_parser.rs
@@ -37,7 +37,11 @@ impl VersionParser {
php::preg_match(&pattern, &lower, &mut match_);
// match_[3] = the ([.-]?dev)? capture
- if match_.get(3).and_then(|o| o.as_deref()).is_some_and(|s| !s.is_empty()) {
+ if match_
+ .get(3)
+ .and_then(|o| o.as_deref())
+ .is_some_and(|s| !s.is_empty())
+ {
return "dev".to_string();
}
@@ -116,8 +120,10 @@ impl VersionParser {
let mut matches: Vec<Option<String>> = Vec::new();
// match classical versioning
- let classical_pattern =
- format!("{{^v?(\\d{{1,5}}+)(\\.\\d++)?(\\.\\d++)?(\\.\\d++)?{}$}}i", MODIFIER_REGEX);
+ let classical_pattern = format!(
+ "{{^v?(\\d{{1,5}}+)(\\.\\d++)?(\\.\\d++)?(\\.\\d++)?{}$}}i",
+ MODIFIER_REGEX
+ );
if php::preg_match(&classical_pattern, &version, &mut matches) > 0 {
let m2 = matches[2].as_deref().unwrap_or("");
let m3 = matches[3].as_deref().unwrap_or("");
@@ -137,12 +143,8 @@ impl VersionParser {
MODIFIER_REGEX
);
if php::preg_match(&datetime_pattern, &version, &mut matches) > 0 {
- version = php::preg_replace(
- "{\\D}",
- ".",
- matches[1].as_deref().unwrap_or(""),
- )
- .unwrap_or_default();
+ version = php::preg_replace("{\\D}", ".", matches[1].as_deref().unwrap_or(""))
+ .unwrap_or_default();
index = Some(2);
}
}
@@ -154,7 +156,10 @@ impl VersionParser {
if mi == "stable" {
return Ok(version);
}
- let mi1 = matches.get(idx + 1).and_then(|o| o.as_deref()).unwrap_or("");
+ let mi1 = matches
+ .get(idx + 1)
+ .and_then(|o| o.as_deref())
+ .unwrap_or("");
version = format!(
"{}-{}{}",
version,
@@ -203,7 +208,10 @@ impl VersionParser {
&mut Vec::new(),
) > 0
{
- format!(" in \"{}\", the alias must be an exact version", full_version)
+ format!(
+ " in \"{}\", the alias must be an exact version",
+ full_version
+ )
} else if php::preg_match(
&format!(
"{{^{}(?:@(?:{}))? +as +}}",
@@ -223,7 +231,11 @@ impl VersionParser {
String::new()
};
- anyhow::bail!("Invalid version string \"{}\"{}", orig_version, extra_message)
+ anyhow::bail!(
+ "Invalid version string \"{}\"{}",
+ orig_version,
+ extra_message
+ )
}
pub fn parse_numeric_alias_prefix(&self, branch: &str) -> Option<String> {
@@ -288,11 +300,8 @@ impl VersionParser {
) -> anyhow::Result<Box<dyn ConstraintInterface>> {
let pretty_constraint = constraints.to_string();
- let or_constraints = php::preg_split(
- "{\\s*\\|\\|?\\s*}",
- &php::trim(constraints, None),
- )
- .ok_or_else(|| anyhow::anyhow!("Failed to preg_split string: {}", constraints))?;
+ let or_constraints = php::preg_split("{\\s*\\|\\|?\\s*}", &php::trim(constraints, None))
+ .ok_or_else(|| anyhow::anyhow!("Failed to preg_split string: {}", constraints))?;
let mut or_groups: Vec<Box<dyn ConstraintInterface>> = Vec::new();
@@ -301,22 +310,20 @@ impl VersionParser {
"{(?<!^|as|[=>< ,]) *(?<!-)[, ](?!-) *(?!,|as|$)}",
or_constraint,
)
- .ok_or_else(|| {
- anyhow::anyhow!("Failed to preg_split string: {}", or_constraint)
- })?;
+ .ok_or_else(|| anyhow::anyhow!("Failed to preg_split string: {}", or_constraint))?;
- let constraint_objects: Vec<Box<dyn ConstraintInterface>> =
- if and_constraints.len() > 1 {
- let mut objs: Vec<Box<dyn ConstraintInterface>> = Vec::new();
- for and_constraint in &and_constraints {
- for parsed in self.parse_constraint(and_constraint)? {
- objs.push(parsed);
- }
+ let constraint_objects: Vec<Box<dyn ConstraintInterface>> = if and_constraints.len() > 1
+ {
+ let mut objs: Vec<Box<dyn ConstraintInterface>> = Vec::new();
+ for and_constraint in &and_constraints {
+ for parsed in self.parse_constraint(and_constraint)? {
+ objs.push(parsed);
}
- objs
- } else {
- self.parse_constraint(&and_constraints[0])?
- };
+ }
+ objs
+ } else {
+ self.parse_constraint(&and_constraints[0])?
+ };
let constraint: Box<dyn ConstraintInterface> = if constraint_objects.len() == 1 {
constraint_objects.into_iter().next().unwrap()
@@ -342,7 +349,12 @@ impl VersionParser {
// strip off aliasing
let mut match_: Vec<Option<String>> = Vec::new();
- if php::preg_match("{^([^,\\s]++) ++as ++([^,\\s]++)$}", &constraint, &mut match_) > 0 {
+ if php::preg_match(
+ "{^([^,\\s]++) ++as ++([^,\\s]++)$}",
+ &constraint,
+ &mut match_,
+ ) > 0
+ {
constraint = match_[1].clone().unwrap_or_default();
}
@@ -376,8 +388,16 @@ impl VersionParser {
let mut match_: Vec<Option<String>> = Vec::new();
if php::preg_match("{^(v)?[xX*](\\.[xX*])*$}i", &constraint, &mut match_) > 0 {
- let m1_nonempty = !match_.get(1).and_then(|o| o.as_deref()).unwrap_or("").is_empty();
- let m2_nonempty = !match_.get(2).and_then(|o| o.as_deref()).unwrap_or("").is_empty();
+ let m1_nonempty = !match_
+ .get(1)
+ .and_then(|o| o.as_deref())
+ .unwrap_or("")
+ .is_empty();
+ let m2_nonempty = !match_
+ .get(2)
+ .and_then(|o| o.as_deref())
+ .unwrap_or("")
+ .is_empty();
if m1_nonempty || m2_nonempty {
return Ok(vec![Box::new(Constraint::new(
">=".to_string(),
@@ -385,7 +405,9 @@ impl VersionParser {
)?)]);
}
- return Ok(vec![Box::new(MatchAllConstraint { pretty_string: None })]);
+ return Ok(vec![Box::new(MatchAllConstraint {
+ pretty_string: None,
+ })]);
}
let version_regex = format!(
@@ -428,20 +450,17 @@ impl VersionParser {
}
// Calculate the stability suffix
- let stability_suffix =
- if matches[5].as_deref().unwrap_or("").is_empty()
- && matches[7].as_deref().unwrap_or("").is_empty()
- && matches[8].as_deref().unwrap_or("").is_empty()
- {
- "-dev"
- } else {
- ""
- };
+ let stability_suffix = if matches[5].as_deref().unwrap_or("").is_empty()
+ && matches[7].as_deref().unwrap_or("").is_empty()
+ && matches[8].as_deref().unwrap_or("").is_empty()
+ {
+ "-dev"
+ } else {
+ ""
+ };
- let low_version = self.normalize(
- &format!("{}{}", &constraint[1..], stability_suffix),
- None,
- )?;
+ let low_version =
+ self.normalize(&format!("{}{}", &constraint[1..], stability_suffix), None)?;
let lower_bound = Constraint::new(">=".to_string(), low_version)?;
// For upper bound, we increment the position of one more significance,
@@ -478,20 +497,17 @@ impl VersionParser {
};
// Calculate the stability suffix
- let stability_suffix =
- if matches[5].as_deref().unwrap_or("").is_empty()
- && matches[7].as_deref().unwrap_or("").is_empty()
- && matches[8].as_deref().unwrap_or("").is_empty()
- {
- "-dev"
- } else {
- ""
- };
+ let stability_suffix = if matches[5].as_deref().unwrap_or("").is_empty()
+ && matches[7].as_deref().unwrap_or("").is_empty()
+ && matches[8].as_deref().unwrap_or("").is_empty()
+ {
+ "-dev"
+ } else {
+ ""
+ };
- let low_version = self.normalize(
- &format!("{}{}", &constraint[1..], stability_suffix),
- None,
- )?;
+ let low_version =
+ self.normalize(&format!("{}{}", &constraint[1..], stability_suffix), None)?;
let lower_bound = Constraint::new(">=".to_string(), low_version)?;
// For upper bound, we increment the position of one more significance,
@@ -538,7 +554,10 @@ impl VersionParser {
);
if low_version == "0.0.0.0-dev" {
- return Ok(vec![Box::new(Constraint::new("<".to_string(), high_version)?)]);
+ return Ok(vec![Box::new(Constraint::new(
+ "<".to_string(),
+ high_version,
+ )?)]);
}
return Ok(vec![
@@ -563,15 +582,14 @@ impl VersionParser {
// matches[1]='from' string, matches[2..9]=from captures, matches[10]='to' string,
// matches[11..18]=to captures, matches[19]='($)'
// matches[6]=from stability, matches[8]=from dev, matches[9]=from wildcard-dev
- let low_stability_suffix =
- if matches[6].as_deref().unwrap_or("").is_empty()
- && matches[8].as_deref().unwrap_or("").is_empty()
- && matches[9].as_deref().unwrap_or("").is_empty()
- {
- "-dev"
- } else {
- ""
- };
+ let low_stability_suffix = if matches[6].as_deref().unwrap_or("").is_empty()
+ && matches[8].as_deref().unwrap_or("").is_empty()
+ && matches[9].as_deref().unwrap_or("").is_empty()
+ {
+ "-dev"
+ } else {
+ ""
+ };
let from_str = matches[1].clone().unwrap_or_default(); // matches['from']
let low_version = self.normalize(&from_str, None)?;
@@ -581,9 +599,8 @@ impl VersionParser {
)?;
// PHP's empty() on "0" returns true, but here we only check for truly empty/missing
- let empty = |x: &Option<String>| -> bool {
- x.as_deref().map_or(true, |s| s.is_empty())
- };
+ let empty =
+ |x: &Option<String>| -> bool { x.as_deref().map_or(true, |s| s.is_empty()) };
// matches[12]=to minor, matches[13]=to patch, matches[15]=to stability,
// matches[17]=to dev, matches[18]=to wildcard-dev
@@ -636,11 +653,8 @@ impl VersionParser {
// dev-foobar except if the constraint uses a known operator, in which
// case it must be a parse error
if version_str.ends_with("-dev")
- && php::preg_match(
- "{^[0-9a-zA-Z-./]+$}",
- &version_str,
- &mut Vec::new(),
- ) > 0
+ && php::preg_match("{^[0-9a-zA-Z-./]+$}", &version_str, &mut Vec::new())
+ > 0
{
self.normalize(
&format!("dev-{}", &version_str[..version_str.len() - 4]),
@@ -697,10 +711,30 @@ impl VersionParser {
) -> Option<String> {
let mut parts: [i64; 5] = [
0,
- matches.get(1).and_then(|o| o.as_deref()).unwrap_or("0").parse().unwrap_or(0),
- matches.get(2).and_then(|o| o.as_deref()).unwrap_or("0").parse().unwrap_or(0),
- matches.get(3).and_then(|o| o.as_deref()).unwrap_or("0").parse().unwrap_or(0),
- matches.get(4).and_then(|o| o.as_deref()).unwrap_or("0").parse().unwrap_or(0),
+ matches
+ .get(1)
+ .and_then(|o| o.as_deref())
+ .unwrap_or("0")
+ .parse()
+ .unwrap_or(0),
+ matches
+ .get(2)
+ .and_then(|o| o.as_deref())
+ .unwrap_or("0")
+ .parse()
+ .unwrap_or(0),
+ matches
+ .get(3)
+ .and_then(|o| o.as_deref())
+ .unwrap_or("0")
+ .parse()
+ .unwrap_or(0),
+ matches
+ .get(4)
+ .and_then(|o| o.as_deref())
+ .unwrap_or("0")
+ .parse()
+ .unwrap_or(0),
];
let pad_val: i64 = pad.parse().unwrap_or(0);
let mut position = position;
@@ -722,7 +756,10 @@ impl VersionParser {
}
}
- Some(format!("{}.{}.{}.{}", parts[1], parts[2], parts[3], parts[4]))
+ Some(format!(
+ "{}.{}.{}.{}",
+ parts[1], parts[2], parts[3], parts[4]
+ ))
}
fn expand_stability(&self, stability: &str) -> String {
diff --git a/crates/shirabe/src/advisory/audit_config.rs b/crates/shirabe/src/advisory/audit_config.rs
index da01a2c..f75d499 100644
--- a/crates/shirabe/src/advisory/audit_config.rs
+++ b/crates/shirabe/src/advisory/audit_config.rs
@@ -59,7 +59,10 @@ impl AuditConfig {
/// Detailed format: ['CVE-123' => ['apply' => 'audit|block|all', 'reason' => '...']]
fn parse_ignore_with_apply(
config: &PhpMixed,
- ) -> anyhow::Result<(IndexMap<String, Option<String>>, IndexMap<String, Option<String>>)> {
+ ) -> anyhow::Result<(
+ IndexMap<String, Option<String>>,
+ IndexMap<String, Option<String>>,
+ )> {
let mut for_audit: IndexMap<String, Option<String>> = IndexMap::new();
let mut for_block: IndexMap<String, Option<String>> = IndexMap::new();
@@ -83,11 +86,13 @@ impl AuditConfig {
(key.clone(), "all".to_string(), Some(reason_str.clone()))
}
PhpMixed::Array(detail) => {
- let apply = detail.get("apply")
+ let apply = detail
+ .get("apply")
.and_then(|v| v.as_string())
.unwrap_or("all")
.to_string();
- let reason = detail.get("reason")
+ let reason = detail
+ .get("reason")
.and_then(|v| v.as_string())
.map(|s| s.to_string());
diff --git a/crates/shirabe/src/advisory/auditor.rs b/crates/shirabe/src/advisory/auditor.rs
index d96a474..37c86d9 100644
--- a/crates/shirabe/src/advisory/auditor.rs
+++ b/crates/shirabe/src/advisory/auditor.rs
@@ -5,8 +5,8 @@ use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::symfony::console::formatter::output_formatter::OutputFormatter;
use shirabe_php_shim::{
- array_all, array_any, array_key_exists, array_keys, array_reduce, get_class, is_string,
- sprintf, str_starts_with, InvalidArgumentException, PhpMixed, DATE_ATOM,
+ DATE_ATOM, InvalidArgumentException, PhpMixed, array_all, array_any, array_key_exists,
+ array_keys, array_reduce, get_class, is_string, sprintf, str_starts_with,
};
use crate::advisory::ignored_security_advisory::IgnoredSecurityAdvisory;
@@ -96,16 +96,12 @@ impl Auditor {
&& self.needs_complete_advisory_load(&all_advisories, &ignore_list)
{
// TODO(phase-b): $packages reused here; see note above
- let result = repo_set.get_matching_security_advisories(
- vec![],
- false,
- ignore_unreachable,
- )?;
+ let result =
+ repo_set.get_matching_security_advisories(vec![], false, ignore_unreachable)?;
all_advisories = result.advisories;
unreachable_repos.extend(result.unreachable_repos);
}
- let processed =
- self.process_advisories(all_advisories, &ignore_list, &ignored_severities);
+ let processed = self.process_advisories(all_advisories, &ignore_list, &ignored_severities);
let advisories = processed.advisories;
let ignored_advisories = processed.ignored_advisories;
@@ -175,9 +171,7 @@ impl Auditor {
io.write(
PhpMixed::String(JsonFile::encode(
- &PhpMixed::Array(
- json.into_iter().map(|(k, v)| (k, Box::new(v))).collect(),
- ),
+ &PhpMixed::Array(json.into_iter().map(|(k, v)| (k, Box::new(v))).collect()),
shirabe_php_shim::JSON_UNESCAPED_SLASHES
| shirabe_php_shim::JSON_PRETTY_PRINT
| shirabe_php_shim::JSON_UNESCAPED_UNICODE,
@@ -210,10 +204,13 @@ impl Auditor {
),
];
for (advisories_to_output, message) in passes {
- let (pkg_count, total_advisory_count) =
- self.count_advisories(advisories_to_output);
+ let (pkg_count, total_advisory_count) = self.count_advisories(advisories_to_output);
if pkg_count > 0 {
- let plurality = if total_advisory_count == 1 { "y" } else { "ies" };
+ let plurality = if total_advisory_count == 1 {
+ "y"
+ } else {
+ "ies"
+ };
let pkg_plurality = if pkg_count == 1 { "" } else { "s" };
let punctuation = if format == "summary" { "." } else { ":" };
io.write_error(
@@ -290,8 +287,7 @@ impl Auditor {
}
// no partial advisories present
- let advisories_values: Vec<&Vec<PartialSecurityAdvisory>> =
- advisories.values().collect();
+ let advisories_values: Vec<&Vec<PartialSecurityAdvisory>> = advisories.values().collect();
if array_all(
&advisories_values,
|pkg_advisories: &&Vec<PartialSecurityAdvisory>| {
@@ -382,12 +378,12 @@ impl Auditor {
// only holds PartialSecurityAdvisory
let advisory_as_full: Option<&SecurityAdvisory> = None;
if let Some(full) = advisory_as_full {
- if is_string(&PhpMixed::String(
- full.severity.clone().unwrap_or_default(),
- )) && array_key_exists(
- full.severity.as_deref().unwrap_or(""),
- ignored_severities,
- ) {
+ if is_string(&PhpMixed::String(full.severity.clone().unwrap_or_default()))
+ && array_key_exists(
+ full.severity.as_deref().unwrap_or(""),
+ ignored_severities,
+ )
+ {
is_active = false;
let sev = full.severity.as_deref().unwrap_or("");
ignore_reason = ignored_severities
@@ -397,10 +393,7 @@ impl Auditor {
}
if is_string(&PhpMixed::String(full.cve.clone().unwrap_or_default()))
- && array_key_exists(
- full.cve.as_deref().unwrap_or(""),
- ignore_list,
- )
+ && array_key_exists(full.cve.as_deref().unwrap_or(""), ignore_list)
{
is_active = false;
ignore_reason = ignore_list
@@ -413,8 +406,7 @@ impl Auditor {
let remote_id = source.get("remoteId").cloned().unwrap_or_default();
if array_key_exists(&remote_id, ignore_list) {
is_active = false;
- ignore_reason =
- ignore_list.get(&remote_id).cloned().unwrap_or(None);
+ ignore_reason = ignore_list.get(&remote_id).cloned().unwrap_or(None);
break;
}
}
@@ -584,7 +576,9 @@ impl Auditor {
error.push(format!("URL: {}", /* self.get_url(advisory) */ ""));
error.push(format!(
"Affected versions: {}",
- OutputFormatter::escape(/* advisory.affectedVersions.getPrettyString() */ "")
+ OutputFormatter::escape(
+ /* advisory.affectedVersions.getPrettyString() */ ""
+ )
));
error.push(format!(
"Reported at: {}",
diff --git a/crates/shirabe/src/advisory/ignored_security_advisory.rs b/crates/shirabe/src/advisory/ignored_security_advisory.rs
index b260644..7ed3a4c 100644
--- a/crates/shirabe/src/advisory/ignored_security_advisory.rs
+++ b/crates/shirabe/src/advisory/ignored_security_advisory.rs
@@ -1,10 +1,10 @@
//! ref: composer/src/Composer/Advisory/IgnoredSecurityAdvisory.php
+use crate::advisory::security_advisory::SecurityAdvisory;
use chrono::{DateTime, Utc};
use indexmap::IndexMap;
use shirabe_php_shim::PhpMixed;
use shirabe_semver::constraint::constraint_interface::ConstraintInterface;
-use crate::advisory::security_advisory::SecurityAdvisory;
#[derive(Debug)]
pub struct IgnoredSecurityAdvisory {
@@ -25,7 +25,17 @@ impl IgnoredSecurityAdvisory {
ignore_reason: Option<String>,
severity: Option<String>,
) -> Self {
- let inner = SecurityAdvisory::new(package_name, advisory_id, affected_versions, title, sources, reported_at, cve, link, severity);
+ let inner = SecurityAdvisory::new(
+ package_name,
+ advisory_id,
+ affected_versions,
+ title,
+ sources,
+ reported_at,
+ cve,
+ link,
+ severity,
+ );
Self {
inner,
ignore_reason,
diff --git a/crates/shirabe/src/advisory/mod.rs b/crates/shirabe/src/advisory/mod.rs
new file mode 100644
index 0000000..783e9b7
--- /dev/null
+++ b/crates/shirabe/src/advisory/mod.rs
@@ -0,0 +1,5 @@
+pub mod audit_config;
+pub mod auditor;
+pub mod ignored_security_advisory;
+pub mod partial_security_advisory;
+pub mod security_advisory;
diff --git a/crates/shirabe/src/advisory/partial_security_advisory.rs b/crates/shirabe/src/advisory/partial_security_advisory.rs
index cd64dc8..e7aa96e 100644
--- a/crates/shirabe/src/advisory/partial_security_advisory.rs
+++ b/crates/shirabe/src/advisory/partial_security_advisory.rs
@@ -1,5 +1,6 @@
//! ref: composer/src/Composer/Advisory/PartialSecurityAdvisory.php
+use crate::advisory::security_advisory::SecurityAdvisory;
use anyhow::Result;
use chrono::{DateTime, TimeZone, Utc};
use indexmap::IndexMap;
@@ -8,7 +9,6 @@ use shirabe_php_shim::{PhpMixed, UnexpectedValueException};
use shirabe_semver::constraint::constraint::Constraint;
use shirabe_semver::constraint::constraint_interface::ConstraintInterface;
use shirabe_semver::version_parser::VersionParser;
-use crate::advisory::security_advisory::SecurityAdvisory;
fn serialize_constraint<S: serde::Serializer>(
c: &Box<dyn ConstraintInterface>,
@@ -34,16 +34,18 @@ impl PartialSecurityAdvisory {
) -> Result<Box<dyn std::any::Any>> {
let affected_versions_str = data["affectedVersions"].as_string().unwrap_or("");
- let constraint: Box<dyn ConstraintInterface> = match parser.parse_constraints(affected_versions_str) {
- Ok(c) => c,
- Err(_) => {
- let affected_version = Preg::replace(r"(^[>=<^~]*[\d.]+).*", "$1", affected_versions_str);
- match parser.parse_constraints(&affected_version) {
- Ok(c) => c,
- Err(_) => Box::new(Constraint::new("==", "0.0.0-invalid-version")),
+ let constraint: Box<dyn ConstraintInterface> =
+ match parser.parse_constraints(affected_versions_str) {
+ Ok(c) => c,
+ Err(_) => {
+ let affected_version =
+ Preg::replace(r"(^[>=<^~]*[\d.]+).*", "$1", affected_versions_str);
+ match parser.parse_constraints(&affected_version) {
+ Ok(c) => c,
+ Err(_) => Box::new(Constraint::new("==", "0.0.0-invalid-version")),
+ }
}
- }
- };
+ };
let has_full_data = data.contains_key("title")
&& data.contains_key("sources")
@@ -63,9 +65,15 @@ impl PartialSecurityAdvisory {
data["title"].as_string().unwrap_or("").to_string(),
data["sources"].clone(),
reported_at,
- data.get("cve").and_then(|v| v.as_string()).map(|s| s.to_string()),
- data.get("link").and_then(|v| v.as_string()).map(|s| s.to_string()),
- data.get("severity").and_then(|v| v.as_string()).map(|s| s.to_string()),
+ data.get("cve")
+ .and_then(|v| v.as_string())
+ .map(|s| s.to_string()),
+ data.get("link")
+ .and_then(|v| v.as_string())
+ .map(|s| s.to_string()),
+ data.get("severity")
+ .and_then(|v| v.as_string())
+ .map(|s| s.to_string()),
);
return Ok(Box::new(advisory));
}
@@ -82,6 +90,10 @@ impl PartialSecurityAdvisory {
advisory_id: String,
affected_versions: Box<dyn ConstraintInterface>,
) -> Self {
- Self { advisory_id, package_name, affected_versions }
+ Self {
+ advisory_id,
+ package_name,
+ affected_versions,
+ }
}
}
diff --git a/crates/shirabe/src/autoload/autoload_generator.rs b/crates/shirabe/src/autoload/autoload_generator.rs
index 023afd6..df8b16b 100644
--- a/crates/shirabe/src/autoload/autoload_generator.rs
+++ b/crates/shirabe/src/autoload/autoload_generator.rs
@@ -7,15 +7,16 @@ use shirabe_class_map_generator::class_map_generator::ClassMapGenerator;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::symfony::component::console::formatter::output_formatter::OutputFormatter;
use shirabe_php_shim::{
- array_filter, array_keys, array_map, array_merge, array_merge_recursive, array_reverse,
- array_shift, array_slice, array_unique, bin2hex, explode, file_exists, file_get_contents,
- hash, implode, in_array, is_array, krsort, ksort, ltrim, preg_quote, random_bytes, realpath,
- sprintf, str_replace, str_starts_with, str_contains, strlen, strpos, strtr, substr,
- substr_count, trim, trigger_error, unlink, var_export, E_USER_DEPRECATED,
- InvalidArgumentException, PhpMixed, RuntimeException,
+ E_USER_DEPRECATED, InvalidArgumentException, PhpMixed, RuntimeException, array_filter,
+ array_keys, array_map, array_merge, array_merge_recursive, array_reverse, array_shift,
+ array_slice, array_unique, bin2hex, explode, file_exists, file_get_contents, hash, implode,
+ in_array, is_array, krsort, ksort, ltrim, preg_quote, random_bytes, realpath, sprintf,
+ str_contains, str_replace, str_starts_with, strlen, strpos, strtr, substr, substr_count,
+ trigger_error, trim, unlink, var_export,
};
use shirabe_semver::constraint::bound::Bound;
+use crate::autoload::class_loader::ClassLoader;
use crate::config::Config;
use crate::event_dispatcher::event_dispatcher::EventDispatcher;
use crate::filter::platform_requirement_filter::ignore_all_platform_requirement_filter::IgnoreAllPlatformRequirementFilter;
@@ -34,7 +35,6 @@ use crate::script::script_events::ScriptEvents;
use crate::util::filesystem::Filesystem;
use crate::util::package_sorter::PackageSorter;
use crate::util::platform::Platform;
-use crate::autoload::class_loader::ClassLoader;
#[derive(Debug)]
pub struct AutoloadGenerator {
@@ -104,7 +104,9 @@ impl AutoloadGenerator {
E_USER_DEPRECATED,
);
- self.set_platform_requirement_filter(PlatformRequirementFilterFactory::from_bool_or_list(ignore_platform_reqs));
+ self.set_platform_requirement_filter(PlatformRequirementFilterFactory::from_bool_or_list(
+ ignore_platform_reqs,
+ ));
}
pub fn set_platform_requirement_filter(
@@ -160,7 +162,11 @@ impl AutoloadGenerator {
if shirabe_php_shim::server_get("COMPOSER_DEV_MODE").is_none() {
Platform::put_env(
"COMPOSER_DEV_MODE",
- if self.dev_mode.unwrap_or(false) { "1" } else { "0" },
+ if self.dev_mode.unwrap_or(false) {
+ "1"
+ } else {
+ "0"
+ },
);
}
@@ -174,7 +180,8 @@ impl AutoloadGenerator {
);
}
- let mut class_map_generator = ClassMapGenerator::new(vec!["php".to_string(), "inc".to_string(), "hh".to_string()]);
+ let mut class_map_generator =
+ ClassMapGenerator::new(vec!["php".to_string(), "inc".to_string(), "hh".to_string()]);
class_map_generator.avoid_duplicate_scans();
let filesystem = Filesystem::new(None);
@@ -182,8 +189,15 @@ impl AutoloadGenerator {
// Do not remove double realpath() calls.
// Fixes failing Windows realpath() implementation.
// See https://bugs.php.net/bug.php?id=72738
- let base_path = filesystem.normalize_path(&realpath(&realpath(&Platform::get_cwd()).unwrap_or_default()).unwrap_or_default());
- let vendor_path = filesystem.normalize_path(&realpath(&realpath(config.get("vendor-dir").as_string().unwrap_or("")).unwrap_or_default()).unwrap_or_default());
+ let base_path = filesystem.normalize_path(
+ &realpath(&realpath(&Platform::get_cwd()).unwrap_or_default()).unwrap_or_default(),
+ );
+ let vendor_path = filesystem.normalize_path(
+ &realpath(
+ &realpath(config.get("vendor-dir").as_string().unwrap_or("")).unwrap_or_default(),
+ )
+ .unwrap_or_default(),
+ );
let use_global_include_path = config.get("use-include-path").as_bool().unwrap_or(false);
let prepend_autoloader = if config.get("prepend-autoloader").as_bool() == Some(false) {
"false"
@@ -193,10 +207,21 @@ impl AutoloadGenerator {
let target_dir = format!("{}/{}", vendor_path, target_dir);
filesystem.ensure_directory_exists(&target_dir)?;
- let vendor_path_code = filesystem.find_shortest_path_code(&realpath(&target_dir).unwrap_or_default(), &vendor_path, true, false);
- let vendor_path_to_target_dir_code = filesystem.find_shortest_path_code(&vendor_path, &realpath(&target_dir).unwrap_or_default(), true, false);
+ let vendor_path_code = filesystem.find_shortest_path_code(
+ &realpath(&target_dir).unwrap_or_default(),
+ &vendor_path,
+ true,
+ false,
+ );
+ let vendor_path_to_target_dir_code = filesystem.find_shortest_path_code(
+ &vendor_path,
+ &realpath(&target_dir).unwrap_or_default(),
+ true,
+ false,
+ );
- let app_base_dir_code = filesystem.find_shortest_path_code(&vendor_path, &base_path, true, false);
+ let app_base_dir_code =
+ filesystem.find_shortest_path_code(&vendor_path, &base_path, true, false);
let app_base_dir_code = str_replace("__DIR__", "$vendorDir", &app_base_dir_code);
let mut namespaces_file = format!(
@@ -211,14 +236,23 @@ impl AutoloadGenerator {
// Collect information from all packages.
let dev_package_names = local_repo.get_dev_package_names();
- let package_map = self.build_package_map(installation_manager, root_package, local_repo.get_canonical_packages())?;
+ let package_map = self.build_package_map(
+ installation_manager,
+ root_package,
+ local_repo.get_canonical_packages(),
+ )?;
let filtered_dev_packages: PhpMixed = if self.dev_mode.unwrap_or(false) {
// if dev mode is enabled, then we do not filter any dev packages out so disable this entirely
PhpMixed::Bool(false)
} else {
// if the list of dev package names is available we use that straight, otherwise pass true which means use legacy algo to figure them out
if !dev_package_names.is_empty() {
- PhpMixed::List(dev_package_names.iter().map(|s| Box::new(PhpMixed::String(s.clone()))).collect())
+ PhpMixed::List(
+ dev_package_names
+ .iter()
+ .map(|s| Box::new(PhpMixed::String(s.clone())))
+ .collect(),
+ )
} else {
PhpMixed::Bool(true)
}
@@ -226,12 +260,20 @@ impl AutoloadGenerator {
let autoloads = self.parse_autoloads(&package_map, root_package, filtered_dev_packages);
// Process the 'psr-0' base directories.
- let psr0_map = autoloads.get("psr-0").and_then(|v| v.as_array().cloned()).unwrap_or_default();
+ let psr0_map = autoloads
+ .get("psr-0")
+ .and_then(|v| v.as_array().cloned())
+ .unwrap_or_default();
for (namespace, paths) in &psr0_map {
let mut exported_paths: Vec<String> = vec![];
if let Some(p_list) = paths.as_list() {
for path in p_list {
- exported_paths.push(self.get_path_code(&filesystem, &base_path, &vendor_path, path.as_string().unwrap_or("")));
+ exported_paths.push(self.get_path_code(
+ &filesystem,
+ &base_path,
+ &vendor_path,
+ path.as_string().unwrap_or(""),
+ ));
}
}
let exported_prefix = var_export(&PhpMixed::String(namespace.clone()), true);
@@ -241,12 +283,20 @@ impl AutoloadGenerator {
namespaces_file.push_str(");\n");
// Process the 'psr-4' base directories.
- let psr4_map = autoloads.get("psr-4").and_then(|v| v.as_array().cloned()).unwrap_or_default();
+ let psr4_map = autoloads
+ .get("psr-4")
+ .and_then(|v| v.as_array().cloned())
+ .unwrap_or_default();
for (namespace, paths) in &psr4_map {
let mut exported_paths: Vec<String> = vec![];
if let Some(p_list) = paths.as_list() {
for path in p_list {
- exported_paths.push(self.get_path_code(&filesystem, &base_path, &vendor_path, path.as_string().unwrap_or("")));
+ exported_paths.push(self.get_path_code(
+ &filesystem,
+ &base_path,
+ &vendor_path,
+ path.as_string().unwrap_or(""),
+ ));
}
}
let exported_prefix = var_export(&PhpMixed::String(namespace.clone()), true);
@@ -261,8 +311,15 @@ impl AutoloadGenerator {
if root_package.get_target_dir().is_some()
&& main_autoload.get("psr-0").map_or(false, |v| !v.is_empty())
{
- let levels = substr_count(&filesystem.normalize_path(&root_package.get_target_dir().unwrap_or_default()), "/") + 1;
- let psr0_keys = main_autoload.get("psr-0").and_then(|v| v.as_array()).cloned().unwrap_or_default();
+ let levels = substr_count(
+ &filesystem.normalize_path(&root_package.get_target_dir().unwrap_or_default()),
+ "/",
+ ) + 1;
+ let psr0_keys = main_autoload
+ .get("psr-0")
+ .and_then(|v| v.as_array())
+ .cloned()
+ .unwrap_or_default();
let prefixes = implode(
", ",
&array_map(
@@ -280,29 +337,52 @@ impl AutoloadGenerator {
}
let mut excluded: Vec<String> = vec![];
- if let Some(ex) = autoloads.get("exclude-from-classmap").and_then(|v| v.as_list()) {
+ if let Some(ex) = autoloads
+ .get("exclude-from-classmap")
+ .and_then(|v| v.as_list())
+ {
if !ex.is_empty() {
- excluded = ex.iter().filter_map(|v| v.as_string().map(|s| s.to_string())).collect();
+ excluded = ex
+ .iter()
+ .filter_map(|v| v.as_string().map(|s| s.to_string()))
+ .collect();
}
}
- let classmap_list = autoloads.get("classmap").and_then(|v| v.as_list()).cloned().unwrap_or_default();
+ let classmap_list = autoloads
+ .get("classmap")
+ .and_then(|v| v.as_list())
+ .cloned()
+ .unwrap_or_default();
for dir in &classmap_list {
let dir_str = dir.as_string().unwrap_or("");
- class_map_generator.scan_paths(dir_str, self.build_exclusion_regex(dir_str, excluded.clone()), "classmap", "");
+ class_map_generator.scan_paths(
+ dir_str,
+ self.build_exclusion_regex(dir_str, excluded.clone()),
+ "classmap",
+ "",
+ );
}
if scan_psr_packages {
- let mut namespaces_to_scan: IndexMap<String, Vec<IndexMap<String, PhpMixed>>> = IndexMap::new();
+ let mut namespaces_to_scan: IndexMap<String, Vec<IndexMap<String, PhpMixed>>> =
+ IndexMap::new();
// Scan the PSR-0/4 directories for class files, and add them to the class map
for psr_type in &["psr-4", "psr-0"] {
- let map = autoloads.get(*psr_type).and_then(|v| v.as_array()).cloned().unwrap_or_default();
+ let map = autoloads
+ .get(*psr_type)
+ .and_then(|v| v.as_array())
+ .cloned()
+ .unwrap_or_default();
for (namespace, paths) in &map {
let mut entry: IndexMap<String, PhpMixed> = IndexMap::new();
entry.insert("paths".to_string(), (**paths).clone());
entry.insert("type".to_string(), PhpMixed::String(psr_type.to_string()));
- namespaces_to_scan.entry(namespace.clone()).or_insert_with(Vec::new).push(entry);
+ namespaces_to_scan
+ .entry(namespace.clone())
+ .or_insert_with(Vec::new)
+ .push(entry);
}
}
@@ -310,30 +390,48 @@ impl AutoloadGenerator {
for (namespace, groups) in &namespaces_to_scan {
for group in groups {
- let paths = group.get("paths").and_then(|v| v.as_list()).cloned().unwrap_or_default();
- let group_type = group.get("type").and_then(|v| v.as_string()).unwrap_or("").to_string();
+ let paths = group
+ .get("paths")
+ .and_then(|v| v.as_list())
+ .cloned()
+ .unwrap_or_default();
+ let group_type = group
+ .get("type")
+ .and_then(|v| v.as_string())
+ .unwrap_or("")
+ .to_string();
for dir in &paths {
let dir_str = dir.as_string().unwrap_or("").to_string();
- let dir_str = filesystem.normalize_path(if filesystem.is_absolute_path(&dir_str) {
- &dir_str
- } else {
- &format!("{}/{}", base_path, dir_str)
- });
+ let dir_str =
+ filesystem.normalize_path(if filesystem.is_absolute_path(&dir_str) {
+ &dir_str
+ } else {
+ &format!("{}/{}", base_path, dir_str)
+ });
if !shirabe_php_shim::is_dir(&dir_str) {
continue;
}
// if the vendor dir is contained within a psr-0/psr-4 dir being scanned we exclude it
- let exclusion_regex = if str_contains(&vendor_path, &format!("{}/", dir_str)) {
- self.build_exclusion_regex(
- &dir_str,
- array_merge(excluded.clone(), vec![format!("{}/", vendor_path)]),
- )
- } else {
- self.build_exclusion_regex(&dir_str, excluded.clone())
- };
+ let exclusion_regex =
+ if str_contains(&vendor_path, &format!("{}/", dir_str)) {
+ self.build_exclusion_regex(
+ &dir_str,
+ array_merge(
+ excluded.clone(),
+ vec![format!("{}/", vendor_path)],
+ ),
+ )
+ } else {
+ self.build_exclusion_regex(&dir_str, excluded.clone())
+ };
- class_map_generator.scan_paths(&dir_str, exclusion_regex, &group_type, namespace);
+ class_map_generator.scan_paths(
+ &dir_str,
+ exclusion_regex,
+ &group_type,
+ namespace,
+ );
}
}
}
@@ -376,7 +474,10 @@ impl AutoloadGenerator {
self.io.write_error(&format!("<warning>{}</warning>", msg));
}
- class_map.add_class("Composer\\InstalledVersions".to_string(), format!("{}/composer/InstalledVersions.php", vendor_path));
+ class_map.add_class(
+ "Composer\\InstalledVersions".to_string(),
+ format!("{}/composer/InstalledVersions.php", vendor_path),
+ );
class_map.sort();
let mut classmap_file = format!(
@@ -384,8 +485,15 @@ impl AutoloadGenerator {
vendor_path_code, app_base_dir_code
);
for (class_name, path) in class_map.get_map() {
- let path_code = format!("{},\n", self.get_path_code(&filesystem, &base_path, &vendor_path, &path));
- classmap_file.push_str(&format!(" {} => {}", var_export(&PhpMixed::String(class_name.clone()), true), path_code));
+ let path_code = format!(
+ "{},\n",
+ self.get_path_code(&filesystem, &base_path, &vendor_path, &path)
+ );
+ classmap_file.push_str(&format!(
+ " {} => {}",
+ var_export(&PhpMixed::String(class_name.clone()), true),
+ path_code
+ ));
}
classmap_file.push_str(");\n");
@@ -394,13 +502,24 @@ impl AutoloadGenerator {
suffix = None;
}
if suffix.is_none() {
- suffix = config.get("autoloader-suffix").as_string().map(|s| s.to_string());
+ suffix = config
+ .get("autoloader-suffix")
+ .as_string()
+ .map(|s| s.to_string());
// carry over existing autoload.php's suffix if possible and none is configured
- if suffix.is_none() && Filesystem::is_readable(&format!("{}/autoload.php", vendor_path)) {
- let content = file_get_contents(&format!("{}/autoload.php", vendor_path)).unwrap_or_default();
+ if suffix.is_none() && Filesystem::is_readable(&format!("{}/autoload.php", vendor_path))
+ {
+ let content =
+ file_get_contents(&format!("{}/autoload.php", vendor_path)).unwrap_or_default();
let mut matches: Vec<String> = vec![];
- if Preg::is_match("{ComposerAutoloaderInit([^:\\s]+)::}", &content, Some(&mut matches)).unwrap_or(false) {
+ if Preg::is_match(
+ "{ComposerAutoloaderInit([^:\\s]+)::}",
+ &content,
+ Some(&mut matches),
+ )
+ .unwrap_or(false)
+ {
suffix = matches.get(1).cloned();
}
}
@@ -408,7 +527,11 @@ impl AutoloadGenerator {
if suffix.is_none() {
suffix = Some(if let Some(l) = locker {
if l.is_locked() {
- l.get_lock_data().get("content-hash").and_then(|v| v.as_string()).unwrap_or("").to_string()
+ l.get_lock_data()
+ .get("content-hash")
+ .and_then(|v| v.as_string())
+ .unwrap_or("")
+ .to_string()
} else {
bin2hex(&random_bytes(16))
}
@@ -423,23 +546,50 @@ impl AutoloadGenerator {
return Ok(class_map);
}
- filesystem.file_put_contents_if_modified(&format!("{}/autoload_namespaces.php", target_dir), &namespaces_file)?;
- filesystem.file_put_contents_if_modified(&format!("{}/autoload_psr4.php", target_dir), &psr4_file)?;
- filesystem.file_put_contents_if_modified(&format!("{}/autoload_classmap.php", target_dir), &classmap_file)?;
+ filesystem.file_put_contents_if_modified(
+ &format!("{}/autoload_namespaces.php", target_dir),
+ &namespaces_file,
+ )?;
+ filesystem.file_put_contents_if_modified(
+ &format!("{}/autoload_psr4.php", target_dir),
+ &psr4_file,
+ )?;
+ filesystem.file_put_contents_if_modified(
+ &format!("{}/autoload_classmap.php", target_dir),
+ &classmap_file,
+ )?;
let include_path_file_path = format!("{}/include_paths.php", target_dir);
- let include_path_file_contents = self.get_include_paths_file(&package_map, &filesystem, &base_path, &vendor_path, &vendor_path_code, &app_base_dir_code);
+ let include_path_file_contents = self.get_include_paths_file(
+ &package_map,
+ &filesystem,
+ &base_path,
+ &vendor_path,
+ &vendor_path_code,
+ &app_base_dir_code,
+ );
if let Some(ref c) = include_path_file_contents {
filesystem.file_put_contents_if_modified(&include_path_file_path, c)?;
} else if file_exists(&include_path_file_path) {
unlink(&include_path_file_path);
}
let include_files_file_path = format!("{}/autoload_files.php", target_dir);
- let files_map = autoloads.get("files").and_then(|v| v.as_array()).cloned().unwrap_or_default();
+ let files_map = autoloads
+ .get("files")
+ .and_then(|v| v.as_array())
+ .cloned()
+ .unwrap_or_default();
let mut files_str_map: IndexMap<String, String> = IndexMap::new();
for (k, v) in &files_map {
files_str_map.insert(k.clone(), v.as_string().unwrap_or("").to_string());
}
- let include_files_file_contents = self.get_include_files_file(&files_str_map, &filesystem, &base_path, &vendor_path, &vendor_path_code, &app_base_dir_code);
+ let include_files_file_contents = self.get_include_files_file(
+ &files_str_map,
+ &filesystem,
+ &base_path,
+ &vendor_path,
+ &vendor_path_code,
+ &app_base_dir_code,
+ );
if let Some(ref c) = include_files_file_contents {
filesystem.file_put_contents_if_modified(&include_files_file_path, c)?;
} else if file_exists(&include_files_file_path) {
@@ -535,9 +685,14 @@ impl AutoloadGenerator {
let abs_dir = if fs.is_absolute_path(dir) {
dir.to_string()
} else {
- format!("{}/{}", realpath(&Platform::get_cwd()).unwrap_or_default(), dir)
+ format!(
+ "{}/{}",
+ realpath(&Platform::get_cwd()).unwrap_or_default(),
+ dir
+ )
};
- let dir_match_normalized = preg_quote(&strtr(&fs.normalize_path(&abs_dir), "\\", "/"), None);
+ let dir_match_normalized =
+ preg_quote(&strtr(&fs.normalize_path(&abs_dir), "\\", "/"), None);
let is_symlink = dir_match != dir_match_normalized;
let mut new_excluded: Vec<String> = vec![];
@@ -575,8 +730,10 @@ impl AutoloadGenerator {
packages: Vec<Box<dyn PackageInterface>>,
) -> anyhow::Result<Vec<(Box<dyn PackageInterface>, Option<String>)>> {
// build package => install path map
- let mut package_map: Vec<(Box<dyn PackageInterface>, Option<String>)> =
- vec![(root_package.clone_as_package_interface(), Some(String::new()))];
+ let mut package_map: Vec<(Box<dyn PackageInterface>, Option<String>)> = vec![(
+ root_package.clone_as_package_interface(),
+ Some(String::new()),
+ )];
for package in packages {
if package.as_alias_package().is_some() {
@@ -593,7 +750,9 @@ impl AutoloadGenerator {
/// Throws InvalidArgumentException if the package has illegal settings.
pub(crate) fn validate_package(&self, package: &dyn PackageInterface) -> anyhow::Result<()> {
let autoload = package.get_autoload();
- if autoload.get("psr-4").map_or(false, |v| !v.is_empty()) && package.get_target_dir().is_some() {
+ if autoload.get("psr-4").map_or(false, |v| !v.is_empty())
+ && package.get_target_dir().is_some()
+ {
let name = package.get_name();
let _ = package.get_target_dir();
return Err(InvalidArgumentException {
@@ -628,11 +787,18 @@ impl AutoloadGenerator {
let package_map = if is_array(&filtered_dev_packages) {
let dev_list = filtered_dev_packages
.as_list()
- .map(|l| l.iter().filter_map(|v| v.as_string().map(|s| s.to_string())).collect::<Vec<_>>())
+ .map(|l| {
+ l.iter()
+ .filter_map(|v| v.as_string().map(|s| s.to_string()))
+ .collect::<Vec<_>>()
+ })
.unwrap_or_default();
- array_filter(package_map, |item: &(Box<dyn PackageInterface>, Option<String>)| -> bool {
- !in_array(item.0.get_name(), &dev_list, true)
- })
+ array_filter(
+ package_map,
+ |item: &(Box<dyn PackageInterface>, Option<String>)| -> bool {
+ !in_array(item.0.get_name(), &dev_list, true)
+ },
+ )
} else if filtered_dev_packages.as_bool() == Some(true) {
self.filter_package_map(package_map, root_package)
} else {
@@ -651,7 +817,8 @@ impl AutoloadGenerator {
// sorted (i.e. dependents first) for files to ensure that dependencies are loaded/available once a file is included
let files = self.parse_autoloads_type(&sorted_package_map, "files", root_package);
// using sorted here but it does not really matter as all are excluded equally
- let exclude = self.parse_autoloads_type(&sorted_package_map, "exclude-from-classmap", root_package);
+ let exclude =
+ self.parse_autoloads_type(&sorted_package_map, "exclude-from-classmap", root_package);
krsort(&mut psr0);
krsort(&mut psr4);
@@ -661,12 +828,19 @@ impl AutoloadGenerator {
result.insert("psr-4".to_string(), PhpMixed::Array(psr4));
result.insert("classmap".to_string(), PhpMixed::Array(classmap));
result.insert("files".to_string(), PhpMixed::Array(files));
- result.insert("exclude-from-classmap".to_string(), PhpMixed::Array(exclude));
+ result.insert(
+ "exclude-from-classmap".to_string(),
+ PhpMixed::Array(exclude),
+ );
result
}
/// Registers an autoloader based on an autoload-map returned by parseAutoloads
- pub fn create_loader(&self, autoloads: &IndexMap<String, PhpMixed>, vendor_dir: Option<String>) -> ClassLoader {
+ pub fn create_loader(
+ &self,
+ autoloads: &IndexMap<String, PhpMixed>,
+ vendor_dir: Option<String>,
+ ) -> ClassLoader {
let mut loader = ClassLoader::new(vendor_dir);
if let Some(psr0) = autoloads.get("psr-0").and_then(|v| v.as_array()) {
@@ -683,22 +857,38 @@ impl AutoloadGenerator {
if let Some(classmap) = autoloads.get("classmap").and_then(|v| v.as_list()) {
let mut excluded: Vec<String> = vec![];
- if let Some(ex) = autoloads.get("exclude-from-classmap").and_then(|v| v.as_list()) {
+ if let Some(ex) = autoloads
+ .get("exclude-from-classmap")
+ .and_then(|v| v.as_list())
+ {
if !ex.is_empty() {
- excluded = ex.iter().filter_map(|v| v.as_string().map(|s| s.to_string())).collect();
+ excluded = ex
+ .iter()
+ .filter_map(|v| v.as_string().map(|s| s.to_string()))
+ .collect();
}
}
- let mut class_map_generator = ClassMapGenerator::new(vec!["php".to_string(), "inc".to_string(), "hh".to_string()]);
+ let mut class_map_generator = ClassMapGenerator::new(vec![
+ "php".to_string(),
+ "inc".to_string(),
+ "hh".to_string(),
+ ]);
class_map_generator.avoid_duplicate_scans();
for dir in classmap {
let dir_str = dir.as_string().unwrap_or("");
let res = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
- class_map_generator.scan_paths(dir_str, self.build_exclusion_regex(dir_str, excluded.clone()), "classmap", "");
+ class_map_generator.scan_paths(
+ dir_str,
+ self.build_exclusion_regex(dir_str, excluded.clone()),
+ "classmap",
+ "",
+ );
}));
if let Err(_e) = res {
- self.io.write_error(&format!("<warning>{}</warning>", "scan failure"));
+ self.io
+ .write_error(&format!("<warning>{}</warning>", "scan failure"));
}
}
@@ -732,7 +922,8 @@ impl AutoloadGenerator {
if let Some(target_dir) = package.get_target_dir() {
if !target_dir.is_empty() {
let suffix_to_remove = format!("/{}", target_dir);
- install_path = substr(&install_path, 0, Some(-(suffix_to_remove.len() as isize)));
+ install_path =
+ substr(&install_path, 0, Some(-(suffix_to_remove.len() as isize)));
}
}
@@ -777,7 +968,10 @@ impl AutoloadGenerator {
let mut files: IndexMap<String, String> = files
.iter()
.map(|(k, function_file)| {
- (k.clone(), self.get_path_code(filesystem, base_path, vendor_path, function_file))
+ (
+ k.clone(),
+ self.get_path_code(filesystem, base_path, vendor_path, function_file),
+ )
})
.collect();
let unique_files: Vec<String> = array_unique(files.values().cloned().collect());
@@ -792,7 +986,8 @@ impl AutoloadGenerator {
}
}
for duplicate_file in array_unique(duplicates) {
- self.io.write_error(&format!("<warning> - {}</warning>", duplicate_file));
+ self.io
+ .write_error(&format!("<warning> - {}</warning>", duplicate_file));
}
}
let _ = unique_files;
@@ -839,7 +1034,8 @@ impl AutoloadGenerator {
path = substr(&path, vendor_path.len() as isize, None);
base_dir = "$vendorDir . ".to_string();
} else {
- path = filesystem.normalize_path(&filesystem.find_shortest_path(base_path, &path, true));
+ path =
+ filesystem.normalize_path(&filesystem.find_shortest_path(base_path, &path, true));
if !filesystem.is_absolute_path(&path) {
base_dir = "$baseDir . ".to_string();
path = format!("/{}", path);
@@ -862,7 +1058,10 @@ impl AutoloadGenerator {
let mut lowest_php_version = Bound::zero();
let mut required_php_64bit = false;
let mut required_extensions: IndexMap<String, String> = IndexMap::new();
- let mut extension_providers: IndexMap<String, Vec<Box<dyn shirabe_semver::constraint::constraint_interface::ConstraintInterface>>> = IndexMap::new();
+ let mut extension_providers: IndexMap<
+ String,
+ Vec<Box<dyn shirabe_semver::constraint::constraint_interface::ConstraintInterface>>,
+ > = IndexMap::new();
for item in package_map {
let package = &item.0;
@@ -872,7 +1071,9 @@ impl AutoloadGenerator {
}
for (_k, link) in &links {
let mut matches: Vec<String> = vec![];
- if Preg::is_match("{^ext-(.+)$}iD", link.get_target(), Some(&mut matches)).unwrap_or(false) {
+ if Preg::is_match("{^ext-(.+)$}iD", link.get_target(), Some(&mut matches))
+ .unwrap_or(false)
+ {
extension_providers
.entry(matches[1].clone())
.or_insert_with(Vec::new)
@@ -889,13 +1090,23 @@ impl AutoloadGenerator {
}
for (_k, link) in &package.get_requires() {
- if self.platform_requirement_filter.is_ignored(link.get_target()) {
+ if self
+ .platform_requirement_filter
+ .is_ignored(link.get_target())
+ {
continue;
}
- if in_array(link.get_target(), &vec!["php".to_string(), "php-64bit".to_string()], true) {
+ if in_array(
+ link.get_target(),
+ &vec!["php".to_string(), "php-64bit".to_string()],
+ true,
+ ) {
let constraint = link.get_constraint();
- if constraint.get_lower_bound().compare_to(&lowest_php_version, ">") {
+ if constraint
+ .get_lower_bound()
+ .compare_to(&lowest_php_version, ">")
+ {
lowest_php_version = constraint.get_lower_bound();
}
}
@@ -906,7 +1117,8 @@ impl AutoloadGenerator {
let mut matches: Vec<String> = vec![];
if check_platform.as_bool() == Some(true)
- && Preg::is_match("{^ext-(.+)$}iD", link.get_target(), Some(&mut matches)).unwrap_or(false)
+ && Preg::is_match("{^ext-(.+)$}iD", link.get_target(), Some(&mut matches))
+ .unwrap_or(false)
{
// skip extension checks if they have a valid provider/replacer
if let Some(provided_list) = extension_providers.get(&matches[1]) {
@@ -984,8 +1196,16 @@ impl AutoloadGenerator {
let mut required_php = String::new();
let mut required_php_error = String::new();
if !lowest_php_version.is_zero() {
- let operator = if lowest_php_version.is_inclusive() { ">=" } else { ">" };
- required_php = format!("PHP_VERSION_ID {} {}", operator, format_to_php_version_id(&lowest_php_version));
+ let operator = if lowest_php_version.is_inclusive() {
+ ">="
+ } else {
+ ">"
+ };
+ required_php = format!(
+ "PHP_VERSION_ID {} {}",
+ operator,
+ format_to_php_version_id(&lowest_php_version)
+ );
let human_readable = format_to_human_readable(&lowest_php_version);
required_php_error = format!(
"\"{} {}\"",
@@ -1009,7 +1229,10 @@ impl AutoloadGenerator {
required_php.push_str("\nif (PHP_INT_SIZE !== 8) {\n $issues[] = 'Your Composer dependencies require a 64-bit build of PHP.';\n}\n");
}
- let required_extensions_str = implode("", &required_extensions.values().cloned().collect::<Vec<_>>());
+ let required_extensions_str = implode(
+ "",
+ &required_extensions.values().cloned().collect::<Vec<_>>(),
+ );
let required_extensions_block = if !required_extensions_str.is_empty() {
format!(
"\n$missingExtensions = array();\n{}\nif ($missingExtensions) {{\n $issues[] = 'Your Composer dependencies require the following PHP extensions to be installed: ' . implode(', ', $missingExtensions) . '.';\n}}\n",
@@ -1029,7 +1252,11 @@ impl AutoloadGenerator {
))
}
- pub(crate) fn get_autoload_file(&self, vendor_path_to_target_dir_code: &str, suffix: &str) -> String {
+ pub(crate) fn get_autoload_file(
+ &self,
+ vendor_path_to_target_dir_code: &str,
+ suffix: &str,
+ ) -> String {
let last_char = vendor_path_to_target_dir_code
.chars()
.nth(vendor_path_to_target_dir_code.len() - 1)
@@ -1101,7 +1328,10 @@ impl AutoloadGenerator {
}),
true,
);
- file.push_str(&format!(" $loader->setApcuPrefix({});\n", apcu_prefix));
+ file.push_str(&format!(
+ " $loader->setApcuPrefix({});\n",
+ apcu_prefix
+ ));
}
if use_global_include_path {
@@ -1165,7 +1395,8 @@ impl AutoloadGenerator {
}
}
- let class_map = shirabe_php_shim::php_require(&format!("{}/autoload_classmap.php", target_dir));
+ let class_map =
+ shirabe_php_shim::php_require(&format!("{}/autoload_classmap.php", target_dir));
if class_map.as_bool() != Some(false) && !class_map.is_null() {
if let Some(cm) = class_map.as_array() {
let cm_str: IndexMap<String, String> = cm
@@ -1180,26 +1411,49 @@ impl AutoloadGenerator {
let vendor_path_code = format!(
" => {} . '/",
- filesystem.find_shortest_path_code(&realpath(target_dir).unwrap_or_default(), vendor_path, true, true)
+ filesystem.find_shortest_path_code(
+ &realpath(target_dir).unwrap_or_default(),
+ vendor_path,
+ true,
+ true
+ )
);
let vendor_phar_path_code = format!(
" => 'phar://' . {} . '/",
- filesystem.find_shortest_path_code(&realpath(target_dir).unwrap_or_default(), vendor_path, true, true)
+ filesystem.find_shortest_path_code(
+ &realpath(target_dir).unwrap_or_default(),
+ vendor_path,
+ true,
+ true
+ )
);
let app_base_dir_code = format!(
" => {} . '/",
- filesystem.find_shortest_path_code(&realpath(target_dir).unwrap_or_default(), base_path, true, true)
+ filesystem.find_shortest_path_code(
+ &realpath(target_dir).unwrap_or_default(),
+ base_path,
+ true,
+ true
+ )
);
let app_base_dir_phar_code = format!(
" => 'phar://' . {} . '/",
- filesystem.find_shortest_path_code(&realpath(target_dir).unwrap_or_default(), base_path, true, true)
+ filesystem.find_shortest_path_code(
+ &realpath(target_dir).unwrap_or_default(),
+ base_path,
+ true,
+ true
+ )
);
// PHP: ' => ' . substr(var_export(rtrim($vendorDir, '\\/') . '/', true), 0, -1)
let absolute_vendor_path_code = format!(
" => {}",
substr(
- &var_export(&PhpMixed::String(format!("{}/", shirabe_php_shim::rtrim(vendor_path, "\\/"))), true),
+ &var_export(
+ &PhpMixed::String(format!("{}/", shirabe_php_shim::rtrim(vendor_path, "\\/"))),
+ true
+ ),
0,
Some(-1),
)
@@ -1207,7 +1461,13 @@ impl AutoloadGenerator {
let absolute_vendor_phar_path_code = format!(
" => {}",
substr(
- &var_export(&PhpMixed::String(format!("{}/", shirabe_php_shim::rtrim(&format!("phar://{}", vendor_path), "\\/"))), true),
+ &var_export(
+ &PhpMixed::String(format!(
+ "{}/",
+ shirabe_php_shim::rtrim(&format!("phar://{}", vendor_path), "\\/")
+ )),
+ true
+ ),
0,
Some(-1),
)
@@ -1215,7 +1475,10 @@ impl AutoloadGenerator {
let absolute_app_base_dir_code = format!(
" => {}",
substr(
- &var_export(&PhpMixed::String(format!("{}/", shirabe_php_shim::rtrim(base_path, "\\/"))), true),
+ &var_export(
+ &PhpMixed::String(format!("{}/", shirabe_php_shim::rtrim(base_path, "\\/"))),
+ true
+ ),
0,
Some(-1),
)
@@ -1223,7 +1486,13 @@ impl AutoloadGenerator {
let absolute_app_base_dir_phar_code = format!(
" => {}",
substr(
- &var_export(&PhpMixed::String(format!("{}/", shirabe_php_shim::rtrim(&format!("phar://{}", base_path), "\\/"))), true),
+ &var_export(
+ &PhpMixed::String(format!(
+ "{}/",
+ shirabe_php_shim::rtrim(&format!("phar://{}", base_path), "\\/")
+ )),
+ true
+ ),
0,
Some(-1),
)
@@ -1242,7 +1511,8 @@ impl AutoloadGenerator {
// PHP: foreach ((array) $loader as $prop => $value) — iterate over the loader's properties
for (prop, value) in loader.as_array_iter() {
- if !is_array(&value) || value.as_array().map_or(0, |a| a.len()) == 0
+ if !is_array(&value)
+ || value.as_array().map_or(0, |a| a.len()) == 0
|| !str_starts_with(&prop, prefix)
{
continue;
@@ -1251,17 +1521,23 @@ impl AutoloadGenerator {
}
for (prop, value) in &maps {
- let value = strtr(
- &var_export(value, true),
- &{
- let mut m: IndexMap<String, String> = IndexMap::new();
- m.insert(absolute_vendor_path_code.clone(), vendor_path_code.clone());
- m.insert(absolute_vendor_phar_path_code.clone(), vendor_phar_path_code.clone());
- m.insert(absolute_app_base_dir_code.clone(), app_base_dir_code.clone());
- m.insert(absolute_app_base_dir_phar_code.clone(), app_base_dir_phar_code.clone());
- m
- },
- );
+ let value = strtr(&var_export(value, true), &{
+ let mut m: IndexMap<String, String> = IndexMap::new();
+ m.insert(absolute_vendor_path_code.clone(), vendor_path_code.clone());
+ m.insert(
+ absolute_vendor_phar_path_code.clone(),
+ vendor_phar_path_code.clone(),
+ );
+ m.insert(
+ absolute_app_base_dir_code.clone(),
+ app_base_dir_code.clone(),
+ );
+ m.insert(
+ absolute_app_base_dir_phar_code.clone(),
+ app_base_dir_phar_code.clone(),
+ );
+ m
+ });
let value = shirabe_php_shim::ltrim(&Preg::replace("/^ */m", " $0$0", &value), None);
let value = Preg::replace("/ +$/m", "", &value);
@@ -1324,7 +1600,11 @@ impl AutoloadGenerator {
let type_arr = type_value.as_array().cloned().unwrap_or_default();
for (namespace, paths) in type_arr {
- let namespace = if in_array(r#type, &vec!["psr-4".to_string(), "psr-0".to_string()], true) {
+ let namespace = if in_array(
+ r#type,
+ &vec!["psr-4".to_string(), "psr-0".to_string()],
+ true,
+ ) {
// normalize namespaces to ensure "\" becomes "" and others do not have leading separators as they are not needed
ltrim(&namespace, "\\")
} else {
@@ -1338,7 +1618,9 @@ impl AutoloadGenerator {
};
for path in path_list {
let mut path_str = path.as_string().unwrap_or("").to_string();
- if (r#type == "files" || r#type == "classmap" || r#type == "exclude-from-classmap")
+ if (r#type == "files"
+ || r#type == "classmap"
+ || r#type == "exclude-from-classmap")
&& package.get_target_dir().is_some()
&& !Filesystem::is_readable(&format!("{}/{}", install_path, path_str))
{
@@ -1348,23 +1630,38 @@ impl AutoloadGenerator {
"\\<dirsep\\>",
"[\\\\/]",
&preg_quote(
- &str_replace_multi(&package.get_target_dir().unwrap_or_default(), &[("/", "<dirsep>"), ("\\", "<dirsep>")]),
+ &str_replace_multi(
+ &package.get_target_dir().unwrap_or_default(),
+ &[("/", "<dirsep>"), ("\\", "<dirsep>")],
+ ),
None,
),
);
path_str = ltrim(
- &Preg::replace(&format!("{{^{}}}", target_dir), "", &ltrim(&path_str, "\\/")),
+ &Preg::replace(
+ &format!("{{^{}}}", target_dir),
+ "",
+ &ltrim(&path_str, "\\/"),
+ ),
"\\/",
);
} else {
// add target-dir from file paths that don't have it
- path_str = format!("{}/{}", package.get_target_dir().unwrap_or_default(), path_str);
+ path_str = format!(
+ "{}/{}",
+ package.get_target_dir().unwrap_or_default(),
+ path_str
+ );
}
}
if r#type == "exclude-from-classmap" {
// first escape user input
- let p = Preg::replace("{/+}", "/", &preg_quote(&trim(&strtr(&path_str, "\\", "/"), "/"), None));
+ let p = Preg::replace(
+ "{/+}",
+ "/",
+ &preg_quote(&trim(&strtr(&path_str, "\\", "/"), "/"), None),
+ );
// add support for wildcards * and **
let p = strtr(&p, &{
@@ -1392,7 +1689,11 @@ impl AutoloadGenerator {
install_path.clone()
};
- let resolved_path = realpath(&format!("{}/{}", install_path_for_resolve, updir.clone().unwrap_or_default()));
+ let resolved_path = realpath(&format!(
+ "{}/{}",
+ install_path_for_resolve,
+ updir.clone().unwrap_or_default()
+ ));
let resolved_path = match resolved_path {
Some(rp) => rp,
None => continue,
@@ -1402,13 +1703,18 @@ impl AutoloadGenerator {
preg_quote(&strtr(&resolved_path, "\\", "/"), None),
p
);
- autoloads.insert(numeric_index.to_string(), Box::new(PhpMixed::String(entry)));
+ autoloads
+ .insert(numeric_index.to_string(), Box::new(PhpMixed::String(entry)));
numeric_index += 1;
continue;
}
let relative_path = if install_path.is_empty() {
- if path_str.is_empty() { ".".to_string() } else { path_str.clone() }
+ if path_str.is_empty() {
+ ".".to_string()
+ } else {
+ path_str.clone()
+ }
} else {
format!("{}/{}", install_path, path_str)
};
@@ -1421,7 +1727,10 @@ impl AutoloadGenerator {
continue;
}
if r#type == "classmap" {
- autoloads.insert(numeric_index.to_string(), Box::new(PhpMixed::String(relative_path)));
+ autoloads.insert(
+ numeric_index.to_string(),
+ Box::new(PhpMixed::String(relative_path)),
+ );
numeric_index += 1;
continue;
}
@@ -1484,18 +1793,26 @@ impl AutoloadGenerator {
}
}
}
- add(root_package.as_package_interface(), &packages, &mut include, &replaced_by);
+ add(
+ root_package.as_package_interface(),
+ &packages,
+ &mut include,
+ &replaced_by,
+ );
- array_filter(package_map, |item: &(Box<dyn PackageInterface>, Option<String>)| -> bool {
- let package = &item.0;
- for name in package.get_names(true) {
- if include.contains_key(&name) {
- return true;
+ array_filter(
+ package_map,
+ |item: &(Box<dyn PackageInterface>, Option<String>)| -> bool {
+ let package = &item.0;
+ for name in package.get_names(true) {
+ if include.contains_key(&name) {
+ return true;
+ }
}
- }
- false
- })
+ false
+ },
+ )
}
/// Sorts packages by dependency weight
@@ -1515,13 +1832,19 @@ impl AutoloadGenerator {
paths.insert(name, path.clone());
}
- let sorted_packages = PackageSorter::sort_packages(packages.values().map(|p| p.clone_box()).collect(), IndexMap::new());
+ let sorted_packages = PackageSorter::sort_packages(
+ packages.values().map(|p| p.clone_box()).collect(),
+ IndexMap::new(),
+ );
let mut sorted_package_map: Vec<(Box<dyn PackageInterface>, Option<String>)> = vec![];
for package in sorted_packages {
let name = package.get_name().to_string();
- sorted_package_map.push((packages.get(&name).unwrap().clone_box(), paths.get(&name).cloned().flatten()));
+ sorted_package_map.push((
+ packages.get(&name).unwrap().clone_box(),
+ paths.get(&name).cloned().flatten(),
+ ));
}
sorted_package_map
@@ -1534,7 +1857,10 @@ pub fn composer_require(file_identifier: &str, file: &str) {
.map(|v| v.as_bool().unwrap_or(false))
.unwrap_or(false)
{
- shirabe_php_shim::globals_set(&["__composer_autoload_files", file_identifier], PhpMixed::Bool(true));
+ shirabe_php_shim::globals_set(
+ &["__composer_autoload_files", file_identifier],
+ PhpMixed::Bool(true),
+ );
let _ = shirabe_php_shim::php_require(file);
}
diff --git a/crates/shirabe/src/autoload/class_loader.rs b/crates/shirabe/src/autoload/class_loader.rs
index 9727a45..2f4cfa0 100644
--- a/crates/shirabe/src/autoload/class_loader.rs
+++ b/crates/shirabe/src/autoload/class_loader.rs
@@ -4,10 +4,10 @@ use indexmap::IndexMap;
use std::sync::{LazyLock, Mutex};
use shirabe_php_shim::{
- apcu_add, apcu_fetch, array_merge, array_values, call_user_func_array, defined, file_exists,
- filter_var, function_exists, include_file, ini_get, spl_autoload_register,
- spl_autoload_unregister, stream_resolve_include_path, strlen, strpos, strrpos, strtr, substr,
- InvalidArgumentException, PhpMixed, DIRECTORY_SEPARATOR, FILTER_VALIDATE_BOOLEAN,
+ DIRECTORY_SEPARATOR, FILTER_VALIDATE_BOOLEAN, InvalidArgumentException, PhpMixed, apcu_add,
+ apcu_fetch, array_merge, array_values, call_user_func_array, defined, file_exists, filter_var,
+ function_exists, include_file, ini_get, spl_autoload_register, spl_autoload_unregister,
+ stream_resolve_include_path, strlen, strpos, strrpos, strtr, substr,
};
/// @var array<string, self>
@@ -314,8 +314,7 @@ impl ClassLoader {
&& filter_var(
&ini_get("apc.enabled").unwrap_or_default(),
FILTER_VALIDATE_BOOLEAN,
- )
- {
+ ) {
apcu_prefix
} else {
None
@@ -344,8 +343,7 @@ impl ClassLoader {
if prepend {
let mut new_map: IndexMap<String, ClassLoader> = IndexMap::new();
new_map.insert(self.vendor_dir.clone().unwrap(), self.clone());
- let old_map: IndexMap<String, ClassLoader> =
- std::mem::take(&mut *registered);
+ let old_map: IndexMap<String, ClassLoader> = std::mem::take(&mut *registered);
for (k, v) in old_map {
if !new_map.contains_key(&k) {
new_map.insert(k, v);
diff --git a/crates/shirabe/src/autoload/class_map_generator.rs b/crates/shirabe/src/autoload/class_map_generator.rs
index 3cfe83a..df61795 100644
--- a/crates/shirabe/src/autoload/class_map_generator.rs
+++ b/crates/shirabe/src/autoload/class_map_generator.rs
@@ -29,7 +29,13 @@ impl ClassMapGenerator {
.map(|(k, v)| (k, Box::new(PhpMixed::String(v))))
.collect(),
);
- std::fs::write(file, format!("<?php return {};", shirabe_php_shim::var_export(&maps_php, true)))?;
+ std::fs::write(
+ file,
+ format!(
+ "<?php return {};",
+ shirabe_php_shim::var_export(&maps_php, true)
+ ),
+ )?;
Ok(())
}
@@ -41,12 +47,21 @@ impl ClassMapGenerator {
autoload_type: Option<String>,
scanned_files: &mut IndexMap<String, bool>,
) -> anyhow::Result<IndexMap<String, String>> {
- let generator = ExternalClassMapGenerator::new(vec!["php".to_string(), "inc".to_string(), "hh".to_string()]);
+ let generator = ExternalClassMapGenerator::new(vec![
+ "php".to_string(),
+ "inc".to_string(),
+ "hh".to_string(),
+ ]);
let mut file_list = FileList::new();
file_list.files = scanned_files.clone();
generator.avoid_duplicate_scans(&file_list);
- generator.scan_paths(path, excluded.as_deref(), autoload_type.as_deref().unwrap_or("classmap"), namespace.as_deref())?;
+ generator.scan_paths(
+ path,
+ excluded.as_deref(),
+ autoload_type.as_deref().unwrap_or("classmap"),
+ namespace.as_deref(),
+ )?;
let class_map = generator.get_class_map();
diff --git a/crates/shirabe/src/autoload/mod.rs b/crates/shirabe/src/autoload/mod.rs
new file mode 100644
index 0000000..e460f71
--- /dev/null
+++ b/crates/shirabe/src/autoload/mod.rs
@@ -0,0 +1,3 @@
+pub mod autoload_generator;
+pub mod class_loader;
+pub mod class_map_generator;
diff --git a/crates/shirabe/src/cache.rs b/crates/shirabe/src/cache.rs
index 301ddc5..fb05ce2 100644
--- a/crates/shirabe/src/cache.rs
+++ b/crates/shirabe/src/cache.rs
@@ -7,9 +7,9 @@ use chrono::Utc;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::symfony::component::finder::finder::Finder;
use shirabe_php_shim::{
- abs, bin2hex, dirname, file_exists, file_get_contents, file_put_contents, filemtime,
- function_exists, hash_file, is_dir, is_writable, mkdir, random_bytes, random_int, rename,
- sprintf, time, unlink, ErrorException, PhpMixed,
+ ErrorException, PhpMixed, abs, bin2hex, dirname, file_exists, file_get_contents,
+ file_put_contents, filemtime, function_exists, hash_file, is_dir, is_writable, mkdir,
+ random_bytes, random_int, rename, sprintf, time, unlink,
};
use crate::io::io_interface::IOInterface;
@@ -71,10 +71,7 @@ impl Cache {
}
pub fn is_usable(path: &str) -> bool {
- !Preg::is_match(
- r"{(^|[\\\\/])(\$null|nul|NUL|/dev/null)([\\\\/]|$)}",
- path,
- )
+ !Preg::is_match(r"{(^|[\\\\/])(\$null|nul|NUL|/dev/null)([\\\\/]|$)}", path)
}
pub fn is_enabled(&mut self) -> bool {
@@ -136,12 +133,7 @@ impl Cache {
IOInterface::DEBUG,
);
- let temp_file_name = format!(
- "{}{}{}.tmp",
- self.root,
- file,
- bin2hex(&random_bytes(5)),
- );
+ let temp_file_name = format!("{}{}{}.tmp", self.root, file, bin2hex(&random_bytes(5)),);
// TODO(phase-b): use anyhow::Result<Result<T, E>> to model PHP try/catch (ErrorException)
let attempt: Result<bool> = {
let put = file_put_contents(&temp_file_name, contents.as_bytes());
@@ -188,8 +180,10 @@ impl Cache {
if function_exists("disk_free_space") {
// TODO(phase-b): @disk_free_space suppresses errors
PhpMixed::Float(
- shirabe_php_shim::disk_free_space(&dirname(&temp_file_name))
- .unwrap_or(0.0),
+ shirabe_php_shim::disk_free_space(&dirname(
+ &temp_file_name,
+ ))
+ .unwrap_or(0.0),
)
} else {
PhpMixed::String("unknown".to_string())
@@ -197,11 +191,8 @@ impl Cache {
],
);
- self.io.write_error(
- PhpMixed::String(message),
- true,
- IOInterface::NORMAL,
- );
+ self.io
+ .write_error(PhpMixed::String(message), true, IOInterface::NORMAL);
return Ok(false);
}
@@ -219,7 +210,8 @@ impl Cache {
if self.is_enabled() && !self.read_only {
let file = Preg::replace(&format!("{{[^{}]}}i", self.allowlist), "-", file);
let full_path = format!("{}{}", self.root, file);
- self.filesystem.ensure_directory_exists(&dirname(&full_path));
+ self.filesystem
+ .ensure_directory_exists(&dirname(&full_path));
if !file_exists(source) {
self.io.write_error(
@@ -232,10 +224,7 @@ impl Cache {
);
} else if self.io.is_debug() {
self.io.write_error(
- PhpMixed::String(format!(
- "Writing {} into cache from {}",
- full_path, source,
- )),
+ PhpMixed::String(format!("Writing {} into cache from {}", full_path, source,)),
true,
IOInterface::NORMAL,
);
diff --git a/crates/shirabe/src/command/about_command.rs b/crates/shirabe/src/command/about_command.rs
index 627a7f2..3b16b0e 100644
--- a/crates/shirabe/src/command/about_command.rs
+++ b/crates/shirabe/src/command/about_command.rs
@@ -1,9 +1,9 @@
//! ref: composer/src/Composer/Command/AboutCommand.php
-use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
-use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
use crate::command::base_command::BaseCommand;
use crate::composer::Composer;
+use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
+use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
pub struct AboutCommand {
inner: BaseCommand,
diff --git a/crates/shirabe/src/command/archive_command.rs b/crates/shirabe/src/command/archive_command.rs
index b07a303..b1c8e83 100644
--- a/crates/shirabe/src/command/archive_command.rs
+++ b/crates/shirabe/src/command/archive_command.rs
@@ -6,7 +6,7 @@ use anyhow::Result;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
-use shirabe_php_shim::{get_debug_type, LogicException};
+use shirabe_php_shim::{LogicException, get_debug_type};
use crate::command::base_command::BaseCommand;
use crate::command::completion_trait::CompletionTrait;
@@ -88,29 +88,59 @@ impl ArchiveCommand {
None => Factory::create_config(None, None)?,
};
- let format = input.get_option("format").as_string_opt()
+ let format = input
+ .get_option("format")
+ .as_string_opt()
.map(|s| s.to_string())
- .unwrap_or_else(|| config.get("archive-format").as_string().unwrap_or("tar").to_string());
+ .unwrap_or_else(|| {
+ config
+ .get("archive-format")
+ .as_string()
+ .unwrap_or("tar")
+ .to_string()
+ });
- let dir = input.get_option("dir").as_string_opt()
+ let dir = input
+ .get_option("dir")
+ .as_string_opt()
.map(|s| s.to_string())
- .unwrap_or_else(|| config.get("archive-dir").as_string().unwrap_or(".").to_string());
+ .unwrap_or_else(|| {
+ config
+ .get("archive-dir")
+ .as_string()
+ .unwrap_or(".")
+ .to_string()
+ });
let return_code = self.archive(
self.inner.get_io(),
&config,
- input.get_argument("package").as_string_opt().map(|s| s.to_string()),
- input.get_argument("version").as_string_opt().map(|s| s.to_string()),
+ input
+ .get_argument("package")
+ .as_string_opt()
+ .map(|s| s.to_string()),
+ input
+ .get_argument("version")
+ .as_string_opt()
+ .map(|s| s.to_string()),
&format,
&dir,
- input.get_option("file").as_string_opt().map(|s| s.to_string()),
- input.get_option("ignore-filters").as_bool().unwrap_or(false),
+ input
+ .get_option("file")
+ .as_string_opt()
+ .map(|s| s.to_string()),
+ input
+ .get_option("ignore-filters")
+ .as_bool()
+ .unwrap_or(false),
composer.as_ref(),
)?;
if return_code == 0 {
if let Some(ref composer) = composer {
- composer.get_event_dispatcher().dispatch_script(ScriptEvents::POST_ARCHIVE_CMD, true);
+ composer
+ .get_event_dispatcher()
+ .dispatch_script(ScriptEvents::POST_ARCHIVE_CMD, true);
}
}
@@ -135,7 +165,8 @@ impl ArchiveCommand {
let factory = Factory::new();
let process = ProcessExecutor::new_default();
let http_downloader = Factory::create_http_downloader(io, config)?;
- let download_manager = factory.create_download_manager(io, config, &http_downloader, &process)?;
+ let download_manager =
+ factory.create_download_manager(io, config, &http_downloader, &process)?;
let loop_ = Loop::new(http_downloader, process);
factory.create_archive_manager(config, &download_manager, &loop_)?
};
@@ -149,13 +180,26 @@ impl ArchiveCommand {
self.inner.require_composer()?.get_package().clone_box()
};
- io.write_error(&format!("<info>Creating the archive into \"{}\".</info>", dest));
- let package_path = archive_manager.archive(package.as_ref(), format, dest, file_name.as_deref(), ignore_filters)?;
+ io.write_error(&format!(
+ "<info>Creating the archive into \"{}\".</info>",
+ dest
+ ));
+ let package_path = archive_manager.archive(
+ package.as_ref(),
+ format,
+ dest,
+ file_name.as_deref(),
+ ignore_filters,
+ )?;
let fs = Filesystem::new();
let short_path = fs.find_shortest_path(&Platform::get_cwd(), &package_path, true);
io.write_error_no_newline("Created: ");
- let display = if short_path.len() < package_path.len() { &short_path } else { &package_path };
+ let display = if short_path.len() < package_path.len() {
+ &short_path
+ } else {
+ &package_path
+ };
io.write(display);
Ok(0)
@@ -175,20 +219,33 @@ impl ArchiveCommand {
if let Some(composer) = self.inner.try_composer() {
let local_repo = composer.get_repository_manager().get_local_repository();
- let mut repos: Vec<Box<dyn crate::repository::repository_interface::RepositoryInterface>> = vec![local_repo.clone_box()];
- repos.extend(composer.get_repository_manager().get_repositories().iter().map(|r| r.clone_box()));
+ let mut repos: Vec<
+ Box<dyn crate::repository::repository_interface::RepositoryInterface>,
+ > = vec![local_repo.clone_box()];
+ repos.extend(
+ composer
+ .get_repository_manager()
+ .get_repositories()
+ .iter()
+ .map(|r| r.clone_box()),
+ );
repo = CompositeRepository::new(repos);
min_stability = composer.get_package().get_minimum_stability().to_string();
} else {
let default_repos = RepositoryFactory::default_repos_with_default_manager(io)?;
let repo_names: Vec<String> = default_repos.iter().map(|r| r.get_repo_name()).collect();
- io.write_error(&format!("No composer.json found in the current directory, searching packages from {}", repo_names.join(", ")));
+ io.write_error(&format!(
+ "No composer.json found in the current directory, searching packages from {}",
+ repo_names.join(", ")
+ ));
repo = CompositeRepository::new(default_repos);
min_stability = "stable".to_string();
}
if let Some(version_str) = &version {
- if let Some(matches) = Preg::match_strict_groups(r"{@(stable|RC|beta|alpha|dev)$}i", version_str) {
+ if let Some(matches) =
+ Preg::match_strict_groups(r"{@(stable|RC|beta|alpha|dev)$}i", version_str)
+ {
min_stability = VersionParser::normalize_stability(&matches[1]);
let full_match_len = matches[0].len();
version = Some(version_str[..version_str.len() - full_match_len].to_string());
@@ -203,33 +260,60 @@ impl ArchiveCommand {
let package = if packages.len() > 1 {
let version_selector = VersionSelector::new(&repo_set);
- let best = version_selector.find_best_candidate(&package_name.to_lowercase(), version.as_deref(), &min_stability);
+ let best = version_selector.find_best_candidate(
+ &package_name.to_lowercase(),
+ version.as_deref(),
+ &min_stability,
+ );
let p = best.unwrap_or_else(|| packages.into_iter().next().unwrap());
- io.write_error(&format!("<info>Found multiple matches, selected {}.</info>", p.get_pretty_string()));
+ io.write_error(&format!(
+ "<info>Found multiple matches, selected {}.</info>",
+ p.get_pretty_string()
+ ));
// alternatives message omitted for brevity (already logged via p being selected)
io.write_error("<comment>Please use a more specific constraint to pick a different package.</comment>");
p
} else if packages.len() == 1 {
let p = packages.into_iter().next().unwrap();
- io.write_error(&format!("<info>Found an exact match {}.</info>", p.get_pretty_string()));
+ io.write_error(&format!(
+ "<info>Found an exact match {}.</info>",
+ p.get_pretty_string()
+ ));
p
} else {
- io.write_error(&format!("<error>Could not find a package matching {}.</error>", package_name));
+ io.write_error(&format!(
+ "<error>Could not find a package matching {}.</error>",
+ package_name
+ ));
return Ok(None);
};
- if (package.as_any() as &dyn Any).downcast_ref::<dyn CompletePackageInterface>().is_none() {
+ if (package.as_any() as &dyn Any)
+ .downcast_ref::<dyn CompletePackageInterface>()
+ .is_none()
+ {
return Err(LogicException {
- message: format!("Expected a CompletePackageInterface instance but found {}", get_debug_type(package.as_php_mixed())),
+ message: format!(
+ "Expected a CompletePackageInterface instance but found {}",
+ get_debug_type(package.as_php_mixed())
+ ),
code: 0,
- }.into());
+ }
+ .into());
}
- if (package.as_any() as &dyn Any).downcast_ref::<BasePackage>().is_none() {
+ if (package.as_any() as &dyn Any)
+ .downcast_ref::<BasePackage>()
+ .is_none()
+ {
return Err(LogicException {
- message: format!("Expected a BasePackage instance but found {}", get_debug_type(package.as_php_mixed())),
+ message: format!(
+ "Expected a BasePackage instance but found {}",
+ get_debug_type(package.as_php_mixed())
+ ),
code: 0,
- }.into());
+ }
+ .into());
}
Ok(Some(package.into_complete()))
diff --git a/crates/shirabe/src/command/audit_command.rs b/crates/shirabe/src/command/audit_command.rs
index 6889c99..7fb6c5f 100644
--- a/crates/shirabe/src/command/audit_command.rs
+++ b/crates/shirabe/src/command/audit_command.rs
@@ -1,9 +1,5 @@
//! ref: composer/src/Composer/Command/AuditCommand.php
-use anyhow::Result;
-use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
-use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
-use shirabe_php_shim::{array_fill_keys, array_merge, implode, in_array, InvalidArgumentException, PhpMixed, UnexpectedValueException};
use crate::advisory::audit_config::AuditConfig;
use crate::advisory::auditor::Auditor;
use crate::command::base_command::BaseCommand;
@@ -13,6 +9,13 @@ use crate::package::package_interface::PackageInterface;
use crate::repository::installed_repository::InstalledRepository;
use crate::repository::repository_set::RepositorySet;
use crate::repository::repository_utils::RepositoryUtils;
+use anyhow::Result;
+use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
+use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
+use shirabe_php_shim::{
+ InvalidArgumentException, PhpMixed, UnexpectedValueException, array_fill_keys, array_merge,
+ implode, in_array,
+};
#[derive(Debug)]
pub struct AuditCommand {
@@ -40,12 +43,18 @@ impl AuditCommand {
);
}
- pub fn execute(&mut self, input: &dyn InputInterface, _output: &dyn OutputInterface) -> Result<i64> {
+ pub fn execute(
+ &mut self,
+ input: &dyn InputInterface,
+ _output: &dyn OutputInterface,
+ ) -> Result<i64> {
let composer = self.inner.require_composer()?;
let packages = self.get_packages(&composer, input)?;
if packages.is_empty() {
- self.inner.get_io().write_error("No packages - skipping audit.");
+ self.inner
+ .get_io()
+ .write_error("No packages - skipping audit.");
return Ok(0);
}
@@ -57,12 +66,31 @@ impl AuditCommand {
let audit_config = AuditConfig::from_config(composer.get_config())?;
- let abandoned = input.get_option("abandoned").as_string_opt().map(|s| s.to_string());
- if abandoned.is_some() && !in_array(PhpMixed::String(abandoned.clone().unwrap()), &PhpMixed::from(Auditor::ABANDONEDS.to_vec()), true) {
+ let abandoned = input
+ .get_option("abandoned")
+ .as_string_opt()
+ .map(|s| s.to_string());
+ if abandoned.is_some()
+ && !in_array(
+ PhpMixed::String(abandoned.clone().unwrap()),
+ &PhpMixed::from(Auditor::ABANDONEDS.to_vec()),
+ true,
+ )
+ {
return Err(InvalidArgumentException {
- message: format!("--abandoned must be one of {}.", implode(", ", &Auditor::ABANDONEDS.iter().map(|s| s.to_string()).collect::<Vec<_>>())),
+ message: format!(
+ "--abandoned must be one of {}.",
+ implode(
+ ", ",
+ &Auditor::ABANDONEDS
+ .iter()
+ .map(|s| s.to_string())
+ .collect::<Vec<_>>()
+ )
+ ),
code: 0,
- }.into());
+ }
+ .into());
}
let abandoned = abandoned.unwrap_or_else(|| audit_config.audit_abandoned.clone());
@@ -71,23 +99,33 @@ impl AuditCommand {
array_fill_keys(input.get_option("ignore-severity"), PhpMixed::Null),
PhpMixed::from(audit_config.ignore_severity_for_audit.clone()),
);
- let ignore_unreachable = input.get_option("ignore-unreachable").as_bool().unwrap_or(false) || audit_config.ignore_unreachable;
+ let ignore_unreachable = input
+ .get_option("ignore-unreachable")
+ .as_bool()
+ .unwrap_or(false)
+ || audit_config.ignore_unreachable;
- Ok(auditor.audit(
- self.inner.get_io(),
- &repo_set,
- &packages,
- &self.inner.get_audit_format(input, "format"),
- false,
- &audit_config.ignore_list_for_audit,
- &abandoned,
- &ignore_severities,
- ignore_unreachable,
- &audit_config.ignore_abandoned_for_audit,
- )?.min(255))
+ Ok(auditor
+ .audit(
+ self.inner.get_io(),
+ &repo_set,
+ &packages,
+ &self.inner.get_audit_format(input, "format"),
+ false,
+ &audit_config.ignore_list_for_audit,
+ &abandoned,
+ &ignore_severities,
+ ignore_unreachable,
+ &audit_config.ignore_abandoned_for_audit,
+ )?
+ .min(255))
}
- fn get_packages(&self, composer: &Composer, input: &dyn InputInterface) -> Result<Vec<Box<dyn PackageInterface>>> {
+ fn get_packages(
+ &self,
+ composer: &Composer,
+ input: &dyn InputInterface,
+ ) -> Result<Vec<Box<dyn PackageInterface>>> {
if input.get_option("locked").as_bool().unwrap_or(false) {
if !composer.get_locker().is_locked() {
return Err(UnexpectedValueException {
@@ -96,14 +134,21 @@ impl AuditCommand {
}.into());
}
let locker = composer.get_locker();
- return Ok(locker.get_locked_repository(!input.get_option("no-dev").as_bool().unwrap_or(false))?.get_packages());
+ return Ok(locker
+ .get_locked_repository(!input.get_option("no-dev").as_bool().unwrap_or(false))?
+ .get_packages());
}
let root_pkg = composer.get_package();
- let installed_repo = InstalledRepository::new(vec![composer.get_repository_manager().get_local_repository()]);
+ let installed_repo = InstalledRepository::new(vec![
+ composer.get_repository_manager().get_local_repository(),
+ ]);
if input.get_option("no-dev").as_bool().unwrap_or(false) {
- return Ok(RepositoryUtils::filter_required_packages(installed_repo.get_packages(), root_pkg));
+ return Ok(RepositoryUtils::filter_required_packages(
+ installed_repo.get_packages(),
+ root_pkg,
+ ));
}
Ok(installed_repo.get_packages())
diff --git a/crates/shirabe/src/command/base_command.rs b/crates/shirabe/src/command/base_command.rs
index 704b932..77777ef 100644
--- a/crates/shirabe/src/command/base_command.rs
+++ b/crates/shirabe/src/command/base_command.rs
@@ -11,8 +11,8 @@ use shirabe_external_packages::symfony::component::console::input::input_interfa
use shirabe_external_packages::symfony::component::console::output::output_interface::OutputInterface;
use shirabe_external_packages::symfony::component::console::terminal::Terminal;
use shirabe_php_shim::{
- count, explode, in_array, is_string, max, InvalidArgumentException, LogicException, PhpMixed,
- RuntimeException, UnexpectedValueException,
+ InvalidArgumentException, LogicException, PhpMixed, RuntimeException, UnexpectedValueException,
+ count, explode, in_array, is_string, max,
};
use crate::advisory::audit_config::AuditConfig;
@@ -71,7 +71,9 @@ impl BaseCommand {
disable_scripts: Option<bool>,
) -> Result<Option<Composer>> {
if required {
- return Ok(Some(self.require_composer(disable_plugins, disable_scripts)?));
+ return Ok(Some(
+ self.require_composer(disable_plugins, disable_scripts)?,
+ ));
}
Ok(self.try_composer(disable_plugins, disable_scripts))
@@ -267,8 +269,14 @@ impl BaseCommand {
("COMPOSER_PREFER_LOWEST", vec!["prefer-lowest"]),
("COMPOSER_MINIMAL_CHANGES", vec!["minimal-changes"]),
("COMPOSER_WITH_DEPENDENCIES", vec!["with-dependencies"]),
- ("COMPOSER_WITH_ALL_DEPENDENCIES", vec!["with-all-dependencies"]),
- ("COMPOSER_NO_SECURITY_BLOCKING", vec!["no-security-blocking"]),
+ (
+ "COMPOSER_WITH_ALL_DEPENDENCIES",
+ vec!["with-all-dependencies"],
+ ),
+ (
+ "COMPOSER_NO_SECURITY_BLOCKING",
+ vec!["no-security-blocking"],
+ ),
]
.into_iter()
.collect();
@@ -285,7 +293,10 @@ impl BaseCommand {
}
if true == input.has_option("ignore-platform-reqs") {
- if !input.get_option("ignore-platform-reqs").as_bool().unwrap_or(false)
+ if !input
+ .get_option("ignore-platform-reqs")
+ .as_bool()
+ .unwrap_or(false)
&& Platform::get_env("COMPOSER_IGNORE_PLATFORM_REQS")
.as_bool()
.unwrap_or(false)
@@ -304,7 +315,10 @@ impl BaseCommand {
.unwrap_or(false))
{
let ignore_platform_req_env = Platform::get_env("COMPOSER_IGNORE_PLATFORM_REQ");
- let ignore_str = ignore_platform_req_env.as_string().unwrap_or("").to_string();
+ let ignore_str = ignore_platform_req_env
+ .as_string()
+ .unwrap_or("")
+ .to_string();
if 0 == count(&input.get_option("ignore-platform-req"))
&& is_string(&ignore_platform_req_env)
&& "" != ignore_str
@@ -385,9 +399,7 @@ impl BaseCommand {
return Ok((prefer_source, prefer_dist));
}
- if input.has_option("prefer-install")
- && is_string(&input.get_option("prefer-install"))
- {
+ if input.has_option("prefer-install") && is_string(&input.get_option("prefer-install")) {
if input.get_option("prefer-source").as_bool().unwrap_or(false) {
return Err(InvalidArgumentException {
message: "--prefer-source can not be used together with --prefer-install"
@@ -450,9 +462,7 @@ impl BaseCommand {
&self,
input: &dyn InputInterface,
) -> Result<Box<dyn PlatformRequirementFilterInterface>> {
- if !input.has_option("ignore-platform-reqs")
- || !input.has_option("ignore-platform-req")
- {
+ if !input.has_option("ignore-platform-reqs") || !input.has_option("ignore-platform-req") {
return Err(LogicException {
message:
"Calling getPlatformRequirementFilter from a command which does not define the --ignore-platform-req[s] flags is not permitted."
@@ -462,7 +472,12 @@ impl BaseCommand {
.into());
}
- if true == input.get_option("ignore-platform-reqs").as_bool().unwrap_or(false) {
+ if true
+ == input
+ .get_option("ignore-platform-reqs")
+ .as_bool()
+ .unwrap_or(false)
+ {
return Ok(PlatformRequirementFilterFactory::ignore_all());
}
@@ -541,11 +556,7 @@ impl BaseCommand {
/// @internal
/// @param 'format'|'audit-format' $optName
/// @return Auditor::FORMAT_*
- pub fn get_audit_format(
- &self,
- input: &dyn InputInterface,
- opt_name: &str,
- ) -> Result<String> {
+ pub fn get_audit_format(&self, input: &dyn InputInterface, opt_name: &str) -> Result<String> {
if !input.has_option(opt_name) {
return Err(LogicException {
message: format!(
diff --git a/crates/shirabe/src/command/base_config_command.rs b/crates/shirabe/src/command/base_config_command.rs
index 3d6e0da..74929da 100644
--- a/crates/shirabe/src/command/base_config_command.rs
+++ b/crates/shirabe/src/command/base_config_command.rs
@@ -1,9 +1,5 @@
//! ref: composer/src/Composer/Command/BaseConfigCommand.php
-use indexmap::IndexMap;
-use shirabe_php_shim::{touch, chmod, PhpMixed};
-use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
-use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
use crate::command::base_command::BaseCommand;
use crate::config::Config;
use crate::config::json_config_source::JsonConfigSource;
@@ -11,6 +7,10 @@ use crate::factory::Factory;
use crate::json::json_file::JsonFile;
use crate::util::platform::Platform;
use crate::util::silencer::Silencer;
+use indexmap::IndexMap;
+use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
+use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
+use shirabe_php_shim::{PhpMixed, chmod, touch};
#[derive(Debug)]
pub struct BaseConfigCommand {
@@ -63,7 +63,10 @@ impl BaseConfigCommand {
touch(&path);
self.config_file.as_mut().unwrap().write(PhpMixed::Array({
let mut m = IndexMap::new();
- m.insert("config".to_string(), Box::new(PhpMixed::Array(IndexMap::new())));
+ m.insert(
+ "config".to_string(),
+ Box::new(PhpMixed::Array(IndexMap::new())),
+ );
m
}))?;
let _ = Silencer::call(|| {
diff --git a/crates/shirabe/src/command/base_dependency_command.rs b/crates/shirabe/src/command/base_dependency_command.rs
index 3a62a18..4ea779a 100644
--- a/crates/shirabe/src/command/base_dependency_command.rs
+++ b/crates/shirabe/src/command/base_dependency_command.rs
@@ -80,8 +80,9 @@ impl BaseDependencyCommand {
if !locker.is_locked() {
return Err(anyhow::anyhow!(UnexpectedValueException {
- message: "A valid composer.lock file is required to run this command with --locked"
- .to_string(),
+ message:
+ "A valid composer.lock file is required to run this command with --locked"
+ .to_string(),
code: 0,
}));
}
@@ -108,7 +109,10 @@ impl BaseDependencyCommand {
repos.push(Box::new(local_repo));
let platform_overrides = composer.get_config().get("platform").unwrap_or_default();
- repos.push(Box::new(PlatformRepository::new(vec![], platform_overrides)));
+ repos.push(Box::new(PlatformRepository::new(
+ vec![],
+ platform_overrides,
+ )));
}
let mut installed_repo = InstalledRepository::new(repos)?;
@@ -158,11 +162,14 @@ impl BaseDependencyCommand {
let parser = VersionParser::new();
let platform_constraint = parser.parse_constraints(&text_constraint)?;
if platform_constraint.get_lower_bound() != Bound::zero() {
- let version = platform_constraint.get_lower_bound().get_version().to_string();
+ let version = platform_constraint
+ .get_lower_bound()
+ .get_version()
+ .to_string();
let temp_platform_pkg = Package::new(needle.clone(), version.clone(), version);
- installed_repo.add_repository(Box::new(InstalledArrayRepository::new(vec![
- Box::new(temp_platform_pkg),
- ])))?;
+ installed_repo.add_repository(Box::new(InstalledArrayRepository::new(
+ vec![Box::new(temp_platform_pkg)],
+ )))?;
}
} else {
self.inner.get_io().write_error(&format!(
@@ -221,9 +228,15 @@ impl BaseDependencyCommand {
None
};
- let render_tree = input.get_option(Self::OPTION_TREE).as_bool().unwrap_or(false);
- let recursive =
- render_tree || input.get_option(Self::OPTION_RECURSIVE).as_bool().unwrap_or(false);
+ let render_tree = input
+ .get_option(Self::OPTION_TREE)
+ .as_bool()
+ .unwrap_or(false);
+ let recursive = render_tree
+ || input
+ .get_option(Self::OPTION_RECURSIVE)
+ .as_bool()
+ .unwrap_or(false);
let mut r#return: i64 = if inverted { 1 } else { 0 };
@@ -296,11 +309,7 @@ impl BaseDependencyCommand {
Ok(r#return)
}
- pub(crate) fn print_table(
- &self,
- output: &dyn OutputInterface,
- results: Vec<DependentsEntry>,
- ) {
+ pub(crate) fn print_table(&self, output: &dyn OutputInterface, results: Vec<DependentsEntry>) {
let mut table: Vec<Vec<String>> = vec![];
let mut doubles: IndexMap<String, bool> = IndexMap::new();
let mut results = results;
@@ -316,12 +325,12 @@ impl BaseDependencyCommand {
continue;
}
doubles.insert(unique.clone(), true);
- let version =
- if package.get_pretty_version() == RootPackage::DEFAULT_PRETTY_VERSION {
- "-".to_string()
- } else {
- package.get_pretty_version().to_string()
- };
+ let version = if package.get_pretty_version() == RootPackage::DEFAULT_PRETTY_VERSION
+ {
+ "-".to_string()
+ } else {
+ package.get_pretty_version().to_string()
+ };
let package_url = PackageInfo::get_view_source_or_homepage_url(&*package);
let name_with_link = match &package_url {
Some(url) => format!(
diff --git a/crates/shirabe/src/command/bump_command.rs b/crates/shirabe/src/command/bump_command.rs
index 2787fcc..ddb17c2 100644
--- a/crates/shirabe/src/command/bump_command.rs
+++ b/crates/shirabe/src/command/bump_command.rs
@@ -4,7 +4,7 @@ use anyhow::Result;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
-use shirabe_php_shim::{file_get_contents, file_put_contents, is_writable, strtolower, PhpMixed};
+use shirabe_php_shim::{PhpMixed, file_get_contents, file_put_contents, is_writable, strtolower};
use crate::command::base_command::BaseCommand;
use crate::command::completion_trait::CompletionTrait;
@@ -100,7 +100,10 @@ impl BumpCommand {
if !Filesystem::is_readable(&composer_json_path) {
io.write_error(
- PhpMixed::String(format!("<error>{} is not readable.</error>", composer_json_path)),
+ PhpMixed::String(format!(
+ "<error>{} is not readable.</error>",
+ composer_json_path
+ )),
true,
IOInterface::NORMAL,
);
@@ -215,12 +218,9 @@ impl BumpCommand {
.collect::<std::collections::HashSet<_>>()
.into_iter()
.collect();
- let pattern =
- BasePackage::package_names_to_regexp(&unique_lower);
+ let pattern = BasePackage::package_names_to_regexp(&unique_lower);
for (key, reqs) in tasks.iter_mut() {
- reqs.retain(|pkg_name, _| {
- Preg::is_match(&pattern, pkg_name).unwrap_or(false)
- });
+ reqs.retain(|pkg_name, _| Preg::is_match(&pattern, pkg_name).unwrap_or(false));
}
packages_filter
} else {
@@ -246,8 +246,8 @@ impl BumpCommand {
package = alias.get_alias_of();
}
- let bumped = bumper
- .bump_requirement(link.get_constraint().as_ref(), package.as_ref())?;
+ let bumped =
+ bumper.bump_requirement(link.get_constraint().as_ref(), package.as_ref())?;
if bumped == current_constraint {
continue;
diff --git a/crates/shirabe/src/command/check_platform_reqs_command.rs b/crates/shirabe/src/command/check_platform_reqs_command.rs
index fe7c79b..fcf10aa 100644
--- a/crates/shirabe/src/command/check_platform_reqs_command.rs
+++ b/crates/shirabe/src/command/check_platform_reqs_command.rs
@@ -4,13 +4,13 @@ use anyhow::Result;
use indexmap::IndexMap;
use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
-use shirabe_php_shim::{strip_tags, PhpMixed};
+use shirabe_php_shim::{PhpMixed, strip_tags};
use shirabe_semver::constraint::constraint::Constraint;
use crate::command::base_command::BaseCommand;
+use crate::console::input::input_option::InputOption;
use crate::json::json_file::JsonFile;
use crate::package::link::Link;
-use crate::console::input::input_option::InputOption;
use crate::repository::installed_repository::InstalledRepository;
use crate::repository::platform_repository::PlatformRepository;
use crate::repository::root_package_repository::RootPackageRepository;
@@ -45,7 +45,11 @@ impl CheckPlatformReqsCommand {
);
}
- pub fn execute(&self, input: &dyn InputInterface, _output: &dyn OutputInterface) -> Result<i64> {
+ pub fn execute(
+ &self,
+ input: &dyn InputInterface,
+ _output: &dyn OutputInterface,
+ ) -> Result<i64> {
let composer = self.inner.require_composer()?;
let io = self.inner.get_io();
@@ -82,19 +86,26 @@ impl CheckPlatformReqsCommand {
if !no_dev {
for (require, link) in composer.get_package().get_dev_requires() {
- requires.entry(require.to_string()).or_insert_with(Vec::new).push(link.clone());
+ requires
+ .entry(require.to_string())
+ .or_insert_with(Vec::new)
+ .push(link.clone());
}
}
let root_pkg_repo = RootPackageRepository::new(composer.get_package().clone_box());
- let installed_repo = InstalledRepository::new(vec![installed_repo_base, Box::new(root_pkg_repo)]);
+ let installed_repo =
+ InstalledRepository::new(vec![installed_repo_base, Box::new(root_pkg_repo)]);
for package in installed_repo.get_packages() {
if remove_packages.contains(&package.get_name().to_string()) {
continue;
}
for (require, link) in package.get_requires() {
- requires.entry(require.to_string()).or_insert_with(Vec::new).push(link.clone());
+ requires
+ .entry(require.to_string())
+ .or_insert_with(Vec::new)
+ .push(link.clone());
}
}
@@ -111,7 +122,8 @@ impl CheckPlatformReqsCommand {
'requirements: for (require, links) in &requires_sorted {
if PlatformRepository::is_platform_package(require) {
- let candidates = installed_repo_with_platform.find_packages_with_replacers_and_providers(require);
+ let candidates = installed_repo_with_platform
+ .find_packages_with_replacers_and_providers(require);
if !candidates.is_empty() {
let mut req_results: Vec<CheckResult> = vec![];
'candidates: for candidate in &candidates {
@@ -121,7 +133,11 @@ impl CheckPlatformReqsCommand {
Some(c)
} else {
let mut found = None;
- for link in candidate.get_provides().iter().chain(candidate.get_replaces().iter()) {
+ for link in candidate
+ .get_provides()
+ .iter()
+ .chain(candidate.get_replaces().iter())
+ {
if link.get_target() == require {
found = Some(link.get_constraint().clone_box());
break;
@@ -149,7 +165,10 @@ impl CheckPlatformReqsCommand {
provider: if candidate.get_name() == require {
String::new()
} else {
- format!("<comment>provided by {}</comment>", candidate.get_pretty_name())
+ format!(
+ "<comment>provided by {}</comment>",
+ candidate.get_pretty_name()
+ )
},
});
continue 'candidates;
@@ -168,7 +187,10 @@ impl CheckPlatformReqsCommand {
provider: if candidate.get_name() == require {
String::new()
} else {
- format!("<comment>provided by {}</comment>", candidate.get_pretty_name())
+ format!(
+ "<comment>provided by {}</comment>",
+ candidate.get_pretty_name()
+ )
},
});
continue 'requirements;
@@ -190,7 +212,11 @@ impl CheckPlatformReqsCommand {
}
}
- let format = input.get_option("format").as_string().unwrap_or("text").to_string();
+ let format = input
+ .get_option("format")
+ .as_string()
+ .unwrap_or("text")
+ .to_string();
self.print_table(_output, &results, &format);
Ok(exit_code)
@@ -200,49 +226,91 @@ impl CheckPlatformReqsCommand {
let io = self.inner.get_io();
if format == "json" {
- let rows: Vec<PhpMixed> = results.iter().map(|result| {
- let mut row = IndexMap::new();
- row.insert("name".to_string(), Box::new(PhpMixed::String(result.platform_package.clone())));
- row.insert("version".to_string(), Box::new(PhpMixed::String(result.version.clone())));
- row.insert("status".to_string(), Box::new(PhpMixed::String(strip_tags(&result.status))));
- if let Some(link) = &result.link {
- let mut failed_req = IndexMap::new();
- failed_req.insert("source".to_string(), Box::new(PhpMixed::String(link.get_source().to_string())));
- failed_req.insert("type".to_string(), Box::new(PhpMixed::String(link.get_description().to_string())));
- failed_req.insert("target".to_string(), Box::new(PhpMixed::String(link.get_target().to_string())));
- failed_req.insert("constraint".to_string(), Box::new(PhpMixed::String(link.get_pretty_constraint().unwrap_or("").to_string())));
- row.insert("failed_requirement".to_string(), Box::new(PhpMixed::Array(failed_req)));
- } else {
- row.insert("failed_requirement".to_string(), Box::new(PhpMixed::Null));
- }
- let provider_str = strip_tags(&result.provider);
- row.insert("provider".to_string(), Box::new(if provider_str.is_empty() {
- PhpMixed::Null
- } else {
- PhpMixed::String(provider_str)
- }));
- PhpMixed::Array(row)
- }).collect();
-
- io.write(&JsonFile::encode(&PhpMixed::List(rows.into_iter().map(Box::new).collect())));
- } else {
- let rows: Vec<Vec<PhpMixed>> = results.iter().map(|result| {
- vec![
- PhpMixed::String(result.platform_package.clone()),
- PhpMixed::String(result.version.clone()),
+ let rows: Vec<PhpMixed> = results
+ .iter()
+ .map(|result| {
+ let mut row = IndexMap::new();
+ row.insert(
+ "name".to_string(),
+ Box::new(PhpMixed::String(result.platform_package.clone())),
+ );
+ row.insert(
+ "version".to_string(),
+ Box::new(PhpMixed::String(result.version.clone())),
+ );
+ row.insert(
+ "status".to_string(),
+ Box::new(PhpMixed::String(strip_tags(&result.status))),
+ );
if let Some(link) = &result.link {
- PhpMixed::String(format!("{} {} {} ({})",
- link.get_source(),
- link.get_description(),
- link.get_target(),
- link.get_pretty_constraint().unwrap_or(""),
- ))
+ let mut failed_req = IndexMap::new();
+ failed_req.insert(
+ "source".to_string(),
+ Box::new(PhpMixed::String(link.get_source().to_string())),
+ );
+ failed_req.insert(
+ "type".to_string(),
+ Box::new(PhpMixed::String(link.get_description().to_string())),
+ );
+ failed_req.insert(
+ "target".to_string(),
+ Box::new(PhpMixed::String(link.get_target().to_string())),
+ );
+ failed_req.insert(
+ "constraint".to_string(),
+ Box::new(PhpMixed::String(
+ link.get_pretty_constraint().unwrap_or("").to_string(),
+ )),
+ );
+ row.insert(
+ "failed_requirement".to_string(),
+ Box::new(PhpMixed::Array(failed_req)),
+ );
} else {
- PhpMixed::String(String::new())
- },
- PhpMixed::String(format!("{} {}", result.status, result.provider).trim_end().to_string()),
- ]
- }).collect();
+ row.insert("failed_requirement".to_string(), Box::new(PhpMixed::Null));
+ }
+ let provider_str = strip_tags(&result.provider);
+ row.insert(
+ "provider".to_string(),
+ Box::new(if provider_str.is_empty() {
+ PhpMixed::Null
+ } else {
+ PhpMixed::String(provider_str)
+ }),
+ );
+ PhpMixed::Array(row)
+ })
+ .collect();
+
+ io.write(&JsonFile::encode(&PhpMixed::List(
+ rows.into_iter().map(Box::new).collect(),
+ )));
+ } else {
+ let rows: Vec<Vec<PhpMixed>> = results
+ .iter()
+ .map(|result| {
+ vec![
+ PhpMixed::String(result.platform_package.clone()),
+ PhpMixed::String(result.version.clone()),
+ if let Some(link) = &result.link {
+ PhpMixed::String(format!(
+ "{} {} {} ({})",
+ link.get_source(),
+ link.get_description(),
+ link.get_target(),
+ link.get_pretty_constraint().unwrap_or(""),
+ ))
+ } else {
+ PhpMixed::String(String::new())
+ },
+ PhpMixed::String(
+ format!("{} {}", result.status, result.provider)
+ .trim_end()
+ .to_string(),
+ ),
+ ]
+ })
+ .collect();
self.inner.render_table(rows, output);
}
diff --git a/crates/shirabe/src/command/clear_cache_command.rs b/crates/shirabe/src/command/clear_cache_command.rs
index fe2c4dd..06026a4 100644
--- a/crates/shirabe/src/command/clear_cache_command.rs
+++ b/crates/shirabe/src/command/clear_cache_command.rs
@@ -1,12 +1,12 @@
//! ref: composer/src/Composer/Command/ClearCacheCommand.php
-use indexmap::IndexMap;
-use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
-use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
use crate::cache::Cache;
use crate::command::base_command::BaseCommand;
use crate::console::input::input_option::InputOption;
use crate::factory::Factory;
+use indexmap::IndexMap;
+use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
+use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
#[derive(Debug)]
pub struct ClearCacheCommand {
@@ -19,22 +19,24 @@ impl ClearCacheCommand {
.set_name("clear-cache")
.set_aliases(vec!["clearcache".to_string(), "cc".to_string()])
.set_description("Clears composer's internal package cache")
- .set_definition(vec![
- InputOption::new(
- "gc",
- None,
- InputOption::VALUE_NONE,
- "Only run garbage collection, not a full cache clear",
- ),
- ])
+ .set_definition(vec![InputOption::new(
+ "gc",
+ None,
+ InputOption::VALUE_NONE,
+ "Only run garbage collection, not a full cache clear",
+ )])
.set_help(
"The <info>clear-cache</info> deletes all cached packages from composer's\n\
cache directory.\n\n\
- Read more at https://getcomposer.org/doc/03-cli.md#clear-cache-clearcache-cc"
+ Read more at https://getcomposer.org/doc/03-cli.md#clear-cache-clearcache-cc",
);
}
- pub fn execute(&self, input: &dyn InputInterface, _output: &dyn OutputInterface) -> anyhow::Result<i64> {
+ pub fn execute(
+ &self,
+ input: &dyn InputInterface,
+ _output: &dyn OutputInterface,
+ ) -> anyhow::Result<i64> {
let composer = self.inner.try_composer();
let config = if let Some(composer) = composer {
composer.get_config()
@@ -45,9 +47,18 @@ impl ClearCacheCommand {
let io = self.inner.get_io();
let mut cache_paths: IndexMap<String, String> = IndexMap::new();
- cache_paths.insert("cache-vcs-dir".to_string(), config.get("cache-vcs-dir").to_string());
- cache_paths.insert("cache-repo-dir".to_string(), config.get("cache-repo-dir").to_string());
- cache_paths.insert("cache-files-dir".to_string(), config.get("cache-files-dir").to_string());
+ cache_paths.insert(
+ "cache-vcs-dir".to_string(),
+ config.get("cache-vcs-dir").to_string(),
+ );
+ cache_paths.insert(
+ "cache-repo-dir".to_string(),
+ config.get("cache-repo-dir").to_string(),
+ );
+ cache_paths.insert(
+ "cache-files-dir".to_string(),
+ config.get("cache-files-dir").to_string(),
+ );
cache_paths.insert("cache-dir".to_string(), config.get("cache-dir").to_string());
for (key, cache_path) in &cache_paths {
@@ -59,28 +70,39 @@ impl ClearCacheCommand {
let cache_path = shirabe_php_shim::realpath(cache_path);
if !cache_path.as_ref().map(|s| !s.is_empty()).unwrap_or(false) {
let cache_path_display = cache_path.as_deref().unwrap_or("");
- io.write_error(&format!("<info>Cache directory does not exist ({key}): {cache_path_display}</info>"));
+ io.write_error(&format!(
+ "<info>Cache directory does not exist ({key}): {cache_path_display}</info>"
+ ));
continue;
}
let cache_path = cache_path.unwrap();
let mut cache = Cache::new(io, &cache_path);
cache.set_read_only(config.get("cache-read-only").as_bool().unwrap_or(false));
if !cache.is_enabled() {
- io.write_error(&format!("<info>Cache is not enabled ({key}): {cache_path}</info>"));
+ io.write_error(&format!(
+ "<info>Cache is not enabled ({key}): {cache_path}</info>"
+ ));
continue;
}
if input.get_option("gc").as_bool() {
- io.write_error(&format!("<info>Garbage-collecting cache ({key}): {cache_path}</info>"));
+ io.write_error(&format!(
+ "<info>Garbage-collecting cache ({key}): {cache_path}</info>"
+ ));
if key == "cache-files-dir" {
- cache.gc(config.get("cache-files-ttl"), config.get("cache-files-maxsize"))?;
+ cache.gc(
+ config.get("cache-files-ttl"),
+ config.get("cache-files-maxsize"),
+ )?;
} else if key == "cache-repo-dir" {
cache.gc(config.get("cache-ttl"), 1024 * 1024 * 1024)?;
} else if key == "cache-vcs-dir" {
cache.gc_vcs_cache(config.get("cache-ttl"))?;
}
} else {
- io.write_error(&format!("<info>Clearing cache ({key}): {cache_path}</info>"));
+ io.write_error(&format!(
+ "<info>Clearing cache ({key}): {cache_path}</info>"
+ ));
cache.clear()?;
}
}
diff --git a/crates/shirabe/src/command/completion_trait.rs b/crates/shirabe/src/command/completion_trait.rs
index 2594407..8278603 100644
--- a/crates/shirabe/src/command/completion_trait.rs
+++ b/crates/shirabe/src/command/completion_trait.rs
@@ -1,8 +1,5 @@
//! ref: composer/src/Composer/Command/CompletionTrait.php
-use shirabe_external_packages::composer::pcre::preg::Preg;
-use shirabe_external_packages::symfony::component::console::completion::completion_input::CompletionInput;
-use shirabe_php_shim::preg_quote;
use crate::composer::Composer;
use crate::package::base_package::BasePackage;
use crate::package::package_interface::PackageInterface;
@@ -11,9 +8,16 @@ use crate::repository::installed_repository::InstalledRepository;
use crate::repository::platform_repository::PlatformRepository;
use crate::repository::repository_interface::RepositoryInterface;
use crate::repository::root_package_repository::RootPackageRepository;
+use shirabe_external_packages::composer::pcre::preg::Preg;
+use shirabe_external_packages::symfony::component::console::completion::completion_input::CompletionInput;
+use shirabe_php_shim::preg_quote;
pub trait CompletionTrait {
- fn require_composer(&self, disable_plugins: Option<bool>, disable_scripts: Option<bool>) -> Composer;
+ fn require_composer(
+ &self,
+ disable_plugins: Option<bool>,
+ disable_scripts: Option<bool>,
+ ) -> Composer;
fn suggest_prefer_install(&self) -> Vec<String> {
vec!["dist".to_string(), "source".to_string(), "auto".to_string()]
@@ -23,26 +27,46 @@ pub trait CompletionTrait {
Box::new(move |_input: &CompletionInput| -> Vec<String> {
let composer = self.require_composer(None, None);
- let requires: Vec<String> = composer.get_package().get_requires().keys().cloned().collect();
- let dev_requires: Vec<String> = composer.get_package().get_dev_requires().keys().cloned().collect();
+ let requires: Vec<String> = composer
+ .get_package()
+ .get_requires()
+ .keys()
+ .cloned()
+ .collect();
+ let dev_requires: Vec<String> = composer
+ .get_package()
+ .get_dev_requires()
+ .keys()
+ .cloned()
+ .collect();
[requires, dev_requires].concat()
})
}
- fn suggest_installed_package(&self, include_root_package: bool, include_platform_packages: bool) -> Box<dyn Fn(&CompletionInput) -> Vec<String> + '_> {
+ fn suggest_installed_package(
+ &self,
+ include_root_package: bool,
+ include_platform_packages: bool,
+ ) -> Box<dyn Fn(&CompletionInput) -> Vec<String> + '_> {
Box::new(move |input: &CompletionInput| -> Vec<String> {
let composer = self.require_composer(None, None);
- let mut installed_repos: Vec<Box<dyn crate::repository::repository_interface::RepositoryInterface>> = Vec::new();
+ let mut installed_repos: Vec<
+ Box<dyn crate::repository::repository_interface::RepositoryInterface>,
+ > = Vec::new();
if include_root_package {
- installed_repos.push(Box::new(RootPackageRepository::new(composer.get_package().clone())));
+ installed_repos.push(Box::new(RootPackageRepository::new(
+ composer.get_package().clone(),
+ )));
}
let locker = composer.get_locker();
if locker.is_locked() {
installed_repos.push(Box::new(locker.get_locked_repository(true)));
} else {
- installed_repos.push(Box::new(composer.get_repository_manager().get_local_repository()));
+ installed_repos.push(Box::new(
+ composer.get_repository_manager().get_local_repository(),
+ ));
}
let mut platform_hint: Vec<String> = Vec::new();
@@ -54,7 +78,8 @@ pub trait CompletionTrait {
};
if input.get_completion_value() == "" {
// to reduce noise, when no text is yet entered we list only two entries for ext- and lib- prefixes
- let mut hints_to_find: indexmap::IndexMap<String, i64> = indexmap::IndexMap::new();
+ let mut hints_to_find: indexmap::IndexMap<String, i64> =
+ indexmap::IndexMap::new();
hints_to_find.insert("ext-".to_string(), 0);
hints_to_find.insert("lib-".to_string(), 0);
hints_to_find.insert("php".to_string(), 99);
@@ -70,7 +95,11 @@ pub trait CompletionTrait {
hints_to_find.remove(hint_prefix);
platform_hint.push(format!(
"{}...",
- &pkg.get_name()[..pkg.get_name().len().saturating_sub(3).max(hint_prefix.len() + 1)]
+ &pkg.get_name()[..pkg
+ .get_name()
+ .len()
+ .saturating_sub(3)
+ .max(hint_prefix.len() + 1)]
));
}
continue 'pkg_loop;
@@ -84,7 +113,9 @@ pub trait CompletionTrait {
let installed_repo = InstalledRepository::new(installed_repos);
- let mut result: Vec<String> = installed_repo.get_packages().iter()
+ let mut result: Vec<String> = installed_repo
+ .get_packages()
+ .iter()
.map(|package| package.get_name().to_string())
.collect();
result.extend(platform_hint);
@@ -92,25 +123,36 @@ pub trait CompletionTrait {
})
}
- fn suggest_installed_package_types(&self, include_root_package: bool) -> Box<dyn Fn(&CompletionInput) -> Vec<String> + '_> {
+ fn suggest_installed_package_types(
+ &self,
+ include_root_package: bool,
+ ) -> Box<dyn Fn(&CompletionInput) -> Vec<String> + '_> {
Box::new(move |_input: &CompletionInput| -> Vec<String> {
let composer = self.require_composer(None, None);
- let mut installed_repos: Vec<Box<dyn crate::repository::repository_interface::RepositoryInterface>> = Vec::new();
+ let mut installed_repos: Vec<
+ Box<dyn crate::repository::repository_interface::RepositoryInterface>,
+ > = Vec::new();
if include_root_package {
- installed_repos.push(Box::new(RootPackageRepository::new(composer.get_package().clone())));
+ installed_repos.push(Box::new(RootPackageRepository::new(
+ composer.get_package().clone(),
+ )));
}
let locker = composer.get_locker();
if locker.is_locked() {
installed_repos.push(Box::new(locker.get_locked_repository(true)));
} else {
- installed_repos.push(Box::new(composer.get_repository_manager().get_local_repository()));
+ installed_repos.push(Box::new(
+ composer.get_repository_manager().get_local_repository(),
+ ));
}
let installed_repo = InstalledRepository::new(installed_repos);
- let mut types: Vec<String> = installed_repo.get_packages().iter()
+ let mut types: Vec<String> = installed_repo
+ .get_packages()
+ .iter()
.map(|package| package.get_type().to_string())
.collect();
types.sort();
@@ -119,14 +161,18 @@ pub trait CompletionTrait {
})
}
- fn suggest_available_package(&self, max: i64) -> Box<dyn Fn(&CompletionInput) -> Vec<String> + '_> {
+ fn suggest_available_package(
+ &self,
+ max: i64,
+ ) -> Box<dyn Fn(&CompletionInput) -> Vec<String> + '_> {
Box::new(move |input: &CompletionInput| -> Vec<String> {
if max < 1 {
return Vec::new();
}
let composer = self.require_composer(None, None);
- let repos = CompositeRepository::new(composer.get_repository_manager().get_repositories());
+ let repos =
+ CompositeRepository::new(composer.get_repository_manager().get_repositories());
let mut results: Vec<String>;
let mut show_vendors = false;
@@ -154,7 +200,8 @@ pub trait CompletionTrait {
}
if show_vendors {
- let mut results: Vec<String> = results.into_iter()
+ let mut results: Vec<String> = results
+ .into_iter()
.map(|name| format!("{}/", name))
.collect();
@@ -188,13 +235,16 @@ pub trait CompletionTrait {
})
}
- fn suggest_available_package_incl_platform(&self) -> Box<dyn Fn(&CompletionInput) -> Vec<String> + '_> {
+ fn suggest_available_package_incl_platform(
+ &self,
+ ) -> Box<dyn Fn(&CompletionInput) -> Vec<String> + '_> {
Box::new(move |input: &CompletionInput| -> Vec<String> {
- let matches = if Preg::is_match(r"{^(ext|lib|php)(-|$)|^com}", input.get_completion_value()) {
- self.suggest_platform_package()(input)
- } else {
- Vec::new()
- };
+ let matches =
+ if Preg::is_match(r"{^(ext|lib|php)(-|$)|^com}", input.get_completion_value()) {
+ self.suggest_platform_package()(input)
+ } else {
+ Vec::new()
+ };
let max = 99i64 - matches.len() as i64;
let mut result = matches;
@@ -207,12 +257,17 @@ pub trait CompletionTrait {
Box::new(move |input: &CompletionInput| -> Vec<String> {
let repos = PlatformRepository::new(
vec![],
- self.require_composer(None, None).get_config().get("platform"),
+ self.require_composer(None, None)
+ .get_config()
+ .get("platform"),
);
- let pattern = BasePackage::package_name_to_regexp(&format!("{}*", input.get_completion_value()));
+ let pattern =
+ BasePackage::package_name_to_regexp(&format!("{}*", input.get_completion_value()));
- repos.get_packages().iter()
+ repos
+ .get_packages()
+ .iter()
.map(|package| package.get_name().to_string())
.filter(|name| Preg::is_match(&pattern, name))
.collect()
diff --git a/crates/shirabe/src/command/config_command.rs b/crates/shirabe/src/command/config_command.rs
index 3924002..5237b62 100644
--- a/crates/shirabe/src/command/config_command.rs
+++ b/crates/shirabe/src/command/config_command.rs
@@ -8,19 +8,18 @@ use shirabe_external_packages::symfony::component::console::input::input_interfa
use shirabe_external_packages::symfony::component::console::input::input_option::InputOption;
use shirabe_external_packages::symfony::component::console::output::output_interface::OutputInterface;
use shirabe_php_shim::{
- array_filter, array_filter_use_key, array_is_list, array_map, array_merge, array_unique,
- call_user_func, count, escapeshellcmd, exec, explode, file_exists, file_get_contents, implode,
- in_array, is_array, is_bool, is_dir, is_numeric, is_object, is_string, json_encode, key, sort,
- sprintf, str_replace, str_starts_with, strpos, strtolower, system, touch, var_export,
- InvalidArgumentException, JsonObject, PhpMixed, RuntimeException,
- ArrayObject,
- JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE,
+ ArrayObject, InvalidArgumentException, JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE,
+ JsonObject, PhpMixed, RuntimeException, array_filter, array_filter_use_key, array_is_list,
+ array_map, array_merge, array_unique, call_user_func, count, escapeshellcmd, exec, explode,
+ file_exists, file_get_contents, implode, in_array, is_array, is_bool, is_dir, is_numeric,
+ is_object, is_string, json_encode, key, sort, sprintf, str_replace, str_starts_with, strpos,
+ strtolower, system, touch, var_export,
};
use crate::advisory::auditor::Auditor;
use crate::command::base_config_command::BaseConfigCommand;
-use crate::config::json_config_source::JsonConfigSource;
use crate::config::Config;
+use crate::config::json_config_source::JsonConfigSource;
use crate::console::input::input_argument::InputArgument;
use crate::factory::Factory;
use crate::io::io_interface::IOInterface;
@@ -120,23 +119,50 @@ impl ConfigCommand {
) -> anyhow::Result<()> {
self.inner.initialize(input, output)?;
- let auth_config_file = self.inner.get_auth_config_file(input, self.inner.config.as_ref().unwrap());
+ let auth_config_file = self
+ .inner
+ .get_auth_config_file(input, self.inner.config.as_ref().unwrap());
- self.auth_config_file = Some(JsonFile::new(auth_config_file, None, Some(self.inner.inner.get_io())));
- self.auth_config_source = Some(JsonConfigSource::new_with_auth(self.auth_config_file.as_ref().unwrap(), true));
+ self.auth_config_file = Some(JsonFile::new(
+ auth_config_file,
+ None,
+ Some(self.inner.inner.get_io()),
+ ));
+ self.auth_config_source = Some(JsonConfigSource::new_with_auth(
+ self.auth_config_file.as_ref().unwrap(),
+ true,
+ ));
// Initialize the global file if it's not there, ignoring any warnings or notices
- if input.get_option("global").as_bool() == Some(true) && !self.auth_config_file.as_ref().unwrap().exists() {
+ if input.get_option("global").as_bool() == Some(true)
+ && !self.auth_config_file.as_ref().unwrap().exists()
+ {
touch(self.auth_config_file.as_ref().unwrap().get_path());
let mut empty_objs: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
for k in &[
- "bitbucket-oauth", "github-oauth", "gitlab-oauth", "gitlab-token",
- "http-basic", "bearer", "forgejo-token",
+ "bitbucket-oauth",
+ "github-oauth",
+ "gitlab-oauth",
+ "gitlab-token",
+ "http-basic",
+ "bearer",
+ "forgejo-token",
] {
- empty_objs.insert(k.to_string(), Box::new(PhpMixed::Object(ArrayObject::new())));
+ empty_objs.insert(
+ k.to_string(),
+ Box::new(PhpMixed::Object(ArrayObject::new())),
+ );
}
- self.auth_config_file.as_mut().unwrap().write(PhpMixed::Array(empty_objs))?;
- let path_clone = self.auth_config_file.as_ref().unwrap().get_path().to_string();
+ self.auth_config_file
+ .as_mut()
+ .unwrap()
+ .write(PhpMixed::Array(empty_objs))?;
+ let path_clone = self
+ .auth_config_file
+ .as_ref()
+ .unwrap()
+ .get_path()
+ .to_string();
Silencer::call(|| {
shirabe_php_shim::chmod(&path_clone, 0o600);
Ok(())
@@ -169,15 +195,28 @@ impl ConfigCommand {
}
let file = if input.get_option("auth").as_bool() == Some(true) {
- self.auth_config_file.as_ref().unwrap().get_path().to_string()
+ self.auth_config_file
+ .as_ref()
+ .unwrap()
+ .get_path()
+ .to_string()
} else {
- self.inner.config_file.as_ref().unwrap().get_path().to_string()
+ self.inner
+ .config_file
+ .as_ref()
+ .unwrap()
+ .get_path()
+ .to_string()
};
system(&format!(
"{} {}{}",
editor.unwrap_or_default(),
file,
- if Platform::is_windows() { "" } else { " > `tty`" }
+ if Platform::is_windows() {
+ ""
+ } else {
+ " > `tty`"
+ }
));
return Ok(0);
@@ -201,7 +240,10 @@ impl ConfigCommand {
);
}
- self.inner.inner.get_io().load_configuration(self.inner.config.as_ref().unwrap());
+ self.inner
+ .inner
+ .get_io()
+ .load_configuration(self.inner.config.as_ref().unwrap());
// List the configuration of the file settings
if input.get_option("list").as_bool() == Some(true) {
@@ -226,7 +268,11 @@ impl ConfigCommand {
let setting_values_raw = input.get_argument("setting-value");
let setting_values: Vec<String> = setting_values_raw
.as_list()
- .map(|l| l.iter().filter_map(|v| v.as_string().map(|s| s.to_string())).collect())
+ .map(|l| {
+ l.iter()
+ .filter_map(|v| v.as_string().map(|s| s.to_string()))
+ .collect()
+ })
.unwrap_or_default();
if !setting_values.is_empty() && input.get_option("unset").as_bool() == Some(true) {
return Err(RuntimeException {
@@ -243,7 +289,10 @@ impl ConfigCommand {
properties_defaults.insert("type".to_string(), PhpMixed::String("library".to_string()));
properties_defaults.insert("description".to_string(), PhpMixed::String(String::new()));
properties_defaults.insert("homepage".to_string(), PhpMixed::String(String::new()));
- properties_defaults.insert("minimum-stability".to_string(), PhpMixed::String("stable".to_string()));
+ properties_defaults.insert(
+ "minimum-stability".to_string(),
+ PhpMixed::String("stable".to_string()),
+ );
properties_defaults.insert("prefer-stable".to_string(), PhpMixed::Bool(false));
properties_defaults.insert("keywords".to_string(), PhpMixed::List(vec![]));
properties_defaults.insert("license".to_string(), PhpMixed::List(vec![]));
@@ -251,22 +300,46 @@ impl ConfigCommand {
properties_defaults.insert("extra".to_string(), PhpMixed::List(vec![]));
let raw_data = self.inner.config_file.as_ref().unwrap().read()?;
let mut data = self.inner.config.as_ref().unwrap().all();
- let mut source = self.inner.config.as_ref().unwrap().get_source_of_value(&setting_key);
+ let mut source = self
+ .inner
+ .config
+ .as_ref()
+ .unwrap()
+ .get_source_of_value(&setting_key);
let mut value: PhpMixed;
let mut matches: Vec<String> = vec![];
- if Preg::is_match("/^repos?(?:itories)?(?:\\.(.+))?/", &setting_key, Some(&mut matches)).unwrap_or(false) {
+ if Preg::is_match(
+ "/^repos?(?:itories)?(?:\\.(.+))?/",
+ &setting_key,
+ Some(&mut matches),
+ )
+ .unwrap_or(false)
+ {
if matches.get(1).is_none() {
- value = data.as_array().and_then(|a| a.get("repositories")).map(|v| (**v).clone()).unwrap_or_else(|| PhpMixed::Array(IndexMap::new()));
+ value = data
+ .as_array()
+ .and_then(|a| a.get("repositories"))
+ .map(|v| (**v).clone())
+ .unwrap_or_else(|| PhpMixed::Array(IndexMap::new()));
} else {
let repo_key = matches[1].clone();
- let repos = data.as_array().and_then(|a| a.get("repositories")).map(|v| (**v).clone());
- value = match repos.as_ref().and_then(|r| r.as_array().and_then(|a| a.get(&repo_key))) {
+ let repos = data
+ .as_array()
+ .and_then(|a| a.get("repositories"))
+ .map(|v| (**v).clone());
+ value = match repos
+ .as_ref()
+ .and_then(|r| r.as_array().and_then(|a| a.get(&repo_key)))
+ {
Some(v) => (**v).clone(),
- None => return Err(InvalidArgumentException {
- message: format!("There is no {} repository defined", repo_key),
- code: 0,
- }.into()),
+ None => {
+ return Err(InvalidArgumentException {
+ message: format!("There is no {} repository defined", repo_key),
+ code: 0,
+ }
+ .into());
+ }
};
}
} else if strpos(&setting_key, ".").is_some() {
@@ -274,7 +347,11 @@ impl ConfigCommand {
if bits[0] == "extra" || bits[0] == "suggest" {
data = raw_data.clone();
} else {
- data = data.as_array().and_then(|a| a.get("config")).map(|v| (**v).clone()).unwrap_or(PhpMixed::Null);
+ data = data
+ .as_array()
+ .and_then(|a| a.get("config"))
+ .map(|v| (**v).clone())
+ .unwrap_or(PhpMixed::Null);
}
let mut r#match = false;
let mut key_acc: Option<String> = None;
@@ -303,10 +380,20 @@ impl ConfigCommand {
}
value = data;
- } else if data.as_array().and_then(|a| a.get("config")).and_then(|c| c.as_array()).map(|c| c.contains_key(&setting_key)).unwrap_or(false) {
+ } else if data
+ .as_array()
+ .and_then(|a| a.get("config"))
+ .and_then(|c| c.as_array())
+ .map(|c| c.contains_key(&setting_key))
+ .unwrap_or(false)
+ {
value = self.inner.config.as_ref().unwrap().get_with_flags(
&setting_key,
- if input.get_option("absolute").as_bool() == Some(true) { 0 } else { Config::RELATIVE_PATHS },
+ if input.get_option("absolute").as_bool() == Some(true) {
+ 0
+ } else {
+ Config::RELATIVE_PATHS
+ },
);
// ensure we get {} output for properties which are objects
if value.as_array().map(|a| a.is_empty()).unwrap_or(false) {
@@ -335,7 +422,11 @@ impl ConfigCommand {
"object",
&type_array
.as_list()
- .map(|l| l.iter().filter_map(|v| v.as_string().map(|s| s.to_string())).collect::<Vec<_>>())
+ .map(|l| {
+ l.iter()
+ .filter_map(|v| v.as_string().map(|s| s.to_string()))
+ .collect::<Vec<_>>()
+ })
.unwrap_or_default(),
true,
) {
@@ -343,11 +434,20 @@ impl ConfigCommand {
}
}
}
- } else if raw_data.as_array().and_then(|a| a.get(&setting_key)).is_some()
+ } else if raw_data
+ .as_array()
+ .and_then(|a| a.get(&setting_key))
+ .is_some()
&& in_array(setting_key.as_str(), &properties, true)
{
value = (**raw_data.as_array().unwrap().get(&setting_key).unwrap()).clone();
- source = self.inner.config_file.as_ref().unwrap().get_path().to_string();
+ source = self
+ .inner
+ .config_file
+ .as_ref()
+ .unwrap()
+ .get_path()
+ .to_string();
} else if let Some(v) = properties_defaults.get(&setting_key) {
value = v.clone();
source = "defaults".to_string();
@@ -384,7 +484,12 @@ impl ConfigCommand {
let boolean_validator = |val: &PhpMixed| -> bool {
in_array(
val.as_string().unwrap_or(""),
- &vec!["true".to_string(), "false".to_string(), "1".to_string(), "0".to_string()],
+ &vec![
+ "true".to_string(),
+ "false".to_string(),
+ "1".to_string(),
+ "0".to_string(),
+ ],
true,
)
};
@@ -399,19 +504,39 @@ impl ConfigCommand {
// allow unsetting audit config entirely
if input.get_option("unset").as_bool() == Some(true) && setting_key == "audit" {
- self.inner.config_source.as_mut().unwrap().remove_config_setting(&setting_key);
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .remove_config_setting(&setting_key);
return Ok(0);
}
if input.get_option("unset").as_bool() == Some(true)
- && (unique_config_values.contains_key(&setting_key) || multi_config_values.contains_key(&setting_key))
+ && (unique_config_values.contains_key(&setting_key)
+ || multi_config_values.contains_key(&setting_key))
{
- if setting_key == "disable-tls" && self.inner.config.as_ref().unwrap().get("disable-tls").as_bool().unwrap_or(false) {
- self.inner.inner.get_io().write_error("<info>You are now running Composer with SSL/TLS protection enabled.</info>");
+ if setting_key == "disable-tls"
+ && self
+ .inner
+ .config
+ .as_ref()
+ .unwrap()
+ .get("disable-tls")
+ .as_bool()
+ .unwrap_or(false)
+ {
+ self.inner.inner.get_io().write_error(
+ "<info>You are now running Composer with SSL/TLS protection enabled.</info>",
+ );
}
- self.inner.config_source.as_mut().unwrap().remove_config_setting(&setting_key);
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .remove_config_setting(&setting_key);
return Ok(0);
}
@@ -427,42 +552,69 @@ impl ConfigCommand {
}
// handle preferred-install per-package config
let mut matches: Vec<String> = vec![];
- if Preg::is_match("/^preferred-install\\.(.+)/", &setting_key, Some(&mut matches)).unwrap_or(false) {
+ if Preg::is_match(
+ "/^preferred-install\\.(.+)/",
+ &setting_key,
+ Some(&mut matches),
+ )
+ .unwrap_or(false)
+ {
if input.get_option("unset").as_bool() == Some(true) {
- self.inner.config_source.as_mut().unwrap().remove_config_setting(&setting_key);
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .remove_config_setting(&setting_key);
return Ok(0);
}
let validator = &unique_config_values.get("preferred-install").unwrap().0;
- if !validator(&PhpMixed::String(values[0].clone())).as_bool().unwrap_or(false) {
+ if !validator(&PhpMixed::String(values[0].clone()))
+ .as_bool()
+ .unwrap_or(false)
+ {
return Err(RuntimeException {
- message: format!("Invalid value for {}. Should be one of: auto, source, or dist", setting_key),
+ message: format!(
+ "Invalid value for {}. Should be one of: auto, source, or dist",
+ setting_key
+ ),
code: 0,
}
.into());
}
- self.inner.config_source.as_mut().unwrap().add_config_setting(&setting_key, PhpMixed::String(values[0].clone()));
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .add_config_setting(&setting_key, PhpMixed::String(values[0].clone()));
return Ok(0);
}
// handle allow-plugins config setting elements true or false to add/remove
let mut matches: Vec<String> = vec![];
- if Preg::is_match("{^allow-plugins\\.([a-zA-Z0-9/*-]+)}", &setting_key, Some(&mut matches)).unwrap_or(false) {
+ if Preg::is_match(
+ "{^allow-plugins\\.([a-zA-Z0-9/*-]+)}",
+ &setting_key,
+ Some(&mut matches),
+ )
+ .unwrap_or(false)
+ {
if input.get_option("unset").as_bool() == Some(true) {
- self.inner.config_source.as_mut().unwrap().remove_config_setting(&setting_key);
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .remove_config_setting(&setting_key);
return Ok(0);
}
if !boolean_validator(&PhpMixed::String(values[0].clone())) {
return Err(RuntimeException {
- message: sprintf(
- "\"%s\" is an invalid value",
- &[values[0].clone().into()],
- ),
+ message: sprintf("\"%s\" is an invalid value", &[values[0].clone().into()]),
code: 0,
}
.into());
@@ -470,7 +622,11 @@ impl ConfigCommand {
let normalized_value = boolean_normalizer(&PhpMixed::String(values[0].clone()));
- self.inner.config_source.as_mut().unwrap().add_config_setting(&setting_key, normalized_value);
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .add_config_setting(&setting_key, normalized_value);
return Ok(0);
}
@@ -493,7 +649,11 @@ impl ConfigCommand {
if input.get_option("unset").as_bool() == Some(true)
&& (unique_props.contains_key(&setting_key) || multi_props.contains_key(&setting_key))
{
- self.inner.config_source.as_mut().unwrap().remove_property(&setting_key);
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .remove_property(&setting_key);
return Ok(0);
}
@@ -510,17 +670,33 @@ impl ConfigCommand {
// handle repositories
let mut matches: Vec<String> = vec![];
- if Preg::is_match_strict_groups("/^repos?(?:itories)?\\.(.+)/", &setting_key, Some(&mut matches)).unwrap_or(false) {
+ if Preg::is_match_strict_groups(
+ "/^repos?(?:itories)?\\.(.+)/",
+ &setting_key,
+ Some(&mut matches),
+ )
+ .unwrap_or(false)
+ {
if input.get_option("unset").as_bool() == Some(true) {
- self.inner.config_source.as_mut().unwrap().remove_repository(&matches[1]);
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .remove_repository(&matches[1]);
return Ok(0);
}
if 2 == count(&values) {
let mut repo: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
- repo.insert("type".to_string(), Box::new(PhpMixed::String(values[0].clone())));
- repo.insert("url".to_string(), Box::new(PhpMixed::String(values[1].clone())));
+ repo.insert(
+ "type".to_string(),
+ Box::new(PhpMixed::String(values[0].clone())),
+ );
+ repo.insert(
+ "url".to_string(),
+ Box::new(PhpMixed::String(values[1].clone())),
+ );
self.inner.config_source.as_mut().unwrap().add_repository(
&matches[1],
PhpMixed::Array(repo),
@@ -533,7 +709,10 @@ impl ConfigCommand {
if 1 == count(&values) {
let value = strtolower(&values[0]);
if boolean_validator(&PhpMixed::String(value.clone())) {
- if !boolean_normalizer(&PhpMixed::String(value.clone())).as_bool().unwrap_or(false) {
+ if !boolean_normalizer(&PhpMixed::String(value.clone()))
+ .as_bool()
+ .unwrap_or(false)
+ {
self.inner.config_source.as_mut().unwrap().add_repository(
&matches[1],
PhpMixed::Bool(false),
@@ -565,7 +744,11 @@ impl ConfigCommand {
let mut matches: Vec<String> = vec![];
if Preg::is_match("/^extra\\.(.+)/", &setting_key, Some(&mut matches)).unwrap_or(false) {
if input.get_option("unset").as_bool() == Some(true) {
- self.inner.config_source.as_mut().unwrap().remove_property(&setting_key);
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .remove_property(&setting_key);
return Ok(0);
}
@@ -592,7 +775,8 @@ impl ConfigCommand {
));
} else {
// PHP "+" operator on arrays: keep keys from left, fill from right
- let mut merged: IndexMap<String, Box<PhpMixed>> = value.as_array().cloned().unwrap_or_default();
+ let mut merged: IndexMap<String, Box<PhpMixed>> =
+ value.as_array().cloned().unwrap_or_default();
if let Some(cv) = current_value.as_array() {
for (k, v) in cv {
if !merged.contains_key(k) {
@@ -605,7 +789,11 @@ impl ConfigCommand {
}
}
}
- self.inner.config_source.as_mut().unwrap().add_property(&setting_key, value);
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .add_property(&setting_key, value);
return Ok(0);
}
@@ -614,7 +802,11 @@ impl ConfigCommand {
let mut matches: Vec<String> = vec![];
if Preg::is_match("/^suggest\\.(.+)/", &setting_key, Some(&mut matches)).unwrap_or(false) {
if input.get_option("unset").as_bool() == Some(true) {
- self.inner.config_source.as_mut().unwrap().remove_property(&setting_key);
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .remove_property(&setting_key);
return Ok(0);
}
@@ -629,10 +821,17 @@ impl ConfigCommand {
}
// handle unsetting extra/suggest
- if in_array(setting_key.as_str(), &vec!["suggest".to_string(), "extra".to_string()], true)
- && input.get_option("unset").as_bool() == Some(true)
+ if in_array(
+ setting_key.as_str(),
+ &vec!["suggest".to_string(), "extra".to_string()],
+ true,
+ ) && input.get_option("unset").as_bool() == Some(true)
{
- self.inner.config_source.as_mut().unwrap().remove_property(&setting_key);
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .remove_property(&setting_key);
return Ok(0);
}
@@ -641,7 +840,11 @@ impl ConfigCommand {
let mut matches: Vec<String> = vec![];
if Preg::is_match("/^platform\\.(.+)/", &setting_key, Some(&mut matches)).unwrap_or(false) {
if input.get_option("unset").as_bool() == Some(true) {
- self.inner.config_source.as_mut().unwrap().remove_config_setting(&setting_key);
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .remove_config_setting(&setting_key);
return Ok(0);
}
@@ -651,14 +854,22 @@ impl ConfigCommand {
} else {
PhpMixed::String(values[0].clone())
};
- self.inner.config_source.as_mut().unwrap().add_config_setting(&setting_key, value);
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .add_config_setting(&setting_key, value);
return Ok(0);
}
// handle unsetting platform
if setting_key == "platform" && input.get_option("unset").as_bool() == Some(true) {
- self.inner.config_source.as_mut().unwrap().remove_config_setting(&setting_key);
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .remove_config_setting(&setting_key);
return Ok(0);
}
@@ -666,16 +877,28 @@ impl ConfigCommand {
// handle audit.ignore and audit.ignore-abandoned with --merge support
if in_array(
setting_key.as_str(),
- &vec!["audit.ignore".to_string(), "audit.ignore-abandoned".to_string()],
+ &vec![
+ "audit.ignore".to_string(),
+ "audit.ignore-abandoned".to_string(),
+ ],
true,
) {
if input.get_option("unset").as_bool() == Some(true) {
- self.inner.config_source.as_mut().unwrap().remove_config_setting(&setting_key);
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .remove_config_setting(&setting_key);
return Ok(0);
}
- let mut value: PhpMixed = PhpMixed::List(values.iter().map(|s| Box::new(PhpMixed::String(s.clone()))).collect());
+ let mut value: PhpMixed = PhpMixed::List(
+ values
+ .iter()
+ .map(|s| Box::new(PhpMixed::String(s.clone())))
+ .collect(),
+ );
if input.get_option("json").as_bool() == Some(true) {
value = JsonFile::parse_json(&values[0], "composer.json")?;
if !is_array(&value) {
@@ -709,7 +932,8 @@ impl ConfigCommand {
));
} else if !array_is_list(&current_value) && !array_is_list(&value) {
// Both are associative arrays (objects), merge them
- let mut merged: IndexMap<String, Box<PhpMixed>> = value.as_array().cloned().unwrap_or_default();
+ let mut merged: IndexMap<String, Box<PhpMixed>> =
+ value.as_array().cloned().unwrap_or_default();
if let Some(cv) = current_value.as_array() {
for (k, v) in cv {
if !merged.contains_key(k) {
@@ -728,7 +952,11 @@ impl ConfigCommand {
}
}
- self.inner.config_source.as_mut().unwrap().add_config_setting(&setting_key, value);
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .add_config_setting(&setting_key, value);
return Ok(0);
}
@@ -851,30 +1079,50 @@ impl ConfigCommand {
let mut matches: Vec<String> = vec![];
if Preg::is_match("/^scripts\\.(.+)/", &setting_key, Some(&mut matches)).unwrap_or(false) {
if input.get_option("unset").as_bool() == Some(true) {
- self.inner.config_source.as_mut().unwrap().remove_property(&setting_key);
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .remove_property(&setting_key);
return Ok(0);
}
let value: PhpMixed = if count(&values) > 1 {
- PhpMixed::List(values.iter().map(|s| Box::new(PhpMixed::String(s.clone()))).collect())
+ PhpMixed::List(
+ values
+ .iter()
+ .map(|s| Box::new(PhpMixed::String(s.clone())))
+ .collect(),
+ )
} else {
PhpMixed::String(values[0].clone())
};
- self.inner.config_source.as_mut().unwrap().add_property(&setting_key, value);
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .add_property(&setting_key, value);
return Ok(0);
}
// handle unsetting other top level properties
if input.get_option("unset").as_bool() == Some(true) {
- self.inner.config_source.as_mut().unwrap().remove_property(&setting_key);
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .remove_property(&setting_key);
return Ok(0);
}
Err(InvalidArgumentException {
- message: format!("Setting {} does not exist or is not supported by this command", setting_key),
+ message: format!(
+ "Setting {} does not exist or is not supported by this command",
+ setting_key
+ ),
code: 0,
}
.into())
@@ -917,11 +1165,27 @@ impl ConfigCommand {
if key == "disable-tls" {
if !normalized_value.as_bool().unwrap_or(false)
- && self.inner.config.as_ref().unwrap().get("disable-tls").as_bool().unwrap_or(false)
+ && self
+ .inner
+ .config
+ .as_ref()
+ .unwrap()
+ .get("disable-tls")
+ .as_bool()
+ .unwrap_or(false)
{
- self.inner.inner.get_io().write_error("<info>You are now running Composer with SSL/TLS protection enabled.</info>");
+ self.inner.inner.get_io().write_error(
+ "<info>You are now running Composer with SSL/TLS protection enabled.</info>",
+ );
} else if normalized_value.as_bool().unwrap_or(false)
- && !self.inner.config.as_ref().unwrap().get("disable-tls").as_bool().unwrap_or(false)
+ && !self
+ .inner
+ .config
+ .as_ref()
+ .unwrap()
+ .get("disable-tls")
+ .as_bool()
+ .unwrap_or(false)
{
self.inner.inner.get_io().write_error("<warning>You are now running Composer with SSL/TLS protection disabled.</warning>");
}
@@ -943,7 +1207,12 @@ impl ConfigCommand {
method: &str,
) -> anyhow::Result<()> {
let (validator, normalizer) = callbacks;
- let values_mixed = PhpMixed::List(values.iter().map(|s| Box::new(PhpMixed::String(s.clone()))).collect());
+ let values_mixed = PhpMixed::List(
+ values
+ .iter()
+ .map(|s| Box::new(PhpMixed::String(s.clone())))
+ .collect(),
+ );
let validation = validator(&values_mixed);
if validation.as_bool() != Some(true) {
let suffix = if !validation.is_null() && validation.as_bool() != Some(false) {
@@ -984,15 +1253,20 @@ impl ConfigCommand {
let raw_contents_arr = raw_contents.as_array().cloned().unwrap_or_default();
let mut k = k;
for (key, value) in &contents_arr {
- if k.is_none() && !in_array(
- key.as_str(),
- &vec!["config".to_string(), "repositories".to_string()],
- true,
- ) {
+ if k.is_none()
+ && !in_array(
+ key.as_str(),
+ &vec!["config".to_string(), "repositories".to_string()],
+ true,
+ )
+ {
continue;
}
- let raw_val = raw_contents_arr.get(key).map(|v| (**v).clone()).unwrap_or(PhpMixed::Null);
+ let raw_val = raw_contents_arr
+ .get(key)
+ .map(|v| (**v).clone())
+ .unwrap_or(PhpMixed::Null);
let value_inner = (**value).clone();
@@ -1034,7 +1308,11 @@ impl ConfigCommand {
let source = if show_source {
format!(
" ({})",
- self.inner.config.as_ref().unwrap().get_source_of_value(&format!("{}{}", k.clone().unwrap_or_default(), key))
+ self.inner
+ .config
+ .as_ref()
+ .unwrap()
+ .get_source_of_value(&format!("{}{}", k.clone().unwrap_or_default(), key))
)
} else {
String::new()
@@ -1050,11 +1328,21 @@ impl ConfigCommand {
k.clone().unwrap()
};
let id = Preg::replace("{\\..*$}", "", &id_source);
- let id = Preg::replace("{[^a-z0-9]}i", "-", &strtolower(&shirabe_php_shim::trim(&id, " \t\n\r\0\u{0B}")));
+ let id = Preg::replace(
+ "{[^a-z0-9]}i",
+ "-",
+ &strtolower(&shirabe_php_shim::trim(&id, " \t\n\r\0\u{0B}")),
+ );
let id = Preg::replace("{-+}", "-", &id);
link = format!("https://getcomposer.org/doc/06-config.md#{}", id);
}
- if is_string(&raw_val) && raw_val.as_string().map(|s| s.to_string()).unwrap_or_default() != value_display {
+ if is_string(&raw_val)
+ && raw_val
+ .as_string()
+ .map(|s| s.to_string())
+ .unwrap_or_default()
+ != value_display
+ {
io.write(
&format!(
"[<fg=yellow;href={}>{}{}</>] <info>{} ({})</info>{}",
@@ -1103,16 +1391,24 @@ impl ConfigCommand {
// load configuration
// TODO: BaseConfigCommand::get_composer_config_file is an instance method; using a free helper here.
- let config_file = JsonFile::new(get_composer_config_file_static(input, &config), None, None);
+ let config_file =
+ JsonFile::new(get_composer_config_file_static(input, &config), None, None);
if config_file.exists() {
- config.merge(config_file.read().unwrap_or(PhpMixed::Null), config_file.get_path());
+ config.merge(
+ config_file.read().unwrap_or(PhpMixed::Null),
+ config_file.get_path(),
+ );
}
// load auth-configuration
- let auth_config_file = JsonFile::new(get_auth_config_file_static(input, &config), None, None);
+ let auth_config_file =
+ JsonFile::new(get_auth_config_file_static(input, &config), None, None);
if auth_config_file.exists() {
let mut wrap: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
- wrap.insert("config".to_string(), Box::new(auth_config_file.read().unwrap_or(PhpMixed::Null)));
+ wrap.insert(
+ "config".to_string(),
+ Box::new(auth_config_file.read().unwrap_or(PhpMixed::Null)),
+ );
config.merge(PhpMixed::Array(wrap), auth_config_file.get_path());
}
@@ -1120,20 +1416,38 @@ impl ConfigCommand {
let raw_config = config.raw();
let raw_arr = raw_config.as_array().cloned().unwrap_or_default();
let mut keys: Vec<String> = array_merge(
- flatten_setting_keys(raw_arr.get("config").map(|v| (**v).clone()).unwrap_or(PhpMixed::Null), ""),
- flatten_setting_keys(raw_arr.get("repositories").map(|v| (**v).clone()).unwrap_or(PhpMixed::Null), "repositories."),
+ flatten_setting_keys(
+ raw_arr
+ .get("config")
+ .map(|v| (**v).clone())
+ .unwrap_or(PhpMixed::Null),
+ "",
+ ),
+ flatten_setting_keys(
+ raw_arr
+ .get("repositories")
+ .map(|v| (**v).clone())
+ .unwrap_or(PhpMixed::Null),
+ "repositories.",
+ ),
);
// if unsetting …
if input.get_option("unset").as_bool() == Some(true) {
// … keep only the currently customized setting-keys …
- let sources = vec![config_file.get_path().to_string(), auth_config_file.get_path().to_string()];
+ let sources = vec![
+ config_file.get_path().to_string(),
+ auth_config_file.get_path().to_string(),
+ ];
keys = array_filter(keys, |k: &String| -> bool {
in_array(config.get_source_of_value(k).as_str(), &sources, true)
});
} else {
// … add all configurable package-properties, no matter if it exist
- let configurable: Vec<String> = ConfigCommand::CONFIGURABLE_PACKAGE_PROPERTIES.iter().map(|s| s.to_string()).collect();
+ let configurable: Vec<String> = ConfigCommand::CONFIGURABLE_PACKAGE_PROPERTIES
+ .iter()
+ .map(|s| s.to_string())
+ .collect();
keys = array_merge(keys, configurable);
// it would be nice to distinguish between showing and setting
@@ -1144,9 +1458,17 @@ impl ConfigCommand {
// add all existing configurable package-properties
if config_file.exists() {
- let configurable: Vec<String> = ConfigCommand::CONFIGURABLE_PACKAGE_PROPERTIES.iter().map(|s| s.to_string()).collect();
+ let configurable: Vec<String> = ConfigCommand::CONFIGURABLE_PACKAGE_PROPERTIES
+ .iter()
+ .map(|s| s.to_string())
+ .collect();
let properties = array_filter_use_key(
- config_file.read().unwrap_or(PhpMixed::Null).as_array().cloned().unwrap_or_default(),
+ config_file
+ .read()
+ .unwrap_or(PhpMixed::Null)
+ .as_array()
+ .cloned()
+ .unwrap_or_default(),
|key: &String| -> bool { in_array(key.as_str(), &configurable, true) },
);
@@ -1176,7 +1498,12 @@ pub type NormalizerFn = Box<dyn Fn(&PhpMixed) -> PhpMixed>;
fn boolean_validator(val: &PhpMixed) -> PhpMixed {
PhpMixed::Bool(in_array(
val.as_string().unwrap_or(""),
- &vec!["true".to_string(), "false".to_string(), "1".to_string(), "0".to_string()],
+ &vec![
+ "true".to_string(),
+ "false".to_string(),
+ "1".to_string(),
+ "0".to_string(),
+ ],
true,
))
}
@@ -1198,26 +1525,54 @@ fn build_unique_config_values() -> IndexMap<String, (ValidatorFn, NormalizerFn)>
Box::new(|val| PhpMixed::Int(shirabe_php_shim::intval(val.as_string().unwrap_or("0")))),
),
);
- m.insert("use-include-path".to_string(), (Box::new(boolean_validator), Box::new(boolean_normalizer)));
- m.insert("use-github-api".to_string(), (Box::new(boolean_validator), Box::new(boolean_normalizer)));
+ m.insert(
+ "use-include-path".to_string(),
+ (Box::new(boolean_validator), Box::new(boolean_normalizer)),
+ );
+ m.insert(
+ "use-github-api".to_string(),
+ (Box::new(boolean_validator), Box::new(boolean_normalizer)),
+ );
m.insert(
"preferred-install".to_string(),
(
- Box::new(|val| PhpMixed::Bool(in_array(val.as_string().unwrap_or(""), &vec!["auto".to_string(), "source".to_string(), "dist".to_string()], true))),
+ Box::new(|val| {
+ PhpMixed::Bool(in_array(
+ val.as_string().unwrap_or(""),
+ &vec!["auto".to_string(), "source".to_string(), "dist".to_string()],
+ true,
+ ))
+ }),
Box::new(|val| val.clone()),
),
);
m.insert(
"gitlab-protocol".to_string(),
(
- Box::new(|val| PhpMixed::Bool(in_array(val.as_string().unwrap_or(""), &vec!["git".to_string(), "http".to_string(), "https".to_string()], true))),
+ Box::new(|val| {
+ PhpMixed::Bool(in_array(
+ val.as_string().unwrap_or(""),
+ &vec!["git".to_string(), "http".to_string(), "https".to_string()],
+ true,
+ ))
+ }),
Box::new(|val| val.clone()),
),
);
m.insert(
"store-auths".to_string(),
(
- Box::new(|val| PhpMixed::Bool(in_array(val.as_string().unwrap_or(""), &vec!["true".to_string(), "false".to_string(), "prompt".to_string()], true))),
+ Box::new(|val| {
+ PhpMixed::Bool(in_array(
+ val.as_string().unwrap_or(""),
+ &vec![
+ "true".to_string(),
+ "false".to_string(),
+ "prompt".to_string(),
+ ],
+ true,
+ ))
+ }),
Box::new(|val| {
let s = val.as_string().unwrap_or("");
if s == "prompt" {
@@ -1228,16 +1583,73 @@ fn build_unique_config_values() -> IndexMap<String, (ValidatorFn, NormalizerFn)>
}),
),
);
- m.insert("notify-on-install".to_string(), (Box::new(boolean_validator), Box::new(boolean_normalizer)));
- m.insert("vendor-dir".to_string(), (Box::new(|val| PhpMixed::Bool(is_string(val))), Box::new(|val| val.clone())));
- m.insert("bin-dir".to_string(), (Box::new(|val| PhpMixed::Bool(is_string(val))), Box::new(|val| val.clone())));
- m.insert("archive-dir".to_string(), (Box::new(|val| PhpMixed::Bool(is_string(val))), Box::new(|val| val.clone())));
- m.insert("archive-format".to_string(), (Box::new(|val| PhpMixed::Bool(is_string(val))), Box::new(|val| val.clone())));
- m.insert("data-dir".to_string(), (Box::new(|val| PhpMixed::Bool(is_string(val))), Box::new(|val| val.clone())));
- m.insert("cache-dir".to_string(), (Box::new(|val| PhpMixed::Bool(is_string(val))), Box::new(|val| val.clone())));
- m.insert("cache-files-dir".to_string(), (Box::new(|val| PhpMixed::Bool(is_string(val))), Box::new(|val| val.clone())));
- m.insert("cache-repo-dir".to_string(), (Box::new(|val| PhpMixed::Bool(is_string(val))), Box::new(|val| val.clone())));
- m.insert("cache-vcs-dir".to_string(), (Box::new(|val| PhpMixed::Bool(is_string(val))), Box::new(|val| val.clone())));
+ m.insert(
+ "notify-on-install".to_string(),
+ (Box::new(boolean_validator), Box::new(boolean_normalizer)),
+ );
+ m.insert(
+ "vendor-dir".to_string(),
+ (
+ Box::new(|val| PhpMixed::Bool(is_string(val))),
+ Box::new(|val| val.clone()),
+ ),
+ );
+ m.insert(
+ "bin-dir".to_string(),
+ (
+ Box::new(|val| PhpMixed::Bool(is_string(val))),
+ Box::new(|val| val.clone()),
+ ),
+ );
+ m.insert(
+ "archive-dir".to_string(),
+ (
+ Box::new(|val| PhpMixed::Bool(is_string(val))),
+ Box::new(|val| val.clone()),
+ ),
+ );
+ m.insert(
+ "archive-format".to_string(),
+ (
+ Box::new(|val| PhpMixed::Bool(is_string(val))),
+ Box::new(|val| val.clone()),
+ ),
+ );
+ m.insert(
+ "data-dir".to_string(),
+ (
+ Box::new(|val| PhpMixed::Bool(is_string(val))),
+ Box::new(|val| val.clone()),
+ ),
+ );
+ m.insert(
+ "cache-dir".to_string(),
+ (
+ Box::new(|val| PhpMixed::Bool(is_string(val))),
+ Box::new(|val| val.clone()),
+ ),
+ );
+ m.insert(
+ "cache-files-dir".to_string(),
+ (
+ Box::new(|val| PhpMixed::Bool(is_string(val))),
+ Box::new(|val| val.clone()),
+ ),
+ );
+ m.insert(
+ "cache-repo-dir".to_string(),
+ (
+ Box::new(|val| PhpMixed::Bool(is_string(val))),
+ Box::new(|val| val.clone()),
+ ),
+ );
+ m.insert(
+ "cache-vcs-dir".to_string(),
+ (
+ Box::new(|val| PhpMixed::Bool(is_string(val))),
+ Box::new(|val| val.clone()),
+ ),
+ );
m.insert(
"cache-ttl".to_string(),
(
@@ -1255,21 +1667,53 @@ fn build_unique_config_values() -> IndexMap<String, (ValidatorFn, NormalizerFn)>
m.insert(
"cache-files-maxsize".to_string(),
(
- Box::new(|val| PhpMixed::Bool(Preg::is_match("/^\\s*([0-9.]+)\\s*(?:([kmg])(?:i?b)?)?\\s*$/i", val.as_string().unwrap_or(""), None).unwrap_or(false))),
+ Box::new(|val| {
+ PhpMixed::Bool(
+ Preg::is_match(
+ "/^\\s*([0-9.]+)\\s*(?:([kmg])(?:i?b)?)?\\s*$/i",
+ val.as_string().unwrap_or(""),
+ None,
+ )
+ .unwrap_or(false),
+ )
+ }),
Box::new(|val| val.clone()),
),
);
m.insert(
"bin-compat".to_string(),
(
- Box::new(|val| PhpMixed::Bool(in_array(val.as_string().unwrap_or(""), &vec!["auto".to_string(), "full".to_string(), "proxy".to_string(), "symlink".to_string()], false))),
+ Box::new(|val| {
+ PhpMixed::Bool(in_array(
+ val.as_string().unwrap_or(""),
+ &vec![
+ "auto".to_string(),
+ "full".to_string(),
+ "proxy".to_string(),
+ "symlink".to_string(),
+ ],
+ false,
+ ))
+ }),
Box::new(|val| val.clone()),
),
);
m.insert(
"discard-changes".to_string(),
(
- Box::new(|val| PhpMixed::Bool(in_array(val.as_string().unwrap_or(""), &vec!["stash".to_string(), "true".to_string(), "false".to_string(), "1".to_string(), "0".to_string()], true))),
+ Box::new(|val| {
+ PhpMixed::Bool(in_array(
+ val.as_string().unwrap_or(""),
+ &vec![
+ "stash".to_string(),
+ "true".to_string(),
+ "false".to_string(),
+ "1".to_string(),
+ "0".to_string(),
+ ],
+ true,
+ ))
+ }),
Box::new(|val| {
let s = val.as_string().unwrap_or("");
if s == "stash" {
@@ -1293,18 +1737,55 @@ fn build_unique_config_values() -> IndexMap<String, (ValidatorFn, NormalizerFn)>
}),
),
);
- m.insert("sort-packages".to_string(), (Box::new(boolean_validator), Box::new(boolean_normalizer)));
- m.insert("optimize-autoloader".to_string(), (Box::new(boolean_validator), Box::new(boolean_normalizer)));
- m.insert("classmap-authoritative".to_string(), (Box::new(boolean_validator), Box::new(boolean_normalizer)));
- m.insert("apcu-autoloader".to_string(), (Box::new(boolean_validator), Box::new(boolean_normalizer)));
- m.insert("prepend-autoloader".to_string(), (Box::new(boolean_validator), Box::new(boolean_normalizer)));
- m.insert("update-with-minimal-changes".to_string(), (Box::new(boolean_validator), Box::new(boolean_normalizer)));
- m.insert("disable-tls".to_string(), (Box::new(boolean_validator), Box::new(boolean_normalizer)));
- m.insert("secure-http".to_string(), (Box::new(boolean_validator), Box::new(boolean_normalizer)));
+ m.insert(
+ "sort-packages".to_string(),
+ (Box::new(boolean_validator), Box::new(boolean_normalizer)),
+ );
+ m.insert(
+ "optimize-autoloader".to_string(),
+ (Box::new(boolean_validator), Box::new(boolean_normalizer)),
+ );
+ m.insert(
+ "classmap-authoritative".to_string(),
+ (Box::new(boolean_validator), Box::new(boolean_normalizer)),
+ );
+ m.insert(
+ "apcu-autoloader".to_string(),
+ (Box::new(boolean_validator), Box::new(boolean_normalizer)),
+ );
+ m.insert(
+ "prepend-autoloader".to_string(),
+ (Box::new(boolean_validator), Box::new(boolean_normalizer)),
+ );
+ m.insert(
+ "update-with-minimal-changes".to_string(),
+ (Box::new(boolean_validator), Box::new(boolean_normalizer)),
+ );
+ m.insert(
+ "disable-tls".to_string(),
+ (Box::new(boolean_validator), Box::new(boolean_normalizer)),
+ );
+ m.insert(
+ "secure-http".to_string(),
+ (Box::new(boolean_validator), Box::new(boolean_normalizer)),
+ );
m.insert(
"bump-after-update".to_string(),
(
- Box::new(|val| PhpMixed::Bool(in_array(val.as_string().unwrap_or(""), &vec!["dev".to_string(), "no-dev".to_string(), "true".to_string(), "false".to_string(), "1".to_string(), "0".to_string()], true))),
+ Box::new(|val| {
+ PhpMixed::Bool(in_array(
+ val.as_string().unwrap_or(""),
+ &vec![
+ "dev".to_string(),
+ "no-dev".to_string(),
+ "true".to_string(),
+ "false".to_string(),
+ "1".to_string(),
+ "0".to_string(),
+ ],
+ true,
+ ))
+ }),
Box::new(|val| {
let s = val.as_string().unwrap_or("");
if s == "dev" || s == "no-dev" {
@@ -1318,25 +1799,71 @@ fn build_unique_config_values() -> IndexMap<String, (ValidatorFn, NormalizerFn)>
m.insert(
"cafile".to_string(),
(
- Box::new(|val| PhpMixed::Bool(file_exists(val.as_string().unwrap_or("")) && Filesystem::is_readable(val.as_string().unwrap_or("")))),
- Box::new(|val| if val.as_string() == Some("null") { PhpMixed::Null } else { val.clone() }),
+ Box::new(|val| {
+ PhpMixed::Bool(
+ file_exists(val.as_string().unwrap_or(""))
+ && Filesystem::is_readable(val.as_string().unwrap_or("")),
+ )
+ }),
+ Box::new(|val| {
+ if val.as_string() == Some("null") {
+ PhpMixed::Null
+ } else {
+ val.clone()
+ }
+ }),
),
);
m.insert(
"capath".to_string(),
(
- Box::new(|val| PhpMixed::Bool(is_dir(val.as_string().unwrap_or("")) && Filesystem::is_readable(val.as_string().unwrap_or("")))),
- Box::new(|val| if val.as_string() == Some("null") { PhpMixed::Null } else { val.clone() }),
+ Box::new(|val| {
+ PhpMixed::Bool(
+ is_dir(val.as_string().unwrap_or(""))
+ && Filesystem::is_readable(val.as_string().unwrap_or("")),
+ )
+ }),
+ Box::new(|val| {
+ if val.as_string() == Some("null") {
+ PhpMixed::Null
+ } else {
+ val.clone()
+ }
+ }),
),
);
- m.insert("github-expose-hostname".to_string(), (Box::new(boolean_validator), Box::new(boolean_normalizer)));
- m.insert("htaccess-protect".to_string(), (Box::new(boolean_validator), Box::new(boolean_normalizer)));
- m.insert("lock".to_string(), (Box::new(boolean_validator), Box::new(boolean_normalizer)));
- m.insert("allow-plugins".to_string(), (Box::new(boolean_validator), Box::new(boolean_normalizer)));
+ m.insert(
+ "github-expose-hostname".to_string(),
+ (Box::new(boolean_validator), Box::new(boolean_normalizer)),
+ );
+ m.insert(
+ "htaccess-protect".to_string(),
+ (Box::new(boolean_validator), Box::new(boolean_normalizer)),
+ );
+ m.insert(
+ "lock".to_string(),
+ (Box::new(boolean_validator), Box::new(boolean_normalizer)),
+ );
+ m.insert(
+ "allow-plugins".to_string(),
+ (Box::new(boolean_validator), Box::new(boolean_normalizer)),
+ );
m.insert(
"platform-check".to_string(),
(
- Box::new(|val| PhpMixed::Bool(in_array(val.as_string().unwrap_or(""), &vec!["php-only".to_string(), "true".to_string(), "false".to_string(), "1".to_string(), "0".to_string()], true))),
+ Box::new(|val| {
+ PhpMixed::Bool(in_array(
+ val.as_string().unwrap_or(""),
+ &vec![
+ "php-only".to_string(),
+ "true".to_string(),
+ "false".to_string(),
+ "1".to_string(),
+ "0".to_string(),
+ ],
+ true,
+ ))
+ }),
Box::new(|val| {
let s = val.as_string().unwrap_or("");
if s == "php-only" {
@@ -1350,7 +1877,17 @@ fn build_unique_config_values() -> IndexMap<String, (ValidatorFn, NormalizerFn)>
m.insert(
"use-parent-dir".to_string(),
(
- Box::new(|val| PhpMixed::Bool(in_array(val.as_string().unwrap_or(""), &vec!["true".to_string(), "false".to_string(), "prompt".to_string()], true))),
+ Box::new(|val| {
+ PhpMixed::Bool(in_array(
+ val.as_string().unwrap_or(""),
+ &vec![
+ "true".to_string(),
+ "false".to_string(),
+ "prompt".to_string(),
+ ],
+ true,
+ ))
+ }),
Box::new(|val| {
let s = val.as_string().unwrap_or("");
if s == "prompt" {
@@ -1364,13 +1901,32 @@ fn build_unique_config_values() -> IndexMap<String, (ValidatorFn, NormalizerFn)>
m.insert(
"audit.abandoned".to_string(),
(
- Box::new(|val| PhpMixed::Bool(in_array(val.as_string().unwrap_or(""), &vec![Auditor::ABANDONED_IGNORE.to_string(), Auditor::ABANDONED_REPORT.to_string(), Auditor::ABANDONED_FAIL.to_string()], true))),
+ Box::new(|val| {
+ PhpMixed::Bool(in_array(
+ val.as_string().unwrap_or(""),
+ &vec![
+ Auditor::ABANDONED_IGNORE.to_string(),
+ Auditor::ABANDONED_REPORT.to_string(),
+ Auditor::ABANDONED_FAIL.to_string(),
+ ],
+ true,
+ ))
+ }),
Box::new(|val| val.clone()),
),
);
- m.insert("audit.ignore-unreachable".to_string(), (Box::new(boolean_validator), Box::new(boolean_normalizer)));
- m.insert("audit.block-insecure".to_string(), (Box::new(boolean_validator), Box::new(boolean_normalizer)));
- m.insert("audit.block-abandoned".to_string(), (Box::new(boolean_validator), Box::new(boolean_normalizer)));
+ m.insert(
+ "audit.ignore-unreachable".to_string(),
+ (Box::new(boolean_validator), Box::new(boolean_normalizer)),
+ );
+ m.insert(
+ "audit.block-insecure".to_string(),
+ (Box::new(boolean_validator), Box::new(boolean_normalizer)),
+ );
+ m.insert(
+ "audit.block-abandoned".to_string(),
+ (Box::new(boolean_validator), Box::new(boolean_normalizer)),
+ );
let _ = identity;
m
@@ -1387,8 +1943,14 @@ fn build_multi_config_values() -> IndexMap<String, (ValidatorFn, NormalizerFn)>
}
if let Some(list) = vals.as_list() {
for val in list {
- if !in_array(val.as_string().unwrap_or(""), &vec!["git".to_string(), "https".to_string(), "ssh".to_string()], false) {
- return PhpMixed::String("valid protocols include: git, https, ssh".to_string());
+ if !in_array(
+ val.as_string().unwrap_or(""),
+ &vec!["git".to_string(), "https".to_string(), "ssh".to_string()],
+ false,
+ ) {
+ return PhpMixed::String(
+ "valid protocols include: git, https, ssh".to_string(),
+ );
}
}
}
@@ -1430,8 +1992,19 @@ fn build_multi_config_values() -> IndexMap<String, (ValidatorFn, NormalizerFn)>
}
if let Some(list) = vals.as_list() {
for val in list {
- if !in_array(val.as_string().unwrap_or(""), &vec!["low".to_string(), "medium".to_string(), "high".to_string(), "critical".to_string()], true) {
- return PhpMixed::String("valid severities include: low, medium, high, critical".to_string());
+ if !in_array(
+ val.as_string().unwrap_or(""),
+ &vec![
+ "low".to_string(),
+ "medium".to_string(),
+ "high".to_string(),
+ "critical".to_string(),
+ ],
+ true,
+ ) {
+ return PhpMixed::String(
+ "valid severities include: low, medium, high, critical".to_string(),
+ );
}
}
}
@@ -1445,11 +2018,41 @@ fn build_multi_config_values() -> IndexMap<String, (ValidatorFn, NormalizerFn)>
fn build_unique_props() -> IndexMap<String, (ValidatorFn, NormalizerFn)> {
let mut m: IndexMap<String, (ValidatorFn, NormalizerFn)> = IndexMap::new();
- m.insert("name".to_string(), (Box::new(|val| PhpMixed::Bool(is_string(val))), Box::new(|val| val.clone())));
- m.insert("type".to_string(), (Box::new(|val| PhpMixed::Bool(is_string(val))), Box::new(|val| val.clone())));
- m.insert("description".to_string(), (Box::new(|val| PhpMixed::Bool(is_string(val))), Box::new(|val| val.clone())));
- m.insert("homepage".to_string(), (Box::new(|val| PhpMixed::Bool(is_string(val))), Box::new(|val| val.clone())));
- m.insert("version".to_string(), (Box::new(|val| PhpMixed::Bool(is_string(val))), Box::new(|val| val.clone())));
+ m.insert(
+ "name".to_string(),
+ (
+ Box::new(|val| PhpMixed::Bool(is_string(val))),
+ Box::new(|val| val.clone()),
+ ),
+ );
+ m.insert(
+ "type".to_string(),
+ (
+ Box::new(|val| PhpMixed::Bool(is_string(val))),
+ Box::new(|val| val.clone()),
+ ),
+ );
+ m.insert(
+ "description".to_string(),
+ (
+ Box::new(|val| PhpMixed::Bool(is_string(val))),
+ Box::new(|val| val.clone()),
+ ),
+ );
+ m.insert(
+ "homepage".to_string(),
+ (
+ Box::new(|val| PhpMixed::Bool(is_string(val))),
+ Box::new(|val| val.clone()),
+ ),
+ );
+ m.insert(
+ "version".to_string(),
+ (
+ Box::new(|val| PhpMixed::Bool(is_string(val))),
+ Box::new(|val| val.clone()),
+ ),
+ );
m.insert(
"minimum-stability".to_string(),
(
@@ -1457,10 +2060,17 @@ fn build_unique_props() -> IndexMap<String, (ValidatorFn, NormalizerFn)> {
let normalized = VersionParser::normalize_stability(val.as_string().unwrap_or(""));
PhpMixed::Bool(base_package::STABILITIES.contains_key(normalized.as_str()))
}),
- Box::new(|val| PhpMixed::String(VersionParser::normalize_stability(val.as_string().unwrap_or("")))),
+ Box::new(|val| {
+ PhpMixed::String(VersionParser::normalize_stability(
+ val.as_string().unwrap_or(""),
+ ))
+ }),
),
);
- m.insert("prefer-stable".to_string(), (Box::new(boolean_validator), Box::new(boolean_normalizer)));
+ m.insert(
+ "prefer-stable".to_string(),
+ (Box::new(boolean_validator), Box::new(boolean_normalizer)),
+ );
m
}
@@ -1505,7 +2115,10 @@ fn flatten_setting_keys(config: PhpMixed, prefix: &str) -> Vec<String> {
// array-lists must not be added to completion
// sub-keys of repository-keys must not be added to completion
if is_array(value) && !array_is_list(value) && prefix != "repositories." {
- keys.push(flatten_setting_keys((**value).clone(), &format!("{}{}.", prefix, key)));
+ keys.push(flatten_setting_keys(
+ (**value).clone(),
+ &format!("{}{}.", prefix, key),
+ ));
}
}
@@ -1519,7 +2132,10 @@ fn flatten_setting_keys(config: PhpMixed, prefix: &str) -> Vec<String> {
// Helpers for the suggester since BaseConfigCommand methods need an instance.
fn get_composer_config_file_static(input: &CompletionInput, config: &Config) -> String {
if input.get_option("global").as_bool() == Some(true) {
- format!("{}/config.json", config.get("home").as_string().unwrap_or(""))
+ format!(
+ "{}/config.json",
+ config.get("home").as_string().unwrap_or("")
+ )
} else {
input
.get_option("file")
diff --git a/crates/shirabe/src/command/create_project_command.rs b/crates/shirabe/src/command/create_project_command.rs
index 6614b11..c649848 100644
--- a/crates/shirabe/src/command/create_project_command.rs
+++ b/crates/shirabe/src/command/create_project_command.rs
@@ -7,17 +7,17 @@ use shirabe_external_packages::symfony::component::console::input::input_interfa
use shirabe_external_packages::symfony::component::console::output::output_interface::OutputInterface;
use shirabe_external_packages::symfony::component::finder::finder::Finder;
use shirabe_php_shim::{
- array_pop, chdir, explode_with_limit, file_exists, getcwd, implode, is_dir, is_file,
- mkdir, realpath, rtrim, strtolower, unlink, InvalidArgumentException, PhpMixed,
- RuntimeException, UnexpectedValueException, DIRECTORY_SEPARATOR,
+ DIRECTORY_SEPARATOR, InvalidArgumentException, PhpMixed, RuntimeException,
+ UnexpectedValueException, array_pop, chdir, explode_with_limit, file_exists, getcwd, implode,
+ is_dir, is_file, mkdir, realpath, rtrim, strtolower, unlink,
};
use crate::advisory::auditor::Auditor;
use crate::command::base_command::BaseCommand;
use crate::command::completion_trait::CompletionTrait;
use crate::composer::Composer;
-use crate::config::json_config_source::JsonConfigSource;
use crate::config::Config;
+use crate::config::json_config_source::JsonConfigSource;
use crate::console::input::input_argument::InputArgument;
use crate::console::input::input_option::InputOption;
use crate::dependency_resolver::operation::install_operation::InstallOperation;
@@ -25,9 +25,9 @@ use crate::factory::Factory;
use crate::filter::platform_requirement_filter::ignore_all_platform_requirement_filter::IgnoreAllPlatformRequirementFilter;
use crate::filter::platform_requirement_filter::platform_requirement_filter_factory::PlatformRequirementFilterFactory;
use crate::filter::platform_requirement_filter::platform_requirement_filter_interface::PlatformRequirementFilterInterface;
+use crate::installer::Installer;
use crate::installer::project_installer::ProjectInstaller;
use crate::installer::suggested_packages_reporter::SuggestedPackagesReporter;
-use crate::installer::Installer;
use crate::io::io_interface::IOInterface;
use crate::json::json_file::JsonFile;
use crate::package::alias_package::AliasPackage;
@@ -116,13 +116,18 @@ impl CreateProjectCommand {
let config = Factory::create_config(None, None)?;
let io = self.inner.get_io();
- let (prefer_source, prefer_dist) =
- self.inner.get_preferred_install_options(&config, input, true)?;
+ let (prefer_source, prefer_dist) = self
+ .inner
+ .get_preferred_install_options(&config, input, true)?;
if input.get_option("dev").as_bool().unwrap_or(false) {
io.write_error("<warning>You are using the deprecated option \"dev\". Dev packages are installed by default now.</warning>");
}
- if input.get_option("no-custom-installers").as_bool().unwrap_or(false) {
+ if input
+ .get_option("no-custom-installers")
+ .as_bool()
+ .unwrap_or(false)
+ {
io.write_error("<warning>You are using the deprecated option \"no-custom-installers\". Use \"no-plugins\" instead.</warning>");
input.set_option("no-plugins", PhpMixed::Bool(true));
}
@@ -136,11 +141,8 @@ impl CreateProjectCommand {
}
.into());
}
- let mut parts = explode_with_limit(
- "/",
- &strtolower(package.as_string().unwrap_or("")),
- 2,
- );
+ let mut parts =
+ explode_with_limit("/", &strtolower(package.as_string().unwrap_or("")), 2);
let prompt = format!(
"New project directory [<comment>{}</comment>]: ",
array_pop(&mut parts).unwrap_or_default()
@@ -150,7 +152,11 @@ impl CreateProjectCommand {
let repository_opt = input.get_option("repository");
let repository_url_opt = input.get_option("repository-url");
- let repositories = if repository_opt.as_list().map(|l| l.len() > 0).unwrap_or(false) {
+ let repositories = if repository_opt
+ .as_list()
+ .map(|l| l.len() > 0)
+ .unwrap_or(false)
+ {
Some(repository_opt)
} else {
Some(repository_url_opt)
@@ -160,10 +166,22 @@ impl CreateProjectCommand {
io,
config,
input,
- input.get_argument("package").as_string().map(|s| s.to_string()),
- input.get_argument("directory").as_string().map(|s| s.to_string()),
- input.get_argument("version").as_string().map(|s| s.to_string()),
- input.get_option("stability").as_string().map(|s| s.to_string()),
+ input
+ .get_argument("package")
+ .as_string()
+ .map(|s| s.to_string()),
+ input
+ .get_argument("directory")
+ .as_string()
+ .map(|s| s.to_string()),
+ input
+ .get_argument("version")
+ .as_string()
+ .map(|s| s.to_string()),
+ input
+ .get_option("stability")
+ .as_string()
+ .map(|s| s.to_string()),
prefer_source,
prefer_dist,
!input.get_option("no-dev").as_bool().unwrap_or(false),
@@ -173,8 +191,14 @@ impl CreateProjectCommand {
input.get_option("no-progress").as_bool().unwrap_or(false),
input.get_option("no-install").as_bool().unwrap_or(false),
Some(self.inner.get_platform_requirement_filter(input)?),
- !input.get_option("no-secure-http").as_bool().unwrap_or(false),
- input.get_option("add-repository").as_bool().unwrap_or(false),
+ !input
+ .get_option("no-secure-http")
+ .as_bool()
+ .unwrap_or(false),
+ input
+ .get_option("add-repository")
+ .as_bool()
+ .unwrap_or(false),
)
}
@@ -255,13 +279,8 @@ impl CreateProjectCommand {
unlink("composer.lock");
}
- let mut composer = self.create_composer_instance(
- input,
- io,
- None,
- disable_plugins,
- Some(disable_scripts),
- )?;
+ let mut composer =
+ self.create_composer_instance(input, io, None, disable_plugins, Some(disable_scripts))?;
// add the repository to the composer.json and use it for the install run later
if let Some(repos) = repositories.as_ref() {
@@ -288,20 +307,13 @@ impl CreateProjectCommand {
let is_packagist_disabled = (repo_config.contains_key("packagist")
&& repo_config.len() == 1
- && repo_config.get("packagist").and_then(|v| v.as_bool())
- == Some(false))
+ && repo_config.get("packagist").and_then(|v| v.as_bool()) == Some(false))
|| (repo_config.contains_key("packagist.org")
&& repo_config.len() == 1
- && repo_config
- .get("packagist.org")
- .and_then(|v| v.as_bool())
+ && repo_config.get("packagist.org").and_then(|v| v.as_bool())
== Some(false));
if is_packagist_disabled {
- config_source.add_repository(
- "packagist.org",
- PhpMixed::Bool(false),
- false,
- );
+ config_source.add_repository("packagist.org", PhpMixed::Bool(false), false);
} else {
config_source.add_repository(
&name,
@@ -315,8 +327,8 @@ impl CreateProjectCommand {
);
}
- composer = self
- .create_composer_instance(input, io, None, disable_plugins, None)?;
+ composer =
+ self.create_composer_instance(input, io, None, disable_plugins, None)?;
}
}
}
@@ -332,8 +344,9 @@ impl CreateProjectCommand {
// use the new config including the newly installed project
let config = composer.get_config();
- let (ps, pd) =
- self.inner.get_preferred_install_options(config, input, false)?;
+ let (ps, pd) = self
+ .inner
+ .get_preferred_install_options(config, input, false)?;
prefer_source = ps;
prefer_dist = pd;
@@ -356,7 +369,10 @@ impl CreateProjectCommand {
config.get("optimize-autoloader").as_bool().unwrap_or(false),
)
.set_class_map_authoritative(
- config.get("classmap-authoritative").as_bool().unwrap_or(false),
+ config
+ .get("classmap-authoritative")
+ .as_bool()
+ .unwrap_or(false),
)
.set_apcu_autoloader(
config.get("apcu-autoloader").as_bool().unwrap_or(false),
@@ -456,11 +472,8 @@ impl CreateProjectCommand {
// rewriting self.version dependencies with explicit version numbers if the package's vcs metadata is gone
if !has_vcs {
let package = composer.get_package();
- let config_source = JsonConfigSource::new(JsonFile::new(
- "composer.json".to_string(),
- None,
- None,
- ));
+ let config_source =
+ JsonConfigSource::new(JsonFile::new("composer.json".to_string(), None, None));
for (r#type, meta) in SUPPORTED_LINK_TYPES.iter() {
// PHP: $package->{'get'.$meta['method']}() — dynamic getter dispatch
// TODO(phase-b): dynamic getter dispatch by name
@@ -479,10 +492,9 @@ impl CreateProjectCommand {
}
// dispatch event
- composer.get_event_dispatcher().dispatch_script(
- ScriptEvents::POST_CREATE_PROJECT_CMD,
- install_dev_packages,
- );
+ composer
+ .get_event_dispatcher()
+ .dispatch_script(ScriptEvents::POST_CREATE_PROJECT_CMD, install_dev_packages);
chdir(&old_cwd);
@@ -515,8 +527,12 @@ impl CreateProjectCommand {
// TODO(phase-b): VersionParser has no public `new` yet
let parser: VersionParser = todo!("VersionParser::new()");
let requirements = parser.parse_name_version_pairs(vec![package_name.to_string()])?;
- let name =
- strtolower(requirements[0].get("name").map(|s| s.as_str()).unwrap_or(""));
+ let name = strtolower(
+ requirements[0]
+ .get("name")
+ .map(|s| s.as_str())
+ .unwrap_or(""),
+ );
if package_version.is_none() && requirements[0].contains_key("version") {
package_version = requirements[0].get("version").cloned();
}
@@ -606,7 +622,10 @@ impl CreateProjectCommand {
"{{^[^,\\s]*?@({})$}}i",
implode(
"|",
- &STABILITIES.keys().map(|k| k.to_string()).collect::<Vec<_>>()
+ &STABILITIES
+ .keys()
+ .map(|k| k.to_string())
+ .collect::<Vec<_>>()
)
),
package_version.as_deref().unwrap_or(""),
@@ -619,8 +638,7 @@ impl CreateProjectCommand {
}
}
- let stability =
- VersionParser::normalize_stability(stability.as_deref().unwrap_or(""));
+ let stability = VersionParser::normalize_stability(stability.as_deref().unwrap_or(""));
if !STABILITIES.contains_key(stability.as_str()) {
return Err(InvalidArgumentException {
@@ -629,7 +647,10 @@ impl CreateProjectCommand {
stability,
implode(
", ",
- &STABILITIES.keys().map(|k| k.to_string()).collect::<Vec<_>>()
+ &STABILITIES
+ .keys()
+ .map(|k| k.to_string())
+ .collect::<Vec<_>>()
)
),
code: 0,
@@ -660,13 +681,10 @@ impl CreateProjectCommand {
RepositoryFactory::config_from_string(io, config, repo, true)?;
let is_packagist_disabled = (repo_config.contains_key("packagist")
&& repo_config.len() == 1
- && repo_config.get("packagist").and_then(|v| v.as_bool())
- == Some(false))
+ && repo_config.get("packagist").and_then(|v| v.as_bool()) == Some(false))
|| (repo_config.contains_key("packagist.org")
&& repo_config.len() == 1
- && repo_config
- .get("packagist.org")
- .and_then(|v| v.as_bool())
+ && repo_config.get("packagist.org").and_then(|v| v.as_bool())
== Some(false));
if is_packagist_disabled {
continue;
@@ -687,10 +705,7 @@ impl CreateProjectCommand {
.entry("options".to_string())
.or_insert(PhpMixed::Array(indexmap::IndexMap::new()));
if let PhpMixed::Array(options_map) = options_entry {
- options_map.insert(
- "symlink".to_string(),
- Box::new(PhpMixed::Bool(false)),
- );
+ options_map.insert("symlink".to_string(), Box::new(PhpMixed::Bool(false)));
}
}
@@ -774,7 +789,11 @@ impl CreateProjectCommand {
if let Some(real_dir) = realpath(&directory) {
let real_dir_clone = real_dir.clone();
signal_handler = Some(SignalHandler::create(
- vec![SignalHandler::SIGINT, SignalHandler::SIGTERM, SignalHandler::SIGHUP],
+ vec![
+ SignalHandler::SIGINT,
+ SignalHandler::SIGTERM,
+ SignalHandler::SIGHUP,
+ ],
Box::new(move |signal: String, handler: &SignalHandler| {
// TODO(phase-b): self.get_io().write_error(...) inside the closure
let _ = &signal;
diff --git a/crates/shirabe/src/command/depends_command.rs b/crates/shirabe/src/command/depends_command.rs
index 36f7e22..9ec3dde 100644
--- a/crates/shirabe/src/command/depends_command.rs
+++ b/crates/shirabe/src/command/depends_command.rs
@@ -1,11 +1,11 @@
//! ref: composer/src/Composer/Command/DependsCommand.php
-use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
-use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
use crate::command::base_dependency_command::BaseDependencyCommand;
use crate::command::completion_trait::CompletionTrait;
use crate::console::input::input_argument::InputArgument;
use crate::console::input::input_option::InputOption;
+use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
+use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
pub struct DependsCommand {
inner: BaseDependencyCommand,
@@ -50,7 +50,7 @@ impl DependsCommand {
.set_help(
"Displays detailed information about where a package is referenced.\n\n\
<info>php composer.phar depends composer/composer</info>\n\n\
- Read more at https://getcomposer.org/doc/03-cli.md#depends-why"
+ Read more at https://getcomposer.org/doc/03-cli.md#depends-why",
);
}
diff --git a/crates/shirabe/src/command/diagnose_command.rs b/crates/shirabe/src/command/diagnose_command.rs
index 664b242..07e367f 100644
--- a/crates/shirabe/src/command/diagnose_command.rs
+++ b/crates/shirabe/src/command/diagnose_command.rs
@@ -8,15 +8,14 @@ use shirabe_external_packages::symfony::component::console::input::input_interfa
use shirabe_external_packages::symfony::component::console::output::output_interface::OutputInterface;
use shirabe_external_packages::symfony::component::process::executable_finder::ExecutableFinder;
use shirabe_php_shim::{
- count, curl_version, defined, disk_free_space, extension_loaded, file_exists, filter_var,
- function_exists, get_class, hash, implode, ini_get, ioncube_loader_iversion,
- ioncube_loader_version, is_array, is_string, key, max_i64, ob_get_clean, ob_start, phpinfo,
- reset, rtrim, sprintf, str_contains, str_replace, str_starts_with, strpos, strstr, strtolower,
- trim, version_compare, FILTER_VALIDATE_BOOLEAN, INFO_GENERAL,
- InvalidArgumentException, PhpMixed, RuntimeException,
- OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT, PHP_BINARY, PHP_EOL, PHP_VERSION,
- PHP_VERSION_ID, PHP_WINDOWS_VERSION_BUILD,
CURL_HTTP_VERSION_2_0, CURL_VERSION_HTTP2, CURL_VERSION_HTTP3, CURL_VERSION_ZSTD,
+ FILTER_VALIDATE_BOOLEAN, INFO_GENERAL, InvalidArgumentException, OPENSSL_VERSION_NUMBER,
+ OPENSSL_VERSION_TEXT, PHP_BINARY, PHP_EOL, PHP_VERSION, PHP_VERSION_ID,
+ PHP_WINDOWS_VERSION_BUILD, PhpMixed, RuntimeException, count, curl_version, defined,
+ disk_free_space, extension_loaded, file_exists, filter_var, function_exists, get_class, hash,
+ implode, ini_get, ioncube_loader_iversion, ioncube_loader_version, is_array, is_string, key,
+ max_i64, ob_get_clean, ob_start, phpinfo, reset, rtrim, sprintf, str_contains, str_replace,
+ str_starts_with, strpos, strstr, strtolower, trim, version_compare,
};
use crate::advisory::auditor::Auditor;
@@ -70,7 +69,11 @@ impl DiagnoseCommand {
);
}
- pub(crate) fn execute(&mut self, input: &dyn InputInterface, output: &dyn OutputInterface) -> anyhow::Result<i64> {
+ pub(crate) fn execute(
+ &mut self,
+ input: &dyn InputInterface,
+ output: &dyn OutputInterface,
+ ) -> anyhow::Result<i64> {
let composer = self.inner.try_composer();
let io = self.inner.get_io();
@@ -78,8 +81,16 @@ impl DiagnoseCommand {
if let Some(ref c) = composer {
config = c.get_config().clone();
- let command_event = CommandEvent::new(PluginEvents::COMMAND, "diagnose", input, output, vec![], IndexMap::new());
- c.get_event_dispatcher().dispatch(command_event.get_name(), &command_event);
+ let command_event = CommandEvent::new(
+ PluginEvents::COMMAND,
+ "diagnose",
+ input,
+ output,
+ vec![],
+ IndexMap::new(),
+ );
+ c.get_event_dispatcher()
+ .dispatch(command_event.get_name(), &command_event);
self.process = Some(
c.get_loop()
.get_process_executor()
@@ -94,7 +105,10 @@ impl DiagnoseCommand {
let mut secure_http_wrap: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
let mut config_inner: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
config_inner.insert("secure-http".to_string(), Box::new(PhpMixed::Bool(false)));
- secure_http_wrap.insert("config".to_string(), Box::new(PhpMixed::Array(config_inner)));
+ secure_http_wrap.insert(
+ "config".to_string(),
+ Box::new(PhpMixed::Array(config_inner)),
+ );
let mut config = config;
config.merge(PhpMixed::Array(secure_http_wrap), Config::SOURCE_COMMAND);
config.prohibit_url_by_config("http://repo.packagist.org", &NullIO::new());
@@ -111,26 +125,40 @@ impl DiagnoseCommand {
self.output_result(r);
}
- io.write(&format!("Composer version: <comment>{}</comment>", Composer::get_version()));
+ io.write(&format!(
+ "Composer version: <comment>{}</comment>",
+ Composer::get_version()
+ ));
io.write_no_newline("Checking Composer and its dependencies for vulnerabilities: ");
let r = self.check_composer_audit(&config)?;
self.output_result(r);
- let platform_overrides = config.get("platform").as_array().cloned().unwrap_or_default();
+ let platform_overrides = config
+ .get("platform")
+ .as_array()
+ .cloned()
+ .unwrap_or_default();
let platform_repo = PlatformRepository::new(vec![], platform_overrides);
let php_pkg = platform_repo.find_package("php", "*").unwrap();
let mut php_version = php_pkg.get_pretty_version().to_string();
if let Some(cp) = php_pkg.as_complete_package_interface() {
if str_contains(&cp.get_description().unwrap_or_default(), "overridden") {
- php_version = format!("{} - {}", php_version, cp.get_description().unwrap_or_default());
+ php_version = format!(
+ "{} - {}",
+ php_version,
+ cp.get_description().unwrap_or_default()
+ );
}
}
io.write(&format!("PHP version: <comment>{}</comment>", php_version));
if defined("PHP_BINARY") {
- io.write(&format!("PHP binary path: <comment>{}</comment>", PHP_BINARY));
+ io.write(&format!(
+ "PHP binary path: <comment>{}</comment>",
+ PHP_BINARY
+ ));
}
io.write(&format!(
@@ -242,7 +270,10 @@ impl DiagnoseCommand {
}
io.write_no_newline(&format!(
"Checking connectivity to {}: ",
- repo_arr.get("url").and_then(|v| v.as_string()).unwrap_or("")
+ repo_arr
+ .get("url")
+ .and_then(|v| v.as_string())
+ .unwrap_or("")
));
let r = self.check_composer_repo(&url, &config)?;
self.output_result(r);
@@ -257,7 +288,8 @@ impl DiagnoseCommand {
};
let proxy_check_result: Result<(), anyhow::Error> = (|| -> anyhow::Result<()> {
for proto in &protos {
- let proxy = proxy_manager.get_proxy_for_request(&format!("{}://repo.packagist.org", proto));
+ let proxy =
+ proxy_manager.get_proxy_for_request(&format!("{}://repo.packagist.org", proto));
if !proxy.get_status().is_empty() {
let r#type = if proxy.is_secure() { "HTTPS" } else { "HTTP" };
io.write_no_newline(&format!("Checking {} proxy with {}: ", r#type, proto));
@@ -274,14 +306,22 @@ impl DiagnoseCommand {
self.output_result(if is_string(&status) {
status
} else {
- PhpMixed::String(format!("<error>[{}] {}</error>", get_class(&e), e.to_string()))
+ PhpMixed::String(format!(
+ "<error>[{}] {}</error>",
+ get_class(&e),
+ e.to_string()
+ ))
});
} else {
return Err(e);
}
}
- let oauth = config.get("github-oauth").as_array().cloned().unwrap_or_default();
+ let oauth = config
+ .get("github-oauth")
+ .as_array()
+ .cloned()
+ .unwrap_or_default();
if count(&oauth) > 0 {
for (domain, token) in &oauth {
io.write_no_newline(&format!("Checking {} oauth access: ", domain));
@@ -313,10 +353,18 @@ impl DiagnoseCommand {
if te.get_code() == 401 {
self.output_result(PhpMixed::String("<comment>The oauth token for github.com seems invalid, run \"composer config --global --unset github-oauth.github.com\" to remove it</comment>".to_string()));
} else {
- self.output_result(PhpMixed::String(format!("<error>[{}] {}</error>", get_class(&e), e.to_string())));
+ self.output_result(PhpMixed::String(format!(
+ "<error>[{}] {}</error>",
+ get_class(&e),
+ e.to_string()
+ )));
}
} else {
- self.output_result(PhpMixed::String(format!("<error>[{}] {}</error>", get_class(&e), e.to_string())));
+ self.output_result(PhpMixed::String(format!(
+ "<error>[{}] {}</error>",
+ get_class(&e),
+ e.to_string()
+ )));
}
}
}
@@ -379,7 +427,11 @@ impl DiagnoseCommand {
let mut output = String::new();
self.process.as_mut().unwrap().execute(
- &vec!["git".to_string(), "config".to_string(), "color.ui".to_string()],
+ &vec![
+ "git".to_string(),
+ "config".to_string(),
+ "color.ui".to_string(),
+ ],
&mut output,
);
if strtolower(&trim(&output, " \t\n\r\0\u{0B}")) == "always" {
@@ -393,7 +445,10 @@ impl DiagnoseCommand {
};
if version_compare("2.24.0", &git_version, ">") {
- return format!("<warning>Your git version ({}) is too old and possibly will cause issues. Please upgrade to git 2.24 or above</>", git_version);
+ return format!(
+ "<warning>Your git version ({}) is too old and possibly will cause issues. Please upgrade to git 2.24 or above</>",
+ git_version
+ );
}
format!("<info>OK</> <comment>git version {}</>", git_version)
@@ -411,7 +466,10 @@ impl DiagnoseCommand {
tls_warning = Some("<warning>Composer is configured to disable SSL/TLS protection. This will leave remote HTTPS requests vulnerable to Man-In-The-Middle attacks.</warning>".to_string());
}
- match self.http_downloader.as_mut().unwrap().get(&format!("{}://repo.packagist.org/packages.json", proto), IndexMap::new()) {
+ match self.http_downloader.as_mut().unwrap().get(
+ &format!("{}://repo.packagist.org/packages.json", proto),
+ IndexMap::new(),
+ ) {
Ok(_) => {}
Err(e) => {
if let Some(te) = e.downcast_ref::<TransportException>() {
@@ -456,7 +514,12 @@ impl DiagnoseCommand {
tls_warning = Some("<warning>Composer is configured to disable SSL/TLS protection. This will leave remote HTTPS requests vulnerable to Man-In-The-Middle attacks.</warning>".to_string());
}
- match self.http_downloader.as_mut().unwrap().get(url, IndexMap::new()) {
+ match self
+ .http_downloader
+ .as_mut()
+ .unwrap()
+ .get(url, IndexMap::new())
+ {
Ok(_) => {}
Err(e) => {
if let Some(te) = e.downcast_ref::<TransportException>() {
@@ -489,7 +552,11 @@ impl DiagnoseCommand {
Ok(PhpMixed::Bool(true))
}
- fn check_http_proxy(&mut self, proxy: &RequestProxy, protocol: &str) -> anyhow::Result<PhpMixed> {
+ fn check_http_proxy(
+ &mut self,
+ proxy: &RequestProxy,
+ protocol: &str,
+ ) -> anyhow::Result<PhpMixed> {
let result = self.check_connectivity_and_composer_network_http_enablement();
if result.as_bool() != Some(true) {
return Ok(result);
@@ -508,21 +575,32 @@ impl DiagnoseCommand {
.http_downloader
.as_mut()
.unwrap()
- .get(&format!("{}://repo.packagist.org/packages.json", protocol), IndexMap::new())?
+ .get(
+ &format!("{}://repo.packagist.org/packages.json", protocol),
+ IndexMap::new(),
+ )?
.decode_json()?;
if let Some(provider_includes) = json.as_array().and_then(|a| a.get("provider-includes")) {
let mut hash_val = reset(&provider_includes.as_array().cloned().unwrap_or_default());
- hash_val = hash_val.as_array().and_then(|a| a.get("sha256")).map(|v| (**v).clone()).unwrap_or(PhpMixed::Null);
+ hash_val = hash_val
+ .as_array()
+ .and_then(|a| a.get("sha256"))
+ .map(|v| (**v).clone())
+ .unwrap_or(PhpMixed::Null);
let path = str_replace(
"%hash%",
hash_val.as_string().unwrap_or(""),
- &key(&provider_includes.as_array().cloned().unwrap_or_default()).unwrap_or_default(),
+ &key(&provider_includes.as_array().cloned().unwrap_or_default())
+ .unwrap_or_default(),
);
let provider = self
.http_downloader
.as_mut()
.unwrap()
- .get(&format!("{}://repo.packagist.org/{}", protocol, path), IndexMap::new())?
+ .get(
+ &format!("{}://repo.packagist.org/{}", protocol, path),
+ IndexMap::new(),
+ )?
.get_body();
if hash("sha256", &provider) != hash_val.as_string().unwrap_or("") {
@@ -533,7 +611,10 @@ impl DiagnoseCommand {
}
}
- Ok(PhpMixed::String(format!("<info>OK</> <comment>{}</>", proxy_status)))
+ Ok(PhpMixed::String(format!(
+ "<info>OK</> <comment>{}</>",
+ proxy_status
+ )))
}
fn check_github_oauth(&mut self, domain: &str, token: &str) -> anyhow::Result<PhpMixed> {
@@ -542,7 +623,11 @@ impl DiagnoseCommand {
return Ok(result);
}
- self.inner.get_io().set_authentication(domain.to_string(), token.to_string(), Some("x-oauth-basic".to_string()));
+ self.inner.get_io().set_authentication(
+ domain.to_string(),
+ token.to_string(),
+ Some("x-oauth-basic".to_string()),
+ );
let url = if domain == "github.com" {
format!("https://api.{}/", domain)
} else {
@@ -550,14 +635,19 @@ impl DiagnoseCommand {
};
let mut opts: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
- opts.insert("retry-auth-failure".to_string(), Box::new(PhpMixed::Bool(false)));
+ opts.insert(
+ "retry-auth-failure".to_string(),
+ Box::new(PhpMixed::Bool(false)),
+ );
match self.http_downloader.as_mut().unwrap().get(&url, opts) {
Ok(response) => {
let expiration = response.get_header("github-authentication-token-expiration");
if expiration.is_none() {
- return Ok(PhpMixed::String("<info>OK</> <comment>does not expire</>".to_string()));
+ return Ok(PhpMixed::String(
+ "<info>OK</> <comment>does not expire</>".to_string(),
+ ));
}
Ok(PhpMixed::String(format!(
@@ -574,19 +664,31 @@ impl DiagnoseCommand {
)));
}
}
- Ok(PhpMixed::String(format!("<error>[{}] {}</error>", get_class(&e), e.to_string())))
+ Ok(PhpMixed::String(format!(
+ "<error>[{}] {}</error>",
+ get_class(&e),
+ e.to_string()
+ )))
}
}
}
- fn get_github_rate_limit(&mut self, domain: &str, token: Option<&str>) -> anyhow::Result<PhpMixed> {
+ fn get_github_rate_limit(
+ &mut self,
+ domain: &str,
+ token: Option<&str>,
+ ) -> anyhow::Result<PhpMixed> {
let result = self.check_connectivity_and_composer_network_http_enablement();
if result.as_bool() != Some(true) {
return Ok(result);
}
if let Some(t) = token {
- self.inner.get_io().set_authentication(domain.to_string(), t.to_string(), Some("x-oauth-basic".to_string()));
+ self.inner.get_io().set_authentication(
+ domain.to_string(),
+ t.to_string(),
+ Some("x-oauth-basic".to_string()),
+ );
}
let url = if domain == "github.com" {
@@ -595,8 +697,16 @@ impl DiagnoseCommand {
format!("https://{}/api/rate_limit", domain)
};
let mut opts: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
- opts.insert("retry-auth-failure".to_string(), Box::new(PhpMixed::Bool(false)));
- let data = self.http_downloader.as_mut().unwrap().get(&url, opts)?.decode_json()?;
+ opts.insert(
+ "retry-auth-failure".to_string(),
+ Box::new(PhpMixed::Bool(false)),
+ );
+ let data = self
+ .http_downloader
+ .as_mut()
+ .unwrap()
+ .get(&url, opts)?
+ .decode_json()?;
Ok(data
.as_array()
@@ -614,7 +724,11 @@ impl DiagnoseCommand {
let min_space_free = 1024 * 1024;
let home_dir = config.get("home").as_string().unwrap_or("").to_string();
- let vendor_dir = config.get("vendor-dir").as_string().unwrap_or("").to_string();
+ let vendor_dir = config
+ .get("vendor-dir")
+ .as_string()
+ .unwrap_or("")
+ .to_string();
let mut dir = home_dir.clone();
let df_home = disk_free_space(&home_dir);
if df_home.map(|d| d < min_space_free).unwrap_or(false) {
@@ -634,7 +748,9 @@ impl DiagnoseCommand {
let mut errors: Vec<Box<PhpMixed>> = vec![];
let io = self.inner.get_io();
- if file_exists(&format!("{}/keys.tags.pub", home)) && file_exists(&format!("{}/keys.dev.pub", home)) {
+ if file_exists(&format!("{}/keys.tags.pub", home))
+ && file_exists(&format!("{}/keys.dev.pub", home))
+ {
io.write("");
}
@@ -644,7 +760,9 @@ impl DiagnoseCommand {
Keys::fingerprint(&format!("{}/keys.tags.pub", home))
));
} else {
- errors.push(Box::new(PhpMixed::String("<error>Missing pubkey for tags verification</error>".to_string())));
+ errors.push(Box::new(PhpMixed::String(
+ "<error>Missing pubkey for tags verification</error>".to_string(),
+ )));
}
if file_exists(&format!("{}/keys.dev.pub", home)) {
@@ -653,11 +771,15 @@ impl DiagnoseCommand {
Keys::fingerprint(&format!("{}/keys.dev.pub", home))
));
} else {
- errors.push(Box::new(PhpMixed::String("<error>Missing pubkey for dev verification</error>".to_string())));
+ errors.push(Box::new(PhpMixed::String(
+ "<error>Missing pubkey for dev verification</error>".to_string(),
+ )));
}
if !errors.is_empty() {
- errors.push(Box::new(PhpMixed::String("<error>Run composer self-update --update-keys to set them up</error>".to_string())));
+ errors.push(Box::new(PhpMixed::String(
+ "<error>Run composer self-update --update-keys to set them up</error>".to_string(),
+ )));
}
if !errors.is_empty() {
@@ -676,10 +798,21 @@ impl DiagnoseCommand {
let versions_util = Versions::new(config.clone(), self.http_downloader.clone().unwrap());
let latest = match versions_util.get_latest() {
Ok(l) => l,
- Err(e) => return Ok(PhpMixed::String(format!("<error>[{}] {}</error>", get_class(&e), e.to_string()))),
+ Err(e) => {
+ return Ok(PhpMixed::String(format!(
+ "<error>[{}] {}</error>",
+ get_class(&e),
+ e.to_string()
+ )));
+ }
};
- let latest_version = latest.as_array().and_then(|a| a.get("version")).and_then(|v| v.as_string()).unwrap_or("").to_string();
+ let latest_version = latest
+ .as_array()
+ .and_then(|a| a.get("version"))
+ .and_then(|v| v.as_string())
+ .unwrap_or("")
+ .to_string();
if Composer::VERSION != latest_version && Composer::VERSION != "@package_version@" {
return Ok(PhpMixed::String(format!(
"<comment>You are not running the latest {} version, run `composer self-update` to update ({} => {})</comment>",
@@ -723,12 +856,22 @@ impl DiagnoseCommand {
if version != "@package_version@" {
let version_parser = VersionParser::new();
let normalized_version = version_parser.normalize(&version, None)?;
- let root_pkg = RootPackage::new("composer/composer".to_string(), normalized_version, version.clone());
+ let root_pkg = RootPackage::new(
+ "composer/composer".to_string(),
+ normalized_version,
+ version.clone(),
+ );
packages.push(Box::new(root_pkg));
}
let mut repo_config: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
- repo_config.insert("type".to_string(), Box::new(PhpMixed::String("composer".to_string())));
- repo_config.insert("url".to_string(), Box::new(PhpMixed::String("https://packagist.org".to_string())));
+ repo_config.insert(
+ "type".to_string(),
+ Box::new(PhpMixed::String("composer".to_string())),
+ );
+ repo_config.insert(
+ "url".to_string(),
+ Box::new(PhpMixed::String("https://packagist.org".to_string())),
+ );
repo_set.add_repository(Box::new(ComposerRepository::new(
PhpMixed::Array(repo_config),
Box::new(NullIO::new()),
@@ -750,11 +893,20 @@ impl DiagnoseCommand {
&IndexMap::new(),
) {
Ok(r) => r,
- Err(e) => return Ok(PhpMixed::String(format!("<highlight>Failed performing audit: {}</>", e.to_string()))),
+ Err(e) => {
+ return Ok(PhpMixed::String(format!(
+ "<highlight>Failed performing audit: {}</>",
+ e.to_string()
+ )));
+ }
};
if result > 0 {
- return Ok(PhpMixed::String(format!("<highlight>Audit found some issues:</>{}{}", PHP_EOL, io.get_output())));
+ return Ok(PhpMixed::String(format!(
+ "<highlight>Audit found some issues:</>{}{}",
+ PHP_EOL,
+ io.get_output()
+ )));
}
Ok(PhpMixed::Bool(true))
@@ -768,20 +920,51 @@ impl DiagnoseCommand {
let version = curl_version();
let version_arr = version.as_array().cloned().unwrap_or_default();
- let libz_version = version_arr.get("libz_version").and_then(|v| v.as_string()).filter(|s| !s.is_empty()).unwrap_or("missing").to_string();
- let brotli_version = version_arr.get("brotli_version").and_then(|v| v.as_string()).filter(|s| !s.is_empty()).unwrap_or("missing").to_string();
- let ssl_version = version_arr.get("ssl_version").and_then(|v| v.as_string()).filter(|s| !s.is_empty()).unwrap_or("missing").to_string();
- let features = version_arr.get("features").and_then(|v| v.as_int()).unwrap_or(0);
- let has_zstd = features != 0 && defined("CURL_VERSION_ZSTD") && 0 != (features & CURL_VERSION_ZSTD);
+ let libz_version = version_arr
+ .get("libz_version")
+ .and_then(|v| v.as_string())
+ .filter(|s| !s.is_empty())
+ .unwrap_or("missing")
+ .to_string();
+ let brotli_version = version_arr
+ .get("brotli_version")
+ .and_then(|v| v.as_string())
+ .filter(|s| !s.is_empty())
+ .unwrap_or("missing")
+ .to_string();
+ let ssl_version = version_arr
+ .get("ssl_version")
+ .and_then(|v| v.as_string())
+ .filter(|s| !s.is_empty())
+ .unwrap_or("missing")
+ .to_string();
+ let features = version_arr
+ .get("features")
+ .and_then(|v| v.as_int())
+ .unwrap_or(0);
+ let has_zstd = features != 0
+ && defined("CURL_VERSION_ZSTD")
+ && 0 != (features & CURL_VERSION_ZSTD);
let mut http_versions = "1.0, 1.1".to_string();
- if features != 0 && defined("CURL_VERSION_HTTP2") && defined("CURL_HTTP_VERSION_2_0") && (CURL_VERSION_HTTP2 & features) != 0 {
+ if features != 0
+ && defined("CURL_VERSION_HTTP2")
+ && defined("CURL_HTTP_VERSION_2_0")
+ && (CURL_VERSION_HTTP2 & features) != 0
+ {
http_versions.push_str(", 2");
}
- if features != 0 && defined("CURL_VERSION_HTTP3") && (features & CURL_VERSION_HTTP3) != 0 {
+ if features != 0
+ && defined("CURL_VERSION_HTTP3")
+ && (features & CURL_VERSION_HTTP3) != 0
+ {
http_versions.push_str(", 3");
}
- let curl_version_str = version_arr.get("version").and_then(|v| v.as_string()).unwrap_or("").to_string();
+ let curl_version_str = version_arr
+ .get("version")
+ .and_then(|v| v.as_string())
+ .unwrap_or("")
+ .to_string();
return format!(
"<comment>{}</comment> libz <comment>{}</comment> brotli <comment>{}</comment> zstd <comment>{}</comment> ssl <comment>{}</comment> HTTP <comment>{}</comment>",
curl_version_str,
@@ -876,12 +1059,18 @@ impl DiagnoseCommand {
errors.insert("iconv_mbstring".to_string(), PhpMixed::Bool(true));
}
- if !filter_var(&ini_get("allow_url_fopen"), FILTER_VALIDATE_BOOLEAN).as_bool().unwrap_or(false) {
+ if !filter_var(&ini_get("allow_url_fopen"), FILTER_VALIDATE_BOOLEAN)
+ .as_bool()
+ .unwrap_or(false)
+ {
errors.insert("allow_url_fopen".to_string(), PhpMixed::Bool(true));
}
if extension_loaded("ionCube Loader") && ioncube_loader_iversion() < 40009 {
- errors.insert("ioncube".to_string(), PhpMixed::String(ioncube_loader_version()));
+ errors.insert(
+ "ioncube".to_string(),
+ PhpMixed::String(ioncube_loader_version()),
+ );
}
if PHP_VERSION_ID < 70205 {
@@ -898,7 +1087,9 @@ impl DiagnoseCommand {
if !defined("HHVM_VERSION")
&& !extension_loaded("apcu")
- && filter_var(&ini_get("apc.enable_cli"), FILTER_VALIDATE_BOOLEAN).as_bool().unwrap_or(false)
+ && filter_var(&ini_get("apc.enable_cli"), FILTER_VALIDATE_BOOLEAN)
+ .as_bool()
+ .unwrap_or(false)
{
warnings.insert("apc_cli".to_string(), PhpMixed::Bool(true));
}
@@ -930,7 +1121,10 @@ impl DiagnoseCommand {
}
}
- if filter_var(&ini_get("xdebug.profiler_enabled"), FILTER_VALIDATE_BOOLEAN).as_bool().unwrap_or(false) {
+ if filter_var(&ini_get("xdebug.profiler_enabled"), FILTER_VALIDATE_BOOLEAN)
+ .as_bool()
+ .unwrap_or(false)
+ {
warnings.insert("xdebug_profile".to_string(), PhpMixed::Bool(true));
} else if XdebugHandler::is_xdebug_active() {
warnings.insert("xdebug_loaded".to_string(), PhpMixed::Bool(true));
@@ -942,12 +1136,19 @@ impl DiagnoseCommand {
&& version_compare(PHP_VERSION, "7.3.10", "<")))
{
let _ = PHP_WINDOWS_VERSION_BUILD;
- warnings.insert("onedrive".to_string(), PhpMixed::String(PHP_VERSION.to_string()));
+ warnings.insert(
+ "onedrive".to_string(),
+ PhpMixed::String(PHP_VERSION.to_string()),
+ );
}
if extension_loaded("uopz")
- && !(filter_var(&ini_get("uopz.disable"), FILTER_VALIDATE_BOOLEAN).as_bool().unwrap_or(false)
- || filter_var(&ini_get("uopz.exit"), FILTER_VALIDATE_BOOLEAN).as_bool().unwrap_or(false))
+ && !(filter_var(&ini_get("uopz.disable"), FILTER_VALIDATE_BOOLEAN)
+ .as_bool()
+ .unwrap_or(false)
+ || filter_var(&ini_get("uopz.exit"), FILTER_VALIDATE_BOOLEAN)
+ .as_bool()
+ .unwrap_or(false))
{
warnings.insert("uopz".to_string(), PhpMixed::Bool(true));
}
@@ -959,11 +1160,26 @@ impl DiagnoseCommand {
if !errors.is_empty() {
for (error, current) in &errors {
let text = match error.as_str() {
- "json" => format!("{}The json extension is missing.{}Install it or recompile php without --disable-json", PHP_EOL, PHP_EOL),
- "phar" => format!("{}The phar extension is missing.{}Install it or recompile php without --disable-phar", PHP_EOL, PHP_EOL),
- "filter" => format!("{}The filter extension is missing.{}Install it or recompile php without --disable-filter", PHP_EOL, PHP_EOL),
- "hash" => format!("{}The hash extension is missing.{}Install it or recompile php without --disable-hash", PHP_EOL, PHP_EOL),
- "iconv_mbstring" => format!("{}The iconv OR mbstring extension is required and both are missing.{}Install either of them or recompile php without --disable-iconv", PHP_EOL, PHP_EOL),
+ "json" => format!(
+ "{}The json extension is missing.{}Install it or recompile php without --disable-json",
+ PHP_EOL, PHP_EOL
+ ),
+ "phar" => format!(
+ "{}The phar extension is missing.{}Install it or recompile php without --disable-phar",
+ PHP_EOL, PHP_EOL
+ ),
+ "filter" => format!(
+ "{}The filter extension is missing.{}Install it or recompile php without --disable-filter",
+ PHP_EOL, PHP_EOL
+ ),
+ "hash" => format!(
+ "{}The hash extension is missing.{}Install it or recompile php without --disable-hash",
+ PHP_EOL, PHP_EOL
+ ),
+ "iconv_mbstring" => format!(
+ "{}The iconv OR mbstring extension is required and both are missing.{}Install either of them or recompile php without --disable-iconv",
+ PHP_EOL, PHP_EOL
+ ),
"php" => format!(
"{}Your PHP ({}) is too old, you must upgrade to PHP 7.2.5 or higher.",
PHP_EOL,
@@ -1034,7 +1250,8 @@ impl DiagnoseCommand {
),
"openssl_version" => {
// Attempt to parse version number out, fallback to whole string value.
- let openssl_trimmed = trim(&strstr(OPENSSL_VERSION_TEXT, " ", false), " \t\n\r\0\u{0B}");
+ let openssl_trimmed =
+ trim(&strstr(OPENSSL_VERSION_TEXT, " ", false), " \t\n\r\0\u{0B}");
let mut openssl_version = strstr(&openssl_trimmed, " ", true);
if openssl_version.is_empty() {
openssl_version = OPENSSL_VERSION_TEXT.to_string();
@@ -1107,8 +1324,12 @@ impl DiagnoseCommand {
/// Check if allow_url_fopen is ON
fn check_connectivity(&self) -> PhpMixed {
- if !ini_get("allow_url_fopen").parse::<bool>().unwrap_or(false) && ini_get("allow_url_fopen") != "1" {
- return PhpMixed::String("<info>SKIP</> <comment>Because allow_url_fopen is missing.</>".to_string());
+ if !ini_get("allow_url_fopen").parse::<bool>().unwrap_or(false)
+ && ini_get("allow_url_fopen") != "1"
+ {
+ return PhpMixed::String(
+ "<info>SKIP</> <comment>Because allow_url_fopen is missing.</>".to_string(),
+ );
}
PhpMixed::Bool(true)
@@ -1130,8 +1351,14 @@ impl DiagnoseCommand {
/// Check if Composer network is enabled for HTTP/S
fn check_composer_network_http_enablement(&self) -> PhpMixed {
- if Platform::get_env("COMPOSER_DISABLE_NETWORK").map(|v| !v.is_empty() && v != "0").unwrap_or(false) {
- return PhpMixed::String("<info>SKIP</> <comment>Network is disabled by COMPOSER_DISABLE_NETWORK.</>".to_string());
+ if Platform::get_env("COMPOSER_DISABLE_NETWORK")
+ .map(|v| !v.is_empty() && v != "0")
+ .unwrap_or(false)
+ {
+ return PhpMixed::String(
+ "<info>SKIP</> <comment>Network is disabled by COMPOSER_DISABLE_NETWORK.</>"
+ .to_string(),
+ );
}
PhpMixed::Bool(true)
diff --git a/crates/shirabe/src/command/dump_autoload_command.rs b/crates/shirabe/src/command/dump_autoload_command.rs
index 7341124..295f1c0 100644
--- a/crates/shirabe/src/command/dump_autoload_command.rs
+++ b/crates/shirabe/src/command/dump_autoload_command.rs
@@ -3,7 +3,7 @@
use anyhow::Result;
use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
-use shirabe_php_shim::{file_exists, InvalidArgumentException, PhpMixed};
+use shirabe_php_shim::{InvalidArgumentException, PhpMixed, file_exists};
use crate::command::base_command::BaseCommand;
use crate::console::input::input_option::InputOption;
@@ -52,7 +52,9 @@ impl DumpAutoloadCommand {
vec![],
vec![],
);
- composer.get_event_dispatcher().dispatch(command_event.get_name(), &command_event);
+ composer
+ .get_event_dispatcher()
+ .dispatch(command_event.get_name(), &command_event);
let installation_manager = composer.get_installation_manager();
let local_repo = composer.get_repository_manager().get_local_repository();
@@ -71,21 +73,37 @@ impl DumpAutoloadCommand {
let optimize = input.get_option("optimize").as_bool().unwrap_or(false)
|| config.get("optimize-autoloader").as_bool().unwrap_or(false);
- let authoritative = input.get_option("classmap-authoritative").as_bool().unwrap_or(false)
- || config.get("classmap-authoritative").as_bool().unwrap_or(false);
- let apcu_prefix = input.get_option("apcu-prefix").as_string_opt().map(|s| s.to_string());
+ let authoritative = input
+ .get_option("classmap-authoritative")
+ .as_bool()
+ .unwrap_or(false)
+ || config
+ .get("classmap-authoritative")
+ .as_bool()
+ .unwrap_or(false);
+ let apcu_prefix = input
+ .get_option("apcu-prefix")
+ .as_string_opt()
+ .map(|s| s.to_string());
let apcu = apcu_prefix.is_some()
|| input.get_option("apcu").as_bool().unwrap_or(false)
|| config.get("apcu-autoloader").as_bool().unwrap_or(false);
- if input.get_option("strict-psr").as_bool().unwrap_or(false) && !optimize && !authoritative {
+ if input.get_option("strict-psr").as_bool().unwrap_or(false) && !optimize && !authoritative
+ {
return Err(InvalidArgumentException {
message: "--strict-psr mode only works with optimized autoloader, use --optimize or --classmap-authoritative if you want a strict return value.".to_string(),
code: 0,
}
.into());
}
- if input.get_option("strict-ambiguous").as_bool().unwrap_or(false) && !optimize && !authoritative {
+ if input
+ .get_option("strict-ambiguous")
+ .as_bool()
+ .unwrap_or(false)
+ && !optimize
+ && !authoritative
+ {
return Err(InvalidArgumentException {
message: "--strict-ambiguous mode only works with optimized autoloader, use --optimize or --classmap-authoritative if you want a strict return value.".to_string(),
code: 0,
@@ -94,11 +112,17 @@ impl DumpAutoloadCommand {
}
if authoritative {
- self.inner.get_io().write("<info>Generating optimized autoload files (authoritative)</info>");
+ self.inner
+ .get_io()
+ .write("<info>Generating optimized autoload files (authoritative)</info>");
} else if optimize {
- self.inner.get_io().write("<info>Generating optimized autoload files</info>");
+ self.inner
+ .get_io()
+ .write("<info>Generating optimized autoload files</info>");
} else {
- self.inner.get_io().write("<info>Generating autoload files</info>");
+ self.inner
+ .get_io()
+ .write("<info>Generating autoload files</info>");
}
let generator = composer.get_autoload_generator();
@@ -111,7 +135,9 @@ impl DumpAutoloadCommand {
if input.get_option("dev").as_bool().unwrap_or(false) {
if input.get_option("no-dev").as_bool().unwrap_or(false) {
return Err(InvalidArgumentException {
- message: "You can not use both --no-dev and --dev as they conflict with each other.".to_string(),
+ message:
+ "You can not use both --no-dev and --dev as they conflict with each other."
+ .to_string(),
code: 0,
}
.into());
@@ -121,7 +147,8 @@ impl DumpAutoloadCommand {
generator.set_class_map_authoritative(authoritative);
generator.set_run_scripts(true);
generator.set_apcu(apcu, apcu_prefix.as_deref());
- generator.set_platform_requirement_filter(self.inner.get_platform_requirement_filter(input)?);
+ generator
+ .set_platform_requirement_filter(self.inner.get_platform_requirement_filter(input)?);
let class_map = generator.dump(
config,
&local_repo,
@@ -131,23 +158,39 @@ impl DumpAutoloadCommand {
optimize,
None,
composer.get_locker(),
- input.get_option("strict-ambiguous").as_bool().unwrap_or(false),
+ input
+ .get_option("strict-ambiguous")
+ .as_bool()
+ .unwrap_or(false),
)?;
let number_of_classes = class_map.len();
if authoritative {
self.inner.get_io().write(&format!("<info>Generated optimized autoload files (authoritative) containing {} classes</info>", number_of_classes));
} else if optimize {
- self.inner.get_io().write(&format!("<info>Generated optimized autoload files containing {} classes</info>", number_of_classes));
+ self.inner.get_io().write(&format!(
+ "<info>Generated optimized autoload files containing {} classes</info>",
+ number_of_classes
+ ));
} else {
- self.inner.get_io().write("<info>Generated autoload files</info>");
+ self.inner
+ .get_io()
+ .write("<info>Generated autoload files</info>");
}
- if missing_dependencies || (input.get_option("strict-psr").as_bool().unwrap_or(false) && !class_map.get_psr_violations().is_empty()) {
+ if missing_dependencies
+ || (input.get_option("strict-psr").as_bool().unwrap_or(false)
+ && !class_map.get_psr_violations().is_empty())
+ {
return Ok(1);
}
- if input.get_option("strict-ambiguous").as_bool().unwrap_or(false) && !class_map.get_ambiguous_classes(false).is_empty() {
+ if input
+ .get_option("strict-ambiguous")
+ .as_bool()
+ .unwrap_or(false)
+ && !class_map.get_ambiguous_classes(false).is_empty()
+ {
return Ok(2);
}
diff --git a/crates/shirabe/src/command/exec_command.rs b/crates/shirabe/src/command/exec_command.rs
index 432e3a0..5602e85 100644
--- a/crates/shirabe/src/command/exec_command.rs
+++ b/crates/shirabe/src/command/exec_command.rs
@@ -3,7 +3,7 @@
use anyhow::Result;
use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
-use shirabe_php_shim::{basename, chdir, getcwd, glob, PhpMixed, RuntimeException};
+use shirabe_php_shim::{PhpMixed, RuntimeException, basename, chdir, getcwd, glob};
use crate::command::base_command::BaseCommand;
use crate::console::input::input_argument::InputArgument;
@@ -43,13 +43,19 @@ impl ExecCommand {
);
}
- pub fn interact(&self, input: &mut dyn InputInterface, _output: &dyn OutputInterface) -> Result<()> {
+ pub fn interact(
+ &self,
+ input: &mut dyn InputInterface,
+ _output: &dyn OutputInterface,
+ ) -> Result<()> {
let binaries = self.get_binaries(false)?;
if binaries.is_empty() {
return Ok(());
}
- if input.get_argument("binary").as_string_opt().is_some() || input.get_option("list").as_bool().unwrap_or(false) {
+ if input.get_argument("binary").as_string_opt().is_some()
+ || input.get_option("list").as_bool().unwrap_or(false)
+ {
return Ok(());
}
@@ -70,45 +76,77 @@ impl ExecCommand {
Ok(())
}
- pub fn execute(&self, input: &dyn InputInterface, _output: &dyn OutputInterface) -> Result<i64> {
+ pub fn execute(
+ &self,
+ input: &dyn InputInterface,
+ _output: &dyn OutputInterface,
+ ) -> Result<i64> {
let composer = self.inner.require_composer()?;
- if input.get_option("list").as_bool().unwrap_or(false) || input.get_argument("binary").as_string_opt().is_none() {
+ if input.get_option("list").as_bool().unwrap_or(false)
+ || input.get_argument("binary").as_string_opt().is_none()
+ {
let bins = self.get_binaries(true)?;
if bins.is_empty() {
- let bin_dir = composer.get_config().get("bin-dir").as_string().unwrap_or("").to_string();
+ let bin_dir = composer
+ .get_config()
+ .get("bin-dir")
+ .as_string()
+ .unwrap_or("")
+ .to_string();
return Err(RuntimeException {
- message: format!("No binaries found in composer.json or in bin-dir ({})", bin_dir),
+ message: format!(
+ "No binaries found in composer.json or in bin-dir ({})",
+ bin_dir
+ ),
code: 0,
}
.into());
}
- self.inner.get_io().write("<comment>Available binaries:</comment>");
+ self.inner
+ .get_io()
+ .write("<comment>Available binaries:</comment>");
for bin in &bins {
- self.inner.get_io().write(&format!("<info>- {}</info>", bin));
+ self.inner
+ .get_io()
+ .write(&format!("<info>- {}</info>", bin));
}
return Ok(0);
}
- let binary = input.get_argument("binary").as_string().unwrap_or("").to_string();
+ let binary = input
+ .get_argument("binary")
+ .as_string()
+ .unwrap_or("")
+ .to_string();
let dispatcher = composer.get_event_dispatcher();
dispatcher.add_listener("__exec_command", &binary);
- let initial_working_directory = self.inner.get_application().get_initial_working_directory();
+ let initial_working_directory =
+ self.inner.get_application().get_initial_working_directory();
if let Some(ref iwd) = initial_working_directory {
if getcwd().as_deref() != Some(iwd.as_str()) {
- chdir(iwd).map_err(|e| {
- RuntimeException { message: format!("Could not switch back to working directory \"{}\"", iwd.display()), code: 0 }
+ chdir(iwd).map_err(|e| RuntimeException {
+ message: format!(
+ "Could not switch back to working directory \"{}\"",
+ iwd.display()
+ ),
+ code: 0,
})?;
}
}
- let args = input.get_argument("args")
+ let args = input
+ .get_argument("args")
.as_list()
- .map(|l| l.iter().filter_map(|v| v.as_string().map(|s| s.to_string())).collect::<Vec<_>>())
+ .map(|l| {
+ l.iter()
+ .filter_map(|v| v.as_string().map(|s| s.to_string()))
+ .collect::<Vec<_>>()
+ })
.unwrap_or_default();
Ok(dispatcher.dispatch_script("__exec_command", true, args)?)
@@ -116,11 +154,19 @@ impl ExecCommand {
fn get_binaries(&self, for_display: bool) -> Result<Vec<String>> {
let composer = self.inner.require_composer()?;
- let bin_dir = composer.get_config().get("bin-dir").as_string().unwrap_or("").to_string();
+ let bin_dir = composer
+ .get_config()
+ .get("bin-dir")
+ .as_string()
+ .unwrap_or("")
+ .to_string();
let bins = glob(&format!("{}/*", bin_dir));
let local_bins_raw: Vec<String> = composer.get_package().get_binaries();
let local_bins: Vec<String> = if for_display {
- local_bins_raw.into_iter().map(|e| format!("{} (local)", e)).collect()
+ local_bins_raw
+ .into_iter()
+ .map(|e| format!("{} (local)", e))
+ .collect()
} else {
local_bins_raw
};
diff --git a/crates/shirabe/src/command/fund_command.rs b/crates/shirabe/src/command/fund_command.rs
index 41b1805..398efd9 100644
--- a/crates/shirabe/src/command/fund_command.rs
+++ b/crates/shirabe/src/command/fund_command.rs
@@ -29,35 +29,63 @@ impl FundCommand {
self.inner
.set_name("fund")
.set_description("Discover how to help fund the maintenance of your dependencies")
- .set_definition(vec![
- InputOption::new("format", Some(PhpMixed::String("f".to_string())), Some(InputOption::VALUE_REQUIRED), "Format of the output: text or json", Some(PhpMixed::String("text".to_string())), vec!["text".to_string(), "json".to_string()]),
- ]);
+ .set_definition(vec![InputOption::new(
+ "format",
+ Some(PhpMixed::String("f".to_string())),
+ Some(InputOption::VALUE_REQUIRED),
+ "Format of the output: text or json",
+ Some(PhpMixed::String("text".to_string())),
+ vec!["text".to_string(), "json".to_string()],
+ )]);
}
- pub fn execute(&self, input: &dyn InputInterface, _output: &dyn OutputInterface) -> Result<i64> {
+ pub fn execute(
+ &self,
+ input: &dyn InputInterface,
+ _output: &dyn OutputInterface,
+ ) -> Result<i64> {
let composer = self.inner.require_composer()?;
let repo = composer.get_repository_manager().get_local_repository();
- let remote_repos = CompositeRepository::new(composer.get_repository_manager().get_repositories());
+ let remote_repos =
+ CompositeRepository::new(composer.get_repository_manager().get_repositories());
let mut fundings: IndexMap<String, IndexMap<String, Vec<String>>> = IndexMap::new();
let mut packages_to_load: IndexMap<String, Box<MatchAllConstraint>> = IndexMap::new();
for package in repo.get_packages() {
- if (package.as_any() as &dyn Any).downcast_ref::<AliasPackage>().is_some() {
+ if (package.as_any() as &dyn Any)
+ .downcast_ref::<AliasPackage>()
+ .is_some()
+ {
continue;
}
- packages_to_load.insert(package.get_name().to_string(), Box::new(MatchAllConstraint::new()));
+ packages_to_load.insert(
+ package.get_name().to_string(),
+ Box::new(MatchAllConstraint::new()),
+ );
}
// load all packages dev versions in parallel
- let result = remote_repos.load_packages(&packages_to_load, &IndexMap::from([("dev".to_string(), BasePackage::STABILITY_DEV)]), &IndexMap::new())?;
+ let result = remote_repos.load_packages(
+ &packages_to_load,
+ &IndexMap::from([("dev".to_string(), BasePackage::STABILITY_DEV)]),
+ &IndexMap::new(),
+ )?;
// collect funding data from default branches
for package in &result.packages {
- if (package.as_any() as &dyn Any).downcast_ref::<AliasPackage>().is_none() {
+ if (package.as_any() as &dyn Any)
+ .downcast_ref::<AliasPackage>()
+ .is_none()
+ {
// TODO: check for CompleteAliasPackage as well
- if let Some(complete_pkg) = (package.as_any() as &dyn Any).downcast_ref::<CompletePackage>() {
- if complete_pkg.is_default_branch() && !complete_pkg.get_funding().is_empty() && packages_to_load.contains_key(complete_pkg.get_name()) {
+ if let Some(complete_pkg) =
+ (package.as_any() as &dyn Any).downcast_ref::<CompletePackage>()
+ {
+ if complete_pkg.is_default_branch()
+ && !complete_pkg.get_funding().is_empty()
+ && packages_to_load.contains_key(complete_pkg.get_name())
+ {
Self::insert_funding_data(&mut fundings, complete_pkg)?;
packages_to_load.remove(complete_pkg.get_name());
}
@@ -67,11 +95,17 @@ impl FundCommand {
// collect funding from installed packages if none was found in the default branch above
for package in repo.get_packages() {
- if (package.as_any() as &dyn Any).downcast_ref::<AliasPackage>().is_some() || !packages_to_load.contains_key(package.get_name()) {
+ if (package.as_any() as &dyn Any)
+ .downcast_ref::<AliasPackage>()
+ .is_some()
+ || !packages_to_load.contains_key(package.get_name())
+ {
continue;
}
// TODO: check for CompleteAliasPackage as well
- if let Some(complete_pkg) = (package.as_any() as &dyn Any).downcast_ref::<CompletePackage>() {
+ if let Some(complete_pkg) =
+ (package.as_any() as &dyn Any).downcast_ref::<CompletePackage>()
+ {
if !complete_pkg.get_funding().is_empty() {
Self::insert_funding_data(&mut fundings, complete_pkg)?;
}
@@ -82,9 +116,16 @@ impl FundCommand {
let io = self.inner.get_io();
- let format = input.get_option("format").as_string().unwrap_or("text").to_string();
+ let format = input
+ .get_option("format")
+ .as_string()
+ .unwrap_or("text")
+ .to_string();
if !matches!(format.as_str(), "text" | "json") {
- io.write_error(&format!("Unsupported format \"{}\". See help for supported formats.", format));
+ io.write_error(&format!(
+ "Unsupported format \"{}\". See help for supported formats.",
+ format
+ ));
return Ok(1);
}
@@ -102,12 +143,18 @@ impl FundCommand {
io.write(&line);
prev = Some(line);
}
- io.write(&format!(" <href={}>{}</>", OutputFormatter::escape(url), url));
+ io.write(&format!(
+ " <href={}>{}</>",
+ OutputFormatter::escape(url),
+ url
+ ));
}
}
io.write("");
- io.write("Please consider following these links and sponsoring the work of package authors!");
+ io.write(
+ "Please consider following these links and sponsoring the work of package authors!",
+ );
io.write("Thank you!");
} else if format == "json" {
io.write(&JsonFile::encode(&fundings));
@@ -118,7 +165,10 @@ impl FundCommand {
Ok(0)
}
- fn insert_funding_data(fundings: &mut IndexMap<String, IndexMap<String, Vec<String>>>, package: &CompletePackage) -> Result<()> {
+ fn insert_funding_data(
+ fundings: &mut IndexMap<String, IndexMap<String, Vec<String>>>,
+ package: &CompletePackage,
+ ) -> Result<()> {
let pretty_name = package.get_pretty_name();
let (vendor, package_name) = pretty_name.split_once('/').unwrap_or(("", pretty_name));
@@ -128,15 +178,25 @@ impl FundCommand {
continue;
}
let mut url = url_val.unwrap().to_string();
- let r#type = funding_option.get("type").and_then(|v| v.as_string()).unwrap_or("");
+ let r#type = funding_option
+ .get("type")
+ .and_then(|v| v.as_string())
+ .unwrap_or("");
if r#type == "github" {
- if let Ok(Some(matches)) = Preg::is_match_with_indexed_captures(r"^https://github.com/([^/]+)$", &url) {
+ if let Ok(Some(matches)) =
+ Preg::is_match_with_indexed_captures(r"^https://github.com/([^/]+)$", &url)
+ {
if let Some(sponsor) = matches.into_iter().nth(1) {
url = format!("https://github.com/sponsors/{}", sponsor);
}
}
}
- fundings.entry(vendor.to_string()).or_default().entry(url).or_default().push(package_name.to_string());
+ fundings
+ .entry(vendor.to_string())
+ .or_default()
+ .entry(url)
+ .or_default()
+ .push(package_name.to_string());
}
Ok(())
}
diff --git a/crates/shirabe/src/command/global_command.rs b/crates/shirabe/src/command/global_command.rs
index 5dc22a3..695232c 100644
--- a/crates/shirabe/src/command/global_command.rs
+++ b/crates/shirabe/src/command/global_command.rs
@@ -9,7 +9,7 @@ use shirabe_external_packages::symfony::console::completion::completion_suggesti
use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
use shirabe_external_packages::symfony::console::input::string_input::StringInput;
use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
-use shirabe_php_shim::{chdir, LogicException, RuntimeException};
+use shirabe_php_shim::{LogicException, RuntimeException, chdir};
use crate::command::base_command::BaseCommand;
use crate::console::input::input_argument::InputArgument;
@@ -26,7 +26,8 @@ impl GlobalCommand {
pub fn complete(&self, input: &CompletionInput, suggestions: &mut CompletionSuggestions) {
let application = self.inner.get_application();
if input.must_suggest_argument_values_for("command-name") {
- let names: Vec<String> = application.all()
+ let names: Vec<String> = application
+ .all()
.into_iter()
.filter(|cmd| !cmd.is_hidden())
.filter_map(|cmd| cmd.get_name().map(|n| n.to_string()))
@@ -35,7 +36,11 @@ impl GlobalCommand {
return;
}
- let command_name = input.get_argument("command-name").as_string().unwrap_or("").to_string();
+ let command_name = input
+ .get_argument("command-name")
+ .as_string()
+ .unwrap_or("")
+ .to_string();
if application.has(&command_name) {
let sub_input = self.prepare_subcommand_input(input.as_input_interface(), true);
let sub_input = CompletionInput::from_string(&sub_input.to_string(), 2);
@@ -51,8 +56,20 @@ impl GlobalCommand {
.set_name("global")
.set_description("Allows running commands in the global composer dir ($COMPOSER_HOME)")
.set_definition(vec![
- InputArgument::new("command-name", Some(InputArgument::REQUIRED), "", None, vec![]),
- InputArgument::new("args", Some(InputArgument::IS_ARRAY | InputArgument::OPTIONAL), "", None, vec![]),
+ InputArgument::new(
+ "command-name",
+ Some(InputArgument::REQUIRED),
+ "",
+ None,
+ vec![],
+ ),
+ InputArgument::new(
+ "args",
+ Some(InputArgument::IS_ARRAY | InputArgument::OPTIONAL),
+ "",
+ None,
+ vec![],
+ ),
])
.set_help(
"Use this command as a wrapper to run other Composer commands\n\
@@ -65,7 +82,7 @@ impl GlobalCommand {
XDG_CONFIG_HOME or default to /home/<user>/.config/composer\n\n\
Note: This path may vary depending on customizations to bin-dir in\n\
composer.json or the environmental variable COMPOSER_BIN_DIR.\n\n\
- Read more at https://getcomposer.org/doc/03-cli.md#global"
+ Read more at https://getcomposer.org/doc/03-cli.md#global",
);
}
@@ -89,7 +106,11 @@ impl GlobalCommand {
Ok(self.inner.get_application().run(&sub_input, output)?)
}
- fn prepare_subcommand_input(&self, input: &dyn InputInterface, quiet: bool) -> Result<StringInput> {
+ fn prepare_subcommand_input(
+ &self,
+ input: &dyn InputInterface,
+ quiet: bool,
+ ) -> Result<StringInput> {
if Platform::get_env("COMPOSER").is_some() {
Platform::clear_env("COMPOSER");
}
@@ -104,17 +125,29 @@ impl GlobalCommand {
return Err(RuntimeException {
message: "Could not create home directory".to_string(),
code: 0,
- }.into());
+ }
+ .into());
}
}
- chdir(&home).map_err(|e| RuntimeException { message: format!("Could not switch to home directory \"{}\"", home), code: 0 })?;
+ chdir(&home).map_err(|e| RuntimeException {
+ message: format!("Could not switch to home directory \"{}\"", home),
+ code: 0,
+ })?;
if !quiet {
- self.inner.get_io().write_error(&format!("<info>Changed current directory to {}</info>", home));
+ self.inner.get_io().write_error(&format!(
+ "<info>Changed current directory to {}</info>",
+ home
+ ));
}
- let new_input_str = Preg::replace(r"{\bg(?:l(?:o(?:b(?:a(?:l)?)?)?)?)?\b}", "", &input.to_string(), 1)?;
+ let new_input_str = Preg::replace(
+ r"{\bg(?:l(?:o(?:b(?:a(?:l)?)?)?)?)?\b}",
+ "",
+ &input.to_string(),
+ 1,
+ )?;
self.inner.get_application().reset_composer();
Ok(StringInput::new(new_input_str))
diff --git a/crates/shirabe/src/command/home_command.rs b/crates/shirabe/src/command/home_command.rs
index 12ea759..142f868 100644
--- a/crates/shirabe/src/command/home_command.rs
+++ b/crates/shirabe/src/command/home_command.rs
@@ -3,7 +3,7 @@
use anyhow::Result;
use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
-use shirabe_php_shim::{filter_var, FILTER_VALIDATE_URL};
+use shirabe_php_shim::{FILTER_VALIDATE_URL, filter_var};
use crate::command::base_command::BaseCommand;
use crate::command::completion_trait::CompletionTrait;
@@ -37,31 +37,60 @@ impl HomeCommand {
None,
self.suggest_installed_package(),
),
- InputOption::new("homepage", Some(shirabe_php_shim::PhpMixed::String("H".to_string())), Some(InputOption::VALUE_NONE), "Open the homepage instead of the repository URL.", None, vec![]),
- InputOption::new("show", Some(shirabe_php_shim::PhpMixed::String("s".to_string())), Some(InputOption::VALUE_NONE), "Only show the homepage or repository URL.", None, vec![]),
+ InputOption::new(
+ "homepage",
+ Some(shirabe_php_shim::PhpMixed::String("H".to_string())),
+ Some(InputOption::VALUE_NONE),
+ "Open the homepage instead of the repository URL.",
+ None,
+ vec![],
+ ),
+ InputOption::new(
+ "show",
+ Some(shirabe_php_shim::PhpMixed::String("s".to_string())),
+ Some(InputOption::VALUE_NONE),
+ "Only show the homepage or repository URL.",
+ None,
+ vec![],
+ ),
])
.set_help(
"The home command opens or shows a package's repository URL or\n\
homepage in your default browser.\n\n\
To open the homepage by default, use -H or --homepage.\n\
To show instead of open the repository or homepage URL, use -s or --show.\n\n\
- Read more at https://getcomposer.org/doc/03-cli.md#browse-home"
+ Read more at https://getcomposer.org/doc/03-cli.md#browse-home",
);
}
- pub fn execute(&self, input: &dyn InputInterface, _output: &dyn OutputInterface) -> Result<i64> {
+ pub fn execute(
+ &self,
+ input: &dyn InputInterface,
+ _output: &dyn OutputInterface,
+ ) -> Result<i64> {
let repos = self.initialize_repos()?;
let io = self.inner.get_io();
let mut return_code: i64 = 0;
- let packages: Vec<String> = input.get_argument("packages")
+ let packages: Vec<String> = input
+ .get_argument("packages")
.as_list()
- .map(|l| l.iter().filter_map(|v| v.as_string().map(|s| s.to_string())).collect())
+ .map(|l| {
+ l.iter()
+ .filter_map(|v| v.as_string().map(|s| s.to_string()))
+ .collect()
+ })
.unwrap_or_default();
let packages = if packages.is_empty() {
io.write_error("No package specified, opening homepage for the root package");
- vec![self.inner.require_composer()?.get_package().get_name().to_string()]
+ vec![
+ self.inner
+ .require_composer()?
+ .get_package()
+ .get_name()
+ .to_string(),
+ ]
} else {
packages
};
@@ -87,12 +116,19 @@ impl HomeCommand {
if !package_exists {
return_code = 1;
- io.write_error(&format!("<warning>Package {} not found</warning>", package_name));
+ io.write_error(&format!(
+ "<warning>Package {} not found</warning>",
+ package_name
+ ));
}
if !handled {
return_code = 1;
- let msg = if show_homepage { "Invalid or missing homepage" } else { "Invalid or missing repository URL" };
+ let msg = if show_homepage {
+ "Invalid or missing homepage"
+ } else {
+ "Invalid or missing repository URL"
+ };
io.write_error(&format!("<warning>{} for {}</warning>", msg, package_name));
}
}
@@ -100,9 +136,17 @@ impl HomeCommand {
Ok(return_code)
}
- fn handle_package(&self, package: &dyn CompletePackageInterface, show_homepage: bool, show_only: bool) -> bool {
+ fn handle_package(
+ &self,
+ package: &dyn CompletePackageInterface,
+ show_homepage: bool,
+ show_only: bool,
+ ) -> bool {
let support = package.get_support();
- let mut url = support.get("source").and_then(|v| v.as_string()).map(|s| s.to_string())
+ let mut url = support
+ .get("source")
+ .and_then(|v| v.as_string())
+ .map(|s| s.to_string())
.or_else(|| package.get_source_url().map(|s| s.to_string()));
if url.as_deref().map_or(true, |s| s.is_empty()) || show_homepage {
url = package.get_homepage().map(|s| s.to_string());
@@ -143,7 +187,10 @@ impl HomeCommand {
} else if osx == 0 {
process.execute(&["open", url], None);
} else {
- io.write_error(&format!("No suitable browser opening command found, open yourself: {}", url));
+ io.write_error(&format!(
+ "No suitable browser opening command found, open yourself: {}",
+ url
+ ));
}
}
@@ -152,14 +199,20 @@ impl HomeCommand {
if let Some(composer) = composer {
let mut repos: Vec<Box<dyn RepositoryInterface>> = vec![];
- repos.push(Box::new(RootPackageRepository::new(composer.get_package().clone_package())));
- repos.push(Box::new(composer.get_repository_manager().get_local_repository()));
+ repos.push(Box::new(RootPackageRepository::new(
+ composer.get_package().clone_package(),
+ )));
+ repos.push(Box::new(
+ composer.get_repository_manager().get_local_repository(),
+ ));
for repo in composer.get_repository_manager().get_repositories() {
repos.push(repo);
}
return Ok(repos);
}
- Ok(RepositoryFactory::default_repos_with_default_manager(self.inner.get_io()))
+ Ok(RepositoryFactory::default_repos_with_default_manager(
+ self.inner.get_io(),
+ ))
}
}
diff --git a/crates/shirabe/src/command/init_command.rs b/crates/shirabe/src/command/init_command.rs
index 9e55092..e61b7a6 100644
--- a/crates/shirabe/src/command/init_command.rs
+++ b/crates/shirabe/src/command/init_command.rs
@@ -9,11 +9,11 @@ use shirabe_external_packages::symfony::component::console::input::array_input::
use shirabe_external_packages::symfony::component::console::input::input_interface::InputInterface;
use shirabe_external_packages::symfony::component::console::output::output_interface::OutputInterface;
use shirabe_php_shim::{
- array_filter, array_flip, array_intersect_key, array_keys, array_map, basename, empty,
- explode, file, file_exists, file_get_contents, file_put_contents, function_exists,
- get_current_user, implode, is_dir, is_string, preg_quote, realpath, server_get, sprintf,
- str_replace, strpos, strtolower, trim, ucwords, FILE_IGNORE_NEW_LINES, FILTER_VALIDATE_EMAIL,
- InvalidArgumentException, PhpMixed, PHP_EOL,
+ FILE_IGNORE_NEW_LINES, FILTER_VALIDATE_EMAIL, InvalidArgumentException, PHP_EOL, PhpMixed,
+ array_filter, array_flip, array_intersect_key, array_keys, array_map, basename, empty, explode,
+ file, file_exists, file_get_contents, file_put_contents, function_exists, get_current_user,
+ implode, is_dir, is_string, preg_quote, realpath, server_get, sprintf, str_replace, strpos,
+ strtolower, trim, ucwords,
};
use crate::command::base_command::BaseCommand;
@@ -95,13 +95,9 @@ impl InitCommand {
"autoload".to_string(),
];
let mut options = array_filter(
- &array_intersect_key(
- &input.get_options(),
- &array_flip(&allowlist),
- ),
+ &array_intersect_key(&input.get_options(), &array_flip(&allowlist)),
|val: &PhpMixed| {
- !matches!(val, PhpMixed::Null)
- && !matches!(val, PhpMixed::List(l) if l.is_empty())
+ !matches!(val, PhpMixed::Null) && !matches!(val, PhpMixed::List(l) if l.is_empty())
},
);
@@ -138,9 +134,7 @@ impl InitCommand {
.into_iter()
.map(|m| {
Box::new(PhpMixed::Array(
- m.into_iter()
- .map(|(k, v)| (k, Box::new(v)))
- .collect(),
+ m.into_iter().map(|(k, v)| (k, Box::new(v))).collect(),
))
})
.collect(),
@@ -250,10 +244,7 @@ impl InitCommand {
.to_string();
let namespace = self.namespace_from_package_name(&name).unwrap_or_default();
let mut psr4: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
- psr4.insert(
- format!("{}\\", namespace),
- Box::new(PhpMixed::String(ap)),
- );
+ psr4.insert(format!("{}\\", namespace), Box::new(PhpMixed::String(ap)));
let mut autoload_obj: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
autoload_obj.insert("psr-4".to_string(), Box::new(PhpMixed::Array(psr4)));
options.insert("autoload".to_string(), PhpMixed::Array(autoload_obj));
@@ -303,7 +294,9 @@ impl InitCommand {
// try to downcast to JsonValidationException
if let Some(json_err) = e.downcast_ref::<JsonValidationException>() {
io.write_error(
- PhpMixed::String("<error>Schema validation error, aborting</error>".to_string()),
+ PhpMixed::String(
+ "<error>Schema validation error, aborting</error>".to_string(),
+ ),
true,
IOInterface::NORMAL,
);
@@ -312,10 +305,7 @@ impl InitCommand {
implode(&format!("{} - ", PHP_EOL), &json_err.get_errors())
);
io.write_error(
- PhpMixed::String(format!(
- "{}:{}{}",
- json_err.message, PHP_EOL, errors
- )),
+ PhpMixed::String(format!("{}:{}{}", json_err.message, PHP_EOL, errors)),
true,
IOInterface::NORMAL,
);
@@ -356,7 +346,8 @@ impl InitCommand {
}
}
- let question = "Would you like to install dependencies now [<comment>yes</comment>]? ".to_string();
+ let question =
+ "Would you like to install dependencies now [<comment>yes</comment>]? ".to_string();
if input.is_interactive()
&& self.has_dependencies(&options)
&& io.ask_confirmation(question, true)
@@ -395,11 +386,7 @@ impl InitCommand {
Ok(0)
}
- pub(crate) fn initialize(
- &mut self,
- input: &dyn InputInterface,
- output: &dyn OutputInterface,
- ) {
+ pub(crate) fn initialize(&mut self, input: &dyn InputInterface, output: &dyn OutputInterface) {
self.inner.initialize(input, output);
if !input.is_interactive() {
@@ -442,16 +429,13 @@ impl InitCommand {
io.load_configuration(&config);
let mut repo_manager = RepositoryFactory::manager(io, &config, None, None);
- let mut repos: Vec<Box<dyn crate::repository::repository_interface::RepositoryInterface>> =
- vec![Box::new(PlatformRepository::new(vec![], PhpMixed::Null))];
+ let mut repos: Vec<
+ Box<dyn crate::repository::repository_interface::RepositoryInterface>,
+ > = vec![Box::new(PlatformRepository::new(vec![], PhpMixed::Null))];
let mut create_default_packagist_repo = true;
for repo in &repositories {
- let repo_config = RepositoryFactory::config_from_string(
- io,
- &config,
- repo,
- Some(true),
- )?;
+ let repo_config =
+ RepositoryFactory::config_from_string(io, &config, repo, Some(true))?;
let is_packagist_false = repo_config
.get("packagist")
.map(|v| v.as_bool() == Some(false))
@@ -476,10 +460,7 @@ impl InitCommand {
if create_default_packagist_repo {
let mut default_config: IndexMap<String, PhpMixed> = IndexMap::new();
- default_config.insert(
- "type".to_string(),
- PhpMixed::String("composer".to_string()),
- );
+ default_config.insert("type".to_string(), PhpMixed::String("composer".to_string()));
default_config.insert(
"url".to_string(),
PhpMixed::String("https://repo.packagist.org".to_string()),
@@ -672,9 +653,7 @@ impl InitCommand {
),
type_val,
);
- if type_value.as_string() == Some("")
- || matches!(type_value, PhpMixed::Bool(false))
- {
+ if type_value.as_string() == Some("") || matches!(type_value, PhpMixed::Bool(false)) {
type_value = PhpMixed::Null;
}
input.set_option("type", type_value);
@@ -820,7 +799,9 @@ impl InitCommand {
.as_string()
.unwrap_or("")
.to_string();
- let namespace = self.namespace_from_package_name(&name_str).unwrap_or_default();
+ let namespace = self
+ .namespace_from_package_name(&name_str)
+ .unwrap_or_default();
let autoload_for_validate = autoload.clone();
let autoload_default = autoload.clone();
let autoload_value = io.ask_and_validate(
@@ -869,7 +850,7 @@ impl InitCommand {
/// @return array{name: string, email: string|null}
fn parse_author_string(&self, author: &str) -> Result<IndexMap<String, Option<String>>> {
if let Some(m) = Preg::is_match_strict_groups(
- r"/^(?P<name>[- .,\p{L}\p{N}\p{Mn}\'’\"()]+)(?:\s+<(?P<email>.+?)>)?$/u",
+ r#"/^(?P<name>[- .,\p{L}\p{N}\p{Mn}\'’\"()]+)(?:\s+<(?P<email>.+?)>)?$/u"#,
author,
) {
let email = m.get("email").cloned();
@@ -902,10 +883,7 @@ impl InitCommand {
}
/// @return array<int, array{name: string, email?: string}>
- pub(crate) fn format_authors(
- &self,
- author: &str,
- ) -> Result<Vec<IndexMap<String, PhpMixed>>> {
+ pub(crate) fn format_authors(&self, author: &str) -> Result<Vec<IndexMap<String, PhpMixed>>> {
let parsed = self.parse_author_string(author)?;
let mut author_map: IndexMap<String, PhpMixed> = IndexMap::new();
let name = parsed.get("name").cloned().unwrap_or(None);
@@ -950,18 +928,13 @@ impl InitCommand {
let mut output = String::new();
if process.execute(
- &vec![
- "git".to_string(),
- "config".to_string(),
- "-l".to_string(),
- ],
+ &vec!["git".to_string(), "config".to_string(), "-l".to_string()],
&mut output,
None,
) == 0
{
self.git_config = Some(IndexMap::new());
- let matches =
- Preg::is_match_all_strict_groups(r"{^([^=]+)=(.*)$}m", &output);
+ let matches = Preg::is_match_all_strict_groups(r"{^([^=]+)=(.*)$}m", &output);
if let Some(m) = matches {
let keys: Vec<String> = m.get(1).cloned().unwrap_or_default();
let values: Vec<String> = m.get(2).cloned().unwrap_or_default();
@@ -1033,15 +1006,12 @@ impl InitCommand {
fn update_dependencies(&self, output: &dyn OutputInterface) {
// PHP try/catch: catch \Exception
- let result = self
- .inner
- .get_application()
- .and_then(|app| {
- let update_command = app.find("update")?;
- app.reset_composer()?;
- update_command.run(ArrayInput::new(IndexMap::new()), output)?;
- Ok(())
- });
+ let result = self.inner.get_application().and_then(|app| {
+ let update_command = app.find("update")?;
+ app.reset_composer()?;
+ update_command.run(ArrayInput::new(IndexMap::new()), output)?;
+ Ok(())
+ });
if let Err(_e) = result {
self.inner.get_io().write_error(
PhpMixed::String(
@@ -1055,15 +1025,12 @@ impl InitCommand {
}
fn run_dump_autoload_command(&self, output: &dyn OutputInterface) {
- let result = self
- .inner
- .get_application()
- .and_then(|app| {
- let command = app.find("dump-autoload")?;
- app.reset_composer()?;
- command.run(ArrayInput::new(IndexMap::new()), output)?;
- Ok(())
- });
+ let result = self.inner.get_application().and_then(|app| {
+ let command = app.find("dump-autoload")?;
+ app.reset_composer()?;
+ command.run(ArrayInput::new(IndexMap::new()), output)?;
+ Ok(())
+ });
if let Err(_e) = result {
self.inner.get_io().write_error(
PhpMixed::String("Could not run dump-autoload.".to_string()),
diff --git a/crates/shirabe/src/command/install_command.rs b/crates/shirabe/src/command/install_command.rs
index 8302137..264b58c 100644
--- a/crates/shirabe/src/command/install_command.rs
+++ b/crates/shirabe/src/command/install_command.rs
@@ -74,8 +74,13 @@ impl InstallCommand {
}
let args = input.get_argument("packages");
- let args_vec: Vec<String> = args.as_list()
- .map(|l| l.iter().filter_map(|v| v.as_string().map(|s| s.to_string())).collect())
+ let args_vec: Vec<String> = args
+ .as_list()
+ .map(|l| {
+ l.iter()
+ .filter_map(|v| v.as_string().map(|s| s.to_string()))
+ .collect()
+ })
.unwrap_or_default();
if !args_vec.is_empty() {
io.write_error(&format!(
@@ -106,23 +111,43 @@ impl InstallCommand {
vec![],
vec![],
);
- composer.get_event_dispatcher().dispatch(command_event.get_name(), &command_event);
+ composer
+ .get_event_dispatcher()
+ .dispatch(command_event.get_name(), &command_event);
let install = Installer::create(io, &composer);
let config = composer.get_config();
- let (prefer_source, prefer_dist) = self.inner.get_preferred_install_options(config, input)?;
+ let (prefer_source, prefer_dist) =
+ self.inner.get_preferred_install_options(config, input)?;
- let optimize = input.get_option("optimize-autoloader").as_bool().unwrap_or(false)
+ let optimize = input
+ .get_option("optimize-autoloader")
+ .as_bool()
+ .unwrap_or(false)
|| config.get("optimize-autoloader").as_bool().unwrap_or(false);
- let authoritative = input.get_option("classmap-authoritative").as_bool().unwrap_or(false)
- || config.get("classmap-authoritative").as_bool().unwrap_or(false);
- let apcu_prefix = input.get_option("apcu-autoloader-prefix").as_string_opt().map(|s| s.to_string());
+ let authoritative = input
+ .get_option("classmap-authoritative")
+ .as_bool()
+ .unwrap_or(false)
+ || config
+ .get("classmap-authoritative")
+ .as_bool()
+ .unwrap_or(false);
+ let apcu_prefix = input
+ .get_option("apcu-autoloader-prefix")
+ .as_string_opt()
+ .map(|s| s.to_string());
let apcu = apcu_prefix.is_some()
- || input.get_option("apcu-autoloader").as_bool().unwrap_or(false)
+ || input
+ .get_option("apcu-autoloader")
+ .as_bool()
+ .unwrap_or(false)
|| config.get("apcu-autoloader").as_bool().unwrap_or(false);
- composer.get_installation_manager().set_output_progress(!input.get_option("no-progress").as_bool().unwrap_or(false));
+ composer
+ .get_installation_manager()
+ .set_output_progress(!input.get_option("no-progress").as_bool().unwrap_or(false));
install
.set_dry_run(input.get_option("dry-run").as_bool().unwrap_or(false))
@@ -136,7 +161,10 @@ impl InstallCommand {
.set_class_map_authoritative(authoritative)
.set_apcu_autoloader(apcu, apcu_prefix.as_deref())
.set_platform_requirement_filter(self.inner.get_platform_requirement_filter(input)?)
- .set_audit_config(self.inner.create_audit_config(composer.get_config(), input)?)
+ .set_audit_config(
+ self.inner
+ .create_audit_config(composer.get_config(), input)?,
+ )
.set_error_on_audit(input.get_option("audit").as_bool().unwrap_or(false));
if input.get_option("no-plugins").as_bool().unwrap_or(false) {
diff --git a/crates/shirabe/src/command/licenses_command.rs b/crates/shirabe/src/command/licenses_command.rs
index 84cbff6..ddb7b32 100644
--- a/crates/shirabe/src/command/licenses_command.rs
+++ b/crates/shirabe/src/command/licenses_command.rs
@@ -33,16 +33,41 @@ impl LicensesCommand {
.set_name("licenses")
.set_description("Shows information about licenses of dependencies")
.set_definition(vec![
- InputOption::new("format", Some(PhpMixed::String("f".to_string())), Some(InputOption::VALUE_REQUIRED), "Format of the output: text, json or summary", Some(PhpMixed::String("text".to_string())), vec!["text".to_string(), "json".to_string(), "summary".to_string()]),
- InputOption::new("no-dev", None, Some(InputOption::VALUE_NONE), "Disables search in require-dev packages.", None, vec![]),
- InputOption::new("locked", None, Some(InputOption::VALUE_NONE), "Shows licenses from the lock file instead of installed packages.", None, vec![]),
+ InputOption::new(
+ "format",
+ Some(PhpMixed::String("f".to_string())),
+ Some(InputOption::VALUE_REQUIRED),
+ "Format of the output: text, json or summary",
+ Some(PhpMixed::String("text".to_string())),
+ vec![
+ "text".to_string(),
+ "json".to_string(),
+ "summary".to_string(),
+ ],
+ ),
+ InputOption::new(
+ "no-dev",
+ None,
+ Some(InputOption::VALUE_NONE),
+ "Disables search in require-dev packages.",
+ None,
+ vec![],
+ ),
+ InputOption::new(
+ "locked",
+ None,
+ Some(InputOption::VALUE_NONE),
+ "Shows licenses from the lock file instead of installed packages.",
+ None,
+ vec![],
+ ),
])
.set_help(
"The license command displays detailed information about the licenses of\n\
the installed dependencies.\n\n\
Use --locked to show licenses from composer.lock instead of what's currently\n\
installed in the vendor directory.\n\n\
- Read more at https://getcomposer.org/doc/03-cli.md#licenses"
+ Read more at https://getcomposer.org/doc/03-cli.md#licenses",
);
}
@@ -50,8 +75,11 @@ impl LicensesCommand {
let composer = self.inner.require_composer()?;
// TODO(plugin): dispatch COMMAND event for plugin hooks
- let command_event = CommandEvent::new(PluginEvents::COMMAND, "licenses".to_string(), input, output);
- composer.get_event_dispatcher().dispatch(command_event.get_name(), &command_event);
+ let command_event =
+ CommandEvent::new(PluginEvents::COMMAND, "licenses".to_string(), input, output);
+ composer
+ .get_event_dispatcher()
+ .dispatch(command_event.get_name(), &command_event);
let root = composer.get_package();
@@ -78,7 +106,11 @@ impl LicensesCommand {
let packages = PackageSorter::sort_packages_alphabetically(packages);
let io = self.inner.get_io();
- let format = input.get_option("format").as_string().unwrap_or("text").to_string();
+ let format = input
+ .get_option("format")
+ .as_string()
+ .unwrap_or("text")
+ .to_string();
match format.as_str() {
"text" => {
let root_licenses = root.get_license();
@@ -87,23 +119,39 @@ impl LicensesCommand {
} else {
root_licenses.join(", ")
};
- io.write(&format!("Name: <comment>{}</comment>", root.get_pretty_name()));
- io.write(&format!("Version: <comment>{}</comment>", root.get_full_pretty_version()));
+ io.write(&format!(
+ "Name: <comment>{}</comment>",
+ root.get_pretty_name()
+ ));
+ io.write(&format!(
+ "Version: <comment>{}</comment>",
+ root.get_full_pretty_version()
+ ));
io.write(&format!("Licenses: <comment>{}</comment>", licenses_str));
io.write("Dependencies:");
io.write("");
let mut table = Table::new(output);
table.set_style("compact");
- table.set_headers(vec!["Name".to_string(), "Version".to_string(), "Licenses".to_string()]);
+ table.set_headers(vec![
+ "Name".to_string(),
+ "Version".to_string(),
+ "Licenses".to_string(),
+ ]);
for package in &packages {
let link = PackageInfo::get_view_source_or_homepage_url(package.as_ref());
let name = if let Some(link) = link {
- format!("<href={}>{}</>", OutputFormatter::escape(&link), package.get_pretty_name())
+ format!(
+ "<href={}>{}</>",
+ OutputFormatter::escape(&link),
+ package.get_pretty_name()
+ )
} else {
package.get_pretty_name().to_string()
};
- let pkg_licenses = if let Some(complete_pkg) = (package.as_any() as &dyn Any).downcast_ref::<CompletePackage>() {
+ let pkg_licenses = if let Some(complete_pkg) =
+ (package.as_any() as &dyn Any).downcast_ref::<CompletePackage>()
+ {
complete_pkg.get_license()
} else {
vec![]
@@ -113,40 +161,85 @@ impl LicensesCommand {
} else {
pkg_licenses.join(", ")
};
- table.add_row(vec![name, package.get_full_pretty_version().to_string(), licenses_str]);
+ table.add_row(vec![
+ name,
+ package.get_full_pretty_version().to_string(),
+ licenses_str,
+ ]);
}
table.render();
}
"json" => {
- let mut dependencies: IndexMap<String, IndexMap<String, PhpMixed>> = IndexMap::new();
+ let mut dependencies: IndexMap<String, IndexMap<String, PhpMixed>> =
+ IndexMap::new();
for package in &packages {
- let pkg_licenses = if let Some(complete_pkg) = (package.as_any() as &dyn Any).downcast_ref::<CompletePackage>() {
+ let pkg_licenses = if let Some(complete_pkg) =
+ (package.as_any() as &dyn Any).downcast_ref::<CompletePackage>()
+ {
complete_pkg.get_license()
} else {
vec![]
};
let mut dep_info: IndexMap<String, PhpMixed> = IndexMap::new();
- dep_info.insert("version".to_string(), PhpMixed::String(package.get_full_pretty_version().to_string()));
- dep_info.insert("license".to_string(), PhpMixed::List(pkg_licenses.into_iter().map(|l| Box::new(PhpMixed::String(l))).collect()));
+ dep_info.insert(
+ "version".to_string(),
+ PhpMixed::String(package.get_full_pretty_version().to_string()),
+ );
+ dep_info.insert(
+ "license".to_string(),
+ PhpMixed::List(
+ pkg_licenses
+ .into_iter()
+ .map(|l| Box::new(PhpMixed::String(l)))
+ .collect(),
+ ),
+ );
dependencies.insert(package.get_pretty_name().to_string(), dep_info);
}
let mut output_map: IndexMap<String, PhpMixed> = IndexMap::new();
- output_map.insert("name".to_string(), PhpMixed::String(root.get_pretty_name().to_string()));
- output_map.insert("version".to_string(), PhpMixed::String(root.get_full_pretty_version().to_string()));
+ output_map.insert(
+ "name".to_string(),
+ PhpMixed::String(root.get_pretty_name().to_string()),
+ );
+ output_map.insert(
+ "version".to_string(),
+ PhpMixed::String(root.get_full_pretty_version().to_string()),
+ );
let root_licenses = root.get_license();
- output_map.insert("license".to_string(), PhpMixed::List(root_licenses.into_iter().map(|l| Box::new(PhpMixed::String(l))).collect()));
- output_map.insert("dependencies".to_string(), PhpMixed::Array(
- dependencies.into_iter().map(|(k, v)| (k, Box::new(PhpMixed::Array(
- v.into_iter().map(|(k2, v2)| (k2, Box::new(v2))).collect()
- )))).collect()
- ));
+ output_map.insert(
+ "license".to_string(),
+ PhpMixed::List(
+ root_licenses
+ .into_iter()
+ .map(|l| Box::new(PhpMixed::String(l)))
+ .collect(),
+ ),
+ );
+ output_map.insert(
+ "dependencies".to_string(),
+ PhpMixed::Array(
+ dependencies
+ .into_iter()
+ .map(|(k, v)| {
+ (
+ k,
+ Box::new(PhpMixed::Array(
+ v.into_iter().map(|(k2, v2)| (k2, Box::new(v2))).collect(),
+ )),
+ )
+ })
+ .collect(),
+ ),
+ );
io.write(&JsonFile::encode(&output_map));
}
"summary" => {
let mut used_licenses: IndexMap<String, i64> = IndexMap::new();
for package in &packages {
- let mut licenses = if let Some(complete_pkg) = (package.as_any() as &dyn Any).downcast_ref::<CompletePackage>() {
+ let mut licenses = if let Some(complete_pkg) =
+ (package.as_any() as &dyn Any).downcast_ref::<CompletePackage>()
+ {
complete_pkg.get_license()
} else {
vec![]
@@ -162,7 +255,8 @@ impl LicensesCommand {
let mut entries: Vec<(String, i64)> = used_licenses.into_iter().collect();
entries.sort_by(|a, b| b.1.cmp(&a.1));
- let rows: Vec<Vec<String>> = entries.iter()
+ let rows: Vec<Vec<String>> = entries
+ .iter()
.map(|(license, count)| vec![license.clone(), count.to_string()])
.collect();
@@ -174,9 +268,13 @@ impl LicensesCommand {
}
_ => {
return Err(RuntimeException {
- message: format!("Unsupported format \"{}\". See help for supported formats.", format),
+ message: format!(
+ "Unsupported format \"{}\". See help for supported formats.",
+ format
+ ),
code: 0,
- }.into());
+ }
+ .into());
}
}
diff --git a/crates/shirabe/src/command/mod.rs b/crates/shirabe/src/command/mod.rs
new file mode 100644
index 0000000..9761805
--- /dev/null
+++ b/crates/shirabe/src/command/mod.rs
@@ -0,0 +1,38 @@
+pub mod about_command;
+pub mod archive_command;
+pub mod audit_command;
+pub mod base_command;
+pub mod base_config_command;
+pub mod base_dependency_command;
+pub mod bump_command;
+pub mod check_platform_reqs_command;
+pub mod clear_cache_command;
+pub mod completion_trait;
+pub mod config_command;
+pub mod create_project_command;
+pub mod depends_command;
+pub mod diagnose_command;
+pub mod dump_autoload_command;
+pub mod exec_command;
+pub mod fund_command;
+pub mod global_command;
+pub mod home_command;
+pub mod init_command;
+pub mod install_command;
+pub mod licenses_command;
+pub mod outdated_command;
+pub mod package_discovery_trait;
+pub mod prohibits_command;
+pub mod reinstall_command;
+pub mod remove_command;
+pub mod repository_command;
+pub mod require_command;
+pub mod run_script_command;
+pub mod script_alias_command;
+pub mod search_command;
+pub mod self_update_command;
+pub mod show_command;
+pub mod status_command;
+pub mod suggests_command;
+pub mod update_command;
+pub mod validate_command;
diff --git a/crates/shirabe/src/command/outdated_command.rs b/crates/shirabe/src/command/outdated_command.rs
index f7a8f47..ed927b7 100644
--- a/crates/shirabe/src/command/outdated_command.rs
+++ b/crates/shirabe/src/command/outdated_command.rs
@@ -1,15 +1,15 @@
//! ref: composer/src/Composer/Command/OutdatedCommand.php
+use crate::command::base_command::BaseCommand;
+use crate::command::completion_trait::CompletionTrait;
+use crate::console::input::input_argument::InputArgument;
+use crate::console::input::input_option::InputOption;
use anyhow::Result;
use indexmap::IndexMap;
use shirabe_external_packages::symfony::console::input::array_input::ArrayInput;
use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
use shirabe_php_shim::PhpMixed;
-use crate::command::base_command::BaseCommand;
-use crate::command::completion_trait::CompletionTrait;
-use crate::console::input::input_argument::InputArgument;
-use crate::console::input::input_option::InputOption;
#[derive(Debug)]
pub struct OutdatedCommand {
@@ -54,12 +54,20 @@ impl OutdatedCommand {
);
}
- pub fn execute(&mut self, input: &dyn InputInterface, output: &dyn OutputInterface) -> Result<i64> {
+ pub fn execute(
+ &mut self,
+ input: &dyn InputInterface,
+ output: &dyn OutputInterface,
+ ) -> Result<i64> {
let mut args: IndexMap<String, PhpMixed> = IndexMap::new();
args.insert("command".to_string(), PhpMixed::String("show".to_string()));
args.insert("--latest".to_string(), PhpMixed::Bool(true));
- if input.get_option("no-interaction").as_bool().unwrap_or(false) {
+ if input
+ .get_option("no-interaction")
+ .as_bool()
+ .unwrap_or(false)
+ {
args.insert("--no-interaction".to_string(), PhpMixed::Bool(true));
}
if input.get_option("no-plugins").as_bool().unwrap_or(false) {
@@ -102,8 +110,15 @@ impl OutdatedCommand {
if input.get_option("sort-by-age").as_bool().unwrap_or(false) {
args.insert("--sort-by-age".to_string(), PhpMixed::Bool(true));
}
- args.insert("--ignore-platform-req".to_string(), input.get_option("ignore-platform-req"));
- if input.get_option("ignore-platform-reqs").as_bool().unwrap_or(false) {
+ args.insert(
+ "--ignore-platform-req".to_string(),
+ input.get_option("ignore-platform-req"),
+ );
+ if input
+ .get_option("ignore-platform-reqs")
+ .as_bool()
+ .unwrap_or(false)
+ {
args.insert("--ignore-platform-reqs".to_string(), PhpMixed::Bool(true));
}
args.insert("--format".to_string(), input.get_option("format"));
diff --git a/crates/shirabe/src/command/package_discovery_trait.rs b/crates/shirabe/src/command/package_discovery_trait.rs
index df55c5c..8fcf2c8 100644
--- a/crates/shirabe/src/command/package_discovery_trait.rs
+++ b/crates/shirabe/src/command/package_discovery_trait.rs
@@ -8,9 +8,10 @@ use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::symfony::component::console::input::input_interface::InputInterface;
use shirabe_external_packages::symfony::component::console::output::output_interface::OutputInterface;
use shirabe_php_shim::{
- array_keys, array_slice, array_unshift, array_values, asort, count, explode, file_get_contents,
- implode, in_array, is_array, is_file, is_numeric, is_string, json_decode, levenshtein,
- sprintf, strlen, strpos, trim, InvalidArgumentException, LogicException, PhpMixed, PHP_EOL,
+ InvalidArgumentException, LogicException, PHP_EOL, PhpMixed, array_keys, array_slice,
+ array_unshift, array_values, asort, count, explode, file_get_contents, implode, in_array,
+ is_array, is_file, is_numeric, is_string, json_decode, levenshtein, sprintf, strlen, strpos,
+ trim,
};
use crate::composer::Composer;
@@ -40,29 +41,29 @@ pub trait PackageDiscoveryTrait {
// PHP: trait dependencies (provided by BaseCommand)
fn get_io(&self) -> &dyn IOInterface;
fn try_composer(&self) -> Option<Composer>;
- fn require_composer(&self, disable_plugins: Option<bool>, disable_scripts: Option<bool>)
- -> Composer;
+ fn require_composer(
+ &self,
+ disable_plugins: Option<bool>,
+ disable_scripts: Option<bool>,
+ ) -> Composer;
fn get_platform_requirement_filter(
&self,
input: &dyn InputInterface,
) -> Box<dyn crate::filter::platform_requirement_filter::platform_requirement_filter_interface::PlatformRequirementFilterInterface>;
- fn normalize_requirements(
- &self,
- requires: Vec<String>,
- ) -> Vec<IndexMap<String, String>>;
+ fn normalize_requirements(&self, requires: Vec<String>) -> Vec<IndexMap<String, String>>;
fn get_repos(&mut self) -> &CompositeRepository {
if self.get_repos_mut().is_none() {
// PHP: array_merge([new PlatformRepository], RepositoryFactory::defaultReposWithDefaultManager($this->getIO()))
- let mut repos: Vec<Box<dyn crate::repository::repository_interface::RepositoryInterface>> = vec![
+ let mut repos: Vec<
+ Box<dyn crate::repository::repository_interface::RepositoryInterface>,
+ > = vec![
// TODO(phase-b): PlatformRepository::new() signature
Box::new(todo!("PlatformRepository::new()") as PlatformRepository),
];
let io_owned: Box<dyn IOInterface> = todo!("clone self.get_io() into a Box");
- for repo in
- RepositoryFactory::default_repos_with_default_manager(io_owned)
- {
+ for repo in RepositoryFactory::default_repos_with_default_manager(io_owned) {
repos.push(repo);
}
*self.get_repos_mut() = Some(CompositeRepository::new(repos));
@@ -192,10 +193,7 @@ pub trait PackageDiscoveryTrait {
&[
PhpMixed::String(version),
PhpMixed::String(
- requirement
- .get("name")
- .cloned()
- .unwrap_or_default(),
+ requirement.get("name").cloned().unwrap_or_default(),
),
],
)),
@@ -245,10 +243,7 @@ pub trait PackageDiscoveryTrait {
let mut matches = self.get_repos().search(package.clone(), 0, None);
if count(&PhpMixed::List(
- matches
- .iter()
- .map(|_| Box::new(PhpMixed::Null))
- .collect(),
+ matches.iter().map(|_| Box::new(PhpMixed::Null)).collect(),
)) > 0
{
// Remove existing packages from search results.
@@ -277,10 +272,7 @@ pub trait PackageDiscoveryTrait {
if !exact_match {
let providers = self.get_repos().get_providers(package.clone());
if count(&PhpMixed::List(
- providers
- .iter()
- .map(|_| Box::new(PhpMixed::Null))
- .collect(),
+ providers.iter().map(|_| Box::new(PhpMixed::Null)).collect(),
)) > 0
{
// PHP: array_unshift($matches, ['name' => $package, 'description' => '']);
@@ -352,16 +344,12 @@ pub trait PackageDiscoveryTrait {
true,
IOInterface::NORMAL,
);
- io.write_error(
- PhpMixed::String(String::new()),
- true,
- IOInterface::NORMAL,
- );
+ io.write_error(PhpMixed::String(String::new()), true, IOInterface::NORMAL);
let matches_clone = matches.clone();
let version_parser_clone = version_parser.clone();
- let validator: Box<dyn Fn(PhpMixed) -> PhpMixed> = Box::new(
- move |selection_mixed: PhpMixed| -> PhpMixed {
+ let validator: Box<dyn Fn(PhpMixed) -> PhpMixed> =
+ Box::new(move |selection_mixed: PhpMixed| -> PhpMixed {
let selection = selection_mixed.as_string().unwrap_or("").to_string();
if "" == selection {
return PhpMixed::Bool(false);
@@ -399,8 +387,7 @@ pub trait PackageDiscoveryTrait {
// TODO(phase-b): throw new \Exception('Not a valid selection');
panic!("Not a valid selection");
- },
- );
+ });
package = io
.ask_and_validate(
@@ -416,16 +403,15 @@ pub trait PackageDiscoveryTrait {
// no constraint yet, determine the best version automatically
if !package.is_empty() && strpos(&package, " ").is_none() {
- let validator: Box<dyn Fn(PhpMixed) -> PhpMixed> = Box::new(
- |input_mixed: PhpMixed| -> PhpMixed {
+ let validator: Box<dyn Fn(PhpMixed) -> PhpMixed> =
+ Box::new(|input_mixed: PhpMixed| -> PhpMixed {
let input = trim(input_mixed.as_string().unwrap_or(""), None);
if strlen(&input) > 0 {
PhpMixed::String(input)
} else {
PhpMixed::Bool(false)
}
- },
- );
+ });
let constraint_mixed = io.ask_and_validate(
"Enter the version constraint to require (or leave blank to use the latest version): ".to_string(),
@@ -523,26 +509,22 @@ pub trait PackageDiscoveryTrait {
// Check if it is a virtual package provided by others
let providers = repo_set.get_providers(name);
if count(&PhpMixed::List(
- providers
- .iter()
- .map(|_| Box::new(PhpMixed::Null))
- .collect(),
+ providers.iter().map(|_| Box::new(PhpMixed::Null)).collect(),
)) > 0
{
let mut constraint = "*".to_string();
if input.is_interactive() {
let providers_count = providers.len();
let name_owned = name.to_string();
- let validator: Box<dyn Fn(PhpMixed) -> PhpMixed> = Box::new(
- move |value_mixed: PhpMixed| -> PhpMixed {
+ let validator: Box<dyn Fn(PhpMixed) -> PhpMixed> =
+ Box::new(move |value_mixed: PhpMixed| -> PhpMixed {
let value = value_mixed.as_string().unwrap_or("").to_string();
let parser = VersionParser::new();
// TODO(phase-b): parse_constraints returns Result
let _ = parser.parse_constraints(&value);
PhpMixed::String(value)
- },
- );
+ });
constraint = self
.get_io()
.ask_and_validate(
@@ -676,10 +658,7 @@ pub trait PackageDiscoveryTrait {
// Check for similar names/typos
let similar = self.find_similar(name)?;
if count(&PhpMixed::List(
- similar
- .iter()
- .map(|_| Box::new(PhpMixed::Null))
- .collect(),
+ similar.iter().map(|_| Box::new(PhpMixed::Null)).collect(),
)) > 0
{
if in_array(
@@ -737,7 +716,11 @@ pub trait PackageDiscoveryTrait {
message: sprintf(
&format!(
"Could not find package %s.\n\nDid you mean {}?\n %s",
- if similar.len() > 1 { "one of these" } else { "this" },
+ if similar.len() > 1 {
+ "one of these"
+ } else {
+ "this"
+ },
),
&[
PhpMixed::String(name.to_string()),
@@ -779,7 +762,8 @@ pub trait PackageDiscoveryTrait {
let results: Vec<SearchResult> = match (|| -> Result<Vec<SearchResult>> {
if self.get_repos_mut().is_none() {
return Err(LogicException {
- message: "findSimilar was called before $this->repos was initialized".to_string(),
+ message: "findSimilar was called before $this->repos was initialized"
+ .to_string(),
code: 0,
}
.into());
@@ -890,8 +874,11 @@ pub trait PackageDiscoveryTrait {
.is_some();
if has_config_platform && is_complete {
// TODO(phase-b): platform_pkg.get_description() via CompletePackageInterface
- platform_pkg_version =
- format!("{} ({})", platform_pkg_version, todo!("platform_pkg.get_description()"));
+ platform_pkg_version = format!(
+ "{} ({})",
+ platform_pkg_version,
+ todo!("platform_pkg.get_description()")
+ );
}
details.push(format!(
"{} {} requires {} {} which does not match your installed version {}.",
@@ -905,15 +892,16 @@ pub trait PackageDiscoveryTrait {
}
if count(&PhpMixed::List(
- details
- .iter()
- .map(|_| Box::new(PhpMixed::Null))
- .collect(),
+ details.iter().map(|_| Box::new(PhpMixed::Null)).collect(),
)) == 0
{
return String::new();
}
- format!(":{} - {}", PHP_EOL, implode(&format!("{} - ", PHP_EOL), &details))
+ format!(
+ ":{} - {}",
+ PHP_EOL,
+ implode(&format!("{} - ", PHP_EOL), &details)
+ )
}
}
diff --git a/crates/shirabe/src/command/prohibits_command.rs b/crates/shirabe/src/command/prohibits_command.rs
index 216b050..accfcf0 100644
--- a/crates/shirabe/src/command/prohibits_command.rs
+++ b/crates/shirabe/src/command/prohibits_command.rs
@@ -1,11 +1,11 @@
//! ref: composer/src/Composer/Command/ProhibitsCommand.php
-use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
-use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
use crate::command::base_dependency_command::BaseDependencyCommand;
use crate::command::completion_trait::CompletionTrait;
use crate::console::input::input_argument::InputArgument;
use crate::console::input::input_option::InputOption;
+use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
+use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
pub struct ProhibitsCommand {
inner: BaseDependencyCommand,
@@ -57,7 +57,7 @@ impl ProhibitsCommand {
.set_help(
"Displays detailed information about why a package cannot be installed.\n\n\
<info>php composer.phar prohibits composer/composer</info>\n\n\
- Read more at https://getcomposer.org/doc/03-cli.md#prohibits-why-not"
+ Read more at https://getcomposer.org/doc/03-cli.md#prohibits-why-not",
);
}
diff --git a/crates/shirabe/src/command/reinstall_command.rs b/crates/shirabe/src/command/reinstall_command.rs
index 59bb2ec..3fb26a2 100644
--- a/crates/shirabe/src/command/reinstall_command.rs
+++ b/crates/shirabe/src/command/reinstall_command.rs
@@ -68,7 +68,9 @@ impl ReinstallCommand {
let composer = self.inner.require_composer()?;
let local_repo = composer.get_repository_manager().get_local_repository();
- let mut packages_to_reinstall: Vec<Box<dyn crate::package::package_interface::PackageInterface>> = vec![];
+ let mut packages_to_reinstall: Vec<
+ Box<dyn crate::package::package_interface::PackageInterface>,
+ > = vec![];
let mut package_names_to_reinstall: Vec<String> = vec![];
let type_option = input.get_option("type");
@@ -79,12 +81,20 @@ impl ReinstallCommand {
if type_count > 0 {
if packages_count > 0 {
return Err(InvalidArgumentException {
- message: "You cannot specify package names and filter by type at the same time.".to_string(),
+ message:
+ "You cannot specify package names and filter by type at the same time."
+ .to_string(),
code: 0,
- }.into());
+ }
+ .into());
}
- let filter_types: Vec<String> = type_option.as_list()
- .map(|l| l.iter().filter_map(|v| v.as_string().map(|s| s.to_string())).collect())
+ let filter_types: Vec<String> = type_option
+ .as_list()
+ .map(|l| {
+ l.iter()
+ .filter_map(|v| v.as_string().map(|s| s.to_string()))
+ .collect()
+ })
.unwrap_or_default();
for package in local_repo.get_canonical_packages() {
if filter_types.contains(&package.get_type().to_string()) {
@@ -95,12 +105,19 @@ impl ReinstallCommand {
} else {
if packages_count == 0 {
return Err(InvalidArgumentException {
- message: "You must pass one or more package names to be reinstalled.".to_string(),
+ message: "You must pass one or more package names to be reinstalled."
+ .to_string(),
code: 0,
- }.into());
+ }
+ .into());
}
- let patterns: Vec<String> = packages_arg.as_list()
- .map(|l| l.iter().filter_map(|v| v.as_string().map(|s| s.to_string())).collect())
+ let patterns: Vec<String> = packages_arg
+ .as_list()
+ .map(|l| {
+ l.iter()
+ .filter_map(|v| v.as_string().map(|s| s.to_string()))
+ .collect()
+ })
.unwrap_or_default();
for pattern in &patterns {
let pattern_regexp = BasePackage::package_name_to_regexp(pattern);
@@ -130,7 +147,8 @@ impl ReinstallCommand {
let present_packages = local_repo.get_packages();
let result_packages = present_packages.clone();
- let present_packages: Vec<_> = present_packages.into_iter()
+ let present_packages: Vec<_> = present_packages
+ .into_iter()
.filter(|package| !package_names_to_reinstall.contains(&package.get_name().to_string()))
.collect();
@@ -140,15 +158,24 @@ impl ReinstallCommand {
let mut install_order = indexmap::IndexMap::new();
for (index, op) in install_operations.iter().enumerate() {
if let Some(install_op) = (op.as_any() as &dyn Any).downcast_ref::<InstallOperation>() {
- if (install_op.get_package().as_any() as &dyn Any).downcast_ref::<AliasPackage>().is_none() {
+ if (install_op.get_package().as_any() as &dyn Any)
+ .downcast_ref::<AliasPackage>()
+ .is_none()
+ {
install_order.insert(install_op.get_package().get_name().to_string(), index);
}
}
}
uninstall_operations.sort_by(|a, b| {
- let a_order = install_order.get(a.get_package().get_name()).copied().unwrap_or(0);
- let b_order = install_order.get(b.get_package().get_name()).copied().unwrap_or(0);
+ let a_order = install_order
+ .get(a.get_package().get_name())
+ .copied()
+ .unwrap_or(0);
+ let b_order = install_order
+ .get(b.get_package().get_name())
+ .copied()
+ .unwrap_or(0);
b_order.cmp(&a_order)
});
@@ -165,13 +192,15 @@ impl ReinstallCommand {
event_dispatcher.dispatch(command_event.get_name(), &command_event);
let config = composer.get_config();
- let (prefer_source, prefer_dist) = self.inner.get_preferred_install_options(config, input)?;
+ let (prefer_source, prefer_dist) =
+ self.inner.get_preferred_install_options(config, input)?;
let installation_manager = composer.get_installation_manager();
let download_manager = composer.get_download_manager();
let package = composer.get_package();
- installation_manager.set_output_progress(!input.get_option("no-progress").as_bool().unwrap_or(false));
+ installation_manager
+ .set_output_progress(!input.get_option("no-progress").as_bool().unwrap_or(false));
if input.get_option("no-plugins").as_bool().unwrap_or(false) {
installation_manager.disable_plugins();
}
@@ -188,19 +217,36 @@ impl ReinstallCommand {
installation_manager.execute(local_repo, install_operations, dev_mode);
if !input.get_option("no-autoloader").as_bool().unwrap_or(false) {
- let optimize = input.get_option("optimize-autoloader").as_bool().unwrap_or(false)
+ let optimize = input
+ .get_option("optimize-autoloader")
+ .as_bool()
+ .unwrap_or(false)
|| config.get("optimize-autoloader").as_bool().unwrap_or(false);
- let authoritative = input.get_option("classmap-authoritative").as_bool().unwrap_or(false)
- || config.get("classmap-authoritative").as_bool().unwrap_or(false);
- let apcu_prefix = input.get_option("apcu-autoloader-prefix").as_string_opt().map(|s| s.to_string());
+ let authoritative = input
+ .get_option("classmap-authoritative")
+ .as_bool()
+ .unwrap_or(false)
+ || config
+ .get("classmap-authoritative")
+ .as_bool()
+ .unwrap_or(false);
+ let apcu_prefix = input
+ .get_option("apcu-autoloader-prefix")
+ .as_string_opt()
+ .map(|s| s.to_string());
let apcu = apcu_prefix.is_some()
- || input.get_option("apcu-autoloader").as_bool().unwrap_or(false)
+ || input
+ .get_option("apcu-autoloader")
+ .as_bool()
+ .unwrap_or(false)
|| config.get("apcu-autoloader").as_bool().unwrap_or(false);
let generator = composer.get_autoload_generator();
generator.set_class_map_authoritative(authoritative);
generator.set_apcu(apcu, apcu_prefix.as_deref());
- generator.set_platform_requirement_filter(self.inner.get_platform_requirement_filter(input)?);
+ generator.set_platform_requirement_filter(
+ self.inner.get_platform_requirement_filter(input)?,
+ );
generator.dump(
config,
local_repo,
diff --git a/crates/shirabe/src/command/remove_command.rs b/crates/shirabe/src/command/remove_command.rs
index 3ad3c74..b7f8378 100644
--- a/crates/shirabe/src/command/remove_command.rs
+++ b/crates/shirabe/src/command/remove_command.rs
@@ -5,7 +5,7 @@ use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::symfony::component::console::exception::invalid_argument_exception::InvalidArgumentException;
use shirabe_external_packages::symfony::component::console::input::input_interface::InputInterface;
use shirabe_external_packages::symfony::component::console::output::output_interface::OutputInterface;
-use shirabe_php_shim::{array_map, strtolower, PhpMixed, UnexpectedValueException};
+use shirabe_php_shim::{PhpMixed, UnexpectedValueException, array_map, strtolower};
use crate::advisory::auditor::Auditor;
use crate::command::base_command::BaseCommand;
@@ -221,7 +221,11 @@ impl RemoveCommand {
input: &dyn InputInterface,
output: &dyn OutputInterface,
) -> anyhow::Result<i64> {
- if input.get_argument("packages").as_list().map(|l| l.is_empty()).unwrap_or(true)
+ if input
+ .get_argument("packages")
+ .as_list()
+ .map(|l| l.is_empty())
+ .unwrap_or(true)
&& !input.get_option("unused").as_bool().unwrap_or(false)
{
return Err(anyhow::anyhow!(InvalidArgumentException {
@@ -245,7 +249,9 @@ impl RemoveCommand {
let locker = composer.get_locker();
if !locker.is_locked() {
return Err(anyhow::anyhow!(UnexpectedValueException {
- message: "A valid composer.lock file is required to run this command with --unused".to_string(),
+ message:
+ "A valid composer.lock file is required to run this command with --unused"
+ .to_string(),
code: 0,
}));
}
@@ -293,7 +299,8 @@ impl RemoveCommand {
packages.extend(unused);
if packages.is_empty() {
- self.get_io().write_error("<info>No unused packages to remove</info>");
+ self.get_io()
+ .write_error("<info>No unused packages to remove</info>");
return Ok(0);
}
}
@@ -339,10 +346,7 @@ impl RemoveCommand {
.filter_map(|(k, v)| v.as_string().map(|_| (k.clone(), k.clone())))
.collect();
for (name, canonical) in entries {
- section.insert(
- strtolower(&name),
- Box::new(PhpMixed::String(canonical)),
- );
+ section.insert(strtolower(&name), Box::new(PhpMixed::String(canonical)));
}
}
}
@@ -381,10 +385,13 @@ impl RemoveCommand {
canonical_name, r#type, alt_type
));
if io.is_interactive() {
- if io.ask_confirmation(&format!(
- "Do you want to remove it from {} [<comment>yes</comment>]? ",
- alt_type
- ), true) {
+ if io.ask_confirmation(
+ &format!(
+ "Do you want to remove it from {} [<comment>yes</comment>]? ",
+ alt_type
+ ),
+ true,
+ ) {
if dry_run {
to_remove
.entry(alt_type.to_string())
@@ -402,11 +409,9 @@ impl RemoveCommand {
.and_then(|v| v.as_array())
.map(|m| m.keys().cloned().collect())
.unwrap_or_default();
- let matches_in_type = Preg::grep(
- &BasePackage::package_name_to_regexp(package),
- &type_keys,
- )
- .unwrap_or_default();
+ let matches_in_type =
+ Preg::grep(&BasePackage::package_name_to_regexp(package), &type_keys)
+ .unwrap_or_default();
let alt_type_keys: Vec<String> = composer_data
.as_array()
@@ -438,10 +443,13 @@ impl RemoveCommand {
matched_package, r#type, alt_type
));
if io.is_interactive() {
- if io.ask_confirmation(&format!(
- "Do you want to remove it from {} [<comment>yes</comment>]? ",
- alt_type
- ), true) {
+ if io.ask_confirmation(
+ &format!(
+ "Do you want to remove it from {} [<comment>yes</comment>]? ",
+ alt_type
+ ),
+ true,
+ ) {
if dry_run {
to_remove
.entry(alt_type.to_string())
@@ -470,7 +478,9 @@ impl RemoveCommand {
// TODO(plugin): deactivate installed plugins
if let Some(composer_opt) = self.try_composer() {
- composer_opt.get_plugin_manager().deactivate_installed_plugins();
+ composer_opt
+ .get_plugin_manager()
+ .deactivate_installed_plugins();
}
self.reset_composer();
@@ -507,17 +517,16 @@ impl RemoveCommand {
.dispatch(command_event.get_name(), command_event);
let allow_plugins = composer.get_config().get("allow-plugins");
- let removed_plugins: Vec<String> = if let Some(allow_map) =
- allow_plugins.as_ref().and_then(|v| v.as_array())
- {
- packages
- .iter()
- .filter(|p| allow_map.contains_key(p.as_str()))
- .cloned()
- .collect()
- } else {
- vec![]
- };
+ let removed_plugins: Vec<String> =
+ if let Some(allow_map) = allow_plugins.as_ref().and_then(|v| v.as_array()) {
+ packages
+ .iter()
+ .filter(|p| allow_map.contains_key(p.as_str()))
+ .cloned()
+ .collect()
+ } else {
+ vec![]
+ };
if !dry_run
&& allow_plugins.as_ref().and_then(|v| v.as_array()).is_some()
@@ -544,26 +553,67 @@ impl RemoveCommand {
let mut install = Installer::create(io, &composer);
let update_dev_mode = !input.get_option("update-no-dev").as_bool().unwrap_or(false);
- let optimize = input.get_option("optimize-autoloader").as_bool().unwrap_or(false)
- || composer.get_config().get("optimize-autoloader").and_then(|v| v.as_bool()).unwrap_or(false);
- let authoritative = input.get_option("classmap-authoritative").as_bool().unwrap_or(false)
- || composer.get_config().get("classmap-authoritative").and_then(|v| v.as_bool()).unwrap_or(false);
- let apcu_prefix = input.get_option("apcu-autoloader-prefix").as_string().map(|s| s.to_string());
+ let optimize = input
+ .get_option("optimize-autoloader")
+ .as_bool()
+ .unwrap_or(false)
+ || composer
+ .get_config()
+ .get("optimize-autoloader")
+ .and_then(|v| v.as_bool())
+ .unwrap_or(false);
+ let authoritative = input
+ .get_option("classmap-authoritative")
+ .as_bool()
+ .unwrap_or(false)
+ || composer
+ .get_config()
+ .get("classmap-authoritative")
+ .and_then(|v| v.as_bool())
+ .unwrap_or(false);
+ let apcu_prefix = input
+ .get_option("apcu-autoloader-prefix")
+ .as_string()
+ .map(|s| s.to_string());
let apcu = apcu_prefix.is_some()
- || input.get_option("apcu-autoloader").as_bool().unwrap_or(false)
- || composer.get_config().get("apcu-autoloader").and_then(|v| v.as_bool()).unwrap_or(false);
- let minimal_changes = input.get_option("minimal-changes").as_bool().unwrap_or(false)
- || composer.get_config().get("update-with-minimal-changes").and_then(|v| v.as_bool()).unwrap_or(false);
+ || input
+ .get_option("apcu-autoloader")
+ .as_bool()
+ .unwrap_or(false)
+ || composer
+ .get_config()
+ .get("apcu-autoloader")
+ .and_then(|v| v.as_bool())
+ .unwrap_or(false);
+ let minimal_changes = input
+ .get_option("minimal-changes")
+ .as_bool()
+ .unwrap_or(false)
+ || composer
+ .get_config()
+ .get("update-with-minimal-changes")
+ .and_then(|v| v.as_bool())
+ .unwrap_or(false);
let mut update_allow_transitive_dependencies =
Request::UPDATE_LISTED_WITH_TRANSITIVE_DEPS_NO_ROOT_REQUIRE;
let mut flags = String::new();
- if input.get_option("update-with-all-dependencies").as_bool().unwrap_or(false)
- || input.get_option("with-all-dependencies").as_bool().unwrap_or(false)
+ if input
+ .get_option("update-with-all-dependencies")
+ .as_bool()
+ .unwrap_or(false)
+ || input
+ .get_option("with-all-dependencies")
+ .as_bool()
+ .unwrap_or(false)
{
update_allow_transitive_dependencies = Request::UPDATE_LISTED_WITH_TRANSITIVE_DEPS;
flags += " --with-all-dependencies";
- } else if input.get_option("no-update-with-dependencies").as_bool().unwrap_or(false) {
+ } else if input
+ .get_option("no-update-with-dependencies")
+ .as_bool()
+ .unwrap_or(false)
+ {
update_allow_transitive_dependencies = Request::UPDATE_ONLY_LISTED;
flags += " --with-dependencies";
}
@@ -582,9 +632,7 @@ impl RemoveCommand {
install.set_update(true);
install.set_install(!input.get_option("no-install").as_bool().unwrap_or(false));
install.set_update_allow_transitive_dependencies(update_allow_transitive_dependencies);
- install.set_platform_requirement_filter(
- self.get_platform_requirement_filter(input),
- );
+ install.set_platform_requirement_filter(self.get_platform_requirement_filter(input));
install.set_dry_run(dry_run);
install.set_audit_config(self.create_audit_config(composer.get_config(), input));
install.set_minimal_update(minimal_changes);
diff --git a/crates/shirabe/src/command/repository_command.rs b/crates/shirabe/src/command/repository_command.rs
index 0c72c2a..cfe9065 100644
--- a/crates/shirabe/src/command/repository_command.rs
+++ b/crates/shirabe/src/command/repository_command.rs
@@ -5,8 +5,9 @@ use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::symfony::console::completion::completion_input::CompletionInput;
use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
-use shirabe_php_shim::{parse_url, strtolower, InvalidArgumentException, PhpMixed, RuntimeException,
- PHP_URL_HOST};
+use shirabe_php_shim::{
+ InvalidArgumentException, PHP_URL_HOST, PhpMixed, RuntimeException, parse_url, strtolower,
+};
use crate::command::base_config_command::BaseConfigCommand;
use crate::console::input::input_argument::InputArgument;
@@ -59,15 +60,44 @@ impl RepositoryCommand {
);
}
- pub fn execute(&mut self, input: &dyn InputInterface, _output: &dyn OutputInterface) -> anyhow::Result<i64> {
- let action = strtolower(&input.get_argument("action").as_string().unwrap_or("").to_string());
- let name = input.get_argument("name").as_string().map(|s| s.to_string());
- let arg1 = input.get_argument("arg1").as_string().map(|s| s.to_string());
- let arg2 = input.get_argument("arg2").as_string().map(|s| s.to_string());
+ pub fn execute(
+ &mut self,
+ input: &dyn InputInterface,
+ _output: &dyn OutputInterface,
+ ) -> anyhow::Result<i64> {
+ let action = strtolower(
+ &input
+ .get_argument("action")
+ .as_string()
+ .unwrap_or("")
+ .to_string(),
+ );
+ let name = input
+ .get_argument("name")
+ .as_string()
+ .map(|s| s.to_string());
+ let arg1 = input
+ .get_argument("arg1")
+ .as_string()
+ .map(|s| s.to_string());
+ let arg2 = input
+ .get_argument("arg2")
+ .as_string()
+ .map(|s| s.to_string());
let config_data = self.inner.config_file.as_ref().unwrap().read()?;
- let config_file_path = self.inner.config_file.as_ref().unwrap().get_path().to_string();
- self.inner.config.as_mut().unwrap().merge(config_data, &config_file_path);
+ let config_file_path = self
+ .inner
+ .config_file
+ .as_ref()
+ .unwrap()
+ .get_path()
+ .to_string();
+ self.inner
+ .config
+ .as_mut()
+ .unwrap()
+ .merge(config_data, &config_file_path);
let repos = self.inner.config.as_ref().unwrap().get_repositories();
match action.as_str() {
@@ -89,7 +119,8 @@ impl RepositoryCommand {
}));
}
let arg1_str = arg1.as_deref().unwrap();
- let repo_config: PhpMixed = if Preg::is_match(r"^\s*\{", arg1_str).unwrap_or(false) {
+ let repo_config: PhpMixed = if Preg::is_match(r"^\s*\{", arg1_str).unwrap_or(false)
+ {
JsonFile::parse_json(Some(arg1_str), None)?
} else {
if arg2.is_none() {
@@ -99,12 +130,18 @@ impl RepositoryCommand {
}));
}
let mut m = IndexMap::new();
- m.insert("type".to_string(), Box::new(PhpMixed::String(arg1_str.to_string())));
+ m.insert(
+ "type".to_string(),
+ Box::new(PhpMixed::String(arg1_str.to_string())),
+ );
m.insert("url".to_string(), Box::new(PhpMixed::String(arg2.unwrap())));
PhpMixed::Array(m)
};
- let before = input.get_option("before").as_string().map(|s| s.to_string());
+ let before = input
+ .get_option("before")
+ .as_string()
+ .map(|s| s.to_string());
let after = input.get_option("after").as_string().map(|s| s.to_string());
if before.is_some() && after.is_some() {
return Err(anyhow::anyhow!(RuntimeException {
@@ -116,18 +153,23 @@ impl RepositoryCommand {
if before.is_some() || after.is_some() {
if matches!(repo_config, PhpMixed::Bool(false)) {
return Err(anyhow::anyhow!(RuntimeException {
- message: "Cannot use --before/--after with boolean repository values".to_string(),
+ message: "Cannot use --before/--after with boolean repository values"
+ .to_string(),
code: 0,
}));
}
let reference_name = before.as_deref().or(after.as_deref()).unwrap();
let offset: i64 = if after.is_some() { 1 } else { 0 };
- self.inner.config_source.as_mut().unwrap().insert_repository(
- name.as_deref().unwrap(),
- repo_config,
- reference_name,
- offset,
- );
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .insert_repository(
+ name.as_deref().unwrap(),
+ repo_config,
+ reference_name,
+ offset,
+ );
return Ok(0);
}
@@ -147,7 +189,11 @@ impl RepositoryCommand {
}));
}
let name_str = name.as_deref().unwrap();
- self.inner.config_source.as_mut().unwrap().remove_repository(name_str);
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .remove_repository(name_str);
if ["packagist", "packagist.org"].contains(&name_str) {
self.inner.config_source.as_mut().unwrap().add_repository(
"packagist.org",
@@ -164,10 +210,11 @@ impl RepositoryCommand {
code: 0,
}));
}
- self.inner.config_source.as_mut().unwrap().set_repository_url(
- name.as_deref().unwrap(),
- arg1.as_deref().unwrap(),
- );
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .set_repository_url(name.as_deref().unwrap(), arg1.as_deref().unwrap());
Ok(0)
}
"get-url" | "geturl" => {
@@ -201,7 +248,10 @@ impl RepositoryCommand {
return Ok(0);
}
return Err(anyhow::anyhow!(InvalidArgumentException {
- message: format!("The {} repository does not have a URL", name_str),
+ message: format!(
+ "The {} repository does not have a URL",
+ name_str
+ ),
code: 0,
}));
}
@@ -244,16 +294,24 @@ impl RepositoryCommand {
}
let name_str = name.as_deref().unwrap();
if ["packagist", "packagist.org"].contains(&name_str) {
- self.inner.config_source.as_mut().unwrap().remove_repository("packagist.org");
+ self.inner
+ .config_source
+ .as_mut()
+ .unwrap()
+ .remove_repository("packagist.org");
return Ok(0);
}
Err(anyhow::anyhow!(RuntimeException {
- message: "Only packagist.org can be enabled/disabled using this command.".to_string(),
+ message: "Only packagist.org can be enabled/disabled using this command."
+ .to_string(),
code: 0,
}))
}
_ => Err(anyhow::anyhow!(InvalidArgumentException {
- message: format!("Unknown action \"{}\". Use list, add, remove, set-url, get-url, enable, disable", action),
+ message: format!(
+ "Unknown action \"{}\". Use list, add, remove, set-url, get-url, enable, disable",
+ action
+ ),
code: 0,
})),
}
@@ -265,8 +323,10 @@ impl RepositoryCommand {
let mut packagist_present = false;
for (_key, repo) in &repos {
if let PhpMixed::Array(ref repo_map) = *repo {
- let has_type_and_url = repo_map.contains_key("type") && repo_map.contains_key("url");
- let is_composer_type = repo_map.get("type").and_then(|v| v.as_string()) == Some("composer");
+ let has_type_and_url =
+ repo_map.contains_key("type") && repo_map.contains_key("url");
+ let is_composer_type =
+ repo_map.get("type").and_then(|v| v.as_string()) == Some("composer");
let url_host_ends_with_packagist = repo_map
.get("url")
.and_then(|v| v.as_string())
@@ -346,7 +406,11 @@ impl RepositoryCommand {
fn suggest_repo_names(&self) -> Box<dyn Fn(&CompletionInput) -> Vec<String> + '_> {
Box::new(move |input: &CompletionInput| {
- let action = input.get_argument("action").as_string().unwrap_or("").to_string();
+ let action = input
+ .get_argument("action")
+ .as_string()
+ .unwrap_or("")
+ .to_string();
if ["enable", "disable"].contains(&action.as_str()) {
return vec!["packagist.org".to_string()];
}
diff --git a/crates/shirabe/src/command/require_command.rs b/crates/shirabe/src/command/require_command.rs
index 1b966f2..738790d 100644
--- a/crates/shirabe/src/command/require_command.rs
+++ b/crates/shirabe/src/command/require_command.rs
@@ -7,10 +7,10 @@ use shirabe_external_packages::seld::signal::signal_handler::SignalHandler;
use shirabe_external_packages::symfony::component::console::input::input_interface::InputInterface;
use shirabe_external_packages::symfony::component::console::output::output_interface::OutputInterface;
use shirabe_php_shim::{
- array_fill_keys, array_intersect, array_keys, array_map, array_merge, array_merge_recursive,
- array_unique, count, empty, file_exists, file_get_contents, file_put_contents, filesize,
- implode, is_writable, sprintf, strtolower, unlink, PhpMixed, RuntimeException,
- UnexpectedValueException,
+ PhpMixed, RuntimeException, UnexpectedValueException, array_fill_keys, array_intersect,
+ array_keys, array_map, array_merge, array_merge_recursive, array_unique, count, empty,
+ file_exists, file_get_contents, file_put_contents, filesize, implode, is_writable, sprintf,
+ strtolower, unlink,
};
use crate::advisory::auditor::Auditor;
@@ -21,8 +21,8 @@ use crate::console::input::input_argument::InputArgument;
use crate::console::input::input_option::InputOption;
use crate::dependency_resolver::request::Request;
use crate::factory::Factory;
-use crate::installer::installer_events::InstallerEvents;
use crate::installer::Installer;
+use crate::installer::installer_events::InstallerEvents;
use crate::io::io_interface::IOInterface;
use crate::json::json_file::JsonFile;
use crate::json::json_manipulator::JsonManipulator;
@@ -63,7 +63,8 @@ impl PackageDiscoveryTrait for RequireCommand {}
impl RequireCommand {
pub fn configure(&mut self) {
- let suggest_available_package_incl_platform = self.suggest_available_package_incl_platform();
+ let suggest_available_package_incl_platform =
+ self.suggest_available_package_incl_platform();
let suggest_prefer_install = self.suggest_prefer_install();
self.inner
.set_name("require")
@@ -137,7 +138,10 @@ impl RequireCommand {
self.newly_created = !file_exists(&self.file);
if self.newly_created && !file_put_contents(&self.file, "{\n}\n") {
io.write_error(
- PhpMixed::String(format!("<error>{} could not be created.</error>", self.file)),
+ PhpMixed::String(format!(
+ "<error>{} could not be created.</error>",
+ self.file
+ )),
true,
IOInterface::NORMAL,
);
@@ -160,8 +164,8 @@ impl RequireCommand {
self.json = Some(JsonFile::new(&self.file, None, None));
self.lock = Factory::get_lock_file(&self.file);
- self.composer_backup = file_get_contents(self.json.as_ref().unwrap().get_path())
- .unwrap_or_default();
+ self.composer_backup =
+ file_get_contents(self.json.as_ref().unwrap().get_path()).unwrap_or_default();
self.lock_backup = if file_exists(&self.lock) {
file_get_contents(&self.lock)
} else {
@@ -220,9 +224,7 @@ impl RequireCommand {
};
/// @see https://github.com/composer/composer/pull/8313#issuecomment-532637955
- if package_type != "project"
- && !input.get_option("dev").as_bool().unwrap_or(false)
- {
+ if package_type != "project" && !input.get_option("dev").as_bool().unwrap_or(false) {
io.write_error(
PhpMixed::String(
"<error>The \"--fixed\" option is only allowed for packages with a \"project\" type or for dev dependencies to prevent possible misuses.</error>"
@@ -253,9 +255,9 @@ impl RequireCommand {
let platform_overrides = composer.get_config().get("platform");
// initialize self.repos as it is used by the PackageDiscoveryTrait
let platform_repo = PlatformRepository::new(vec![], platform_overrides);
- let mut combined: Vec<Box<dyn crate::repository::repository_interface::RepositoryInterface>> = vec![
- Box::new(platform_repo.clone()),
- ];
+ let mut combined: Vec<
+ Box<dyn crate::repository::repository_interface::RepositoryInterface>,
+ > = vec![Box::new(platform_repo.clone())];
for repo in repos {
combined.push(repo);
}
@@ -273,7 +275,11 @@ impl RequireCommand {
input
.get_argument("packages")
.as_list()
- .map(|l| l.iter().filter_map(|v| v.as_string().map(|s| s.to_string())).collect())
+ .map(|l| {
+ l.iter()
+ .filter_map(|v| v.as_string().map(|s| s.to_string()))
+ .collect()
+ })
.unwrap_or_default(),
&platform_repo,
&preferred_stability,
@@ -327,10 +333,8 @@ impl RequireCommand {
// TODO(phase-b): instanceof CompletePackageInterface downcast
let pkg_as_complete: Option<&dyn CompletePackageInterface> = None;
if let Some(pkg_complete) = pkg_as_complete {
- let lowered: Vec<String> = array_map(
- |s: &String| strtolower(s),
- &pkg_complete.get_keywords(),
- );
+ let lowered: Vec<String> =
+ array_map(|s: &String| strtolower(s), &pkg_complete.get_keywords());
let pkg_dev_tags: Vec<String> = array_intersect(&dev_tags, &lowered);
if (pkg_dev_tags.len() as i64) > 0 {
dev_packages.push(pkg_dev_tags);
@@ -340,8 +344,16 @@ impl RequireCommand {
}
if (dev_packages.len() as i64) == (requirements.len() as i64) {
- let plural = if (requirements.len() as i64) > 1 { "s" } else { "" };
- let plural2 = if (requirements.len() as i64) > 1 { "are" } else { "is" };
+ let plural = if (requirements.len() as i64) > 1 {
+ "s"
+ } else {
+ ""
+ };
+ let plural2 = if (requirements.len() as i64) > 1 {
+ "are"
+ } else {
+ "is"
+ };
let plural3 = if (requirements.len() as i64) > 1 {
"they are"
} else {
@@ -520,7 +532,11 @@ impl RequireCommand {
PhpMixed::String(format!(
"<info>{} has been {}</info>",
self.file,
- if self.newly_created { "created" } else { "updated" }
+ if self.newly_created {
+ "created"
+ } else {
+ "updated"
+ }
)),
true,
IOInterface::NORMAL,
@@ -533,24 +549,24 @@ impl RequireCommand {
composer.get_plugin_manager().deactivate_installed_plugins();
// try/catch/finally
- let do_update_result = self.do_update(input, output, io, &requirements, require_key, remove_key);
+ let do_update_result =
+ self.do_update(input, output, io, &requirements, require_key, remove_key);
let dry_run = input.get_option("dry-run").as_bool().unwrap_or(false);
let result = match do_update_result {
Ok(result) => {
- let final_result =
- if result == 0 && (requirements_to_guess.len() as i64) > 0 {
- self.update_requirements_after_resolution(
- &requirements_to_guess,
- require_key,
- remove_key,
- sort_packages,
- dry_run,
- input.get_option("fixed").as_bool().unwrap_or(false),
- )?
- } else {
- result
- };
+ let final_result = if result == 0 && (requirements_to_guess.len() as i64) > 0 {
+ self.update_requirements_after_resolution(
+ &requirements_to_guess,
+ require_key,
+ remove_key,
+ sort_packages,
+ dry_run,
+ input.get_option("fixed").as_bool().unwrap_or(false),
+ )?
+ } else {
+ result
+ };
Ok(final_result)
}
Err(e) => {
@@ -598,7 +614,10 @@ impl RequireCommand {
let mut require: IndexMap<String, PhpMixed> = IndexMap::new();
let mut require_dev: IndexMap<String, PhpMixed> = IndexMap::new();
- if let Some(r) = composer_definition.get("require").and_then(|v| v.as_array()) {
+ if let Some(r) = composer_definition
+ .get("require")
+ .and_then(|v| v.as_array())
+ {
for (k, v) in r {
require.insert(k.clone(), (**v).clone());
}
@@ -712,7 +731,10 @@ impl RequireCommand {
}
let update_dev_mode = !input.get_option("update-no-dev").as_bool().unwrap_or(false);
- let optimize = input.get_option("optimize-autoloader").as_bool().unwrap_or(false)
+ let optimize = input
+ .get_option("optimize-autoloader")
+ .as_bool()
+ .unwrap_or(false)
|| composer
.get_config()
.get("optimize-autoloader")
@@ -732,13 +754,19 @@ impl RequireCommand {
.as_string()
.map(|s| s.to_string());
let apcu = apcu_prefix.is_some()
- || input.get_option("apcu-autoloader").as_bool().unwrap_or(false)
+ || input
+ .get_option("apcu-autoloader")
+ .as_bool()
+ .unwrap_or(false)
|| composer
.get_config()
.get("apcu-autoloader")
.as_bool()
.unwrap_or(false);
- let minimal_changes = input.get_option("minimal-changes").as_bool().unwrap_or(false)
+ let minimal_changes = input
+ .get_option("minimal-changes")
+ .as_bool()
+ .unwrap_or(false)
|| composer
.get_config()
.get("update-with-minimal-changes")
@@ -751,7 +779,10 @@ impl RequireCommand {
.get_option("update-with-all-dependencies")
.as_bool()
.unwrap_or(false)
- || input.get_option("with-all-dependencies").as_bool().unwrap_or(false)
+ || input
+ .get_option("with-all-dependencies")
+ .as_bool()
+ .unwrap_or(false)
{
update_allow_transitive_dependencies = Request::UPDATE_LISTED_WITH_TRANSITIVE_DEPS;
flags += " --with-all-dependencies";
@@ -759,7 +790,10 @@ impl RequireCommand {
.get_option("update-with-dependencies")
.as_bool()
.unwrap_or(false)
- || input.get_option("with-dependencies").as_bool().unwrap_or(false)
+ || input
+ .get_option("with-dependencies")
+ .as_bool()
+ .unwrap_or(false)
{
update_allow_transitive_dependencies =
Request::UPDATE_LISTED_WITH_TRANSITIVE_DEPS_NO_ROOT_REQUIRE;
@@ -781,12 +815,7 @@ impl RequireCommand {
IOInterface::NORMAL,
);
- let command_event = CommandEvent::new(
- PluginEvents::COMMAND,
- "require",
- input,
- output,
- );
+ let command_event = CommandEvent::new(PluginEvents::COMMAND, "require", input, output);
composer
.get_event_dispatcher()
.dispatch(command_event.get_name(), &command_event);
@@ -813,19 +842,22 @@ impl RequireCommand {
.set_update(true)
.set_install(!input.get_option("no-install").as_bool().unwrap_or(false))
.set_update_allow_transitive_dependencies(update_allow_transitive_dependencies)
- .set_platform_requirement_filter(
- self.inner.get_platform_requirement_filter(input)?,
- )
+ .set_platform_requirement_filter(self.inner.get_platform_requirement_filter(input)?)
.set_prefer_stable(input.get_option("prefer-stable").as_bool().unwrap_or(false))
.set_prefer_lowest(input.get_option("prefer-lowest").as_bool().unwrap_or(false))
- .set_audit_config(self.inner.create_audit_config(composer.get_config(), input)?)
+ .set_audit_config(
+ self.inner
+ .create_audit_config(composer.get_config(), input)?,
+ )
.set_minimal_update(minimal_changes);
// if no lock is present, or the file is brand new, we do not do a
// partial update as this is not supported by the Installer
if !self.first_require && composer.get_locker().is_locked() {
install.set_update_allow_list(
- array_keys(requirements).into_iter().collect::<Vec<String>>(),
+ array_keys(requirements)
+ .into_iter()
+ .collect::<Vec<String>>(),
);
}
@@ -887,8 +919,7 @@ impl RequireCommand {
// TODO(phase-b): `$package instanceof AliasPackage` downcast
let mut package_as_alias: Option<&AliasPackage> = None;
while let Some(alias) = package_as_alias {
- package = Some(Box::new(alias.get_alias_of().clone())
- as Box<dyn PackageInterface>);
+ package = Some(Box::new(alias.get_alias_of().clone()) as Box<dyn PackageInterface>);
package_as_alias = None;
}
@@ -924,7 +955,10 @@ impl RequireCommand {
if Preg::is_match(
r"{^dev-(?!main$|master$|trunk$|latest$)}",
- requirements.get(package_name).map(|s| s.as_str()).unwrap_or(""),
+ requirements
+ .get(package_name)
+ .map(|s| s.as_str())
+ .unwrap_or(""),
)
.unwrap_or(false)
{
@@ -967,14 +1001,9 @@ impl RequireCommand {
for (package_name, flag) in &stability_flags_clone {
let entry = lock_data
.entry("stability-flags".to_string())
- .or_insert_with(|| {
- PhpMixed::Array(IndexMap::new())
- });
+ .or_insert_with(|| PhpMixed::Array(IndexMap::new()));
if let PhpMixed::Array(m) = entry {
- m.insert(
- package_name.clone(),
- Box::new(PhpMixed::Int(*flag)),
- );
+ m.insert(package_name.clone(), Box::new(PhpMixed::Int(*flag)));
}
}
@@ -1000,12 +1029,7 @@ impl RequireCommand {
return;
}
- let mut composer_definition = self
- .json
- .as_ref()
- .unwrap()
- .read()
- .unwrap_or_default();
+ let mut composer_definition = self.json.as_ref().unwrap().read().unwrap_or_default();
for (package, version) in new {
if let Some(section) = composer_definition
.entry(require_key.to_string())
@@ -1029,15 +1053,12 @@ impl RequireCommand {
composer_definition.shift_remove(remove_key);
}
}
- self.json
- .as_ref()
- .unwrap()
- .write(&PhpMixed::Array(
- composer_definition
- .into_iter()
- .map(|(k, v)| (k, Box::new(v)))
- .collect(),
- ));
+ self.json.as_ref().unwrap().write(&PhpMixed::Array(
+ composer_definition
+ .into_iter()
+ .map(|(k, v)| (k, Box::new(v)))
+ .collect(),
+ ));
}
/// @param array<string, string> $new
@@ -1069,12 +1090,7 @@ impl RequireCommand {
true
}
- pub(crate) fn interact(
- &self,
- _input: &dyn InputInterface,
- _output: &dyn OutputInterface,
- ) {
- }
+ pub(crate) fn interact(&self, _input: &dyn InputInterface, _output: &dyn OutputInterface) {}
fn revert_composer_file(&mut self) {
let io = self.inner.get_io();
diff --git a/crates/shirabe/src/command/run_script_command.rs b/crates/shirabe/src/command/run_script_command.rs
index 155a2f1..cbf85c0 100644
--- a/crates/shirabe/src/command/run_script_command.rs
+++ b/crates/shirabe/src/command/run_script_command.rs
@@ -47,27 +47,73 @@ impl RunScriptCommand {
.set_description("Runs the scripts defined in composer.json")
.set_definition(vec![
// completion callback (runtime script names) is deferred to Phase B
- InputArgument::new("script", Some(InputArgument::OPTIONAL), "Script name to run.", None, vec![]),
- InputArgument::new("args", Some(InputArgument::IS_ARRAY | InputArgument::OPTIONAL), "", None, vec![]),
- InputOption::new("timeout", None, Some(InputOption::VALUE_REQUIRED), "Sets script timeout in seconds, or 0 for never.", None, vec![]),
- InputOption::new("dev", None, Some(InputOption::VALUE_NONE), "Sets the dev mode.", None, vec![]),
- InputOption::new("no-dev", None, Some(InputOption::VALUE_NONE), "Disables the dev mode.", None, vec![]),
- InputOption::new("list", Some(PhpMixed::String("l".to_string())), Some(InputOption::VALUE_NONE), "List scripts.", None, vec![]),
+ InputArgument::new(
+ "script",
+ Some(InputArgument::OPTIONAL),
+ "Script name to run.",
+ None,
+ vec![],
+ ),
+ InputArgument::new(
+ "args",
+ Some(InputArgument::IS_ARRAY | InputArgument::OPTIONAL),
+ "",
+ None,
+ vec![],
+ ),
+ InputOption::new(
+ "timeout",
+ None,
+ Some(InputOption::VALUE_REQUIRED),
+ "Sets script timeout in seconds, or 0 for never.",
+ None,
+ vec![],
+ ),
+ InputOption::new(
+ "dev",
+ None,
+ Some(InputOption::VALUE_NONE),
+ "Sets the dev mode.",
+ None,
+ vec![],
+ ),
+ InputOption::new(
+ "no-dev",
+ None,
+ Some(InputOption::VALUE_NONE),
+ "Disables the dev mode.",
+ None,
+ vec![],
+ ),
+ InputOption::new(
+ "list",
+ Some(PhpMixed::String("l".to_string())),
+ Some(InputOption::VALUE_NONE),
+ "List scripts.",
+ None,
+ vec![],
+ ),
])
.set_help(
"The <info>run-script</info> command runs scripts defined in composer.json:\n\n\
<info>php composer.phar run-script post-update-cmd</info>\n\n\
- Read more at https://getcomposer.org/doc/03-cli.md#run-script-run"
+ Read more at https://getcomposer.org/doc/03-cli.md#run-script-run",
);
}
- pub fn interact(&self, input: &mut dyn InputInterface, _output: &dyn OutputInterface) -> Result<()> {
+ pub fn interact(
+ &self,
+ input: &mut dyn InputInterface,
+ _output: &dyn OutputInterface,
+ ) -> Result<()> {
let scripts = self.get_scripts()?;
if scripts.is_empty() {
return Ok(());
}
- if input.get_argument("script").as_string_opt().is_some() || input.get_option("list").as_bool().unwrap_or(false) {
+ if input.get_argument("script").as_string_opt().is_some()
+ || input.get_option("list").as_bool().unwrap_or(false)
+ {
return Ok(());
}
@@ -103,7 +149,8 @@ impl RunScriptCommand {
return Err(RuntimeException {
message: "Missing required argument \"script\"".to_string(),
code: 0,
- }.into());
+ }
+ .into());
}
Some(s) => s.to_string(),
};
@@ -114,33 +161,44 @@ impl RunScriptCommand {
return Err(InvalidArgumentException {
message: format!("Script \"{}\" cannot be run with this command", script),
code: 0,
- }.into());
+ }
+ .into());
}
}
let composer = self.inner.require_composer()?;
- let dev_mode = input.get_option("dev").as_bool().unwrap_or(false) || !input.get_option("no-dev").as_bool().unwrap_or(false);
+ let dev_mode = input.get_option("dev").as_bool().unwrap_or(false)
+ || !input.get_option("no-dev").as_bool().unwrap_or(false);
let event = ScriptEvent::new(script.clone(), &composer, self.inner.get_io(), dev_mode);
let has_listeners = composer.get_event_dispatcher().has_event_listeners(&event);
if !has_listeners {
return Err(InvalidArgumentException {
message: format!("Script \"{}\" is not defined in this package", script),
code: 0,
- }.into());
+ }
+ .into());
}
- let args: Vec<String> = input.get_argument("args")
+ let args: Vec<String> = input
+ .get_argument("args")
.as_list()
- .map(|l| l.iter().filter_map(|v| v.as_string().map(|s| s.to_string())).collect())
+ .map(|l| {
+ l.iter()
+ .filter_map(|v| v.as_string().map(|s| s.to_string()))
+ .collect()
+ })
.unwrap_or_default();
if let Some(timeout_val) = input.get_option("timeout").as_string_opt() {
let timeout_str = timeout_val.to_string();
if !timeout_str.chars().all(|c| c.is_ascii_digit()) {
return Err(RuntimeException {
- message: "Timeout value must be numeric and positive if defined, or 0 for forever".to_string(),
+ message:
+ "Timeout value must be numeric and positive if defined, or 0 for forever"
+ .to_string(),
code: 0,
- }.into());
+ }
+ .into());
}
let timeout: i64 = timeout_str.parse().unwrap_or(0);
ProcessExecutor::set_timeout(timeout);
@@ -148,7 +206,9 @@ impl RunScriptCommand {
Platform::put_env("COMPOSER_DEV_MODE", if dev_mode { "1" } else { "0" });
- Ok(composer.get_event_dispatcher().dispatch_script(&script, dev_mode, args)?)
+ Ok(composer
+ .get_event_dispatcher()
+ .dispatch_script(&script, dev_mode, args)?)
}
fn list_scripts(&self, output: &dyn OutputInterface) -> Result<i64> {
@@ -159,7 +219,8 @@ impl RunScriptCommand {
let io = self.inner.get_io();
io.write_error("<info>scripts:</info>");
- let table: Vec<Vec<String>> = scripts.iter()
+ let table: Vec<Vec<String>> = scripts
+ .iter()
.map(|(name, desc)| vec![format!(" {}", name), desc.clone()])
.collect();
@@ -176,7 +237,10 @@ impl RunScriptCommand {
let mut result: Vec<(String, String)> = vec![];
for (name, _script) in scripts {
- let description = self.inner.get_application().find(&name)
+ let description = self
+ .inner
+ .get_application()
+ .find(&name)
.map(|cmd| cmd.get_description().unwrap_or("").to_string())
.unwrap_or_default();
result.push((name, description));
diff --git a/crates/shirabe/src/command/script_alias_command.rs b/crates/shirabe/src/command/script_alias_command.rs
index ad26cd7..c5bacc4 100644
--- a/crates/shirabe/src/command/script_alias_command.rs
+++ b/crates/shirabe/src/command/script_alias_command.rs
@@ -1,14 +1,14 @@
//! ref: composer/src/Composer/Command/ScriptAliasCommand.php
-use anyhow::Result;
-use shirabe_external_packages::composer::pcre::preg::Preg;
-use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
-use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
-use shirabe_php_shim::{is_string, InvalidArgumentException, LogicException, PhpMixed};
use crate::command::base_command::BaseCommand;
use crate::console::input::input_argument::InputArgument;
use crate::console::input::input_option::InputOption;
use crate::util::platform::Platform;
+use anyhow::Result;
+use shirabe_external_packages::composer::pcre::preg::Preg;
+use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
+use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
+use shirabe_php_shim::{InvalidArgumentException, LogicException, PhpMixed, is_string};
pub struct ScriptAliasCommand {
inner: BaseCommand,
@@ -19,21 +19,30 @@ pub struct ScriptAliasCommand {
impl ScriptAliasCommand {
pub fn new(script: String, description: Option<String>, aliases: Vec<String>) -> Result<Self> {
- let description = description.unwrap_or_else(|| format!("Runs the {} script as defined in composer.json", script));
+ let description = description
+ .unwrap_or_else(|| format!("Runs the {} script as defined in composer.json", script));
for alias in &aliases {
if !is_string(&PhpMixed::String(alias.clone())) {
return Err(InvalidArgumentException {
- message: r#""scripts-aliases" element array values should contain only strings"#.to_string(),
+ message:
+ r#""scripts-aliases" element array values should contain only strings"#
+ .to_string(),
code: 0,
- }.into());
+ }
+ .into());
}
}
let mut inner = BaseCommand::new();
inner.ignore_validation_errors();
- Ok(Self { inner, script, description, aliases })
+ Ok(Self {
+ inner,
+ script,
+ description,
+ aliases,
+ })
}
pub fn configure(&mut self) {
@@ -42,18 +51,42 @@ impl ScriptAliasCommand {
.set_description(&self.description)
.set_aliases(self.aliases.clone())
.set_definition(vec![
- InputOption::new("dev", None, Some(InputOption::VALUE_NONE), "Sets the dev mode.", None, vec![]),
- InputOption::new("no-dev", None, Some(InputOption::VALUE_NONE), "Disables the dev mode.", None, vec![]),
- InputArgument::new("args", Some(InputArgument::IS_ARRAY | InputArgument::OPTIONAL), "", None, vec![]),
+ InputOption::new(
+ "dev",
+ None,
+ Some(InputOption::VALUE_NONE),
+ "Sets the dev mode.",
+ None,
+ vec![],
+ ),
+ InputOption::new(
+ "no-dev",
+ None,
+ Some(InputOption::VALUE_NONE),
+ "Disables the dev mode.",
+ None,
+ vec![],
+ ),
+ InputArgument::new(
+ "args",
+ Some(InputArgument::IS_ARRAY | InputArgument::OPTIONAL),
+ "",
+ None,
+ vec![],
+ ),
])
.set_help(
"The <info>run-script</info> command runs scripts defined in composer.json:\n\n\
<info>php composer.phar run-script post-update-cmd</info>\n\n\
- Read more at https://getcomposer.org/doc/03-cli.md#run-script-run"
+ Read more at https://getcomposer.org/doc/03-cli.md#run-script-run",
);
}
- pub fn execute(&mut self, input: &dyn InputInterface, _output: &dyn OutputInterface) -> Result<i64> {
+ pub fn execute(
+ &mut self,
+ input: &dyn InputInterface,
+ _output: &dyn OutputInterface,
+ ) -> Result<i64> {
let composer = self.inner.require_composer()?;
let args = input.get_arguments();
@@ -61,9 +94,13 @@ impl ScriptAliasCommand {
// TODO remove for Symfony 6+ as it is then in the interface
if !input.has_to_string() {
return Err(LogicException {
- message: format!("Expected an Input instance that is stringable, got {}", input.get_class_name()),
+ message: format!(
+ "Expected an Input instance that is stringable, got {}",
+ input.get_class_name()
+ ),
code: 0,
- }.into());
+ }
+ .into());
}
let dev_mode = input.get_option("dev").as_bool().unwrap_or(false)
@@ -73,10 +110,18 @@ impl ScriptAliasCommand {
let script_alias_input = Preg::replace_limit(r"^\S+ ?", "", &input.to_string(), 1);
let mut flags = indexmap::IndexMap::new();
- flags.insert("script-alias-input".to_string(), PhpMixed::String(script_alias_input));
+ flags.insert(
+ "script-alias-input".to_string(),
+ PhpMixed::String(script_alias_input),
+ );
let args_value = args.get("args").cloned().unwrap_or(PhpMixed::Null);
- Ok(composer.get_event_dispatcher().dispatch_script(&self.script, dev_mode, args_value, flags)?)
+ Ok(composer.get_event_dispatcher().dispatch_script(
+ &self.script,
+ dev_mode,
+ args_value,
+ flags,
+ )?)
}
}
diff --git a/crates/shirabe/src/command/search_command.rs b/crates/shirabe/src/command/search_command.rs
index 87c9e72..2c727e5 100644
--- a/crates/shirabe/src/command/search_command.rs
+++ b/crates/shirabe/src/command/search_command.rs
@@ -1,10 +1,5 @@
//! ref: composer/src/Composer/Command/SearchCommand.php
-use anyhow::Result;
-use shirabe_external_packages::symfony::console::formatter::output_formatter::OutputFormatter;
-use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
-use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
-use shirabe_php_shim::{implode, in_array, preg_quote, InvalidArgumentException, PhpMixed};
use crate::command::base_command::BaseCommand;
use crate::console::input::input_argument::InputArgument;
use crate::console::input::input_option::InputOption;
@@ -14,6 +9,11 @@ use crate::plugin::plugin_events::PluginEvents;
use crate::repository::composite_repository::CompositeRepository;
use crate::repository::platform_repository::PlatformRepository;
use crate::repository::repository_interface::RepositoryInterface;
+use anyhow::Result;
+use shirabe_external_packages::symfony::console::formatter::output_formatter::OutputFormatter;
+use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
+use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
+use shirabe_php_shim::{InvalidArgumentException, PhpMixed, implode, in_array, preg_quote};
#[derive(Debug)]
pub struct SearchCommand {
@@ -39,23 +39,43 @@ impl SearchCommand {
);
}
- pub fn execute(&mut self, input: &dyn InputInterface, output: &dyn OutputInterface) -> Result<i64> {
+ pub fn execute(
+ &mut self,
+ input: &dyn InputInterface,
+ output: &dyn OutputInterface,
+ ) -> Result<i64> {
let platform_repo = PlatformRepository;
let io = self.inner.get_io();
- let format = input.get_option("format").as_string_opt().map(|s| s.to_string()).unwrap_or_else(|| "text".to_string());
- if !in_array(PhpMixed::String(format.clone()), &PhpMixed::List(vec![Box::new(PhpMixed::String("text".to_string())), Box::new(PhpMixed::String("json".to_string()))]), false) {
- io.write_error(&format!("Unsupported format \"{}\". See help for supported formats.", format));
+ let format = input
+ .get_option("format")
+ .as_string_opt()
+ .map(|s| s.to_string())
+ .unwrap_or_else(|| "text".to_string());
+ if !in_array(
+ PhpMixed::String(format.clone()),
+ &PhpMixed::List(vec![
+ Box::new(PhpMixed::String("text".to_string())),
+ Box::new(PhpMixed::String("json".to_string())),
+ ]),
+ false,
+ ) {
+ io.write_error(&format!(
+ "Unsupported format \"{}\". See help for supported formats.",
+ format
+ ));
return Ok(1);
}
let composer = if let Some(c) = self.inner.try_composer() {
c
} else {
- self.inner.create_composer_instance(input, self.inner.get_io(), vec![])?
+ self.inner
+ .create_composer_instance(input, self.inner.get_io(), vec![])?
};
let local_repo = composer.get_repository_manager().get_local_repository();
- let installed_repo = CompositeRepository::new(vec![Box::new(local_repo), Box::new(platform_repo)]);
+ let installed_repo =
+ CompositeRepository::new(vec![Box::new(local_repo), Box::new(platform_repo)]);
let mut all_repos: Vec<Box<dyn RepositoryInterface>> = vec![Box::new(installed_repo)];
all_repos.extend(composer.get_repository_manager().get_repositories());
let repos = CompositeRepository::new(all_repos);
@@ -69,7 +89,9 @@ impl SearchCommand {
vec![],
vec![],
);
- composer.get_event_dispatcher().dispatch(command_event.get_name(), &command_event);
+ composer
+ .get_event_dispatcher()
+ .dispatch(command_event.get_name(), &command_event);
let mut mode: i64 = RepositoryInterface::SEARCH_FULLTEXT;
if input.get_option("only-name").as_bool().unwrap_or(false) {
@@ -77,18 +99,27 @@ impl SearchCommand {
return Err(InvalidArgumentException {
message: "--only-name and --only-vendor cannot be used together".to_string(),
code: 0,
- }.into());
+ }
+ .into());
}
mode = RepositoryInterface::SEARCH_NAME;
} else if input.get_option("only-vendor").as_bool().unwrap_or(false) {
mode = RepositoryInterface::SEARCH_VENDOR;
}
- let r#type = input.get_option("type").as_string_opt().map(|s| s.to_string());
+ let r#type = input
+ .get_option("type")
+ .as_string_opt()
+ .map(|s| s.to_string());
let tokens_arg = input.get_argument("tokens");
- let token_strings: Vec<String> = tokens_arg.as_array()
- .map(|arr| arr.values().filter_map(|v| v.as_string().map(|s| s.to_string())).collect())
+ let token_strings: Vec<String> = tokens_arg
+ .as_array()
+ .map(|arr| {
+ arr.values()
+ .filter_map(|v| v.as_string().map(|s| s.to_string()))
+ .collect()
+ })
.unwrap_or_default();
let mut query = implode(" ", &token_strings);
if mode != RepositoryInterface::SEARCH_FULLTEXT {
@@ -106,7 +137,11 @@ impl SearchCommand {
name_length += 1;
for result in &results {
let description = result.description.clone().unwrap_or_default();
- let warning = if result.abandoned.is_some() { "<warning>! Abandoned !</warning> " } else { "" };
+ let warning = if result.abandoned.is_some() {
+ "<warning>! Abandoned !</warning> "
+ } else {
+ ""
+ };
let remaining = width - name_length - warning.len() as i64 - 2;
let description = if description.len() as i64 > remaining {
format!("{}...", &description[..(remaining - 3) as usize])
@@ -125,7 +160,13 @@ impl SearchCommand {
description
));
} else {
- io.write(&format!("{:<width$}{}{}", result.name, warning, description, width = name_length as usize));
+ io.write(&format!(
+ "{:<width$}{}{}",
+ result.name,
+ warning,
+ description,
+ width = name_length as usize
+ ));
}
}
} else if format == "json" {
diff --git a/crates/shirabe/src/command/self_update_command.rs b/crates/shirabe/src/command/self_update_command.rs
index 444e8fc..f69476d 100644
--- a/crates/shirabe/src/command/self_update_command.rs
+++ b/crates/shirabe/src/command/self_update_command.rs
@@ -6,15 +6,15 @@ use shirabe_external_packages::symfony::component::console::input::input_interfa
use shirabe_external_packages::symfony::component::console::output::output_interface::OutputInterface;
use shirabe_external_packages::symfony::component::finder::finder::Finder;
use shirabe_php_shim::{
- array_map, base64_decode, basename_with_suffix, chmod, class_exists, copy, defined, dirname,
- end_arr, exec, extension_loaded, file_exists, file_get_contents, file_put_contents,
- fileowner, fileperms, function_exists, hash_file, ini_get, in_array, is_array, is_file,
- is_numeric, is_writable, iterator_to_array, json_decode, openssl_free_key,
- openssl_get_md_methods, openssl_pkey_get_public, openssl_verify, posix_geteuid,
- posix_getpwuid, random_int, rename, server_argv, sprintf, str_contains, str_replace, strpos,
- strtolower, strtr, tempnam, unlink, usleep, version_compare, InvalidArgumentException, Phar,
- PharException, PhpMixed, RuntimeException, UnexpectedValueException, OPENSSL_ALGO_SHA384,
- PHP_EOL, PHP_VERSION_ID,
+ InvalidArgumentException, OPENSSL_ALGO_SHA384, PHP_EOL, PHP_VERSION_ID, Phar, PharException,
+ PhpMixed, RuntimeException, UnexpectedValueException, array_map, base64_decode,
+ basename_with_suffix, chmod, class_exists, copy, defined, dirname, end_arr, exec,
+ extension_loaded, file_exists, file_get_contents, file_put_contents, fileowner, fileperms,
+ function_exists, hash_file, in_array, ini_get, is_array, is_file, is_numeric, is_writable,
+ iterator_to_array, json_decode, openssl_free_key, openssl_get_md_methods,
+ openssl_pkey_get_public, openssl_verify, posix_geteuid, posix_getpwuid, random_int, rename,
+ server_argv, sprintf, str_contains, str_replace, strpos, strtolower, strtr, tempnam, unlink,
+ usleep, version_compare,
};
use crate::command::base_command::BaseCommand;
@@ -154,11 +154,19 @@ impl SelfUpdateCommand {
}
}
- if input.get_option("set-channel-only").as_bool().unwrap_or(false) {
+ if input
+ .get_option("set-channel-only")
+ .as_bool()
+ .unwrap_or(false)
+ {
return Ok(0);
}
- let cache_dir = config.get("cache-dir").as_string().unwrap_or("").to_string();
+ let cache_dir = config
+ .get("cache-dir")
+ .as_string()
+ .unwrap_or("")
+ .to_string();
let rollback_dir = config.get("data-dir").as_string().unwrap_or("").to_string();
let home = config.get("home").as_string().unwrap_or("").to_string();
let local_filename = Phar::running(false);
@@ -414,7 +422,8 @@ impl SelfUpdateCommand {
],
);
- let updating_to_tag = !Preg::is_match(r"{^[0-9a-f]{40}$}", &update_version).unwrap_or(false);
+ let updating_to_tag =
+ !Preg::is_match(r"{^[0-9a-f]{40}$}", &update_version).unwrap_or(false);
io.write(
PhpMixed::String(sprintf(
@@ -458,16 +467,9 @@ impl SelfUpdateCommand {
IOInterface::NORMAL,
);
http_downloader.copy(&remote_filename, &temp_filename)?;
- io.write_error(
- PhpMixed::String(String::new()),
- true,
- IOInterface::NORMAL,
- );
+ io.write_error(PhpMixed::String(String::new()), true, IOInterface::NORMAL);
- if !file_exists(&temp_filename)
- || signature.is_none()
- || signature.as_deref() == Some("")
- {
+ if !file_exists(&temp_filename) || signature.is_none() || signature.as_deref() == Some("") {
io.write_error(
PhpMixed::String(
"<error>The download of the new composer version failed for an unexpected reason</error>"
@@ -675,20 +677,21 @@ RGv89BPD+2DLnJysngsvVaUCAwEAAQ==\n\
);
// TODO(phase-b): closure captures none; PHP throws inside the closure on bad input
- let validator: Box<dyn Fn(PhpMixed) -> PhpMixed> = Box::new(|value: PhpMixed| -> PhpMixed {
- let value_str = value.as_string().unwrap_or("").to_string();
- if !Preg::is_match(r"{^-----BEGIN PUBLIC KEY-----$}", &shirabe_php_shim::trim(&value_str, None))
+ let validator: Box<dyn Fn(PhpMixed) -> PhpMixed> =
+ Box::new(|value: PhpMixed| -> PhpMixed {
+ let value_str = value.as_string().unwrap_or("").to_string();
+ if !Preg::is_match(
+ r"{^-----BEGIN PUBLIC KEY-----$}",
+ &shirabe_php_shim::trim(&value_str, None),
+ )
.unwrap_or(false)
- {
- // TODO(phase-b): closure cannot throw
- panic!("{}", "Invalid input");
- }
+ {
+ // TODO(phase-b): closure cannot throw
+ panic!("{}", "Invalid input");
+ }
- PhpMixed::String(format!(
- "{}\n",
- shirabe_php_shim::trim(&value_str, None)
- ))
- });
+ PhpMixed::String(format!("{}\n", shirabe_php_shim::trim(&value_str, None)))
+ });
let mut dev_key = String::new();
let mut match_: Option<String> = None;
@@ -717,17 +720,17 @@ RGv89BPD+2DLnJysngsvVaUCAwEAAQ==\n\
if line_str.is_empty() {
break;
}
- dev_key.push_str(&format!(
- "{}\n",
- shirabe_php_shim::trim(&line_str, None)
- ));
+ dev_key.push_str(&format!("{}\n", shirabe_php_shim::trim(&line_str, None)));
if shirabe_php_shim::trim(&line_str, None) == "-----END PUBLIC KEY-----" {
break;
}
}
}
let _ = &validator;
- let key_path = format!("{}/keys.dev.pub", config.get("home").as_string().unwrap_or(""));
+ let key_path = format!(
+ "{}/keys.dev.pub",
+ config.get("home").as_string().unwrap_or("")
+ );
file_put_contents(&key_path, match_.as_deref().unwrap_or(""));
io.write(
PhpMixed::String(format!(
@@ -765,16 +768,16 @@ RGv89BPD+2DLnJysngsvVaUCAwEAAQ==\n\
if line_str.is_empty() {
break;
}
- tags_key.push_str(&format!(
- "{}\n",
- shirabe_php_shim::trim(&line_str, None)
- ));
+ tags_key.push_str(&format!("{}\n", shirabe_php_shim::trim(&line_str, None)));
if shirabe_php_shim::trim(&line_str, None) == "-----END PUBLIC KEY-----" {
break;
}
}
}
- let key_path = format!("{}/keys.tags.pub", config.get("home").as_string().unwrap_or(""));
+ let key_path = format!(
+ "{}/keys.tags.pub",
+ config.get("home").as_string().unwrap_or("")
+ );
file_put_contents(&key_path, match_.as_deref().unwrap_or(""));
io.write(
PhpMixed::String(format!(
@@ -821,12 +824,17 @@ RGv89BPD+2DLnJysngsvVaUCAwEAAQ==\n\
let old_file = format!(
"{}/{}{}",
- rollback_dir, rollback_version, Self::OLD_INSTALL_EXT
+ rollback_dir,
+ rollback_version,
+ Self::OLD_INSTALL_EXT
);
if !is_file(&old_file) {
return Err(FilesystemException::new(
- format!("Composer rollback failed: \"{}\" could not be found", old_file),
+ format!(
+ "Composer rollback failed: \"{}\" could not be found",
+ old_file
+ ),
0,
)
.0
@@ -834,7 +842,10 @@ RGv89BPD+2DLnJysngsvVaUCAwEAAQ==\n\
}
if !Filesystem::is_readable(&old_file) {
return Err(FilesystemException::new(
- format!("Composer rollback failed: \"{}\" could not be read", old_file),
+ format!(
+ "Composer rollback failed: \"{}\" could not be read",
+ old_file
+ ),
0,
)
.0
@@ -877,7 +888,11 @@ RGv89BPD+2DLnJysngsvVaUCAwEAAQ==\n\
io.write_error(
PhpMixed::String(format!(
"<error>The {} file is corrupted ({})</error>",
- if backup_target.is_some() { "update" } else { "backup" },
+ if backup_target.is_some() {
+ "update"
+ } else {
+ "backup"
+ },
error.unwrap_or_default()
)),
true,
@@ -931,15 +946,16 @@ RGv89BPD+2DLnJysngsvVaUCAwEAAQ==\n\
let _ = unlink(new_filename);
let action = format!(
"Composer {}",
- if backup_target.is_some() { "update" } else { "rollback" }
+ if backup_target.is_some() {
+ "update"
+ } else {
+ "rollback"
+ }
);
Err(FilesystemException::new(
format!(
"{} failed: \"{}\" could not be written.{}{}",
- action,
- local_filename,
- PHP_EOL,
- e
+ action, local_filename, PHP_EOL, e
),
0,
)
@@ -1061,7 +1077,8 @@ RGv89BPD+2DLnJysngsvVaUCAwEAAQ==\n\
IOInterface::NORMAL,
);
let help_message = "Please run the self-update command as an Administrator.";
- let question = "Complete this operation with Administrator privileges [<comment>Y,n</comment>]? ";
+ let question =
+ "Complete this operation with Administrator privileges [<comment>Y,n</comment>]? ";
if !io.ask_confirmation(question.to_string(), true) {
io.write_error(
@@ -1081,10 +1098,7 @@ RGv89BPD+2DLnJysngsvVaUCAwEAAQ==\n\
Some(f) => f,
None => {
io.write_error(
- PhpMixed::String(format!(
- "<error>Operation failed. {}</error>",
- help_message
- )),
+ PhpMixed::String(format!("<error>Operation failed. {}</error>", help_message)),
true,
IOInterface::NORMAL,
);
@@ -1095,7 +1109,11 @@ RGv89BPD+2DLnJysngsvVaUCAwEAAQ==\n\
let mut output: Vec<String> = vec![];
let mut exit_code: i64 = 0;
- exec("sudo config 2> NUL", Some(&mut output), Some(&mut exit_code));
+ exec(
+ "sudo config 2> NUL",
+ Some(&mut output),
+ Some(&mut exit_code),
+ );
let using_sudo = exit_code == 0;
let script = if using_sudo {
@@ -1151,10 +1169,7 @@ RGv89BPD+2DLnJysngsvVaUCAwEAAQ==\n\
);
} else {
io.write_error(
- PhpMixed::String(format!(
- "<error>Operation failed. {}</error>",
- help_message
- )),
+ PhpMixed::String(format!("<error>Operation failed. {}</error>", help_message)),
true,
IOInterface::NORMAL,
);
diff --git a/crates/shirabe/src/command/show_command.rs b/crates/shirabe/src/command/show_command.rs
index da060f1..8b5e967 100644
--- a/crates/shirabe/src/command/show_command.rs
+++ b/crates/shirabe/src/command/show_command.rs
@@ -10,8 +10,8 @@ use shirabe_external_packages::symfony::console::formatter::output_formatter_sty
use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
use shirabe_php_shim::{
- array_search, date, extension_loaded, in_array, realpath, strtolower, version_compare,
- InvalidArgumentException, LogicException, PhpMixed, UnexpectedValueException,
+ InvalidArgumentException, LogicException, PhpMixed, UnexpectedValueException, array_search,
+ date, extension_loaded, in_array, realpath, strtolower, version_compare,
};
use shirabe_semver::constraint::constraint_interface::ConstraintInterface;
@@ -73,9 +73,7 @@ impl ShowCommand {
);
}
- pub fn suggest_package_based_on_mode(
- &self,
- ) -> Box<dyn Fn(&CompletionInput) -> Vec<String>> {
+ pub fn suggest_package_based_on_mode(&self) -> Box<dyn Fn(&CompletionInput) -> Vec<String>> {
// return function (CompletionInput $input) { ... }
Box::new(|_input: &CompletionInput| -> Vec<String> {
// TODO(plugin): inspect $input->getOption() and dispatch to specific suggesters
@@ -104,12 +102,7 @@ impl ShowCommand {
if input.get_option("outdated").as_bool() == Some(true) {
input.set_option("latest", PhpMixed::Bool(true));
- } else if input
- .get_option("ignore")
- .as_list()
- .map_or(0, |l| l.len())
- > 0
- {
+ } else if input.get_option("ignore").as_list().map_or(0, |l| l.len()) > 0 {
io.write_error("<warning>You are using the option \"ignore\" for action other than \"outdated\", it will be ignored.</warning>");
}
@@ -141,7 +134,9 @@ impl ShowCommand {
.filter(|b| **b)
.count();
if only_count > 1 {
- io.write_error("Only one of --major-only, --minor-only or --patch-only can be used at once");
+ io.write_error(
+ "Only one of --major-only, --minor-only or --patch-only can be used at once",
+ );
return Ok(1);
}
@@ -149,7 +144,9 @@ impl ShowCommand {
if input.get_option("tree").as_bool() == Some(true)
&& input.get_option("latest").as_bool() == Some(true)
{
- io.write_error("The --tree (-t) option is not usable in combination with --latest (-l)");
+ io.write_error(
+ "The --tree (-t) option is not usable in combination with --latest (-l)",
+ );
return Ok(1);
}
@@ -226,8 +223,9 @@ impl ShowCommand {
)]));
single_package = package.into_complete_package_interface();
} else if input.get_option("platform").as_bool() == Some(true) {
- installed_repo =
- Box::new(InstalledRepository::new(vec![Box::new(platform_repo.clone())]));
+ installed_repo = Box::new(InstalledRepository::new(vec![Box::new(
+ platform_repo.clone(),
+ )]));
repos = Box::new(InstalledRepository::new(vec![Box::new(
platform_repo.clone(),
)]));
@@ -240,8 +238,7 @@ impl ShowCommand {
ir.add_repository(composer.get_repository_manager().get_local_repository());
installed_repo = Box::new(ir);
} else {
- let default_repos =
- RepositoryFactory::default_repos_with_default_manager(io);
+ let default_repos = RepositoryFactory::default_repos_with_default_manager(io);
let names: Vec<String> = default_repos.keys().cloned().collect();
repos = Box::new(CompositeRepository::new(
default_repos.into_values().collect(),
@@ -270,15 +267,13 @@ impl ShowCommand {
Box::new(platform_repo.clone()),
]));
}
- let mut composite_input: Vec<Box<dyn RepositoryInterface>> =
- vec![Box::new(FilterRepository::new(
- installed_repo.as_repository_interface().clone_box(),
- {
- let mut m = IndexMap::new();
- m.insert("canonical".to_string(), PhpMixed::Bool(false));
- m
- },
- ))];
+ let mut composite_input: Vec<Box<dyn RepositoryInterface>> = vec![Box::new(
+ FilterRepository::new(installed_repo.as_repository_interface().clone_box(), {
+ let mut m = IndexMap::new();
+ m.insert("canonical".to_string(), PhpMixed::Bool(false));
+ m
+ }),
+ )];
for r in composer_ref.get_repository_manager().get_repositories() {
composite_input.push(r);
}
@@ -389,12 +384,16 @@ impl ShowCommand {
}
if input.get_option("latest").as_bool() == Some(true) && composer.is_none() {
- io.write_error("No composer.json found in the current directory, disabling \"latest\" option");
+ io.write_error(
+ "No composer.json found in the current directory, disabling \"latest\" option",
+ );
input.set_option("latest", PhpMixed::Bool(false));
}
- let package_filter: Option<String> =
- input.get_argument("package").as_string().map(|s| s.to_string());
+ let package_filter: Option<String> = input
+ .get_argument("package")
+ .as_string()
+ .map(|s| s.to_string());
// show single package or single version
if let Some(ref pkg) = single_package {
@@ -404,12 +403,8 @@ impl ShowCommand {
);
} else if let Some(ref pf) = package_filter {
if !pf.contains('*') {
- let (matched_package, vers) = self.get_package(
- &*installed_repo,
- &*repos,
- pf,
- input.get_argument("version"),
- )?;
+ let (matched_package, vers) =
+ self.get_package(&*installed_repo, &*repos, pf, input.get_argument("version"))?;
if let Some(ref pkg) = matched_package {
if input.get_option("direct").as_bool() == Some(true) {
@@ -458,7 +453,9 @@ impl ShowCommand {
if input.get_option("all").as_bool() != Some(true)
&& input.get_option("available").as_bool() != Some(true)
{
- hint.push_str(", try using --available (-a) to show all available packages");
+ hint.push_str(
+ ", try using --available (-a) to show all available packages",
+ );
}
return Err(InvalidArgumentException {
@@ -541,8 +538,7 @@ impl ShowCommand {
.get_install_path(package.as_package_interface());
if let Some(path) = path {
let real = realpath(&path).unwrap_or_default();
- let trimmed =
- real.split(|c| c == '\r' || c == '\n').next().unwrap_or("");
+ let trimmed = real.split(|c| c == '\r' || c == '\n').next().unwrap_or("");
io.write(&format!(" {}", trimmed));
} else {
io.write(" null");
@@ -615,9 +611,7 @@ impl ShowCommand {
),
);
io.write(&JsonFile::encode(
- &PhpMixed::Array(
- wrapper.into_iter().map(|(k, v)| (k, Box::new(v))).collect(),
- ),
+ &PhpMixed::Array(wrapper.into_iter().map(|(k, v)| (k, Box::new(v))).collect()),
0,
)?);
} else {
@@ -632,8 +626,7 @@ impl ShowCommand {
let mut package_filter_regex: Option<String> = None;
if let Some(ref pf) = package_filter {
let escaped = shirabe_php_shim::preg_quote(pf, None);
- package_filter_regex =
- Some(format!("{{^{}$}}i", escaped.replace("\\*", ".*?")));
+ package_filter_regex = Some(format!("{{^{}$}}i", escaped.replace("\\*", ".*?")));
}
let mut package_list_filter: Option<Vec<String>> = None;
@@ -642,7 +635,9 @@ impl ShowCommand {
}
if input.get_option("path").as_bool() == Some(true) && composer.is_none() {
- io.write_error("No composer.json found in the current directory, disabling \"path\" option");
+ io.write_error(
+ "No composer.json found in the current directory, disabling \"path\" option",
+ );
input.set_option("path", PhpMixed::Bool(false));
}
@@ -652,11 +647,13 @@ impl ShowCommand {
} else if let Some(ref lr) = locked_repo {
if Self::same_repository_dyn(&*repo, &**lr) {
"locked"
- } else if Self::same_repository_dyn(&*repo, installed_repo.as_repository_interface())
- || installed_repo
- .get_repositories()
- .iter()
- .any(|r| Self::same_repository_dyn(&*repo, &**r))
+ } else if Self::same_repository_dyn(
+ &*repo,
+ installed_repo.as_repository_interface(),
+ ) || installed_repo
+ .get_repositories()
+ .iter()
+ .any(|r| Self::same_repository_dyn(&*repo, &**r))
{
"installed"
} else {
@@ -688,11 +685,9 @@ impl ShowCommand {
let need_replace = match existing {
None => true,
Some(PackageOrName::Name(_)) => true,
- Some(PackageOrName::Pkg(existing)) => version_compare(
- existing.get_version(),
- package.get_version(),
- "<",
- ),
+ Some(PackageOrName::Pkg(existing)) => {
+ version_compare(existing.get_version(), package.get_version(), "<")
+ }
};
if need_replace {
let mut p: Box<dyn PackageInterface> = package.clone_box();
@@ -720,10 +715,7 @@ impl ShowCommand {
packages
.entry(type_owned.clone())
.or_insert_with(IndexMap::new)
- .insert(
- p.get_name().to_string(),
- PackageOrName::Pkg(p),
- );
+ .insert(p.get_name().to_string(), PackageOrName::Pkg(p));
}
}
}
@@ -782,10 +774,8 @@ impl ShowCommand {
if show_latest && *show_version {
for package_or_name in type_packages.values() {
if let PackageOrName::Pkg(package) = package_or_name {
- if !Preg::is_match(
- &ignored_packages_regex,
- package.get_pretty_name(),
- )? {
+ if !Preg::is_match(&ignored_packages_regex, package.get_pretty_name())?
+ {
let latest = self.find_latest_package(
&**package,
composer.as_ref().unwrap(),
@@ -799,10 +789,8 @@ impl ShowCommand {
continue;
}
- latest_packages.insert(
- package.get_pretty_name().to_string(),
- latest.unwrap(),
- );
+ latest_packages
+ .insert(package.get_pretty_name().to_string(), latest.unwrap());
}
}
}
@@ -845,8 +833,7 @@ impl ShowCommand {
// Determine if Composer is checking outdated dependencies and if current package should trigger non-default exit code
let mut package_is_up_to_date = if let Some(latest) = latest_package {
- latest.get_full_pretty_version()
- == package.get_full_pretty_version()
+ latest.get_full_pretty_version() == package.get_full_pretty_version()
&& latest
.as_complete_package_interface()
.map_or(true, |c| !c.is_abandoned())
@@ -854,12 +841,10 @@ impl ShowCommand {
false
};
// When using --major-only, and no bigger version than current major is found then it is considered up to date
- package_is_up_to_date = package_is_up_to_date
- || (latest_package.is_none() && show_major_only);
- let package_is_ignored = Preg::is_match(
- &ignored_packages_regex,
- package.get_pretty_name(),
- )?;
+ package_is_up_to_date =
+ package_is_up_to_date || (latest_package.is_none() && show_major_only);
+ let package_is_ignored =
+ Preg::is_match(&ignored_packages_regex, package.get_pretty_name())?;
if input.get_option("outdated").as_bool() == Some(true)
&& (package_is_up_to_date || package_is_ignored)
{
@@ -889,8 +874,7 @@ impl ShowCommand {
true,
)),
);
- if format != "json"
- || input.get_option("name-only").as_bool() != Some(true)
+ if format != "json" || input.get_option("name-only").as_bool() != Some(true)
{
package_view_data.insert(
"homepage".to_string(),
@@ -917,10 +901,8 @@ impl ShowCommand {
version_str = version_str.trim_start_matches('v').to_string();
}
version_length = version_length.max(version_str.len());
- package_view_data.insert(
- "version".to_string(),
- PhpMixed::String(version_str),
- );
+ package_view_data
+ .insert("version".to_string(), PhpMixed::String(version_str));
}
if write_release_date {
if let Some(release_date) = package.get_release_date() {
@@ -958,10 +940,8 @@ impl ShowCommand {
}
let update_status = Self::get_update_status(&**latest, &**package);
latest_length = latest_length.max(latest_version_str.len());
- package_view_data.insert(
- "latest".to_string(),
- PhpMixed::String(latest_version_str),
- );
+ package_view_data
+ .insert("latest".to_string(), PhpMixed::String(latest_version_str));
package_view_data.insert(
"latest-status".to_string(),
PhpMixed::String(update_status),
@@ -1012,8 +992,7 @@ impl ShowCommand {
PhpMixed::String(trimmed.to_string()),
);
} else {
- package_view_data
- .insert("path".to_string(), PhpMixed::Null);
+ package_view_data.insert("path".to_string(), PhpMixed::Null);
}
}
@@ -1045,8 +1024,7 @@ impl ShowCommand {
}
}
- package_view_data
- .insert("abandoned".to_string(), package_is_abandoned);
+ package_view_data.insert("abandoned".to_string(), package_is_abandoned);
} else if let PackageOrName::Name(name) = package_or_name {
package_view_data
.insert("name".to_string(), PhpMixed::String(name.clone()));
@@ -1093,7 +1071,10 @@ impl ShowCommand {
}
io.write(&JsonFile::encode(
&PhpMixed::Array(
- json_map.into_iter().map(|(k, v)| (k, Box::new(v))).collect(),
+ json_map
+ .into_iter()
+ .map(|(k, v)| (k, Box::new(v)))
+ .collect(),
),
0,
)?);
@@ -1111,7 +1092,9 @@ impl ShowCommand {
} else {
io.write_error("<info>Color legend:</info>");
io.write_error("- <highlight>patch or minor</highlight> release available - update recommended");
- io.write_error("- <comment>major</comment> release available - update possible");
+ io.write_error(
+ "- <comment>major</comment> release available - update possible",
+ );
if input.get_option("outdated").as_bool() != Some(true) {
io.write_error("- <info>up to date</info> version");
}
@@ -1134,18 +1117,11 @@ impl ShowCommand {
let version_fits = name_length + version_length + 3 <= width;
let latest_fits = name_length + version_length + latest_length + 3 <= width;
- let release_date_fits = name_length
- + version_length
- + latest_length
- + release_date_length
- + 3
- <= width;
- let description_fits = name_length
- + version_length
- + latest_length
- + release_date_length
- + 24
- <= width;
+ let release_date_fits =
+ name_length + version_length + latest_length + release_date_length + 3 <= width;
+ let description_fits =
+ name_length + version_length + latest_length + release_date_length + 24
+ <= width;
if latest_fits && !io.is_decorated() {
latest_length += 2;
@@ -1195,7 +1171,9 @@ impl ShowCommand {
io.write_error("Everything up to date");
}
io.write_error("");
- io.write_error("<info>Transitive dependencies not required in composer.json:</>");
+ io.write_error(
+ "<info>Transitive dependencies not required in composer.json:</>",
+ );
if !transitive_deps.is_empty() {
self.print_packages(
io,
@@ -1259,8 +1237,7 @@ impl ShowCommand {
write_release_date: bool,
release_date_length: usize,
) {
- let pad_name =
- write_version || write_latest || write_release_date || write_description;
+ let pad_name = write_version || write_latest || write_release_date || write_description;
let pad_version = write_latest || write_release_date || write_description;
let pad_latest = write_description || write_release_date;
let pad_release_date = write_description;
@@ -1298,21 +1275,12 @@ impl ShowCommand {
));
} else {
let width_pad = if pad_name { name_length } else { 0 };
- io.write_no_newline(&format!(
- "{}{:<width$}",
- indent,
- name,
- width = width_pad
- ));
+ io.write_no_newline(&format!("{}{:<width$}", indent, name, width = width_pad));
}
if let Some(version) = package.get("version").and_then(|v| v.as_string()) {
if write_version {
let width_pad = if pad_version { version_length } else { 0 };
- io.write_no_newline(&format!(
- " {:<width$}",
- version,
- width = width_pad
- ));
+ io.write_no_newline(&format!(" {:<width$}", version, width = width_pad));
}
}
if let (Some(latest_version), Some(update_status)) = (
@@ -1338,19 +1306,13 @@ impl ShowCommand {
width = width_pad
));
if write_release_date {
- if let Some(age) =
- package.get("release-age").and_then(|v| v.as_string())
- {
+ if let Some(age) = package.get("release-age").and_then(|v| v.as_string()) {
let width_pad = if pad_release_date {
release_date_length
} else {
0
};
- io.write_no_newline(&format!(
- " {:<width$}",
- age,
- width = width_pad
- ));
+ io.write_no_newline(&format!(" {:<width$}", age, width = width_pad));
}
}
}
@@ -1440,11 +1402,8 @@ impl ShowCommand {
latest_package: &dyn PackageInterface,
package: &dyn PackageInterface,
) -> String {
- Self::update_status_to_version_style(&Self::get_update_status(
- latest_package,
- package,
- ))
- .to_string()
+ Self::update_status_to_version_style(&Self::get_update_status(latest_package, package))
+ .to_string()
}
/// finds a package by name and version if provided
@@ -1454,8 +1413,10 @@ impl ShowCommand {
repos: &dyn RepositoryInterface,
name: &str,
version: PhpMixed,
- ) -> anyhow::Result<(Option<Box<dyn CompletePackageInterface>>, IndexMap<String, String>)>
- {
+ ) -> anyhow::Result<(
+ Option<Box<dyn CompletePackageInterface>>,
+ IndexMap<String, String>,
+ )> {
let name = strtolower(name);
let constraint: Option<Box<dyn ConstraintInterface>> = match &version {
PhpMixed::String(s) => Some(self.version_parser.parse_constraints(s)?),
@@ -1562,7 +1523,10 @@ impl ShowCommand {
&& installed_repo.has_package(package.as_package_interface());
let io = self.inner.get_io();
- io.write(&format!("<info>name</info> : {}", package.get_pretty_name()));
+ io.write(&format!(
+ "<info>name</info> : {}",
+ package.get_pretty_name()
+ ));
io.write(&format!(
"<info>descrip.</info> : {}",
package.get_description()
@@ -1603,7 +1567,10 @@ impl ShowCommand {
} else {
package.as_package_interface()
};
- io.write(&format!("<info>type</info> : {}", package.get_type_field()));
+ io.write(&format!(
+ "<info>type</info> : {}",
+ package.get_type_field()
+ ));
self.print_licenses(package);
io.write(&format!(
"<info>homepage</info> : {}",
@@ -1643,10 +1610,7 @@ impl ShowCommand {
if let Some(c) = latest.as_complete_package_interface() {
if c.is_abandoned() {
let replacement = match c.get_replacement_package() {
- Some(rp) => format!(
- " The author suggests using the {} package instead.",
- rp
- ),
+ Some(rp) => format!(" The author suggests using the {} package instead.", rp),
None => String::new(),
};
@@ -1726,8 +1690,7 @@ impl ShowCommand {
.collect();
if let Some(found) = array_search(&installed_version, &key_map) {
if let Some(idx) = versions_keys.iter().position(|v| v == &found) {
- versions_keys[idx] =
- format!("<info>* {}</info>", installed_version);
+ versions_keys[idx] = format!("<info>* {}</info>", installed_version);
}
}
}
@@ -1783,10 +1746,7 @@ impl ShowCommand {
license.fullname, license_id, license.url
)
} else {
- format!(
- "{} ({}) {}",
- license.fullname, license_id, license.url
- )
+ format!("{} ({}) {}", license.fullname, license_id, license.url)
}
}
};
@@ -1917,10 +1877,7 @@ impl ShowCommand {
}
if let Some(rd) = package.get_release_date() {
- json.insert(
- "released".to_string(),
- PhpMixed::String(rd.to_rfc3339()),
- );
+ json.insert("released".to_string(), PhpMixed::String(rd.to_rfc3339()));
}
}
@@ -1976,9 +1933,7 @@ impl ShowCommand {
json = Self::append_links(json, package);
self.inner.get_io().write(&JsonFile::encode(
- &PhpMixed::Array(
- json.into_iter().map(|(k, v)| (k, Box::new(v))).collect(),
- ),
+ &PhpMixed::Array(json.into_iter().map(|(k, v)| (k, Box::new(v))).collect()),
0,
)?);
Ok(())
@@ -1988,8 +1943,10 @@ impl ShowCommand {
mut json: IndexMap<String, PhpMixed>,
versions: &IndexMap<String, String>,
) -> IndexMap<String, PhpMixed> {
- let mut versions_pairs: Vec<(String, String)> =
- versions.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
+ let mut versions_pairs: Vec<(String, String)> = versions
+ .iter()
+ .map(|(k, v)| (k.clone(), v.clone()))
+ .collect();
// uasort($versions, 'version_compare');
versions_pairs.sort_by(|a, b| {
if version_compare(&a.1, &b.1, "<") {
@@ -2032,9 +1989,7 @@ impl ShowCommand {
m.insert("name".to_string(), PhpMixed::String(l.fullname));
m.insert("osi".to_string(), PhpMixed::String(license_id));
m.insert("url".to_string(), PhpMixed::String(l.url));
- PhpMixed::Array(
- m.into_iter().map(|(k, v)| (k, Box::new(v))).collect(),
- )
+ PhpMixed::Array(m.into_iter().map(|(k, v)| (k, Box::new(v))).collect())
}
}
})
@@ -2083,9 +2038,7 @@ impl ShowCommand {
autoload.insert(
r#type.clone(),
- PhpMixed::Array(
- psr.into_iter().map(|(k, v)| (k, Box::new(v))).collect(),
- ),
+ PhpMixed::Array(psr.into_iter().map(|(k, v)| (k, Box::new(v))).collect()),
);
} else if r#type == "classmap" {
autoload.insert("classmap".to_string(), autoloads.clone());
@@ -2095,7 +2048,10 @@ impl ShowCommand {
json.insert(
"autoload".to_string(),
PhpMixed::Array(
- autoload.into_iter().map(|(k, v)| (k, Box::new(v))).collect(),
+ autoload
+ .into_iter()
+ .map(|(k, v)| (k, Box::new(v)))
+ .collect(),
),
);
}
@@ -2155,10 +2111,7 @@ impl ShowCommand {
}
/// Display the tree
- pub(crate) fn display_package_tree(
- &self,
- array_tree: Vec<IndexMap<String, PhpMixed>>,
- ) {
+ pub(crate) fn display_package_tree(&self, array_tree: Vec<IndexMap<String, PhpMixed>>) {
let io = self.inner.get_io();
for package in array_tree.iter() {
let name = package
@@ -2259,8 +2212,7 @@ impl ShowCommand {
];
let mut tree_child_desc: IndexMap<String, PhpMixed> = IndexMap::new();
- tree_child_desc
- .insert("name".to_string(), PhpMixed::String(require_name.clone()));
+ tree_child_desc.insert("name".to_string(), PhpMixed::String(require_name.clone()));
tree_child_desc.insert(
"version".to_string(),
PhpMixed::String(require.get_pretty_constraint().to_string()),
@@ -2374,12 +2326,7 @@ impl ShowCommand {
let circular_warn = if in_array(
PhpMixed::String(require_name.clone()),
- &PhpMixed::List(
- current_tree
- .iter()
- .map(|v| Box::new(v.clone()))
- .collect(),
- ),
+ &PhpMixed::List(current_tree.iter().map(|v| Box::new(v.clone())).collect()),
true,
) {
"(circular dependency aborted here)"
@@ -2425,10 +2372,7 @@ impl ShowCommand {
let mut current_tree = packages_in_tree.to_vec();
let mut tree_child_desc: IndexMap<String, PhpMixed> = IndexMap::new();
- tree_child_desc.insert(
- "name".to_string(),
- PhpMixed::String(require_name.clone()),
- );
+ tree_child_desc.insert("name".to_string(), PhpMixed::String(require_name.clone()));
tree_child_desc.insert(
"version".to_string(),
PhpMixed::String(require.get_pretty_constraint().to_string()),
@@ -2436,9 +2380,7 @@ impl ShowCommand {
if !in_array(
PhpMixed::String(require_name.clone()),
- &PhpMixed::List(
- current_tree.iter().map(|v| Box::new(v.clone())).collect(),
- ),
+ &PhpMixed::List(current_tree.iter().map(|v| Box::new(v.clone())).collect()),
true,
) {
current_tree.push(PhpMixed::String(require_name.clone()));
@@ -2457,9 +2399,7 @@ impl ShowCommand {
.into_iter()
.map(|m| {
Box::new(PhpMixed::Array(
- m.into_iter()
- .map(|(k, v)| (k, Box::new(v)))
- .collect(),
+ m.into_iter().map(|(k, v)| (k, Box::new(v))).collect(),
))
})
.collect(),
@@ -2595,9 +2535,12 @@ impl ShowCommand {
}
if patch_only {
- let trimmed_version =
- Preg::replace(r"{(\.0)+$}D", "", package.get_version())?;
- let parts_needed = if trimmed_version.starts_with('0') { 4 } else { 3 };
+ let trimmed_version = Preg::replace(r"{(\.0)+$}D", "", package.get_version())?;
+ let parts_needed = if trimmed_version.starts_with('0') {
+ 4
+ } else {
+ 3
+ };
let mut trimmed_version = trimmed_version;
while trimmed_version.chars().filter(|&c| c == '.').count() + 1 < parts_needed {
trimmed_version.push_str(".0");
@@ -2641,10 +2584,7 @@ impl ShowCommand {
Ok(candidate)
}
- fn get_repository_set(
- &mut self,
- composer: &Composer,
- ) -> anyhow::Result<&mut RepositorySet> {
+ fn get_repository_set(&mut self, composer: &Composer) -> anyhow::Result<&mut RepositorySet> {
if self.repository_set.is_none() {
let mut rs = RepositorySet::with_stability_and_flags(
composer.get_package().get_minimum_stability(),
diff --git a/crates/shirabe/src/command/status_command.rs b/crates/shirabe/src/command/status_command.rs
index 341e1e4..ff6675d 100644
--- a/crates/shirabe/src/command/status_command.rs
+++ b/crates/shirabe/src/command/status_command.rs
@@ -49,13 +49,19 @@ impl StatusCommand {
vec![],
vec![],
);
- composer.get_event_dispatcher().dispatch(command_event.get_name(), &command_event);
+ composer
+ .get_event_dispatcher()
+ .dispatch(command_event.get_name(), &command_event);
- composer.get_event_dispatcher().dispatch_script(ScriptEvents::PRE_STATUS_CMD, true);
+ composer
+ .get_event_dispatcher()
+ .dispatch_script(ScriptEvents::PRE_STATUS_CMD, true);
let exit_code = self.do_execute(input)?;
- composer.get_event_dispatcher().dispatch_script(ScriptEvents::POST_STATUS_CMD, true);
+ composer
+ .get_event_dispatcher()
+ .dispatch_script(ScriptEvents::POST_STATUS_CMD, true);
Ok(exit_code)
}
@@ -71,10 +77,13 @@ impl StatusCommand {
let mut errors: IndexMap<String, String> = IndexMap::new();
let io = self.inner.get_io();
let mut unpushed_changes: IndexMap<String, String> = IndexMap::new();
- let mut vcs_version_changes: IndexMap<String, IndexMap<String, IndexMap<String, String>>> = IndexMap::new();
+ let mut vcs_version_changes: IndexMap<String, IndexMap<String, IndexMap<String, String>>> =
+ IndexMap::new();
let parser = VersionParser::new();
- let process_executor = composer.get_loop().get_process_executor()
+ let process_executor = composer
+ .get_loop()
+ .get_process_executor()
.cloned()
.unwrap_or_else(|| ProcessExecutor::new(io));
let guesser = VersionGuesser::new(composer.get_config(), &process_executor, &parser, io);
@@ -91,35 +100,57 @@ impl StatusCommand {
// TODO(phase-b): isinstance checks using ChangeReportInterface/VcsCapableDownloaderInterface/DvcsDownloaderInterface
if let Some(change_reporter) = downloader.as_change_report_interface() {
if std::path::Path::new(&target_dir).is_symlink() {
- errors.insert(target_dir.clone(), format!("{} is a symbolic link.", target_dir));
+ errors.insert(
+ target_dir.clone(),
+ format!("{} is a symbolic link.", target_dir),
+ );
}
- if let Some(changes) = change_reporter.get_local_changes(package.as_ref(), target_dir.clone()) {
+ if let Some(changes) =
+ change_reporter.get_local_changes(package.as_ref(), target_dir.clone())
+ {
errors.insert(target_dir.clone(), changes);
}
}
if let Some(vcs_downloader) = downloader.as_vcs_capable_downloader_interface() {
- if vcs_downloader.get_vcs_reference(package.as_ref(), target_dir.clone()).is_some() {
+ if vcs_downloader
+ .get_vcs_reference(package.as_ref(), target_dir.clone())
+ .is_some()
+ {
let previous_ref = match package.get_installation_source().as_deref() {
Some("source") => package.get_source_reference().map(|s| s.to_string()),
Some("dist") => package.get_dist_reference().map(|s| s.to_string()),
_ => None,
};
- let current_version = guesser.guess_version(&dumper.dump(package.as_ref()), &target_dir);
+ let current_version =
+ guesser.guess_version(&dumper.dump(package.as_ref()), &target_dir);
if let (Some(prev_ref), Some(cur_version)) = (&previous_ref, &current_version) {
if cur_version.get("commit").map(|s| s.as_str()) != Some(prev_ref.as_str())
- && cur_version.get("pretty_version").map(|s| s.as_str()) != Some(prev_ref.as_str())
+ && cur_version.get("pretty_version").map(|s| s.as_str())
+ != Some(prev_ref.as_str())
{
let mut previous = IndexMap::new();
- previous.insert("version".to_string(), package.get_pretty_version().to_string());
+ previous.insert(
+ "version".to_string(),
+ package.get_pretty_version().to_string(),
+ );
previous.insert("ref".to_string(), prev_ref.clone());
let mut current = IndexMap::new();
- current.insert("version".to_string(), cur_version.get("pretty_version").cloned().unwrap_or_default());
- current.insert("ref".to_string(), cur_version.get("commit").cloned().unwrap_or_default());
+ current.insert(
+ "version".to_string(),
+ cur_version
+ .get("pretty_version")
+ .cloned()
+ .unwrap_or_default(),
+ );
+ current.insert(
+ "ref".to_string(),
+ cur_version.get("commit").cloned().unwrap_or_default(),
+ );
let mut change = IndexMap::new();
change.insert("previous".to_string(), previous);
@@ -132,7 +163,9 @@ impl StatusCommand {
}
if let Some(dvcs_downloader) = downloader.as_dvcs_downloader_interface() {
- if let Some(unpushed) = dvcs_downloader.get_unpushed_changes(package.as_ref(), target_dir.clone()) {
+ if let Some(unpushed) =
+ dvcs_downloader.get_unpushed_changes(package.as_ref(), target_dir.clone())
+ {
unpushed_changes.insert(target_dir, unpushed);
}
}
@@ -148,7 +181,8 @@ impl StatusCommand {
for (path, changes) in &errors {
if input.get_option("verbose").as_bool().unwrap_or(false) {
- let indented_changes = changes.lines()
+ let indented_changes = changes
+ .lines()
.map(|line| format!(" {}", line.trim_start()))
.collect::<Vec<_>>()
.join("\n");
@@ -165,7 +199,8 @@ impl StatusCommand {
for (path, changes) in &unpushed_changes {
if input.get_option("verbose").as_bool().unwrap_or(false) {
- let indented_changes = changes.lines()
+ let indented_changes = changes
+ .lines()
.map(|line| format!(" {}", line.trim_start()))
.collect::<Vec<_>>()
.join("\n");
@@ -178,24 +213,52 @@ impl StatusCommand {
}
if !vcs_version_changes.is_empty() {
- io.write_error("<warning>You have version variations in the following dependencies:</warning>");
+ io.write_error(
+ "<warning>You have version variations in the following dependencies:</warning>",
+ );
for (path, changes) in &vcs_version_changes {
if input.get_option("verbose").as_bool().unwrap_or(false) {
let current_version = {
- let v = changes["current"].get("version").map(|s| s.as_str()).unwrap_or("");
- let r = changes["current"].get("ref").map(|s| s.as_str()).unwrap_or("");
- if v.is_empty() { r.to_string() } else { v.to_string() }
+ let v = changes["current"]
+ .get("version")
+ .map(|s| s.as_str())
+ .unwrap_or("");
+ let r = changes["current"]
+ .get("ref")
+ .map(|s| s.as_str())
+ .unwrap_or("");
+ if v.is_empty() {
+ r.to_string()
+ } else {
+ v.to_string()
+ }
};
let previous_version = {
- let v = changes["previous"].get("version").map(|s| s.as_str()).unwrap_or("");
- let r = changes["previous"].get("ref").map(|s| s.as_str()).unwrap_or("");
- if v.is_empty() { r.to_string() } else { v.to_string() }
+ let v = changes["previous"]
+ .get("version")
+ .map(|s| s.as_str())
+ .unwrap_or("");
+ let r = changes["previous"]
+ .get("ref")
+ .map(|s| s.as_str())
+ .unwrap_or("");
+ if v.is_empty() {
+ r.to_string()
+ } else {
+ v.to_string()
+ }
};
let (current_display, previous_display) = if io.is_very_verbose() {
- let cur_ref = changes["current"].get("ref").map(|s| s.as_str()).unwrap_or("");
- let prev_ref = changes["previous"].get("ref").map(|s| s.as_str()).unwrap_or("");
+ let cur_ref = changes["current"]
+ .get("ref")
+ .map(|s| s.as_str())
+ .unwrap_or("");
+ let prev_ref = changes["previous"]
+ .get("ref")
+ .map(|s| s.as_str())
+ .unwrap_or("");
(
format!("{} ({})", current_version, cur_ref),
format!("{} ({})", previous_version, prev_ref),
@@ -205,7 +268,10 @@ impl StatusCommand {
};
io.write(&format!("<info>{}</info>:", path));
- io.write(&format!(" From <comment>{}</comment> to <comment>{}</comment>", previous_display, current_display));
+ io.write(&format!(
+ " From <comment>{}</comment> to <comment>{}</comment>",
+ previous_display, current_display
+ ));
} else {
io.write(path);
}
@@ -218,9 +284,19 @@ impl StatusCommand {
io.write_error("Use --verbose (-v) to see a list of files");
}
- let exit_code = (if !errors.is_empty() { Self::EXIT_CODE_ERRORS } else { 0 })
- + (if !unpushed_changes.is_empty() { Self::EXIT_CODE_UNPUSHED_CHANGES } else { 0 })
- + (if !vcs_version_changes.is_empty() { Self::EXIT_CODE_VERSION_CHANGES } else { 0 });
+ let exit_code = (if !errors.is_empty() {
+ Self::EXIT_CODE_ERRORS
+ } else {
+ 0
+ }) + (if !unpushed_changes.is_empty() {
+ Self::EXIT_CODE_UNPUSHED_CHANGES
+ } else {
+ 0
+ }) + (if !vcs_version_changes.is_empty() {
+ Self::EXIT_CODE_VERSION_CHANGES
+ } else {
+ 0
+ });
Ok(exit_code)
}
diff --git a/crates/shirabe/src/command/suggests_command.rs b/crates/shirabe/src/command/suggests_command.rs
index 5f0fa59..efa0ce2 100644
--- a/crates/shirabe/src/command/suggests_command.rs
+++ b/crates/shirabe/src/command/suggests_command.rs
@@ -1,6 +1,5 @@
//! ref: composer/src/Composer/Command/SuggestsCommand.php
-use anyhow::Result;
use crate::command::base_command::BaseCommand;
use crate::command::completion_trait::CompletionTrait;
use crate::console::input::input_argument::InputArgument;
@@ -9,9 +8,10 @@ use crate::installer::suggested_packages_reporter::SuggestedPackagesReporter;
use crate::repository::installed_repository::InstalledRepository;
use crate::repository::platform_repository::PlatformRepository;
use crate::repository::root_package_repository::RootPackageRepository;
+use anyhow::Result;
use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
-use shirabe_php_shim::{empty, in_array, PhpMixed};
+use shirabe_php_shim::{PhpMixed, empty, in_array};
#[derive(Debug)]
pub struct SuggestsCommand {
@@ -38,20 +38,34 @@ impl SuggestsCommand {
);
}
- pub fn execute(&mut self, input: &dyn InputInterface, _output: &dyn OutputInterface) -> Result<i64> {
+ pub fn execute(
+ &mut self,
+ input: &dyn InputInterface,
+ _output: &dyn OutputInterface,
+ ) -> Result<i64> {
let composer = self.inner.require_composer()?;
- let mut installed_repos = vec![
- Box::new(RootPackageRepository::new(composer.get_package().clone())),
- ];
+ let mut installed_repos = vec![Box::new(RootPackageRepository::new(
+ composer.get_package().clone(),
+ ))];
let locker = composer.get_locker();
if locker.is_locked() {
- installed_repos.push(Box::new(PlatformRepository::new(vec![], locker.get_platform_overrides())));
- installed_repos.push(Box::new(locker.get_locked_repository(!input.get_option("no-dev").as_bool().unwrap_or(false))));
+ installed_repos.push(Box::new(PlatformRepository::new(
+ vec![],
+ locker.get_platform_overrides(),
+ )));
+ installed_repos.push(Box::new(locker.get_locked_repository(
+ !input.get_option("no-dev").as_bool().unwrap_or(false),
+ )));
} else {
- installed_repos.push(Box::new(PlatformRepository::new(vec![], composer.get_config().get("platform"))));
- installed_repos.push(Box::new(composer.get_repository_manager().get_local_repository()));
+ installed_repos.push(Box::new(PlatformRepository::new(
+ vec![],
+ composer.get_config().get("platform"),
+ )));
+ installed_repos.push(Box::new(
+ composer.get_repository_manager().get_local_repository(),
+ ));
}
let installed_repo = InstalledRepository::new(installed_repos);
@@ -61,7 +75,13 @@ impl SuggestsCommand {
let mut packages = installed_repo.get_packages();
packages.push(composer.get_package());
for package in &packages {
- if !empty(&filter) && !in_array(PhpMixed::String(package.get_name().to_string()), &filter, false) {
+ if !empty(&filter)
+ && !in_array(
+ PhpMixed::String(package.get_name().to_string()),
+ &filter,
+ false,
+ )
+ {
continue;
}
reporter.add_suggestions_from_package(package);
diff --git a/crates/shirabe/src/command/update_command.rs b/crates/shirabe/src/command/update_command.rs
index 14848fb..0311cec 100644
--- a/crates/shirabe/src/command/update_command.rs
+++ b/crates/shirabe/src/command/update_command.rs
@@ -7,8 +7,8 @@ use shirabe_external_packages::symfony::component::console::helper::table::Table
use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
use shirabe_php_shim::{
- array_filter, array_intersect, array_keys, array_merge, array_search, count, empty, in_array,
- sprintf, strtolower, InvalidArgumentException, PhpMixed, RuntimeException,
+ InvalidArgumentException, PhpMixed, RuntimeException, array_filter, array_intersect,
+ array_keys, array_merge, array_search, count, empty, in_array, sprintf, strtolower,
};
use shirabe_semver::constraint::multi_constraint::MultiConstraint;
use shirabe_semver::intervals::Intervals;
@@ -20,9 +20,7 @@ use crate::command::completion_trait::CompletionTrait;
use crate::composer::Composer;
use crate::console::input::input_argument::InputArgument;
use crate::console::input::input_option::InputOption;
-use crate::dependency_resolver::request::{
- self, Request, UpdateAllowTransitiveDeps,
-};
+use crate::dependency_resolver::request::{self, Request, UpdateAllowTransitiveDeps};
use crate::installer::Installer;
use crate::io::io_interface::IOInterface;
use crate::package::base_package::BasePackage;
@@ -167,10 +165,10 @@ impl UpdateCommand {
// extract --with shorthands from the allowlist
if packages.len() > 0 {
- let allowlist_packages_with_requirements: Vec<String> = array_filter(
- &packages,
- |pkg: &String| -> bool { Preg::is_match(r"{\S+[ =:]\S+}", pkg) },
- );
+ let allowlist_packages_with_requirements: Vec<String> =
+ array_filter(&packages, |pkg: &String| -> bool {
+ Preg::is_match(r"{\S+[ =:]\S+}", pkg)
+ });
for (package, constraint) in self
.inner
.format_requirements(allowlist_packages_with_requirements.clone())
@@ -267,9 +265,15 @@ impl UpdateCommand {
let Some(matches) = matches else {
continue;
};
- let constraint = parser.parse_constraints(&format!("~{}", matches.get(1).cloned().unwrap_or_default()))?;
+ let constraint = parser.parse_constraints(&format!(
+ "~{}",
+ matches.get(1).cloned().unwrap_or_default()
+ ))?;
if temporary_constraints.contains_key(package.get_name()) {
- let existing = temporary_constraints.get(package.get_name()).cloned().unwrap();
+ let existing = temporary_constraints
+ .get(package.get_name())
+ .cloned()
+ .unwrap();
temporary_constraints.insert(
package.get_name().to_string(),
// TODO(phase-b): MultiConstraint::create signature
@@ -351,22 +355,38 @@ impl UpdateCommand {
let mut install = Installer::create(io, &composer);
let config = composer.get_config();
- let (prefer_source, prefer_dist) =
- self.inner.get_preferred_install_options(config, input, false);
+ let (prefer_source, prefer_dist) = self
+ .inner
+ .get_preferred_install_options(config, input, false);
- let optimize = input.get_option("optimize-autoloader").as_bool().unwrap_or(false)
+ let optimize = input
+ .get_option("optimize-autoloader")
+ .as_bool()
+ .unwrap_or(false)
|| config.get("optimize-autoloader").as_bool().unwrap_or(false);
let authoritative = input
.get_option("classmap-authoritative")
.as_bool()
.unwrap_or(false)
- || config.get("classmap-authoritative").as_bool().unwrap_or(false);
+ || config
+ .get("classmap-authoritative")
+ .as_bool()
+ .unwrap_or(false);
let apcu_prefix = input.get_option("apcu-autoloader-prefix");
let apcu = !matches!(apcu_prefix, PhpMixed::Null)
- || input.get_option("apcu-autoloader").as_bool().unwrap_or(false)
+ || input
+ .get_option("apcu-autoloader")
+ .as_bool()
+ .unwrap_or(false)
|| config.get("apcu-autoloader").as_bool().unwrap_or(false);
- let minimal_changes = input.get_option("minimal-changes").as_bool().unwrap_or(false)
- || config.get("update-with-minimal-changes").as_bool().unwrap_or(false);
+ let minimal_changes = input
+ .get_option("minimal-changes")
+ .as_bool()
+ .unwrap_or(false)
+ || config
+ .get("update-with-minimal-changes")
+ .as_bool()
+ .unwrap_or(false);
let mut update_allow_transitive_dependencies = UpdateAllowTransitiveDeps::UpdateOnlyListed;
if input
@@ -404,7 +424,10 @@ impl UpdateCommand {
.set_prefer_stable(input.get_option("prefer-stable").as_bool().unwrap_or(false))
.set_prefer_lowest(input.get_option("prefer-lowest").as_bool().unwrap_or(false))
.set_temporary_constraints(temporary_constraints)
- .set_audit_config(self.inner.create_audit_config(composer.get_config(), input)?)
+ .set_audit_config(
+ self.inner
+ .create_audit_config(composer.get_config(), input)?,
+ )
.set_minimal_update(minimal_changes);
if input.get_option("no-plugins").as_bool().unwrap_or(false) {
@@ -490,9 +513,15 @@ impl UpdateCommand {
);
let mut autocompleter_values: IndexMap<String, String> = IndexMap::new();
let installed_packages = if composer.get_locker().is_locked() {
- composer.get_locker().get_locked_repository(true)?.get_packages()
+ composer
+ .get_locker()
+ .get_locked_repository(true)?
+ .get_packages()
} else {
- composer.get_repository_manager().get_local_repository().get_packages()
+ composer
+ .get_repository_manager()
+ .get_local_repository()
+ .get_packages()
};
let version_selector = self.create_version_selector(composer);
for package in &installed_packages {
@@ -502,7 +531,8 @@ impl UpdateCommand {
}
}
let current_version = package.get_pretty_version();
- let constraint = todo!("requires[package.get_name()].get_pretty_constraint() if present");
+ let constraint =
+ todo!("requires[package.get_name()].get_pretty_constraint() if present");
let stability = todo!(
"if stabilityFlags[package_name] use array_search(BasePackage::STABILITIES) else minimum_stability"
);
@@ -579,18 +609,16 @@ impl UpdateCommand {
fn create_version_selector(&self, composer: &Composer) -> VersionSelector {
let mut repository_set = RepositorySet::new();
- repository_set.add_repository(Box::new(CompositeRepository::new(
- array_filter(
- &composer.get_repository_manager().get_repositories(),
- |repository: &Box<dyn RepositoryInterface>| -> bool {
- // PHP: !$repository instanceof PlatformRepository
- repository
- .as_any()
- .downcast_ref::<PlatformRepository>()
- .is_none()
- },
- ),
- )));
+ repository_set.add_repository(Box::new(CompositeRepository::new(array_filter(
+ &composer.get_repository_manager().get_repositories(),
+ |repository: &Box<dyn RepositoryInterface>| -> bool {
+ // PHP: !$repository instanceof PlatformRepository
+ repository
+ .as_any()
+ .downcast_ref::<PlatformRepository>()
+ .is_none()
+ },
+ ))));
VersionSelector::new(repository_set)
}
diff --git a/crates/shirabe/src/command/validate_command.rs b/crates/shirabe/src/command/validate_command.rs
index d2f726a..e95e5ca 100644
--- a/crates/shirabe/src/command/validate_command.rs
+++ b/crates/shirabe/src/command/validate_command.rs
@@ -26,14 +26,69 @@ impl ValidateCommand {
.set_name("validate")
.set_description("Validates a composer.json and composer.lock")
.set_definition(vec![
- InputOption::new("no-check-all", None, Some(InputOption::VALUE_NONE), "Do not validate requires for overly strict/loose constraints", None, vec![]),
- InputOption::new("check-lock", None, Some(InputOption::VALUE_NONE), "Check if lock file is up to date (even when config.lock is false)", None, vec![]),
- InputOption::new("no-check-lock", None, Some(InputOption::VALUE_NONE), "Do not check if lock file is up to date", None, vec![]),
- InputOption::new("no-check-publish", None, Some(InputOption::VALUE_NONE), "Do not check for publish errors", None, vec![]),
- InputOption::new("no-check-version", None, Some(InputOption::VALUE_NONE), "Do not report a warning if the version field is present", None, vec![]),
- InputOption::new("with-dependencies", Some(shirabe_php_shim::PhpMixed::String("A".to_string())), Some(InputOption::VALUE_NONE), "Also validate the composer.json of all installed dependencies", None, vec![]),
- InputOption::new("strict", None, Some(InputOption::VALUE_NONE), "Return a non-zero exit code for warnings as well as errors", None, vec![]),
- InputArgument::new("file", Some(InputArgument::OPTIONAL), "path to composer.json file", None, vec![]),
+ InputOption::new(
+ "no-check-all",
+ None,
+ Some(InputOption::VALUE_NONE),
+ "Do not validate requires for overly strict/loose constraints",
+ None,
+ vec![],
+ ),
+ InputOption::new(
+ "check-lock",
+ None,
+ Some(InputOption::VALUE_NONE),
+ "Check if lock file is up to date (even when config.lock is false)",
+ None,
+ vec![],
+ ),
+ InputOption::new(
+ "no-check-lock",
+ None,
+ Some(InputOption::VALUE_NONE),
+ "Do not check if lock file is up to date",
+ None,
+ vec![],
+ ),
+ InputOption::new(
+ "no-check-publish",
+ None,
+ Some(InputOption::VALUE_NONE),
+ "Do not check for publish errors",
+ None,
+ vec![],
+ ),
+ InputOption::new(
+ "no-check-version",
+ None,
+ Some(InputOption::VALUE_NONE),
+ "Do not report a warning if the version field is present",
+ None,
+ vec![],
+ ),
+ InputOption::new(
+ "with-dependencies",
+ Some(shirabe_php_shim::PhpMixed::String("A".to_string())),
+ Some(InputOption::VALUE_NONE),
+ "Also validate the composer.json of all installed dependencies",
+ None,
+ vec![],
+ ),
+ InputOption::new(
+ "strict",
+ None,
+ Some(InputOption::VALUE_NONE),
+ "Return a non-zero exit code for warnings as well as errors",
+ None,
+ vec![],
+ ),
+ InputArgument::new(
+ "file",
+ Some(InputArgument::OPTIONAL),
+ "path to composer.json file",
+ None,
+ vec![],
+ ),
])
.set_help(
"The validate command validates a given composer.json and composer.lock\n\n\
@@ -41,12 +96,14 @@ impl ValidateCommand {
1 validation warning(s), only when --strict is given\n\
2 validation error(s)\n\
3 file unreadable or missing\n\n\
- Read more at https://getcomposer.org/doc/03-cli.md#validate"
+ Read more at https://getcomposer.org/doc/03-cli.md#validate",
);
}
pub fn execute(&self, input: &dyn InputInterface, output: &dyn OutputInterface) -> Result<i64> {
- let file = input.get_argument("file").as_string_opt()
+ let file = input
+ .get_argument("file")
+ .as_string_opt()
.map(|s| s.to_string())
.unwrap_or_else(|| Factory::get_composer_file());
let io = self.inner.get_io();
@@ -66,19 +123,29 @@ impl ValidateCommand {
} else {
ValidatingArrayLoader::CHECK_ALL
};
- let check_publish = !input.get_option("no-check-publish").as_bool().unwrap_or(false);
+ let check_publish = !input
+ .get_option("no-check-publish")
+ .as_bool()
+ .unwrap_or(false);
let check_lock = !input.get_option("no-check-lock").as_bool().unwrap_or(false);
- let check_version = if input.get_option("no-check-version").as_bool().unwrap_or(false) {
+ let check_version = if input
+ .get_option("no-check-version")
+ .as_bool()
+ .unwrap_or(false)
+ {
0
} else {
ConfigValidator::CHECK_VERSION
};
let is_strict = input.get_option("strict").as_bool().unwrap_or(false);
- let (mut errors, mut publish_errors, mut warnings) = validator.validate(&file, check_all, check_version)?;
+ let (mut errors, mut publish_errors, mut warnings) =
+ validator.validate(&file, check_all, check_version)?;
let mut lock_errors: Vec<String> = vec![];
let composer = self.inner.create_composer_instance(input, io, vec![])?;
- let check_lock = (check_lock && composer.get_config().get("lock").as_bool().unwrap_or(true)) || input.get_option("check-lock").as_bool().unwrap_or(false);
+ let check_lock = (check_lock
+ && composer.get_config().get("lock").as_bool().unwrap_or(true))
+ || input.get_option("check-lock").as_bool().unwrap_or(false);
let locker = composer.get_locker();
if locker.is_locked() && !locker.is_fresh() {
lock_errors.push("- The lock file is not up to date with the latest changes in composer.json, it is recommended that you run `composer update` or `composer update <package name>`.".to_string());
@@ -88,7 +155,17 @@ impl ValidateCommand {
lock_errors.extend(locker.get_missing_requirement_info(composer.get_package(), true));
}
- self.output_result(io, &file, &mut errors, &mut warnings, check_publish, &mut publish_errors, check_lock, &mut lock_errors, true);
+ self.output_result(
+ io,
+ &file,
+ &mut errors,
+ &mut warnings,
+ check_publish,
+ &mut publish_errors,
+ check_lock,
+ &mut lock_errors,
+ true,
+ );
let exit_code = if !errors.is_empty() {
2
@@ -100,19 +177,37 @@ impl ValidateCommand {
let mut exit_code = exit_code;
- if input.get_option("with-dependencies").as_bool().unwrap_or(false) {
+ if input
+ .get_option("with-dependencies")
+ .as_bool()
+ .unwrap_or(false)
+ {
let local_repo = composer.get_repository_manager().get_local_repository();
for package in local_repo.get_packages() {
- let path = composer.get_installation_manager().get_install_path(package.as_ref());
+ let path = composer
+ .get_installation_manager()
+ .get_install_path(package.as_ref());
let path = match path {
Some(p) => p,
None => continue,
};
let dep_file = format!("{}/composer.json", path);
- if std::path::Path::new(&path).is_dir() && std::path::Path::new(&dep_file).exists() {
- let (mut dep_errors, mut dep_publish_errors, mut dep_warnings) = validator.validate(&dep_file, check_all, check_version)?;
+ if std::path::Path::new(&path).is_dir() && std::path::Path::new(&dep_file).exists()
+ {
+ let (mut dep_errors, mut dep_publish_errors, mut dep_warnings) =
+ validator.validate(&dep_file, check_all, check_version)?;
- self.output_result(io, package.get_pretty_name(), &mut dep_errors, &mut dep_warnings, check_publish, &mut dep_publish_errors, false, &mut vec![], false);
+ self.output_result(
+ io,
+ package.get_pretty_name(),
+ &mut dep_errors,
+ &mut dep_warnings,
+ check_publish,
+ &mut dep_publish_errors,
+ false,
+ &mut vec![],
+ false,
+ );
let dep_code = if !dep_errors.is_empty() {
2
@@ -135,7 +230,9 @@ impl ValidateCommand {
vec![],
vec![],
);
- let event_code = composer.get_event_dispatcher().dispatch(command_event.get_name(), &command_event);
+ let event_code = composer
+ .get_event_dispatcher()
+ .dispatch(command_event.get_name(), &command_event);
Ok(exit_code.max(event_code))
}
@@ -155,16 +252,31 @@ impl ValidateCommand {
let mut do_print_schema_url = false;
if !errors.is_empty() {
- io.write_error(&format!("<error>{} is invalid, the following errors/warnings were found:</error>", name));
+ io.write_error(&format!(
+ "<error>{} is invalid, the following errors/warnings were found:</error>",
+ name
+ ));
} else if !publish_errors.is_empty() && check_publish {
- io.write_error(&format!("<info>{} is valid for simple usage with Composer but has</info>", name));
- io.write_error("<info>strict errors that make it unable to be published as a package</info>");
+ io.write_error(&format!(
+ "<info>{} is valid for simple usage with Composer but has</info>",
+ name
+ ));
+ io.write_error(
+ "<info>strict errors that make it unable to be published as a package</info>",
+ );
do_print_schema_url = print_schema_url;
} else if !warnings.is_empty() {
- io.write_error(&format!("<info>{} is valid, but with a few warnings</info>", name));
+ io.write_error(&format!(
+ "<info>{} is valid, but with a few warnings</info>",
+ name
+ ));
do_print_schema_url = print_schema_url;
} else if !lock_errors.is_empty() {
- io.write(&format!("<info>{} is valid but your composer.lock has some {}</info>", name, if check_lock { "errors" } else { "warnings" }));
+ io.write(&format!(
+ "<info>{} is valid but your composer.lock has some {}</info>",
+ name,
+ if check_lock { "errors" } else { "warnings" }
+ ));
} else {
io.write(&format!("<info>{} is valid</info>", name));
}
diff --git a/crates/shirabe/src/compiler.rs b/crates/shirabe/src/compiler.rs
index 4f5abc2..e8ce824 100644
--- a/crates/shirabe/src/compiler.rs
+++ b/crates/shirabe/src/compiler.rs
@@ -8,9 +8,9 @@ use shirabe_external_packages::seld::phar_utils::timestamps::Timestamps;
use shirabe_external_packages::symfony::component::finder::finder::Finder;
use shirabe_external_packages::symfony::component::finder::spl_file_info::SplFileInfo;
use shirabe_php_shim::{
- array_search, file_exists, file_get_contents, strcmp, strtr, strtr_array,
- token_get_all, PhpMixed, Phar, RuntimeException, UnexpectedValueException,
- T_COMMENT, T_DOC_COMMENT, T_WHITESPACE,
+ Phar, PhpMixed, RuntimeException, T_COMMENT, T_DOC_COMMENT, T_WHITESPACE,
+ UnexpectedValueException, array_search, file_exists, file_get_contents, strcmp, strtr,
+ strtr_array, token_get_all,
};
use crate::json::json_file::JsonFile;
@@ -57,7 +57,9 @@ impl Compiler {
code: 0,
}.into());
}
- self.version = Git::parse_rev_list_output(&output, &process).trim().to_string();
+ self.version = Git::parse_rev_list_output(&output, &process)
+ .trim()
+ .to_string();
let command = Git::build_rev_list_command(&process, &["-n1", "--format=%ci", "HEAD"]);
let mut output = String::new();
@@ -69,9 +71,10 @@ impl Compiler {
}
let version_date_str = Git::parse_rev_list_output(&output, &process);
- self.version_date = chrono::DateTime::parse_from_str(version_date_str.trim(), "%Y-%m-%d %H:%M:%S %z")
- .map(|dt| dt.with_timezone(&chrono::Utc))
- .unwrap_or_else(|_| chrono::Utc::now());
+ self.version_date =
+ chrono::DateTime::parse_from_str(version_date_str.trim(), "%Y-%m-%d %H:%M:%S %z")
+ .map(|dt| dt.with_timezone(&chrono::Utc))
+ .unwrap_or_else(|_| chrono::Utc::now());
let mut git_describe_output = String::new();
if process.execute(
@@ -118,13 +121,12 @@ impl Compiler {
phar.start_buffering();
- let finder_sort =
- |a: &SplFileInfo, b: &SplFileInfo| -> i64 {
- strcmp(
- &strtr(a.get_real_path(), "\\", "/"),
- &strtr(b.get_real_path(), "\\", "/"),
- )
- };
+ let finder_sort = |a: &SplFileInfo, b: &SplFileInfo| -> i64 {
+ strcmp(
+ &strtr(a.get_real_path(), "\\", "/"),
+ &strtr(b.get_real_path(), "\\", "/"),
+ )
+ };
// Add Composer sources
let mut finder = Finder::new();
@@ -143,7 +145,10 @@ impl Compiler {
// Add runtime utilities separately to make sure they retain the docblocks as these will get copied into projects
self.add_file(
&mut phar,
- &SplFileInfo::new(&format!("{}/src/Composer/Autoload/ClassLoader.php", repo_root)),
+ &SplFileInfo::new(&format!(
+ "{}/src/Composer/Autoload/ClassLoader.php",
+ repo_root
+ )),
false,
)?;
self.add_file(
@@ -218,14 +223,9 @@ impl Compiler {
let mut unexpected_files: Vec<String> = vec![];
for file in finder.iter() {
- if let Some(index) =
- array_search(file.get_real_path(), &extra_files)
- {
+ if let Some(index) = array_search(file.get_real_path(), &extra_files) {
extra_files.shift_remove(&index);
- } else if !Preg::is_match(
- r"{(^LICENSE(?:\.txt)?$|\.php$)}",
- file.get_filename(),
- )? {
+ } else if !Preg::is_match(r"{(^LICENSE(?:\.txt)?$|\.php$)}", file.get_filename())? {
unexpected_files.push(file.to_string());
}
@@ -314,8 +314,7 @@ impl Compiler {
fn add_file(&self, phar: &mut Phar, file: &SplFileInfo, strip: bool) -> anyhow::Result<()> {
let path = self.get_relative_file_path(file);
- let content = file_get_contents(file.get_path())
- .unwrap_or_default();
+ let content = file_get_contents(file.get_path()).unwrap_or_default();
let mut content = if strip {
self.strip_whitespace(&content)
} else if file.get_filename() == "LICENSE" {
@@ -326,10 +325,7 @@ impl Compiler {
if path == "src/Composer/Composer.php" {
let mut replacements: IndexMap<String, String> = IndexMap::new();
- replacements.insert(
- "@package_version@".to_string(),
- self.version.clone(),
- );
+ replacements.insert("@package_version@".to_string(), self.version.clone());
replacements.insert(
"@package_branch_alias_version@".to_string(),
self.branch_alias_version.clone(),
@@ -340,8 +336,7 @@ impl Compiler {
);
content = strtr_array(&content, &replacements);
content = Preg::replace(
- r"{SOURCE_VERSION = '[^']+';}"
-,
+ r"{SOURCE_VERSION = '[^']+';}",
"SOURCE_VERSION = '';",
&content,
)?;
@@ -354,8 +349,7 @@ impl Compiler {
fn add_composer_bin(&self, phar: &mut Phar) -> anyhow::Result<()> {
let repo_root = shirabe_php_shim::dirname_levels(file!(), 2);
- let content = file_get_contents(&format!("{}/bin/composer", repo_root))
- .unwrap_or_default();
+ let content = file_get_contents(&format!("{}/bin/composer", repo_root)).unwrap_or_default();
let content = Preg::replace(r"{^#!/usr/bin/env php\s*}", "", &content)?;
phar.add_from_string("bin/composer", &content);
Ok(())
@@ -388,8 +382,8 @@ impl Compiler {
let whitespace = Preg::replace(r"{(?:\r\n|\r|\n)}", "\n", &whitespace)
.unwrap_or(whitespace);
// trim leading spaces
- let whitespace = Preg::replace(r"{\n +}", "\n", &whitespace)
- .unwrap_or(whitespace);
+ let whitespace =
+ Preg::replace(r"{\n +}", "\n", &whitespace).unwrap_or(whitespace);
output.push_str(&whitespace);
} else {
output.push_str(token_value);
diff --git a/crates/shirabe/src/composer.rs b/crates/shirabe/src/composer.rs
index 25e509c..7d1ad19 100644
--- a/crates/shirabe/src/composer.rs
+++ b/crates/shirabe/src/composer.rs
@@ -32,7 +32,9 @@ impl Composer {
if Self::VERSION == "@package_version@" {
return Self::SOURCE_VERSION.to_string();
}
- if Self::BRANCH_ALIAS_VERSION != "" && Preg::is_match("{^[a-f0-9]{40}$}", Self::VERSION).unwrap_or(false) {
+ if Self::BRANCH_ALIAS_VERSION != ""
+ && Preg::is_match("{^[a-f0-9]{40}$}", Self::VERSION).unwrap_or(false)
+ {
return format!("{}+{}", Self::BRANCH_ALIAS_VERSION, Self::VERSION);
}
Self::VERSION.to_string()
diff --git a/crates/shirabe/src/config.rs b/crates/shirabe/src/config.rs
index d6d9dcc..12755b0 100644
--- a/crates/shirabe/src/config.rs
+++ b/crates/shirabe/src/config.rs
@@ -1,13 +1,16 @@
//! ref: composer/src/Composer/Config.php
+pub mod config_source_interface;
+pub mod json_config_source;
+
use anyhow::Result;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- array_key_exists, array_merge_recursive, array_reverse, array_search_mixed, array_unique,
- current, empty, filter_var, implode, in_array, is_array, is_int, is_string, key, max, parse_url,
- reset, rtrim, strtolower, strtoupper, strtr, substr, trigger_error, PhpMixed,
- RuntimeException, E_USER_DEPRECATED, FILTER_VALIDATE_URL, PHP_URL_HOST, PHP_URL_SCHEME,
+ E_USER_DEPRECATED, FILTER_VALIDATE_URL, PHP_URL_HOST, PHP_URL_SCHEME, PhpMixed,
+ RuntimeException, array_key_exists, array_merge_recursive, array_reverse, array_search_mixed,
+ array_unique, current, empty, filter_var, implode, in_array, is_array, is_int, is_string, key,
+ max, parse_url, reset, rtrim, strtolower, strtoupper, strtr, substr, trigger_error,
};
use crate::advisory::auditor::Auditor;
@@ -49,11 +52,23 @@ impl Config {
let mut c: IndexMap<String, PhpMixed> = IndexMap::new();
c.insert("process-timeout".to_string(), PhpMixed::Int(300));
c.insert("use-include-path".to_string(), PhpMixed::Bool(false));
- c.insert("allow-plugins".to_string(), PhpMixed::Array(IndexMap::new()));
- c.insert("use-parent-dir".to_string(), PhpMixed::String("prompt".to_string()));
- c.insert("preferred-install".to_string(), PhpMixed::String("dist".to_string()));
+ c.insert(
+ "allow-plugins".to_string(),
+ PhpMixed::Array(IndexMap::new()),
+ );
+ c.insert(
+ "use-parent-dir".to_string(),
+ PhpMixed::String("prompt".to_string()),
+ );
+ c.insert(
+ "preferred-install".to_string(),
+ PhpMixed::String("dist".to_string()),
+ );
let mut audit: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
- audit.insert("ignore".to_string(), Box::new(PhpMixed::Array(IndexMap::new())));
+ audit.insert(
+ "ignore".to_string(),
+ Box::new(PhpMixed::Array(IndexMap::new())),
+ );
audit.insert(
"abandoned".to_string(),
Box::new(PhpMixed::String(Auditor::ABANDONED_FAIL.to_string())),
@@ -69,7 +84,10 @@ impl Config {
]),
);
c.insert("gitlab-protocol".to_string(), PhpMixed::Null);
- c.insert("vendor-dir".to_string(), PhpMixed::String("vendor".to_string()));
+ c.insert(
+ "vendor-dir".to_string(),
+ PhpMixed::String("vendor".to_string()),
+ );
c.insert(
"bin-dir".to_string(),
PhpMixed::String("{$vendor-dir}/bin".to_string()),
@@ -78,7 +96,10 @@ impl Config {
"cache-dir".to_string(),
PhpMixed::String("{$home}/cache".to_string()),
);
- c.insert("data-dir".to_string(), PhpMixed::String("{$home}".to_string()));
+ c.insert(
+ "data-dir".to_string(),
+ PhpMixed::String("{$home}".to_string()),
+ );
c.insert(
"cache-files-dir".to_string(),
PhpMixed::String("{$cache-dir}/files".to_string()),
@@ -98,7 +119,10 @@ impl Config {
PhpMixed::String("300MiB".to_string()),
);
c.insert("cache-read-only".to_string(), PhpMixed::Bool(false));
- c.insert("bin-compat".to_string(), PhpMixed::String("auto".to_string()));
+ c.insert(
+ "bin-compat".to_string(),
+ PhpMixed::String("auto".to_string()),
+ );
c.insert("discard-changes".to_string(), PhpMixed::Bool(false));
c.insert("autoloader-suffix".to_string(), PhpMixed::Null);
c.insert("sort-packages".to_string(), PhpMixed::Bool(false));
@@ -106,18 +130,21 @@ impl Config {
c.insert("classmap-authoritative".to_string(), PhpMixed::Bool(false));
c.insert("apcu-autoloader".to_string(), PhpMixed::Bool(false));
c.insert("prepend-autoloader".to_string(), PhpMixed::Bool(true));
- c.insert("update-with-minimal-changes".to_string(), PhpMixed::Bool(false));
+ c.insert(
+ "update-with-minimal-changes".to_string(),
+ PhpMixed::Bool(false),
+ );
c.insert(
"github-domains".to_string(),
PhpMixed::List(vec![Box::new(PhpMixed::String("github.com".to_string()))]),
);
- c.insert("bitbucket-expose-hostname".to_string(), PhpMixed::Bool(true));
- c.insert("disable-tls".to_string(), PhpMixed::Bool(false));
- c.insert("secure-http".to_string(), PhpMixed::Bool(true));
c.insert(
- "secure-svn-domains".to_string(),
- PhpMixed::List(vec![]),
+ "bitbucket-expose-hostname".to_string(),
+ PhpMixed::Bool(true),
);
+ c.insert("disable-tls".to_string(), PhpMixed::Bool(false));
+ c.insert("secure-http".to_string(), PhpMixed::Bool(true));
+ c.insert("secure-svn-domains".to_string(), PhpMixed::List(vec![]));
c.insert("cafile".to_string(), PhpMixed::Null);
c.insert("capath".to_string(), PhpMixed::Null);
c.insert("github-expose-hostname".to_string(), PhpMixed::Bool(true));
@@ -125,9 +152,15 @@ impl Config {
"gitlab-domains".to_string(),
PhpMixed::List(vec![Box::new(PhpMixed::String("gitlab.com".to_string()))]),
);
- c.insert("store-auths".to_string(), PhpMixed::String("prompt".to_string()));
+ c.insert(
+ "store-auths".to_string(),
+ PhpMixed::String("prompt".to_string()),
+ );
c.insert("platform".to_string(), PhpMixed::Array(IndexMap::new()));
- c.insert("archive-format".to_string(), PhpMixed::String("tar".to_string()));
+ c.insert(
+ "archive-format".to_string(),
+ PhpMixed::String("tar".to_string()),
+ );
c.insert("archive-dir".to_string(), PhpMixed::String(".".to_string()));
c.insert("htaccess-protect".to_string(), PhpMixed::Bool(true));
c.insert("use-github-api".to_string(), PhpMixed::Bool(true));
@@ -136,21 +169,36 @@ impl Config {
"platform-check".to_string(),
PhpMixed::String("php-only".to_string()),
);
- c.insert("bitbucket-oauth".to_string(), PhpMixed::Array(IndexMap::new()));
+ c.insert(
+ "bitbucket-oauth".to_string(),
+ PhpMixed::Array(IndexMap::new()),
+ );
c.insert("github-oauth".to_string(), PhpMixed::Array(IndexMap::new()));
c.insert("gitlab-oauth".to_string(), PhpMixed::Array(IndexMap::new()));
c.insert("gitlab-token".to_string(), PhpMixed::Array(IndexMap::new()));
c.insert("http-basic".to_string(), PhpMixed::Array(IndexMap::new()));
c.insert("bearer".to_string(), PhpMixed::Array(IndexMap::new()));
- c.insert("custom-headers".to_string(), PhpMixed::Array(IndexMap::new()));
+ c.insert(
+ "custom-headers".to_string(),
+ PhpMixed::Array(IndexMap::new()),
+ );
c.insert("bump-after-update".to_string(), PhpMixed::Bool(false));
- c.insert("allow-missing-requirements".to_string(), PhpMixed::Bool(false));
- c.insert("client-certificate".to_string(), PhpMixed::Array(IndexMap::new()));
+ c.insert(
+ "allow-missing-requirements".to_string(),
+ PhpMixed::Bool(false),
+ );
+ c.insert(
+ "client-certificate".to_string(),
+ PhpMixed::Array(IndexMap::new()),
+ );
c.insert(
"forgejo-domains".to_string(),
PhpMixed::List(vec![Box::new(PhpMixed::String("codeberg.org".to_string()))]),
);
- c.insert("forgejo-token".to_string(), PhpMixed::Array(IndexMap::new()));
+ c.insert(
+ "forgejo-token".to_string(),
+ PhpMixed::Array(IndexMap::new()),
+ );
c
}
@@ -271,7 +319,9 @@ impl Config {
self.set_source_of_config_value(&val, key, source);
} else if in_array(
PhpMixed::String(key.clone()),
- &PhpMixed::List(vec![Box::new(PhpMixed::String("allow-plugins".to_string()))]),
+ &PhpMixed::List(vec![Box::new(PhpMixed::String(
+ "allow-plugins".to_string(),
+ ))]),
true,
) && self.config.contains_key(key)
&& is_array(self.config.get(key).cloned().unwrap_or(PhpMixed::Null))
@@ -320,10 +370,7 @@ impl Config {
if is_array(val.clone()) || is_array(existing.clone()) {
if is_string(&val) {
let mut m = IndexMap::new();
- m.insert(
- "*".to_string(),
- Box::new(val.clone()),
- );
+ m.insert("*".to_string(), Box::new(val.clone()));
val = PhpMixed::Array(m);
}
let existing = self.config.get(key).cloned().unwrap_or(PhpMixed::Null);
@@ -335,10 +382,8 @@ impl Config {
.insert(format!("{}*", key), source.to_string());
}
let cur = self.config.get(key).cloned().unwrap_or(PhpMixed::Null);
- self.config.insert(
- key.clone(),
- array_merge_recursive(vec![cur, val.clone()]),
- );
+ self.config
+ .insert(key.clone(), array_merge_recursive(vec![cur, val.clone()]));
self.set_source_of_config_value(&val, key, source);
// the full match pattern needs to be last
let has_wildcard = matches!(
@@ -379,8 +424,7 @@ impl Config {
.unwrap_or(PhpMixed::List(vec![])),
_ => PhpMixed::List(vec![]),
};
- let new_ignores =
- array_merge_recursive(vec![current_ignores, val_ignore]);
+ let new_ignores = array_merge_recursive(vec![current_ignores, val_ignore]);
if let Some(PhpMixed::Array(audit)) = self.config.get_mut("audit") {
audit.insert("ignore".to_string(), Box::new(new_ignores));
}
@@ -391,7 +435,10 @@ impl Config {
}
}
- let repositories_section = config.get("repositories").cloned().unwrap_or(PhpMixed::Null);
+ let repositories_section = config
+ .get("repositories")
+ .cloned()
+ .unwrap_or(PhpMixed::Null);
if !empty(&repositories_section) && is_array(repositories_section.clone()) {
self.repositories = array_reverse(&self.repositories, true);
let new_repos_map = match &repositories_section {
@@ -448,7 +495,8 @@ impl Config {
// PHP: $this->repositories[] = $repository
// appending to numeric-keyed map
let next_idx = self.repositories.len();
- self.repositories.insert(next_idx.to_string(), repository.clone());
+ self.repositories
+ .insert(next_idx.to_string(), repository.clone());
}
let found_key = array_search_mixed(
repository,
@@ -469,7 +517,8 @@ impl Config {
);
} else if name == "packagist" {
// BC support for default "packagist" named repo
- self.repositories.insert(format!("{}.org", name), repository.clone());
+ self.repositories
+ .insert(format!("{}.org", name), repository.clone());
self.set_source_of_config_value(
repository,
&format!("repositories.{}.org", name),
@@ -506,16 +555,8 @@ impl Config {
pub fn get_with_flags(&mut self, key: &str, flags: i64) -> Result<PhpMixed> {
match key {
// strings/paths with env var and {$refs} support
- "vendor-dir"
- | "bin-dir"
- | "process-timeout"
- | "data-dir"
- | "cache-dir"
- | "cache-files-dir"
- | "cache-repo-dir"
- | "cache-vcs-dir"
- | "cafile"
- | "capath" => {
+ "vendor-dir" | "bin-dir" | "process-timeout" | "data-dir" | "cache-dir"
+ | "cache-files-dir" | "cache-repo-dir" | "cache-vcs-dir" | "cafile" | "capath" => {
// convert foo-bar to COMPOSER_FOO_BAR and check if it exists since it overrides the local config
let env = format!("COMPOSER_{}", strtoupper(&strtr(key, "-", "_")));
@@ -592,10 +633,7 @@ impl Config {
// ints without env var support
"cache-ttl" => Ok(PhpMixed::Int(max(
0,
- self.config
- .get(key)
- .and_then(|v| v.as_int())
- .unwrap_or(0),
+ self.config.get(key).and_then(|v| v.as_int()).unwrap_or(0),
))),
// numbers with kb/mb/gb support, without env var support
@@ -747,8 +785,7 @@ impl Config {
}
let val = self.config.get(key).cloned().unwrap_or(PhpMixed::Null);
- let allowed = matches!(&val, PhpMixed::Bool(_))
- || val.as_string() == Some("stash");
+ let allowed = matches!(&val, PhpMixed::Bool(_)) || val.as_string() == Some("stash");
if !allowed {
return Err(RuntimeException {
message: format!(
@@ -795,7 +832,11 @@ impl Config {
false,
);
if let Some(idx_val) = found {
- let idx = idx_val.as_string().unwrap_or("").parse::<usize>().unwrap_or(usize::MAX);
+ let idx = idx_val
+ .as_string()
+ .unwrap_or("")
+ .parse::<usize>()
+ .unwrap_or(usize::MAX);
if idx < protos.len() {
protos.remove(idx);
}
@@ -832,12 +873,9 @@ impl Config {
let mut result = self.config.get(key).cloned().unwrap_or(PhpMixed::Null);
let abandoned_env = self.get_composer_env("COMPOSER_AUDIT_ABANDONED");
if !matches!(abandoned_env, PhpMixed::Bool(false)) {
- let abandoned_env_str =
- abandoned_env.as_string().unwrap_or("").to_string();
- let valid_choices: Vec<String> = Auditor::ABANDONEDS
- .iter()
- .map(|s| s.to_string())
- .collect();
+ let abandoned_env_str = abandoned_env.as_string().unwrap_or("").to_string();
+ let valid_choices: Vec<String> =
+ Auditor::ABANDONEDS.iter().map(|s| s.to_string()).collect();
if !in_array(
PhpMixed::String(abandoned_env_str.clone()),
&PhpMixed::List(
@@ -941,12 +979,7 @@ impl Config {
}
/// @param mixed $configValue
- fn set_source_of_config_value(
- &mut self,
- config_value: &PhpMixed,
- path: &str,
- source: &str,
- ) {
+ fn set_source_of_config_value(&mut self, config_value: &PhpMixed, path: &str, source: &str) {
self.source_of_config_value
.insert(path.to_string(), source.to_string());
diff --git a/crates/shirabe/src/config/config_source_interface.rs b/crates/shirabe/src/config/config_source_interface.rs
index 9f3321c..2a48635 100644
--- a/crates/shirabe/src/config/config_source_interface.rs
+++ b/crates/shirabe/src/config/config_source_interface.rs
@@ -4,9 +4,20 @@ use indexmap::IndexMap;
use shirabe_php_shim::PhpMixed;
pub trait ConfigSourceInterface {
- fn add_repository(&mut self, name: &str, config: Option<IndexMap<String, PhpMixed>>, append: bool) -> anyhow::Result<()>;
+ fn add_repository(
+ &mut self,
+ name: &str,
+ config: Option<IndexMap<String, PhpMixed>>,
+ append: bool,
+ ) -> anyhow::Result<()>;
- fn insert_repository(&mut self, name: &str, config: Option<IndexMap<String, PhpMixed>>, reference_name: &str, offset: i64) -> anyhow::Result<()>;
+ fn insert_repository(
+ &mut self,
+ name: &str,
+ config: Option<IndexMap<String, PhpMixed>>,
+ reference_name: &str,
+ offset: i64,
+ ) -> anyhow::Result<()>;
fn set_repository_url(&mut self, name: &str, url: &str) -> anyhow::Result<()>;
diff --git a/crates/shirabe/src/config/json_config_source.rs b/crates/shirabe/src/config/json_config_source.rs
index 264b0e1..5dc5e8d 100644
--- a/crates/shirabe/src/config/json_config_source.rs
+++ b/crates/shirabe/src/config/json_config_source.rs
@@ -3,8 +3,8 @@
use anyhow::Result;
use indexmap::IndexMap;
use shirabe_php_shim::{
- array_unshift, call_user_func_array, chmod, explode, file_get_contents, file_put_contents,
- implode, is_writable, sprintf, PhpMixed, RuntimeException, Silencer, PHP_EOL,
+ PHP_EOL, PhpMixed, RuntimeException, Silencer, array_unshift, call_user_func_array, chmod,
+ explode, file_get_contents, file_put_contents, implode, is_writable, sprintf,
};
use crate::config::config_source_interface::ConfigSourceInterface;
@@ -198,9 +198,12 @@ impl JsonConfigSource {
}
}
}
- self.file.write(config, shirabe_php_shim::JSON_UNESCAPED_SLASHES
- | shirabe_php_shim::JSON_PRETTY_PRINT
- | shirabe_php_shim::JSON_UNESCAPED_UNICODE)?;
+ self.file.write(
+ config,
+ shirabe_php_shim::JSON_UNESCAPED_SLASHES
+ | shirabe_php_shim::JSON_PRETTY_PRINT
+ | shirabe_php_shim::JSON_UNESCAPED_UNICODE,
+ )?;
}
// TODO(phase-b): use anyhow::Result<Result<T, E>> to model PHP try/catch
@@ -320,7 +323,10 @@ impl ConfigSourceInterface for JsonConfigSource {
let _ = (cfg, args);
todo!("setRepositoryUrl fallback closure body");
}),
- vec![PhpMixed::String(name.to_string()), PhpMixed::String(url.to_string())],
+ vec![
+ PhpMixed::String(name.to_string()),
+ PhpMixed::String(url.to_string()),
+ ],
)
}
diff --git a/crates/shirabe/src/console/application.rs b/crates/shirabe/src/console/application.rs
index 25bea8d..8fb84dc 100644
--- a/crates/shirabe/src/console/application.rs
+++ b/crates/shirabe/src/console/application.rs
@@ -112,7 +112,9 @@ impl Application {
ini_set("xdebug.scream", "0");
}
- if function_exists("date_default_timezone_set") && function_exists("date_default_timezone_get") {
+ if function_exists("date_default_timezone_set")
+ && function_exists("date_default_timezone_get")
+ {
let tz = Silencer::call(|| Ok(date_default_timezone_get())).unwrap_or_default();
date_default_timezone_set(&tz);
}
@@ -153,7 +155,11 @@ impl Application {
}
}
- pub fn run(&mut self, input: Option<&dyn InputInterface>, output: Option<&dyn OutputInterface>) -> anyhow::Result<i64> {
+ pub fn run(
+ &mut self,
+ input: Option<&dyn InputInterface>,
+ output: Option<&dyn OutputInterface>,
+ ) -> anyhow::Result<i64> {
let output_owned: Box<dyn OutputInterface>;
let output_ref: &dyn OutputInterface = if let Some(o) = output {
o
@@ -165,13 +171,18 @@ impl Application {
self.inner.run(input, Some(output_ref))
}
- pub fn do_run(&mut self, input: &mut dyn InputInterface, output: &dyn OutputInterface) -> anyhow::Result<i64> {
+ pub fn do_run(
+ &mut self,
+ input: &mut dyn InputInterface,
+ output: &dyn OutputInterface,
+ ) -> anyhow::Result<i64> {
self.disable_plugins_by_default = input.has_parameter_option("--no-plugins", false);
self.disable_scripts_by_default = input.has_parameter_option("--no-scripts", false);
// PHP: static $stdin = null;
// We use an Option here to mimic the lazy initialization.
- static STDIN: std::sync::OnceLock<Option<shirabe_php_shim::PhpResource>> = std::sync::OnceLock::new();
+ static STDIN: std::sync::OnceLock<Option<shirabe_php_shim::PhpResource>> =
+ std::sync::OnceLock::new();
let stdin = STDIN.get_or_init(|| {
if defined("STDIN") {
Some(shirabe_php_shim::stdin_handle())
@@ -187,7 +198,9 @@ impl Application {
input.set_interactive(false);
}
- let mut helpers: Vec<Box<dyn shirabe_external_packages::symfony::component::console::helper::helper::Helper>> = vec![];
+ let mut helpers: Vec<
+ Box<dyn shirabe_external_packages::symfony::component::console::helper::helper::Helper>,
+ > = vec![];
helpers.push(Box::new(QuestionHelper::new()));
let console_io = ConsoleIO::new(input, output, HelperSet::new(helpers));
self.io = Box::new(console_io);
@@ -200,7 +213,11 @@ impl Application {
io.write_error("Disabling cache usage", true, IOInterface::DEBUG);
Platform::put_env(
"COMPOSER_CACHE_DIR",
- if Platform::is_windows() { "nul" } else { "/dev/null" },
+ if Platform::is_windows() {
+ "nul"
+ } else {
+ "/dev/null"
+ },
);
}
@@ -213,7 +230,14 @@ impl Application {
self.initial_working_directory = getcwd();
let cwd = Platform::get_cwd_real(true);
io.write_error(
- &format!("Changed CWD to {}", if !cwd.is_empty() { cwd.clone() } else { nwd.clone() }),
+ &format!(
+ "Changed CWD to {}",
+ if !cwd.is_empty() {
+ cwd.clone()
+ } else {
+ nwd.clone()
+ }
+ ),
true,
IOInterface::DEBUG,
);
@@ -237,13 +261,24 @@ impl Application {
// prompt user for dir change if no composer.json is present in current dir
let no_composer_json_commands = vec![
- "".to_string(), "list".to_string(), "init".to_string(), "about".to_string(),
- "help".to_string(), "diagnose".to_string(), "self-update".to_string(),
- "global".to_string(), "create-project".to_string(), "outdated".to_string(),
+ "".to_string(),
+ "list".to_string(),
+ "init".to_string(),
+ "about".to_string(),
+ "help".to_string(),
+ "diagnose".to_string(),
+ "self-update".to_string(),
+ "global".to_string(),
+ "create-project".to_string(),
+ "outdated".to_string(),
];
let use_parent_dir_if_no_json_available = self.get_use_parent_dir_config_value();
if new_work_dir.is_none()
- && !in_array(command_name.as_deref().unwrap_or(""), &no_composer_json_commands, true)
+ && !in_array(
+ command_name.as_deref().unwrap_or(""),
+ &no_composer_json_commands,
+ true,
+ )
&& !file_exists(&Factory::get_composer_file())
&& use_parent_dir_if_no_json_available.as_bool() != Some(false)
&& (command_name.as_deref() != Some("config")
@@ -253,13 +288,17 @@ impl Application {
&& input.has_parameter_option("-h", true) == false
{
let mut dir = dirname(&Platform::get_cwd_real(true));
- let home_value = Platform::get_env("HOME").or_else(|| Platform::get_env("USERPROFILE")).unwrap_or_else(|| "/".to_string());
+ let home_value = Platform::get_env("HOME")
+ .or_else(|| Platform::get_env("USERPROFILE"))
+ .unwrap_or_else(|| "/".to_string());
let home = realpath(&home_value).unwrap_or_default();
// abort when we reach the home dir or top of the filesystem
while dirname(&dir) != dir && dir != home {
if file_exists(&format!("{}/{}", dir, Factory::get_composer_file())) {
- if use_parent_dir_if_no_json_available.as_bool() != Some(true) && !io.is_interactive() {
+ if use_parent_dir_if_no_json_available.as_bool() != Some(true)
+ && !io.is_interactive()
+ {
io.write_error(&format!("<info>No composer.json in current directory, to use the one at {} run interactively or set config.use-parent-dir to true</info>", dir));
break;
}
@@ -292,12 +331,17 @@ impl Application {
is_non_allowed_root = self.is_running_as_root();
if is_non_allowed_root {
- let uid: i64 = Platform::get_env("SUDO_UID").map(|v| v.parse().unwrap_or(0)).unwrap_or(0);
+ let uid: i64 = Platform::get_env("SUDO_UID")
+ .map(|v| v.parse().unwrap_or(0))
+ .unwrap_or(0);
if uid != 0 {
// Silently clobber any sudo credentials on the invoking user to avoid privilege escalations later on
// ref. https://github.com/composer/composer/issues/5119
let _ = Silencer::call(|| {
- shirabe_php_shim::exec(&format!("sudo -u \\#{} sudo -K > /dev/null 2>&1", uid));
+ shirabe_php_shim::exec(&format!(
+ "sudo -u \\#{} sudo -K > /dev/null 2>&1",
+ uid
+ ));
Ok(())
});
}
@@ -312,24 +356,34 @@ impl Application {
// avoid loading plugins/initializing the Composer instance earlier than necessary if no plugin command is needed
// if showing the version, we never need plugin commands
- let may_need_plugin_command = !input.has_parameter_option_array(&vec!["--version".to_string(), "-V".to_string()], false)
- && (
- command_name.is_none()
- || in_array(command_name.as_deref().unwrap_or(""), &vec!["".to_string(), "list".to_string(), "help".to_string()], true)
- || (command_name.as_deref() == Some("_complete") && !is_non_allowed_root)
- );
+ let may_need_plugin_command = !input
+ .has_parameter_option_array(&vec!["--version".to_string(), "-V".to_string()], false)
+ && (command_name.is_none()
+ || in_array(
+ command_name.as_deref().unwrap_or(""),
+ &vec!["".to_string(), "list".to_string(), "help".to_string()],
+ true,
+ )
+ || (command_name.as_deref() == Some("_complete") && !is_non_allowed_root));
let may_need_script_command = may_need_plugin_command
|| command_name.as_deref() == Some("run-script")
|| raw_command_name != command_name;
- if may_need_plugin_command && !self.disable_plugins_by_default && !self.has_plugin_commands {
+ if may_need_plugin_command && !self.disable_plugins_by_default && !self.has_plugin_commands
+ {
// at this point plugins are needed, so if we are running as root and it is not allowed we need to prompt
// if interactive, and abort otherwise
if is_non_allowed_root {
io.write_error("<warning>Do not run Composer as root/super user! See https://getcomposer.org/root for details</warning>");
- if io.is_interactive() && io.ask_confirmation("<info>Continue as root/super user</info> [<comment>yes</comment>]? ".to_string(), true) {
+ if io.is_interactive()
+ && io.ask_confirmation(
+ "<info>Continue as root/super user</info> [<comment>yes</comment>]? "
+ .to_string(),
+ true,
+ )
+ {
// avoid a second prompt later
is_non_allowed_root = false;
} else {
@@ -431,7 +485,9 @@ impl Application {
io.write_error(&format!("<warning>Composer supports PHP 7.2.5 and above, you will most likely encounter problems with your PHP {}. Upgrading is strongly recommended but you can use Composer 2.2.x LTS as a fallback.</warning>", PHP_VERSION));
}
- if XdebugHandler::is_xdebug_active() && Platform::get_env("COMPOSER_DISABLE_XDEBUG_WARN").is_none() {
+ if XdebugHandler::is_xdebug_active()
+ && Platform::get_env("COMPOSER_DISABLE_XDEBUG_WARN").is_none()
+ {
io.write_error("<warning>Composer is operating slower than normal because you have Xdebug enabled. See https://getcomposer.org/xdebug</warning>");
}
@@ -454,7 +510,11 @@ impl Application {
io.write_error("<warning>Do not run Composer as root/super user! See https://getcomposer.org/root for details</warning>");
if io.is_interactive() {
- if !io.ask_confirmation("<info>Continue as root/super user</info> [<comment>yes</comment>]? ".to_string(), true) {
+ if !io.ask_confirmation(
+ "<info>Continue as root/super user</info> [<comment>yes</comment>]? "
+ .to_string(),
+ true,
+ ) {
return Ok(1);
}
}
@@ -468,7 +528,12 @@ impl Application {
} else {
String::new()
};
- let tempfile = format!("{}/temp-{}{}", sys_get_temp_dir(), pid, bin2hex(&random_bytes(5)));
+ let tempfile = format!(
+ "{}/temp-{}{}",
+ sys_get_temp_dir(),
+ pid,
+ bin2hex(&random_bytes(5))
+ );
if !(file_put_contents(&tempfile, file!()) > 0
&& file_get_contents(&tempfile).as_deref() == Some(file!())
&& unlink(&tempfile)
@@ -482,31 +547,70 @@ impl Application {
// add non-standard scripts as own commands
let file = Factory::get_composer_file();
if may_need_script_command && is_file(&file) && Filesystem::is_readable(&file) {
- let composer_json = json_decode(&file_get_contents(&file).unwrap_or_default(), true);
+ let composer_json =
+ json_decode(&file_get_contents(&file).unwrap_or_default(), true);
if let Some(arr) = composer_json.as_array() {
if let Some(scripts) = arr.get("scripts").and_then(|v| v.as_array()) {
for (script, dummy) in scripts {
- let script_event_const = format!("Composer\\Script\\ScriptEvents::{}", str_replace("-", "_", &strtoupper(script)));
+ let script_event_const = format!(
+ "Composer\\Script\\ScriptEvents::{}",
+ str_replace("-", "_", &strtoupper(script))
+ );
if !defined(&script_event_const) {
if self.inner.has(script) {
io.write_error(&format!("<warning>A script named {} would override a Composer command and has been skipped</warning>", script));
} else {
- let mut description = format!("Runs the {} script as defined in composer.json", script);
+ let mut description = format!(
+ "Runs the {} script as defined in composer.json",
+ script
+ );
- if let Some(desc) = arr.get("scripts-descriptions").and_then(|v| v.as_array()).and_then(|a| a.get(script)).and_then(|v| v.as_string()) {
+ if let Some(desc) = arr
+ .get("scripts-descriptions")
+ .and_then(|v| v.as_array())
+ .and_then(|a| a.get(script))
+ .and_then(|v| v.as_string())
+ {
description = desc.to_string();
}
- let aliases: Vec<String> = arr.get("scripts-aliases").and_then(|v| v.as_array()).and_then(|a| a.get(script)).and_then(|v| v.as_list()).map(|l| l.iter().filter_map(|v| v.as_string().map(|s| s.to_string())).collect()).unwrap_or_default();
+ let aliases: Vec<String> = arr
+ .get("scripts-aliases")
+ .and_then(|v| v.as_array())
+ .and_then(|a| a.get(script))
+ .and_then(|v| v.as_list())
+ .map(|l| {
+ l.iter()
+ .filter_map(|v| {
+ v.as_string().map(|s| s.to_string())
+ })
+ .collect()
+ })
+ .unwrap_or_default();
if let Some(composer) = self.get_composer(false, None, None)? {
let root_package = composer.get_package();
let generator = composer.get_autoload_generator();
- let package_map = generator.build_package_map(composer.get_installation_manager(), &*root_package, vec![])?;
- let map = generator.parse_autoloads(&package_map, &*root_package, PhpMixed::Bool(false));
+ let package_map = generator.build_package_map(
+ composer.get_installation_manager(),
+ &*root_package,
+ vec![],
+ )?;
+ let map = generator.parse_autoloads(
+ &package_map,
+ &*root_package,
+ PhpMixed::Bool(false),
+ );
- let loader = generator.create_loader(&map, composer.get_config().get("vendor-dir").as_string().map(|s| s.to_string()));
+ let loader = generator.create_loader(
+ &map,
+ composer
+ .get_config()
+ .get("vendor-dir")
+ .as_string()
+ .map(|s| s.to_string()),
+ );
loader.register(false);
}
@@ -514,12 +618,22 @@ impl Application {
let dummy_str = dummy.as_string().unwrap_or("");
let cmd: Box<dyn SymfonyCommand> = if is_string(dummy)
&& shirabe_php_shim::class_exists(dummy_str)
- && is_subclass_of(dummy_str, "Symfony\\Component\\Console\\Command\\Command")
- {
- if is_subclass_of(dummy_str, "Symfony\\Component\\Console\\SingleCommandApplication") {
+ && is_subclass_of(
+ dummy_str,
+ "Symfony\\Component\\Console\\Command\\Command",
+ ) {
+ if is_subclass_of(
+ dummy_str,
+ "Symfony\\Component\\Console\\SingleCommandApplication",
+ ) {
io.write_error(&format!("<warning>The script named {} extends SingleCommandApplication which is not compatible with Composer 2.9+, make sure you extend Symfony\\Component\\Console\\Command instead.</warning>", script));
}
- let mut cmd = shirabe_php_shim::instantiate_class::<Box<dyn SymfonyCommand>>(dummy_str, vec![PhpMixed::String(script.clone())]);
+ let mut cmd = shirabe_php_shim::instantiate_class::<
+ Box<dyn SymfonyCommand>,
+ >(
+ dummy_str,
+ vec![PhpMixed::String(script.clone())],
+ );
let _ = SingleCommandApplication::class_name();
// makes sure the command is find()'able by the name defined in composer.json, and the name isn't overridden in its configure()
@@ -529,13 +643,19 @@ impl Application {
cmd.set_name(script);
}
- if cmd.get_description().is_empty() && is_string(&PhpMixed::String(description.clone())) {
+ if cmd.get_description().is_empty()
+ && is_string(&PhpMixed::String(description.clone()))
+ {
cmd.set_description(&description);
}
cmd
} else {
// fallback to usual aliasing behavior
- Box::new(ScriptAliasCommand::new(script.clone(), description.clone(), aliases))
+ Box::new(ScriptAliasCommand::new(
+ script.clone(),
+ description.clone(),
+ aliases,
+ ))
};
// Compatibility layer for symfony/console <7.4
@@ -561,12 +681,16 @@ impl Application {
let result = self.inner.do_run(input, output)?;
- if input.has_parameter_option_array(&vec!["--version".to_string(), "-V".to_string()], true) {
+ if input
+ .has_parameter_option_array(&vec!["--version".to_string(), "-V".to_string()], true)
+ {
io.write_error(&sprintf(
"<info>PHP</info> version <comment>%s</comment> (%s)",
&[PHP_VERSION.into(), PHP_BINARY.into()],
));
- io.write_error("Run the \"diagnose\" command to get more detailed diagnostics output.");
+ io.write_error(
+ "Run the \"diagnose\" command to get more detailed diagnostics output.",
+ );
}
Ok(result)
@@ -596,9 +720,16 @@ impl Application {
Ok(r) => Ok(r),
Err(e) => {
if let Some(see) = e.downcast_ref::<ScriptExecutionException>() {
- if self.get_disable_plugins_by_default() && self.is_running_as_root() && !self.io.is_interactive() {
+ if self.get_disable_plugins_by_default()
+ && self.is_running_as_root()
+ && !self.io.is_interactive()
+ {
io.write_error("<error>Plugins have been disabled automatically as you are running as root, this may be the cause of the script failure.</error>", true, IOInterface::QUIET);
- io.write_error("<error>See also https://getcomposer.org/root</error>", true, IOInterface::QUIET);
+ io.write_error(
+ "<error>See also https://getcomposer.org/root</error>",
+ true,
+ IOInterface::QUIET,
+ );
}
Ok(see.get_code())
@@ -609,13 +740,18 @@ impl Application {
self.hint_common_errors(&e, output);
if !method_exists(&self.inner, "setCatchErrors") {
- if let Some(coi) = output.as_any().downcast_ref::<dyn ConsoleOutputInterface>() {
+ if let Some(coi) =
+ output.as_any().downcast_ref::<dyn ConsoleOutputInterface>()
+ {
self.inner.render_throwable(&e, coi.get_error_output());
} else {
self.inner.render_throwable(&e, output);
}
- let code = e.downcast_ref::<RuntimeException>().map(|r| r.code).unwrap_or(0);
+ let code = e
+ .downcast_ref::<RuntimeException>()
+ .map(|r| r.code)
+ .unwrap_or(0);
return Ok(max_i64(1, code));
}
@@ -641,13 +777,20 @@ impl Application {
fn get_new_working_dir(&self, input: &dyn InputInterface) -> anyhow::Result<Option<String>> {
let working_dir = input
- .get_parameter_option(&vec!["--working-dir".to_string(), "-d".to_string()], None, true)
+ .get_parameter_option(
+ &vec!["--working-dir".to_string(), "-d".to_string()],
+ None,
+ true,
+ )
.as_string()
.map(|s| s.to_string());
if let Some(ref wd) = working_dir {
if !is_dir(wd) {
return Err(RuntimeException {
- message: format!("Invalid working directory specified, {} does not exist.", wd),
+ message: format!(
+ "Invalid working directory specified, {} does not exist.",
+ wd
+ ),
code: 0,
}
.into());
@@ -677,7 +820,11 @@ impl Application {
let df = disk_free_space(&dir);
let mut hit = df.map(|d| d < min_space_free).unwrap_or(false);
if !hit {
- dir = config.get("vendor-dir").as_string().unwrap_or("").to_string();
+ dir = config
+ .get("vendor-dir")
+ .as_string()
+ .unwrap_or("")
+ .to_string();
let df = disk_free_space(&dir);
hit = df.map(|d| d < min_space_free).unwrap_or(false);
}
@@ -695,23 +842,48 @@ impl Application {
Silencer::restore();
let message = exception.to_string();
- if exception.downcast_ref::<TransportException>().is_some() && str_contains(&message, "Unable to use a proxy") {
- io.write_error("<error>The following exception indicates your proxy is misconfigured</error>", true, IOInterface::QUIET);
+ if exception.downcast_ref::<TransportException>().is_some()
+ && str_contains(&message, "Unable to use a proxy")
+ {
+ io.write_error(
+ "<error>The following exception indicates your proxy is misconfigured</error>",
+ true,
+ IOInterface::QUIET,
+ );
io.write_error("<error>Check https://getcomposer.org/doc/faqs/how-to-use-composer-behind-a-proxy.md for details</error>", true, IOInterface::QUIET);
}
- if Platform::is_windows() && exception.downcast_ref::<TransportException>().is_some() && str_contains(&message, "unable to get local issuer certificate") {
+ if Platform::is_windows()
+ && exception.downcast_ref::<TransportException>().is_some()
+ && str_contains(&message, "unable to get local issuer certificate")
+ {
let avast_detect = glob("C:\\Program Files\\Avast*");
- if is_array(&PhpMixed::List(avast_detect.iter().map(|s| Box::new(PhpMixed::String(s.clone()))).collect())) && count(&avast_detect) != 0 {
+ if is_array(&PhpMixed::List(
+ avast_detect
+ .iter()
+ .map(|s| Box::new(PhpMixed::String(s.clone())))
+ .collect(),
+ )) && count(&avast_detect) != 0
+ {
io.write_error("<error>The following exception indicates a possible issue with the Avast Firewall</error>", true, IOInterface::QUIET);
- io.write_error("<error>Check https://getcomposer.org/local-issuer for details</error>", true, IOInterface::QUIET);
+ io.write_error(
+ "<error>Check https://getcomposer.org/local-issuer for details</error>",
+ true,
+ IOInterface::QUIET,
+ );
} else {
io.write_error("<error>The following exception indicates a possible issue with a Firewall/Antivirus</error>", true, IOInterface::QUIET);
- io.write_error("<error>Check https://getcomposer.org/local-issuer for details</error>", true, IOInterface::QUIET);
+ io.write_error(
+ "<error>Check https://getcomposer.org/local-issuer for details</error>",
+ true,
+ IOInterface::QUIET,
+ );
}
}
- if Platform::is_windows() && strpos(&message, "The system cannot find the path specified").is_some() {
+ if Platform::is_windows()
+ && strpos(&message, "The system cannot find the path specified").is_some()
+ {
io.write_error("<error>The following exception may be caused by a stale entry in your cmd.exe AutoRun</error>", true, IOInterface::QUIET);
io.write_error("<error>Check https://getcomposer.org/doc/articles/troubleshooting.md#-the-system-cannot-find-the-path-specified-windows- for details</error>", true, IOInterface::QUIET);
}
@@ -721,14 +893,28 @@ impl Application {
io.write_error("<error>Check https://getcomposer.org/doc/articles/troubleshooting.md#proc-open-fork-failed-errors for details</error>", true, IOInterface::QUIET);
}
- if exception.downcast_ref::<ProcessTimedOutException>().is_some() {
- io.write_error("<error>The following exception is caused by a process timeout</error>", true, IOInterface::QUIET);
+ if exception
+ .downcast_ref::<ProcessTimedOutException>()
+ .is_some()
+ {
+ io.write_error(
+ "<error>The following exception is caused by a process timeout</error>",
+ true,
+ IOInterface::QUIET,
+ );
io.write_error("<error>Check https://getcomposer.org/doc/06-config.md#process-timeout for details</error>", true, IOInterface::QUIET);
}
- if self.get_disable_plugins_by_default() && self.is_running_as_root() && !self.io.is_interactive() {
+ if self.get_disable_plugins_by_default()
+ && self.is_running_as_root()
+ && !self.io.is_interactive()
+ {
io.write_error("<error>Plugins have been disabled automatically as you are running as root, this may be the cause of the following exception. See also https://getcomposer.org/root</error>", true, IOInterface::QUIET);
- } else if exception.downcast_ref::<CommandNotFoundException>().is_some() && self.get_disable_plugins_by_default() {
+ } else if exception
+ .downcast_ref::<CommandNotFoundException>()
+ .is_some()
+ && self.get_disable_plugins_by_default()
+ {
io.write_error("<error>Plugins have been disabled, which may be why some commands are missing, unless you made a typo</error>", true, IOInterface::QUIET);
}
@@ -851,7 +1037,10 @@ impl Application {
if !Composer::BRANCH_ALIAS_VERSION.is_empty()
&& Composer::BRANCH_ALIAS_VERSION != "@package_branch_alias_version@"
{
- branch_alias_string = sprintf(" (%s)", &[Composer::BRANCH_ALIAS_VERSION.to_string().into()]);
+ branch_alias_string = sprintf(
+ " (%s)",
+ &[Composer::BRANCH_ALIAS_VERSION.to_string().into()],
+ );
}
sprintf(
@@ -867,11 +1056,46 @@ impl Application {
pub(crate) fn get_default_input_definition(&self) -> InputDefinition {
let mut definition = self.inner.get_default_input_definition();
- definition.add_option(InputOption::new("--profile", None, Some(InputOption::VALUE_NONE), "Display timing and memory usage information", None, vec![]));
- definition.add_option(InputOption::new("--no-plugins", None, Some(InputOption::VALUE_NONE), "Whether to disable plugins.", None, vec![]));
- definition.add_option(InputOption::new("--no-scripts", None, Some(InputOption::VALUE_NONE), "Skips the execution of all scripts defined in composer.json file.", None, vec![]));
- definition.add_option(InputOption::new("--working-dir", Some("-d"), Some(InputOption::VALUE_REQUIRED), "If specified, use the given directory as working directory.", None, vec![]));
- definition.add_option(InputOption::new("--no-cache", None, Some(InputOption::VALUE_NONE), "Prevent use of the cache", None, vec![]));
+ definition.add_option(InputOption::new(
+ "--profile",
+ None,
+ Some(InputOption::VALUE_NONE),
+ "Display timing and memory usage information",
+ None,
+ vec![],
+ ));
+ definition.add_option(InputOption::new(
+ "--no-plugins",
+ None,
+ Some(InputOption::VALUE_NONE),
+ "Whether to disable plugins.",
+ None,
+ vec![],
+ ));
+ definition.add_option(InputOption::new(
+ "--no-scripts",
+ None,
+ Some(InputOption::VALUE_NONE),
+ "Skips the execution of all scripts defined in composer.json file.",
+ None,
+ vec![],
+ ));
+ definition.add_option(InputOption::new(
+ "--working-dir",
+ Some("-d"),
+ Some(InputOption::VALUE_REQUIRED),
+ "If specified, use the given directory as working directory.",
+ None,
+ vec![],
+ ));
+ definition.add_option(InputOption::new(
+ "--no-cache",
+ None,
+ Some(InputOption::VALUE_NONE),
+ "Prevent use of the cache",
+ None,
+ vec![],
+ ));
definition
}
@@ -883,15 +1107,27 @@ impl Application {
let composer = self.get_composer(false, Some(false), None)?.cloned();
let composer = match composer {
Some(c) => Some(c),
- None => Factory::create_global(&*self.io, self.disable_plugins_by_default, self.disable_scripts_by_default),
+ None => Factory::create_global(
+ &*self.io,
+ self.disable_plugins_by_default,
+ self.disable_scripts_by_default,
+ ),
};
if let Some(composer) = composer {
let pm = composer.get_plugin_manager();
let mut ctor_args: IndexMap<String, PhpMixed> = IndexMap::new();
- ctor_args.insert("composer".to_string(), PhpMixed::Object(shirabe_php_shim::ArrayObject::new()));
- ctor_args.insert("io".to_string(), PhpMixed::Object(shirabe_php_shim::ArrayObject::new()));
- for capability in pm.get_plugin_capabilities("Composer\\Plugin\\Capability\\CommandProvider", ctor_args) {
+ ctor_args.insert(
+ "composer".to_string(),
+ PhpMixed::Object(shirabe_php_shim::ArrayObject::new()),
+ );
+ ctor_args.insert(
+ "io".to_string(),
+ PhpMixed::Object(shirabe_php_shim::ArrayObject::new()),
+ );
+ for capability in pm
+ .get_plugin_capabilities("Composer\\Plugin\\Capability\\CommandProvider", ctor_args)
+ {
let new_commands = capability.get_commands();
for command in &new_commands {
if command.as_any().downcast_ref::<BaseCommand>().is_none() {
diff --git a/crates/shirabe/src/console/github_action_error.rs b/crates/shirabe/src/console/github_action_error.rs
index cb6a181..c74f95f 100644
--- a/crates/shirabe/src/console/github_action_error.rs
+++ b/crates/shirabe/src/console/github_action_error.rs
@@ -24,10 +24,16 @@ impl GithubActionError {
if file_truthy && line_truthy {
let file = self.escape_property(file.unwrap());
- self.io.write(&format!("::error file={},line={}::{}", file, line.unwrap(), message));
+ self.io.write(&format!(
+ "::error file={},line={}::{}",
+ file,
+ line.unwrap(),
+ message
+ ));
} else if file_truthy {
let file = self.escape_property(file.unwrap());
- self.io.write(&format!("::error file={}::{}", file, message));
+ self.io
+ .write(&format!("::error file={}::{}", file, message));
} else {
self.io.write(&format!("::error ::{}", message));
}
diff --git a/crates/shirabe/src/console/html_output_formatter.rs b/crates/shirabe/src/console/html_output_formatter.rs
index f34ca1b..a69b4c6 100644
--- a/crates/shirabe/src/console/html_output_formatter.rs
+++ b/crates/shirabe/src/console/html_output_formatter.rs
@@ -1,9 +1,9 @@
//! ref: composer/src/Composer/Console/HtmlOutputFormatter.php
+use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::symfony::console::formatter::output_formatter::OutputFormatter;
use shirabe_external_packages::symfony::console::formatter::output_formatter_style::OutputFormatterStyle;
-use indexmap::IndexMap;
#[derive(Debug)]
pub struct HtmlOutputFormatter {
@@ -66,11 +66,19 @@ impl HtmlOutputFormatter {
for code_str in codes_str.split(';') {
let code: i64 = code_str.parse().unwrap_or(0);
- if let Some(&(_, color)) = Self::AVAILABLE_FOREGROUND_COLORS.iter().find(|&&(k, _)| k == code) {
+ if let Some(&(_, color)) = Self::AVAILABLE_FOREGROUND_COLORS
+ .iter()
+ .find(|&&(k, _)| k == code)
+ {
out.push_str(&format!("color:{};", color));
- } else if let Some(&(_, color)) = Self::AVAILABLE_BACKGROUND_COLORS.iter().find(|&&(k, _)| k == code) {
+ } else if let Some(&(_, color)) = Self::AVAILABLE_BACKGROUND_COLORS
+ .iter()
+ .find(|&&(k, _)| k == code)
+ {
out.push_str(&format!("background-color:{};", color));
- } else if let Some(&(_, option)) = Self::AVAILABLE_OPTIONS.iter().find(|&&(k, _)| k == code) {
+ } else if let Some(&(_, option)) =
+ Self::AVAILABLE_OPTIONS.iter().find(|&&(k, _)| k == code)
+ {
match option {
"bold" => out.push_str("font-weight:bold;"),
"underscore" => out.push_str("text-decoration:underline;"),
diff --git a/crates/shirabe/src/console/input/input_option.rs b/crates/shirabe/src/console/input/input_option.rs
index 069c3f4..6e93a62 100644
--- a/crates/shirabe/src/console/input/input_option.rs
+++ b/crates/shirabe/src/console/input/input_option.rs
@@ -51,16 +51,20 @@ impl InputOption {
if let SuggestedValues::List(ref list) = this.suggested_values {
if !list.is_empty() && !this.inner.accept_value() {
return Err(LogicException {
- message: "Cannot set suggested values if the option does not accept a value.".to_string(),
+ message: "Cannot set suggested values if the option does not accept a value."
+ .to_string(),
code: 0,
- }.into());
+ }
+ .into());
}
} else if let SuggestedValues::Closure(_) = this.suggested_values {
if !this.inner.accept_value() {
return Err(LogicException {
- message: "Cannot set suggested values if the option does not accept a value.".to_string(),
+ message: "Cannot set suggested values if the option does not accept a value."
+ .to_string(),
code: 0,
- }.into());
+ }
+ .into());
}
}
diff --git a/crates/shirabe/src/console/input/mod.rs b/crates/shirabe/src/console/input/mod.rs
new file mode 100644
index 0000000..f4451af
--- /dev/null
+++ b/crates/shirabe/src/console/input/mod.rs
@@ -0,0 +1,2 @@
+pub mod input_argument;
+pub mod input_option;
diff --git a/crates/shirabe/src/console/mod.rs b/crates/shirabe/src/console/mod.rs
new file mode 100644
index 0000000..ea42d75
--- /dev/null
+++ b/crates/shirabe/src/console/mod.rs
@@ -0,0 +1,4 @@
+pub mod application;
+pub mod github_action_error;
+pub mod html_output_formatter;
+pub mod input;
diff --git a/crates/shirabe/src/dependency_resolver/decisions.rs b/crates/shirabe/src/dependency_resolver/decisions.rs
index db1068d..22b6fa4 100644
--- a/crates/shirabe/src/dependency_resolver/decisions.rs
+++ b/crates/shirabe/src/dependency_resolver/decisions.rs
@@ -1,11 +1,11 @@
//! ref: composer/src/Composer/DependencyResolver/Decisions.php
-use std::fmt;
-use indexmap::IndexMap;
-use shirabe_php_shim::LogicException;
use crate::dependency_resolver::pool::Pool;
use crate::dependency_resolver::rule::Rule;
use crate::dependency_resolver::solver_bug_exception::SolverBugException;
+use indexmap::IndexMap;
+use shirabe_php_shim::LogicException;
+use std::fmt;
#[derive(Debug)]
pub struct Decisions {
@@ -43,16 +43,28 @@ impl Decisions {
pub fn conflict(&self, literal: i64) -> bool {
let package_id = literal.abs();
- (self.decision_map.contains_key(&package_id) && self.decision_map[&package_id] > 0 && literal < 0)
- || (self.decision_map.contains_key(&package_id) && self.decision_map[&package_id] < 0 && literal > 0)
+ (self.decision_map.contains_key(&package_id)
+ && self.decision_map[&package_id] > 0
+ && literal < 0)
+ || (self.decision_map.contains_key(&package_id)
+ && self.decision_map[&package_id] < 0
+ && literal > 0)
}
pub fn decided(&self, literal_or_package_id: i64) -> bool {
- self.decision_map.get(&literal_or_package_id.abs()).copied().unwrap_or(0) != 0
+ self.decision_map
+ .get(&literal_or_package_id.abs())
+ .copied()
+ .unwrap_or(0)
+ != 0
}
pub fn undecided(&self, literal_or_package_id: i64) -> bool {
- self.decision_map.get(&literal_or_package_id.abs()).copied().unwrap_or(0) == 0
+ self.decision_map
+ .get(&literal_or_package_id.abs())
+ .copied()
+ .unwrap_or(0)
+ == 0
}
pub fn decided_install(&self, literal_or_package_id: i64) -> bool {
@@ -79,10 +91,17 @@ impl Decisions {
}
}
- panic!("{}", LogicException {
- message: format!("Did not find a decision rule using {}", literal_or_package_id),
- code: 0,
- }.message);
+ panic!(
+ "{}",
+ LogicException {
+ message: format!(
+ "Did not find a decision rule using {}",
+ literal_or_package_id
+ ),
+ code: 0,
+ }
+ .message
+ );
}
pub fn at_offset(&self, queue_offset: usize) -> &(i64, Rule) {
@@ -133,7 +152,8 @@ impl Decisions {
}
pub fn current(&self) -> Option<&(i64, Rule)> {
- self.iterator_cursor.and_then(|cursor| self.decision_queue.get(cursor))
+ self.iterator_cursor
+ .and_then(|cursor| self.decision_queue.get(cursor))
}
pub fn key(&self) -> Option<usize> {
@@ -141,13 +161,9 @@ impl Decisions {
}
pub fn next(&mut self) {
- self.iterator_cursor = self.iterator_cursor.and_then(|cursor| {
- if cursor > 0 {
- Some(cursor - 1)
- } else {
- None
- }
- });
+ self.iterator_cursor = self
+ .iterator_cursor
+ .and_then(|cursor| if cursor > 0 { Some(cursor - 1) } else { None });
}
pub fn valid(&self) -> bool {
@@ -163,11 +179,19 @@ impl Decisions {
let previous_decision = self.decision_map.get(&package_id).copied().unwrap_or(0);
if previous_decision != 0 {
- let literal_string = self.pool.literal_to_pretty_string(literal, &IndexMap::new());
+ let literal_string = self
+ .pool
+ .literal_to_pretty_string(literal, &IndexMap::new());
let package = self.pool.literal_to_package(literal);
- panic!("{}", SolverBugException::new(
- format!("Trying to decide {} on level {}, even though {} was previously decided as {}.", literal_string, level, package, previous_decision)
- ).0.message);
+ panic!(
+ "{}",
+ SolverBugException::new(format!(
+ "Trying to decide {} on level {}, even though {} was previously decided as {}.",
+ literal_string, level, package, previous_decision
+ ))
+ .0
+ .message
+ );
}
if literal > 0 {
diff --git a/crates/shirabe/src/dependency_resolver/default_policy.rs b/crates/shirabe/src/dependency_resolver/default_policy.rs
index d84863b..f647327 100644
--- a/crates/shirabe/src/dependency_resolver/default_policy.rs
+++ b/crates/shirabe/src/dependency_resolver/default_policy.rs
@@ -51,8 +51,12 @@ impl DefaultPolicy {
ignore_replace: bool,
) -> i64 {
if a.get_name() == b.get_name() {
- let a_aliased = (a.as_any() as &dyn Any).downcast_ref::<AliasPackage>().is_some();
- let b_aliased = (b.as_any() as &dyn Any).downcast_ref::<AliasPackage>().is_some();
+ let a_aliased = (a.as_any() as &dyn Any)
+ .downcast_ref::<AliasPackage>()
+ .is_some();
+ let b_aliased = (b.as_any() as &dyn Any)
+ .downcast_ref::<AliasPackage>()
+ .is_some();
if a_aliased && !b_aliased {
return -1;
}
@@ -108,7 +112,9 @@ impl DefaultPolicy {
let best_literals: Vec<i64> = literals
.iter()
.copied()
- .filter(|&literal| pool.literal_to_package(literal).get_version() == preferred_version)
+ .filter(|&literal| {
+ pool.literal_to_package(literal).get_version() == preferred_version
+ })
.collect();
if !best_literals.is_empty() {
return best_literals;
@@ -174,15 +180,28 @@ impl DefaultPolicy {
}
impl PolicyInterface for DefaultPolicy {
- fn version_compare(&self, a: &dyn PackageInterface, b: &dyn PackageInterface, operator: &str) -> bool {
+ fn version_compare(
+ &self,
+ a: &dyn PackageInterface,
+ b: &dyn PackageInterface,
+ operator: &str,
+ ) -> bool {
if self.prefer_stable {
let stab_a = a.get_stability().to_string();
let stab_b = b.get_stability().to_string();
if stab_a != stab_b {
let (mut stab_a, mut stab_b) = (stab_a, stab_b);
- if self.prefer_lowest && self.prefer_dev_over_prerelease && "stable" != stab_a && "stable" != stab_b {
- if stab_a == "dev" { stab_a = "stable".to_string(); }
- if stab_b == "dev" { stab_b = "stable".to_string(); }
+ if self.prefer_lowest
+ && self.prefer_dev_over_prerelease
+ && "stable" != stab_a
+ && "stable" != stab_b
+ {
+ if stab_a == "dev" {
+ stab_a = "stable".to_string();
+ }
+ if stab_b == "dev" {
+ stab_b = "stable".to_string();
+ }
}
return STABILITIES.get(stab_a.as_str()).copied().unwrap_or(0)
< STABILITIES.get(stab_b.as_str()).copied().unwrap_or(0);
@@ -213,7 +232,11 @@ impl PolicyInterface for DefaultPolicy {
literals.sort();
let result_cache_key = format!(
"{}{}",
- literals.iter().map(|l| l.to_string()).collect::<Vec<_>>().join(","),
+ literals
+ .iter()
+ .map(|l| l.to_string())
+ .collect::<Vec<_>>()
+ .join(","),
required_package.as_deref().unwrap_or("")
);
let pool_id = pool as *const Pool as i64;
@@ -231,12 +254,8 @@ impl PolicyInterface for DefaultPolicy {
for name_literals in packages.values_mut() {
name_literals.sort_by(|&a, &b| {
- let cache_key = format!(
- "i{}.{}{}",
- a,
- b,
- required_package.as_deref().unwrap_or("")
- );
+ let cache_key =
+ format!("i{}.{}{}", a, b, required_package.as_deref().unwrap_or(""));
{
let cache = self.sorting_cache_per_pool.borrow();
if let Some(pool_cache) = cache.get(&pool_id) {
@@ -269,12 +288,7 @@ impl PolicyInterface for DefaultPolicy {
let mut selected: Vec<i64> = packages.into_values().flatten().collect();
selected.sort_by(|&a, &b| {
- let cache_key = format!(
- "{}.{}{}",
- a,
- b,
- required_package.as_deref().unwrap_or("")
- );
+ let cache_key = format!("{}.{}{}", a, b, required_package.as_deref().unwrap_or(""));
{
let cache = self.sorting_cache_per_pool.borrow();
if let Some(pool_cache) = cache.get(&pool_id) {
diff --git a/crates/shirabe/src/dependency_resolver/generic_rule.rs b/crates/shirabe/src/dependency_resolver/generic_rule.rs
index 520d483..f30d612 100644
--- a/crates/shirabe/src/dependency_resolver/generic_rule.rs
+++ b/crates/shirabe/src/dependency_resolver/generic_rule.rs
@@ -1,8 +1,8 @@
//! ref: composer/src/Composer/DependencyResolver/GenericRule.php
-use anyhow::Result;
-use shirabe_php_shim::{hash_raw, implode, unpack, RuntimeException, PHP_VERSION_ID};
use crate::dependency_resolver::rule::Rule;
+use anyhow::Result;
+use shirabe_php_shim::{PHP_VERSION_ID, RuntimeException, hash_raw, implode, unpack};
pub struct GenericRule {
inner: Rule,
@@ -10,7 +10,11 @@ pub struct GenericRule {
}
impl GenericRule {
- pub fn new(mut literals: Vec<i64>, reason: shirabe_php_shim::PhpMixed, reason_data: shirabe_php_shim::PhpMixed) -> Self {
+ pub fn new(
+ mut literals: Vec<i64>,
+ reason: shirabe_php_shim::PhpMixed,
+ reason_data: shirabe_php_shim::PhpMixed,
+ ) -> Self {
let inner = Rule::new(reason, reason_data);
literals.sort();
Self { inner, literals }
@@ -21,8 +25,17 @@ impl GenericRule {
}
pub fn get_hash(&self) -> Result<i64> {
- let joined = self.literals.iter().map(|l| l.to_string()).collect::<Vec<_>>().join(",");
- let algo = if PHP_VERSION_ID > 80100 { "xxh3" } else { "sha1" };
+ let joined = self
+ .literals
+ .iter()
+ .map(|l| l.to_string())
+ .collect::<Vec<_>>()
+ .join(",");
+ let algo = if PHP_VERSION_ID > 80100 {
+ "xxh3"
+ } else {
+ "sha1"
+ };
let binary = hash_raw(algo, &joined);
let data = unpack("ihash", &binary);
match data {
@@ -33,13 +46,15 @@ impl GenericRule {
Err(RuntimeException {
message: format!("Failed unpacking: {}", joined),
code: 0,
- }.into())
+ }
+ .into())
}
}
None => Err(RuntimeException {
message: format!("Failed unpacking: {}", joined),
code: 0,
- }.into()),
+ }
+ .into()),
}
}
@@ -52,7 +67,11 @@ impl GenericRule {
}
pub fn to_string(&self) -> String {
- let prefix = if self.inner.is_disabled() { "disabled(" } else { "(" };
+ let prefix = if self.inner.is_disabled() {
+ "disabled("
+ } else {
+ "("
+ };
let mut result = prefix.to_string();
for (i, literal) in self.literals.iter().enumerate() {
if i != 0 {
@@ -67,7 +86,9 @@ impl GenericRule {
pub trait RuleLiterals {
fn get_literals(&self) -> &Vec<i64>;
- fn is_multi_conflict_rule(&self) -> bool { false }
+ fn is_multi_conflict_rule(&self) -> bool {
+ false
+ }
}
impl RuleLiterals for GenericRule {
diff --git a/crates/shirabe/src/dependency_resolver/local_repo_transaction.rs b/crates/shirabe/src/dependency_resolver/local_repo_transaction.rs
index 5797a3b..dca5c1a 100644
--- a/crates/shirabe/src/dependency_resolver/local_repo_transaction.rs
+++ b/crates/shirabe/src/dependency_resolver/local_repo_transaction.rs
@@ -1,8 +1,8 @@
//! ref: composer/src/Composer/DependencyResolver/LocalRepoTransaction.php
+use super::transaction::Transaction;
use crate::repository::installed_repository_interface::InstalledRepositoryInterface;
use crate::repository::repository_interface::RepositoryInterface;
-use super::transaction::Transaction;
#[derive(Debug)]
pub struct LocalRepoTransaction {
@@ -10,7 +10,10 @@ pub struct LocalRepoTransaction {
}
impl LocalRepoTransaction {
- pub fn new(locked_repository: &dyn RepositoryInterface, local_repository: &dyn InstalledRepositoryInterface) -> Self {
+ pub fn new(
+ locked_repository: &dyn RepositoryInterface,
+ local_repository: &dyn InstalledRepositoryInterface,
+ ) -> Self {
Self {
inner: Transaction::new(
local_repository.get_packages(),
diff --git a/crates/shirabe/src/dependency_resolver/lock_transaction.rs b/crates/shirabe/src/dependency_resolver/lock_transaction.rs
index 4b4cc32..44becb0 100644
--- a/crates/shirabe/src/dependency_resolver/lock_transaction.rs
+++ b/crates/shirabe/src/dependency_resolver/lock_transaction.rs
@@ -39,9 +39,8 @@ impl LockTransaction {
};
this.set_result_packages(pool, decisions);
let all = this.result_packages.get("all").cloned().unwrap_or_default();
- let present: Vec<Box<dyn PackageInterface>> = this.present_map.values()
- .map(|p| p.clone_box())
- .collect();
+ let present: Vec<Box<dyn PackageInterface>> =
+ this.present_map.values().map(|p| p.clone_box()).collect();
this.inner = Transaction::new(present, all);
this
}
@@ -58,9 +57,15 @@ impl LockTransaction {
if literal > 0 {
let package = pool.literal_to_package(literal);
- result_packages.get_mut("all").unwrap().push(package.clone_box());
+ result_packages
+ .get_mut("all")
+ .unwrap()
+ .push(package.clone_box());
if !self.unlockable_map.contains_key(&package.get_id()) {
- result_packages.get_mut("non-dev").unwrap().push(package.clone_box());
+ result_packages
+ .get_mut("non-dev")
+ .unwrap()
+ .push(package.clone_box());
}
}
}
@@ -81,22 +86,37 @@ impl LockTransaction {
while i < remaining_dev.len() {
if package.get_name() == remaining_dev[i].get_name() {
let result_package = remaining_dev.remove(i);
- self.result_packages.get_mut("non-dev").unwrap().push(result_package);
+ self.result_packages
+ .get_mut("non-dev")
+ .unwrap()
+ .push(result_package);
} else {
i += 1;
}
}
}
- self.result_packages.insert("dev".to_string(), remaining_dev);
+ self.result_packages
+ .insert("dev".to_string(), remaining_dev);
}
- pub fn get_new_lock_packages(&self, dev_mode: bool, update_mirrors: bool) -> Vec<Box<dyn PackageInterface>> {
+ pub fn get_new_lock_packages(
+ &self,
+ dev_mode: bool,
+ update_mirrors: bool,
+ ) -> Vec<Box<dyn PackageInterface>> {
let key = if dev_mode { "dev" } else { "non-dev" };
let mut packages = vec![];
- let source = self.result_packages.get(key).map(|v| v.as_slice()).unwrap_or_default();
+ let source = self
+ .result_packages
+ .get(key)
+ .map(|v| v.as_slice())
+ .unwrap_or_default();
for package in source {
- if (package.as_any() as &dyn Any).downcast_ref::<AliasPackage>().is_some() {
+ if (package.as_any() as &dyn Any)
+ .downcast_ref::<AliasPackage>()
+ .is_some()
+ {
continue;
}
@@ -129,7 +149,9 @@ impl LockTransaction {
continue;
}
- if let Some(concrete_pkg) = (present_package.as_any() as &dyn Any).downcast_ref::<Package>() {
+ if let Some(concrete_pkg) =
+ (present_package.as_any() as &dyn Any).downcast_ref::<Package>()
+ {
concrete_pkg.set_source_url(package.get_source_url());
concrete_pkg.set_source_mirrors(package.get_source_mirrors());
}
@@ -167,10 +189,15 @@ impl LockTransaction {
if let Some(all_packages) = self.result_packages.get("all") {
for package in all_packages {
- if (package.as_any() as &dyn Any).downcast_ref::<AliasPackage>().is_some() {
+ if (package.as_any() as &dyn Any)
+ .downcast_ref::<AliasPackage>()
+ .is_some()
+ {
let mut i = 0;
while i < remaining_aliases.len() {
- if remaining_aliases[i].get("package").map(|s| s.as_str()) == Some(package.get_name()) {
+ if remaining_aliases[i].get("package").map(|s| s.as_str())
+ == Some(package.get_name())
+ {
used_aliases.push(remaining_aliases.remove(i));
} else {
i += 1;
@@ -189,7 +216,10 @@ impl LockTransaction {
used_aliases
}
- pub fn get_operations(&self) -> &Vec<Box<dyn crate::dependency_resolver::operation::operation_interface::OperationInterface>> {
+ pub fn get_operations(
+ &self,
+ ) -> &Vec<Box<dyn crate::dependency_resolver::operation::operation_interface::OperationInterface>>
+ {
self.inner.get_operations()
}
}
diff --git a/crates/shirabe/src/dependency_resolver/mod.rs b/crates/shirabe/src/dependency_resolver/mod.rs
new file mode 100644
index 0000000..9154084
--- /dev/null
+++ b/crates/shirabe/src/dependency_resolver/mod.rs
@@ -0,0 +1,26 @@
+pub mod decisions;
+pub mod default_policy;
+pub mod generic_rule;
+pub mod local_repo_transaction;
+pub mod lock_transaction;
+pub mod multi_conflict_rule;
+pub mod operation;
+pub mod policy_interface;
+pub mod pool;
+pub mod pool_builder;
+pub mod pool_optimizer;
+pub mod problem;
+pub mod request;
+pub mod rule;
+pub mod rule2_literals;
+pub mod rule_set;
+pub mod rule_set_generator;
+pub mod rule_set_iterator;
+pub mod rule_watch_chain;
+pub mod rule_watch_graph;
+pub mod rule_watch_node;
+pub mod security_advisory_pool_filter;
+pub mod solver;
+pub mod solver_bug_exception;
+pub mod solver_problems_exception;
+pub mod transaction;
diff --git a/crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs b/crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs
index 172b6f4..b15434e 100644
--- a/crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs
+++ b/crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs
@@ -1,9 +1,9 @@
//! ref: composer/src/Composer/DependencyResolver/MultiConflictRule.php
-use anyhow::Result;
-use shirabe_php_shim::{hash_raw, PHP_VERSION_ID, RuntimeException};
use crate::dependency_resolver::generic_rule::RuleLiterals;
use crate::dependency_resolver::rule::Rule;
+use anyhow::Result;
+use shirabe_php_shim::{PHP_VERSION_ID, RuntimeException, hash_raw};
#[derive(Debug)]
pub struct MultiConflictRule {
@@ -12,12 +12,17 @@ pub struct MultiConflictRule {
}
impl MultiConflictRule {
- pub fn new(mut literals: Vec<i64>, reason: shirabe_php_shim::PhpMixed, reason_data: shirabe_php_shim::PhpMixed) -> Result<Self> {
+ pub fn new(
+ mut literals: Vec<i64>,
+ reason: shirabe_php_shim::PhpMixed,
+ reason_data: shirabe_php_shim::PhpMixed,
+ ) -> Result<Self> {
if literals.len() < 3 {
return Err(RuntimeException {
message: "multi conflict rule requires at least 3 literals".to_string(),
code: 0,
- }.into());
+ }
+ .into());
}
// sort all packages ascending by id
@@ -34,8 +39,17 @@ impl MultiConflictRule {
}
pub fn get_hash(&self) -> Result<i64> {
- let joined = self.literals.iter().map(|l| l.to_string()).collect::<Vec<_>>().join(",");
- let algo = if PHP_VERSION_ID > 80100 { "xxh3" } else { "sha1" };
+ let joined = self
+ .literals
+ .iter()
+ .map(|l| l.to_string())
+ .collect::<Vec<_>>()
+ .join(",");
+ let algo = if PHP_VERSION_ID > 80100 {
+ "xxh3"
+ } else {
+ "sha1"
+ };
let binary = hash_raw(algo, &format!("c:{}", joined));
let data = shirabe_php_shim::unpack("ihash", &binary);
match data {
@@ -46,13 +60,15 @@ impl MultiConflictRule {
Err(RuntimeException {
message: format!("Failed unpacking: {}", joined),
code: 0,
- }.into())
+ }
+ .into())
}
}
None => Err(RuntimeException {
message: format!("Failed unpacking: {}", joined),
code: 0,
- }.into()),
+ }
+ .into()),
}
}
diff --git a/crates/shirabe/src/dependency_resolver/operation/mod.rs b/crates/shirabe/src/dependency_resolver/operation/mod.rs
new file mode 100644
index 0000000..ffb0ac7
--- /dev/null
+++ b/crates/shirabe/src/dependency_resolver/operation/mod.rs
@@ -0,0 +1,7 @@
+pub mod install_operation;
+pub mod mark_alias_installed_operation;
+pub mod mark_alias_uninstalled_operation;
+pub mod operation_interface;
+pub mod solver_operation;
+pub mod uninstall_operation;
+pub mod update_operation;
diff --git a/crates/shirabe/src/dependency_resolver/operation/update_operation.rs b/crates/shirabe/src/dependency_resolver/operation/update_operation.rs
index eb6e9d6..618ecee 100644
--- a/crates/shirabe/src/dependency_resolver/operation/update_operation.rs
+++ b/crates/shirabe/src/dependency_resolver/operation/update_operation.rs
@@ -13,7 +13,10 @@ pub struct UpdateOperation {
impl UpdateOperation {
pub fn new(initial: Box<dyn PackageInterface>, target: Box<dyn PackageInterface>) -> Self {
- Self { initial_package: initial, target_package: target }
+ Self {
+ initial_package: initial,
+ target_package: target,
+ }
}
pub fn get_initial_package(&self) -> &dyn PackageInterface {
@@ -24,19 +27,36 @@ impl UpdateOperation {
self.target_package.as_ref()
}
- pub fn format(initial_package: &dyn PackageInterface, target_package: &dyn PackageInterface, lock: bool) -> String {
- let mut from_version = initial_package.get_full_pretty_version(false, PackageInterface::DISPLAY_SOURCE_REF);
- let mut to_version = target_package.get_full_pretty_version(false, PackageInterface::DISPLAY_SOURCE_REF);
+ pub fn format(
+ initial_package: &dyn PackageInterface,
+ target_package: &dyn PackageInterface,
+ lock: bool,
+ ) -> String {
+ let mut from_version =
+ initial_package.get_full_pretty_version(false, PackageInterface::DISPLAY_SOURCE_REF);
+ let mut to_version =
+ target_package.get_full_pretty_version(false, PackageInterface::DISPLAY_SOURCE_REF);
- if from_version == to_version && initial_package.get_source_reference() != target_package.get_source_reference() {
- from_version = initial_package.get_full_pretty_version(true, PackageInterface::DISPLAY_SOURCE_REF);
- to_version = target_package.get_full_pretty_version(true, PackageInterface::DISPLAY_SOURCE_REF);
- } else if from_version == to_version && initial_package.get_dist_reference() != target_package.get_dist_reference() {
- from_version = initial_package.get_full_pretty_version(true, PackageInterface::DISPLAY_DIST_REF);
- to_version = target_package.get_full_pretty_version(true, PackageInterface::DISPLAY_DIST_REF);
+ if from_version == to_version
+ && initial_package.get_source_reference() != target_package.get_source_reference()
+ {
+ from_version =
+ initial_package.get_full_pretty_version(true, PackageInterface::DISPLAY_SOURCE_REF);
+ to_version =
+ target_package.get_full_pretty_version(true, PackageInterface::DISPLAY_SOURCE_REF);
+ } else if from_version == to_version
+ && initial_package.get_dist_reference() != target_package.get_dist_reference()
+ {
+ from_version =
+ initial_package.get_full_pretty_version(true, PackageInterface::DISPLAY_DIST_REF);
+ to_version =
+ target_package.get_full_pretty_version(true, PackageInterface::DISPLAY_DIST_REF);
}
- let action_name = if VersionParser::is_upgrade(&initial_package.get_version(), &target_package.get_version()) {
+ let action_name = if VersionParser::is_upgrade(
+ &initial_package.get_version(),
+ &target_package.get_version(),
+ ) {
"Upgrading"
} else {
"Downgrading"
@@ -62,7 +82,11 @@ impl OperationInterface for UpdateOperation {
}
fn show(&self, lock: bool) -> String {
- Self::format(self.initial_package.as_ref(), self.target_package.as_ref(), lock)
+ Self::format(
+ self.initial_package.as_ref(),
+ self.target_package.as_ref(),
+ lock,
+ )
}
fn to_string(&self) -> String {
diff --git a/crates/shirabe/src/dependency_resolver/policy_interface.rs b/crates/shirabe/src/dependency_resolver/policy_interface.rs
index 279cf38..a48cd4b 100644
--- a/crates/shirabe/src/dependency_resolver/policy_interface.rs
+++ b/crates/shirabe/src/dependency_resolver/policy_interface.rs
@@ -4,7 +4,17 @@ use crate::dependency_resolver::pool::Pool;
use crate::package::package_interface::PackageInterface;
pub trait PolicyInterface {
- fn version_compare(&self, a: &dyn PackageInterface, b: &dyn PackageInterface, operator: &str) -> bool;
+ fn version_compare(
+ &self,
+ a: &dyn PackageInterface,
+ b: &dyn PackageInterface,
+ operator: &str,
+ ) -> bool;
- fn select_preferred_packages(&self, pool: &Pool, literals: Vec<i64>, required_package: Option<String>) -> Vec<i64>;
+ fn select_preferred_packages(
+ &self,
+ pool: &Pool,
+ literals: Vec<i64>,
+ required_package: Option<String>,
+ ) -> Vec<i64>;
}
diff --git a/crates/shirabe/src/dependency_resolver/pool.rs b/crates/shirabe/src/dependency_resolver/pool.rs
index c783f45..e86e4c2 100644
--- a/crates/shirabe/src/dependency_resolver/pool.rs
+++ b/crates/shirabe/src/dependency_resolver/pool.rs
@@ -3,7 +3,7 @@
use std::fmt;
use indexmap::IndexMap;
-use shirabe_php_shim::{abs, spl_object_hash, str_pad, Countable, STR_PAD_LEFT};
+use shirabe_php_shim::{Countable, STR_PAD_LEFT, abs, spl_object_hash, str_pad};
use shirabe_semver::compiling_matcher::CompilingMatcher;
use shirabe_semver::constraint::constraint::Constraint;
use shirabe_semver::constraint::constraint_interface::ConstraintInterface;
@@ -48,10 +48,7 @@ impl Pool {
unacceptable_fixed_or_locked_packages: Vec<Box<BasePackage>>,
removed_versions: IndexMap<String, IndexMap<String, String>>,
removed_versions_by_package: IndexMap<String, IndexMap<String, String>>,
- security_removed_versions: IndexMap<
- String,
- IndexMap<String, Vec<PartialSecurityAdvisory>>,
- >,
+ security_removed_versions: IndexMap<String, IndexMap<String, Vec<PartialSecurityAdvisory>>>,
abandoned_removed_versions: IndexMap<String, IndexMap<String, String>>,
) -> Self {
let mut this = Self {
@@ -116,7 +113,10 @@ impl Pool {
constraint: Option<&dyn ConstraintInterface>,
) -> bool {
let empty = IndexMap::new();
- let versions = self.security_removed_versions.get(package_name).unwrap_or(&empty);
+ let versions = self
+ .security_removed_versions
+ .get(package_name)
+ .unwrap_or(&empty);
for (version, _package_with_security_advisories) in versions {
if let Some(c) = constraint {
if c.matches(&Constraint::new("==", version)) {
@@ -135,7 +135,10 @@ impl Pool {
constraint: Option<&dyn ConstraintInterface>,
) -> Vec<String> {
let empty = IndexMap::new();
- let versions = self.security_removed_versions.get(package_name).unwrap_or(&empty);
+ let versions = self
+ .security_removed_versions
+ .get(package_name)
+ .unwrap_or(&empty);
for (version, package_with_security_advisories) in versions {
if let Some(c) = constraint {
if c.matches(&Constraint::new("==", version)) {
@@ -156,7 +159,10 @@ impl Pool {
constraint: Option<&dyn ConstraintInterface>,
) -> bool {
let empty = IndexMap::new();
- let versions = self.abandoned_removed_versions.get(package_name).unwrap_or(&empty);
+ let versions = self
+ .abandoned_removed_versions
+ .get(package_name)
+ .unwrap_or(&empty);
for (version, _pretty_version) in versions {
if let Some(c) = constraint {
if c.matches(&Constraint::new("==", version)) {
@@ -280,11 +286,7 @@ impl Pool {
let package = self.literal_to_package(literal);
let prefix = if installed_map.contains_key(&package.id) {
- if literal > 0 {
- "keep"
- } else {
- "remove"
- }
+ if literal > 0 { "keep" } else { "remove" }
} else {
if literal > 0 {
"install"
@@ -328,8 +330,7 @@ impl Pool {
if replaces.contains_key("0") || provides.contains_key("0") {
for link in provides.values() {
if link.get_target() == name
- && (constraint.is_none()
- || constraint.unwrap().matches(link.get_constraint()))
+ && (constraint.is_none() || constraint.unwrap().matches(link.get_constraint()))
{
return true;
}
@@ -337,8 +338,7 @@ impl Pool {
for link in replaces.values() {
if link.get_target() == name
- && (constraint.is_none()
- || constraint.unwrap().matches(link.get_constraint()))
+ && (constraint.is_none() || constraint.unwrap().matches(link.get_constraint()))
{
return true;
}
diff --git a/crates/shirabe/src/dependency_resolver/pool_builder.rs b/crates/shirabe/src/dependency_resolver/pool_builder.rs
index 0d99587..f518545 100644
--- a/crates/shirabe/src/dependency_resolver/pool_builder.rs
+++ b/crates/shirabe/src/dependency_resolver/pool_builder.rs
@@ -6,8 +6,8 @@ use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::composer::semver::compiling_matcher::CompilingMatcher;
use shirabe_external_packages::composer::semver::intervals::Intervals;
use shirabe_php_shim::{
- array_chunk, array_flip, array_map, array_merge, array_search, count, in_array, microtime,
- number_format, round, spl_object_hash, sprintf, strpos, LogicException, PhpMixed,
+ LogicException, PhpMixed, array_chunk, array_flip, array_map, array_merge, array_search, count,
+ in_array, microtime, number_format, round, spl_object_hash, sprintf, strpos,
};
use shirabe_semver::constraint::constraint::Constraint;
use shirabe_semver::constraint::constraint_interface::ConstraintInterface;
@@ -126,7 +126,11 @@ impl PoolBuilder {
self.allowed_types = types;
}
- pub fn build_pool(&mut self, repositories: Vec<Box<dyn RepositoryInterface>>, request: &mut Request) -> anyhow::Result<Pool> {
+ pub fn build_pool(
+ &mut self,
+ repositories: Vec<Box<dyn RepositoryInterface>>,
+ request: &mut Request,
+ ) -> anyhow::Result<Pool> {
self.restricted_packages_list = if request.get_restricted_packages().is_some() {
Some(array_flip(&request.get_restricted_packages().unwrap()))
} else {
@@ -139,7 +143,8 @@ impl PoolBuilder {
if request.get_locked_repository().is_none() {
return Err(LogicException {
- message: "No lock repo present and yet a partial update was requested.".to_string(),
+ message: "No lock repo present and yet a partial update was requested."
+ .to_string(),
code: 0,
}
.into());
@@ -165,9 +170,13 @@ impl PoolBuilder {
// if they do get unlocked, but by default they are unlocked without update propagation.
if locked_package.get_dist_type().as_deref() == Some("path") {
let transport_options = locked_package.get_transport_options();
- let symlink_disabled = transport_options.get("symlink").map(|v| v.as_bool() == Some(false)).unwrap_or(false);
+ let symlink_disabled = transport_options
+ .get("symlink")
+ .map(|v| v.as_bool() == Some(false))
+ .unwrap_or(false);
if !transport_options.contains_key("symlink") || !symlink_disabled {
- self.path_repo_unlocked.insert(locked_package.get_name().to_string(), true);
+ self.path_repo_unlocked
+ .insert(locked_package.get_name().to_string(), true);
continue;
}
}
@@ -180,11 +189,17 @@ impl PoolBuilder {
for package in request.get_fixed_or_locked_packages() {
// using MatchAllConstraint here because fixed packages do not need to retrigger
// loading any packages
- self.loaded_packages.insert(package.get_name().to_string(), Box::new(MatchAllConstraint::new()));
+ self.loaded_packages.insert(
+ package.get_name().to_string(),
+ Box::new(MatchAllConstraint::new()),
+ );
// replace means conflict, so if a fixed package replaces a name, no need to load that one, packages would conflict anyways
for (_k, link) in &package.get_replaces() {
- self.loaded_packages.insert(link.get_target().to_string(), Box::new(MatchAllConstraint::new()));
+ self.loaded_packages.insert(
+ link.get_target().to_string(),
+ Box::new(MatchAllConstraint::new()),
+ );
}
// TODO in how far can we do the above for conflicts? It's more tricky cause conflicts can be limited to
@@ -193,7 +208,8 @@ impl PoolBuilder {
let in_root_or_platform = package
.get_repository()
.map(|r| {
- r.as_any().is::<RootPackageRepository>() || r.as_any().is::<PlatformRepository>()
+ r.as_any().is::<RootPackageRepository>()
+ || r.as_any().is::<PlatformRepository>()
})
.unwrap_or(false);
if in_root_or_platform
@@ -206,7 +222,8 @@ impl PoolBuilder {
{
self.load_package(request, &repositories, &*package, false)?;
} else {
- self.unacceptable_fixed_or_locked_packages.push(package.clone_box());
+ self.unacceptable_fixed_or_locked_packages
+ .push(package.clone_box());
}
}
@@ -216,7 +233,8 @@ impl PoolBuilder {
continue;
}
- self.packages_to_load.insert(package_name.clone(), constraint.clone_box());
+ self.packages_to_load
+ .insert(package_name.clone(), constraint.clone_box());
self.max_extended_reqs.insert(package_name.clone(), true);
}
@@ -253,7 +271,8 @@ impl PoolBuilder {
None => continue,
};
- let mut package_and_aliases: IndexMap<i64, Box<dyn BasePackage>> = IndexMap::new();
+ let mut package_and_aliases: IndexMap<i64, Box<dyn BasePackage>> =
+ IndexMap::new();
package_and_aliases.insert(i, package.clone_box());
if let Some(aliases) = self.alias_map.get(&spl_object_hash(&*package)) {
for (idx, alias) in aliases {
@@ -263,7 +282,11 @@ impl PoolBuilder {
let mut found = false;
for (_idx, package_or_alias) in &package_and_aliases {
- if CompilingMatcher::matches(&*constraint, Constraint::OP_EQ, package_or_alias.get_version()) {
+ if CompilingMatcher::matches(
+ &*constraint,
+ Constraint::OP_EQ,
+ package_or_alias.get_version(),
+ ) {
found = true;
}
}
@@ -287,7 +310,10 @@ impl PoolBuilder {
self.root_aliases.clone(),
self.root_references.clone(),
self.packages.values().map(|p| p.clone_box()).collect(),
- self.unacceptable_fixed_or_locked_packages.iter().map(|p| p.clone_box()).collect(),
+ self.unacceptable_fixed_or_locked_packages
+ .iter()
+ .map(|p| p.clone_box())
+ .collect(),
);
self.event_dispatcher
.as_mut()
@@ -300,12 +326,16 @@ impl PoolBuilder {
.enumerate()
.map(|(i, p)| (i as i64, p))
.collect();
- self.unacceptable_fixed_or_locked_packages = pre_pool_create_event.get_unacceptable_fixed_packages();
+ self.unacceptable_fixed_or_locked_packages =
+ pre_pool_create_event.get_unacceptable_fixed_packages();
}
let mut pool = Pool::new(
self.packages.values().map(|p| p.clone_box()).collect(),
- self.unacceptable_fixed_or_locked_packages.iter().map(|p| p.clone_box()).collect(),
+ self.unacceptable_fixed_or_locked_packages
+ .iter()
+ .map(|p| p.clone_box())
+ .collect(),
);
self.alias_map = IndexMap::new();
@@ -330,7 +360,12 @@ impl PoolBuilder {
Ok(pool)
}
- fn mark_package_name_for_loading(&mut self, request: &Request, name: &str, constraint: Box<dyn ConstraintInterface>) {
+ fn mark_package_name_for_loading(
+ &mut self,
+ request: &Request,
+ name: &str,
+ constraint: Box<dyn ConstraintInterface>,
+ ) {
// Skip platform requires at this stage
if PlatformRepository::is_platform_package(name) {
return;
@@ -399,7 +434,11 @@ impl PoolBuilder {
self.loaded_packages.shift_remove(name);
}
- fn load_packages_marked_for_loading(&mut self, request: &mut Request, repositories: &Vec<Box<dyn RepositoryInterface>>) -> anyhow::Result<()> {
+ fn load_packages_marked_for_loading(
+ &mut self,
+ request: &mut Request,
+ repositories: &Vec<Box<dyn RepositoryInterface>>,
+ ) -> anyhow::Result<()> {
let to_remove: Vec<String> = self
.packages_to_load
.keys()
@@ -420,7 +459,8 @@ impl PoolBuilder {
.map(|(k, v)| (k.clone(), v.clone_box()))
.collect();
for (name, constraint) in &snapshot {
- self.loaded_packages.insert(name.clone(), constraint.clone_box());
+ self.loaded_packages
+ .insert(name.clone(), constraint.clone_box());
}
// Load packages in chunks of 50 to prevent memory usage build-up due to caches of all sorts
@@ -432,7 +472,12 @@ impl PoolBuilder {
// never need to load anything else from them
let is_locked_repo = request
.get_locked_repository()
- .map(|lr| std::ptr::eq(lr as *const _ as *const u8, repository.as_ref() as *const _ as *const u8))
+ .map(|lr| {
+ std::ptr::eq(
+ lr as *const _ as *const u8,
+ repository.as_ref() as *const _ as *const u8,
+ )
+ })
.unwrap_or(false);
if repository.as_any().is::<PlatformRepository>() || is_locked_repo {
continue;
@@ -447,17 +492,28 @@ impl PoolBuilder {
package_batch,
&self.acceptable_stabilities,
&self.stability_flags,
- self.loaded_per_repo.get(&(repo_index as i64)).cloned().unwrap_or_default(),
+ self.loaded_per_repo
+ .get(&(repo_index as i64))
+ .cloned()
+ .unwrap_or_default(),
);
- let names_found = result.get("namesFound").and_then(|v| v.as_list()).cloned().unwrap_or_default();
+ let names_found = result
+ .get("namesFound")
+ .and_then(|v| v.as_list())
+ .cloned()
+ .unwrap_or_default();
for name in &names_found {
// avoid loading the same package again from other repositories once it has been found
if let Some(b) = package_batches.get_mut(batch_index) {
b.shift_remove(name.as_string().unwrap_or(""));
}
}
- let packages_in_result = result.get("packages").and_then(|v| v.as_list()).cloned().unwrap_or_default();
+ let packages_in_result = result
+ .get("packages")
+ .and_then(|v| v.as_list())
+ .cloned()
+ .unwrap_or_default();
for package in &packages_in_result {
let pkg = match package.as_package_interface() {
Some(p) => p,
@@ -472,7 +528,11 @@ impl PoolBuilder {
if in_array(pkg.get_type(), &self.ignored_types, true)
|| (self.allowed_types.is_some()
- && !in_array(pkg.get_type(), self.allowed_types.as_ref().unwrap(), true))
+ && !in_array(
+ pkg.get_type(),
+ self.allowed_types.as_ref().unwrap(),
+ true,
+ ))
{
continue;
}
@@ -495,7 +555,13 @@ impl PoolBuilder {
Ok(())
}
- fn load_package(&mut self, request: &mut Request, repositories: &Vec<Box<dyn RepositoryInterface>>, package: &dyn BasePackage, propagate_update: bool) -> anyhow::Result<()> {
+ fn load_package(
+ &mut self,
+ request: &mut Request,
+ repositories: &Vec<Box<dyn RepositoryInterface>>,
+ package: &dyn BasePackage,
+ propagate_update: bool,
+ ) -> anyhow::Result<()> {
let index = self.index_counter;
self.index_counter += 1;
self.packages.insert(index, package.clone_box());
@@ -537,19 +603,20 @@ impl PoolBuilder {
} else {
package.clone_box()
};
- let alias_package: Box<dyn BasePackage> = if base_package.as_any().is::<CompletePackage>() {
- Box::new(CompleteAliasPackage::new(
- base_package.clone_box(),
- alias.get("alias_normalized").cloned().unwrap_or_default(),
- alias.get("alias").cloned().unwrap_or_default(),
- ))
- } else {
- Box::new(AliasPackage::new(
- base_package.clone_box(),
- alias.get("alias_normalized").cloned().unwrap_or_default(),
- alias.get("alias").cloned().unwrap_or_default(),
- ))
- };
+ let alias_package: Box<dyn BasePackage> =
+ if base_package.as_any().is::<CompletePackage>() {
+ Box::new(CompleteAliasPackage::new(
+ base_package.clone_box(),
+ alias.get("alias_normalized").cloned().unwrap_or_default(),
+ alias.get("alias").cloned().unwrap_or_default(),
+ ))
+ } else {
+ Box::new(AliasPackage::new(
+ base_package.clone_box(),
+ alias.get("alias_normalized").cloned().unwrap_or_default(),
+ alias.get("alias").cloned().unwrap_or_default(),
+ ))
+ };
// PHP: $aliasPackage->setRootPackageAlias(true);
// BasePackage doesn't expose this directly; the AliasPackage trait method handles it.
@@ -577,7 +644,9 @@ impl PoolBuilder {
if propagate_update && request.get_update_allow_transitive_dependencies() {
let skipped_root_requires = self.get_skipped_root_requires(request, &require);
- if request.get_update_allow_transitive_root_dependencies() || 0 == count(&skipped_root_requires) {
+ if request.get_update_allow_transitive_root_dependencies()
+ || 0 == count(&skipped_root_requires)
+ {
self.unlock_package(request, repositories, &require)?;
self.mark_package_name_for_loading(request, &require, link_constraint);
} else {
@@ -588,7 +657,9 @@ impl PoolBuilder {
}
}
}
- } else if self.path_repo_unlocked.contains_key(&require) && !self.loaded_packages.contains_key(&require) {
+ } else if self.path_repo_unlocked.contains_key(&require)
+ && !self.loaded_packages.contains_key(&require)
+ {
// if doing a partial update and a package depends on a path-repo-unlocked package which is not referenced by the root, we need to ensure it gets loaded as it was not loaded by the request's root requirements
// and would not be loaded above if update propagation is not allowed (which happens if the requirer is itself a path-repo-unlocked package) or if transitive deps are not allowed to be unlocked
self.mark_package_name_for_loading(request, &require, link_constraint);
@@ -603,10 +674,14 @@ impl PoolBuilder {
if propagate_update && request.get_update_allow_transitive_dependencies() {
for (_k, link) in &package.get_replaces() {
let replace = link.get_target().to_string();
- if self.loaded_packages.contains_key(&replace) && self.skipped_load.contains_key(&replace) {
+ if self.loaded_packages.contains_key(&replace)
+ && self.skipped_load.contains_key(&replace)
+ {
let skipped_root_requires = self.get_skipped_root_requires(request, &replace);
- if request.get_update_allow_transitive_root_dependencies() || 0 == count(&skipped_root_requires) {
+ if request.get_update_allow_transitive_root_dependencies()
+ || 0 == count(&skipped_root_requires)
+ {
self.unlock_package(request, repositories, &replace)?;
// the replaced package only needs to be loaded if something else requires it
self.mark_package_name_for_loading_if_required(request, &replace);
@@ -660,7 +735,11 @@ impl PoolBuilder {
for (_k, link) in &package_or_replacer.get_replaces() {
if root_requires.contains_key(link.get_target()) {
if name != package_or_replacer.get_name() {
- matches.push(format!("{} (via replace of {})", package_or_replacer.get_name(), name));
+ matches.push(format!(
+ "{} (via replace of {})",
+ package_or_replacer.get_name(),
+ name
+ ));
} else {
matches.push(package_or_replacer.get_name().to_string());
}
@@ -735,7 +814,12 @@ impl PoolBuilder {
/// Reverts the decision to use a locked package if a partial update with transitive dependencies
/// found that this package actually needs to be updated
- fn unlock_package(&mut self, request: &mut Request, repositories: &Vec<Box<dyn RepositoryInterface>>, name: &str) -> anyhow::Result<()> {
+ fn unlock_package(
+ &mut self,
+ request: &mut Request,
+ repositories: &Vec<Box<dyn RepositoryInterface>>,
+ name: &str,
+ ) -> anyhow::Result<()> {
let skipped: Vec<Box<dyn PackageInterface>> = self
.skipped_load
.get(name)
@@ -744,21 +828,35 @@ impl PoolBuilder {
for package_or_replacer in &skipped {
// if we unfixed a replaced package name, we also need to unfix the replacer itself
// as long as it was not unfixed yet
- if package_or_replacer.get_name() != name && self.skipped_load.contains_key(package_or_replacer.get_name()) {
+ if package_or_replacer.get_name() != name
+ && self
+ .skipped_load
+ .contains_key(package_or_replacer.get_name())
+ {
let replacer_name = package_or_replacer.get_name().to_string();
if request.get_update_allow_transitive_root_dependencies()
- || (!self.is_root_require(request, name) && !self.is_root_require(request, &replacer_name))
+ || (!self.is_root_require(request, name)
+ && !self.is_root_require(request, &replacer_name))
{
self.unlock_package(request, repositories, &replacer_name)?;
if self.is_root_require(request, &replacer_name) {
- self.mark_package_name_for_loading(request, &replacer_name, Box::new(MatchAllConstraint::new()));
+ self.mark_package_name_for_loading(
+ request,
+ &replacer_name,
+ Box::new(MatchAllConstraint::new()),
+ );
} else {
- let pkgs: Vec<Box<dyn BasePackage>> = self.packages.values().map(|p| p.clone_box()).collect();
+ let pkgs: Vec<Box<dyn BasePackage>> =
+ self.packages.values().map(|p| p.clone_box()).collect();
for loaded_package in &pkgs {
let requires = loaded_package.get_requires();
if let Some(req_link) = requires.get(&replacer_name) {
- self.mark_package_name_for_loading(request, &replacer_name, req_link.get_constraint());
+ self.mark_package_name_for_loading(
+ request,
+ &replacer_name,
+ req_link.get_constraint(),
+ );
}
}
}
@@ -784,10 +882,15 @@ impl PoolBuilder {
self.path_repo_unlocked.shift_remove(name);
// remove locked package by this name which was already initialized
- let locked_packages: Vec<Box<dyn BasePackage>> = request.get_locked_packages().iter().map(|p| p.clone_box()).collect();
+ let locked_packages: Vec<Box<dyn BasePackage>> = request
+ .get_locked_packages()
+ .iter()
+ .map(|p| p.clone_box())
+ .collect();
for locked_package in &locked_packages {
if locked_package.as_alias_package().is_none() && locked_package.get_name() == name {
- let pkgs: Vec<Box<dyn BasePackage>> = self.packages.values().map(|p| p.clone_box()).collect();
+ let pkgs: Vec<Box<dyn BasePackage>> =
+ self.packages.values().map(|p| p.clone_box()).collect();
let index_opt = array_search(&**locked_package, &pkgs, true);
if let Some(index) = index_opt {
request.unlock_package(&**locked_package);
@@ -798,23 +901,47 @@ impl PoolBuilder {
// satisfied their requirements
// and if this package is replacing another that is required by a locked or fixed package, ensure
// that we load that replaced package in case an update to this package removes the replacement
- let fixed_or_locked: Vec<Box<dyn BasePackage>> = request.get_fixed_or_locked_packages().iter().map(|p| p.clone_box()).collect();
+ let fixed_or_locked: Vec<Box<dyn BasePackage>> = request
+ .get_fixed_or_locked_packages()
+ .iter()
+ .map(|p| p.clone_box())
+ .collect();
for fixed_or_locked_package in &fixed_or_locked {
- if std::ptr::eq(fixed_or_locked_package.as_ref() as *const _, locked_package.as_ref() as *const _) {
+ if std::ptr::eq(
+ fixed_or_locked_package.as_ref() as *const _,
+ locked_package.as_ref() as *const _,
+ ) {
continue;
}
- if self.skipped_load.contains_key(fixed_or_locked_package.get_name()) {
+ if self
+ .skipped_load
+ .contains_key(fixed_or_locked_package.get_name())
+ {
let requires = fixed_or_locked_package.get_requires();
if let Some(req_link) = requires.get(locked_package.get_name()) {
- self.mark_package_name_for_loading(request, locked_package.get_name(), req_link.get_constraint());
+ self.mark_package_name_for_loading(
+ request,
+ locked_package.get_name(),
+ req_link.get_constraint(),
+ );
}
for (_k, replace) in &locked_package.get_replaces() {
- if requires.contains_key(replace.get_target()) && self.skipped_load.contains_key(replace.get_target()) {
- self.unlock_package(request, repositories, replace.get_target())?;
+ if requires.contains_key(replace.get_target())
+ && self.skipped_load.contains_key(replace.get_target())
+ {
+ self.unlock_package(
+ request,
+ repositories,
+ replace.get_target(),
+ )?;
// this package is in $requires so no need to call markPackageNameForLoadingIfRequired
- self.mark_package_name_for_loading(request, replace.get_target(), replace.get_constraint());
+ self.mark_package_name_for_loading(
+ request,
+ replace.get_target(),
+ replace.get_constraint(),
+ );
}
}
}
@@ -827,21 +954,37 @@ impl PoolBuilder {
fn mark_package_name_for_loading_if_required(&mut self, request: &Request, name: &str) {
if self.is_root_require(request, name) {
- self.mark_package_name_for_loading(request, name, request.get_requires()[name].clone_box());
+ self.mark_package_name_for_loading(
+ request,
+ name,
+ request.get_requires()[name].clone_box(),
+ );
}
- let pkgs: Vec<Box<dyn BasePackage>> = self.packages.values().map(|p| p.clone_box()).collect();
+ let pkgs: Vec<Box<dyn BasePackage>> =
+ self.packages.values().map(|p| p.clone_box()).collect();
for package in &pkgs {
for (_k, link) in &package.get_requires() {
if name == link.get_target() {
- self.mark_package_name_for_loading(request, link.get_target(), link.get_constraint());
+ self.mark_package_name_for_loading(
+ request,
+ link.get_target(),
+ link.get_constraint(),
+ );
}
}
}
}
- fn remove_loaded_package(&mut self, _request: &Request, repositories: &Vec<Box<dyn RepositoryInterface>>, package: &dyn BasePackage, index: i64) {
- let repos_box: Vec<Box<dyn RepositoryInterface>> = repositories.iter().map(|r| r.clone_box()).collect();
+ fn remove_loaded_package(
+ &mut self,
+ _request: &Request,
+ repositories: &Vec<Box<dyn RepositoryInterface>>,
+ package: &dyn BasePackage,
+ index: i64,
+ ) {
+ let repos_box: Vec<Box<dyn RepositoryInterface>> =
+ repositories.iter().map(|r| r.clone_box()).collect();
let repo_index = match package.get_repository() {
Some(repo) => array_search(&*repo, &repos_box, true).unwrap_or(-1),
None => -1,
@@ -881,7 +1024,11 @@ impl PoolBuilder {
let before = microtime(true);
let total = count(&pool.get_packages()) as f64;
- let pool = self.pool_optimizer.as_mut().unwrap().optimize(request, pool);
+ let pool = self
+ .pool_optimizer
+ .as_mut()
+ .unwrap()
+ .optimize(request, pool);
let filtered = total - (count(&pool.get_packages()) as f64);
@@ -890,7 +1037,10 @@ impl PoolBuilder {
}
self.io.write_with_verbosity(
- &sprintf("Pool optimizer completed in %.3f seconds", &[(microtime(true) - before).into()]),
+ &sprintf(
+ "Pool optimizer completed in %.3f seconds",
+ &[(microtime(true) - before).into()],
+ ),
true,
IOInterface::VERY_VERBOSE,
);
@@ -910,7 +1060,12 @@ impl PoolBuilder {
pool
}
- fn run_security_advisory_filter(&mut self, pool: Pool, repositories: &Vec<Box<dyn RepositoryInterface>>, request: &Request) -> Pool {
+ fn run_security_advisory_filter(
+ &mut self,
+ pool: Pool,
+ repositories: &Vec<Box<dyn RepositoryInterface>>,
+ request: &Request,
+ ) -> Pool {
if self.security_advisory_pool_filter.is_none() {
return pool;
}
@@ -920,7 +1075,11 @@ impl PoolBuilder {
let before = microtime(true);
let total = count(&pool.get_packages()) as f64;
- let pool = self.security_advisory_pool_filter.as_mut().unwrap().filter(pool, repositories, request);
+ let pool = self.security_advisory_pool_filter.as_mut().unwrap().filter(
+ pool,
+ repositories,
+ request,
+ );
let filtered = total - (count(&pool.get_packages()) as f64);
@@ -929,7 +1088,10 @@ impl PoolBuilder {
}
self.io.write_with_verbosity(
- &sprintf("Security advisory pool filter completed in %.3f seconds", &[(microtime(true) - before).into()]),
+ &sprintf(
+ "Security advisory pool filter completed in %.3f seconds",
+ &[(microtime(true) - before).into()],
+ ),
true,
IOInterface::VERY_VERBOSE,
);
diff --git a/crates/shirabe/src/dependency_resolver/pool_optimizer.rs b/crates/shirabe/src/dependency_resolver/pool_optimizer.rs
index 94b6771..b71af14 100644
--- a/crates/shirabe/src/dependency_resolver/pool_optimizer.rs
+++ b/crates/shirabe/src/dependency_resolver/pool_optimizer.rs
@@ -4,7 +4,7 @@ use std::any::Any;
use anyhow::Result;
use indexmap::IndexMap;
-use shirabe_php_shim::{implode, ksort, spl_object_hash, LogicException, PhpMixed};
+use shirabe_php_shim::{LogicException, PhpMixed, implode, ksort, spl_object_hash};
use shirabe_semver::compiling_matcher::CompilingMatcher;
use shirabe_semver::constraint::constraint::Constraint;
use shirabe_semver::constraint::constraint_interface::ConstraintInterface;
@@ -28,7 +28,8 @@ pub struct PoolOptimizer {
irremovable_packages: IndexMap<i64, bool>,
/// @var array<string, array<string, ConstraintInterface>>
- require_constraints_per_package: IndexMap<String, IndexMap<String, Box<dyn ConstraintInterface>>>,
+ require_constraints_per_package:
+ IndexMap<String, IndexMap<String, Box<dyn ConstraintInterface>>>,
/// @var array<string, array<string, ConstraintInterface>>
conflict_constraints_per_package:
@@ -104,10 +105,7 @@ impl PoolOptimizer {
// Extract requested package requirements
for (require, constraint) in request.get_requires() {
// TODO(phase-b): clone Box<dyn ConstraintInterface>
- self.extract_require_constraints_per_package(
- require,
- todo!("constraint.clone_box()"),
- );
+ self.extract_require_constraints_per_package(require, todo!("constraint.clone_box()"));
}
// First pass over all packages to extract information and mark package constraints irremovable
@@ -131,9 +129,7 @@ impl PoolOptimizer {
// Keep track of alias packages for every package so if either the alias or aliased is kept
// we keep the others as they are a unit of packages really
- if let Some(alias_pkg) =
- (package.as_any() as &dyn Any).downcast_ref::<AliasPackage>()
- {
+ if let Some(alias_pkg) = (package.as_any() as &dyn Any).downcast_ref::<AliasPackage>() {
self.aliases_per_package
.entry(alias_pkg.get_alias_of().id)
.or_insert_with(Vec::new)
@@ -162,7 +158,9 @@ impl PoolOptimizer {
continue;
}
- let constraint = irremovable_package_constraints.get(package.get_name()).unwrap();
+ let constraint = irremovable_package_constraints
+ .get(package.get_name())
+ .unwrap();
if CompilingMatcher::r#match(
constraint.as_ref(),
Constraint::OP_EQ,
@@ -175,9 +173,7 @@ impl PoolOptimizer {
fn mark_package_irremovable(&mut self, package: &BasePackage) {
self.irremovable_packages.insert(package.id, true);
- if let Some(alias_pkg) =
- (package.as_any() as &dyn Any).downcast_ref::<AliasPackage>()
- {
+ if let Some(alias_pkg) = (package.as_any() as &dyn Any).downcast_ref::<AliasPackage>() {
// recursing here so aliasesPerPackage for the aliasOf can be checked
// and all its aliases marked as irremovable as well
self.mark_package_irremovable(alias_pkg.get_alias_of());
@@ -279,8 +275,7 @@ impl PoolOptimizer {
package.get_version(),
) {
// Use the same hash part as the regular require hash because that's what the replacement does
- group_hash_parts
- .push(format!("require:{}", link.get_constraint()));
+ group_hash_parts.push(format!("require:{}", link.get_constraint()));
}
}
}
@@ -294,8 +289,7 @@ impl PoolOptimizer {
Constraint::OP_EQ,
package.get_version(),
) {
- group_hash_parts
- .push(format!("conflict:{}", conflict_constraint));
+ group_hash_parts.push(format!("conflict:{}", conflict_constraint));
}
}
}
@@ -350,7 +344,10 @@ impl PoolOptimizer {
literals.push(package.id);
}
- for preferred_literal in self.policy.select_preferred_packages(pool, literals.clone()) {
+ for preferred_literal in self
+ .policy
+ .select_preferred_packages(pool, literals.clone())
+ {
self.keep_package(
&pool.literal_to_package(preferred_literal),
&identical_definitions_per_package,
@@ -392,7 +389,10 @@ impl PoolOptimizer {
// However, the majority of projects are going to specify their constraints already pretty
// much in the best variant possible. In other words, we'd be wasting time here and it would actually hurt
// performance more than the additional few packages that could be filtered out would benefit the process.
- subhash.insert(link.get_target().to_string(), link.get_constraint().to_string());
+ subhash.insert(
+ link.get_target().to_string(),
+ link.get_constraint().to_string(),
+ );
}
// Sort for best result
@@ -442,9 +442,7 @@ impl PoolOptimizer {
self.packages_to_remove.shift_remove(&package.id);
- if let Some(alias_pkg) =
- (package.as_any() as &dyn Any).downcast_ref::<AliasPackage>()
- {
+ if let Some(alias_pkg) = (package.as_any() as &dyn Any).downcast_ref::<AliasPackage>() {
// recursing here so aliasesPerPackage for the aliasOf can be checked
// and all its aliases marked to be kept as well
self.keep_package(
@@ -467,7 +465,9 @@ impl PoolOptimizer {
let pkg = if let Some(alias_pkg) =
(pkg.as_any() as &dyn Any).downcast_ref::<AliasPackage>()
{
- if alias_pkg.get_pretty_version() == VersionParser::DEFAULT_BRANCH_ALIAS {
+ if alias_pkg.get_pretty_version()
+ == VersionParser::DEFAULT_BRANCH_ALIAS
+ {
alias_pkg.get_alias_of().clone_box()
} else {
pkg.clone_box()
@@ -498,9 +498,7 @@ impl PoolOptimizer {
// record all the versions of the package group so we can list them later in Problem output
for name in alias_package.get_names(false) {
- if let Some(per_name) =
- package_identical_definition_lookup.get(&alias_package.id)
- {
+ if let Some(per_name) = package_identical_definition_lookup.get(&alias_package.id) {
if let Some(package_group_pointers) = per_name.get(&name) {
let package_group = identical_definitions_per_package
.get(&name)
diff --git a/crates/shirabe/src/dependency_resolver/problem.rs b/crates/shirabe/src/dependency_resolver/problem.rs
index 0108487..50b651d 100644
--- a/crates/shirabe/src/dependency_resolver/problem.rs
+++ b/crates/shirabe/src/dependency_resolver/problem.rs
@@ -5,9 +5,9 @@ use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::symfony::console::formatter::output_formatter::OutputFormatter;
use shirabe_php_shim::{
- defined, extension_loaded, implode, in_array, php_to_string, phpversion, sprintf,
- spl_object_hash, str_replace, str_starts_with, stripos, strpos, strtolower, substr,
- substr_count, version_compare, LogicException, PhpMixed,
+ LogicException, PhpMixed, defined, extension_loaded, implode, in_array, php_to_string,
+ phpversion, spl_object_hash, sprintf, str_replace, str_starts_with, stripos, strpos,
+ strtolower, substr, substr_count, version_compare,
};
use shirabe_semver::constraint::constraint::Constraint;
use shirabe_semver::constraint::constraint_interface::ConstraintInterface;
@@ -134,10 +134,7 @@ impl Problem {
fn get_sortable_string(&self, pool: &Pool, rule: &Rule) -> String {
match rule.get_reason() {
- Rule::RULE_ROOT_REQUIRE => rule
- .get_reason_data()
- .as_array()
- .unwrap()["packageName"]
+ Rule::RULE_ROOT_REQUIRE => rule.get_reason_data().as_array().unwrap()["packageName"]
.as_string()
.unwrap()
.to_string(),
@@ -302,12 +299,9 @@ impl Problem {
};
if versions_list.len() > 1 {
// remove the s from requires/conflicts to correct grammar
- let message_var = Preg::replace(
- r"{^(%s%s (?:require|conflict))s}",
- "$1",
- message,
- )
- .unwrap_or(message.clone());
+ let message_var =
+ Preg::replace(r"{^(%s%s (?:require|conflict))s}", "$1", message)
+ .unwrap_or(message.clone());
result.push(sprintf(
&message_var,
&[
@@ -331,7 +325,11 @@ impl Problem {
}
}
- format!("\n{}- {}", indent, implode(&format!("\n{}- ", indent), &result))
+ format!(
+ "\n{}- {}",
+ indent,
+ implode(&format!("\n{}- ", indent), &result)
+ )
}
pub fn is_caused_by_lock(
@@ -585,7 +583,13 @@ impl Problem {
),
format!(
"found {}. The # character in branch names is replaced by a + character. Make sure to require it as \"{}\".",
- Self::get_package_list(&packages, is_verbose, Some(pool), constraint, false),
+ Self::get_package_list(
+ &packages,
+ is_verbose,
+ Some(pool),
+ constraint,
+ false
+ ),
str_replace("#", "+", &c.get_pretty_string())
),
);
@@ -602,8 +606,7 @@ impl Problem {
let filtered: Vec<&Box<dyn PackageInterface>> = packages
.iter()
.filter(|p| {
- root_reqs[package_name]
- .matches(&Constraint::new("==", &p.get_version()))
+ root_reqs[package_name].matches(&Constraint::new("==", &p.get_version()))
})
.collect();
if filtered.len() == 0 {
@@ -615,7 +618,13 @@ impl Problem {
),
format!(
"found {} but {} with your root composer.json require ({}).",
- Self::get_package_list(&packages, is_verbose, Some(pool), constraint, false),
+ Self::get_package_list(
+ &packages,
+ is_verbose,
+ Some(pool),
+ constraint,
+ false
+ ),
if Self::has_multiple_names(&packages) {
"these conflict"
} else {
@@ -646,7 +655,13 @@ impl Problem {
),
format!(
"found {} but {} with your temporary update constraint ({}:{}).",
- Self::get_package_list(&packages, is_verbose, Some(pool), constraint, false),
+ Self::get_package_list(
+ &packages,
+ is_verbose,
+ Some(pool),
+ constraint,
+ false
+ ),
if Self::has_multiple_names(&packages) {
"these conflict"
} else {
@@ -664,9 +679,7 @@ impl Problem {
let fixed_constraint = Constraint::new("==", &lp.get_version());
let filtered: Vec<&Box<dyn PackageInterface>> = packages
.iter()
- .filter(|p| {
- fixed_constraint.matches(&Constraint::new("==", &p.get_version()))
- })
+ .filter(|p| fixed_constraint.matches(&Constraint::new("==", &p.get_version())))
.collect();
if filtered.len() == 0 {
return (
@@ -677,7 +690,13 @@ impl Problem {
),
format!(
"found {} but the package is fixed to {} (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command.",
- Self::get_package_list(&packages, is_verbose, Some(pool), constraint, false),
+ Self::get_package_list(
+ &packages,
+ is_verbose,
+ Some(pool),
+ constraint,
+ false
+ ),
lp.get_pretty_version()
),
);
@@ -698,7 +717,13 @@ impl Problem {
),
format!(
"found {} in the lock file but not in remote repositories, make sure you avoid updating this package to keep the one from the lock file.",
- Self::get_package_list(&packages, is_verbose, Some(pool), constraint, false)
+ Self::get_package_list(
+ &packages,
+ is_verbose,
+ Some(pool),
+ constraint,
+ false
+ )
),
);
}
@@ -712,7 +737,13 @@ impl Problem {
),
format!(
"found {} but these were not loaded, because they are abandoned and you configured \"block-abandoned\" to true in your \"audit\" config.",
- Self::get_package_list(&packages, is_verbose, Some(pool), constraint, false)
+ Self::get_package_list(
+ &packages,
+ is_verbose,
+ Some(pool),
+ constraint,
+ false
+ )
),
);
}
@@ -781,7 +812,13 @@ impl Problem {
),
format!(
"found {} but these were not loaded, because they are affected by security advisories (\"{}\"). Go to https://packagist.org/security-advisories/ to find advisory details. To ignore the advisories, add them to the audit \"ignore\" config. To turn the feature off entirely, you can set \"block-insecure\" to false in your \"audit\" config.",
- Self::get_package_list(&packages, is_verbose, Some(pool), constraint, false),
+ Self::get_package_list(
+ &packages,
+ is_verbose,
+ Some(pool),
+ constraint,
+ false
+ ),
implode("\", \"", &advisories_list)
),
);
@@ -900,9 +937,8 @@ impl Problem {
let top_package = all_repos_packages.first();
if let Some(tp) = top_package {
if tp.is_root_package_interface() {
- suffix =
- " See https://getcomposer.org/dep-on-root for details and assistance."
- .to_string();
+ suffix = " See https://getcomposer.org/dep-on-root for details and assistance."
+ .to_string();
}
}
@@ -1019,7 +1055,9 @@ impl Problem {
let mut prepared_strings: Vec<String> = Vec::new();
for (name, mut package) in prepared {
// remove the implicit default branch alias to avoid cruft in the display
- if package.versions.contains_key(VersionParser::DEFAULT_BRANCH_ALIAS)
+ if package
+ .versions
+ .contains_key(VersionParser::DEFAULT_BRANCH_ALIAS)
&& has_default_branch.contains_key(&name)
{
package
@@ -1222,7 +1260,13 @@ impl Problem {
),
format!(
"satisfiable by {} from {} but {} {} is the root package and cannot be modified. See https://getcomposer.org/dep-on-root for details and assistance.",
- Self::get_package_list(&next_repo_packages, is_verbose, Some(pool), constraint, false),
+ Self::get_package_list(
+ &next_repo_packages,
+ is_verbose,
+ Some(pool),
+ constraint,
+ false
+ ),
next_repo.get_repo_name(),
top_package.get_pretty_name(),
top_package.get_pretty_version()
@@ -1237,7 +1281,13 @@ impl Problem {
let mut suggestion = format!(
"Make sure you either fix the {} or avoid updating this package to keep the one present in the lock file ({}).",
reason,
- Self::get_package_list(&next_repo_packages, is_verbose, Some(pool), constraint, false)
+ Self::get_package_list(
+ &next_repo_packages,
+ is_verbose,
+ Some(pool),
+ constraint,
+ false
+ )
);
// symlinked path repos cannot be locked so do not suggest keeping it locked
if next_repo_packages[0].get_dist_type() == "path" {
@@ -1260,7 +1310,13 @@ impl Problem {
),
format!(
"found {} but {} not match your {} and {} therefore not installable. {}",
- Self::get_package_list(higher_repo_packages, is_verbose, Some(pool), constraint, false),
+ Self::get_package_list(
+ higher_repo_packages,
+ is_verbose,
+ Some(pool),
+ constraint,
+ false
+ ),
if singular { "it does" } else { "these do" },
reason,
if singular { "is" } else { "are" },
@@ -1277,10 +1333,26 @@ impl Problem {
),
format!(
"satisfiable by {} from {} but {} from {} has higher repository priority. The packages from the higher priority repository do not match your {} and are therefore not installable. That repository is canonical so the lower priority repo's packages are not installable. See https://getcomposer.org/repoprio for details and assistance.",
- Self::get_package_list(&next_repo_packages, is_verbose, Some(pool), constraint, false),
+ Self::get_package_list(
+ &next_repo_packages,
+ is_verbose,
+ Some(pool),
+ constraint,
+ false
+ ),
next_repo.get_repo_name(),
- Self::get_package_list(higher_repo_packages, is_verbose, Some(pool), constraint, false),
- higher_repo_packages.first().unwrap().get_repository().get_repo_name(),
+ Self::get_package_list(
+ higher_repo_packages,
+ is_verbose,
+ Some(pool),
+ constraint,
+ false
+ ),
+ higher_repo_packages
+ .first()
+ .unwrap()
+ .get_repository()
+ .get_repo_name(),
reason
),
)
@@ -1313,7 +1385,10 @@ impl Problem {
"{} or {}",
implode(
", ",
- &versions[..versions.len() - 1].iter().cloned().collect::<Vec<_>>()
+ &versions[..versions.len() - 1]
+ .iter()
+ .cloned()
+ .collect::<Vec<_>>()
),
last
)
@@ -1343,7 +1418,11 @@ impl Problem {
if providers.len() > 0 {
let provider_count = providers.len() as i64;
let slice = if provider_count > max_providers + 1 {
- providers.iter().take(max_providers as usize).cloned().collect::<Vec<_>>()
+ providers
+ .iter()
+ .take(max_providers as usize)
+ .cloned()
+ .collect::<Vec<_>>()
} else {
providers.clone()
};
diff --git a/crates/shirabe/src/dependency_resolver/request.rs b/crates/shirabe/src/dependency_resolver/request.rs
index 9aef975..e1f8c1e 100644
--- a/crates/shirabe/src/dependency_resolver/request.rs
+++ b/crates/shirabe/src/dependency_resolver/request.rs
@@ -1,7 +1,7 @@
//! ref: composer/src/Composer/DependencyResolver/Request.php
use indexmap::IndexMap;
-use shirabe_php_shim::{spl_object_hash, strtolower, LogicException};
+use shirabe_php_shim::{LogicException, spl_object_hash, strtolower};
use shirabe_semver::constraint::constraint_interface::ConstraintInterface;
use shirabe_semver::constraint::match_all_constraint::MatchAllConstraint;
diff --git a/crates/shirabe/src/dependency_resolver/rule.rs b/crates/shirabe/src/dependency_resolver/rule.rs
index 8c015b4..1ba1dd7 100644
--- a/crates/shirabe/src/dependency_resolver/rule.rs
+++ b/crates/shirabe/src/dependency_resolver/rule.rs
@@ -5,8 +5,8 @@ use std::any::Any;
use anyhow::Result;
use indexmap::IndexMap;
use shirabe_php_shim::{
- abs, array_filter, array_keys, array_shift, array_values, implode, is_object, LogicException,
- PhpMixed,
+ LogicException, PhpMixed, abs, array_filter, array_keys, array_shift, array_values, implode,
+ is_object,
};
use shirabe_semver::constraint::constraint::Constraint;
use shirabe_semver::constraint::constraint_interface::ConstraintInterface;
@@ -156,7 +156,9 @@ impl Rule {
if pool.is_unacceptable_fixed_or_locked_package(p) {
return true;
}
- if !link.get_constraint().matches(&Constraint::new("=", p.get_version()))
+ if !link
+ .get_constraint()
+ .matches(&Constraint::new("=", p.get_version()))
{
return true;
}
@@ -173,7 +175,11 @@ impl Rule {
}
if self.get_reason() == Self::RULE_ROOT_REQUIRE {
- if let ReasonData::RootRequire { package_name, constraint } = self.get_reason_data() {
+ if let ReasonData::RootRequire {
+ package_name,
+ constraint,
+ } = self.get_reason_data()
+ {
if PlatformRepository::is_platform_package(package_name) {
return false;
}
@@ -254,9 +260,10 @@ impl Rule {
let reason_data = self.get_reason_data();
let (package_name, constraint): (&str, &dyn ConstraintInterface) = match reason_data
{
- ReasonData::RootRequire { package_name, constraint } => {
- (package_name.as_str(), constraint.as_ref())
- }
+ ReasonData::RootRequire {
+ package_name,
+ constraint,
+ } => (package_name.as_str(), constraint.as_ref()),
_ => return String::new(),
};
@@ -273,7 +280,9 @@ impl Rule {
let packages_non_alias: Vec<Box<BasePackage>> = packages
.iter()
.filter(|p| {
- (p.as_any() as &dyn Any).downcast_ref::<AliasPackage>().is_none()
+ (p.as_any() as &dyn Any)
+ .downcast_ref::<AliasPackage>()
+ .is_none()
})
.map(|p| p.clone_box())
.collect();
@@ -293,7 +302,13 @@ impl Rule {
"Root composer.json requires {} {} -> satisfiable by {}.",
package_name,
constraint.get_pretty_string(),
- self.format_packages_unique(pool, packages, is_verbose, Some(constraint), false),
+ self.format_packages_unique(
+ pool,
+ packages,
+ is_verbose,
+ Some(constraint),
+ false
+ ),
)
}
@@ -335,8 +350,11 @@ impl Rule {
// swap literals if they are not in the right order with package2 being the conflicter
if link.get_source() == package1.get_name() {
std::mem::swap(&mut package1, &mut package2);
- conflict_target =
- format!("{} {}", package1.get_pretty_name(), link.get_pretty_constraint().unwrap_or(""));
+ conflict_target = format!(
+ "{} {}",
+ package1.get_pretty_name(),
+ link.get_pretty_constraint().unwrap_or("")
+ );
}
// if the conflict is not directly against the package but something it provides/replaces,
@@ -347,14 +365,16 @@ impl Rule {
for provide in package1.get_provides().values() {
if provide.get_target() == link.get_target() {
provide_type = Some("provides");
- provided = Some(provide.get_pretty_constraint().unwrap_or("").to_string());
+ provided =
+ Some(provide.get_pretty_constraint().unwrap_or("").to_string());
break;
}
}
for replace in package1.get_replaces().values() {
if replace.get_target() == link.get_target() {
provide_type = Some("replaces");
- provided = Some(replace.get_pretty_constraint().unwrap_or("").to_string());
+ provided =
+ Some(replace.get_pretty_constraint().unwrap_or("").to_string());
break;
}
}
@@ -371,7 +391,11 @@ impl Rule {
}
}
- format!("{} conflicts with {}.", package2.get_pretty_string(), conflict_target)
+ format!(
+ "{} conflicts with {}.",
+ package2.get_pretty_string(),
+ conflict_target
+ )
}
r if r == Self::RULE_PACKAGE_REQUIRES => {
@@ -488,14 +512,18 @@ impl Rule {
return format!(
"Only one of these can be installed: {}. {}",
- self.format_packages_unique_from_literals(pool, &literals, is_verbose, None, true),
+ self.format_packages_unique_from_literals(
+ pool, &literals, is_verbose, None, true
+ ),
reason,
);
}
format!(
"You can only install one version of a package, so only one of these can be installed: {}.",
- self.format_packages_unique_from_literals(pool, &literals, is_verbose, None, true),
+ self.format_packages_unique_from_literals(
+ pool, &literals, is_verbose, None, true
+ ),
)
}
r if r == Self::RULE_LEARNED => {
@@ -512,7 +540,11 @@ impl Rule {
let group = if installed_map.contains_key(&package.id) {
if *literal > 0 { "keep" } else { "remove" }
} else {
- if *literal > 0 { "install" } else { "don't install" }
+ if *literal > 0 {
+ "install"
+ } else {
+ "don't install"
+ }
};
groups
@@ -604,7 +636,13 @@ impl Rule {
packages.push(package);
}
- Problem::get_package_list(packages, is_verbose, pool, constraint, use_removed_version_group)
+ Problem::get_package_list(
+ packages,
+ is_verbose,
+ pool,
+ constraint,
+ use_removed_version_group,
+ )
}
/// Helper for cases where literals come as int IDs (PHP supports both via union).
@@ -620,13 +658,17 @@ impl Rule {
for literal in literals {
packages.push(pool.literal_to_package(*literal).clone_box());
}
- Problem::get_package_list(packages, is_verbose, pool, constraint, use_removed_version_group)
+ Problem::get_package_list(
+ packages,
+ is_verbose,
+ pool,
+ constraint,
+ use_removed_version_group,
+ )
}
fn deduplicate_default_branch_alias(&self, package: Box<BasePackage>) -> Box<BasePackage> {
- if let Some(alias_pkg) =
- (package.as_any() as &dyn Any).downcast_ref::<AliasPackage>()
- {
+ if let Some(alias_pkg) = (package.as_any() as &dyn Any).downcast_ref::<AliasPackage>() {
if alias_pkg.get_pretty_version() == VersionParser::DEFAULT_BRANCH_ALIAS {
return alias_pkg.get_alias_of().clone_box();
}
diff --git a/crates/shirabe/src/dependency_resolver/rule2_literals.rs b/crates/shirabe/src/dependency_resolver/rule2_literals.rs
index 9d3aefc..e86c93d 100644
--- a/crates/shirabe/src/dependency_resolver/rule2_literals.rs
+++ b/crates/shirabe/src/dependency_resolver/rule2_literals.rs
@@ -12,7 +12,12 @@ pub struct Rule2Literals {
}
impl Rule2Literals {
- pub fn new(literal1: i64, literal2: i64, reason: shirabe_php_shim::PhpMixed, reason_data: shirabe_php_shim::PhpMixed) -> Self {
+ pub fn new(
+ literal1: i64,
+ literal2: i64,
+ reason: shirabe_php_shim::PhpMixed,
+ reason_data: shirabe_php_shim::PhpMixed,
+ ) -> Self {
let (literal1, literal2) = if literal1 < literal2 {
(literal1, literal2)
} else {
@@ -52,7 +57,11 @@ impl Rule2Literals {
}
pub fn to_string(&self) -> String {
- let prefix = if self.inner.is_disabled() { "disabled(" } else { "(" };
+ let prefix = if self.inner.is_disabled() {
+ "disabled("
+ } else {
+ "("
+ };
format!("{}{}|{})", prefix, self.literal1, self.literal2)
}
}
diff --git a/crates/shirabe/src/dependency_resolver/rule_set.rs b/crates/shirabe/src/dependency_resolver/rule_set.rs
index 36009d9..4fc7928 100644
--- a/crates/shirabe/src/dependency_resolver/rule_set.rs
+++ b/crates/shirabe/src/dependency_resolver/rule_set.rs
@@ -53,7 +53,8 @@ impl RuleSet {
return Err(OutOfBoundsException {
message: format!("Unknown rule type: {}", r#type),
code: 0,
- }.into());
+ }
+ .into());
}
let hash = rule.get_hash();
@@ -66,13 +67,19 @@ impl RuleSet {
}
}
- self.rules.entry(r#type).or_insert_with(Vec::new).push(rule.clone());
+ self.rules
+ .entry(r#type)
+ .or_insert_with(Vec::new)
+ .push(rule.clone());
rule.set_type(r#type);
self.rule_by_id.insert(self.next_rule_id, rule.clone());
self.next_rule_id += 1;
- self.rules_by_hash.entry(hash).or_insert_with(Vec::new).push(rule);
+ self.rules_by_hash
+ .entry(hash)
+ .or_insert_with(Vec::new)
+ .push(rule);
Ok(())
}
diff --git a/crates/shirabe/src/dependency_resolver/rule_set_generator.rs b/crates/shirabe/src/dependency_resolver/rule_set_generator.rs
index a2066ef..9c803d6 100644
--- a/crates/shirabe/src/dependency_resolver/rule_set_generator.rs
+++ b/crates/shirabe/src/dependency_resolver/rule_set_generator.rs
@@ -12,8 +12,8 @@ use crate::dependency_resolver::policy_interface::PolicyInterface;
use crate::dependency_resolver::pool::Pool;
use crate::dependency_resolver::request::Request;
use crate::dependency_resolver::rule::Rule;
-use crate::dependency_resolver::rule2_literals::Rule2Literals;
use crate::dependency_resolver::rule_set::RuleSet;
+use crate::dependency_resolver::rule2_literals::Rule2Literals;
use crate::filter::platform_requirement_filter::ignore_list_platform_requirement_filter::IgnoreListPlatformRequirementFilter;
use crate::filter::platform_requirement_filter::platform_requirement_filter_factory::PlatformRequirementFilterFactory;
use crate::filter::platform_requirement_filter::platform_requirement_filter_interface::PlatformRequirementFilterInterface;
@@ -65,7 +65,11 @@ impl RuleSetGenerator {
literals.push(provider.get_id());
}
- Some(GenericRule::new(literals, PhpMixed::Int(reason), reason_data))
+ Some(GenericRule::new(
+ literals,
+ PhpMixed::Int(reason),
+ reason_data,
+ ))
}
/// Creates a rule to install at least one of a set of packages.
@@ -126,7 +130,9 @@ impl RuleSetGenerator {
reason_data,
))
} else {
- Rule::from(MultiConflictRule::new(literals, PhpMixed::Int(reason), reason_data).unwrap())
+ Rule::from(
+ MultiConflictRule::new(literals, PhpMixed::Int(reason), reason_data).unwrap(),
+ )
}
}
@@ -202,8 +208,8 @@ impl RuleSetGenerator {
if platform_requirement_filter.is_ignored(link.get_target()) {
continue;
} else if let Some(ignore_list_filter) = (platform_requirement_filter as &dyn Any)
- .downcast_ref::<IgnoreListPlatformRequirementFilter>()
- {
+ .downcast_ref::<IgnoreListPlatformRequirementFilter>(
+ ) {
constraint = ignore_list_filter
.filter_constraint(link.get_target(), constraint, true)
.unwrap_or(constraint);
@@ -230,11 +236,8 @@ impl RuleSetGenerator {
&mut self,
platform_requirement_filter: &dyn PlatformRequirementFilterInterface,
) {
- let packages: Vec<Box<dyn PackageInterface>> = self
- .added_map
- .values()
- .map(|p| p.clone_box())
- .collect();
+ let packages: Vec<Box<dyn PackageInterface>> =
+ self.added_map.values().map(|p| p.clone_box()).collect();
for package in &packages {
for link in package.get_conflicts().values() {
@@ -247,8 +250,8 @@ impl RuleSetGenerator {
if platform_requirement_filter.is_ignored(link.get_target()) {
continue;
} else if let Some(ignore_list_filter) = (platform_requirement_filter as &dyn Any)
- .downcast_ref::<IgnoreListPlatformRequirementFilter>()
- {
+ .downcast_ref::<IgnoreListPlatformRequirementFilter>(
+ ) {
constraint = ignore_list_filter
.filter_constraint(link.get_target(), constraint, false)
.unwrap_or(constraint);
@@ -286,11 +289,8 @@ impl RuleSetGenerator {
for (name, packages) in names_packages {
if packages.len() > 1 {
let reason = Rule::RULE_PACKAGE_SAME_NAME;
- let rule = self.create_multi_conflict_rule(
- &packages,
- reason,
- PhpMixed::String(name),
- );
+ let rule =
+ self.create_multi_conflict_rule(&packages, reason, PhpMixed::String(name));
self.add_rule(RuleSet::TYPE_PACKAGE, Some(rule));
}
}
@@ -309,15 +309,13 @@ impl RuleSetGenerator {
}
// otherwise, looks like a bug
- return Err(anyhow::anyhow!(
- shirabe_php_shim::LogicException {
- message: format!(
- "Fixed package {} was not added to solver pool.",
- package.get_pretty_string()
- ),
- code: 0,
- }
- ));
+ return Err(anyhow::anyhow!(shirabe_php_shim::LogicException {
+ message: format!(
+ "Fixed package {} was not added to solver pool.",
+ package.get_pretty_string()
+ ),
+ code: 0,
+ }));
}
self.add_rules_for_package(package.clone_box(), platform_requirement_filter);
@@ -340,8 +338,8 @@ impl RuleSetGenerator {
if platform_requirement_filter.is_ignored(package_name) {
continue;
} else if let Some(ignore_list_filter) = (platform_requirement_filter as &dyn Any)
- .downcast_ref::<IgnoreListPlatformRequirementFilter>()
- {
+ .downcast_ref::<IgnoreListPlatformRequirementFilter>(
+ ) {
constraint = ignore_list_filter
.filter_constraint(package_name, constraint, true)
.unwrap_or(constraint);
@@ -406,8 +404,8 @@ impl RuleSetGenerator {
request: &Request,
platform_requirement_filter: Option<Box<dyn PlatformRequirementFilterInterface>>,
) -> anyhow::Result<RuleSet> {
- let platform_requirement_filter =
- platform_requirement_filter.unwrap_or_else(PlatformRequirementFilterFactory::ignore_nothing);
+ let platform_requirement_filter = platform_requirement_filter
+ .unwrap_or_else(PlatformRequirementFilterFactory::ignore_nothing);
self.add_rules_for_request(request, &*platform_requirement_filter)?;
diff --git a/crates/shirabe/src/dependency_resolver/rule_set_iterator.rs b/crates/shirabe/src/dependency_resolver/rule_set_iterator.rs
index e2b67f4..f66a277 100644
--- a/crates/shirabe/src/dependency_resolver/rule_set_iterator.rs
+++ b/crates/shirabe/src/dependency_resolver/rule_set_iterator.rs
@@ -1,7 +1,7 @@
//! ref: composer/src/Composer/DependencyResolver/RuleSetIterator.php
-use indexmap::IndexMap;
use crate::dependency_resolver::rule::Rule;
+use indexmap::IndexMap;
/// Implements PHP \Iterator over a grouped rule set.
#[derive(Debug)]
diff --git a/crates/shirabe/src/dependency_resolver/rule_watch_graph.rs b/crates/shirabe/src/dependency_resolver/rule_watch_graph.rs
index 5428ca1..80c9bee 100644
--- a/crates/shirabe/src/dependency_resolver/rule_watch_graph.rs
+++ b/crates/shirabe/src/dependency_resolver/rule_watch_graph.rs
@@ -27,24 +27,38 @@ impl RuleWatchGraph {
return;
}
- if (node.get_rule().as_any() as &dyn Any).downcast_ref::<MultiConflictRule>().is_none() {
+ if (node.get_rule().as_any() as &dyn Any)
+ .downcast_ref::<MultiConflictRule>()
+ .is_none()
+ {
for literal in [node.watch1, node.watch2] {
if !self.watch_chains.contains_key(&literal) {
self.watch_chains.insert(literal, RuleWatchChain::new());
}
- self.watch_chains.get_mut(&literal).unwrap().unshift(node.clone());
+ self.watch_chains
+ .get_mut(&literal)
+ .unwrap()
+ .unshift(node.clone());
}
} else {
for literal in node.get_rule().get_literals() {
if !self.watch_chains.contains_key(&literal) {
self.watch_chains.insert(literal, RuleWatchChain::new());
}
- self.watch_chains.get_mut(&literal).unwrap().unshift(node.clone());
+ self.watch_chains
+ .get_mut(&literal)
+ .unwrap()
+ .unshift(node.clone());
}
}
}
- pub fn propagate_literal(&mut self, decided_literal: i64, level: i64, decisions: &mut Decisions) -> Option<Box<dyn Rule>> {
+ pub fn propagate_literal(
+ &mut self,
+ decided_literal: i64,
+ level: i64,
+ decisions: &mut Decisions,
+ ) -> Option<Box<dyn Rule>> {
let literal = -decided_literal;
if !self.watch_chains.contains_key(&literal) {
@@ -56,13 +70,17 @@ impl RuleWatchGraph {
chain.rewind();
while chain.valid() {
let node = chain.current();
- if (node.get_rule().as_any() as &dyn Any).downcast_ref::<MultiConflictRule>().is_none() {
+ if (node.get_rule().as_any() as &dyn Any)
+ .downcast_ref::<MultiConflictRule>()
+ .is_none()
+ {
let other_watch = node.get_other_watch(literal);
if !node.get_rule().is_disabled() && !decisions.satisfy(other_watch) {
let rule_literals = node.get_rule().get_literals();
- let alternative_literals: Vec<i64> = rule_literals.into_iter()
+ let alternative_literals: Vec<i64> = rule_literals
+ .into_iter()
.filter(|&rule_literal| {
literal != rule_literal
&& other_watch != rule_literal
@@ -107,6 +125,9 @@ impl RuleWatchGraph {
node.move_watch(from_literal, to_literal);
self.watch_chains.get_mut(&from_literal).unwrap().remove();
- self.watch_chains.get_mut(&to_literal).unwrap().unshift(node);
+ self.watch_chains
+ .get_mut(&to_literal)
+ .unwrap()
+ .unshift(node);
}
}
diff --git a/crates/shirabe/src/dependency_resolver/rule_watch_node.rs b/crates/shirabe/src/dependency_resolver/rule_watch_node.rs
index 4161268..12dd83f 100644
--- a/crates/shirabe/src/dependency_resolver/rule_watch_node.rs
+++ b/crates/shirabe/src/dependency_resolver/rule_watch_node.rs
@@ -25,7 +25,11 @@ impl RuleWatchNode {
let watch1 = if literal_count > 0 { literals[0] } else { 0 };
let watch2 = if literal_count > 1 { literals[1] } else { 0 };
- Self { watch1, watch2, rule }
+ Self {
+ watch1,
+ watch2,
+ rule,
+ }
}
pub fn watch2_on_highest(&mut self, decisions: &Decisions) {
diff --git a/crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs b/crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs
index 8c30f60..8caf6bd 100644
--- a/crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs
+++ b/crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs
@@ -1,8 +1,5 @@
//! ref: composer/src/Composer/DependencyResolver/SecurityAdvisoryPoolFilter.php
-use indexmap::IndexMap;
-use shirabe_php_shim::PhpMixed;
-use shirabe_semver::constraint::constraint::Constraint;
use crate::advisory::audit_config::AuditConfig;
use crate::advisory::auditor::Auditor;
use crate::dependency_resolver::pool::Pool;
@@ -11,6 +8,9 @@ use crate::package::package_interface::PackageInterface;
use crate::repository::platform_repository::PlatformRepository;
use crate::repository::repository_interface::RepositoryInterface;
use crate::repository::repository_set::RepositorySet;
+use indexmap::IndexMap;
+use shirabe_php_shim::PhpMixed;
+use shirabe_semver::constraint::constraint::Constraint;
#[derive(Debug)]
pub struct SecurityAdvisoryPoolFilter {
@@ -20,10 +20,18 @@ pub struct SecurityAdvisoryPoolFilter {
impl SecurityAdvisoryPoolFilter {
pub fn new(auditor: Auditor, audit_config: AuditConfig) -> Self {
- Self { auditor, audit_config }
+ Self {
+ auditor,
+ audit_config,
+ }
}
- pub fn filter(&self, pool: Pool, repositories: Vec<Box<dyn RepositoryInterface>>, request: &Request) -> Pool {
+ pub fn filter(
+ &self,
+ pool: Pool,
+ repositories: Vec<Box<dyn RepositoryInterface>>,
+ request: &Request,
+ ) -> Pool {
if !self.audit_config.block_insecure {
return pool;
}
@@ -35,15 +43,23 @@ impl SecurityAdvisoryPoolFilter {
let mut packages_for_advisories: Vec<Box<dyn PackageInterface>> = vec![];
for package in pool.get_packages() {
- if !package.is_root() && !PlatformRepository::is_platform_package(package.get_name()) && !request.is_locked_package(package.as_ref()) {
+ if !package.is_root()
+ && !PlatformRepository::is_platform_package(package.get_name())
+ && !request.is_locked_package(package.as_ref())
+ {
packages_for_advisories.push(package);
}
}
// all_advisories: ['advisories' => array<string, array<PartialSecurityAdvisory|SecurityAdvisory>>, ...]
- let mut all_advisories: IndexMap<String, PhpMixed> = repo_set.get_matching_security_advisories(&packages_for_advisories, true, true);
- if self.auditor.needs_complete_advisory_load(&all_advisories["advisories"], &self.audit_config.ignore_list_for_blocking) {
- all_advisories = repo_set.get_matching_security_advisories(&packages_for_advisories, false, true);
+ let mut all_advisories: IndexMap<String, PhpMixed> =
+ repo_set.get_matching_security_advisories(&packages_for_advisories, true, true);
+ if self.auditor.needs_complete_advisory_load(
+ &all_advisories["advisories"],
+ &self.audit_config.ignore_list_for_blocking,
+ ) {
+ all_advisories =
+ repo_set.get_matching_security_advisories(&packages_for_advisories, false, true);
}
// advisory_map: array<string, array<PartialSecurityAdvisory|SecurityAdvisory>>
@@ -51,20 +67,35 @@ impl SecurityAdvisoryPoolFilter {
&all_advisories["advisories"],
&self.audit_config.ignore_list_for_blocking,
&self.audit_config.ignore_severity_for_blocking,
- )["advisories"].clone().into();
+ )["advisories"]
+ .clone()
+ .into();
let mut packages: Vec<Box<dyn PackageInterface>> = vec![];
// security_removed_versions: array<string, array<string, array<PartialSecurityAdvisory|SecurityAdvisory>>>
- let mut security_removed_versions: IndexMap<String, IndexMap<String, Vec<PhpMixed>>> = IndexMap::new();
+ let mut security_removed_versions: IndexMap<String, IndexMap<String, Vec<PhpMixed>>> =
+ IndexMap::new();
// abandoned_removed_versions: array<string, array<string, string>>
- let mut abandoned_removed_versions: IndexMap<String, IndexMap<String, String>> = IndexMap::new();
+ let mut abandoned_removed_versions: IndexMap<String, IndexMap<String, String>> =
+ IndexMap::new();
for package in pool.get_packages() {
- if self.audit_config.block_abandoned && !self.auditor.filter_abandoned_packages(vec![package.as_ref()], &self.audit_config.ignore_abandoned_for_blocking).is_empty() {
+ if self.audit_config.block_abandoned
+ && !self
+ .auditor
+ .filter_abandoned_packages(
+ vec![package.as_ref()],
+ &self.audit_config.ignore_abandoned_for_blocking,
+ )
+ .is_empty()
+ {
for package_name in package.get_names(false) {
abandoned_removed_versions
.entry(package_name)
.or_default()
- .insert(package.get_version().to_string(), package.get_pretty_version().to_string());
+ .insert(
+ package.get_version().to_string(),
+ package.get_pretty_version().to_string(),
+ );
}
continue;
}
@@ -75,7 +106,10 @@ impl SecurityAdvisoryPoolFilter {
security_removed_versions
.entry(package_name)
.or_default()
- .insert(package.get_version().to_string(), matching_advisories.clone());
+ .insert(
+ package.get_version().to_string(),
+ matching_advisories.clone(),
+ );
}
continue;
}
@@ -83,10 +117,21 @@ impl SecurityAdvisoryPoolFilter {
packages.push(package);
}
- Pool::new(packages, pool.get_unacceptable_fixed_or_locked_packages(), pool.get_all_removed_versions(), pool.get_all_removed_versions_by_package(), security_removed_versions, abandoned_removed_versions)
+ Pool::new(
+ packages,
+ pool.get_unacceptable_fixed_or_locked_packages(),
+ pool.get_all_removed_versions(),
+ pool.get_all_removed_versions_by_package(),
+ security_removed_versions,
+ abandoned_removed_versions,
+ )
}
- fn get_matching_advisories(&self, package: &dyn PackageInterface, advisory_map: &IndexMap<String, Vec<PhpMixed>>) -> Vec<PhpMixed> {
+ fn get_matching_advisories(
+ &self,
+ package: &dyn PackageInterface,
+ advisory_map: &IndexMap<String, Vec<PhpMixed>>,
+ ) -> Vec<PhpMixed> {
if package.is_dev() {
return vec![];
}
diff --git a/crates/shirabe/src/dependency_resolver/solver.rs b/crates/shirabe/src/dependency_resolver/solver.rs
index 76de9de..388cccd 100644
--- a/crates/shirabe/src/dependency_resolver/solver.rs
+++ b/crates/shirabe/src/dependency_resolver/solver.rs
@@ -2,7 +2,9 @@
use indexmap::IndexMap;
-use shirabe_php_shim::{array_pop, array_shift, array_unshift, microtime, spl_object_hash, sprintf, PhpMixed};
+use shirabe_php_shim::{
+ PhpMixed, array_pop, array_shift, array_unshift, microtime, spl_object_hash, sprintf,
+};
use shirabe_semver::constraint::constraint_interface::ConstraintInterface;
use crate::dependency_resolver::decisions::Decisions;
@@ -183,8 +185,8 @@ impl Solver {
continue;
} else if let Some(ignore_filter) = platform_requirement_filter
.as_any()
- .downcast_ref::<IgnoreListPlatformRequirementFilter>()
- {
+ .downcast_ref::<IgnoreListPlatformRequirementFilter>(
+ ) {
constraint = ignore_filter.filter_constraint(package_name, constraint);
}
@@ -201,8 +203,7 @@ impl Solver {
);
// TODO(phase-b): store the constraint inside reason_data; PhpMixed needs to
// accept a `dyn ConstraintInterface` wrapper.
- reason_data
- .insert("constraint".to_string(), PhpMixed::Null);
+ reason_data.insert("constraint".to_string(), PhpMixed::Null);
problem.add_rule(Rule::generic(GenericRule::new(
Vec::new(),
PhpMixed::Int(Rule::RULE_ROOT_REQUIRE),
@@ -233,7 +234,8 @@ impl Solver {
true,
<dyn IOInterface>::DEBUG,
);
- let mut rule_set_generator = RuleSetGenerator::new(self.policy.clone_box(), self.pool.clone());
+ let mut rule_set_generator =
+ RuleSetGenerator::new(self.policy.clone_box(), self.pool.clone());
self.rules =
rule_set_generator.get_rules_for(request, platform_requirement_filter.as_ref())?;
drop(rule_set_generator);
@@ -242,8 +244,7 @@ impl Solver {
self.watch_graph = RuleWatchGraph::new();
for rule in self.rules.iter() {
- self.watch_graph
- .insert(RuleWatchNode::new(rule.clone()))?;
+ self.watch_graph.insert(RuleWatchNode::new(rule.clone()))?;
}
// make decisions based on root require/fix assertions
@@ -298,11 +299,9 @@ impl Solver {
.at_offset(self.propagate_index as usize)
.clone();
- let conflict = self.watch_graph.propagate_literal(
- decision.0,
- level,
- &mut self.decisions,
- );
+ let conflict =
+ self.watch_graph
+ .propagate_literal(decision.0, level, &mut self.decisions);
self.propagate_index += 1;
@@ -333,9 +332,7 @@ impl Solver {
self.propagate_index = self.decisions.count() as i64;
}
- while !self.branches.is_empty()
- && self.branches[self.branches.len() - 1].1 >= level
- {
+ while !self.branches.is_empty() && self.branches[self.branches.len() - 1].1 >= level {
// PHP: array_pop($this->branches)
self.branches.pop();
}
@@ -388,8 +385,7 @@ impl Solver {
self.rules
.add(new_rule.clone().into(), RuleSet::TYPE_LEARNED)?;
- self.learned_why
- .insert(spl_object_hash(&new_rule), why);
+ self.learned_why.insert(spl_object_hash(&new_rule), why);
let mut rule_node = RuleWatchNode::new(new_rule.clone().into());
rule_node.watch2_on_highest(&self.decisions);
@@ -408,9 +404,11 @@ impl Solver {
rule: Rule,
) -> anyhow::Result<i64> {
// choose best package to install from decisionQueue
- let mut literals =
- self.policy
- .select_preferred_packages(&self.pool, decision_queue, rule.get_required_package());
+ let mut literals = self.policy.select_preferred_packages(
+ &self.pool,
+ decision_queue,
+ rule.get_required_package(),
+ );
let selected_literal = array_shift::<i64>(&mut literals);
@@ -422,11 +420,7 @@ impl Solver {
self.set_propagate_learn(level, selected_literal, rule)
}
- fn analyze(
- &mut self,
- level: i64,
- rule: Rule,
- ) -> anyhow::Result<(i64, i64, GenericRule, i64)> {
+ fn analyze(&mut self, level: i64, rule: Rule) -> anyhow::Result<(i64, i64, GenericRule, i64)> {
let analyzed_rule = rule.clone();
let mut rule = rule;
let mut rule_level = 1_i64;
diff --git a/crates/shirabe/src/dependency_resolver/solver_problems_exception.rs b/crates/shirabe/src/dependency_resolver/solver_problems_exception.rs
index 37cbbfe..ddc8746 100644
--- a/crates/shirabe/src/dependency_resolver/solver_problems_exception.rs
+++ b/crates/shirabe/src/dependency_resolver/solver_problems_exception.rs
@@ -50,10 +50,18 @@ impl SolverProblemsException {
for problem in &self.problems {
problems.push(format!(
"{}\n",
- problem.get_pretty_string(repository_set, request, pool, is_verbose, &installed_map, &self.learned_pool)
+ problem.get_pretty_string(
+ repository_set,
+ request,
+ pool,
+ is_verbose,
+ &installed_map,
+ &self.learned_pool
+ )
));
missing_extensions.extend(self.get_extension_problems(problem.get_reasons()));
- is_caused_by_lock = is_caused_by_lock || problem.is_caused_by_lock(repository_set, request, pool);
+ is_caused_by_lock =
+ is_caused_by_lock || problem.is_caused_by_lock(repository_set, request, pool);
}
let mut i = 1;
@@ -66,7 +74,9 @@ impl SolverProblemsException {
}
let mut hints: Vec<String> = Vec::new();
- if !is_dev_extraction && (text.contains("could not be found") || text.contains("no matching package found")) {
+ if !is_dev_extraction
+ && (text.contains("could not be found") || text.contains("no matching package found"))
+ {
hints.push("Potential causes:\n - A typo in the package name\n - The package is not available in a stable-enough version according to your minimum-stability setting\n see <https://getcomposer.org/doc/04-schema.md#minimum-stability> for more details.\n - It's a private package and you forgot to add a custom repository to find it\n\nRead <https://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.".to_string());
}
@@ -74,11 +84,16 @@ impl SolverProblemsException {
hints.push(self.create_extension_hint(&missing_extensions));
}
- if is_caused_by_lock && !is_dev_extraction && !request.get_update_allow_transitive_root_dependencies() {
+ if is_caused_by_lock
+ && !is_dev_extraction
+ && !request.get_update_allow_transitive_root_dependencies()
+ {
hints.push("Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.".to_string());
}
- if text.contains("found composer-plugin-api[2.0.0] but it does not match") && text.contains("- ocramius/package-versions") {
+ if text.contains("found composer-plugin-api[2.0.0] but it does not match")
+ && text.contains("- ocramius/package-versions")
+ {
hints.push("<warning>ocramius/package-versions only provides support for Composer 2 in 1.8+, which requires PHP 7.4.</warning>\nIf you can not upgrade PHP you can require <info>composer/package-versions-deprecated</info> to resolve this with PHP 7.0+.".to_string());
}
@@ -118,7 +133,9 @@ impl SolverProblemsException {
.collect::<Vec<_>>()
.join(" ");
- let mut text = "To enable extensions, verify that they are enabled in your .ini files:\n - ".to_string();
+ let mut text =
+ "To enable extensions, verify that they are enabled in your .ini files:\n - "
+ .to_string();
text.push_str(&paths.join("\n - "));
text.push_str("\nYou can also run `php --ini` in a terminal to see which files are used by PHP in CLI mode.");
text.push_str(&format!("\nAlternatively, you can run Composer with `{}` to temporarily ignore these required extensions.", ignore_extensions_arguments));
diff --git a/crates/shirabe/src/dependency_resolver/transaction.rs b/crates/shirabe/src/dependency_resolver/transaction.rs
index 1b7ed02..7c93114 100644
--- a/crates/shirabe/src/dependency_resolver/transaction.rs
+++ b/crates/shirabe/src/dependency_resolver/transaction.rs
@@ -4,8 +4,8 @@ use std::any::Any;
use indexmap::IndexMap;
use shirabe_php_shim::{
- array_filter, array_intersect, array_keys, array_pop, array_unshift, spl_object_hash, strcmp,
- uasort, PhpMixed,
+ PhpMixed, array_filter, array_intersect, array_keys, array_pop, array_unshift, spl_object_hash,
+ strcmp, uasort,
};
use crate::dependency_resolver::operation::install_operation::InstallOperation;
@@ -150,9 +150,7 @@ impl Transaction {
visited.insert(spl_object_hash(package.as_ref()), true);
stack.push(package.clone_box());
- if let Some(alias) =
- (package.as_any() as &dyn Any).downcast_ref::<AliasPackage>()
- {
+ if let Some(alias) = (package.as_any() as &dyn Any).downcast_ref::<AliasPackage>() {
stack.push(alias.get_alias_of().clone_box());
} else {
for link in package.get_requires().values() {
@@ -170,15 +168,14 @@ impl Transaction {
.downcast_ref::<AliasPackage>()
.is_some()
{
- let alias_key =
- format!("{}::{}", package.get_name(), package.get_version());
+ let alias_key = format!("{}::{}", package.get_name(), package.get_version());
if present_alias_map.contains_key(&alias_key) {
remove_alias_map.shift_remove(&alias_key);
} else {
// TODO(phase-b): MarkAliasInstalledOperation::new expects AliasPackage by value
- operations.push(Box::new(MarkAliasInstalledOperation::new(
- todo!("package as AliasPackage by value"),
- )));
+ operations.push(Box::new(MarkAliasInstalledOperation::new(todo!(
+ "package as AliasPackage by value"
+ ))));
}
} else if let Some(source) = present_package_map.get(package.get_name()) {
// do we need to update?
@@ -187,9 +184,8 @@ impl Transaction {
// TODO(phase-b): downcast to CompletePackageInterface trait object
let package_is_complete = false;
let present_is_complete = false;
- let abandoned_or_replacement_changed = package_is_complete
- && present_is_complete
- && {
+ let abandoned_or_replacement_changed =
+ package_is_complete && present_is_complete && {
// PHP: $package->isAbandoned() !== $presentPackageMap[$package->getName()]->isAbandoned()
// || $package->getReplacementPackage() !== $presentPackageMap[$package->getName()]->getReplacementPackage()
todo!("compare abandoned/replacement across CompletePackageInterface")
@@ -221,9 +217,9 @@ impl Transaction {
}
for (_name_version, _package) in remove_alias_map {
// TODO(phase-b): MarkAliasUninstalledOperation::new expects AliasPackage by value
- operations.push(Box::new(MarkAliasUninstalledOperation::new(
- todo!("package as AliasPackage by value"),
- )));
+ operations.push(Box::new(MarkAliasUninstalledOperation::new(todo!(
+ "package as AliasPackage by value"
+ ))));
}
let operations = self.move_plugins_to_front(operations);
@@ -368,9 +364,7 @@ impl Transaction {
|| package.get_type() == "composer-installer";
// is this a plugin or a dependency of a plugin?
- if is_plugin
- || array_intersect(&package.get_names(true), &plugin_requires).len() > 0
- {
+ if is_plugin || array_intersect(&package.get_names(true), &plugin_requires).len() > 0 {
// get the package's requires, but filter out any platform requirements
let requires: Vec<String> = array_filter(
&array_keys(&package.get_requires()),
diff --git a/crates/shirabe/src/downloader/archive_downloader.rs b/crates/shirabe/src/downloader/archive_downloader.rs
index 9220410..59704e3 100644
--- a/crates/shirabe/src/downloader/archive_downloader.rs
+++ b/crates/shirabe/src/downloader/archive_downloader.rs
@@ -1,14 +1,16 @@
//! ref: composer/src/Composer/Downloader/ArchiveDownloader.php
-use anyhow::Result;
-use indexmap::IndexMap;
-use shirabe_php_shim::{bin2hex, file_exists, is_dir, random_bytes, realpath, RuntimeException, DIRECTORY_SEPARATOR};
-use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
-use shirabe_external_packages::symfony::component::finder::finder::Finder;
use crate::dependency_resolver::operation::install_operation::InstallOperation;
use crate::downloader::file_downloader::FileDownloader;
use crate::package::package_interface::PackageInterface;
use crate::util::platform::Platform;
+use anyhow::Result;
+use indexmap::IndexMap;
+use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
+use shirabe_external_packages::symfony::component::finder::finder::Finder;
+use shirabe_php_shim::{
+ DIRECTORY_SEPARATOR, RuntimeException, bin2hex, file_exists, is_dir, random_bytes, realpath,
+};
#[derive(Debug)]
pub struct ArchiveDownloader {
@@ -17,21 +19,43 @@ pub struct ArchiveDownloader {
}
impl ArchiveDownloader {
- pub fn prepare(&mut self, r#type: &str, package: &dyn PackageInterface, path: &str, prev_package: Option<&dyn PackageInterface>) -> Result<Box<dyn PromiseInterface>> {
+ pub fn prepare(
+ &mut self,
+ r#type: &str,
+ package: &dyn PackageInterface,
+ path: &str,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> Result<Box<dyn PromiseInterface>> {
self.cleanup_executed.remove(package.get_name());
self.inner.prepare(r#type, package, path, prev_package)
}
- pub fn cleanup(&mut self, r#type: &str, package: &dyn PackageInterface, path: &str, prev_package: Option<&dyn PackageInterface>) -> Result<Box<dyn PromiseInterface>> {
- self.cleanup_executed.insert(package.get_name().to_string(), true);
+ pub fn cleanup(
+ &mut self,
+ r#type: &str,
+ package: &dyn PackageInterface,
+ path: &str,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.cleanup_executed
+ .insert(package.get_name().to_string(), true);
self.inner.cleanup(r#type, package, path, prev_package)
}
- pub fn install(&mut self, package: &dyn PackageInterface, path: &str, output: bool) -> Result<Box<dyn PromiseInterface>> {
+ pub fn install(
+ &mut self,
+ package: &dyn PackageInterface,
+ path: &str,
+ output: bool,
+ ) -> Result<Box<dyn PromiseInterface>> {
if output {
- self.inner.io.write_error(&format!(" - {}{}", InstallOperation::format(package, false), self.get_install_operation_appendix(package, path)));
+ self.inner.io.write_error(&format!(
+ " - {}{}",
+ InstallOperation::format(package, false),
+ self.get_install_operation_appendix(package, path)
+ ));
}
let vendor_dir = self.inner.config.get("vendor-dir");
@@ -39,7 +63,12 @@ impl ArchiveDownloader {
// clean up the target directory, unless it contains the vendor dir, as the vendor dir contains
// the archive to be extracted. This is the case when installing with create-project in the current directory
// but in that case we ensure the directory is empty already in ProjectInstaller so no need to empty it here.
- if !self.inner.filesystem.normalize_path(&vendor_dir).contains(&self.inner.filesystem.normalize_path(&format!("{}{}", path, DIRECTORY_SEPARATOR))) {
+ if !self.inner.filesystem.normalize_path(&vendor_dir).contains(
+ &self
+ .inner
+ .filesystem
+ .normalize_path(&format!("{}{}", path, DIRECTORY_SEPARATOR)),
+ ) {
self.inner.filesystem.empty_directory(path);
}
@@ -58,7 +87,9 @@ impl ArchiveDownloader {
self.inner.add_cleanup_path(package, path);
}
- self.inner.filesystem.ensure_directory_exists(&temporary_dir);
+ self.inner
+ .filesystem
+ .ensure_directory_exists(&temporary_dir);
let file_name = self.inner.get_file_name(package, path);
let filesystem = &self.inner.filesystem;
@@ -187,11 +218,20 @@ impl ArchiveDownloader {
))
}
- pub fn get_install_operation_appendix(&self, _package: &dyn PackageInterface, _path: &str) -> &str {
+ pub fn get_install_operation_appendix(
+ &self,
+ _package: &dyn PackageInterface,
+ _path: &str,
+ ) -> &str {
": Extracting archive"
}
- pub(crate) fn extract(&self, _package: &dyn PackageInterface, _file: &str, _path: &str) -> Result<Box<dyn PromiseInterface>> {
+ pub(crate) fn extract(
+ &self,
+ _package: &dyn PackageInterface,
+ _file: &str,
+ _path: &str,
+ ) -> Result<Box<dyn PromiseInterface>> {
todo!()
}
}
diff --git a/crates/shirabe/src/downloader/download_manager.rs b/crates/shirabe/src/downloader/download_manager.rs
index e787689..ff453f3 100644
--- a/crates/shirabe/src/downloader/download_manager.rs
+++ b/crates/shirabe/src/downloader/download_manager.rs
@@ -5,9 +5,9 @@ use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use shirabe_php_shim::{
- array_keys, array_reverse, array_shift, dirname, get_class, implode, in_array, preg_quote,
- rtrim, sprintf, str_replace, strtolower, usort, InvalidArgumentException, LogicException,
- PhpMixed, RuntimeException,
+ InvalidArgumentException, LogicException, PhpMixed, RuntimeException, array_keys,
+ array_reverse, array_shift, dirname, get_class, implode, in_array, preg_quote, rtrim, sprintf,
+ str_replace, strtolower, usort,
};
use crate::downloader::downloader_interface::DownloaderInterface;
@@ -200,7 +200,8 @@ impl DownloadManager {
prev_package: Option<&dyn PackageInterface>,
) -> Result<Box<dyn PromiseInterface>> {
let target_dir = self.normalize_target_dir(target_dir);
- self.filesystem.ensure_directory_exists(&dirname(&target_dir));
+ self.filesystem
+ .ensure_directory_exists(&dirname(&target_dir));
let mut sources = self.get_available_sources(package, prev_package)?;
@@ -241,7 +242,8 @@ impl DownloadManager {
// PHP closure handleError: rethrow if not RuntimeException or if IrrecoverableDownloadException
// TODO(phase-b): downcast for instanceof checks
let is_runtime: bool = todo!("e instanceof RuntimeException");
- let is_irrecoverable: bool = todo!("e instanceof IrrecoverableDownloadException");
+ let is_irrecoverable: bool =
+ todo!("e instanceof IrrecoverableDownloadException");
if is_runtime && !is_irrecoverable {
if sources.is_empty() {
return Err(e);
@@ -268,7 +270,9 @@ impl DownloadManager {
// PHP: $result->then(static fn ($res) => $res, $handleError);
// TODO(phase-b): chain $handleError as the rejection handler on the promise
- let res = result.then(Box::new(move |res: PhpMixed| -> Result<PhpMixed> { Ok(res) }));
+ let res = result.then(Box::new(move |res: PhpMixed| -> Result<PhpMixed> {
+ Ok(res)
+ }));
return Ok(res);
}
@@ -358,10 +362,7 @@ impl DownloadManager {
return Err(e);
}
self.io.write_error(
- PhpMixed::String(format!(
- "<error> Update failed ({})</error>",
- e,
- )),
+ PhpMixed::String(format!("<error> Update failed ({})</error>", e,)),
true,
IOInterface::NORMAL,
);
@@ -503,11 +504,7 @@ impl DownloadManager {
{
let prev_source_owned = prev_source.unwrap_or("").to_string();
usort(&mut sources, move |a: &String, b: &String| -> i64 {
- if *a == prev_source_owned {
- -1
- } else {
- 1
- }
+ if *a == prev_source_owned { -1 } else { 1 }
});
return Ok(sources);
diff --git a/crates/shirabe/src/downloader/downloader_interface.rs b/crates/shirabe/src/downloader/downloader_interface.rs
index c78a094..423df69 100644
--- a/crates/shirabe/src/downloader/downloader_interface.rs
+++ b/crates/shirabe/src/downloader/downloader_interface.rs
@@ -7,15 +7,45 @@ use crate::package::package_interface::PackageInterface;
pub trait DownloaderInterface {
fn get_installation_source(&self) -> String;
- fn download(&self, package: &dyn PackageInterface, path: &str, prev_package: Option<&dyn PackageInterface>) -> anyhow::Result<Box<dyn PromiseInterface>>;
+ fn download(
+ &self,
+ package: &dyn PackageInterface,
+ path: &str,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> anyhow::Result<Box<dyn PromiseInterface>>;
- fn prepare(&self, r#type: &str, package: &dyn PackageInterface, path: &str, prev_package: Option<&dyn PackageInterface>) -> anyhow::Result<Box<dyn PromiseInterface>>;
+ fn prepare(
+ &self,
+ r#type: &str,
+ package: &dyn PackageInterface,
+ path: &str,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> anyhow::Result<Box<dyn PromiseInterface>>;
- fn install(&self, package: &dyn PackageInterface, path: &str) -> anyhow::Result<Box<dyn PromiseInterface>>;
+ fn install(
+ &self,
+ package: &dyn PackageInterface,
+ path: &str,
+ ) -> anyhow::Result<Box<dyn PromiseInterface>>;
- fn update(&self, initial: &dyn PackageInterface, target: &dyn PackageInterface, path: &str) -> anyhow::Result<Box<dyn PromiseInterface>>;
+ fn update(
+ &self,
+ initial: &dyn PackageInterface,
+ target: &dyn PackageInterface,
+ path: &str,
+ ) -> anyhow::Result<Box<dyn PromiseInterface>>;
- fn remove(&self, package: &dyn PackageInterface, path: &str) -> anyhow::Result<Box<dyn PromiseInterface>>;
+ fn remove(
+ &self,
+ package: &dyn PackageInterface,
+ path: &str,
+ ) -> anyhow::Result<Box<dyn PromiseInterface>>;
- fn cleanup(&self, r#type: &str, package: &dyn PackageInterface, path: &str, prev_package: Option<&dyn PackageInterface>) -> anyhow::Result<Box<dyn PromiseInterface>>;
+ fn cleanup(
+ &self,
+ r#type: &str,
+ package: &dyn PackageInterface,
+ path: &str,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> anyhow::Result<Box<dyn PromiseInterface>>;
}
diff --git a/crates/shirabe/src/downloader/file_downloader.rs b/crates/shirabe/src/downloader/file_downloader.rs
index 7ddc60a..5b002ff 100644
--- a/crates/shirabe/src/downloader/file_downloader.rs
+++ b/crates/shirabe/src/downloader/file_downloader.rs
@@ -7,11 +7,11 @@ use std::sync::{LazyLock, Mutex};
use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use shirabe_external_packages::react::promise::resolve as react_promise_resolve;
use shirabe_php_shim::{
- array_search, array_shift, file_exists, filesize, get_class, hash, hash_file, in_array,
- is_dir, is_executable, parse_url, pathinfo, realpath, rtrim, spl_object_hash, strlen, strpos,
- strtr, trim, umask, usleep, InvalidArgumentException, PhpMixed, RuntimeException, Silencer,
- UnexpectedValueException, DIRECTORY_SEPARATOR, PATHINFO_BASENAME, PATHINFO_EXTENSION,
- PHP_URL_PATH,
+ DIRECTORY_SEPARATOR, InvalidArgumentException, PATHINFO_BASENAME, PATHINFO_EXTENSION,
+ PHP_URL_PATH, PhpMixed, RuntimeException, Silencer, UnexpectedValueException, array_search,
+ array_shift, file_exists, filesize, get_class, hash, hash_file, in_array, is_dir,
+ is_executable, parse_url, pathinfo, realpath, rtrim, spl_object_hash, strlen, strpos, strtr,
+ trim, umask, usleep,
};
use crate::cache::Cache;
@@ -106,10 +106,7 @@ impl FileDownloader {
this.io.write_error("Running cache garbage collection");
this.cache.as_mut().unwrap().gc(
this.config.get("cache-files-ttl").as_int().unwrap_or(0),
- this.config
- .get("cache-files-maxsize")
- .as_int()
- .unwrap_or(0),
+ this.config.get("cache-files-maxsize").as_int().unwrap_or(0),
);
}
@@ -180,13 +177,15 @@ impl DownloaderInterface for FileDownloader {
let _ = PluginEvents::PRE_FILE_DOWNLOAD;
let _ = PluginEvents::POST_FILE_DOWNLOAD;
- todo!("phase-b: orchestrate download/accept/reject closures and call download() returning a PromiseInterface")
+ todo!(
+ "phase-b: orchestrate download/accept/reject closures and call download() returning a PromiseInterface"
+ )
}
/// @inheritDoc
fn prepare(
&mut self,
- _r#type: &str,
+ _type: &str,
_package: &dyn PackageInterface,
_path: &str,
_prev_package: Option<&dyn PackageInterface>,
@@ -197,7 +196,7 @@ impl DownloaderInterface for FileDownloader {
/// @inheritDoc
fn cleanup(
&mut self,
- _r#type: &str,
+ _type: &str,
package: &dyn PackageInterface,
path: &str,
_prev_package: Option<&dyn PackageInterface>,
@@ -226,7 +225,11 @@ impl DownloaderInterface for FileDownloader {
vendor_dir.clone(),
];
- if let Some(paths) = self.additional_cleanup_paths.get(package.get_name()).cloned() {
+ if let Some(paths) = self
+ .additional_cleanup_paths
+ .get(package.get_name())
+ .cloned()
+ {
for path_to_clean in &paths {
self.filesystem.remove(path_to_clean)?;
}
@@ -337,9 +340,7 @@ impl DownloaderInterface for FileDownloader {
// TODO(phase-b): chain `.then(|result| if !result { throw RuntimeException })`
let _ = path;
- todo!(
- "phase-b: chain promise.then(|result| {{ if !result {{ throw RuntimeException }} }})"
- )
+ todo!("phase-b: chain promise.then(|result| {{ if !result {{ throw RuntimeException }} }})")
}
}
@@ -365,7 +366,8 @@ impl ChangeReportInterface for FileDownloader {
.remove_directory(&format!("{}_compare", target_dir), false)?;
}
- let promise = self.download(package, &format!("{}_compare", target_dir), None, false)?;
+ let promise =
+ self.download(package, &format!("{}_compare", target_dir), None, false)?;
promise.then_with(
None,
Some(Box::new(|ex: PhpMixed| {
@@ -419,7 +421,11 @@ impl ChangeReportInterface for FileDownloader {
let output = trim(&output, None);
- Ok(if strlen(&output) > 0 { Some(output) } else { None })
+ Ok(if strlen(&output) > 0 {
+ Some(output)
+ } else {
+ None
+ })
}
}
diff --git a/crates/shirabe/src/downloader/fossil_downloader.rs b/crates/shirabe/src/downloader/fossil_downloader.rs
index 47ad973..a686177 100644
--- a/crates/shirabe/src/downloader/fossil_downloader.rs
+++ b/crates/shirabe/src/downloader/fossil_downloader.rs
@@ -1,11 +1,11 @@
//! ref: composer/src/Composer/Downloader/FossilDownloader.php
+use crate::downloader::vcs_downloader::VcsDownloader;
+use crate::package::package_interface::PackageInterface;
use anyhow::Result;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use shirabe_php_shim::RuntimeException;
-use crate::downloader::vcs_downloader::VcsDownloader;
-use crate::package::package_interface::PackageInterface;
#[derive(Debug)]
pub struct FossilDownloader {
@@ -29,26 +29,48 @@ impl FossilDownloader {
path: String,
url: String,
) -> Result<Box<dyn PromiseInterface>> {
- self.inner.config.prohibit_url_by_config(&url, &self.inner.io)?;
+ self.inner
+ .config
+ .prohibit_url_by_config(&url, &self.inner.io)?;
let repo_file = format!("{}.fossil", path);
let real_path = shirabe_php_shim::realpath(&path);
- self.inner.io.write_error(&format!("Cloning {}", package.get_source_reference().unwrap_or_default()));
+ self.inner.io.write_error(&format!(
+ "Cloning {}",
+ package.get_source_reference().unwrap_or_default()
+ ));
let mut output = String::new();
self.execute(
- vec!["fossil".to_string(), "clone".to_string(), "--".to_string(), url, repo_file.clone()],
+ vec![
+ "fossil".to_string(),
+ "clone".to_string(),
+ "--".to_string(),
+ url,
+ repo_file.clone(),
+ ],
None,
&mut output,
)?;
self.execute(
- vec!["fossil".to_string(), "open".to_string(), "--nested".to_string(), "--".to_string(), repo_file],
+ vec![
+ "fossil".to_string(),
+ "open".to_string(),
+ "--nested".to_string(),
+ "--".to_string(),
+ repo_file,
+ ],
real_path.clone(),
&mut output,
)?;
self.execute(
- vec!["fossil".to_string(), "update".to_string(), "--".to_string(), package.get_source_reference().unwrap_or_default()],
+ vec![
+ "fossil".to_string(),
+ "update".to_string(),
+ "--".to_string(),
+ package.get_source_reference().unwrap_or_default(),
+ ],
real_path,
&mut output,
)?;
@@ -63,9 +85,14 @@ impl FossilDownloader {
path: String,
url: String,
) -> Result<Box<dyn PromiseInterface>> {
- self.inner.config.prohibit_url_by_config(&url, &self.inner.io)?;
+ self.inner
+ .config
+ .prohibit_url_by_config(&url, &self.inner.io)?;
- self.inner.io.write_error(&format!(" Updating to {}", target.get_source_reference().unwrap_or_default()));
+ self.inner.io.write_error(&format!(
+ " Updating to {}",
+ target.get_source_reference().unwrap_or_default()
+ ));
if !self.has_metadata_repository(&path) {
return Err(RuntimeException {
@@ -85,7 +112,12 @@ impl FossilDownloader {
&mut output,
)?;
self.execute(
- vec!["fossil".to_string(), "up".to_string(), "--".to_string(), target.get_source_reference().unwrap_or_default()],
+ vec![
+ "fossil".to_string(),
+ "up".to_string(),
+ "--".to_string(),
+ target.get_source_reference().unwrap_or_default(),
+ ],
real_path,
&mut output,
)?;
@@ -93,7 +125,11 @@ impl FossilDownloader {
Ok(shirabe_external_packages::react::promise::resolve(None))
}
- pub fn get_local_changes(&self, _package: &dyn PackageInterface, path: String) -> Option<String> {
+ pub fn get_local_changes(
+ &self,
+ _package: &dyn PackageInterface,
+ path: String,
+ ) -> Option<String> {
if !self.has_metadata_repository(&path) {
return None;
}
@@ -119,11 +155,16 @@ impl FossilDownloader {
let mut output = String::new();
self.execute(
vec![
- "fossil".to_string(), "timeline".to_string(),
- "-t".to_string(), "ci".to_string(),
- "-W".to_string(), "0".to_string(),
- "-n".to_string(), "0".to_string(),
- "before".to_string(), to_reference.clone(),
+ "fossil".to_string(),
+ "timeline".to_string(),
+ "-t".to_string(),
+ "ci".to_string(),
+ "-W".to_string(),
+ "0".to_string(),
+ "-n".to_string(),
+ "0".to_string(),
+ "before".to_string(),
+ to_reference.clone(),
],
shirabe_php_shim::realpath(&path),
&mut output,
@@ -149,7 +190,12 @@ impl FossilDownloader {
Ok(log)
}
- fn execute(&self, command: Vec<String>, cwd: Option<String>, output: &mut String) -> Result<()> {
+ fn execute(
+ &self,
+ command: Vec<String>,
+ cwd: Option<String>,
+ output: &mut String,
+ ) -> Result<()> {
if self.inner.process.execute(&command, output, cwd) != 0 {
return Err(RuntimeException {
message: format!(
@@ -158,7 +204,8 @@ impl FossilDownloader {
self.inner.process.get_error_output()
),
code: 0,
- }.into());
+ }
+ .into());
}
Ok(())
}
diff --git a/crates/shirabe/src/downloader/git_downloader.rs b/crates/shirabe/src/downloader/git_downloader.rs
index 6957ba1..97d0ee9 100644
--- a/crates/shirabe/src/downloader/git_downloader.rs
+++ b/crates/shirabe/src/downloader/git_downloader.rs
@@ -6,8 +6,8 @@ use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::react::promise;
use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use shirabe_php_shim::{
- array_map, basename, dirname, implode, in_array, is_dir, preg_quote, realpath, rtrim, sprintf,
- strlen, strpos, substr, trim, version_compare, PhpMixed, RuntimeException,
+ PhpMixed, RuntimeException, array_map, basename, dirname, implode, in_array, is_dir,
+ preg_quote, realpath, rtrim, sprintf, strlen, strpos, substr, trim, version_compare,
};
use crate::cache::Cache;
@@ -42,12 +42,7 @@ impl GitDownloader {
fs: Option<Filesystem>,
) -> Self {
let inner = VcsDownloader::new(io, config, process, fs);
- let git_util = GitUtil::new(
- &*inner.io,
- &inner.config,
- &inner.process,
- &inner.filesystem,
- );
+ let git_util = GitUtil::new(&*inner.io, &inner.config, &inner.process, &inner.filesystem);
Self {
inner,
has_stashed_changes: IndexMap::new(),
@@ -73,7 +68,11 @@ impl GitDownloader {
let cache_path = format!(
"{}/{}/",
- self.inner.config.get("cache-vcs-dir").as_string().unwrap_or(""),
+ self.inner
+ .config
+ .get("cache-vcs-dir")
+ .as_string()
+ .unwrap_or(""),
Preg::replace(r"{[^a-z0-9.]}i", "-", Url::sanitize(url.to_string())),
);
let git_version = GitUtil::get_version(&self.inner.process);
@@ -134,7 +133,11 @@ impl GitDownloader {
let path = self.normalize_path(path);
let cache_path = format!(
"{}/{}/",
- self.inner.config.get("cache-vcs-dir").as_string().unwrap_or(""),
+ self.inner
+ .config
+ .get("cache-vcs-dir")
+ .as_string()
+ .unwrap_or(""),
Preg::replace(r"{[^a-z0-9.]}i", "-", Url::sanitize(url.to_string())),
);
let r#ref = package.get_source_reference().unwrap_or("").to_string();
@@ -157,10 +160,7 @@ impl GitDownloader {
];
let transport_options = package.get_transport_options();
if let Some(git_opts) = transport_options.get("git").and_then(|v| v.as_array()) {
- if let Some(single) = git_opts
- .get("single_use_clone")
- .and_then(|v| v.as_bool())
- {
+ if let Some(single) = git_opts.get("single_use_clone").and_then(|v| v.as_bool()) {
if single {
clone_flags = vec![];
}
@@ -298,7 +298,11 @@ impl GitDownloader {
let cache_path = format!(
"{}/{}/",
- self.inner.config.get("cache-vcs-dir").as_string().unwrap_or(""),
+ self.inner
+ .config
+ .get("cache-vcs-dir")
+ .as_string()
+ .unwrap_or(""),
Preg::replace(r"{[^a-z0-9.]}i", "-", Url::sanitize(url.to_string())),
);
let r#ref = target.get_source_reference().unwrap_or("").to_string();
@@ -401,7 +405,8 @@ impl GitDownloader {
) == 0
{
let origin_match = Preg::is_match_strict_groups(r"{^origin\s+(?P<url>\S+)}m", &output);
- let composer_match = Preg::is_match_strict_groups(r"{^composer\s+(?P<url>\S+)}m", &output);
+ let composer_match =
+ Preg::is_match_strict_groups(r"{^composer\s+(?P<url>\S+)}m", &output);
if let (Some(origin_match), Some(composer_match)) = (origin_match, composer_match) {
let origin_url = origin_match.get("url").cloned().unwrap_or_default();
let composer_url = composer_match.get("url").cloned().unwrap_or_default();
@@ -560,11 +565,11 @@ impl GitDownloader {
"--".to_string(),
];
let mut output = String::new();
- if self.inner.process.execute(
- &command,
- &mut output,
- Some(path.clone()),
- ) != 0
+ if self
+ .inner
+ .process
+ .execute(&command, &mut output, Some(path.clone()))
+ != 0
{
// TODO(phase-b): bubble error via Result later
panic!(
@@ -580,8 +585,7 @@ impl GitDownloader {
let output = trim(&output, None);
// keep the shortest diff from all remote branches we compare against
if unpushed_changes.is_none()
- || strlen(&output)
- < strlen(unpushed_changes.as_deref().unwrap_or(""))
+ || strlen(&output) < strlen(unpushed_changes.as_deref().unwrap_or(""))
{
unpushed_changes = Some(output);
}
@@ -593,11 +597,7 @@ impl GitDownloader {
if unpushed_changes.is_some() && i == 0 {
let mut output = String::new();
self.inner.process.execute(
- &vec![
- "git".to_string(),
- "fetch".to_string(),
- "--all".to_string(),
- ],
+ &vec!["git".to_string(), "fetch".to_string(), "--all".to_string()],
&mut output,
Some(path.clone()),
);
@@ -786,9 +786,7 @@ impl GitDownloader {
" n - abort the {} and let you manually clean things up",
if update { "update" } else { "uninstall" }
))),
- Box::new(PhpMixed::String(
- " v - view modified files".to_string(),
- )),
+ Box::new(PhpMixed::String(" v - view modified files".to_string())),
Box::new(PhpMixed::String(
" d - view local modifications (diff)".to_string(),
)),
@@ -833,11 +831,7 @@ impl GitDownloader {
);
let mut output = String::new();
if self.inner.process.execute(
- &vec![
- "git".to_string(),
- "stash".to_string(),
- "pop".to_string(),
- ],
+ &vec!["git".to_string(), "stash".to_string(), "pop".to_string()],
&mut output,
Some(path.clone()),
) != 0
@@ -886,8 +880,11 @@ impl GitDownloader {
// If the non-existent branch is actually the name of a file, the file
// is checked out.
- let mut branch =
- Preg::replace(r"{(?:^dev-|(?:\.x)?-dev$)}i", "", pretty_version.to_string());
+ let mut branch = Preg::replace(
+ r"{(?:^dev-|(?:\.x)?-dev$)}i",
+ "",
+ pretty_version.to_string(),
+ );
// Closure equivalent: $execute = function(array $command) use (&$output, $path) { ... };
// Inlined below at each call site.
@@ -910,10 +907,7 @@ impl GitDownloader {
if !Preg::is_match(r"{^[a-f0-9]{40}$}", reference).unwrap_or(false)
&& branches.is_some()
&& Preg::is_match(
- &format!(
- "{{^\\s+composer/{}$}}m",
- preg_quote(reference, None)
- ),
+ &format!("{{^\\s+composer/{}$}}m", preg_quote(reference, None)),
branches.as_deref().unwrap_or(""),
)
.unwrap_or(false)
@@ -935,18 +929,17 @@ impl GitDownloader {
];
let mut output = String::new();
- let ok1 = self.inner.process.execute(
- &command1,
- &mut output,
- Some(path.to_string()),
- ) == 0;
+ let ok1 = self
+ .inner
+ .process
+ .execute(&command1, &mut output, Some(path.to_string()))
+ == 0;
let ok2 = if ok1 {
let mut output = String::new();
- self.inner.process.execute(
- &command2,
- &mut output,
- Some(path.to_string()),
- ) == 0
+ self.inner
+ .process
+ .execute(&command2, &mut output, Some(path.to_string()))
+ == 0
} else {
false
};
@@ -960,18 +953,12 @@ impl GitDownloader {
// add 'v' in front of the branch if it was stripped when generating the pretty name
if branches.is_some()
&& !Preg::is_match(
- &format!(
- "{{^\\s+composer/{}$}}m",
- preg_quote(&branch, None)
- ),
+ &format!("{{^\\s+composer/{}$}}m", preg_quote(&branch, None)),
branches.as_deref().unwrap_or(""),
)
.unwrap_or(false)
&& Preg::is_match(
- &format!(
- "{{^\\s+composer/v{}$}}m",
- preg_quote(&branch, None)
- ),
+ &format!("{{^\\s+composer/v{}$}}m", preg_quote(&branch, None)),
branches.as_deref().unwrap_or(""),
)
.unwrap_or(false)
@@ -985,8 +972,7 @@ impl GitDownloader {
branch.clone(),
"--".to_string(),
];
- let mut fallback_command: Vec<String> =
- vec!["git".to_string(), "checkout".to_string()];
+ let mut fallback_command: Vec<String> = vec!["git".to_string(), "checkout".to_string()];
fallback_command.extend(force.clone());
fallback_command.extend(vec![
"-B".to_string(),
@@ -1003,28 +989,26 @@ impl GitDownloader {
];
let mut output = String::new();
- let ok_command = self.inner.process.execute(
- &command,
- &mut output,
- Some(path.to_string()),
- ) == 0;
+ let ok_command =
+ self.inner
+ .process
+ .execute(&command, &mut output, Some(path.to_string()))
+ == 0;
let ok_fallback = if !ok_command {
let mut output = String::new();
- self.inner.process.execute(
- &fallback_command,
- &mut output,
- Some(path.to_string()),
- ) == 0
+ self.inner
+ .process
+ .execute(&fallback_command, &mut output, Some(path.to_string()))
+ == 0
} else {
false
};
let ok_reset = if ok_command || ok_fallback {
let mut output = String::new();
- self.inner.process.execute(
- &reset_command,
- &mut output,
- Some(path.to_string()),
- ) == 0
+ self.inner
+ .process
+ .execute(&reset_command, &mut output, Some(path.to_string()))
+ == 0
} else {
false
};
@@ -1045,18 +1029,17 @@ impl GitDownloader {
];
{
let mut output = String::new();
- let ok1 = self.inner.process.execute(
- &command1,
- &mut output,
- Some(path.to_string()),
- ) == 0;
+ let ok1 = self
+ .inner
+ .process
+ .execute(&command1, &mut output, Some(path.to_string()))
+ == 0;
let ok2 = if ok1 {
let mut output = String::new();
- self.inner.process.execute(
- &command2,
- &mut output,
- Some(path.to_string()),
- ) == 0
+ self.inner
+ .process
+ .execute(&command2, &mut output, Some(path.to_string()))
+ == 0
} else {
false
};
@@ -1193,11 +1176,7 @@ impl GitDownloader {
let path = self.normalize_path(path);
let mut output = String::new();
if self.inner.process.execute(
- &vec![
- "git".to_string(),
- "clean".to_string(),
- "-df".to_string(),
- ],
+ &vec!["git".to_string(), "clean".to_string(), "-df".to_string()],
&mut output,
Some(path.clone()),
) != 0
@@ -1210,11 +1189,7 @@ impl GitDownloader {
}
let mut output = String::new();
if self.inner.process.execute(
- &vec![
- "git".to_string(),
- "reset".to_string(),
- "--hard".to_string(),
- ],
+ &vec!["git".to_string(), "reset".to_string(), "--hard".to_string()],
&mut output,
Some(path.clone()),
) != 0
@@ -1263,11 +1238,7 @@ impl GitDownloader {
let path = self.normalize_path(path);
let mut output = String::new();
if self.inner.process.execute(
- &vec![
- "git".to_string(),
- "diff".to_string(),
- "HEAD".to_string(),
- ],
+ &vec!["git".to_string(), "diff".to_string(), "HEAD".to_string()],
&mut output,
Some(path.clone()),
) != 0
@@ -1333,4 +1304,3 @@ impl DvcsDownloaderInterface for GitDownloader {
GitDownloader::get_unpushed_changes(self, package, &path)
}
}
-
diff --git a/crates/shirabe/src/downloader/gzip_downloader.rs b/crates/shirabe/src/downloader/gzip_downloader.rs
index 2158126..81fdbed 100644
--- a/crates/shirabe/src/downloader/gzip_downloader.rs
+++ b/crates/shirabe/src/downloader/gzip_downloader.rs
@@ -1,25 +1,31 @@
//! ref: composer/src/Composer/Downloader/GzipDownloader.php
+use crate::downloader::archive_downloader::ArchiveDownloader;
+use crate::package::package_interface::PackageInterface;
+use crate::util::platform::Platform;
use anyhow::Result;
use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use shirabe_php_shim::{
- RuntimeException,
- extension_loaded, fclose, fopen, fwrite, gzclose, gzopen, gzread,
- implode, parse_url, pathinfo, strtr,
- DIRECTORY_SEPARATOR, PATHINFO_FILENAME, PHP_URL_PATH,
+ DIRECTORY_SEPARATOR, PATHINFO_FILENAME, PHP_URL_PATH, RuntimeException, extension_loaded,
+ fclose, fopen, fwrite, gzclose, gzopen, gzread, implode, parse_url, pathinfo, strtr,
};
-use crate::downloader::archive_downloader::ArchiveDownloader;
-use crate::package::package_interface::PackageInterface;
-use crate::util::platform::Platform;
pub struct GzipDownloader {
inner: ArchiveDownloader,
}
impl GzipDownloader {
- pub(crate) fn extract(&self, package: &dyn PackageInterface, file: &str, path: &str) -> Result<Box<dyn PromiseInterface>> {
+ pub(crate) fn extract(
+ &self,
+ package: &dyn PackageInterface,
+ file: &str,
+ path: &str,
+ ) -> Result<Box<dyn PromiseInterface>> {
let filename = pathinfo(
- parse_url(&strtr(&package.get_dist_url().unwrap_or_default(), "\\", "/"), PHP_URL_PATH),
+ parse_url(
+ &strtr(&package.get_dist_url().unwrap_or_default(), "\\", "/"),
+ PHP_URL_PATH,
+ ),
PATHINFO_FILENAME,
);
let target_filepath = format!("{}{}{}", path, DIRECTORY_SEPARATOR, filename);
@@ -47,7 +53,10 @@ impl GzipDownloader {
implode(" ", &command),
self.inner.process.get_error_output(),
);
- return Err(anyhow::anyhow!(RuntimeException { message: process_error, code: 0 }));
+ return Err(anyhow::anyhow!(RuntimeException {
+ message: process_error,
+ code: 0
+ }));
}
self.extract_using_ext(file, &target_filepath);
diff --git a/crates/shirabe/src/downloader/hg_downloader.rs b/crates/shirabe/src/downloader/hg_downloader.rs
index 7501fb6..ff06806 100644
--- a/crates/shirabe/src/downloader/hg_downloader.rs
+++ b/crates/shirabe/src/downloader/hg_downloader.rs
@@ -1,11 +1,11 @@
//! ref: composer/src/Composer/Downloader/HgDownloader.php
-use anyhow::Result;
-use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
-use shirabe_php_shim::RuntimeException;
use crate::downloader::vcs_downloader::VcsDownloader;
use crate::package::package_interface::PackageInterface;
use crate::util::hg::Hg as HgUtils;
+use anyhow::Result;
+use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
+use shirabe_php_shim::RuntimeException;
#[derive(Debug)]
pub struct HgDownloader {
@@ -24,7 +24,8 @@ impl HgDownloader {
return Err(RuntimeException {
message: "hg was not found in your PATH, skipping source download".to_string(),
code: 0,
- }.into());
+ }
+ .into());
}
Ok(shirabe_external_packages::react::promise::resolve(None))
@@ -40,7 +41,13 @@ impl HgDownloader {
let path_clone = path.clone();
let clone_command = move |url: String| -> Vec<String> {
- vec!["hg".to_string(), "clone".to_string(), "--".to_string(), url, path_clone.clone()]
+ vec![
+ "hg".to_string(),
+ "clone".to_string(),
+ "--".to_string(),
+ url,
+ path_clone.clone(),
+ ]
};
hg_utils.run_command(clone_command, url, Some(path.clone()));
@@ -51,7 +58,12 @@ impl HgDownloader {
package.get_source_reference().unwrap_or_default(),
];
let mut ignored_output = String::new();
- if self.inner.process.execute(&command, &mut ignored_output, shirabe_php_shim::realpath(&path)) != 0 {
+ if self.inner.process.execute(
+ &command,
+ &mut ignored_output,
+ shirabe_php_shim::realpath(&path),
+ ) != 0
+ {
return Err(RuntimeException {
message: format!(
"Failed to execute {}\n\n{}",
@@ -59,7 +71,8 @@ impl HgDownloader {
self.inner.process.get_error_output()
),
code: 0,
- }.into());
+ }
+ .into());
}
Ok(shirabe_external_packages::react::promise::resolve(None))
@@ -75,7 +88,10 @@ impl HgDownloader {
let hg_utils = HgUtils::new(&self.inner.io, &self.inner.config, &self.inner.process);
let ref_ = target.get_source_reference().unwrap_or_default();
- self.inner.io.write_error(&format!(" Updating to {}", target.get_source_reference().unwrap_or_default()));
+ self.inner.io.write_error(&format!(
+ " Updating to {}",
+ target.get_source_reference().unwrap_or_default()
+ ));
if !self.has_metadata_repository(path.clone()) {
return Err(RuntimeException {
@@ -94,14 +110,23 @@ impl HgDownloader {
let ref_clone = ref_.clone();
let up_command = move |_url: String| -> Vec<String> {
- vec!["hg".to_string(), "up".to_string(), "--".to_string(), ref_clone.clone()]
+ vec![
+ "hg".to_string(),
+ "up".to_string(),
+ "--".to_string(),
+ ref_clone.clone(),
+ ]
};
hg_utils.run_command(up_command, url, Some(path));
Ok(shirabe_external_packages::react::promise::resolve(None))
}
- pub fn get_local_changes(&self, package: &dyn PackageInterface, path: String) -> Option<String> {
+ pub fn get_local_changes(
+ &self,
+ package: &dyn PackageInterface,
+ path: String,
+ ) -> Option<String> {
if !std::path::Path::new(&format!("{}/.hg", path)).is_dir() {
return None;
}
@@ -115,7 +140,11 @@ impl HgDownloader {
let output = output.trim().to_string();
- if !output.is_empty() { Some(output) } else { None }
+ if !output.is_empty() {
+ Some(output)
+ } else {
+ None
+ }
}
pub(crate) fn get_commit_logs(
@@ -134,7 +163,12 @@ impl HgDownloader {
];
let mut output = String::new();
- if self.inner.process.execute(&command, &mut output, shirabe_php_shim::realpath(&path)) != 0 {
+ if self
+ .inner
+ .process
+ .execute(&command, &mut output, shirabe_php_shim::realpath(&path))
+ != 0
+ {
return Err(RuntimeException {
message: format!(
"Failed to execute {}\n\n{}",
@@ -142,7 +176,8 @@ impl HgDownloader {
self.inner.process.get_error_output()
),
code: 0,
- }.into());
+ }
+ .into());
}
Ok(output)
diff --git a/crates/shirabe/src/downloader/mod.rs b/crates/shirabe/src/downloader/mod.rs
new file mode 100644
index 0000000..391ae23
--- /dev/null
+++ b/crates/shirabe/src/downloader/mod.rs
@@ -0,0 +1,23 @@
+pub mod archive_downloader;
+pub mod change_report_interface;
+pub mod download_manager;
+pub mod downloader_interface;
+pub mod dvcs_downloader_interface;
+pub mod file_downloader;
+pub mod filesystem_exception;
+pub mod fossil_downloader;
+pub mod git_downloader;
+pub mod gzip_downloader;
+pub mod hg_downloader;
+pub mod max_file_size_exceeded_exception;
+pub mod path_downloader;
+pub mod perforce_downloader;
+pub mod phar_downloader;
+pub mod rar_downloader;
+pub mod svn_downloader;
+pub mod tar_downloader;
+pub mod transport_exception;
+pub mod vcs_capable_downloader_interface;
+pub mod vcs_downloader;
+pub mod xz_downloader;
+pub mod zip_downloader;
diff --git a/crates/shirabe/src/downloader/path_downloader.rs b/crates/shirabe/src/downloader/path_downloader.rs
index 2ad3312..33e3b45 100644
--- a/crates/shirabe/src/downloader/path_downloader.rs
+++ b/crates/shirabe/src/downloader/path_downloader.rs
@@ -6,8 +6,8 @@ use shirabe_external_packages::react::promise::promise_interface::PromiseInterfa
use shirabe_external_packages::symfony::component::filesystem::exception::io_exception::IOException;
use shirabe_external_packages::symfony::component::filesystem::filesystem::Filesystem as SymfonyFilesystem;
use shirabe_php_shim::{
- file_exists, function_exists, is_dir, realpath, PhpMixed, RuntimeException,
- DIRECTORY_SEPARATOR, PHP_WINDOWS_VERSION_MAJOR, PHP_WINDOWS_VERSION_MINOR,
+ DIRECTORY_SEPARATOR, PHP_WINDOWS_VERSION_MAJOR, PHP_WINDOWS_VERSION_MINOR, PhpMixed,
+ RuntimeException, file_exists, function_exists, is_dir, realpath,
};
use crate::dependency_resolver::operation::install_operation::InstallOperation;
@@ -68,8 +68,12 @@ impl PathDownloader {
return Ok(shirabe_external_packages::react::promise::resolve(None));
}
- if format!("{}{}", realpath(&path).unwrap_or_default(), DIRECTORY_SEPARATOR)
- .starts_with(&format!("{}{}", real_url, DIRECTORY_SEPARATOR))
+ if format!(
+ "{}{}",
+ realpath(&path).unwrap_or_default(),
+ DIRECTORY_SEPARATOR
+ )
+ .starts_with(&format!("{}{}", real_url, DIRECTORY_SEPARATOR))
{
// IMPORTANT NOTICE: If you wish to change this, don't. You are wasting your time and ours.
//
@@ -140,7 +144,10 @@ impl PathDownloader {
if output {
self.inner.io.write_error(
- PhpMixed::String(format!(" - {}: ", InstallOperation::format(package, false))),
+ PhpMixed::String(format!(
+ " - {}: ",
+ InstallOperation::format(package, false)
+ )),
false,
IOInterface::NORMAL,
);
@@ -251,11 +258,9 @@ impl PathDownloader {
}
if output {
- self.inner.io.write_error(
- PhpMixed::String("".to_string()),
- true,
- IOInterface::NORMAL,
- );
+ self.inner
+ .io
+ .write_error(PhpMixed::String("".to_string()), true, IOInterface::NORMAL);
}
Ok(shirabe_external_packages::react::promise::resolve(None))
@@ -352,11 +357,7 @@ impl PathDownloader {
self.inner.remove(package, &path, output)
}
- pub fn get_vcs_reference(
- &self,
- package: &dyn PackageInterface,
- path: &str,
- ) -> Option<String> {
+ pub fn get_vcs_reference(&self, package: &dyn PackageInterface, path: &str) -> Option<String> {
let path = Filesystem::trim_trailing_slash(path);
let parser = VersionParser::new();
let guesser = VersionGuesser::new(
diff --git a/crates/shirabe/src/downloader/perforce_downloader.rs b/crates/shirabe/src/downloader/perforce_downloader.rs
index 27316e7..8674b3d 100644
--- a/crates/shirabe/src/downloader/perforce_downloader.rs
+++ b/crates/shirabe/src/downloader/perforce_downloader.rs
@@ -1,14 +1,14 @@
//! ref: composer/src/Composer/Downloader/PerforceDownloader.php
-use std::any::Any;
-use anyhow::Result;
-use indexmap::IndexMap;
-use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
-use shirabe_php_shim::PhpMixed;
use crate::downloader::vcs_downloader::VcsDownloader;
use crate::package::package_interface::PackageInterface;
use crate::repository::vcs_repository::VcsRepository;
use crate::util::perforce::Perforce;
+use anyhow::Result;
+use indexmap::IndexMap;
+use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
+use shirabe_php_shim::PhpMixed;
+use std::any::Any;
#[derive(Debug)]
pub struct PerforceDownloader {
@@ -36,13 +36,22 @@ impl PerforceDownloader {
let source_ref = package.get_source_reference();
let label = self.get_label_from_source_reference(source_ref.clone().unwrap_or_default());
- self.inner.io.write_error(&format!("Cloning {}", source_ref.clone().unwrap_or_default()));
+ self.inner.io.write_error(&format!(
+ "Cloning {}",
+ source_ref.clone().unwrap_or_default()
+ ));
self.init_perforce(package, path.clone(), url);
- self.perforce.as_mut().unwrap().set_stream(source_ref.clone().unwrap_or_default());
+ self.perforce
+ .as_mut()
+ .unwrap()
+ .set_stream(source_ref.clone().unwrap_or_default());
self.perforce.as_mut().unwrap().p4_login();
self.perforce.as_mut().unwrap().write_p4_client_spec();
self.perforce.as_mut().unwrap().connect_client();
- self.perforce.as_mut().unwrap().sync_code_base(label.as_deref());
+ self.perforce
+ .as_mut()
+ .unwrap()
+ .sync_code_base(label.as_deref());
self.perforce.as_mut().unwrap().cleanup_client_spec();
Ok(shirabe_external_packages::react::promise::resolve(None))
@@ -73,7 +82,13 @@ impl PerforceDownloader {
} else {
None
};
- self.perforce = Some(Perforce::create(repo_config, url, path, &self.inner.process, &self.inner.io));
+ self.perforce = Some(Perforce::create(
+ repo_config,
+ url,
+ path,
+ &self.inner.process,
+ &self.inner.io,
+ ));
}
fn get_repo_config(&self, repository: &VcsRepository) -> IndexMap<String, PhpMixed> {
@@ -90,8 +105,14 @@ impl PerforceDownloader {
self.do_install(target, path, url)
}
- pub fn get_local_changes(&self, _package: &dyn PackageInterface, _path: String) -> Option<String> {
- self.inner.io.write_error("Perforce driver does not check for local changes before overriding");
+ pub fn get_local_changes(
+ &self,
+ _package: &dyn PackageInterface,
+ _path: String,
+ ) -> Option<String> {
+ self.inner
+ .io
+ .write_error("Perforce driver does not check for local changes before overriding");
None
}
@@ -102,7 +123,11 @@ impl PerforceDownloader {
to_reference: String,
_path: String,
) -> Result<String> {
- Ok(self.perforce.as_ref().unwrap().get_commit_logs(from_reference, to_reference))
+ Ok(self
+ .perforce
+ .as_ref()
+ .unwrap()
+ .get_commit_logs(from_reference, to_reference))
}
pub fn set_perforce(&mut self, perforce: Perforce) {
diff --git a/crates/shirabe/src/downloader/phar_downloader.rs b/crates/shirabe/src/downloader/phar_downloader.rs
index 57610f1..8fea679 100644
--- a/crates/shirabe/src/downloader/phar_downloader.rs
+++ b/crates/shirabe/src/downloader/phar_downloader.rs
@@ -1,10 +1,10 @@
//! ref: composer/src/Composer/Downloader/PharDownloader.php
-use anyhow::Result;
-use shirabe_php_shim::Phar;
-use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use crate::downloader::archive_downloader::ArchiveDownloader;
use crate::package::package_interface::PackageInterface;
+use anyhow::Result;
+use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
+use shirabe_php_shim::Phar;
#[derive(Debug)]
pub struct PharDownloader {
@@ -12,7 +12,12 @@ pub struct PharDownloader {
}
impl PharDownloader {
- pub(crate) fn extract(&self, package: &dyn PackageInterface, file: &str, path: &str) -> Result<Box<dyn PromiseInterface>> {
+ pub(crate) fn extract(
+ &self,
+ package: &dyn PackageInterface,
+ file: &str,
+ path: &str,
+ ) -> Result<Box<dyn PromiseInterface>> {
// Can throw an UnexpectedValueException
let archive = Phar::new(file.to_string());
archive.extract_to(path, None, true);
diff --git a/crates/shirabe/src/downloader/rar_downloader.rs b/crates/shirabe/src/downloader/rar_downloader.rs
index 1aaa71c..1b4767f 100644
--- a/crates/shirabe/src/downloader/rar_downloader.rs
+++ b/crates/shirabe/src/downloader/rar_downloader.rs
@@ -1,19 +1,26 @@
//! ref: composer/src/Composer/Downloader/RarDownloader.php
-use anyhow::Result;
-use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
-use shirabe_php_shim::{class_exists, implode, RarArchive, RuntimeException, UnexpectedValueException};
use crate::downloader::archive_downloader::ArchiveDownloader;
use crate::package::package_interface::PackageInterface;
use crate::util::ini_helper::IniHelper;
use crate::util::platform::Platform;
+use anyhow::Result;
+use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
+use shirabe_php_shim::{
+ RarArchive, RuntimeException, UnexpectedValueException, class_exists, implode,
+};
pub struct RarDownloader {
inner: ArchiveDownloader,
}
impl RarDownloader {
- pub(crate) fn extract(&self, _package: &dyn PackageInterface, file: &str, path: &str) -> Result<Box<dyn PromiseInterface>> {
+ pub(crate) fn extract(
+ &self,
+ _package: &dyn PackageInterface,
+ file: &str,
+ path: &str,
+ ) -> Result<Box<dyn PromiseInterface>> {
let mut process_error: Option<String> = None;
if !Platform::is_windows() {
@@ -39,7 +46,10 @@ impl RarDownloader {
if !class_exists("RarArchive") {
let ini_message = IniHelper::get_message();
let error = if !Platform::is_windows() {
- format!("Could not decompress the archive, enable the PHP rar extension.\n{}", ini_message)
+ format!(
+ "Could not decompress the archive, enable the PHP rar extension.\n{}",
+ ini_message
+ )
} else {
format!(
"Could not decompress the archive, enable the PHP rar extension or install unrar.\n{}\n{}",
@@ -47,7 +57,11 @@ impl RarDownloader {
process_error.as_deref().unwrap_or(""),
)
};
- return Err(RuntimeException { message: error, code: 0 }.into());
+ return Err(RuntimeException {
+ message: error,
+ code: 0,
+ }
+ .into());
}
let rar_archive = RarArchive::open(file);
@@ -55,7 +69,8 @@ impl RarDownloader {
return Err(UnexpectedValueException {
message: format!("Could not open RAR archive: {}", file),
code: 0,
- }.into());
+ }
+ .into());
}
let rar_archive = rar_archive.unwrap();
@@ -64,7 +79,8 @@ impl RarDownloader {
return Err(RuntimeException {
message: "Could not retrieve RAR archive entries".to_string(),
code: 0,
- }.into());
+ }
+ .into());
}
for entry in entries.unwrap() {
@@ -72,7 +88,8 @@ impl RarDownloader {
return Err(RuntimeException {
message: "Could not extract entry".to_string(),
code: 0,
- }.into());
+ }
+ .into());
}
}
diff --git a/crates/shirabe/src/downloader/svn_downloader.rs b/crates/shirabe/src/downloader/svn_downloader.rs
index 75e5c02..30a64f2 100644
--- a/crates/shirabe/src/downloader/svn_downloader.rs
+++ b/crates/shirabe/src/downloader/svn_downloader.rs
@@ -3,7 +3,7 @@
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::react::promise;
use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
-use shirabe_php_shim::{is_dir, version_compare, PhpMixed, RuntimeException};
+use shirabe_php_shim::{PhpMixed, RuntimeException, is_dir, version_compare};
use crate::downloader::vcs_downloader::VcsDownloader;
use crate::io::io_interface::IOInterface;
@@ -26,7 +26,12 @@ impl SvnDownloader {
prev_package: Option<&dyn PackageInterface>,
) -> anyhow::Result<Box<dyn PromiseInterface>> {
SvnUtil::clean_env();
- let util = SvnUtil::new(url, &*self.inner.io, &self.inner.config, &self.inner.process);
+ let util = SvnUtil::new(
+ url,
+ &*self.inner.io,
+ &self.inner.config,
+ &self.inner.process,
+ );
if util.binary_version().is_none() {
return Err(RuntimeException {
message: "svn was not found in your PATH, skipping source download".to_string(),
@@ -52,7 +57,10 @@ impl SvnDownloader {
if let Some(vcs_repo) = repo.as_any().downcast_ref::<VcsRepository>() {
let repo_config = vcs_repo.get_repo_config();
if repo_config.contains_key("svn-cache-credentials") {
- if let Some(val) = repo_config.get("svn-cache-credentials").and_then(|v| v.as_bool()) {
+ if let Some(val) = repo_config
+ .get("svn-cache-credentials")
+ .and_then(|v| v.as_bool())
+ {
self.cache_credentials = val;
}
}
@@ -97,7 +105,12 @@ impl SvnDownloader {
.into());
}
- let util = SvnUtil::new(url, &*self.inner.io, &self.inner.config, &self.inner.process);
+ let util = SvnUtil::new(
+ url,
+ &*self.inner.io,
+ &self.inner.config,
+ &self.inner.process,
+ );
let mut flags: Vec<String> = vec![];
if version_compare(&util.binary_version().unwrap_or_default(), "1.7.0", ">=") {
flags.push("--ignore-ancestry".to_string());
@@ -271,9 +284,7 @@ impl SvnDownloader {
" n - abort the {} and let you manually clean things up",
if update { "update" } else { "uninstall" }
))),
- Box::new(PhpMixed::String(
- " v - view modified files".to_string(),
- )),
+ Box::new(PhpMixed::String(" v - view modified files".to_string())),
Box::new(PhpMixed::String(" ? - print help".to_string())),
]),
true,
@@ -355,11 +366,7 @@ impl SvnDownloader {
util.execute_local(command.clone(), path, None, self.inner.io.is_verbose())
.map_err(|e| {
RuntimeException {
- message: format!(
- "Failed to execute {}\n\n{}",
- command.join(" "),
- e
- ),
+ message: format!("Failed to execute {}\n\n{}", command.join(" "), e),
code: 0,
}
.into()
@@ -375,9 +382,7 @@ impl SvnDownloader {
pub(crate) fn discard_changes(&self, path: &str) -> anyhow::Result<Box<dyn PromiseInterface>> {
let mut output = String::new();
if self.inner.process.execute(
- &["svn", "revert", "-R", "."]
- .map(|s| s.to_string())
- .to_vec(),
+ &["svn", "revert", "-R", "."].map(|s| s.to_string()).to_vec(),
&mut output,
Some(path.to_string()),
) != 0
diff --git a/crates/shirabe/src/downloader/tar_downloader.rs b/crates/shirabe/src/downloader/tar_downloader.rs
index 4b13f3b..c327ca0 100644
--- a/crates/shirabe/src/downloader/tar_downloader.rs
+++ b/crates/shirabe/src/downloader/tar_downloader.rs
@@ -1,10 +1,10 @@
//! ref: composer/src/Composer/Downloader/TarDownloader.php
-use anyhow::Result;
-use shirabe_php_shim::PharData;
-use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use crate::downloader::archive_downloader::ArchiveDownloader;
use crate::package::package_interface::PackageInterface;
+use anyhow::Result;
+use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
+use shirabe_php_shim::PharData;
#[derive(Debug)]
pub struct TarDownloader {
@@ -12,7 +12,12 @@ pub struct TarDownloader {
}
impl TarDownloader {
- pub(crate) fn extract(&self, package: &dyn PackageInterface, file: &str, path: &str) -> Result<Box<dyn PromiseInterface>> {
+ pub(crate) fn extract(
+ &self,
+ package: &dyn PackageInterface,
+ file: &str,
+ path: &str,
+ ) -> Result<Box<dyn PromiseInterface>> {
let archive = PharData::new(file.to_string());
archive.extract_to(path, None, true);
diff --git a/crates/shirabe/src/downloader/vcs_downloader.rs b/crates/shirabe/src/downloader/vcs_downloader.rs
index 3fb305f..37954d2 100644
--- a/crates/shirabe/src/downloader/vcs_downloader.rs
+++ b/crates/shirabe/src/downloader/vcs_downloader.rs
@@ -4,9 +4,8 @@ use anyhow::Result;
use indexmap::IndexMap;
use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use shirabe_php_shim::{
- array_map, array_shift, count, explode, get_class, implode, rawurldecode, realpath,
- str_replace, strlen, strpos, substr, trim, InvalidArgumentException, PhpMixed,
- RuntimeException,
+ InvalidArgumentException, PhpMixed, RuntimeException, array_map, array_shift, count, explode,
+ get_class, implode, rawurldecode, realpath, str_replace, strlen, strpos, substr, trim,
};
use crate::config::Config;
@@ -91,11 +90,7 @@ impl VcsDownloader {
}
if self.io.is_debug() {
self.io.write_error(
- PhpMixed::String(format!(
- "Failed: [{}] {}",
- get_class(&e),
- e,
- )),
+ PhpMixed::String(format!("Failed: [{}] {}", get_class(&e), e,)),
true,
IOInterface::NORMAL,
);
@@ -183,7 +178,10 @@ impl VcsDownloader {
}
self.io.write_error(
- PhpMixed::String(format!(" - {}: ", InstallOperation::format(package, false))),
+ PhpMixed::String(format!(
+ " - {}: ",
+ InstallOperation::format(package, false)
+ )),
false,
IOInterface::NORMAL,
);
@@ -203,11 +201,7 @@ impl VcsDownloader {
}
if self.io.is_debug() {
self.io.write_error(
- PhpMixed::String(format!(
- "Failed: [{}] {}",
- get_class(&e),
- e,
- )),
+ PhpMixed::String(format!("Failed: [{}] {}", get_class(&e), e,)),
true,
IOInterface::NORMAL,
);
@@ -285,11 +279,7 @@ impl VcsDownloader {
}
if self.io.is_debug() {
self.io.write_error(
- PhpMixed::String(format!(
- "Failed: [{}] {}",
- get_class(&e),
- e,
- )),
+ PhpMixed::String(format!("Failed: [{}] {}", get_class(&e), e,)),
true,
IOInterface::NORMAL,
);
@@ -364,7 +354,10 @@ impl VcsDownloader {
path: &str,
) -> Result<Box<dyn PromiseInterface>> {
self.io.write_error(
- PhpMixed::String(format!(" - {}", UninstallOperation::format(package, false))),
+ PhpMixed::String(format!(
+ " - {}",
+ UninstallOperation::format(package, false)
+ )),
true,
IOInterface::NORMAL,
);
@@ -372,24 +365,22 @@ impl VcsDownloader {
let promise = self.filesystem.remove_directory_async(path);
let path = path.to_string();
- Ok(promise.then(Box::new(move |result: PhpMixed| -> Result<()> {
- let result_bool = result.as_bool().unwrap_or(false);
- if !result_bool {
- return Err(RuntimeException {
- message: format!("Could not completely delete {}, aborting.", path),
- code: 0,
+ Ok(
+ promise.then(Box::new(move |result: PhpMixed| -> Result<()> {
+ let result_bool = result.as_bool().unwrap_or(false);
+ if !result_bool {
+ return Err(RuntimeException {
+ message: format!("Could not completely delete {}, aborting.", path),
+ code: 0,
+ }
+ .into());
}
- .into());
- }
- Ok(())
- })))
+ Ok(())
+ })),
+ )
}
- pub fn get_vcs_reference(
- &self,
- package: &dyn PackageInterface,
- path: &str,
- ) -> Option<String> {
+ pub fn get_vcs_reference(&self, package: &dyn PackageInterface, path: &str) -> Option<String> {
let parser = VersionParser::new();
let guesser = VersionGuesser::new(&self.config, &self.process, &parser, &*self.io);
let dumper = ArrayDumper::new();
diff --git a/crates/shirabe/src/downloader/xz_downloader.rs b/crates/shirabe/src/downloader/xz_downloader.rs
index a53c9c6..0c5d876 100644
--- a/crates/shirabe/src/downloader/xz_downloader.rs
+++ b/crates/shirabe/src/downloader/xz_downloader.rs
@@ -1,9 +1,9 @@
//! ref: composer/src/Composer/Downloader/XzDownloader.php
-use anyhow::{bail, Result};
-use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use crate::downloader::archive_downloader::ArchiveDownloader;
use crate::package::package_interface::PackageInterface;
+use anyhow::{Result, bail};
+use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
#[derive(Debug)]
pub struct XzDownloader {
@@ -11,7 +11,12 @@ pub struct XzDownloader {
}
impl XzDownloader {
- pub(crate) fn extract(&self, package: &dyn PackageInterface, file: &str, path: &str) -> Result<Box<dyn PromiseInterface>> {
+ pub(crate) fn extract(
+ &self,
+ package: &dyn PackageInterface,
+ file: &str,
+ path: &str,
+ ) -> Result<Box<dyn PromiseInterface>> {
let command = vec!["tar", "-xJf", file, "-C", path];
let mut ignored_output = String::new();
@@ -19,7 +24,11 @@ impl XzDownloader {
return Ok(shirabe_external_packages::react::promise::resolve(None));
}
- let process_error = format!("Failed to execute {}\n\n{}", command.join(" "), self.inner.process.get_error_output());
+ let process_error = format!(
+ "Failed to execute {}\n\n{}",
+ command.join(" "),
+ self.inner.process.get_error_output()
+ );
bail!(process_error);
}
diff --git a/crates/shirabe/src/downloader/zip_downloader.rs b/crates/shirabe/src/downloader/zip_downloader.rs
index 71a23b8..ecb7821 100644
--- a/crates/shirabe/src/downloader/zip_downloader.rs
+++ b/crates/shirabe/src/downloader/zip_downloader.rs
@@ -1,23 +1,22 @@
//! ref: composer/src/Composer/Downloader/ZipDownloader.php
-use std::sync::Mutex;
+use crate::downloader::archive_downloader::ArchiveDownloader;
+use crate::downloader::file_downloader::FileDownloader;
+use crate::package::package_interface::PackageInterface;
+use crate::util::ini_helper::IniHelper;
+use crate::util::platform::Platform;
use anyhow::Result;
use indexmap::IndexMap;
+use shirabe_external_packages::composer::pcre::preg::Preg;
+use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
+use shirabe_external_packages::symfony::component::process::executable_finder::ExecutableFinder;
+use shirabe_external_packages::symfony::component::process::process::Process;
use shirabe_php_shim::{
+ DIRECTORY_SEPARATOR, ErrorException, RuntimeException, UnexpectedValueException, ZipArchive,
bin2hex, class_exists, file_exists, file_get_contents, filesize, function_exists, hash_file,
is_file, json_encode, random_int, version_compare,
- ErrorException, RuntimeException, UnexpectedValueException, ZipArchive,
- DIRECTORY_SEPARATOR,
};
-use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
-use shirabe_external_packages::symfony::component::process::executable_finder::ExecutableFinder;
-use shirabe_external_packages::symfony::component::process::process::Process;
-use shirabe_external_packages::composer::pcre::preg::Preg;
-use crate::downloader::archive_downloader::ArchiveDownloader;
-use crate::downloader::file_downloader::FileDownloader;
-use crate::package::package_interface::PackageInterface;
-use crate::util::ini_helper::IniHelper;
-use crate::util::platform::Platform;
+use std::sync::Mutex;
static UNZIP_COMMANDS: Mutex<Option<Vec<Vec<String>>>> = Mutex::new(None);
static HAS_ZIP_ARCHIVE: Mutex<Option<bool>> = Mutex::new(None);
@@ -46,22 +45,61 @@ impl ZipDownloader {
let commands = unzip_commands.as_mut().unwrap();
if Platform::is_windows() {
if let Some(cmd) = finder.find("7z", None, &[r"C:\Program Files\7-Zip"]) {
- commands.push(vec!["7z".to_string(), cmd, "x".to_string(), "-bb0".to_string(), "-y".to_string(), "%file%".to_string(), "-o%path%".to_string()]);
+ commands.push(vec![
+ "7z".to_string(),
+ cmd,
+ "x".to_string(),
+ "-bb0".to_string(),
+ "-y".to_string(),
+ "%file%".to_string(),
+ "-o%path%".to_string(),
+ ]);
}
}
if let Some(cmd) = finder.find("unzip", None, &[]) {
- commands.push(vec!["unzip".to_string(), cmd, "-qq".to_string(), "%file%".to_string(), "-d".to_string(), "%path%".to_string()]);
+ commands.push(vec![
+ "unzip".to_string(),
+ cmd,
+ "-qq".to_string(),
+ "%file%".to_string(),
+ "-d".to_string(),
+ "%path%".to_string(),
+ ]);
}
if !Platform::is_windows() {
if let Some(cmd) = finder.find("7z", None, &[]) {
// 7z linux/macOS support is only used if unzip is not present
- commands.push(vec!["7z".to_string(), cmd, "x".to_string(), "-bb0".to_string(), "-y".to_string(), "%file%".to_string(), "-o%path%".to_string()]);
+ commands.push(vec![
+ "7z".to_string(),
+ cmd,
+ "x".to_string(),
+ "-bb0".to_string(),
+ "-y".to_string(),
+ "%file%".to_string(),
+ "-o%path%".to_string(),
+ ]);
} else if let Some(cmd) = finder.find("7zz", None, &[]) {
// 7zz linux/macOS support is only used if unzip is not present
- commands.push(vec!["7zz".to_string(), cmd, "x".to_string(), "-bb0".to_string(), "-y".to_string(), "%file%".to_string(), "-o%path%".to_string()]);
+ commands.push(vec![
+ "7zz".to_string(),
+ cmd,
+ "x".to_string(),
+ "-bb0".to_string(),
+ "-y".to_string(),
+ "%file%".to_string(),
+ "-o%path%".to_string(),
+ ]);
} else if let Some(cmd) = finder.find("7za", None, &[]) {
// 7za linux/macOS support is only used if unzip is not present
- commands.push(vec!["7za".to_string(), cmd, "x".to_string(), "-bb0".to_string(), "-y".to_string(), "%file%".to_string(), "-o%path%".to_string()]);
+ commands.push(vec![
+ "7za".to_string(),
+ cmd,
+ "x".to_string(),
+ "-bb0".to_string(),
+ "-y".to_string(),
+ "%file%".to_string(),
+ "-o%path%".to_string(),
+ ]);
}
}
}
@@ -80,16 +118,30 @@ impl ZipDownloader {
}
let has_zip_archive = HAS_ZIP_ARCHIVE.lock().unwrap().unwrap_or(false);
- let unzip_commands_empty = UNZIP_COMMANDS.lock().unwrap().as_ref().map_or(true, |v| v.is_empty());
+ let unzip_commands_empty = UNZIP_COMMANDS
+ .lock()
+ .unwrap()
+ .as_ref()
+ .map_or(true, |v| v.is_empty());
if !has_zip_archive && unzip_commands_empty {
let ini_message = IniHelper::get_message();
let error = if proc_open_missing {
- format!("The zip extension is missing and unzip/7z commands cannot be called as proc_open is disabled, skipping.\n{}", ini_message)
+ format!(
+ "The zip extension is missing and unzip/7z commands cannot be called as proc_open is disabled, skipping.\n{}",
+ ini_message
+ )
} else {
- format!("The zip extension and unzip/7z commands are both missing, skipping.\n{}", ini_message)
+ format!(
+ "The zip extension and unzip/7z commands are both missing, skipping.\n{}",
+ ini_message
+ )
};
- return Err(RuntimeException { message: error, code: 0 }.into());
+ return Err(RuntimeException {
+ message: error,
+ code: 0,
+ }
+ .into());
}
{
@@ -111,7 +163,9 @@ impl ZipDownloader {
}
}
- self.inner.inner.download(package, path, prev_package, output)
+ self.inner
+ .inner
+ .download(package, path, prev_package, output)
}
fn extract_with_system_unzip(
@@ -124,7 +178,11 @@ impl ZipDownloader {
let is_last_chance = !HAS_ZIP_ARCHIVE.lock().unwrap().unwrap_or(false);
- let unzip_commands_empty = UNZIP_COMMANDS.lock().unwrap().as_ref().map_or(true, |v| v.is_empty());
+ let unzip_commands_empty = UNZIP_COMMANDS
+ .lock()
+ .unwrap()
+ .as_ref()
+ .map_or(true, |v| v.is_empty());
if unzip_commands_empty {
return self.extract_with_zip_archive(package, file, path);
}
@@ -136,14 +194,19 @@ impl ZipDownloader {
// see https://github.com/composer/composer/issues/10058
("%file%", file.replace('/', DIRECTORY_SEPARATOR)),
("%path%", path.replace('/', DIRECTORY_SEPARATOR)),
- ].into_iter().collect();
- let command: Vec<String> = command_spec[1..].iter().map(|value| {
- let mut v = value.clone();
- for (from, to) in &map {
- v = v.replace(from, to.as_str());
- }
- v
- }).collect();
+ ]
+ .into_iter()
+ .collect();
+ let command: Vec<String> = command_spec[1..]
+ .iter()
+ .map(|value| {
+ let mut v = value.clone();
+ for (from, to) in &map {
+ v = v.replace(from, to.as_str());
+ }
+ v
+ })
+ .collect();
if !*WARNED_7ZIP_LINUX.lock().unwrap()
&& !Platform::is_windows()
@@ -151,8 +214,16 @@ impl ZipDownloader {
{
*WARNED_7ZIP_LINUX.lock().unwrap() = true;
let mut output = String::new();
- if self.inner.inner.process.execute(&[command_spec[1].as_str()], &mut output) == 0 {
- if let Some(m) = Preg::is_match_strict_groups(r"^\s*7-Zip(?:\s\[64\])?\s([0-9.]+)", &output) {
+ if self
+ .inner
+ .inner
+ .process
+ .execute(&[command_spec[1].as_str()], &mut output)
+ == 0
+ {
+ if let Some(m) =
+ Preg::is_match_strict_groups(r"^\s*7-Zip(?:\s\[64\])?\s([0-9.]+)", &output)
+ {
if version_compare(&m[1], "21.01", "<") {
self.inner.inner.io.write_error(&format!(
" <warning>Unzipping using {} {} may result in incorrect file permissions. Install {} 21.01+ or unzip to ensure you get correct permissions.</warning>",
@@ -180,21 +251,44 @@ impl ZipDownloader {
} else {
io.write_error(&format!(" <warning>{}</warning>", process_error));
io.write_error(" The archive may contain identical file names with different capitalization (which fails on case insensitive filesystems)");
- io.write_error(&format!(" Unzip with {} command failed, falling back to ZipArchive class", executable));
+ io.write_error(&format!(
+ " Unzip with {} command failed, falling back to ZipArchive class",
+ executable
+ ));
- if Platform::get_env("GITHUB_ACTIONS").is_some() && Platform::get_env("COMPOSER_TESTS_ARE_RUNNING").is_none() {
+ if Platform::get_env("GITHUB_ACTIONS").is_some()
+ && Platform::get_env("COMPOSER_TESTS_ARE_RUNNING").is_none()
+ {
io.write_error(" <warning>Additional debug info, please report to https://github.com/composer/composer/issues/11148 if you see this:</warning>");
io.write_error(&format!("File size: {}", filesize(file).unwrap_or(0)));
- io.write_error(&format!("File SHA1: {}", hash_file("sha1", file).unwrap_or_default()));
+ io.write_error(&format!(
+ "File SHA1: {}",
+ hash_file("sha1", file).unwrap_or_default()
+ ));
let content = file_get_contents(file).unwrap_or_default();
let bytes = content.as_bytes();
- io.write_error(&format!("First 100 bytes (hex): {}", bin2hex(&bytes[..bytes.len().min(100)])));
+ io.write_error(&format!(
+ "First 100 bytes (hex): {}",
+ bin2hex(&bytes[..bytes.len().min(100)])
+ ));
let len = bytes.len();
- io.write_error(&format!("Last 100 bytes (hex): {}", bin2hex(&bytes[len.saturating_sub(100)..])));
+ io.write_error(&format!(
+ "Last 100 bytes (hex): {}",
+ bin2hex(&bytes[len.saturating_sub(100)..])
+ ));
if package.get_dist_url().map_or(false, |u| !u.is_empty()) {
- io.write_error(&format!("Origin URL: {}", self.inner.inner.process_url(package, &package.get_dist_url().unwrap_or_default())));
+ io.write_error(&format!(
+ "Origin URL: {}",
+ self.inner
+ .inner
+ .process_url(package, &package.get_dist_url().unwrap_or_default())
+ ));
let headers = FileDownloader::response_headers.lock().unwrap();
- io.write_error(&format!("Response Headers: {}", json_encode(&shirabe_php_shim::PhpMixed::Null).unwrap_or_else(|| "[]".to_string())));
+ io.write_error(&format!(
+ "Response Headers: {}",
+ json_encode(&shirabe_php_shim::PhpMixed::Null)
+ .unwrap_or_else(|| "[]".to_string())
+ ));
}
}
}
@@ -241,7 +335,10 @@ impl ZipDownloader {
file: &str,
path: &str,
) -> Result<Box<dyn PromiseInterface>> {
- let mut zip_archive = self.zip_archive_object.take().unwrap_or_else(ZipArchive::new);
+ let mut zip_archive = self
+ .zip_archive_object
+ .take()
+ .unwrap_or_else(ZipArchive::new);
let result: Result<Box<dyn PromiseInterface>> = (|| {
let retval = if !file_exists(file) || filesize(file).map_or(true, |s| s == 0) {
@@ -259,10 +356,15 @@ impl ZipDownloader {
let mut files_to_inspect = total_files.min(5);
let mut i: i64 = 0;
while i < files_to_inspect {
- let stat_index = if inspect_all { i } else { random_int(0, total_files - 1) };
+ let stat_index = if inspect_all {
+ i
+ } else {
+ random_int(0, total_files - 1)
+ };
if let Some(stat) = zip_archive.stat_index(stat_index) {
let size = stat.get("size").and_then(|v| v.as_int()).unwrap_or(0);
- let comp_size = stat.get("comp_size").and_then(|v| v.as_int()).unwrap_or(0);
+ let comp_size =
+ stat.get("comp_size").and_then(|v| v.as_int()).unwrap_or(0);
total_size += size;
if !inspect_all && size > comp_size * 200 {
total_size = 0;
@@ -305,7 +407,8 @@ impl ZipDownloader {
return Err(UnexpectedValueException {
message: self.get_error_message(code, file).trim_end().to_string(),
code,
- }.into());
+ }
+ .into());
}
})();
@@ -345,8 +448,14 @@ impl ZipDownloader {
ZipArchive::ER_OPEN => format!("Can't open zip file: {}", file),
ZipArchive::ER_READ => format!("Zip read error ({})", file),
ZipArchive::ER_SEEK => format!("Zip seek error ({})", file),
- -1 => format!("'{}' is a corrupted zip archive (0 bytes), try again.", file),
- _ => format!("'{}' is not a valid zip archive, got error code: {}", file, retval),
+ -1 => format!(
+ "'{}' is a corrupted zip archive (0 bytes), try again.",
+ file
+ ),
+ _ => format!(
+ "'{}' is not a valid zip archive, got error code: {}",
+ file, retval
+ ),
}
}
}
diff --git a/crates/shirabe/src/event_dispatcher/event_dispatcher.rs b/crates/shirabe/src/event_dispatcher/event_dispatcher.rs
index 93cc885..6615bd9 100644
--- a/crates/shirabe/src/event_dispatcher/event_dispatcher.rs
+++ b/crates/shirabe/src/event_dispatcher/event_dispatcher.rs
@@ -10,13 +10,13 @@ use shirabe_external_packages::symfony::component::console::output::console_outp
use shirabe_external_packages::symfony::component::process::executable_finder::ExecutableFinder;
use shirabe_external_packages::symfony::component::process::php_executable_finder::PhpExecutableFinder;
use shirabe_php_shim::{
- array_pop, array_push, array_search_in_vec, array_splice, class_exists, count_mixed,
- defined, file_exists, get_class, hash, implode, ini_get, is_a, is_array, is_callable,
- is_object, is_string, krsort, max_i64, method_exists, preg_quote, realpath, spl_autoload_functions,
- spl_autoload_register, spl_autoload_unregister, spl_object_hash, sprintf, str_contains,
- str_ends_with, str_replace, str_starts_with, strlen, strpos, strtoupper, substr, trim,
- Exception, InvalidArgumentException, LogicException, PhpMixed, RuntimeException, PATH_SEPARATOR,
- PHP_VERSION_ID,
+ Exception, InvalidArgumentException, LogicException, PATH_SEPARATOR, PHP_VERSION_ID, PhpMixed,
+ RuntimeException, array_pop, array_push, array_search_in_vec, array_splice, class_exists,
+ count_mixed, defined, file_exists, get_class, hash, implode, ini_get, is_a, is_array,
+ is_callable, is_object, is_string, krsort, max_i64, method_exists, preg_quote, realpath,
+ spl_autoload_functions, spl_autoload_register, spl_autoload_unregister, spl_object_hash,
+ sprintf, str_contains, str_ends_with, str_replace, str_starts_with, strlen, strpos, strtoupper,
+ substr, trim,
};
use crate::autoload::class_loader::ClassLoader;
@@ -257,11 +257,7 @@ impl EventDispatcher {
result
}
- fn do_dispatch_body(
- &mut self,
- event: &Event,
- listeners: Vec<Callable>,
- ) -> anyhow::Result<i64> {
+ fn do_dispatch_body(&mut self, event: &Event, listeners: Vec<Callable>) -> anyhow::Result<i64> {
let mut return_max = 0_i64;
for callable in listeners {
let mut r#return: i64 = 0;
@@ -271,8 +267,8 @@ impl EventDispatcher {
let mut callable = callable;
if let Callable::String(ref s) = callable {
if str_contains(s, "@no_additional_args") {
- let replaced =
- Preg::replace("{ ?@no_additional_args}", "", s).unwrap_or_else(|_| s.clone());
+ let replaced = Preg::replace("{ ?@no_additional_args}", "", s)
+ .unwrap_or_else(|_| s.clone());
callable = Callable::String(replaced);
additional_args = Vec::new();
}
@@ -337,65 +333,66 @@ impl EventDispatcher {
}
// TODO(plugin): actually invoke callable with $event and inspect result
r#return = 0;
- } else { match callable {
- Callable::String(ref callable_str) if self.is_composer_script(callable_str) => {
- self.io.write_error(
- PhpMixed::String(sprintf(
- "> %s: %s",
- &[
- PhpMixed::String(formatted_event_name_with_args.clone()),
- PhpMixed::String(callable_str.clone()),
- ],
- )),
- true,
- <dyn IOInterface>::VERBOSE,
- );
+ } else {
+ match callable {
+ Callable::String(ref callable_str) if self.is_composer_script(callable_str) => {
+ self.io.write_error(
+ PhpMixed::String(sprintf(
+ "> %s: %s",
+ &[
+ PhpMixed::String(formatted_event_name_with_args.clone()),
+ PhpMixed::String(callable_str.clone()),
+ ],
+ )),
+ true,
+ <dyn IOInterface>::VERBOSE,
+ );
- let mut script: Vec<String> = substr(callable_str, 1, None)
- .split(' ')
- .map(|s| s.to_string())
- .collect();
- let script_name = script[0].clone();
- script.remove(0);
+ let mut script: Vec<String> = substr(callable_str, 1, None)
+ .split(' ')
+ .map(|s| s.to_string())
+ .collect();
+ let script_name = script[0].clone();
+ script.remove(0);
- let args: Vec<String>;
- if let Some(index) = array_search_in_vec("@additional_args", &script) {
- let _ = array_splice::<String>(&mut script, index, 0, &additional_args);
- args = script.clone();
- } else {
- let mut merged = script.clone();
- merged.extend(additional_args.clone());
- args = merged;
- }
- let mut flags = event.get_flags().clone();
- if flags.contains_key("script-alias-input") {
- let args_string = script
- .iter()
- .map(|arg| ProcessExecutor::escape(arg))
- .collect::<Vec<_>>()
- .join(" ");
- let existing = flags
- .get("script-alias-input")
- .and_then(|v| v.as_string())
- .unwrap_or("")
- .to_string();
- flags.insert(
- "script-alias-input".to_string(),
- PhpMixed::String(format!("{} {}", args_string, existing)),
- );
- }
- if strpos(callable_str, "@composer ") == Some(0) {
- let exec = format!(
- "{} {} {}",
- self.get_php_exec_command()?,
- ProcessExecutor::escape(
- &Platform::get_env("COMPOSER_BINARY").unwrap_or_default()
- ),
- args.join(" ")
- );
- let exit_code = self.execute_tty(&exec)?;
- if exit_code != 0 {
- self.io.write_error(
+ let args: Vec<String>;
+ if let Some(index) = array_search_in_vec("@additional_args", &script) {
+ let _ = array_splice::<String>(&mut script, index, 0, &additional_args);
+ args = script.clone();
+ } else {
+ let mut merged = script.clone();
+ merged.extend(additional_args.clone());
+ args = merged;
+ }
+ let mut flags = event.get_flags().clone();
+ if flags.contains_key("script-alias-input") {
+ let args_string = script
+ .iter()
+ .map(|arg| ProcessExecutor::escape(arg))
+ .collect::<Vec<_>>()
+ .join(" ");
+ let existing = flags
+ .get("script-alias-input")
+ .and_then(|v| v.as_string())
+ .unwrap_or("")
+ .to_string();
+ flags.insert(
+ "script-alias-input".to_string(),
+ PhpMixed::String(format!("{} {}", args_string, existing)),
+ );
+ }
+ if strpos(callable_str, "@composer ") == Some(0) {
+ let exec = format!(
+ "{} {} {}",
+ self.get_php_exec_command()?,
+ ProcessExecutor::escape(
+ &Platform::get_env("COMPOSER_BINARY").unwrap_or_default()
+ ),
+ args.join(" ")
+ );
+ let exit_code = self.execute_tty(&exec)?;
+ if exit_code != 0 {
+ self.io.write_error(
PhpMixed::String(sprintf(
&format!(
"<error>Script %s handling the %s event returned with error code {}</error>",
@@ -410,26 +407,26 @@ impl EventDispatcher {
<dyn IOInterface>::QUIET,
);
- return Err(anyhow::anyhow!(ScriptExecutionException(
- RuntimeException {
- message: format!(
- "Error Output: {}",
- self.process.get_error_output()
- ),
- code: exit_code,
- }
- )));
- }
- } else {
- if self
- .get_listeners(&Event::new(
- script_name.clone(),
- Vec::new(),
- IndexMap::new(),
- ))
- .is_empty()
- {
- self.io.write_error(
+ return Err(anyhow::anyhow!(ScriptExecutionException(
+ RuntimeException {
+ message: format!(
+ "Error Output: {}",
+ self.process.get_error_output()
+ ),
+ code: exit_code,
+ }
+ )));
+ }
+ } else {
+ if self
+ .get_listeners(&Event::new(
+ script_name.clone(),
+ Vec::new(),
+ IndexMap::new(),
+ ))
+ .is_empty()
+ {
+ self.io.write_error(
PhpMixed::String(sprintf(
"<warning>You made a reference to a non-existent script %s</warning>",
&[PhpMixed::String(callable_str.clone())],
@@ -437,53 +434,56 @@ impl EventDispatcher {
true,
<dyn IOInterface>::QUIET,
);
- }
+ }
- let composer_full = self.composer_as_full_or_panic();
- let mut script_event = ScriptEvent::new(
- script_name.clone(),
- composer_full,
- self.io_clone(),
- // event.isDevMode() is only on InstallerEvent/ScriptEvent/PackageEvent
- // TODO(plugin): proper dev_mode propagation when polymorphic event is supported
- false,
- args,
- flags,
- );
- // TODO(plugin): script_event.set_originating_event(event.clone())
- match self.dispatch(Some(&script_name), Some(Event::new(
- script_name.clone(),
- script_event.inner_args_for_dispatch(),
- script_event.inner_flags_for_dispatch(),
- ))) {
- Ok(v) => r#return = v,
- Err(e) => {
- if e.downcast_ref::<ScriptExecutionException>().is_some() {
- self.io.write_error(
- PhpMixed::String(sprintf(
- "<error>Script %s was called via %s</error>",
- &[
- PhpMixed::String(callable_str.clone()),
- PhpMixed::String(event.get_name().to_string()),
- ],
- )),
- true,
- <dyn IOInterface>::QUIET,
- );
+ let composer_full = self.composer_as_full_or_panic();
+ let mut script_event = ScriptEvent::new(
+ script_name.clone(),
+ composer_full,
+ self.io_clone(),
+ // event.isDevMode() is only on InstallerEvent/ScriptEvent/PackageEvent
+ // TODO(plugin): proper dev_mode propagation when polymorphic event is supported
+ false,
+ args,
+ flags,
+ );
+ // TODO(plugin): script_event.set_originating_event(event.clone())
+ match self.dispatch(
+ Some(&script_name),
+ Some(Event::new(
+ script_name.clone(),
+ script_event.inner_args_for_dispatch(),
+ script_event.inner_flags_for_dispatch(),
+ )),
+ ) {
+ Ok(v) => r#return = v,
+ Err(e) => {
+ if e.downcast_ref::<ScriptExecutionException>().is_some() {
+ self.io.write_error(
+ PhpMixed::String(sprintf(
+ "<error>Script %s was called via %s</error>",
+ &[
+ PhpMixed::String(callable_str.clone()),
+ PhpMixed::String(event.get_name().to_string()),
+ ],
+ )),
+ true,
+ <dyn IOInterface>::QUIET,
+ );
+ }
+ return Err(e);
}
- return Err(e);
}
}
}
- }
- Callable::String(ref callable_str) if self.is_php_script(callable_str) => {
- let pos = strpos(callable_str, "::").unwrap_or(0) as i64;
- let class_name = substr(callable_str, 0, Some(pos));
- let method_name = substr(callable_str, pos + 2, None);
+ Callable::String(ref callable_str) if self.is_php_script(callable_str) => {
+ let pos = strpos(callable_str, "::").unwrap_or(0) as i64;
+ let class_name = substr(callable_str, 0, Some(pos));
+ let method_name = substr(callable_str, pos + 2, None);
- self.make_autoloader(event, &Callable::String(callable_str.clone()));
- if !class_exists(&class_name) {
- self.io.write_error(
+ self.make_autoloader(event, &Callable::String(callable_str.clone()));
+ if !class_exists(&class_name) {
+ self.io.write_error(
PhpMixed::String(format!(
"<warning>Class {} is not autoloadable, can not call {} script</warning>",
class_name,
@@ -492,10 +492,10 @@ impl EventDispatcher {
true,
<dyn IOInterface>::QUIET,
);
- continue;
- }
- if !is_callable(&PhpMixed::String(callable_str.clone())) {
- self.io.write_error(
+ continue;
+ }
+ if !is_callable(&PhpMixed::String(callable_str.clone())) {
+ self.io.write_error(
PhpMixed::String(format!(
"<warning>Method {} is not callable, can not call {} script</warning>",
callable_str,
@@ -504,46 +504,46 @@ impl EventDispatcher {
true,
<dyn IOInterface>::QUIET,
);
- continue;
- }
-
- match self.execute_event_php_script(&class_name, &method_name, event) {
- Ok(v) => {
- r#return = if let PhpMixed::Bool(false) = v { 1 } else { 0 };
+ continue;
}
- Err(e) => {
- let message =
- "Script %s handling the %s event terminated with an exception";
- self.io.write_error(
- PhpMixed::String(format!(
- "<error>{}</error>",
- sprintf(
- message,
- &[
- PhpMixed::String(callable_str.clone()),
- PhpMixed::String(event.get_name().to_string()),
- ],
- )
- )),
- true,
- <dyn IOInterface>::QUIET,
- );
- return Err(e);
+
+ match self.execute_event_php_script(&class_name, &method_name, event) {
+ Ok(v) => {
+ r#return = if let PhpMixed::Bool(false) = v { 1 } else { 0 };
+ }
+ Err(e) => {
+ let message =
+ "Script %s handling the %s event terminated with an exception";
+ self.io.write_error(
+ PhpMixed::String(format!(
+ "<error>{}</error>",
+ sprintf(
+ message,
+ &[
+ PhpMixed::String(callable_str.clone()),
+ PhpMixed::String(event.get_name().to_string()),
+ ],
+ )
+ )),
+ true,
+ <dyn IOInterface>::QUIET,
+ );
+ return Err(e);
+ }
}
}
- }
- Callable::String(ref callable_str) if self.is_command_class(callable_str) => {
- let class_name = callable_str.clone();
+ Callable::String(ref callable_str) if self.is_command_class(callable_str) => {
+ let class_name = callable_str.clone();
- self.make_autoloader(
- event,
- &Callable::ArrayCallable(
- Box::new(PhpMixed::String(callable_str.clone())),
- "run".to_string(),
- ),
- );
- if !class_exists(&class_name) {
- self.io.write_error(
+ self.make_autoloader(
+ event,
+ &Callable::ArrayCallable(
+ Box::new(PhpMixed::String(callable_str.clone())),
+ "run".to_string(),
+ ),
+ );
+ if !class_exists(&class_name) {
+ self.io.write_error(
PhpMixed::String(format!(
"<warning>Class {} is not autoloadable, can not call {} script</warning>",
class_name,
@@ -552,14 +552,14 @@ impl EventDispatcher {
true,
<dyn IOInterface>::QUIET,
);
- continue;
- }
- if !is_a(
- &PhpMixed::String(class_name.clone()),
- "Symfony\\Component\\Console\\Command\\Command",
- true,
- ) {
- self.io.write_error(
+ continue;
+ }
+ if !is_a(
+ &PhpMixed::String(class_name.clone()),
+ "Symfony\\Component\\Console\\Command\\Command",
+ true,
+ ) {
+ self.io.write_error(
PhpMixed::String(format!(
"<warning>Class {} does not extend Symfony\\Component\\Console\\Command\\Command, can not call {} script</warning>",
class_name,
@@ -568,13 +568,13 @@ impl EventDispatcher {
true,
<dyn IOInterface>::QUIET,
);
- continue;
- }
- if defined(&format!(
- "Composer\\Script\\ScriptEvents::{}",
- str_replace("-", "_", &strtoupper(event.get_name()))
- )) {
- self.io.write_error(
+ continue;
+ }
+ if defined(&format!(
+ "Composer\\Script\\ScriptEvents::{}",
+ str_replace("-", "_", &strtoupper(event.get_name()))
+ )) {
+ self.io.write_error(
PhpMixed::String(format!(
"<warning>You cannot bind {} to a Command class, use a non-reserved name</warning>",
event.get_name()
@@ -582,239 +582,241 @@ impl EventDispatcher {
true,
<dyn IOInterface>::QUIET,
);
- continue;
- }
+ continue;
+ }
- let mut app = Application::new();
- app.set_catch_exceptions(false);
- if method_exists(
- &PhpMixed::String("Application".to_string()),
- "setCatchErrors",
- ) {
- app.set_catch_errors(false);
- }
- app.set_auto_exit(false);
- // TODO(plugin): instantiate command class dynamically: `new $className($event->getName())`
- let cmd = Command::new(event.get_name().to_string());
- if method_exists(&PhpMixed::String("Application".to_string()), "addCommand") {
- app.add_command(cmd.clone());
- } else {
- // Compatibility layer for symfony/console <7.4
- app.add(cmd.clone());
+ let mut app = Application::new();
+ app.set_catch_exceptions(false);
+ if method_exists(
+ &PhpMixed::String("Application".to_string()),
+ "setCatchErrors",
+ ) {
+ app.set_catch_errors(false);
+ }
+ app.set_auto_exit(false);
+ // TODO(plugin): instantiate command class dynamically: `new $className($event->getName())`
+ let cmd = Command::new(event.get_name().to_string());
+ if method_exists(&PhpMixed::String("Application".to_string()), "addCommand")
+ {
+ app.add_command(cmd.clone());
+ } else {
+ // Compatibility layer for symfony/console <7.4
+ app.add(cmd.clone());
+ }
+ app.set_default_command(cmd.get_name().to_string(), true);
+ let result = (|| -> anyhow::Result<i64> {
+ let args = additional_args
+ .iter()
+ .map(|arg| ProcessExecutor::escape(arg))
+ .collect::<Vec<_>>()
+ .join(" ");
+ // reusing the output from $this->io is mostly needed for tests, but generally speaking
+ // it does not hurt to keep the same stream as the current Application
+ let output = if let Some(_console_io) =
+ self.io.as_any().downcast_ref::<ConsoleIO>()
+ {
+ // TODO(plugin): \ReflectionProperty to read private `output` from ConsoleIO
+ // is required by the original PHP — needs user-decided porting strategy.
+ let _refl_php_version_gate = PHP_VERSION_ID < 80100;
+ todo!("\\ReflectionProperty on ConsoleIO::$output")
+ } else {
+ ConsoleOutput::new()
+ };
+ let input_str = event
+ .get_flags()
+ .get("script-alias-input")
+ .and_then(|v| v.as_string())
+ .unwrap_or(&args)
+ .to_string();
+ Ok(app.run(StringInput::new(input_str), output))
+ })();
+ match result {
+ Ok(v) => r#return = v,
+ Err(e) => {
+ let message =
+ "Script %s handling the %s event terminated with an exception";
+ self.io.write_error(
+ PhpMixed::String(format!(
+ "<error>{}</error>",
+ sprintf(
+ message,
+ &[
+ PhpMixed::String(callable_str.clone()),
+ PhpMixed::String(event.get_name().to_string()),
+ ],
+ )
+ )),
+ true,
+ <dyn IOInterface>::QUIET,
+ );
+ return Err(e);
+ }
+ }
}
- app.set_default_command(cmd.get_name().to_string(), true);
- let result = (|| -> anyhow::Result<i64> {
+ Callable::String(callable_str) => {
let args = additional_args
.iter()
.map(|arg| ProcessExecutor::escape(arg))
.collect::<Vec<_>>()
.join(" ");
- // reusing the output from $this->io is mostly needed for tests, but generally speaking
- // it does not hurt to keep the same stream as the current Application
- let output = if let Some(_console_io) =
- self.io.as_any().downcast_ref::<ConsoleIO>()
- {
- // TODO(plugin): \ReflectionProperty to read private `output` from ConsoleIO
- // is required by the original PHP — needs user-decided porting strategy.
- let _refl_php_version_gate = PHP_VERSION_ID < 80100;
- todo!("\\ReflectionProperty on ConsoleIO::$output")
+
+ // @putenv does not receive arguments
+ let mut exec = if strpos(&callable_str, "@putenv ") == Some(0) {
+ callable_str.clone()
+ } else if str_contains(&callable_str, "@additional_args") {
+ str_replace("@additional_args", &args, &callable_str)
} else {
- ConsoleOutput::new()
+ format!(
+ "{}{}",
+ callable_str,
+ if args == "" {
+ "".to_string()
+ } else {
+ format!(" {}", args)
+ }
+ )
};
- let input_str = event
- .get_flags()
- .get("script-alias-input")
- .and_then(|v| v.as_string())
- .unwrap_or(&args)
- .to_string();
- Ok(app.run(StringInput::new(input_str), output))
- })();
- match result {
- Ok(v) => r#return = v,
- Err(e) => {
- let message =
- "Script %s handling the %s event terminated with an exception";
+
+ if self.io.is_verbose() {
self.io.write_error(
- PhpMixed::String(format!(
- "<error>{}</error>",
- sprintf(
- message,
- &[
- PhpMixed::String(callable_str.clone()),
- PhpMixed::String(event.get_name().to_string()),
- ],
- )
+ PhpMixed::String(sprintf(
+ "> %s: %s",
+ &[
+ PhpMixed::String(event.get_name().to_string()),
+ PhpMixed::String(exec.clone()),
+ ],
)),
true,
- <dyn IOInterface>::QUIET,
+ <dyn IOInterface>::NORMAL,
+ );
+ } else if self.event_needs_to_output(event) {
+ self.io.write_error(
+ PhpMixed::String(sprintf(
+ "> %s",
+ &[PhpMixed::String(exec.clone())],
+ )),
+ true,
+ <dyn IOInterface>::NORMAL,
);
- return Err(e);
}
- }
- }
- Callable::String(callable_str) => {
- let args = additional_args
- .iter()
- .map(|arg| ProcessExecutor::escape(arg))
- .collect::<Vec<_>>()
- .join(" ");
- // @putenv does not receive arguments
- let mut exec = if strpos(&callable_str, "@putenv ") == Some(0) {
- callable_str.clone()
- } else if str_contains(&callable_str, "@additional_args") {
- str_replace("@additional_args", &args, &callable_str)
- } else {
- format!(
- "{}{}",
- callable_str,
- if args == "" {
- "".to_string()
- } else {
- format!(" {}", args)
- }
- )
- };
-
- if self.io.is_verbose() {
- self.io.write_error(
- PhpMixed::String(sprintf(
- "> %s: %s",
- &[
- PhpMixed::String(event.get_name().to_string()),
- PhpMixed::String(exec.clone()),
- ],
- )),
- true,
- <dyn IOInterface>::NORMAL,
- );
- } else if self.event_needs_to_output(event) {
- self.io.write_error(
- PhpMixed::String(sprintf(
- "> %s",
- &[PhpMixed::String(exec.clone())],
- )),
- true,
- <dyn IOInterface>::NORMAL,
- );
- }
-
- let possible_local_binaries =
- self.composer.get_package().get_binaries();
- if !possible_local_binaries.is_empty() {
- for local_exec in &possible_local_binaries {
- if Preg::is_match(
- &format!("{{\\b{}$}}", preg_quote(&callable_str, None)),
- local_exec,
- )
- .unwrap_or(false)
- {
- let caller = BinaryInstaller::determine_binary_caller(local_exec);
- exec = Preg::replace(
- &format!("{{^{}}}", preg_quote(&callable_str, None)),
- &format!("{} {}", caller, local_exec),
- &exec,
+ let possible_local_binaries = self.composer.get_package().get_binaries();
+ if !possible_local_binaries.is_empty() {
+ for local_exec in &possible_local_binaries {
+ if Preg::is_match(
+ &format!("{{\\b{}$}}", preg_quote(&callable_str, None)),
+ local_exec,
)
- .unwrap_or(exec);
- break;
+ .unwrap_or(false)
+ {
+ let caller =
+ BinaryInstaller::determine_binary_caller(local_exec);
+ exec = Preg::replace(
+ &format!("{{^{}}}", preg_quote(&callable_str, None)),
+ &format!("{} {}", caller, local_exec),
+ &exec,
+ )
+ .unwrap_or(exec);
+ break;
+ }
}
}
- }
- if strpos(&exec, "@putenv ") == Some(0) {
- if strpos(&exec, "=").is_none() {
- Platform::clear_env(&substr(&exec, 8, None));
- } else {
- let parts: Vec<&str> =
- substr(&exec, 8, None).splitn(2, '=').collect::<Vec<_>>()
+ if strpos(&exec, "@putenv ") == Some(0) {
+ if strpos(&exec, "=").is_none() {
+ Platform::clear_env(&substr(&exec, 8, None));
+ } else {
+ let parts: Vec<&str> = substr(&exec, 8, None)
+ .splitn(2, '=')
+ .collect::<Vec<_>>()
.iter()
.map(|s| *s)
.collect();
- let var = parts[0].to_string();
- let value = parts[1].to_string();
- Platform::put_env(&var, &value);
- }
+ let var = parts[0].to_string();
+ let value = parts[1].to_string();
+ Platform::put_env(&var, &value);
+ }
- continue;
- }
- if strpos(&exec, "@php ") == Some(0) {
- let mut path_and_args = substr(&exec, 5, None);
- if Platform::is_windows() {
- path_and_args = Preg::replace_callback(
- "{^\\S+}",
- |m| str_replace("/", "\\", &m[0]),
+ continue;
+ }
+ if strpos(&exec, "@php ") == Some(0) {
+ let mut path_and_args = substr(&exec, 5, None);
+ if Platform::is_windows() {
+ path_and_args = Preg::replace_callback(
+ "{^\\S+}",
+ |m| str_replace("/", "\\", &m[0]),
+ &path_and_args,
+ )
+ .unwrap_or(path_and_args);
+ }
+ // match somename (not in quote, and not a qualified path) and if it is not a valid path from CWD then try to find it
+ // in $PATH. This allows support for `@php foo` where foo is a binary name found in PATH but not an actual relative path
+ let mat = Preg::is_match_strict_groups(
+ "{^[^\\'\"\\s/\\\\]+}",
&path_and_args,
)
- .unwrap_or(path_and_args);
- }
- // match somename (not in quote, and not a qualified path) and if it is not a valid path from CWD then try to find it
- // in $PATH. This allows support for `@php foo` where foo is a binary name found in PATH but not an actual relative path
- let mat = Preg::is_match_strict_groups(
- "{^[^\\'\"\\s/\\\\]+}",
- &path_and_args,
- )
- .ok()
- .flatten();
- if let Some(m) = mat {
- if !file_exists(&m[0]) {
- let finder = ExecutableFinder::new();
- if let Some(path_to_exec) = finder.find(&m[0]) {
- let mut path_to_exec = path_to_exec;
- if Platform::is_windows() {
- let exec_without_ext = Preg::replace(
- "{\\.(exe|bat|cmd|com)$}i",
- "",
- &path_to_exec,
- )
- .unwrap_or(path_to_exec.clone());
- // prefer non-extension file if it exists when executing with PHP
- if file_exists(&exec_without_ext) {
- path_to_exec = exec_without_ext;
+ .ok()
+ .flatten();
+ if let Some(m) = mat {
+ if !file_exists(&m[0]) {
+ let finder = ExecutableFinder::new();
+ if let Some(path_to_exec) = finder.find(&m[0]) {
+ let mut path_to_exec = path_to_exec;
+ if Platform::is_windows() {
+ let exec_without_ext = Preg::replace(
+ "{\\.(exe|bat|cmd|com)$}i",
+ "",
+ &path_to_exec,
+ )
+ .unwrap_or(path_to_exec.clone());
+ // prefer non-extension file if it exists when executing with PHP
+ if file_exists(&exec_without_ext) {
+ path_to_exec = exec_without_ext;
+ }
}
+ path_and_args = format!(
+ "{}{}",
+ path_to_exec,
+ substr(&path_and_args, strlen(&m[0]), None)
+ );
}
- path_and_args = format!(
- "{}{}",
- path_to_exec,
- substr(&path_and_args, strlen(&m[0]), None)
- );
}
}
- }
- exec = format!("{} {}", self.get_php_exec_command()?, path_and_args);
- } else {
- let finder = PhpExecutableFinder::new();
- let php_path = finder.find(false);
- if let Some(ref pp) = php_path {
- Platform::put_env("PHP_BINARY", pp);
- }
+ exec = format!("{} {}", self.get_php_exec_command()?, path_and_args);
+ } else {
+ let finder = PhpExecutableFinder::new();
+ let php_path = finder.find(false);
+ if let Some(ref pp) = php_path {
+ Platform::put_env("PHP_BINARY", pp);
+ }
- if Platform::is_windows() {
- exec = Preg::replace_callback(
- "{^\\S+}",
- |m| str_replace("/", "\\", &m[0]),
- &exec,
- )
- .unwrap_or(exec);
+ if Platform::is_windows() {
+ exec = Preg::replace_callback(
+ "{^\\S+}",
+ |m| str_replace("/", "\\", &m[0]),
+ &exec,
+ )
+ .unwrap_or(exec);
+ }
}
- }
- // if composer is being executed, make sure it runs the expected composer from current path
- // resolution, even if bin-dir contains composer too because the project requires composer/composer
- // see https://github.com/composer/composer/issues/8748
- if strpos(&exec, "composer ") == Some(0) {
- exec = format!(
- "{} {}{}",
- self.get_php_exec_command()?,
- ProcessExecutor::escape(
- &Platform::get_env("COMPOSER_BINARY").unwrap_or_default()
- ),
- substr(&exec, 8, None)
- );
- }
+ // if composer is being executed, make sure it runs the expected composer from current path
+ // resolution, even if bin-dir contains composer too because the project requires composer/composer
+ // see https://github.com/composer/composer/issues/8748
+ if strpos(&exec, "composer ") == Some(0) {
+ exec = format!(
+ "{} {}{}",
+ self.get_php_exec_command()?,
+ ProcessExecutor::escape(
+ &Platform::get_env("COMPOSER_BINARY").unwrap_or_default()
+ ),
+ substr(&exec, 8, None)
+ );
+ }
- let exit_code = self.execute_tty(&exec)?;
- if exit_code != 0 {
- self.io.write_error(
+ let exit_code = self.execute_tty(&exec)?;
+ if exit_code != 0 {
+ self.io.write_error(
PhpMixed::String(sprintf(
&format!(
"<error>Script %s handling the %s event returned with error code {}</error>",
@@ -829,21 +831,22 @@ impl EventDispatcher {
<dyn IOInterface>::QUIET,
);
- return Err(anyhow::anyhow!(ScriptExecutionException(
- RuntimeException {
- message: format!(
- "Error Output: {}",
- self.process.get_error_output()
- ),
- code: exit_code,
- }
- )));
+ return Err(anyhow::anyhow!(ScriptExecutionException(
+ RuntimeException {
+ message: format!(
+ "Error Output: {}",
+ self.process.get_error_output()
+ ),
+ code: exit_code,
+ }
+ )));
+ }
+ }
+ _ => {
+ // unreachable in practice — the first match arm guard handles non-string callables.
}
}
- _ => {
- // unreachable in practice — the first match arm guard handles non-string callables.
- }
- } }
+ }
return_max = max_i64(return_max, r#return);
@@ -866,11 +869,7 @@ impl EventDispatcher {
fn do_dispatch_package(&mut self, event: PackageEvent) -> anyhow::Result<i64> {
// TODO(plugin): preserve PackageEvent identity for `instanceof` checks above.
- let base = Event::new(
- event.get_name().to_string(),
- Vec::new(),
- IndexMap::new(),
- );
+ let base = Event::new(event.get_name().to_string(), Vec::new(), IndexMap::new());
self.do_dispatch(base)
}
@@ -1088,11 +1087,7 @@ impl EventDispatcher {
_ => return Vec::new(),
};
- if self
- .skip_scripts
- .iter()
- .any(|s| s == event.get_name())
- {
+ if self.skip_scripts.iter().any(|s| s == event.get_name()) {
self.io.write_error(
PhpMixed::String(format!(
"Skipped script listeners for <info>{}</info> because of COMPOSER_SKIP_SCRIPTS",
@@ -1290,11 +1285,8 @@ impl EventDispatcher {
self.previous_hash = Some(hash_value);
- let package_map = generator.build_package_map(
- composer.get_installation_manager(),
- package,
- &packages,
- );
+ let package_map =
+ generator.build_package_map(composer.get_installation_manager(), package, &packages);
let map = generator.parse_autoloads(&package_map, package);
if self.loader.is_some() {
diff --git a/crates/shirabe/src/event_dispatcher/mod.rs b/crates/shirabe/src/event_dispatcher/mod.rs
new file mode 100644
index 0000000..97609be
--- /dev/null
+++ b/crates/shirabe/src/event_dispatcher/mod.rs
@@ -0,0 +1,4 @@
+pub mod event;
+pub mod event_dispatcher;
+pub mod event_subscriber_interface;
+pub mod script_execution_exception;
diff --git a/crates/shirabe/src/exception/mod.rs b/crates/shirabe/src/exception/mod.rs
new file mode 100644
index 0000000..d273f7e
--- /dev/null
+++ b/crates/shirabe/src/exception/mod.rs
@@ -0,0 +1,2 @@
+pub mod irrecoverable_download_exception;
+pub mod no_ssl_exception;
diff --git a/crates/shirabe/src/factory.rs b/crates/shirabe/src/factory.rs
index 6411027..eee2b88 100644
--- a/crates/shirabe/src/factory.rs
+++ b/crates/shirabe/src/factory.rs
@@ -6,11 +6,11 @@ use shirabe_external_packages::symfony::component::console::formatter::output_fo
use shirabe_external_packages::symfony::component::console::formatter::output_formatter_style::OutputFormatterStyle;
use shirabe_external_packages::symfony::component::console::output::console_output::ConsoleOutput;
use shirabe_php_shim::{
- array_keys, array_replace_recursive, class_exists, dirname, extension_loaded, file_exists,
- file_get_contents, file_put_contents, implode, in_array, is_array, is_dir, is_file, is_string,
- json_decode, pathinfo, realpath, str_replace, strpos, strtr, substr, trim, InvalidArgumentException,
- Phar, PhpMixed, RuntimeException, UnexpectedValueException, ZipArchive, PATHINFO_EXTENSION,
- PHP_EOL,
+ InvalidArgumentException, PATHINFO_EXTENSION, PHP_EOL, Phar, PhpMixed, RuntimeException,
+ UnexpectedValueException, ZipArchive, array_keys, array_replace_recursive, class_exists,
+ dirname, extension_loaded, file_exists, file_get_contents, file_put_contents, implode,
+ in_array, is_array, is_dir, is_file, is_string, json_decode, pathinfo, realpath, str_replace,
+ strpos, strtr, substr, trim,
};
use crate::autoload::autoload_generator::AutoloadGenerator;
@@ -46,8 +46,8 @@ use crate::json::json_validation_exception::JsonValidationException;
use crate::package::archiver::archive_manager::ArchiveManager;
use crate::package::archiver::phar_archiver::PharArchiver;
use crate::package::archiver::zip_archiver::ZipArchiver;
-use crate::package::locker::Locker;
use crate::package::loader::root_package_loader::RootPackageLoader;
+use crate::package::locker::Locker;
use crate::package::root_package_interface::RootPackageInterface;
use crate::package::version::version_guesser::VersionGuesser;
use crate::package::version::version_parser::VersionParser;
@@ -101,7 +101,10 @@ impl Factory {
}
if Platform::is_windows() {
- if Platform::get_env("APPDATA").map(|s| s.is_empty()).unwrap_or(true) {
+ if Platform::get_env("APPDATA")
+ .map(|s| s.is_empty())
+ .unwrap_or(true)
+ {
return Err(anyhow::anyhow!(RuntimeException {
message:
"The APPDATA or COMPOSER_HOME environment variable must be set for composer to run correctly"
@@ -135,8 +138,8 @@ impl Factory {
// select first dir which exists of: $XDG_CONFIG_HOME/composer or ~/.composer
for dir in &dirs {
let dir_copy = dir.clone();
- let exists = Silencer::call(|| Ok::<bool, anyhow::Error>(is_dir(&dir_copy)))
- .unwrap_or(false);
+ let exists =
+ Silencer::call(|| Ok::<bool, anyhow::Error>(is_dir(&dir_copy))).unwrap_or(false);
if exists {
return Ok(dir.clone());
}
@@ -176,16 +179,13 @@ impl Factory {
{
let from = format!("{}/cache", home);
let to = format!("{}/Library/Caches/composer", user_dir);
- let _ = Silencer::call(|| {
- Ok::<bool, anyhow::Error>(Platform::rename(&from, &to))
- });
+ let _ = Silencer::call(|| Ok::<bool, anyhow::Error>(Platform::rename(&from, &to)));
}
return Ok(format!("{}/Library/Caches/composer", user_dir));
}
- if home == format!("{}/.composer", user_dir).as_str()
- && is_dir(&format!("{}/cache", home))
+ if home == format!("{}/.composer", user_dir).as_str() && is_dir(&format!("{}/cache", home))
{
return Ok(format!("{}/cache", home));
}
@@ -229,8 +229,13 @@ impl Factory {
Ok(home.to_string())
}
- pub fn create_config(io: Option<&dyn IOInterface>, cwd: Option<&str>) -> anyhow::Result<Config> {
- let cwd = cwd.map(|s| s.to_string()).unwrap_or_else(|| Platform::get_cwd(true));
+ pub fn create_config(
+ io: Option<&dyn IOInterface>,
+ cwd: Option<&str>,
+ ) -> anyhow::Result<Config> {
+ let cwd = cwd
+ .map(|s| s.to_string())
+ .unwrap_or_else(|| Platform::get_cwd(true));
let mut config = Config::new(true, cwd);
@@ -263,7 +268,12 @@ impl Factory {
<dyn IOInterface>::DEBUG,
);
}
- Self::validate_json_schema(io, ValidateJsonInput::File(file.clone()), JsonFile::LAX_SCHEMA, None)?;
+ Self::validate_json_schema(
+ io,
+ ValidateJsonInput::File(file.clone()),
+ JsonFile::LAX_SCHEMA,
+ None,
+ )?;
config.merge(file.read()?, file.get_path().to_string());
}
config.set_config_source(JsonConfigSource::new(file.clone(), false));
@@ -298,11 +308,7 @@ impl Factory {
}
// load global auth file
- let auth_file = JsonFile::new(
- format!("{}/auth.json", config.get_str("home")?),
- None,
- io,
- );
+ let auth_file = JsonFile::new(format!("{}/auth.json", config.get_str("home")?), None, io);
if auth_file.exists() {
if let Some(io_ref) = io {
io_ref.write_error(
@@ -318,8 +324,16 @@ impl Factory {
None,
)?;
let mut wrapped: IndexMap<String, PhpMixed> = IndexMap::new();
- wrapped.insert("config".to_string(), PhpMixed::Array(auth_file.read()?
- .into_iter().map(|(k, v)| (k, Box::new(v))).collect()));
+ wrapped.insert(
+ "config".to_string(),
+ PhpMixed::Array(
+ auth_file
+ .read()?
+ .into_iter()
+ .map(|(k, v)| (k, Box::new(v)))
+ .collect(),
+ ),
+ );
config.merge(wrapped, auth_file.get_path().to_string());
}
config.set_auth_config_source(JsonConfigSource::new(auth_file, true));
@@ -352,13 +366,19 @@ impl Factory {
}
pub fn get_lock_file(composer_file: &str) -> String {
- let ext = pathinfo(PhpMixed::String(composer_file.to_string()), PATHINFO_EXTENSION);
+ let ext = pathinfo(
+ PhpMixed::String(composer_file.to_string()),
+ PATHINFO_EXTENSION,
+ );
let is_json = match ext {
PhpMixed::String(s) => s == "json",
_ => false,
};
if is_json {
- format!("{}lock", substr(composer_file, 0, Some(composer_file.len() as i64 - 4)))
+ format!(
+ "{}lock",
+ substr(composer_file, 0, Some(composer_file.len() as i64 - 4))
+ )
} else {
format!("{}.lock", composer_file)
}
@@ -372,7 +392,11 @@ impl Factory {
);
styles.insert(
"warning".to_string(),
- OutputFormatterStyle::new(Some("black".to_string()), Some("yellow".to_string()), Vec::new()),
+ OutputFormatterStyle::new(
+ Some("black".to_string()),
+ Some("yellow".to_string()),
+ Vec::new(),
+ ),
);
styles
}
@@ -438,10 +462,11 @@ impl Factory {
if !Platform::is_input_completion_process() {
if let Err(e) = file.validate_schema(JsonFile::LAX_SCHEMA) {
if let Some(jve) = e.downcast_ref::<JsonValidationException>() {
- let errors =
- format!(" - {}", implode(&format!("{} - ", PHP_EOL), jve.get_errors()));
- let message =
- format!("{}:{}{}", jve.get_message(), PHP_EOL, errors);
+ let errors = format!(
+ " - {}",
+ implode(&format!("{} - ", PHP_EOL), jve.get_errors())
+ );
+ let message = format!("{}:{}{}", jve.get_message(), PHP_EOL, errors);
return Err(anyhow::anyhow!(JsonValidationException::new(
message,
jve.get_errors().clone(),
@@ -474,7 +499,11 @@ impl Factory {
<dyn IOInterface>::DEBUG,
);
config.set_config_source(JsonConfigSource::new(
- JsonFile::new(realpath(composer_file_path).unwrap_or_default(), None, Some(io)),
+ JsonFile::new(
+ realpath(composer_file_path).unwrap_or_default(),
+ None,
+ Some(io),
+ ),
false,
));
@@ -560,37 +589,26 @@ impl Factory {
composer.set_loop(r#loop.clone());
// initialize event dispatcher
- let mut dispatcher = EventDispatcher::new(
- composer.as_partial(),
- io.clone_box(),
- Some(process.clone()),
- );
+ let mut dispatcher =
+ EventDispatcher::new(composer.as_partial(), io.clone_box(), Some(process.clone()));
dispatcher.set_run_scripts(!disable_scripts);
composer.set_event_dispatcher(dispatcher.clone());
// initialize repository manager
- let rm = RepositoryFactory::manager(
- io,
- &config,
- &http_downloader,
- &dispatcher,
- &process,
- )?;
+ let rm = RepositoryFactory::manager(io, &config, &http_downloader, &dispatcher, &process)?;
composer.set_repository_manager(rm.clone());
// force-set the version of the global package if not defined as
// guessing it adds no value and only takes time
if !full_load && !local_config_data.contains_key("version") {
- local_config_data.insert(
- "version".to_string(),
- PhpMixed::String("1.0.0".to_string()),
- );
+ local_config_data.insert("version".to_string(), PhpMixed::String("1.0.0".to_string()));
}
// load package
let parser = VersionParser::new();
let guesser = VersionGuesser::new(&config, process.clone(), parser.clone());
- let mut loader = self.load_root_package(rm.clone(), config.clone(), parser, guesser, io.clone_box());
+ let mut loader =
+ self.load_root_package(rm.clone(), config.clone(), parser, guesser, io.clone_box());
let package = loader.load(
local_config_data
.iter()
@@ -602,15 +620,31 @@ impl Factory {
composer.set_package(package);
// load local repository
- self.add_local_repository(io, rm.clone(), &vendor_dir, composer.get_package(), Some(&process));
+ self.add_local_repository(
+ io,
+ rm.clone(),
+ &vendor_dir,
+ composer.get_package(),
+ Some(&process),
+ );
// initialize installation manager
- let im = self.create_installation_manager(r#loop.clone(), io.clone_box(), Some(dispatcher.clone()));
+ let im = self.create_installation_manager(
+ r#loop.clone(),
+ io.clone_box(),
+ Some(dispatcher.clone()),
+ );
composer.set_installation_manager(im.clone());
if let PartialComposerOrComposer::Full(ref mut composer_full) = composer {
// initialize download manager
- let dm = self.create_download_manager(io, &config, &http_downloader, &process, Some(&dispatcher))?;
+ let dm = self.create_download_manager(
+ io,
+ &config,
+ &http_downloader,
+ &process,
+ Some(&dispatcher),
+ )?;
composer_full.set_download_manager(dm.clone());
// initialize autoload generator
@@ -629,8 +663,7 @@ impl Factory {
if let PartialComposerOrComposer::Full(ref mut composer_full) = composer {
if let Some(ref composer_file_path) = composer_file {
let lock_file = Self::get_lock_file(composer_file_path);
- let lock_enabled =
- config.get("lock").and_then(|v| v.as_bool()).unwrap_or(true);
+ let lock_enabled = config.get("lock").and_then(|v| v.as_bool()).unwrap_or(true);
if !lock_enabled && file_exists(&lock_file) {
io.write_error(
PhpMixed::String(format!(
@@ -687,7 +720,12 @@ impl Factory {
);
}
- let mut pm = self.create_plugin_manager(io, composer_full, global_composer.as_ref(), disable_plugins);
+ let mut pm = self.create_plugin_manager(
+ io,
+ composer_full,
+ global_composer.as_ref(),
+ disable_plugins,
+ );
composer_full.set_plugin_manager(pm.clone());
if composer_full.is_global() {
@@ -757,7 +795,10 @@ impl Factory {
full_load: bool,
) -> Option<PartialComposer> {
// make sure if disable plugins was 'local' it is now turned off
- let disable_plugins = if matches!(disable_plugins, DisablePlugins::Global | DisablePlugins::All) {
+ let disable_plugins = if matches!(
+ disable_plugins,
+ DisablePlugins::Global | DisablePlugins::All
+ ) {
DisablePlugins::All
} else {
DisablePlugins::None
@@ -777,10 +818,7 @@ impl Factory {
Ok(c) => Some(c.into_partial()),
Err(e) => {
io.write_error(
- PhpMixed::String(format!(
- "Failed to initialize global composer: {}",
- e
- )),
+ PhpMixed::String(format!("Failed to initialize global composer: {}", e)),
true,
<dyn IOInterface>::DEBUG,
);
@@ -851,23 +889,48 @@ impl Factory {
dm.set_downloader(
"git",
- Box::new(GitDownloader::new(io.clone_box(), config.clone(), process.clone(), fs.clone())),
+ Box::new(GitDownloader::new(
+ io.clone_box(),
+ config.clone(),
+ process.clone(),
+ fs.clone(),
+ )),
);
dm.set_downloader(
"svn",
- Box::new(SvnDownloader::new(io.clone_box(), config.clone(), process.clone(), fs.clone())),
+ Box::new(SvnDownloader::new(
+ io.clone_box(),
+ config.clone(),
+ process.clone(),
+ fs.clone(),
+ )),
);
dm.set_downloader(
"fossil",
- Box::new(FossilDownloader::new(io.clone_box(), config.clone(), process.clone(), fs.clone())),
+ Box::new(FossilDownloader::new(
+ io.clone_box(),
+ config.clone(),
+ process.clone(),
+ fs.clone(),
+ )),
);
dm.set_downloader(
"hg",
- Box::new(HgDownloader::new(io.clone_box(), config.clone(), process.clone(), fs.clone())),
+ Box::new(HgDownloader::new(
+ io.clone_box(),
+ config.clone(),
+ process.clone(),
+ fs.clone(),
+ )),
);
dm.set_downloader(
"perforce",
- Box::new(PerforceDownloader::new(io.clone_box(), config.clone(), process.clone(), fs.clone())),
+ Box::new(PerforceDownloader::new(
+ io.clone_box(),
+ config.clone(),
+ process.clone(),
+ fs.clone(),
+ )),
);
dm.set_downloader(
"zip",
@@ -993,7 +1056,12 @@ impl Factory {
global_composer: Option<&PartialComposer>,
disable_plugins: DisablePlugins,
) -> PluginManager {
- PluginManager::new(io.clone_box(), composer.clone(), global_composer.cloned(), disable_plugins)
+ PluginManager::new(
+ io.clone_box(),
+ composer.clone(),
+ global_composer.cloned(),
+ disable_plugins,
+ )
}
pub fn create_installation_manager(
@@ -1014,10 +1082,7 @@ impl Factory {
) {
let fs = Filesystem::new(process.cloned());
let bin_dir = trim(
- &composer
- .get_config()
- .get_str("bin-dir")
- .unwrap_or_default(),
+ &composer.get_config().get_str("bin-dir").unwrap_or_default(),
"/",
);
let bin_compat = composer
@@ -1031,13 +1096,8 @@ impl Factory {
.unwrap_or_default(),
"/",
);
- let binary_installer = BinaryInstaller::new(
- io.clone_box(),
- bin_dir,
- bin_compat,
- fs.clone(),
- vendor_dir,
- );
+ let binary_installer =
+ BinaryInstaller::new(io.clone_box(), bin_dir, bin_compat, fs.clone(), vendor_dir);
let mut im = im.clone();
im.add_installer(Box::new(LibraryInstaller::new(
@@ -1056,11 +1116,7 @@ impl Factory {
im.add_installer(Box::new(MetapackageInstaller::new(io.clone_box())));
}
- fn purge_packages(
- &self,
- repo: &dyn InstalledRepositoryInterface,
- im: &InstallationManager,
- ) {
+ fn purge_packages(&self, repo: &dyn InstalledRepositoryInterface, im: &InstallationManager) {
for package in repo.get_packages() {
if !im.is_package_installed(repo, package.as_ref()) {
// TODO(phase-b): mutable access on repo trait object
@@ -1182,14 +1238,21 @@ impl Factory {
let mut ssl_map: IndexMap<String, Box<PhpMixed>> = existing_ssl;
ssl_map.insert(
"capath".to_string(),
- Box::new(PhpMixed::String(config.get_str("capath").unwrap_or_default())),
+ Box::new(PhpMixed::String(
+ config.get_str("capath").unwrap_or_default(),
+ )),
);
http_downloader_options.insert("ssl".to_string(), PhpMixed::Array(ssl_map));
}
http_downloader_options =
array_replace_recursive(http_downloader_options, options.clone());
}
- let http_downloader = match HttpDownloader::new_full(io.clone_box(), config.clone(), http_downloader_options, disable_tls) {
+ let http_downloader = match HttpDownloader::new_full(
+ io.clone_box(),
+ config.clone(),
+ http_downloader_options,
+ disable_tls,
+ ) {
Ok(h) => h,
Err(e) => {
if let Some(te) = e.downcast_ref::<TransportException>() {
@@ -1333,7 +1396,10 @@ impl Factory {
<dyn IOInterface>::NORMAL,
);
} else {
- return Err(anyhow::anyhow!(UnexpectedValueException { message: msg, code: 0 }));
+ return Err(anyhow::anyhow!(UnexpectedValueException {
+ message: msg,
+ code: 0
+ }));
}
} else {
return Err(e);
diff --git a/crates/shirabe/src/filter/mod.rs b/crates/shirabe/src/filter/mod.rs
new file mode 100644
index 0000000..134a679
--- /dev/null
+++ b/crates/shirabe/src/filter/mod.rs
@@ -0,0 +1 @@
+pub mod platform_requirement_filter;
diff --git a/crates/shirabe/src/filter/platform_requirement_filter/ignore_list_platform_requirement_filter.rs b/crates/shirabe/src/filter/platform_requirement_filter/ignore_list_platform_requirement_filter.rs
index 57d5258..29f3c52 100644
--- a/crates/shirabe/src/filter/platform_requirement_filter/ignore_list_platform_requirement_filter.rs
+++ b/crates/shirabe/src/filter/platform_requirement_filter/ignore_list_platform_requirement_filter.rs
@@ -37,7 +37,12 @@ impl IgnoreListPlatformRequirementFilter {
})
}
- pub fn filter_constraint(&self, req: &str, constraint: Box<dyn ConstraintInterface>, allow_upper_bound_override: bool) -> anyhow::Result<Box<dyn ConstraintInterface>> {
+ pub fn filter_constraint(
+ &self,
+ req: &str,
+ constraint: Box<dyn ConstraintInterface>,
+ allow_upper_bound_override: bool,
+ ) -> anyhow::Result<Box<dyn ConstraintInterface>> {
if !PlatformRepository::is_platform_package(req) {
return Ok(constraint);
}
@@ -55,7 +60,10 @@ impl IgnoreListPlatformRequirementFilter {
if let Some(last) = last {
if last.get_end().to_string() != Interval::until_positive_infinity().to_string() {
let constraint = Box::new(MultiConstraint::new(
- vec![constraint, Box::new(Constraint::new(">=", last.get_end().get_version()))],
+ vec![
+ constraint,
+ Box::new(Constraint::new(">=", last.get_end().get_version())),
+ ],
false,
));
return Ok(constraint);
diff --git a/crates/shirabe/src/filter/platform_requirement_filter/mod.rs b/crates/shirabe/src/filter/platform_requirement_filter/mod.rs
new file mode 100644
index 0000000..fdd7feb
--- /dev/null
+++ b/crates/shirabe/src/filter/platform_requirement_filter/mod.rs
@@ -0,0 +1,5 @@
+pub mod ignore_all_platform_requirement_filter;
+pub mod ignore_list_platform_requirement_filter;
+pub mod ignore_nothing_platform_requirement_filter;
+pub mod platform_requirement_filter_factory;
+pub mod platform_requirement_filter_interface;
diff --git a/crates/shirabe/src/filter/platform_requirement_filter/platform_requirement_filter_factory.rs b/crates/shirabe/src/filter/platform_requirement_filter/platform_requirement_filter_factory.rs
index 8dda266..59340cb 100644
--- a/crates/shirabe/src/filter/platform_requirement_filter/platform_requirement_filter_factory.rs
+++ b/crates/shirabe/src/filter/platform_requirement_filter/platform_requirement_filter_factory.rs
@@ -1,18 +1,20 @@
//! ref: composer/src/Composer/Filter/PlatformRequirementFilter/PlatformRequirementFilterFactory.php
-use anyhow::Result;
-use shirabe_php_shim::{InvalidArgumentException, PhpMixed};
use crate::filter::platform_requirement_filter::{
ignore_all_platform_requirement_filter::IgnoreAllPlatformRequirementFilter,
ignore_list_platform_requirement_filter::IgnoreListPlatformRequirementFilter,
ignore_nothing_platform_requirement_filter::IgnoreNothingPlatformRequirementFilter,
platform_requirement_filter_interface::PlatformRequirementFilterInterface,
};
+use anyhow::Result;
+use shirabe_php_shim::{InvalidArgumentException, PhpMixed};
pub struct PlatformRequirementFilterFactory;
impl PlatformRequirementFilterFactory {
- pub fn from_bool_or_list(bool_or_list: PhpMixed) -> Result<Box<dyn PlatformRequirementFilterInterface>> {
+ pub fn from_bool_or_list(
+ bool_or_list: PhpMixed,
+ ) -> Result<Box<dyn PlatformRequirementFilterInterface>> {
match bool_or_list {
PhpMixed::Bool(b) => {
if b {
@@ -21,9 +23,9 @@ impl PlatformRequirementFilterFactory {
Ok(Self::ignore_nothing())
}
}
- list_or_array @ (PhpMixed::List(_) | PhpMixed::Array(_)) => {
- Ok(Box::new(IgnoreListPlatformRequirementFilter::new(list_or_array)))
- }
+ list_or_array @ (PhpMixed::List(_) | PhpMixed::Array(_)) => Ok(Box::new(
+ IgnoreListPlatformRequirementFilter::new(list_or_array),
+ )),
other => Err(anyhow::anyhow!(InvalidArgumentException {
message: format!(
"PlatformRequirementFilter: Unknown $boolOrList parameter {}. Please report at https://github.com/composer/composer/issues/new.",
diff --git a/crates/shirabe/src/installed_versions.rs b/crates/shirabe/src/installed_versions.rs
index 1014d0d..b151d96 100644
--- a/crates/shirabe/src/installed_versions.rs
+++ b/crates/shirabe/src/installed_versions.rs
@@ -5,9 +5,9 @@ use std::sync::Mutex;
use anyhow::Result;
use indexmap::IndexMap;
use shirabe_php_shim::{
- array_flip, array_keys, array_merge, call_user_func_array, implode, is_file, method_exists,
- php_dir, require_php_file, strtr_array, substr, trigger_error, OutOfBoundsException, PhpMixed,
- E_USER_DEPRECATED,
+ E_USER_DEPRECATED, OutOfBoundsException, PhpMixed, array_flip, array_keys, array_merge,
+ call_user_func_array, implode, is_file, method_exists, php_dir, require_php_file, strtr_array,
+ substr, trigger_error,
};
use shirabe_semver::version_parser::VersionParser;
@@ -185,7 +185,10 @@ impl InstalledVersions {
let Some(versions) = installed.get("versions").and_then(|v| v.as_array()) else {
continue;
};
- let Some(pkg) = versions.get(package_name).and_then(|v| v.as_array()).cloned()
+ let Some(pkg) = versions
+ .get(package_name)
+ .and_then(|v| v.as_array())
+ .cloned()
else {
continue;
};
@@ -455,14 +458,11 @@ impl InstalledVersions {
fn get_self_dir() -> String {
let mut self_dir = SELF_DIR.lock().unwrap();
if self_dir.is_none() {
- *self_dir = Some(strtr_array(
- &php_dir(),
- &{
- let mut m = IndexMap::new();
- m.insert("\\".to_string(), "/".to_string());
- m
- },
- ));
+ *self_dir = Some(strtr_array(&php_dir(), &{
+ let mut m = IndexMap::new();
+ m.insert("\\".to_string(), "/".to_string());
+ m
+ }));
}
self_dir.clone().unwrap()
@@ -492,14 +492,16 @@ impl InstalledVersions {
m.insert("\\".to_string(), "/".to_string());
m
});
- let cached = INSTALLED_BY_VENDOR.lock().unwrap().get(&vendor_dir).cloned();
+ let cached = INSTALLED_BY_VENDOR
+ .lock()
+ .unwrap()
+ .get(&vendor_dir)
+ .cloned();
if let Some(cached) = cached {
installed.push(cached);
} else if is_file(&format!("{}/composer/installed.php", vendor_dir)) {
- let required = require_php_file(&format!(
- "{}/composer/installed.php",
- vendor_dir,
- ));
+ let required =
+ require_php_file(&format!("{}/composer/installed.php", vendor_dir,));
let required_map: IndexMap<String, PhpMixed> = required
.as_array()
.cloned()
diff --git a/crates/shirabe/src/installer.rs b/crates/shirabe/src/installer.rs
index bcba5e9..3f6180f 100644
--- a/crates/shirabe/src/installer.rs
+++ b/crates/shirabe/src/installer.rs
@@ -1,13 +1,28 @@
//! ref: composer/src/Composer/Installer.php
+pub mod binary_installer;
+pub mod binary_presence_interface;
+pub mod installation_manager;
+pub mod installer_event;
+pub mod installer_events;
+pub mod installer_interface;
+pub mod library_installer;
+pub mod metapackage_installer;
+pub mod noop_installer;
+pub mod package_event;
+pub mod package_events;
+pub mod plugin_installer;
+pub mod project_installer;
+pub mod suggested_packages_reporter;
+
use indexmap::IndexMap;
use shirabe_external_packages::seld::json_lint::parsing_exception::ParsingException;
use shirabe_php_shim::{
- array_flip, array_map, array_merge, array_unique, array_values, clone, count, defined,
- gc_collect_cycles, gc_disable, gc_enable, get_class, implode, in_array, intval, is_dir,
- is_numeric, is_string, max_i64, sprintf, strcmp, strpos, strtolower, touch, trigger_error,
- usort, RuntimeException,
+ RuntimeException, array_flip, array_map, array_merge, array_unique, array_values, clone, count,
+ defined, gc_collect_cycles, gc_disable, gc_enable, get_class, implode, in_array, intval,
+ is_dir, is_numeric, is_string, max_i64, sprintf, strcmp, strpos, strtolower, touch,
+ trigger_error, usort,
};
use shirabe_semver;
@@ -240,7 +255,8 @@ impl Installer {
} else {
ScriptEvents::PRE_INSTALL_CMD
};
- self.event_dispatcher.dispatch_script(event_name, self.dev_mode);
+ self.event_dispatcher
+ .dispatch_script(event_name, self.dev_mode);
}
self.download_manager.set_prefer_source(self.prefer_source);
@@ -266,7 +282,11 @@ impl Installer {
Err(e) => {
if self.execute_operations
&& self.install
- && self.config.get("notify-on-install").as_bool().unwrap_or(false)
+ && self
+ .config
+ .get("notify-on-install")
+ .as_bool()
+ .unwrap_or(false)
{
self.installation_manager.notify_installs(&*self.io);
}
@@ -277,14 +297,20 @@ impl Installer {
if self.execute_operations
&& self.install
- && self.config.get("notify-on-install").as_bool().unwrap_or(false)
+ && self
+ .config
+ .get("notify-on-install")
+ .as_bool()
+ .unwrap_or(false)
{
self.installation_manager.notify_installs(&*self.io);
}
if self.update {
let installed_repo = InstalledRepository::new(vec![
- self.locker.get_locked_repository(self.dev_mode)?.clone_box(),
+ self.locker
+ .get_locked_repository(self.dev_mode)?
+ .clone_box(),
Box::new(self.create_platform_repo(false)),
Box::new(RootPackageRepository::new(clone(&self.package))),
]);
@@ -315,19 +341,18 @@ impl Installer {
self.io.write_error(&sprintf(
"<warning>Package %s is abandoned, you should avoid using it. %s.</warning>",
- &[
- complete.get_pretty_name().into(),
- replacement.into(),
- ],
+ &[complete.get_pretty_name().into(), replacement.into()],
));
}
if self.dump_autoloader {
// write autoloader
if self.optimize_autoloader {
- self.io.write_error("<info>Generating optimized autoload files</info>");
+ self.io
+ .write_error("<info>Generating optimized autoload files</info>");
} else {
- self.io.write_error("<info>Generating autoload files</info>");
+ self.io
+ .write_error("<info>Generating autoload files</info>");
}
self.autoload_generator
@@ -395,7 +420,8 @@ impl Installer {
} else {
ScriptEvents::POST_INSTALL_CMD
};
- self.event_dispatcher.dispatch_script(event_name, self.dev_mode);
+ self.event_dispatcher
+ .dispatch_script(event_name, self.dev_mode);
}
// re-enable GC except on HHVM which triggers a warning here
@@ -447,13 +473,11 @@ impl Installer {
}
Err(e) => {
if let Some(te) = e.downcast_ref::<TransportException>() {
- self.io.error(&format!("Failed to audit {} packages.", target));
+ self.io
+ .error(&format!("Failed to audit {} packages.", target));
if self.io.is_verbose() {
- self.io.error(&format!(
- "[{}] {}",
- get_class(te),
- te.get_message()
- ));
+ self.io
+ .error(&format!("[{}] {}", get_class(te), te.get_message()));
}
} else {
return Err(e);
@@ -479,19 +503,20 @@ impl Installer {
let mut locked_repository: Option<Box<dyn LockArrayRepository>> = None;
- let try_load_locked = || -> anyhow::Result<Result<Option<Box<dyn LockArrayRepository>>, ParsingException>> {
- if self.locker.is_locked() {
- match self.locker.get_locked_repository(true) {
- Ok(r) => Ok(Ok(Some(r))),
- Err(e) => match e.downcast::<ParsingException>() {
- Ok(p) => Ok(Err(p)),
- Err(other) => Err(other),
- },
+ let try_load_locked =
+ || -> anyhow::Result<Result<Option<Box<dyn LockArrayRepository>>, ParsingException>> {
+ if self.locker.is_locked() {
+ match self.locker.get_locked_repository(true) {
+ Ok(r) => Ok(Ok(Some(r))),
+ Err(e) => match e.downcast::<ParsingException>() {
+ Ok(p) => Ok(Err(p)),
+ Err(other) => Err(other),
+ },
+ }
+ } else {
+ Ok(Ok(None))
}
- } else {
- Ok(Ok(None))
- }
- };
+ };
match try_load_locked()? {
Ok(r) => locked_repository = r,
@@ -505,8 +530,7 @@ impl Installer {
}
}
- if (self.update_allow_list.is_some() || self.update_mirrors)
- && locked_repository.is_none()
+ if (self.update_allow_list.is_some() || self.update_mirrors) && locked_repository.is_none()
{
self.io.write_error(
&format!(
@@ -529,8 +553,7 @@ impl Installer {
// creating repository set
let policy = self.create_policy(true, locked_repository.as_deref());
- let mut repository_set =
- self.create_repository_set(true, &platform_repo, &aliases, None);
+ let mut repository_set = self.create_repository_set(true, &platform_repo, &aliases, None);
let repositories = self.repository_manager.get_repositories();
for repository in repositories {
repository_set.add_repository(repository);
@@ -548,7 +571,10 @@ impl Installer {
// pass the allow list into the request, so the pool builder can apply it
if let Some(ref allow_list) = self.update_allow_list {
- request.set_update_allow_list(allow_list.clone(), self.update_allow_transitive_dependencies);
+ request.set_update_allow_list(
+ allow_list.clone(),
+ self.update_allow_transitive_dependencies,
+ );
}
let mut pool: Option<Pool> = Some(repository_set.create_pool(
@@ -564,7 +590,8 @@ impl Installer {
self.io.write_error("<info>Updating dependencies</info>");
// solve dependencies
- let mut solver: Option<Solver> = Some(Solver::new(&policy, pool.as_ref().unwrap(), &*self.io));
+ let mut solver: Option<Solver> =
+ Some(Solver::new(&policy, pool.as_ref().unwrap(), &*self.io));
let lock_transaction;
let rule_set_size;
match solver
@@ -613,7 +640,10 @@ impl Installer {
let _ = solver;
self.io.write_error(
- &format!("Analyzed {} packages to resolve dependencies", count(&pool.as_ref().unwrap())),
+ &format!(
+ "Analyzed {} packages to resolve dependencies",
+ count(&pool.as_ref().unwrap())
+ ),
true,
IOInterface::VERBOSE,
);
@@ -629,10 +659,7 @@ impl Installer {
if lock_transaction.get_operations().is_empty() {
self.io.write_error("Nothing to modify in lock file");
- if self.minimal_update
- && self.update_allow_list.is_none()
- && self.locker.is_fresh()
- {
+ if self.minimal_update && self.update_allow_list.is_none() && self.locker.is_fresh() {
self.io.write_error("<warning>The --minimal-changes option should be used with package arguments or after modifying composer.json requirements, otherwise it will likely not yield any dependency changes.</warning>");
}
}
@@ -652,7 +679,8 @@ impl Installer {
// write lock
let platform_reqs = self.extract_platform_requirements(&self.package.get_requires());
- let platform_dev_reqs = self.extract_platform_requirements(&self.package.get_dev_requires());
+ let platform_dev_reqs =
+ self.extract_platform_requirements(&self.package.get_dev_requires());
let mut installs_updates: Vec<Box<dyn OperationInterface>> = vec![];
let mut uninstalls: Vec<Box<dyn OperationInterface>> = vec![];
@@ -673,7 +701,8 @@ impl Installer {
// update in the output as it is only an internal lock file metadata update
if self.update_mirrors
&& uo.get_initial_package().get_name() == uo.get_target_package().get_name()
- && uo.get_initial_package().get_version() == uo.get_target_package().get_version()
+ && uo.get_initial_package().get_version()
+ == uo.get_target_package().get_version()
{
continue;
}
@@ -726,7 +755,9 @@ impl Installer {
}
}
- let sort_by_name = |a: &Box<dyn OperationInterface>, b: &Box<dyn OperationInterface>| -> std::cmp::Ordering {
+ let sort_by_name = |a: &Box<dyn OperationInterface>,
+ b: &Box<dyn OperationInterface>|
+ -> std::cmp::Ordering {
let a_name: String = if let Some(uo) = a.as_update_operation() {
uo.get_target_package().get_name().to_string()
} else {
@@ -758,16 +789,18 @@ impl Installer {
if self.io.is_very_verbose()
&& strpos(operation.get_operation_type(), "Alias") == false
{
- let operation_pkg: Box<dyn PackageInterface> = if let Some(uo) = operation.as_update_operation() {
- uo.get_target_package().clone_box()
- } else {
- operation.get_package().clone_box()
- };
+ let operation_pkg: Box<dyn PackageInterface> =
+ if let Some(uo) = operation.as_update_operation() {
+ uo.get_target_package().clone_box()
+ } else {
+ operation.get_package().clone_box()
+ };
if let Some(repo) = operation_pkg.get_repository() {
source_repo = format!(" from {}", repo.get_repo_name());
}
}
- self.io.write_error(&format!(" - {}{}", operation.show(true), source_repo));
+ self.io
+ .write_error(&format!(" - {}{}", operation.show(true), source_repo));
}
}
@@ -781,7 +814,11 @@ impl Installer {
self.package.get_stability_flags(),
self.prefer_stable || self.package.get_prefer_stable(),
self.prefer_lowest,
- self.config.get("platform").as_array().cloned().unwrap_or_default(),
+ self.config
+ .get("platform")
+ .as_array()
+ .cloned()
+ .unwrap_or_default(),
self.write_lock && self.execute_operations,
)?;
if updated_lock && self.write_lock && self.execute_operations {
@@ -814,7 +851,10 @@ impl Installer {
let loader = ArrayLoader::new(None, true);
let dumper = ArrayDumper::new();
for pkg in lock_transaction.get_new_lock_packages(false, false) {
- result_repo.add_package(loader.load(dumper.dump(&*pkg), "Composer\\Package\\CompletePackage".to_string())?);
+ result_repo.add_package(loader.load(
+ dumper.dump(&*pkg),
+ "Composer\\Package\\CompletePackage".to_string(),
+ )?);
}
let mut repository_set = self.create_repository_set(true, platform_repo, aliases, None);
@@ -880,7 +920,11 @@ impl Installer {
if self.config.get("lock").as_bool().unwrap_or(false) {
self.io.write_error(&format!(
"<info>Installing dependencies from lock file{}</info>",
- if self.dev_mode { " (including require-dev)" } else { "" }
+ if self.dev_mode {
+ " (including require-dev)"
+ } else {
+ ""
+ }
));
}
@@ -889,7 +933,9 @@ impl Installer {
// verify that the lock file works with the current platform repository
// we can skip this part if we're doing this as the second step after an update
if !already_solved {
- self.io.write_error("<info>Verifying lock file contents can be installed on current platform.</info>");
+ self.io.write_error(
+ "<info>Verifying lock file contents can be installed on current platform.</info>",
+ );
let platform_repo = self.create_platform_repo(false);
// creating repository set
@@ -918,11 +964,18 @@ impl Installer {
);
}
- let missing_requirement_info = self.locker.get_missing_requirement_info(&*self.package, self.dev_mode);
+ let missing_requirement_info = self
+ .locker
+ .get_missing_requirement_info(&*self.package, self.dev_mode);
if !missing_requirement_info.is_empty() {
self.io.write_error(missing_requirement_info);
- if !self.config.get("allow-missing-requirements").as_bool().unwrap_or(false) {
+ if !self
+ .config
+ .get("allow-missing-requirements")
+ .as_bool()
+ .unwrap_or(false)
+ {
return Ok(Self::ERROR_LOCK_FILE_INVALID);
}
}
@@ -937,13 +990,15 @@ impl Installer {
}
for (_key, link) in &root_requires {
if PlatformRepository::is_platform_package(link.get_target()) {
- request.require_name(link.get_target().to_string(), Some(link.get_constraint()));
+ request
+ .require_name(link.get_target().to_string(), Some(link.get_constraint()));
}
}
for link in self.locker.get_platform_requirements(self.dev_mode) {
if !root_requires.contains_key(link.get_target()) {
- request.require_name(link.get_target().to_string(), Some(link.get_constraint()));
+ request
+ .require_name(link.get_target().to_string(), Some(link.get_constraint()));
}
}
drop(root_requires);
@@ -1087,7 +1142,12 @@ impl Installer {
// see https://github.com/composer/composer/issues/2764
if count(&local_repo_transaction.get_operations()) > 0 {
- let vendor_dir = self.config.get("vendor-dir").as_string().unwrap_or("").to_string();
+ let vendor_dir = self
+ .config
+ .get("vendor-dir")
+ .as_string()
+ .unwrap_or("")
+ .to_string();
if is_dir(&vendor_dir) {
// suppress errors as this fails sometimes on OSX for no apparent reason
// see https://github.com/composer/composer/issues/4070#issuecomment-129792748
@@ -1098,7 +1158,8 @@ impl Installer {
for operation in local_repo_transaction.get_operations() {
// output op, but alias op only in debug verbosity
if strpos(operation.get_operation_type(), "Alias") == false || self.io.is_debug() {
- self.io.write_error(&format!(" - {}", operation.show(false)));
+ self.io
+ .write_error(&format!(" - {}", operation.show(false)));
}
}
}
@@ -1108,7 +1169,11 @@ impl Installer {
pub(crate) fn create_platform_repo(&self, for_update: bool) -> PlatformRepository {
let platform_overrides = if for_update {
- self.config.get("platform").as_array().cloned().unwrap_or_default()
+ self.config
+ .get("platform")
+ .as_array()
+ .cloned()
+ .unwrap_or_default()
} else {
self.locker.get_platform_overrides()
};
@@ -1179,7 +1244,8 @@ impl Installer {
stability_flags.insert(
self.package.get_name().to_string(),
- base_package::STABILITIES[VersionParser::parse_stability(self.package.get_version()).as_str()],
+ base_package::STABILITIES
+ [VersionParser::parse_stability(self.package.get_version()).as_str()],
);
let mut repository_set = RepositorySet::new(
@@ -1190,7 +1256,9 @@ impl Installer {
root_requires,
self.temporary_constraints.clone(),
);
- repository_set.add_repository(Box::new(RootPackageRepository::new(clone(&self.fixed_root_package))));
+ repository_set.add_repository(Box::new(RootPackageRepository::new(clone(
+ &self.fixed_root_package,
+ ))));
repository_set.add_repository(Box::new(platform_repo.clone()));
if let Some(ref additional_fixed_repository) = self.additional_fixed_repository {
// allow using installed repos if needed to avoid warnings about installed repositories being used in the RepositorySet
@@ -1209,7 +1277,9 @@ impl Installer {
.as_any()
.downcast_ref::<InstalledRepository>()
.is_some()
- || additional_fixed_repository.as_installed_repository_interface().is_some()
+ || additional_fixed_repository
+ .as_installed_repository_interface()
+ .is_some()
{
repository_set.allow_installed_repositories();
break;
@@ -1261,7 +1331,11 @@ impl Installer {
preferred_versions = Some(versions);
}
- DefaultPolicy::new(prefer_stable.unwrap(), prefer_lowest.unwrap(), preferred_versions)
+ DefaultPolicy::new(
+ prefer_stable.unwrap(),
+ prefer_lowest.unwrap(),
+ preferred_versions,
+ )
}
fn create_request(
@@ -1279,7 +1353,8 @@ impl Installer {
let mut fixed_packages = platform_repo.get_packages();
if let Some(ref additional_fixed_repository) = self.additional_fixed_repository {
- fixed_packages = array_merge(fixed_packages, additional_fixed_repository.get_packages());
+ fixed_packages =
+ array_merge(fixed_packages, additional_fixed_repository.get_packages());
}
// fix the version of all platform packages + additionally installed packages
@@ -1332,7 +1407,10 @@ impl Installer {
{
request.require_name(
locked_package.get_name().to_string(),
- Some(Box::new(Constraint::new("==", locked_package.get_version().to_string()))),
+ Some(Box::new(Constraint::new(
+ "==",
+ locked_package.get_version().to_string(),
+ ))),
);
}
}
@@ -1357,11 +1435,17 @@ impl Installer {
aliases
}
- fn extract_platform_requirements(&self, links: &IndexMap<String, Link>) -> IndexMap<String, String> {
+ fn extract_platform_requirements(
+ &self,
+ links: &IndexMap<String, Link>,
+ ) -> IndexMap<String, String> {
let mut platform_reqs: IndexMap<String, String> = IndexMap::new();
for (_key, link) in links {
if PlatformRepository::is_platform_package(link.get_target()) {
- platform_reqs.insert(link.get_target().to_string(), link.get_pretty_constraint().to_string());
+ platform_reqs.insert(
+ link.get_target().to_string(),
+ link.get_pretty_constraint().to_string(),
+ );
}
}
@@ -1426,7 +1510,9 @@ impl Installer {
Ok(self.audit_config.as_ref().unwrap())
}
- fn create_security_audit_pool_filter(&mut self) -> anyhow::Result<Option<SecurityAdvisoryPoolFilter>> {
+ fn create_security_audit_pool_filter(
+ &mut self,
+ ) -> anyhow::Result<Option<SecurityAdvisoryPoolFilter>> {
let audit_config = self.get_audit_config()?;
if audit_config.block_insecure && !self.update_mirrors {
@@ -1631,7 +1717,9 @@ impl Installer {
shirabe_php_shim::E_USER_DEPRECATED,
);
- self.set_platform_requirement_filter(PlatformRequirementFilterFactory::from_bool_or_list(ignore_platform_reqs))
+ self.set_platform_requirement_filter(PlatformRequirementFilterFactory::from_bool_or_list(
+ ignore_platform_reqs,
+ ))
}
pub fn set_platform_requirement_filter(
diff --git a/crates/shirabe/src/installer/binary_installer.rs b/crates/shirabe/src/installer/binary_installer.rs
index eb533a4..0e5b3d9 100644
--- a/crates/shirabe/src/installer/binary_installer.rs
+++ b/crates/shirabe/src/installer/binary_installer.rs
@@ -2,9 +2,9 @@
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- basename, basename_with_suffix, chmod, dirname, fclose, fgets, file_exists, file_get_contents,
- file_put_contents, fopen, is_dir, is_file, is_link, realpath, rmdir, substr, trim, umask,
- PhpMixed,
+ PhpMixed, basename, basename_with_suffix, chmod, dirname, fclose, fgets, file_exists,
+ file_get_contents, file_put_contents, fopen, is_dir, is_file, is_link, realpath, rmdir, substr,
+ trim, umask,
};
use crate::io::io_interface::IOInterface;
@@ -166,10 +166,9 @@ impl BinaryInstaller {
let handle = fopen(bin, "r");
let line = fgets(handle.clone()).unwrap_or_default();
fclose(handle);
- if let Some(m) = Preg::is_match_strict_groups(
- r"{^#!/(?:usr/bin/env )?(?:[^/]+/)*(.+)$}m",
- &line,
- ) {
+ if let Some(m) =
+ Preg::is_match_strict_groups(r"{^#!/(?:usr/bin/env )?(?:[^/]+/)*(.+)$}m", &line)
+ {
return trim(m.get(1).map(|s| s.as_str()).unwrap_or(""), None);
}
@@ -246,7 +245,10 @@ impl BinaryInstaller {
SET BIN_TARGET=%~dp0/{}\r\n\
SET COMPOSER_RUNTIME_BIN_DIR=%~dp0\r\n\
{} \"%BIN_TARGET%\" %*\r\n",
- trim(&ProcessExecutor::escape(&basename_with_suffix(link, ".bat")), Some("\"'")),
+ trim(
+ &ProcessExecutor::escape(&basename_with_suffix(link, ".bat")),
+ Some("\"'")
+ ),
caller,
);
}
@@ -273,12 +275,10 @@ impl BinaryInstaller {
let bin_contents = file_get_contents(bin).unwrap_or_default();
// For php files, we generate a PHP proxy instead of a shell one,
// which allows calling the proxy with a custom php process
- if let Some(m) = Preg::is_match_with_indexed_captures(
- r"{^(#!.*\r?\n)?[\r\n\t ]*<\?php}",
- &bin_contents,
- )
- .ok()
- .flatten()
+ if let Some(m) =
+ Preg::is_match_with_indexed_captures(r"{^(#!.*\r?\n)?[\r\n\t ]*<\?php}", &bin_contents)
+ .ok()
+ .flatten()
{
// carry over the existing shebang if present, otherwise add our own
let proxy_code = if m.get(1).is_none() {
@@ -291,9 +291,7 @@ impl BinaryInstaller {
.find_shortest_path_code(link, bin, false, true);
let mut stream_proxy_code = String::new();
let mut stream_hint = String::new();
- let mut globals_code = format!(
- "$GLOBALS['_composer_bin_dir'] = __DIR__;\n",
- );
+ let mut globals_code = format!("$GLOBALS['_composer_bin_dir'] = __DIR__;\n",);
let mut phpunit_hack1 = String::new();
let mut phpunit_hack2 = String::new();
// Don't expose autoload path when vendor dir was not set in custom installers
@@ -326,11 +324,14 @@ impl BinaryInstaller {
phpunit_hack1 = "'phpvfscomposer://'.".to_string();
phpunit_hack2 = "
$data = str_replace('__DIR__', var_export(dirname($this->realpath), true), $data);
- $data = str_replace('__FILE__', var_export($this->realpath, true), $data);".to_string();
+ $data = str_replace('__FILE__', var_export($this->realpath, true), $data);"
+ .to_string();
}
}
if trim(m.get(0).map(|s| s.as_str()).unwrap_or(""), None) != "<?php" {
- stream_hint = format!(" using a stream wrapper to prevent the shebang from being output on PHP<8\n *");
+ stream_hint = format!(
+ " using a stream wrapper to prevent the shebang from being output on PHP<8\n *"
+ );
stream_proxy_code = format!(
"if (PHP_VERSION_ID < 80000) {{\n if (!class_exists('Composer\\BinProxyWrapper')) {{\n /**\n * @internal\n */\n final class BinProxyWrapper\n {{\n private $handle;\n private $position;\n private $realpath;\n\n public function stream_open($path, $mode, $options, &$opened_path)\n {{\n // get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution\n $opened_path = substr($path, 17);\n $this->realpath = realpath($opened_path) ?: $opened_path;\n $opened_path = {phpunit_hack1}$this->realpath;\n $this->handle = fopen($this->realpath, $mode);\n $this->position = 0;\n\n return (bool) $this->handle;\n }}\n\n public function stream_read($count)\n {{\n $data = fread($this->handle, $count);\n\n if ($this->position === 0) {{\n $data = preg_replace('{{^#!.*\\r?\\n}}', '', $data);\n }}{phpunit_hack2}\n\n $this->position += strlen($data);\n\n return $data;\n }}\n\n public function stream_cast($castAs)\n {{\n return $this->handle;\n }}\n\n public function stream_close()\n {{\n fclose($this->handle);\n }}\n\n public function stream_lock($operation)\n {{\n return $operation ? flock($this->handle, $operation) : true;\n }}\n\n public function stream_seek($offset, $whence)\n {{\n if (0 === fseek($this->handle, $offset, $whence)) {{\n $this->position = ftell($this->handle);\n return true;\n }}\n\n return false;\n }}\n\n public function stream_tell()\n {{\n return $this->position;\n }}\n\n public function stream_eof()\n {{\n return feof($this->handle);\n }}\n\n public function stream_stat()\n {{\n return array();\n }}\n\n public function stream_set_option($option, $arg1, $arg2)\n {{\n return true;\n }}\n\n public function url_stat($path, $flags)\n {{\n $path = substr($path, 17);\n if (file_exists($path)) {{\n return stat($path);\n }}\n\n return false;\n }}\n }}\n }}\n\n if (\n (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))\n || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\\BinProxyWrapper'))\n ) {{\n return include(\"phpvfscomposer://\" . {bin_path_exported});\n }}\n}}\n",
phpunit_hack1 = phpunit_hack1,
diff --git a/crates/shirabe/src/installer/installation_manager.rs b/crates/shirabe/src/installer/installation_manager.rs
index 52831aa..519091f 100644
--- a/crates/shirabe/src/installer/installation_manager.rs
+++ b/crates/shirabe/src/installer/installation_manager.rs
@@ -6,8 +6,8 @@ use shirabe_external_packages::react::promise;
use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use shirabe_external_packages::seld::signal::signal_handler::SignalHandler;
use shirabe_php_shim::{
- array_search_mixed, array_splice, array_unshift, count, http_build_query, json_encode,
- str_contains, str_replace, strpos, strtolower, ucfirst, InvalidArgumentException, PhpMixed,
+ InvalidArgumentException, PhpMixed, array_search_mixed, array_splice, array_unshift, count,
+ http_build_query, json_encode, str_contains, str_replace, strpos, strtolower, ucfirst,
};
use crate::dependency_resolver::operation::install_operation::InstallOperation;
@@ -143,7 +143,9 @@ impl InstallationManager {
&& self.is_package_installed(repo, alias.get_alias_of())?);
}
- Ok(self.get_installer(package.get_type())?.is_installed(repo, package))
+ Ok(self
+ .get_installer(package.get_type())?
+ .is_installed(repo, package))
}
/// Install binary for the given package.
@@ -177,8 +179,10 @@ impl InstallationManager {
download_only: bool,
) -> Result<()> {
// @var array<callable(): ?PromiseInterface<void|null>> $cleanupPromises
- let mut cleanup_promises: IndexMap<i64, Box<dyn Fn() -> Option<Box<dyn PromiseInterface>>>> =
- IndexMap::new();
+ let mut cleanup_promises: IndexMap<
+ i64,
+ Box<dyn Fn() -> Option<Box<dyn PromiseInterface>>>,
+ > = IndexMap::new();
let signal_handler = SignalHandler::create(
vec![
@@ -452,13 +456,16 @@ impl InstallationManager {
};
if run_scripts && self.event_dispatcher.is_some() {
- self.event_dispatcher.as_mut().unwrap().dispatch_package_event(
- event_name,
- dev_mode,
- repo,
- all_operations,
- operation.as_ref(),
- );
+ self.event_dispatcher
+ .as_mut()
+ .unwrap()
+ .dispatch_package_event(
+ event_name,
+ dev_mode,
+ repo,
+ all_operations,
+ operation.as_ref(),
+ );
}
let _dispatcher = self.event_dispatcher.as_ref();
@@ -524,11 +531,8 @@ impl InstallationManager {
// progress.clear();
// ProgressBar in non-decorated output does not output a final line-break and clear() does nothing
if !self.io.is_decorated() {
- self.io.write_error(
- PhpMixed::String(String::new()),
- true,
- IOInterface::NORMAL,
- );
+ self.io
+ .write_error(PhpMixed::String(String::new()), true, IOInterface::NORMAL);
}
}
}
@@ -536,7 +540,10 @@ impl InstallationManager {
/// Executes download operation.
///
/// @phpstan-return PromiseInterface<void|null>|null
- pub fn download(&mut self, package: &dyn PackageInterface) -> Option<Box<dyn PromiseInterface>> {
+ pub fn download(
+ &mut self,
+ package: &dyn PackageInterface,
+ ) -> Option<Box<dyn PromiseInterface>> {
let installer = self.get_installer(package.get_type()).ok()?;
let promise = installer.cleanup("install", package, None);
@@ -579,7 +586,10 @@ impl InstallationManager {
self.mark_for_notification(target);
promise
} else {
- let promise = self.get_installer(initial_type).ok()?.uninstall(repo, initial);
+ let promise = self
+ .get_installer(initial_type)
+ .ok()?
+ .uninstall(repo, initial);
let promise = match promise {
Some(p) => p,
None => promise::resolve(None),
@@ -667,10 +677,7 @@ impl InstallationManager {
let mut opts: IndexMap<String, PhpMixed> = IndexMap::new();
opts.insert("retry-auth-failure".to_string(), PhpMixed::Bool(false));
let mut http: IndexMap<String, PhpMixed> = IndexMap::new();
- http.insert(
- "method".to_string(),
- PhpMixed::String("POST".to_string()),
- );
+ http.insert("method".to_string(), PhpMixed::String("POST".to_string()));
http.insert(
"header".to_string(),
PhpMixed::List(vec![Box::new(PhpMixed::String(
@@ -685,15 +692,16 @@ impl InstallationManager {
opts.insert(
"http".to_string(),
PhpMixed::Array(
- http.into_iter()
- .map(|(k, v)| (k, Box::new(v)))
- .collect(),
+ http.into_iter().map(|(k, v)| (k, Box::new(v))).collect(),
),
);
- promises.push(self.loop_.get_http_downloader().add(&url, &PhpMixed::Array(
- opts.into_iter().map(|(k, v)| (k, Box::new(v))).collect(),
- )));
+ promises.push(self.loop_.get_http_downloader().add(
+ &url,
+ &PhpMixed::Array(
+ opts.into_iter().map(|(k, v)| (k, Box::new(v))).collect(),
+ ),
+ ));
}
continue;
@@ -715,8 +723,7 @@ impl InstallationManager {
if let Some(metadata) =
FileDownloader::download_metadata().get(package.get_name())
{
- package_notification
- .insert("downloaded".to_string(), metadata.clone());
+ package_notification.insert("downloaded".to_string(), metadata.clone());
} else {
package_notification
.insert("downloaded".to_string(), PhpMixed::Bool(false));
@@ -757,16 +764,13 @@ impl InstallationManager {
http.insert("timeout".to_string(), PhpMixed::Int(6));
opts.insert(
"http".to_string(),
- PhpMixed::Array(
- http.into_iter()
- .map(|(k, v)| (k, Box::new(v)))
- .collect(),
- ),
+ PhpMixed::Array(http.into_iter().map(|(k, v)| (k, Box::new(v))).collect()),
);
- promises.push(self.loop_.get_http_downloader().add(repo_url, &PhpMixed::Array(
- opts.into_iter().map(|(k, v)| (k, Box::new(v))).collect(),
- )));
+ promises.push(self.loop_.get_http_downloader().add(
+ repo_url,
+ &PhpMixed::Array(opts.into_iter().map(|(k, v)| (k, Box::new(v))).collect()),
+ ));
}
self.loop_.wait(promises, None);
diff --git a/crates/shirabe/src/installer/installer_event.rs b/crates/shirabe/src/installer/installer_event.rs
index 3d0dccc..456a4bd 100644
--- a/crates/shirabe/src/installer/installer_event.rs
+++ b/crates/shirabe/src/installer/installer_event.rs
@@ -25,7 +25,14 @@ impl InstallerEvent {
transaction: Transaction,
) -> Self {
let inner = Event::new(event_name, vec![], vec![]);
- Self { inner, composer, io, dev_mode, execute_operations, transaction }
+ Self {
+ inner,
+ composer,
+ io,
+ dev_mode,
+ execute_operations,
+ transaction,
+ }
}
pub fn get_composer(&self) -> &Composer {
diff --git a/crates/shirabe/src/installer/installer_interface.rs b/crates/shirabe/src/installer/installer_interface.rs
index fc651bb..16cf10c 100644
--- a/crates/shirabe/src/installer/installer_interface.rs
+++ b/crates/shirabe/src/installer/installer_interface.rs
@@ -1,25 +1,56 @@
//! ref: composer/src/Composer/Installer/InstallerInterface.php
-use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use crate::package::package_interface::PackageInterface;
use crate::repository::installed_repository_interface::InstalledRepositoryInterface;
+use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
pub trait InstallerInterface {
fn supports(&self, package_type: &str) -> bool;
- fn is_installed(&self, repo: &dyn InstalledRepositoryInterface, package: &dyn PackageInterface) -> bool;
+ fn is_installed(
+ &self,
+ repo: &dyn InstalledRepositoryInterface,
+ package: &dyn PackageInterface,
+ ) -> bool;
- fn download(&self, package: &dyn PackageInterface, prev_package: Option<&dyn PackageInterface>) -> anyhow::Result<Option<Box<dyn PromiseInterface>>>;
+ fn download(
+ &self,
+ package: &dyn PackageInterface,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> anyhow::Result<Option<Box<dyn PromiseInterface>>>;
- fn prepare(&self, r#type: &str, package: &dyn PackageInterface, prev_package: Option<&dyn PackageInterface>) -> anyhow::Result<Option<Box<dyn PromiseInterface>>>;
+ fn prepare(
+ &self,
+ r#type: &str,
+ package: &dyn PackageInterface,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> anyhow::Result<Option<Box<dyn PromiseInterface>>>;
- fn install(&self, repo: &mut dyn InstalledRepositoryInterface, package: &dyn PackageInterface) -> anyhow::Result<Option<Box<dyn PromiseInterface>>>;
+ fn install(
+ &self,
+ repo: &mut dyn InstalledRepositoryInterface,
+ package: &dyn PackageInterface,
+ ) -> anyhow::Result<Option<Box<dyn PromiseInterface>>>;
- fn update(&self, repo: &mut dyn InstalledRepositoryInterface, initial: &dyn PackageInterface, target: &dyn PackageInterface) -> anyhow::Result<Option<Box<dyn PromiseInterface>>>;
+ fn update(
+ &self,
+ repo: &mut dyn InstalledRepositoryInterface,
+ initial: &dyn PackageInterface,
+ target: &dyn PackageInterface,
+ ) -> anyhow::Result<Option<Box<dyn PromiseInterface>>>;
- fn uninstall(&self, repo: &mut dyn InstalledRepositoryInterface, package: &dyn PackageInterface) -> anyhow::Result<Option<Box<dyn PromiseInterface>>>;
+ fn uninstall(
+ &self,
+ repo: &mut dyn InstalledRepositoryInterface,
+ package: &dyn PackageInterface,
+ ) -> anyhow::Result<Option<Box<dyn PromiseInterface>>>;
- fn cleanup(&self, r#type: &str, package: &dyn PackageInterface, prev_package: Option<&dyn PackageInterface>) -> anyhow::Result<Option<Box<dyn PromiseInterface>>>;
+ fn cleanup(
+ &self,
+ r#type: &str,
+ package: &dyn PackageInterface,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> anyhow::Result<Option<Box<dyn PromiseInterface>>>;
fn get_install_path(&self, package: &dyn PackageInterface) -> Option<String>;
}
diff --git a/crates/shirabe/src/installer/library_installer.rs b/crates/shirabe/src/installer/library_installer.rs
index cc6e7a6..af11ef6 100644
--- a/crates/shirabe/src/installer/library_installer.rs
+++ b/crates/shirabe/src/installer/library_installer.rs
@@ -6,7 +6,7 @@ use anyhow::Result;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use shirabe_php_shim::{
- is_link, preg_quote, realpath, rmdir, rtrim, strpos, InvalidArgumentException, LogicException,
+ InvalidArgumentException, LogicException, is_link, preg_quote, realpath, rmdir, rtrim, strpos,
};
use crate::composer::Composer;
@@ -84,8 +84,11 @@ impl LibraryInstaller {
/// Make sure binaries are installed for a given package.
pub fn ensure_binaries_presence(&self, package: &dyn PackageInterface) {
- self.binary_installer
- .install_binaries(package, &self.get_install_path(package).unwrap(), false);
+ self.binary_installer.install_binaries(
+ package,
+ &self.get_install_path(package).unwrap(),
+ false,
+ );
}
/// Returns the base path of the package without target-dir path
diff --git a/crates/shirabe/src/installer/metapackage_installer.rs b/crates/shirabe/src/installer/metapackage_installer.rs
index 8be21e7..0a5f872 100644
--- a/crates/shirabe/src/installer/metapackage_installer.rs
+++ b/crates/shirabe/src/installer/metapackage_installer.rs
@@ -1,8 +1,5 @@
//! ref: composer/src/Composer/Installer/MetapackageInstaller.php
-use anyhow::Result;
-use shirabe_php_shim::InvalidArgumentException;
-use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use crate::dependency_resolver::operation::install_operation::InstallOperation;
use crate::dependency_resolver::operation::uninstall_operation::UninstallOperation;
use crate::dependency_resolver::operation::update_operation::UpdateOperation;
@@ -10,6 +7,9 @@ use crate::installer::installer_interface::InstallerInterface;
use crate::io::io_interface::IOInterface;
use crate::package::package_interface::PackageInterface;
use crate::repository::installed_repository_interface::InstalledRepositoryInterface;
+use anyhow::Result;
+use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
+use shirabe_php_shim::InvalidArgumentException;
#[derive(Debug)]
pub struct MetapackageInstaller {
@@ -27,59 +27,116 @@ impl InstallerInterface for MetapackageInstaller {
package_type == "metapackage"
}
- fn is_installed(&self, repo: &dyn InstalledRepositoryInterface, package: &dyn PackageInterface) -> bool {
+ fn is_installed(
+ &self,
+ repo: &dyn InstalledRepositoryInterface,
+ package: &dyn PackageInterface,
+ ) -> bool {
repo.has_package(package)
}
- fn download(&self, _package: &dyn PackageInterface, _prev_package: Option<&dyn PackageInterface>) -> Result<Option<Box<dyn PromiseInterface>>> {
- Ok(Some(shirabe_external_packages::react::promise::resolve(None)))
+ fn download(
+ &self,
+ _package: &dyn PackageInterface,
+ _prev_package: Option<&dyn PackageInterface>,
+ ) -> Result<Option<Box<dyn PromiseInterface>>> {
+ Ok(Some(shirabe_external_packages::react::promise::resolve(
+ None,
+ )))
}
- fn prepare(&self, _type: &str, _package: &dyn PackageInterface, _prev_package: Option<&dyn PackageInterface>) -> Result<Option<Box<dyn PromiseInterface>>> {
- Ok(Some(shirabe_external_packages::react::promise::resolve(None)))
+ fn prepare(
+ &self,
+ _type: &str,
+ _package: &dyn PackageInterface,
+ _prev_package: Option<&dyn PackageInterface>,
+ ) -> Result<Option<Box<dyn PromiseInterface>>> {
+ Ok(Some(shirabe_external_packages::react::promise::resolve(
+ None,
+ )))
}
- fn cleanup(&self, _type: &str, _package: &dyn PackageInterface, _prev_package: Option<&dyn PackageInterface>) -> Result<Option<Box<dyn PromiseInterface>>> {
- Ok(Some(shirabe_external_packages::react::promise::resolve(None)))
+ fn cleanup(
+ &self,
+ _type: &str,
+ _package: &dyn PackageInterface,
+ _prev_package: Option<&dyn PackageInterface>,
+ ) -> Result<Option<Box<dyn PromiseInterface>>> {
+ Ok(Some(shirabe_external_packages::react::promise::resolve(
+ None,
+ )))
}
- fn install(&self, repo: &mut dyn InstalledRepositoryInterface, package: &dyn PackageInterface) -> Result<Option<Box<dyn PromiseInterface>>> {
- self.io.write_error(&format!(" - {}", InstallOperation::format(package, false)), true, IOInterface::NORMAL);
+ fn install(
+ &self,
+ repo: &mut dyn InstalledRepositoryInterface,
+ package: &dyn PackageInterface,
+ ) -> Result<Option<Box<dyn PromiseInterface>>> {
+ self.io.write_error(
+ &format!(" - {}", InstallOperation::format(package, false)),
+ true,
+ IOInterface::NORMAL,
+ );
repo.add_package(package.clone_box());
- Ok(Some(shirabe_external_packages::react::promise::resolve(None)))
+ Ok(Some(shirabe_external_packages::react::promise::resolve(
+ None,
+ )))
}
- fn update(&self, repo: &mut dyn InstalledRepositoryInterface, initial: &dyn PackageInterface, target: &dyn PackageInterface) -> Result<Option<Box<dyn PromiseInterface>>> {
+ fn update(
+ &self,
+ repo: &mut dyn InstalledRepositoryInterface,
+ initial: &dyn PackageInterface,
+ target: &dyn PackageInterface,
+ ) -> Result<Option<Box<dyn PromiseInterface>>> {
if !repo.has_package(initial) {
return Err(InvalidArgumentException {
message: format!("Package is not installed: {}", initial),
code: 0,
- }.into());
+ }
+ .into());
}
- self.io.write_error(&format!(" - {}", UpdateOperation::format(initial, target, false)), true, IOInterface::NORMAL);
+ self.io.write_error(
+ &format!(" - {}", UpdateOperation::format(initial, target, false)),
+ true,
+ IOInterface::NORMAL,
+ );
repo.remove_package(initial);
repo.add_package(target.clone_box());
- Ok(Some(shirabe_external_packages::react::promise::resolve(None)))
+ Ok(Some(shirabe_external_packages::react::promise::resolve(
+ None,
+ )))
}
- fn uninstall(&self, repo: &mut dyn InstalledRepositoryInterface, package: &dyn PackageInterface) -> Result<Option<Box<dyn PromiseInterface>>> {
+ fn uninstall(
+ &self,
+ repo: &mut dyn InstalledRepositoryInterface,
+ package: &dyn PackageInterface,
+ ) -> Result<Option<Box<dyn PromiseInterface>>> {
if !repo.has_package(package) {
return Err(InvalidArgumentException {
message: format!("Package is not installed: {}", package),
code: 0,
- }.into());
+ }
+ .into());
}
- self.io.write_error(&format!(" - {}", UninstallOperation::format(package, false)), true, IOInterface::NORMAL);
+ self.io.write_error(
+ &format!(" - {}", UninstallOperation::format(package, false)),
+ true,
+ IOInterface::NORMAL,
+ );
repo.remove_package(package);
- Ok(Some(shirabe_external_packages::react::promise::resolve(None)))
+ Ok(Some(shirabe_external_packages::react::promise::resolve(
+ None,
+ )))
}
fn get_install_path(&self, _package: &dyn PackageInterface) -> Option<String> {
diff --git a/crates/shirabe/src/installer/noop_installer.rs b/crates/shirabe/src/installer/noop_installer.rs
index fd30f4a..09e6afd 100644
--- a/crates/shirabe/src/installer/noop_installer.rs
+++ b/crates/shirabe/src/installer/noop_installer.rs
@@ -1,10 +1,10 @@
//! ref: composer/src/Composer/Installer/NoopInstaller.php
-use shirabe_php_shim::InvalidArgumentException;
-use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use crate::installer::installer_interface::InstallerInterface;
use crate::package::package_interface::PackageInterface;
use crate::repository::installed_repository_interface::InstalledRepositoryInterface;
+use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
+use shirabe_php_shim::InvalidArgumentException;
#[derive(Debug)]
pub struct NoopInstaller;
@@ -14,36 +14,72 @@ impl InstallerInterface for NoopInstaller {
true
}
- fn is_installed(&self, repo: &dyn InstalledRepositoryInterface, package: &dyn PackageInterface) -> bool {
+ fn is_installed(
+ &self,
+ repo: &dyn InstalledRepositoryInterface,
+ package: &dyn PackageInterface,
+ ) -> bool {
repo.has_package(package)
}
- fn download(&self, _package: &dyn PackageInterface, _prev_package: Option<&dyn PackageInterface>) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
- Ok(Some(shirabe_external_packages::react::promise::resolve(None)))
+ fn download(
+ &self,
+ _package: &dyn PackageInterface,
+ _prev_package: Option<&dyn PackageInterface>,
+ ) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
+ Ok(Some(shirabe_external_packages::react::promise::resolve(
+ None,
+ )))
}
- fn prepare(&self, _type: &str, _package: &dyn PackageInterface, _prev_package: Option<&dyn PackageInterface>) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
- Ok(Some(shirabe_external_packages::react::promise::resolve(None)))
+ fn prepare(
+ &self,
+ _type: &str,
+ _package: &dyn PackageInterface,
+ _prev_package: Option<&dyn PackageInterface>,
+ ) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
+ Ok(Some(shirabe_external_packages::react::promise::resolve(
+ None,
+ )))
}
- fn cleanup(&self, _type: &str, _package: &dyn PackageInterface, _prev_package: Option<&dyn PackageInterface>) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
- Ok(Some(shirabe_external_packages::react::promise::resolve(None)))
+ fn cleanup(
+ &self,
+ _type: &str,
+ _package: &dyn PackageInterface,
+ _prev_package: Option<&dyn PackageInterface>,
+ ) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
+ Ok(Some(shirabe_external_packages::react::promise::resolve(
+ None,
+ )))
}
- fn install(&self, repo: &mut dyn InstalledRepositoryInterface, package: &dyn PackageInterface) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
+ fn install(
+ &self,
+ repo: &mut dyn InstalledRepositoryInterface,
+ package: &dyn PackageInterface,
+ ) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
if !repo.has_package(package) {
repo.add_package(package.clone_box());
}
- Ok(Some(shirabe_external_packages::react::promise::resolve(None)))
+ Ok(Some(shirabe_external_packages::react::promise::resolve(
+ None,
+ )))
}
- fn update(&self, repo: &mut dyn InstalledRepositoryInterface, initial: &dyn PackageInterface, target: &dyn PackageInterface) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
+ fn update(
+ &self,
+ repo: &mut dyn InstalledRepositoryInterface,
+ initial: &dyn PackageInterface,
+ target: &dyn PackageInterface,
+ ) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
if !repo.has_package(initial) {
return Err(InvalidArgumentException {
message: format!("Package is not installed: {}", initial),
code: 0,
- }.into());
+ }
+ .into());
}
repo.remove_package(initial);
@@ -51,19 +87,28 @@ impl InstallerInterface for NoopInstaller {
repo.add_package(target.clone_box());
}
- Ok(Some(shirabe_external_packages::react::promise::resolve(None)))
+ Ok(Some(shirabe_external_packages::react::promise::resolve(
+ None,
+ )))
}
- fn uninstall(&self, repo: &mut dyn InstalledRepositoryInterface, package: &dyn PackageInterface) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
+ fn uninstall(
+ &self,
+ repo: &mut dyn InstalledRepositoryInterface,
+ package: &dyn PackageInterface,
+ ) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
if !repo.has_package(package) {
return Err(InvalidArgumentException {
message: format!("Package is not installed: {}", package),
code: 0,
- }.into());
+ }
+ .into());
}
repo.remove_package(package);
- Ok(Some(shirabe_external_packages::react::promise::resolve(None)))
+ Ok(Some(shirabe_external_packages::react::promise::resolve(
+ None,
+ )))
}
fn get_install_path(&self, package: &dyn PackageInterface) -> Option<String> {
diff --git a/crates/shirabe/src/installer/package_event.rs b/crates/shirabe/src/installer/package_event.rs
index 537e97e..2bf1c6b 100644
--- a/crates/shirabe/src/installer/package_event.rs
+++ b/crates/shirabe/src/installer/package_event.rs
@@ -1,11 +1,11 @@
//! ref: composer/src/Composer/Installer/PackageEvent.php
-use indexmap::IndexMap;
use crate::composer::Composer;
use crate::dependency_resolver::operation::operation_interface::OperationInterface;
use crate::event_dispatcher::event::Event;
use crate::io::io_interface::IOInterface;
use crate::repository::repository_interface::RepositoryInterface;
+use indexmap::IndexMap;
#[derive(Debug)]
pub struct PackageEvent {
diff --git a/crates/shirabe/src/installer/plugin_installer.rs b/crates/shirabe/src/installer/plugin_installer.rs
index 55a936a..1fd2334 100644
--- a/crates/shirabe/src/installer/plugin_installer.rs
+++ b/crates/shirabe/src/installer/plugin_installer.rs
@@ -1,8 +1,5 @@
//! ref: composer/src/Composer/Installer/PluginInstaller.php
-use anyhow::Result;
-use shirabe_php_shim::{empty, LogicException, PhpMixed, UnexpectedValueException};
-use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use crate::installer::binary_installer::BinaryInstaller;
use crate::installer::installer_interface::InstallerInterface;
use crate::installer::library_installer::LibraryInstaller;
@@ -13,6 +10,9 @@ use crate::plugin::plugin_manager::PluginManager;
use crate::repository::installed_repository_interface::InstalledRepositoryInterface;
use crate::util::filesystem::Filesystem;
use crate::util::platform::Platform;
+use anyhow::Result;
+use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
+use shirabe_php_shim::{LogicException, PhpMixed, UnexpectedValueException, empty};
#[derive(Debug)]
pub struct PluginInstaller {
@@ -27,7 +27,13 @@ impl PluginInstaller {
binary_installer: Option<BinaryInstaller>,
) -> Self {
Self {
- inner: LibraryInstaller::new(io, composer, Some("composer-plugin".to_string()), fs, binary_installer),
+ inner: LibraryInstaller::new(
+ io,
+ composer,
+ Some("composer-plugin".to_string()),
+ fs,
+ binary_installer,
+ ),
}
}
@@ -36,8 +42,16 @@ impl PluginInstaller {
self.get_plugin_manager().disable_plugins();
}
- fn rollback_install(&self, e: anyhow::Error, repo: &mut dyn InstalledRepositoryInterface, package: &dyn PackageInterface) -> Result<()> {
- self.inner.io.write_error(&format!("Plugin initialization failed ({}), uninstalling plugin", e));
+ fn rollback_install(
+ &self,
+ e: anyhow::Error,
+ repo: &mut dyn InstalledRepositoryInterface,
+ package: &dyn PackageInterface,
+ ) -> Result<()> {
+ self.inner.io.write_error(&format!(
+ "Plugin initialization failed ({}), uninstalling plugin",
+ e
+ ));
self.inner.uninstall(repo, package)?;
Err(e)
}
@@ -48,7 +62,9 @@ impl PluginInstaller {
self.inner.composer.is_full_composer(),
"{}",
LogicException {
- message: "PluginInstaller should be initialized with a fully loaded Composer instance.".to_string(),
+ message:
+ "PluginInstaller should be initialized with a fully loaded Composer instance."
+ .to_string(),
code: 0,
}
);
@@ -62,24 +78,41 @@ impl InstallerInterface for PluginInstaller {
package_type == "composer-plugin" || package_type == "composer-installer"
}
- fn is_installed(&self, repo: &dyn InstalledRepositoryInterface, package: &dyn PackageInterface) -> bool {
+ fn is_installed(
+ &self,
+ repo: &dyn InstalledRepositoryInterface,
+ package: &dyn PackageInterface,
+ ) -> bool {
self.inner.is_installed(repo, package)
}
- fn prepare(&self, r#type: &str, package: &dyn PackageInterface, prev_package: Option<&dyn PackageInterface>) -> Result<Option<Box<dyn PromiseInterface>>> {
- if (r#type == "install" || r#type == "update") && !self.get_plugin_manager().are_plugins_disabled("local") {
- let plugin_optional = package.get_extra()
+ fn prepare(
+ &self,
+ r#type: &str,
+ package: &dyn PackageInterface,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> Result<Option<Box<dyn PromiseInterface>>> {
+ if (r#type == "install" || r#type == "update")
+ && !self.get_plugin_manager().are_plugins_disabled("local")
+ {
+ let plugin_optional = package
+ .get_extra()
.get("plugin-optional")
.map(|v| matches!(v, PhpMixed::Bool(true)))
.unwrap_or(false);
// TODO(plugin): check if plugin is allowed
- self.get_plugin_manager().is_plugin_allowed(package.get_name(), false, plugin_optional);
+ self.get_plugin_manager()
+ .is_plugin_allowed(package.get_name(), false, plugin_optional);
}
self.inner.prepare(r#type, package, prev_package)
}
- fn download(&self, package: &dyn PackageInterface, prev_package: Option<&dyn PackageInterface>) -> Result<Option<Box<dyn PromiseInterface>>> {
+ fn download(
+ &self,
+ package: &dyn PackageInterface,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> Result<Option<Box<dyn PromiseInterface>>> {
let extra = package.get_extra();
let class = extra.get("class").cloned().unwrap_or(PhpMixed::Null);
if empty(&class) {
@@ -95,7 +128,11 @@ impl InstallerInterface for PluginInstaller {
self.inner.download(package, prev_package)
}
- fn install(&self, repo: &mut dyn InstalledRepositoryInterface, package: &dyn PackageInterface) -> Result<Option<Box<dyn PromiseInterface>>> {
+ fn install(
+ &self,
+ repo: &mut dyn InstalledRepositoryInterface,
+ package: &dyn PackageInterface,
+ ) -> Result<Option<Box<dyn PromiseInterface>>> {
let promise = self.inner.install(repo, package)?;
let promise = match promise {
Some(p) => p,
@@ -111,7 +148,12 @@ impl InstallerInterface for PluginInstaller {
}))))
}
- fn update(&self, repo: &mut dyn InstalledRepositoryInterface, initial: &dyn PackageInterface, target: &dyn PackageInterface) -> Result<Option<Box<dyn PromiseInterface>>> {
+ fn update(
+ &self,
+ repo: &mut dyn InstalledRepositoryInterface,
+ initial: &dyn PackageInterface,
+ target: &dyn PackageInterface,
+ ) -> Result<Option<Box<dyn PromiseInterface>>> {
let promise = self.inner.update(repo, initial, target)?;
let promise = match promise {
Some(p) => p,
@@ -128,14 +170,23 @@ impl InstallerInterface for PluginInstaller {
}))))
}
- fn uninstall(&self, repo: &mut dyn InstalledRepositoryInterface, package: &dyn PackageInterface) -> Result<Option<Box<dyn PromiseInterface>>> {
+ fn uninstall(
+ &self,
+ repo: &mut dyn InstalledRepositoryInterface,
+ package: &dyn PackageInterface,
+ ) -> Result<Option<Box<dyn PromiseInterface>>> {
// TODO(plugin): uninstall package from plugin manager
self.get_plugin_manager().uninstall_package(package);
self.inner.uninstall(repo, package)
}
- fn cleanup(&self, r#type: &str, package: &dyn PackageInterface, prev_package: Option<&dyn PackageInterface>) -> Result<Option<Box<dyn PromiseInterface>>> {
+ fn cleanup(
+ &self,
+ r#type: &str,
+ package: &dyn PackageInterface,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> Result<Option<Box<dyn PromiseInterface>>> {
self.inner.cleanup(r#type, package, prev_package)
}
diff --git a/crates/shirabe/src/installer/project_installer.rs b/crates/shirabe/src/installer/project_installer.rs
index 6472472..1a097b0 100644
--- a/crates/shirabe/src/installer/project_installer.rs
+++ b/crates/shirabe/src/installer/project_installer.rs
@@ -1,12 +1,12 @@
//! ref: composer/src/Composer/Installer/ProjectInstaller.php
-use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
-use shirabe_php_shim::InvalidArgumentException;
use crate::downloader::download_manager::DownloadManager;
use crate::installer::installer_interface::InstallerInterface;
use crate::package::package_interface::PackageInterface;
use crate::repository::installed_repository_interface::InstalledRepositoryInterface;
use crate::util::filesystem::Filesystem;
+use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
+use shirabe_php_shim::InvalidArgumentException;
#[derive(Debug)]
pub struct ProjectInstaller {
@@ -31,49 +31,88 @@ impl InstallerInterface for ProjectInstaller {
true
}
- fn is_installed(&self, _repo: &dyn InstalledRepositoryInterface, _package: &dyn PackageInterface) -> bool {
+ fn is_installed(
+ &self,
+ _repo: &dyn InstalledRepositoryInterface,
+ _package: &dyn PackageInterface,
+ ) -> bool {
false
}
- fn download(&self, package: &dyn PackageInterface, prev_package: Option<&dyn PackageInterface>) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
+ fn download(
+ &self,
+ package: &dyn PackageInterface,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
let install_path = &self.install_path;
- if std::path::Path::new(install_path).exists() && !self.filesystem.is_dir_empty(install_path) {
+ if std::path::Path::new(install_path).exists()
+ && !self.filesystem.is_dir_empty(install_path)
+ {
return Err(InvalidArgumentException {
message: format!("Project directory {} is not empty.", install_path),
code: 0,
- }.into());
+ }
+ .into());
}
if !std::path::Path::new(install_path).is_dir() {
std::fs::create_dir_all(install_path)?;
}
- self.download_manager.download(package, install_path, prev_package)
+ self.download_manager
+ .download(package, install_path, prev_package)
}
- fn prepare(&self, r#type: &str, package: &dyn PackageInterface, prev_package: Option<&dyn PackageInterface>) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
- self.download_manager.prepare(r#type, package, &self.install_path, prev_package)
+ fn prepare(
+ &self,
+ r#type: &str,
+ package: &dyn PackageInterface,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
+ self.download_manager
+ .prepare(r#type, package, &self.install_path, prev_package)
}
- fn cleanup(&self, r#type: &str, package: &dyn PackageInterface, prev_package: Option<&dyn PackageInterface>) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
- self.download_manager.cleanup(r#type, package, &self.install_path, prev_package)
+ fn cleanup(
+ &self,
+ r#type: &str,
+ package: &dyn PackageInterface,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
+ self.download_manager
+ .cleanup(r#type, package, &self.install_path, prev_package)
}
- fn install(&self, _repo: &mut dyn InstalledRepositoryInterface, package: &dyn PackageInterface) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
+ fn install(
+ &self,
+ _repo: &mut dyn InstalledRepositoryInterface,
+ package: &dyn PackageInterface,
+ ) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
self.download_manager.install(package, &self.install_path)
}
- fn update(&self, _repo: &mut dyn InstalledRepositoryInterface, _initial: &dyn PackageInterface, _target: &dyn PackageInterface) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
+ fn update(
+ &self,
+ _repo: &mut dyn InstalledRepositoryInterface,
+ _initial: &dyn PackageInterface,
+ _target: &dyn PackageInterface,
+ ) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
Err(InvalidArgumentException {
message: "not supported".to_string(),
code: 0,
- }.into())
+ }
+ .into())
}
- fn uninstall(&self, _repo: &mut dyn InstalledRepositoryInterface, _package: &dyn PackageInterface) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
+ fn uninstall(
+ &self,
+ _repo: &mut dyn InstalledRepositoryInterface,
+ _package: &dyn PackageInterface,
+ ) -> anyhow::Result<Option<Box<dyn PromiseInterface>>> {
Err(InvalidArgumentException {
message: "not supported".to_string(),
code: 0,
- }.into())
+ }
+ .into())
}
fn get_install_path(&self, _package: &dyn PackageInterface) -> Option<String> {
diff --git a/crates/shirabe/src/installer/suggested_packages_reporter.rs b/crates/shirabe/src/installer/suggested_packages_reporter.rs
index 77b4c34..cfee20b 100644
--- a/crates/shirabe/src/installer/suggested_packages_reporter.rs
+++ b/crates/shirabe/src/installer/suggested_packages_reporter.rs
@@ -1,11 +1,11 @@
//! ref: composer/src/Composer/Installer/SuggestedPackagesReporter.php
-use indexmap::IndexMap;
-use shirabe_external_packages::composer::pcre::preg::Preg;
-use shirabe_external_packages::symfony::component::console::formatter::output_formatter::OutputFormatter;
use crate::io::io_interface::IOInterface;
use crate::package::package_interface::PackageInterface;
use crate::repository::installed_repository::InstalledRepository;
+use indexmap::IndexMap;
+use shirabe_external_packages::composer::pcre::preg::Preg;
+use shirabe_external_packages::symfony::component::console::formatter::output_formatter::OutputFormatter;
#[derive(Debug)]
pub struct SuggestedPackagesReporter {
@@ -48,7 +48,12 @@ impl SuggestedPackagesReporter {
self
}
- pub fn output(&self, mode: i64, installed_repo: Option<&InstalledRepository>, only_dependents_of: Option<&dyn PackageInterface>) {
+ pub fn output(
+ &self,
+ mode: i64,
+ installed_repo: Option<&InstalledRepository>,
+ only_dependents_of: Option<&dyn PackageInterface>,
+ ) {
let suggested_packages = self.get_filtered_suggestions(installed_repo, only_dependents_of);
let mut suggesters: IndexMap<String, IndexMap<String, String>> = IndexMap::new();
@@ -78,7 +83,8 @@ impl SuggestedPackagesReporter {
// Grouped by package
if mode & Self::MODE_BY_PACKAGE != 0 {
for (suggester, suggestions) in &suggesters {
- self.io.write(&format!("<comment>{}</comment> suggests:", suggester));
+ self.io
+ .write(&format!("<comment>{}</comment> suggests:", suggester));
for (suggestion, reason) in suggestions {
self.io.write(&format!(
@@ -102,7 +108,10 @@ impl SuggestedPackagesReporter {
self.io.write(&"-".repeat(78));
}
for (suggestion, suggesters) in &suggested {
- self.io.write(&format!("<comment>{}</comment> is suggested by:", suggestion));
+ self.io.write(&format!(
+ "<comment>{}</comment> is suggested by:",
+ suggestion
+ ));
for (suggester, reason) in suggesters {
self.io.write(&format!(
@@ -128,7 +137,11 @@ impl SuggestedPackagesReporter {
}
}
- pub fn output_minimalistic(&self, installed_repo: Option<&InstalledRepository>, only_dependents_of: Option<&dyn PackageInterface>) {
+ pub fn output_minimalistic(
+ &self,
+ installed_repo: Option<&InstalledRepository>,
+ only_dependents_of: Option<&dyn PackageInterface>,
+ ) {
let suggested_packages = self.get_filtered_suggestions(installed_repo, only_dependents_of);
if !suggested_packages.is_empty() {
self.io.write_error(&format!(
@@ -138,7 +151,11 @@ impl SuggestedPackagesReporter {
}
}
- fn get_filtered_suggestions(&self, installed_repo: Option<&InstalledRepository>, only_dependents_of: Option<&dyn PackageInterface>) -> Vec<IndexMap<String, String>> {
+ fn get_filtered_suggestions(
+ &self,
+ installed_repo: Option<&InstalledRepository>,
+ only_dependents_of: Option<&dyn PackageInterface>,
+ ) -> Vec<IndexMap<String, String>> {
let suggested_packages = self.get_packages();
let mut installed_names: Vec<String> = Vec::new();
if installed_repo.is_some() && !suggested_packages.is_empty() {
@@ -149,7 +166,9 @@ impl SuggestedPackagesReporter {
let mut source_filter: Vec<String> = Vec::new();
if let Some(only_dependents_of) = only_dependents_of {
- source_filter = only_dependents_of.get_requires().values()
+ source_filter = only_dependents_of
+ .get_requires()
+ .values()
.chain(only_dependents_of.get_dev_requires().values())
.map(|link| link.get_target().to_string())
.collect();
@@ -171,16 +190,10 @@ impl SuggestedPackagesReporter {
}
fn escape_output(&self, string: &str) -> String {
- OutputFormatter::escape(
- &self.remove_control_characters(string)
- )
+ OutputFormatter::escape(&self.remove_control_characters(string))
}
fn remove_control_characters(&self, string: &str) -> String {
- Preg::replace(
- "/[[:cntrl:]]/",
- "",
- &string.replace('\n', " "),
- )
+ Preg::replace("/[[:cntrl:]]/", "", &string.replace('\n', " "))
}
}
diff --git a/crates/shirabe/src/io/base_io.rs b/crates/shirabe/src/io/base_io.rs
index f1cff3c..58d1e40 100644
--- a/crates/shirabe/src/io/base_io.rs
+++ b/crates/shirabe/src/io/base_io.rs
@@ -1,16 +1,16 @@
//! ref: composer/src/Composer/IO/BaseIO.php
+use crate::config::Config;
+use crate::io::io_interface::IOInterface;
+use crate::util::process_executor::ProcessExecutor;
+use crate::util::silencer::Silencer;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::psr::log::log_level::LogLevel;
use shirabe_php_shim::{
- array_merge, in_array, json_encode_ex, PhpMixed, UnexpectedValueException,
- JSON_INVALID_UTF8_IGNORE, JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE,
+ JSON_INVALID_UTF8_IGNORE, JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE, PhpMixed,
+ UnexpectedValueException, array_merge, in_array, json_encode_ex,
};
-use crate::config::Config;
-use crate::io::io_interface::IOInterface;
-use crate::util::process_executor::ProcessExecutor;
-use crate::util::silencer::Silencer;
#[derive(Debug)]
pub struct BaseIO {
@@ -344,20 +344,15 @@ impl BaseIO {
let mut ssl_options: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
if let Some(cert) = local_cert {
- ssl_options.insert(
- "local_cert".to_string(),
- Box::new(PhpMixed::String(cert)),
- );
+ ssl_options
+ .insert("local_cert".to_string(), Box::new(PhpMixed::String(cert)));
}
if let Some(pk) = local_pk {
- ssl_options
- .insert("local_pk".to_string(), Box::new(PhpMixed::String(pk)));
+ ssl_options.insert("local_pk".to_string(), Box::new(PhpMixed::String(pk)));
}
if let Some(pass) = passphrase {
- ssl_options.insert(
- "passphrase".to_string(),
- Box::new(PhpMixed::String(pass)),
- );
+ ssl_options
+ .insert("passphrase".to_string(), Box::new(PhpMixed::String(pass)));
}
if !ssl_options.contains_key("local_cert") {
diff --git a/crates/shirabe/src/io/buffer_io.rs b/crates/shirabe/src/io/buffer_io.rs
index 30e2aeb..aa1d970 100644
--- a/crates/shirabe/src/io/buffer_io.rs
+++ b/crates/shirabe/src/io/buffer_io.rs
@@ -1,5 +1,6 @@
//! ref: composer/src/Composer/IO/BufferIO.php
+use crate::io::console_io::ConsoleIO;
use anyhow::Result;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::symfony::console::formatter::output_formatter_interface::OutputFormatterInterface;
@@ -8,8 +9,10 @@ use shirabe_external_packages::symfony::console::helper::question_helper::Questi
use shirabe_external_packages::symfony::console::input::streamable_input_interface::StreamableInputInterface;
use shirabe_external_packages::symfony::console::input::string_input::StringInput;
use shirabe_external_packages::symfony::console::output::stream_output::StreamOutput;
-use shirabe_php_shim::{fopen, fseek, fwrite, rewind, stream_get_contents, strip_tags, PhpMixed, RuntimeException, PHP_EOL};
-use crate::io::console_io::ConsoleIO;
+use shirabe_php_shim::{
+ PHP_EOL, PhpMixed, RuntimeException, fopen, fseek, fwrite, rewind, stream_get_contents,
+ strip_tags,
+};
#[derive(Debug)]
pub struct BufferIO {
@@ -17,7 +20,11 @@ pub struct BufferIO {
}
impl BufferIO {
- pub fn new(input: String, verbosity: i64, formatter: Option<Box<dyn OutputFormatterInterface>>) -> Result<Self> {
+ pub fn new(
+ input: String,
+ verbosity: i64,
+ formatter: Option<Box<dyn OutputFormatterInterface>>,
+ ) -> Result<Self> {
let mut input_obj = StringInput::new(input);
input_obj.set_interactive(false);
@@ -66,7 +73,13 @@ impl BufferIO {
}
pub fn set_user_inputs(&mut self, inputs: Vec<String>) -> Result<()> {
- if self.inner.input.as_any().downcast_ref::<dyn StreamableInputInterface>().is_none() {
+ if self
+ .inner
+ .input
+ .as_any()
+ .downcast_ref::<dyn StreamableInputInterface>()
+ .is_none()
+ {
return Err(RuntimeException {
message: "Setting the user inputs requires at least the version 3.2 of the symfony/console component.".to_string(),
code: 0,
diff --git a/crates/shirabe/src/io/console_io.rs b/crates/shirabe/src/io/console_io.rs
index 8dd9f0b..0794ca5 100644
--- a/crates/shirabe/src/io/console_io.rs
+++ b/crates/shirabe/src/io/console_io.rs
@@ -11,9 +11,9 @@ use shirabe_external_packages::symfony::component::console::output::output_inter
use shirabe_external_packages::symfony::component::console::question::choice_question::ChoiceQuestion;
use shirabe_external_packages::symfony::component::console::question::question::Question;
use shirabe_php_shim::{
- array_filter, array_keys, array_search, count, function_exists, implode, in_array, is_array,
- is_string, mb_check_encoding, mb_convert_encoding, microtime, sprintf, str_repeat, strip_tags,
- strlen, PhpMixed,
+ PhpMixed, array_filter, array_keys, array_search, count, function_exists, implode, in_array,
+ is_array, is_string, mb_check_encoding, mb_convert_encoding, microtime, sprintf, str_repeat,
+ strip_tags, strlen,
};
use crate::io::base_io::BaseIO;
@@ -158,7 +158,12 @@ impl ConsoleIO {
)
})
.collect();
- PhpMixed::List(mapped.into_iter().map(|s| Box::new(PhpMixed::String(s))).collect())
+ PhpMixed::List(
+ mapped
+ .into_iter()
+ .map(|s| Box::new(PhpMixed::String(s)))
+ .collect(),
+ )
} else {
messages
};
@@ -396,8 +401,8 @@ impl ConsoleIO {
PhpMixed::List(_) => vec![],
_ => vec![],
};
- let is_assoc = !choice_keys.is_empty()
- && choice_keys.iter().any(|k| !k.parse::<i64>().is_ok());
+ let is_assoc =
+ !choice_keys.is_empty() && choice_keys.iter().any(|k| !k.parse::<i64>().is_ok());
if is_assoc {
return result;
}
@@ -410,9 +415,7 @@ impl ConsoleIO {
PhpMixed::List(l) => l
.iter()
.enumerate()
- .filter_map(|(i, v)| {
- v.as_string().map(|s| (i.to_string(), s.to_string()))
- })
+ .filter_map(|(i, v)| v.as_string().map(|s| (i.to_string(), s.to_string())))
.collect(),
_ => IndexMap::new(),
};
@@ -431,11 +434,7 @@ impl ConsoleIO {
_ => vec![],
};
for (index, choice) in &choice_list {
- if in_array(
- choice.clone(),
- &PhpMixed::List(result_list.clone()),
- true,
- ) {
+ if in_array(choice.clone(), &PhpMixed::List(result_list.clone()), true) {
results.push(index.clone());
}
}
@@ -455,7 +454,9 @@ impl ConsoleIO {
fn get_error_output(&self) -> &dyn OutputInterface {
if self.output.is_console_output_interface() {
// TODO(phase-b): downcast Box<dyn OutputInterface> to ConsoleOutputInterface
- return todo!("downcast self.output to ConsoleOutputInterface and call get_error_output()");
+ return todo!(
+ "downcast self.output to ConsoleOutputInterface and call get_error_output()"
+ );
}
&*self.output
@@ -480,7 +481,10 @@ impl ConsoleIO {
let escape_pattern =
r"\x1B\[[\x30-\x3F]*[\x20-\x2F]*[\x40-\x7E]|\x1B\].*?(?:\x1B\\|\x07)|\x1B.";
let pattern = if allow_newlines {
- format!("{{{}|[\\x01-\\x09\\x0B\\x0C\\x0E-\\x1A]|\\r(?!\\n)}}u", escape_pattern)
+ format!(
+ "{{{}|[\\x01-\\x09\\x0B\\x0C\\x0E-\\x1A]|\\r(?!\\n)}}u",
+ escape_pattern
+ )
} else {
format!("{{{}|[\\x01-\\x1A]}}u", escape_pattern)
};
@@ -495,15 +499,19 @@ impl ConsoleIO {
PhpMixed::List(l) => {
for (key, message) in l.iter().enumerate() {
let s = Self::ensure_valid_utf8(message.as_string().unwrap_or(""));
- sanitized
- .insert(key.to_string(), PhpMixed::String(Preg::replace(&pattern, "", &s)));
+ sanitized.insert(
+ key.to_string(),
+ PhpMixed::String(Preg::replace(&pattern, "", &s)),
+ );
}
}
PhpMixed::Array(a) => {
for (key, message) in a {
let s = Self::ensure_valid_utf8(message.as_string().unwrap_or(""));
- sanitized
- .insert(key.clone(), PhpMixed::String(Preg::replace(&pattern, "", &s)));
+ sanitized.insert(
+ key.clone(),
+ PhpMixed::String(Preg::replace(&pattern, "", &s)),
+ );
}
}
_ => {}
@@ -532,9 +540,8 @@ impl ConsoleIO {
// Fallback to iconv if mbstring unavailable
if function_exists("iconv") {
- let cleaned = Silencer::call(|| {
- Ok(shirabe_php_shim::iconv("UTF-8", "UTF-8//TRANSLIT", string))
- });
+ let cleaned =
+ Silencer::call(|| Ok(shirabe_php_shim::iconv("UTF-8", "UTF-8//TRANSLIT", string)));
if let Ok(Some(c)) = cleaned {
return c;
}
diff --git a/crates/shirabe/src/io/io_interface.rs b/crates/shirabe/src/io/io_interface.rs
index 1a6eb3f..446f47c 100644
--- a/crates/shirabe/src/io/io_interface.rs
+++ b/crates/shirabe/src/io/io_interface.rs
@@ -1,9 +1,9 @@
//! ref: composer/src/Composer/IO/IOInterface.php
+use crate::config::Config;
use indexmap::IndexMap;
-use shirabe_php_shim::PhpMixed;
use shirabe_external_packages::psr::log::logger_interface::LoggerInterface;
-use crate::config::Config;
+use shirabe_php_shim::PhpMixed;
pub trait IOInterface: LoggerInterface {
const QUIET: i64 = 1;
@@ -38,11 +38,25 @@ pub trait IOInterface: LoggerInterface {
fn ask_confirmation(&self, question: String, default: bool) -> bool;
- fn ask_and_validate(&self, question: String, validator: Box<dyn Fn(PhpMixed) -> PhpMixed>, attempts: Option<i64>, default: PhpMixed) -> PhpMixed;
+ fn ask_and_validate(
+ &self,
+ question: String,
+ validator: Box<dyn Fn(PhpMixed) -> PhpMixed>,
+ attempts: Option<i64>,
+ default: PhpMixed,
+ ) -> PhpMixed;
fn ask_and_hide_answer(&self, question: String) -> Option<String>;
- fn select(&self, question: String, choices: Vec<String>, default: PhpMixed, attempts: PhpMixed, error_message: String, multiselect: bool) -> PhpMixed;
+ fn select(
+ &self,
+ question: String,
+ choices: Vec<String>,
+ default: PhpMixed,
+ attempts: PhpMixed,
+ error_message: String,
+ multiselect: bool,
+ ) -> PhpMixed;
fn get_authentications(&self) -> IndexMap<String, IndexMap<String, Option<String>>>;
@@ -50,7 +64,12 @@ pub trait IOInterface: LoggerInterface {
fn get_authentication(&self, repository_name: &str) -> IndexMap<String, Option<String>>;
- fn set_authentication(&self, repository_name: String, username: String, password: Option<String>);
+ fn set_authentication(
+ &self,
+ repository_name: String,
+ username: String,
+ password: Option<String>,
+ );
fn load_configuration(&self, config: &Config);
}
diff --git a/crates/shirabe/src/io/mod.rs b/crates/shirabe/src/io/mod.rs
new file mode 100644
index 0000000..a75d459
--- /dev/null
+++ b/crates/shirabe/src/io/mod.rs
@@ -0,0 +1,5 @@
+pub mod base_io;
+pub mod buffer_io;
+pub mod console_io;
+pub mod io_interface;
+pub mod null_io;
diff --git a/crates/shirabe/src/io/null_io.rs b/crates/shirabe/src/io/null_io.rs
index ad41746..4218398 100644
--- a/crates/shirabe/src/io/null_io.rs
+++ b/crates/shirabe/src/io/null_io.rs
@@ -1,8 +1,8 @@
//! ref: composer/src/Composer/IO/NullIO.php
-use shirabe_php_shim::PhpMixed;
use crate::io::base_io::BaseIO;
use crate::io::io_interface::IOInterface;
+use shirabe_php_shim::PhpMixed;
#[derive(Debug)]
pub struct NullIO {
@@ -30,16 +30,19 @@ impl IOInterface for NullIO {
false
}
- fn write(&self, _messages: PhpMixed, _newline: bool, _verbosity: i64) {
- }
+ fn write(&self, _messages: PhpMixed, _newline: bool, _verbosity: i64) {}
- fn write_error(&self, _messages: PhpMixed, _newline: bool, _verbosity: i64) {
- }
+ fn write_error(&self, _messages: PhpMixed, _newline: bool, _verbosity: i64) {}
- fn overwrite(&self, _messages: PhpMixed, _newline: bool, _size: Option<i64>, _verbosity: i64) {
- }
+ fn overwrite(&self, _messages: PhpMixed, _newline: bool, _size: Option<i64>, _verbosity: i64) {}
- fn overwrite_error(&self, _messages: PhpMixed, _newline: bool, _size: Option<i64>, _verbosity: i64) {
+ fn overwrite_error(
+ &self,
+ _messages: PhpMixed,
+ _newline: bool,
+ _size: Option<i64>,
+ _verbosity: i64,
+ ) {
}
fn ask(&self, _question: String, default: PhpMixed) -> PhpMixed {
@@ -50,7 +53,13 @@ impl IOInterface for NullIO {
default
}
- fn ask_and_validate(&self, _question: String, _validator: Box<dyn Fn(PhpMixed) -> PhpMixed>, _attempts: Option<i64>, default: PhpMixed) -> PhpMixed {
+ fn ask_and_validate(
+ &self,
+ _question: String,
+ _validator: Box<dyn Fn(PhpMixed) -> PhpMixed>,
+ _attempts: Option<i64>,
+ default: PhpMixed,
+ ) -> PhpMixed {
default
}
@@ -58,7 +67,15 @@ impl IOInterface for NullIO {
None
}
- fn select(&self, _question: String, _choices: Vec<String>, default: PhpMixed, _attempts: PhpMixed, _error_message: String, _multiselect: bool) -> PhpMixed {
+ fn select(
+ &self,
+ _question: String,
+ _choices: Vec<String>,
+ default: PhpMixed,
+ _attempts: PhpMixed,
+ _error_message: String,
+ _multiselect: bool,
+ ) -> PhpMixed {
default
}
}
diff --git a/crates/shirabe/src/json/json_file.rs b/crates/shirabe/src/json/json_file.rs
index c6ec3cd..cdb9ba7 100644
--- a/crates/shirabe/src/json/json_file.rs
+++ b/crates/shirabe/src/json/json_file.rs
@@ -6,12 +6,12 @@ use shirabe_external_packages::json_schema::validator::Validator;
use shirabe_external_packages::seld::json_lint::json_parser::JsonParser;
use shirabe_external_packages::seld::json_lint::parsing_exception::ParsingException;
use shirabe_php_shim::{
+ InvalidArgumentException, JSON_ERROR_CTRL_CHAR, JSON_ERROR_DEPTH, JSON_ERROR_NONE,
+ JSON_ERROR_STATE_MISMATCH, JSON_ERROR_UTF8, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES,
+ JSON_UNESCAPED_UNICODE, PhpMixed, RuntimeException, Silencer, UnexpectedValueException,
defined, dirname, file_exists, file_get_contents, file_put_contents, is_dir, is_file,
json_decode, json_encode_ex, json_last_error, mkdir, php_dir, realpath, str_contains,
- str_ends_with, str_repeat, strlen, strpos, usleep, InvalidArgumentException, PhpMixed,
- RuntimeException, Silencer, UnexpectedValueException, JSON_ERROR_CTRL_CHAR, JSON_ERROR_DEPTH,
- JSON_ERROR_NONE, JSON_ERROR_STATE_MISMATCH, JSON_ERROR_UTF8, JSON_PRETTY_PRINT,
- JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE,
+ str_ends_with, str_repeat, strlen, strpos, usleep,
};
use crate::downloader::transport_exception::TransportException;
@@ -236,7 +236,9 @@ impl JsonFile {
/// @return int|false
fn file_put_contents_if_modified(&self, path: &str, content: &str) -> Result<Option<i64>> {
// PHP: @file_get_contents($path)
- let current_content = Silencer::call(|| Ok(file_get_contents(path))).ok().flatten();
+ let current_content = Silencer::call(|| Ok(file_get_contents(path)))
+ .ok()
+ .flatten();
if current_content.is_none() || current_content.as_deref() != Some(content) {
return Ok(file_put_contents(path, content.as_bytes()));
}
@@ -518,11 +520,18 @@ impl JsonFile {
let result = result.unwrap();
Err(match file {
None => ParsingException::new(
- format!("The input does not contain valid JSON\n{}", result.get_message()),
+ format!(
+ "The input does not contain valid JSON\n{}",
+ result.get_message()
+ ),
result.get_details(),
),
Some(f) => ParsingException::new(
- format!("\"{}\" does not contain valid JSON\n{}", f, result.get_message()),
+ format!(
+ "\"{}\" does not contain valid JSON\n{}",
+ f,
+ result.get_message()
+ ),
result.get_details(),
),
}
@@ -530,10 +539,7 @@ impl JsonFile {
}
pub fn detect_indenting(json: Option<&str>) -> String {
- if let Some(m) = Preg::is_match_strict_groups(
- r##"#^([ \t]+)"#m"##,
- json.unwrap_or(""),
- ) {
+ if let Some(m) = Preg::is_match_strict_groups(r##"#^([ \t]+)"#m"##, json.unwrap_or("")) {
return m.get(1).cloned().unwrap_or_default();
}
diff --git a/crates/shirabe/src/json/json_formatter.rs b/crates/shirabe/src/json/json_formatter.rs
index a88bfff..1696982 100644
--- a/crates/shirabe/src/json/json_formatter.rs
+++ b/crates/shirabe/src/json/json_formatter.rs
@@ -1,7 +1,7 @@
//! ref: composer/src/Composer/Json/JsonFormatter.php
use shirabe_external_packages::composer::pcre::preg::Preg;
-use shirabe_php_shim::{function_exists, mb_convert_encoding, pack, PhpMixed};
+use shirabe_php_shim::{PhpMixed, function_exists, mb_convert_encoding, pack};
pub struct JsonFormatter;
diff --git a/crates/shirabe/src/json/json_manipulator.rs b/crates/shirabe/src/json/json_manipulator.rs
index 1ba2d30..ebbfff9 100644
--- a/crates/shirabe/src/json/json_manipulator.rs
+++ b/crates/shirabe/src/json/json_manipulator.rs
@@ -4,11 +4,10 @@ use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- addcslashes, array_key_exists, array_keys, array_reverse, count, explode, implode, in_array,
- is_array, is_int, is_numeric, json_decode, max_i64, preg_quote, rtrim, str_contains,
- str_repeat, str_replace, strlen, strnatcmp, strpos, substr, trim, uksort,
- ArrayObject, InvalidArgumentException, LogicException, PhpMixed, RuntimeException, StdClass,
- PREG_BACKTRACK_LIMIT_ERROR,
+ ArrayObject, InvalidArgumentException, LogicException, PREG_BACKTRACK_LIMIT_ERROR, PhpMixed,
+ RuntimeException, StdClass, addcslashes, array_key_exists, array_keys, array_reverse, count,
+ explode, implode, in_array, is_array, is_int, is_numeric, json_decode, max_i64, preg_quote,
+ rtrim, str_contains, str_repeat, str_replace, strlen, strnatcmp, strpos, substr, trim, uksort,
};
use crate::json::json_file::JsonFile;
@@ -66,20 +65,32 @@ impl JsonManipulator {
format!("{}{}", self.contents, self.newline)
}
- pub fn add_link(&mut self, r#type: &str, package: &str, constraint: &str, sort_packages: bool) -> anyhow::Result<bool> {
+ pub fn add_link(
+ &mut self,
+ r#type: &str,
+ package: &str,
+ constraint: &str,
+ sort_packages: bool,
+ ) -> anyhow::Result<bool> {
let decoded = JsonFile::parse_json(&self.contents, "composer.json")?;
// no link of that type yet
if decoded.as_array().and_then(|a| a.get(r#type)).is_none() {
let mut arr: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
- arr.insert(package.to_string(), Box::new(PhpMixed::String(constraint.to_string())));
+ arr.insert(
+ package.to_string(),
+ Box::new(PhpMixed::String(constraint.to_string())),
+ );
return self.add_main_key(r#type, PhpMixed::Array(arr));
}
let regex = format!(
"{{{}^(?P<start>\\s*\\{{\\s*(?:(?&string)\\s*:\\s*(?&json)\\s*,\\s*)*?)(?P<property>{}\\s*:\\s*)(?P<value>(?&json))(?P<end>.*)}}sx",
Self::DEFINES,
- preg_quote(&JsonFile::encode(&PhpMixed::String(r#type.to_string()), 0)?, None),
+ preg_quote(
+ &JsonFile::encode(&PhpMixed::String(r#type.to_string()), 0)?,
+ None
+ ),
);
let mut matches: IndexMap<String, String> = IndexMap::new();
if !Preg::is_match_named(&regex, &self.contents, &mut matches).unwrap_or(false) {
@@ -114,7 +125,11 @@ impl JsonManipulator {
Box::new(move |m: &IndexMap<String, String>| -> String {
format!(
"{}{}\"{}\"",
- JsonFile::encode(&PhpMixed::String(str_replace("\\/", "/", &existing_owned)), 0).unwrap_or_default(),
+ JsonFile::encode(
+ &PhpMixed::String(str_replace("\\/", "/", &existing_owned)),
+ 0
+ )
+ .unwrap_or_default(),
m.get("separator").cloned().unwrap_or_default(),
constraint_owned
)
@@ -123,7 +138,13 @@ impl JsonManipulator {
);
} else {
let mut groups: Vec<String> = vec![];
- if Preg::is_match_strict_groups("#^\\s*\\{\\s*\\S+.*?(\\s*\\}\\s*)$#s", &links, Some(&mut groups)).unwrap_or(false) {
+ if Preg::is_match_strict_groups(
+ "#^\\s*\\{\\s*\\S+.*?(\\s*\\}\\s*)$#s",
+ &links,
+ Some(&mut groups),
+ )
+ .unwrap_or(false)
+ {
// link missing but non empty links
links = Preg::replace(
&format!("{{{}$}}", preg_quote(&groups[1], None)),
@@ -201,7 +222,12 @@ impl JsonManipulator {
}
}
- pub fn add_repository(&mut self, name: &str, config: PhpMixed, append: bool) -> anyhow::Result<bool> {
+ pub fn add_repository(
+ &mut self,
+ name: &str,
+ config: PhpMixed,
+ append: bool,
+ ) -> anyhow::Result<bool> {
if "" != name && !self.do_remove_repository(name)? {
return Ok(false);
}
@@ -213,7 +239,10 @@ impl JsonManipulator {
let final_config = if is_array(&config) && !is_numeric(name) && "" != name {
// PHP: ['name' => $name] + $config — preserve $config keys
let mut merged: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
- merged.insert("name".to_string(), Box::new(PhpMixed::String(name.to_string())));
+ merged.insert(
+ "name".to_string(),
+ Box::new(PhpMixed::String(name.to_string())),
+ );
if let Some(arr) = config.as_array() {
for (k, v) in arr {
if !merged.contains_key(k) {
@@ -270,10 +299,14 @@ impl JsonManipulator {
return Ok(false);
}
} else {
- let repo: IndexMap<String, Box<PhpMixed>> = repository.as_array().cloned().unwrap_or_default();
+ let repo: IndexMap<String, Box<PhpMixed>> =
+ repository.as_array().cloned().unwrap_or_default();
// prepend name property
let mut prepended: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
- prepended.insert("name".to_string(), Box::new(PhpMixed::String(repository_name.clone())));
+ prepended.insert(
+ "name".to_string(),
+ Box::new(PhpMixed::String(repository_name.clone())),
+ );
for (k, v) in &repo {
if !prepended.contains_key(k) {
prepended.insert(k.clone(), v.clone());
@@ -305,7 +338,10 @@ impl JsonManipulator {
break;
}
- let repo_name = repository.as_array().and_then(|a| a.get("name")).and_then(|v| v.as_string());
+ let repo_name = repository
+ .as_array()
+ .and_then(|a| a.get("name"))
+ .and_then(|v| v.as_string());
if Some(name) == repo_name {
repository_index = Some(PhpMixed::String(index.clone()));
break;
@@ -338,7 +374,9 @@ impl JsonManipulator {
let list_match = list_regex.as_ref().map_or(false, |r| {
Preg::is_match_named(r, &self.contents, &mut matches).unwrap_or(false)
});
- if list_match || Preg::is_match_named(&object_regex, &self.contents, &mut matches).unwrap_or(false) {
+ if list_match
+ || Preg::is_match_named(&object_regex, &self.contents, &mut matches).unwrap_or(false)
+ {
// invalid match due to un-regexable content, abort
let raw_repo = matches.get("repository").cloned().unwrap_or_default();
if json_decode(&raw_repo, false).as_bool() == Some(false) {
@@ -356,14 +394,17 @@ impl JsonManipulator {
matches.get("start").cloned().unwrap_or_default(),
Preg::replace_callback(
&repository_regex,
- Box::new(move |repository_matches: &IndexMap<String, String>| -> String {
- format!(
- "{}{}{}",
- repository_matches.get("start").cloned().unwrap_or_default(),
- JsonFile::encode(&PhpMixed::String(url_owned.clone()), 0).unwrap_or_default(),
- repository_matches.get("end").cloned().unwrap_or_default()
- )
- }),
+ Box::new(
+ move |repository_matches: &IndexMap<String, String>| -> String {
+ format!(
+ "{}{}{}",
+ repository_matches.get("start").cloned().unwrap_or_default(),
+ JsonFile::encode(&PhpMixed::String(url_owned.clone()), 0)
+ .unwrap_or_default(),
+ repository_matches.get("end").cloned().unwrap_or_default()
+ )
+ }
+ ),
&raw_repo,
),
matches.get("end").cloned().unwrap_or_default()
@@ -400,7 +441,10 @@ impl JsonManipulator {
.cloned()
.unwrap_or_default();
for (i, repository) in repos.iter().enumerate() {
- let repo_name = repository.as_array().and_then(|a| a.get("name")).and_then(|v| v.as_string());
+ let repo_name = repository
+ .as_array()
+ .and_then(|a| a.get("name"))
+ .and_then(|v| v.as_string());
if Some(reference_name) == repo_name {
index_to_insert = Some(i as i64);
break;
@@ -410,7 +454,10 @@ impl JsonManipulator {
// PHP: [$referenceName => false] === $repository
if let Some(arr) = repository.as_array() {
if arr.len() == 1
- && arr.get(reference_name).map(|v| v.as_bool() == Some(false)).unwrap_or(false)
+ && arr
+ .get(reference_name)
+ .map(|v| v.as_bool() == Some(false))
+ .unwrap_or(false)
{
index_to_insert = Some(i as i64);
break;
@@ -425,7 +472,10 @@ impl JsonManipulator {
let final_config = if is_array(&config) && !is_numeric(name) && "" != name {
let mut merged: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
- merged.insert("name".to_string(), Box::new(PhpMixed::String(name.to_string())));
+ merged.insert(
+ "name".to_string(),
+ Box::new(PhpMixed::String(name.to_string())),
+ );
if let Some(arr) = config.as_array() {
for (k, v) in arr {
if !merged.contains_key(k) {
@@ -500,7 +550,10 @@ impl JsonManipulator {
let repository_as_array: IndexMap<String, Box<PhpMixed>> =
repository.as_array().cloned().unwrap_or_default();
- if repository_as_array.get(name).map(|v| v.as_bool() == Some(false)).unwrap_or(false)
+ if repository_as_array
+ .get(name)
+ .map(|v| v.as_bool() == Some(false))
+ .unwrap_or(false)
&& 1 == count(&repository_as_array)
{
let idx: i64 = repository_index.parse().unwrap_or(0);
@@ -577,7 +630,11 @@ impl JsonManipulator {
let mut sub_name: Option<String> = None;
if in_array(
main_node,
- &vec!["config".to_string(), "extra".to_string(), "scripts".to_string()],
+ &vec![
+ "config".to_string(),
+ "extra".to_string(),
+ "scripts".to_string(),
+ ],
false,
) && strpos(name, ".").is_some()
{
@@ -610,7 +667,10 @@ impl JsonManipulator {
let node_regex = format!(
"{{{}^(?P<start> \\s* \\{{ \\s* (?: (?&string) \\s* : (?&json) \\s* , \\s* )*?{}\\s*:\\s*)(?P<content>(?&object))(?P<end>.*)}}sx",
Self::DEFINES,
- preg_quote(&JsonFile::encode(&PhpMixed::String(main_node.to_string()), 0)?, None)
+ preg_quote(
+ &JsonFile::encode(&PhpMixed::String(main_node.to_string()), 0)?,
+ None
+ )
);
let mut match_map: IndexMap<String, String> = IndexMap::new();
@@ -631,7 +691,9 @@ impl JsonManipulator {
let mut children = match_map.get("content").cloned().unwrap_or_default();
// invalid match due to un-regexable content, abort
- if json_decode(&children, false).is_null() || json_decode(&children, false).as_bool() == Some(false) {
+ if json_decode(&children, false).is_null()
+ || json_decode(&children, false).as_bool() == Some(false)
+ {
return Ok(false);
}
@@ -659,7 +721,10 @@ impl JsonManipulator {
cur_val = PhpMixed::Array(IndexMap::new());
}
if let Some(arr) = cur_val.as_array_mut() {
- arr.insert(sub_name_capture.clone().unwrap(), Box::new(value_local.clone()));
+ arr.insert(
+ sub_name_capture.clone().unwrap(),
+ Box::new(value_local.clone()),
+ );
}
value_local = cur_val;
}
@@ -675,9 +740,21 @@ impl JsonManipulator {
);
} else {
let mut leading_match: IndexMap<String, String> = IndexMap::new();
- if Preg::is_match_named("#^\\{(?P<leadingspace>\\s*?)(?P<content>\\S+.*?)?(?P<trailingspace>\\s*)\\}$#s", &children, &mut leading_match).unwrap_or(false) {
- let mut whitespace = leading_match.get("trailingspace").cloned().unwrap_or_default();
- let leading_space = leading_match.get("leadingspace").cloned().unwrap_or_default();
+ if Preg::is_match_named(
+ "#^\\{(?P<leadingspace>\\s*?)(?P<content>\\S+.*?)?(?P<trailingspace>\\s*)\\}$#s",
+ &children,
+ &mut leading_match,
+ )
+ .unwrap_or(false)
+ {
+ let mut whitespace = leading_match
+ .get("trailingspace")
+ .cloned()
+ .unwrap_or_default();
+ let leading_space = leading_match
+ .get("leadingspace")
+ .cloned()
+ .unwrap_or_default();
let content_present = leading_match.get("content").is_some();
if content_present {
let mut value_local = value.clone();
@@ -782,7 +859,10 @@ impl JsonManipulator {
let node_regex = format!(
"{{{}^(?P<start> \\s* \\{{ \\s* (?: (?&string) \\s* : (?&json) \\s* , \\s* )*?{}\\s*:\\s*)(?P<content>(?&object))(?P<end>.*)}}sx",
Self::DEFINES,
- preg_quote(&JsonFile::encode(&PhpMixed::String(main_node.to_string()), 0)?, None)
+ preg_quote(
+ &JsonFile::encode(&PhpMixed::String(main_node.to_string()), 0)?,
+ None
+ )
);
let mut match_map: IndexMap<String, String> = IndexMap::new();
let match_result = match Preg::is_match_named(&node_regex, &self.contents, &mut match_map) {
@@ -803,7 +883,9 @@ impl JsonManipulator {
let children = match_map.get("content").cloned().unwrap_or_default();
// invalid match due to un-regexable content, abort
- if json_decode(&children, true).is_null() || json_decode(&children, true).as_bool() == Some(false) {
+ if json_decode(&children, true).is_null()
+ || json_decode(&children, true).as_bool() == Some(false)
+ {
return Ok(false);
}
@@ -811,7 +893,11 @@ impl JsonManipulator {
let mut sub_name: Option<String> = None;
if in_array(
main_node,
- &vec!["config".to_string(), "extra".to_string(), "scripts".to_string()],
+ &vec![
+ "config".to_string(),
+ "extra".to_string(),
+ "scripts".to_string(),
+ ],
false,
) && strpos(name, ".").is_some()
{
@@ -823,7 +909,10 @@ impl JsonManipulator {
}
// no node to remove
- let main_arr = main_node_value.and_then(|v| v.as_array()).cloned().unwrap_or_default();
+ let main_arr = main_node_value
+ .and_then(|v| v.as_array())
+ .cloned()
+ .unwrap_or_default();
if !main_arr.contains_key(&name_owned)
|| (sub_name.is_some()
&& !main_arr
@@ -838,11 +927,16 @@ impl JsonManipulator {
// try and find a match for the subkey
let key_regex = str_replace("/", "\\\\?/", &preg_quote(&name_owned, None));
let mut children_clean: Option<String> = None;
- if Preg::is_match(&format!("{{\"{}\"\\s*:}}i", key_regex), &children, None).unwrap_or(false) {
+ if Preg::is_match(&format!("{{\"{}\"\\s*:}}i", key_regex), &children, None).unwrap_or(false)
+ {
// find best match for the value of "name"
let mut all_matches: Vec<Vec<String>> = vec![];
if Preg::is_match_all(
- &format!("{{{}\"{}\"\\s*:\\s*(?:(?&json))}}x", Self::DEFINES, key_regex),
+ &format!(
+ "{{{}\"{}\"\\s*:\\s*(?:(?&json))}}x",
+ Self::DEFINES,
+ key_regex
+ ),
&children,
&mut all_matches,
)
@@ -889,7 +983,13 @@ impl JsonManipulator {
// no child data left, $name was the only key in
let mut empty_match: IndexMap<String, String> = IndexMap::new();
- if Preg::is_match_named("#^\\{\\s*?(?P<content>\\S+.*?)?(?P<trailingspace>\\s*)\\}$#s", &children_clean, &mut empty_match).unwrap_or(false) {
+ if Preg::is_match_named(
+ "#^\\{\\s*?(?P<content>\\S+.*?)?(?P<trailingspace>\\s*)\\}$#s",
+ &children_clean,
+ &mut empty_match,
+ )
+ .unwrap_or(false)
+ {
if empty_match.get("content").is_none() {
let newline = self.newline.clone();
let indent = self.indent.clone();
@@ -912,7 +1012,8 @@ impl JsonManipulator {
if let Some(sub) = sub_name {
let mut cur_val = json_decode(&children, true);
if let Some(arr) = cur_val.as_array_mut() {
- if let Some(inner) = arr.get_mut(&name_owned).and_then(|v| v.as_array_mut()) {
+ if let Some(inner) = arr.get_mut(&name_owned).and_then(|v| v.as_array_mut())
+ {
inner.shift_remove(&sub);
}
let now_empty = arr
@@ -921,7 +1022,10 @@ impl JsonManipulator {
.map(|a| a.is_empty())
.unwrap_or(false);
if now_empty {
- arr.insert(name_owned.clone(), Box::new(PhpMixed::Object(ArrayObject::new())));
+ arr.insert(
+ name_owned.clone(),
+ Box::new(PhpMixed::Object(ArrayObject::new())),
+ );
}
}
let val = cur_val
@@ -948,9 +1052,12 @@ impl JsonManipulator {
Box::new(move |matches: &IndexMap<String, String>| -> String {
let mut children_clean = children_clean_capture.clone();
if let Some(ref sub) = sub_name_capture {
- let mut cur_val = json_decode(matches.get("content").unwrap_or(&String::new()), true);
+ let mut cur_val =
+ json_decode(matches.get("content").unwrap_or(&String::new()), true);
if let Some(arr) = cur_val.as_array_mut() {
- if let Some(inner) = arr.get_mut(&name_capture).and_then(|v| v.as_array_mut()) {
+ if let Some(inner) =
+ arr.get_mut(&name_capture).and_then(|v| v.as_array_mut())
+ {
inner.shift_remove(sub);
}
let now_empty = arr
@@ -959,7 +1066,10 @@ impl JsonManipulator {
.map(|a| a.is_empty())
.unwrap_or(false);
if now_empty {
- arr.insert(name_capture.clone(), Box::new(PhpMixed::Object(ArrayObject::new())));
+ arr.insert(
+ name_capture.clone(),
+ Box::new(PhpMixed::Object(ArrayObject::new())),
+ );
}
}
children_clean = formatter.format(&cur_val, 0, true).unwrap_or_default();
@@ -978,7 +1088,12 @@ impl JsonManipulator {
Ok(true)
}
- pub fn add_list_item(&mut self, main_node: &str, value: PhpMixed, append: bool) -> anyhow::Result<bool> {
+ pub fn add_list_item(
+ &mut self,
+ main_node: &str,
+ value: PhpMixed,
+ append: bool,
+ ) -> anyhow::Result<bool> {
let decoded = JsonFile::parse_json(&self.contents, "composer.json")?;
// no main node yet
@@ -992,7 +1107,10 @@ impl JsonManipulator {
let node_regex = format!(
"{{{}^(?P<start> \\s* \\{{ \\s* (?: (?&string) \\s* : (?&json) \\s* , \\s* )*?{}\\s*:\\s*)(?P<content>(?&array))(?P<end>.*)}}sx",
Self::DEFINES,
- preg_quote(&JsonFile::encode(&PhpMixed::String(main_node.to_string()), 0)?, None)
+ preg_quote(
+ &JsonFile::encode(&PhpMixed::String(main_node.to_string()), 0)?,
+ None
+ )
);
let mut match_map: IndexMap<String, String> = IndexMap::new();
@@ -1018,10 +1136,23 @@ impl JsonManipulator {
}
let mut leading_match: IndexMap<String, String> = IndexMap::new();
- if Preg::is_match_named("#^\\[(?P<leadingspace>\\s*?)(?P<content>\\S+.*?)?(?P<trailingspace>\\s*)\\]$#s", &children, &mut leading_match).unwrap_or(false) {
- let leading_whitespace = leading_match.get("leadingspace").cloned().unwrap_or_default();
- let mut whitespace = leading_match.get("trailingspace").cloned().unwrap_or_default();
- let mut leading_item_whitespace = format!("{}{}{}", self.newline, self.indent, self.indent);
+ if Preg::is_match_named(
+ "#^\\[(?P<leadingspace>\\s*?)(?P<content>\\S+.*?)?(?P<trailingspace>\\s*)\\]$#s",
+ &children,
+ &mut leading_match,
+ )
+ .unwrap_or(false)
+ {
+ let leading_whitespace = leading_match
+ .get("leadingspace")
+ .cloned()
+ .unwrap_or_default();
+ let mut whitespace = leading_match
+ .get("trailingspace")
+ .cloned()
+ .unwrap_or_default();
+ let mut leading_item_whitespace =
+ format!("{}{}{}", self.newline, self.indent, self.indent);
let mut trailing_item_whitespace = whitespace.clone();
let mut item_depth: i64 = 1;
@@ -1098,7 +1229,12 @@ impl JsonManipulator {
Ok(true)
}
- pub fn insert_list_item(&mut self, main_node: &str, value: PhpMixed, index: i64) -> anyhow::Result<bool> {
+ pub fn insert_list_item(
+ &mut self,
+ main_node: &str,
+ value: PhpMixed,
+ index: i64,
+ ) -> anyhow::Result<bool> {
if index < 0 {
return Err(InvalidArgumentException {
message: "Index can only be positive integer".to_string(),
@@ -1134,7 +1270,10 @@ impl JsonManipulator {
let node_regex = format!(
"{{{}^(?P<start> \\s* \\{{ \\s* (?: (?&string) \\s* : (?&json) \\s* , \\s* )*?{}\\s*:\\s*)(?P<content>(?&array))(?P<end>.*)}}sx",
Self::DEFINES,
- preg_quote(&JsonFile::encode(&PhpMixed::String(main_node.to_string()), 0)?, None)
+ preg_quote(
+ &JsonFile::encode(&PhpMixed::String(main_node.to_string()), 0)?,
+ None
+ )
);
let mut match_map: IndexMap<String, String> = IndexMap::new();
@@ -1177,7 +1316,9 @@ impl JsonManipulator {
"{}{}{},{}{}",
m.get("start").cloned().unwrap_or_default(),
m.get("space_before_item").cloned().unwrap_or_default(),
- formatter.format(&value_capture, 1, false).unwrap_or_default(),
+ formatter
+ .format(&value_capture, 1, false)
+ .unwrap_or_default(),
m.get("space_before_item").cloned().unwrap_or_default(),
m.get("end").cloned().unwrap_or_default()
)
@@ -1220,7 +1361,10 @@ impl JsonManipulator {
let node_regex = format!(
"{{{}^(?P<start> \\s* \\{{ \\s* (?: (?&string) \\s* : (?&json) \\s* , \\s* )*?{}\\s*:\\s*)(?P<content>(?&array))(?P<end>.*)}}sx",
Self::DEFINES,
- preg_quote(&JsonFile::encode(&PhpMixed::String(main_node.to_string()), 0)?, None)
+ preg_quote(
+ &JsonFile::encode(&PhpMixed::String(main_node.to_string()), 0)?,
+ None
+ )
);
let mut match_map: IndexMap<String, String> = IndexMap::new();
let match_result = match Preg::is_match_named(&node_regex, &self.contents, &mut match_map) {
@@ -1246,7 +1390,10 @@ impl JsonManipulator {
}
// no node to remove
- let main_list = main_node_value.and_then(|v| v.as_list()).cloned().unwrap_or_default();
+ let main_list = main_node_value
+ .and_then(|v| v.as_list())
+ .cloned()
+ .unwrap_or_default();
if main_list.get(node_index as usize).is_none() {
return Ok(true);
}
@@ -1308,7 +1455,10 @@ impl JsonManipulator {
let regex = format!(
"{{{}^(?P<start>\\s*\\{{\\s*(?:(?&string)\\s*:\\s*(?&json)\\s*,\\s*)*?)(?P<key>{}\\s*:\\s*(?&json))(?P<end>.*)}}sx",
Self::DEFINES,
- preg_quote(&JsonFile::encode(&PhpMixed::String(key.to_string()), 0)?, None)
+ preg_quote(
+ &JsonFile::encode(&PhpMixed::String(key.to_string()), 0)?,
+ None
+ )
);
let mut matches: IndexMap<String, String> = IndexMap::new();
if decoded.as_array().and_then(|a| a.get(key)).is_some()
@@ -1333,7 +1483,9 @@ impl JsonManipulator {
// append at the end of the file and keep whitespace
let mut tail_match: Vec<String> = vec![];
- if Preg::is_match("#[^{\\s](\\s*)\\}$#", &self.contents, Some(&mut tail_match)).unwrap_or(false) {
+ if Preg::is_match("#[^{\\s](\\s*)\\}$#", &self.contents, Some(&mut tail_match))
+ .unwrap_or(false)
+ {
self.contents = Preg::replace(
&format!("#{}\\}}$#", tail_match[1]),
&addcslashes(
@@ -1384,7 +1536,10 @@ impl JsonManipulator {
let regex = format!(
"{{{}^(?P<start>\\s*\\{{\\s*(?:(?&string)\\s*:\\s*(?&json)\\s*,\\s*)*?)(?P<removal>{}\\s*:\\s*(?&json))\\s*,?\\s*(?P<end>.*)}}sx",
Self::DEFINES,
- preg_quote(&JsonFile::encode(&PhpMixed::String(key.to_string()), 0)?, None)
+ preg_quote(
+ &JsonFile::encode(&PhpMixed::String(key.to_string()), 0)?,
+ None
+ )
);
let mut matches: IndexMap<String, String> = IndexMap::new();
if Preg::is_match_named(&regex, &self.contents, &mut matches).unwrap_or(false) {
@@ -1425,7 +1580,10 @@ impl JsonManipulator {
let regex = format!(
"{{{}^(?P<start>\\s*\\{{\\s*(?:(?&string)\\s*:\\s*(?&json)\\s*,\\s*)*?{}\\s*:\\s*)(?P<removal>\\{{(?P<removal_space>\\s*+)\\}})(?P<end>\\s*,?\\s*.*)}}sx",
Self::DEFINES,
- preg_quote(&JsonFile::encode(&PhpMixed::String(key.to_string()), 0)?, None)
+ preg_quote(
+ &JsonFile::encode(&PhpMixed::String(key.to_string()), 0)?,
+ None
+ )
);
let mut matches: IndexMap<String, String> = IndexMap::new();
if Preg::is_match_named(&regex, &self.contents, &mut matches).unwrap_or(false) {
@@ -1456,7 +1614,10 @@ impl JsonManipulator {
return Ok(true);
}
- let value = decoded_arr.get(key).map(|v| (**v).clone()).unwrap_or(PhpMixed::Null);
+ let value = decoded_arr
+ .get(key)
+ .map(|v| (**v).clone())
+ .unwrap_or(PhpMixed::Null);
if is_array(&value) && value.as_array().map(|a| a.len()).unwrap_or(0) == 0 {
return self.remove_main_key(key);
}
@@ -1551,7 +1712,11 @@ impl ManipulatorFormatter {
&& data.as_list().map(|l| l.len()).unwrap_or(0) == 0
{
return Ok(if was_object {
- format!("{{{}{}}}", self.newline, str_repeat(&self.indent, depth + 1))
+ format!(
+ "{{{}{}}}",
+ self.newline,
+ str_repeat(&self.indent, depth + 1)
+ )
} else {
"[]".to_string()
});
diff --git a/crates/shirabe/src/json/mod.rs b/crates/shirabe/src/json/mod.rs
new file mode 100644
index 0000000..3e5f22c
--- /dev/null
+++ b/crates/shirabe/src/json/mod.rs
@@ -0,0 +1,4 @@
+pub mod json_file;
+pub mod json_formatter;
+pub mod json_manipulator;
+pub mod json_validation_exception;
diff --git a/crates/shirabe/src/lib.rs b/crates/shirabe/src/lib.rs
new file mode 100644
index 0000000..a8fe3a7
--- /dev/null
+++ b/crates/shirabe/src/lib.rs
@@ -0,0 +1,28 @@
+pub mod advisory;
+pub mod autoload;
+pub mod cache;
+pub mod command;
+pub mod compiler;
+pub mod composer;
+pub mod config;
+pub mod console;
+pub mod dependency_resolver;
+pub mod downloader;
+pub mod event_dispatcher;
+pub mod exception;
+pub mod factory;
+pub mod filter;
+pub mod installed_versions;
+pub mod installer;
+pub mod io;
+pub mod json;
+pub mod package;
+pub mod partial_composer;
+pub mod phpstan;
+pub mod platform;
+pub mod plugin;
+pub mod question;
+pub mod repository;
+pub mod script;
+pub mod self_update;
+pub mod util;
diff --git a/crates/shirabe/src/package/alias_package.rs b/crates/shirabe/src/package/alias_package.rs
index 0c8158f..a101a1f 100644
--- a/crates/shirabe/src/package/alias_package.rs
+++ b/crates/shirabe/src/package/alias_package.rs
@@ -2,7 +2,7 @@
use chrono::{DateTime, Utc};
use indexmap::IndexMap;
-use shirabe_php_shim::{in_array, PhpMixed};
+use shirabe_php_shim::{PhpMixed, in_array};
use shirabe_semver::constraint::constraint::Constraint;
use crate::package::base_package::BasePackage;
diff --git a/crates/shirabe/src/package/archiver/archivable_files_filter.rs b/crates/shirabe/src/package/archiver/archivable_files_filter.rs
index a267cf1..f820e08 100644
--- a/crates/shirabe/src/package/archiver/archivable_files_filter.rs
+++ b/crates/shirabe/src/package/archiver/archivable_files_filter.rs
@@ -1,7 +1,7 @@
//! ref: composer/src/Composer/Package/Archiver/ArchivableFilesFilter.php
-use std::path::PathBuf;
use shirabe_php_shim::PharData;
+use std::path::PathBuf;
pub struct ArchivableFilesFilter {
inner: Box<dyn Iterator<Item = PathBuf>>,
diff --git a/crates/shirabe/src/package/archiver/archivable_files_finder.rs b/crates/shirabe/src/package/archiver/archivable_files_finder.rs
index 7d1b94e..35ec36f 100644
--- a/crates/shirabe/src/package/archiver/archivable_files_finder.rs
+++ b/crates/shirabe/src/package/archiver/archivable_files_finder.rs
@@ -1,12 +1,12 @@
//! ref: composer/src/Composer/Package/Archiver/ArchivableFilesFinder.php
-use shirabe_external_packages::composer::pcre::preg::Preg;
-use shirabe_external_packages::symfony::component::finder::finder::Finder;
-use shirabe_external_packages::symfony::component::finder::spl_file_info::SplFileInfo;
-use shirabe_php_shim::{preg_quote, realpath, RuntimeException};
use crate::package::archiver::composer_exclude_filter::ComposerExcludeFilter;
use crate::package::archiver::git_exclude_filter::GitExcludeFilter;
use crate::util::filesystem::Filesystem;
+use shirabe_external_packages::composer::pcre::preg::Preg;
+use shirabe_external_packages::symfony::component::finder::finder::Finder;
+use shirabe_external_packages::symfony::component::finder::spl_file_info::SplFileInfo;
+use shirabe_php_shim::{RuntimeException, preg_quote, realpath};
pub struct ArchivableFilesFinder {
pub(crate) finder: Finder,
@@ -30,7 +30,8 @@ impl ArchivableFilesFinder {
return Err(RuntimeException {
message: format!("Could not realpath() the source directory \"{}\"", sources),
code: 0,
- }.into());
+ }
+ .into());
}
let sources = fs.normalize_path(&sources_real_path.unwrap());
diff --git a/crates/shirabe/src/package/archiver/archive_manager.rs b/crates/shirabe/src/package/archiver/archive_manager.rs
index ed7c6f7..3f7bfe0 100644
--- a/crates/shirabe/src/package/archiver/archive_manager.rs
+++ b/crates/shirabe/src/package/archiver/archive_manager.rs
@@ -1,11 +1,11 @@
//! ref: composer/src/Composer/Package/Archiver/ArchiveManager.php
use indexmap::IndexMap;
+use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- bin2hex, file_exists, random_bytes, realpath, sys_get_temp_dir, InvalidArgumentException,
- RuntimeException,
+ InvalidArgumentException, RuntimeException, bin2hex, file_exists, random_bytes, realpath,
+ sys_get_temp_dir,
};
-use shirabe_external_packages::composer::pcre::preg::Preg;
use crate::downloader::download_manager::DownloadManager;
use crate::json::json_file::JsonFile;
@@ -58,11 +58,7 @@ impl ArchiveManager {
) -> IndexMap<String, String> {
let base_name = match package.get_archive_name() {
Some(name) => name.to_string(),
- None => Preg::replace(
- "#[^a-z0-9-_]#i",
- "-",
- package.get_name(),
- ),
+ None => Preg::replace("#[^a-z0-9-_]#i", "-", package.get_name()),
};
let mut parts: IndexMap<String, String> = IndexMap::new();
@@ -129,7 +125,10 @@ impl ArchiveManager {
let mut usable_archiver_idx: Option<usize> = None;
for (i, archiver) in self.archivers.iter().enumerate() {
- if archiver.supports(format.clone(), package.get_source_type().map(|s| s.to_string())) {
+ if archiver.supports(
+ format.clone(),
+ package.get_source_type().map(|s| s.to_string()),
+ ) {
usable_archiver_idx = Some(i);
break;
}
diff --git a/crates/shirabe/src/package/archiver/base_exclude_filter.rs b/crates/shirabe/src/package/archiver/base_exclude_filter.rs
index 7f737fe..f20af20 100644
--- a/crates/shirabe/src/package/archiver/base_exclude_filter.rs
+++ b/crates/shirabe/src/package/archiver/base_exclude_filter.rs
@@ -53,7 +53,10 @@ impl BaseExcludeFilter {
}
pub fn generate_patterns(&self, rules: Vec<String>) -> Vec<(String, bool, bool)> {
- rules.into_iter().map(|rule| self.generate_pattern(&rule)).collect()
+ rules
+ .into_iter()
+ .map(|rule| self.generate_pattern(&rule))
+ .collect()
}
pub fn generate_pattern(&self, rule: &str) -> (String, bool, bool) {
diff --git a/crates/shirabe/src/package/archiver/git_exclude_filter.rs b/crates/shirabe/src/package/archiver/git_exclude_filter.rs
index b3e43dc..8028c15 100644
--- a/crates/shirabe/src/package/archiver/git_exclude_filter.rs
+++ b/crates/shirabe/src/package/archiver/git_exclude_filter.rs
@@ -1,8 +1,8 @@
//! ref: composer/src/Composer/Package/Archiver/GitExcludeFilter.php
-use std::path::Path;
-use shirabe_external_packages::composer::pcre::preg::Preg;
use crate::package::archiver::base_exclude_filter::BaseExcludeFilter;
+use shirabe_external_packages::composer::pcre::preg::Preg;
+use std::path::Path;
pub struct GitExcludeFilter {
inner: BaseExcludeFilter,
@@ -20,10 +20,9 @@ impl GitExcludeFilter {
.lines()
.map(|l| l.to_string())
.collect();
- let patterns = filter.inner.parse_lines(
- lines,
- |line| GitExcludeFilter::parse_git_attributes_line_static(line),
- );
+ let patterns = filter.inner.parse_lines(lines, |line| {
+ GitExcludeFilter::parse_git_attributes_line_static(line)
+ });
filter.inner.exclude_patterns.extend(patterns);
}
diff --git a/crates/shirabe/src/package/archiver/mod.rs b/crates/shirabe/src/package/archiver/mod.rs
new file mode 100644
index 0000000..ecf86c8
--- /dev/null
+++ b/crates/shirabe/src/package/archiver/mod.rs
@@ -0,0 +1,9 @@
+pub mod archivable_files_filter;
+pub mod archivable_files_finder;
+pub mod archive_manager;
+pub mod archiver_interface;
+pub mod base_exclude_filter;
+pub mod composer_exclude_filter;
+pub mod git_exclude_filter;
+pub mod phar_archiver;
+pub mod zip_archiver;
diff --git a/crates/shirabe/src/package/archiver/phar_archiver.rs b/crates/shirabe/src/package/archiver/phar_archiver.rs
index 24cd738..2e9d96e 100644
--- a/crates/shirabe/src/package/archiver/phar_archiver.rs
+++ b/crates/shirabe/src/package/archiver/phar_archiver.rs
@@ -2,8 +2,8 @@
use indexmap::IndexMap;
use shirabe_php_shim::{
- bzcompress, file_exists, file_put_contents, function_exists, gzcompress, pack, str_repeat,
- strrpos, unlink, FilesystemIterator, Phar, PharData, PhpMixed, RuntimeException,
+ FilesystemIterator, Phar, PharData, PhpMixed, RuntimeException, bzcompress, file_exists,
+ file_put_contents, function_exists, gzcompress, pack, str_repeat, strrpos, unlink,
};
use crate::package::archiver::archivable_files_filter::ArchivableFilesFilter;
@@ -79,14 +79,14 @@ impl ArchiverInterface for PharArchiver {
let eocd = pack(
"VvvvvVVv",
&[
- PhpMixed::Int(0x06054b50), // End of central directory signature
- PhpMixed::Int(0), // Number of this disk
- PhpMixed::Int(0), // Disk where central directory starts
- PhpMixed::Int(0), // Number of central directory records on this disk
- PhpMixed::Int(0), // Total number of central directory records
- PhpMixed::Int(0), // Size of central directory (bytes)
- PhpMixed::Int(0), // Offset of start of central directory
- PhpMixed::Int(0), // Comment length
+ PhpMixed::Int(0x06054b50), // End of central directory signature
+ PhpMixed::Int(0), // Number of this disk
+ PhpMixed::Int(0), // Disk where central directory starts
+ PhpMixed::Int(0), // Number of central directory records on this disk
+ PhpMixed::Int(0), // Total number of central directory records
+ PhpMixed::Int(0), // Size of central directory (bytes)
+ PhpMixed::Int(0), // Offset of start of central directory
+ PhpMixed::Int(0), // Comment length
],
);
file_put_contents(&target, &eocd);
@@ -100,10 +100,12 @@ impl ArchiverInterface for PharArchiver {
.into());
}
if format == "tar.gz" && function_exists("gzcompress") {
- let data = gzcompress(&str_repeat("\0", 10240).into_bytes()).unwrap_or_default();
+ let data =
+ gzcompress(&str_repeat("\0", 10240).into_bytes()).unwrap_or_default();
file_put_contents(&target, &data);
} else if format == "tar.bz2" && function_exists("bzcompress") {
- let data = bzcompress(&str_repeat("\0", 10240).into_bytes()).unwrap_or_default();
+ let data =
+ bzcompress(&str_repeat("\0", 10240).into_bytes()).unwrap_or_default();
file_put_contents(&target, &data);
}
}
diff --git a/crates/shirabe/src/package/archiver/zip_archiver.rs b/crates/shirabe/src/package/archiver/zip_archiver.rs
index 104c544..ef5b40a 100644
--- a/crates/shirabe/src/package/archiver/zip_archiver.rs
+++ b/crates/shirabe/src/package/archiver/zip_archiver.rs
@@ -1,11 +1,13 @@
//! ref: composer/src/Composer/Package/Archiver/ZipArchiver.php
-use indexmap::IndexMap;
-use shirabe_php_shim::{class_exists, fileperms, method_exists, pack, realpath, PhpMixed, RuntimeException, ZipArchive};
use crate::package::archiver::archivable_files_finder::ArchivableFilesFinder;
use crate::package::archiver::archiver_interface::ArchiverInterface;
use crate::util::filesystem::Filesystem;
use crate::util::platform::Platform;
+use indexmap::IndexMap;
+use shirabe_php_shim::{
+ PhpMixed, RuntimeException, ZipArchive, class_exists, fileperms, method_exists, pack, realpath,
+};
#[derive(Debug)]
pub struct ZipArchiver;
@@ -60,22 +62,29 @@ impl ArchiverInterface for ZipArchiver {
// setExternalAttributesName() is only available with libzip 0.11.2 or above
if method_exists(&PhpMixed::Null, "setExternalAttributesName") {
let perms = fileperms(&filepath);
- zip.set_external_attributes_name(&relative_path, ZipArchive::OPSYS_UNIX, perms << 16);
+ zip.set_external_attributes_name(
+ &relative_path,
+ ZipArchive::OPSYS_UNIX,
+ perms << 16,
+ );
}
}
if zip.close() {
if !std::path::Path::new(&target).exists() {
// create minimal valid ZIP file (Empty Central Directory + End of Central Directory record)
- let eocd = pack("VvvvvVVv", &[
- PhpMixed::Int(0x06054b50), // End of central directory signature
- PhpMixed::Int(0), // Number of this disk
- PhpMixed::Int(0), // Disk where central directory starts
- PhpMixed::Int(0), // Number of central directory records on this disk
- PhpMixed::Int(0), // Total number of central directory records
- PhpMixed::Int(0), // Size of central directory (bytes)
- PhpMixed::Int(0), // Offset of start of central directory
- PhpMixed::Int(0), // Comment length
- ]);
+ let eocd = pack(
+ "VvvvvVVv",
+ &[
+ PhpMixed::Int(0x06054b50), // End of central directory signature
+ PhpMixed::Int(0), // Number of this disk
+ PhpMixed::Int(0), // Disk where central directory starts
+ PhpMixed::Int(0), // Number of central directory records on this disk
+ PhpMixed::Int(0), // Total number of central directory records
+ PhpMixed::Int(0), // Size of central directory (bytes)
+ PhpMixed::Int(0), // Offset of start of central directory
+ PhpMixed::Int(0), // Comment length
+ ],
+ );
std::fs::write(&target, &eocd)?;
}
diff --git a/crates/shirabe/src/package/base_package.rs b/crates/shirabe/src/package/base_package.rs
index 820e51b..4cbd11c 100644
--- a/crates/shirabe/src/package/base_package.rs
+++ b/crates/shirabe/src/package/base_package.rs
@@ -3,7 +3,7 @@
use std::sync::LazyLock;
use indexmap::IndexMap;
-use shirabe_php_shim::{preg_quote, LogicException, UnexpectedValueException};
+use shirabe_php_shim::{LogicException, UnexpectedValueException, preg_quote};
use crate::package::link::Link;
use crate::package::package_interface::PackageInterface;
diff --git a/crates/shirabe/src/package/comparer/comparer.rs b/crates/shirabe/src/package/comparer/comparer.rs
index 8f7f312..0e0d295 100644
--- a/crates/shirabe/src/package/comparer/comparer.rs
+++ b/crates/shirabe/src/package/comparer/comparer.rs
@@ -81,17 +81,26 @@ impl Comparer {
let dest_file_hash = destination.get(dir).and_then(|d| d.get(file));
if let Some(dest_hash) = dest_file_hash {
if hash != dest_hash {
- self.changed.entry("changed".to_string()).or_default().push(format!("{}/{}", dir, file));
+ self.changed
+ .entry("changed".to_string())
+ .or_default()
+ .push(format!("{}/{}", dir, file));
}
} else {
- self.changed.entry("removed".to_string()).or_default().push(format!("{}/{}", dir, file));
+ self.changed
+ .entry("removed".to_string())
+ .or_default()
+ .push(format!("{}/{}", dir, file));
}
}
}
for (dir, value) in &destination {
for (file, _hash) in value {
if !source.get(dir).map_or(false, |d| d.contains_key(file)) {
- self.changed.entry("added".to_string()).or_default().push(format!("{}/{}", dir, file));
+ self.changed
+ .entry("added".to_string())
+ .or_default()
+ .push(format!("{}/{}", dir, file));
}
}
}
@@ -106,8 +115,13 @@ impl Comparer {
}
let path = format!("{}/{}", dir, file);
if Path::new(&path).is_symlink() {
- let link_target = std::fs::read_link(&path).ok().and_then(|p| p.to_str().map(|s| s.to_string()));
- array.entry(dir.to_string()).or_default().insert(file, link_target);
+ let link_target = std::fs::read_link(&path)
+ .ok()
+ .and_then(|p| p.to_str().map(|s| s.to_string()));
+ array
+ .entry(dir.to_string())
+ .or_default()
+ .insert(file, link_target);
} else if Path::new(&path).is_dir() {
if array.is_empty() {
array.insert("0".to_string(), IndexMap::new());
@@ -118,7 +132,11 @@ impl Comparer {
} else if Path::new(&path).is_file() {
let size = std::fs::metadata(&path).map(|m| m.len()).unwrap_or(0);
if size > 0 {
- let algo = if shirabe_php_shim::PHP_VERSION_ID > 80100 { "xxh3" } else { "sha1" };
+ let algo = if shirabe_php_shim::PHP_VERSION_ID > 80100 {
+ "xxh3"
+ } else {
+ "sha1"
+ };
let hash = shirabe_php_shim::hash_file(algo, &path);
array.entry(dir.to_string()).or_default().insert(file, hash);
}
diff --git a/crates/shirabe/src/package/comparer/mod.rs b/crates/shirabe/src/package/comparer/mod.rs
new file mode 100644
index 0000000..4c5c6d2
--- /dev/null
+++ b/crates/shirabe/src/package/comparer/mod.rs
@@ -0,0 +1 @@
+pub mod comparer;
diff --git a/crates/shirabe/src/package/complete_alias_package.rs b/crates/shirabe/src/package/complete_alias_package.rs
index 9da998a..134ed3a 100644
--- a/crates/shirabe/src/package/complete_alias_package.rs
+++ b/crates/shirabe/src/package/complete_alias_package.rs
@@ -33,7 +33,10 @@ impl CompleteAliasPackage {
self.alias_of.get_repositories()
}
- pub fn set_repositories(&mut self, repositories: Vec<indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>>) {
+ pub fn set_repositories(
+ &mut self,
+ repositories: Vec<indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>>,
+ ) {
self.alias_of.set_repositories(repositories);
}
@@ -89,7 +92,10 @@ impl CompleteAliasPackage {
self.alias_of.get_funding()
}
- pub fn set_funding(&mut self, funding: Vec<indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>>) {
+ pub fn set_funding(
+ &mut self,
+ funding: Vec<indexmap::IndexMap<String, shirabe_php_shim::PhpMixed>>,
+ ) {
self.alias_of.set_funding(funding);
}
diff --git a/crates/shirabe/src/package/complete_package.rs b/crates/shirabe/src/package/complete_package.rs
index 2120eec..ec2a42a 100644
--- a/crates/shirabe/src/package/complete_package.rs
+++ b/crates/shirabe/src/package/complete_package.rs
@@ -1,9 +1,9 @@
//! ref: composer/src/Composer/Package/CompletePackage.php
-use indexmap::IndexMap;
-use shirabe_php_shim::PhpMixed;
use crate::package::complete_package_interface::CompletePackageInterface;
use crate::package::package::Package;
+use indexmap::IndexMap;
+use shirabe_php_shim::PhpMixed;
#[derive(Debug)]
pub struct CompletePackage {
diff --git a/crates/shirabe/src/package/dumper/array_dumper.rs b/crates/shirabe/src/package/dumper/array_dumper.rs
index bee9aa7..02f1092 100644
--- a/crates/shirabe/src/package/dumper/array_dumper.rs
+++ b/crates/shirabe/src/package/dumper/array_dumper.rs
@@ -20,28 +20,63 @@ impl ArrayDumper {
pub fn dump(&self, package: &dyn PackageInterface) -> IndexMap<String, PhpMixed> {
let mut data: IndexMap<String, PhpMixed> = IndexMap::new();
- data.insert("name".to_string(), PhpMixed::String(package.get_pretty_name().to_string()));
- data.insert("version".to_string(), PhpMixed::String(package.get_pretty_version().to_string()));
- data.insert("version_normalized".to_string(), PhpMixed::String(package.get_version().to_string()));
+ data.insert(
+ "name".to_string(),
+ PhpMixed::String(package.get_pretty_name().to_string()),
+ );
+ data.insert(
+ "version".to_string(),
+ PhpMixed::String(package.get_pretty_version().to_string()),
+ );
+ data.insert(
+ "version_normalized".to_string(),
+ PhpMixed::String(package.get_version().to_string()),
+ );
if let Some(target_dir) = package.get_target_dir() {
- data.insert("target-dir".to_string(), PhpMixed::String(target_dir.to_string()));
+ data.insert(
+ "target-dir".to_string(),
+ PhpMixed::String(target_dir.to_string()),
+ );
}
if let Some(source_type) = package.get_source_type() {
let mut source: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
- source.insert("type".to_string(), Box::new(PhpMixed::String(source_type.to_string())));
- source.insert("url".to_string(), Box::new(PhpMixed::String(package.get_source_url().unwrap_or("").to_string())));
+ source.insert(
+ "type".to_string(),
+ Box::new(PhpMixed::String(source_type.to_string())),
+ );
+ source.insert(
+ "url".to_string(),
+ Box::new(PhpMixed::String(
+ package.get_source_url().unwrap_or("").to_string(),
+ )),
+ );
if let Some(reference) = package.get_source_reference() {
- source.insert("reference".to_string(), Box::new(PhpMixed::String(reference.to_string())));
+ source.insert(
+ "reference".to_string(),
+ Box::new(PhpMixed::String(reference.to_string())),
+ );
}
if let Some(mirrors) = package.get_source_mirrors() {
if !mirrors.is_empty() {
- source.insert("mirrors".to_string(), Box::new(PhpMixed::Array(
- mirrors.into_iter().enumerate().map(|(i, m)| (i.to_string(), Box::new(PhpMixed::Array(
- m.into_iter().map(|(k, v)| (k, Box::new(v))).collect()
- )))).collect()
- )));
+ source.insert(
+ "mirrors".to_string(),
+ Box::new(PhpMixed::Array(
+ mirrors
+ .into_iter()
+ .enumerate()
+ .map(|(i, m)| {
+ (
+ i.to_string(),
+ Box::new(PhpMixed::Array(
+ m.into_iter().map(|(k, v)| (k, Box::new(v))).collect(),
+ )),
+ )
+ })
+ .collect(),
+ )),
+ );
}
}
data.insert("source".to_string(), PhpMixed::Array(source));
@@ -49,21 +84,47 @@ impl ArrayDumper {
if let Some(dist_type) = package.get_dist_type() {
let mut dist: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
- dist.insert("type".to_string(), Box::new(PhpMixed::String(dist_type.to_string())));
- dist.insert("url".to_string(), Box::new(PhpMixed::String(package.get_dist_url().unwrap_or("").to_string())));
+ dist.insert(
+ "type".to_string(),
+ Box::new(PhpMixed::String(dist_type.to_string())),
+ );
+ dist.insert(
+ "url".to_string(),
+ Box::new(PhpMixed::String(
+ package.get_dist_url().unwrap_or("").to_string(),
+ )),
+ );
if let Some(reference) = package.get_dist_reference() {
- dist.insert("reference".to_string(), Box::new(PhpMixed::String(reference.to_string())));
+ dist.insert(
+ "reference".to_string(),
+ Box::new(PhpMixed::String(reference.to_string())),
+ );
}
if let Some(shasum) = package.get_dist_sha1_checksum() {
- dist.insert("shasum".to_string(), Box::new(PhpMixed::String(shasum.to_string())));
+ dist.insert(
+ "shasum".to_string(),
+ Box::new(PhpMixed::String(shasum.to_string())),
+ );
}
if let Some(mirrors) = package.get_dist_mirrors() {
if !mirrors.is_empty() {
- dist.insert("mirrors".to_string(), Box::new(PhpMixed::Array(
- mirrors.into_iter().enumerate().map(|(i, m)| (i.to_string(), Box::new(PhpMixed::Array(
- m.into_iter().map(|(k, v)| (k, Box::new(v))).collect()
- )))).collect()
- )));
+ dist.insert(
+ "mirrors".to_string(),
+ Box::new(PhpMixed::Array(
+ mirrors
+ .into_iter()
+ .enumerate()
+ .map(|(i, m)| {
+ (
+ i.to_string(),
+ Box::new(PhpMixed::Array(
+ m.into_iter().map(|(k, v)| (k, Box::new(v))).collect(),
+ )),
+ )
+ })
+ .collect(),
+ )),
+ );
}
}
data.insert("dist".to_string(), PhpMixed::Array(dist));
@@ -77,7 +138,10 @@ impl ArrayDumper {
}
let mut link_map: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
for link in &links {
- link_map.insert(link.get_target().to_string(), Box::new(PhpMixed::String(link.get_pretty_constraint().to_string())));
+ link_map.insert(
+ link.get_target().to_string(),
+ Box::new(PhpMixed::String(link.get_pretty_constraint().to_string())),
+ );
}
link_map.sort_keys();
data.insert(type_name, PhpMixed::Array(link_map));
@@ -87,13 +151,22 @@ impl ArrayDumper {
if !suggests.is_empty() {
let mut sorted_suggests = suggests.clone();
sorted_suggests.sort_keys();
- data.insert("suggest".to_string(), PhpMixed::Array(
- sorted_suggests.into_iter().map(|(k, v)| (k, Box::new(PhpMixed::String(v)))).collect()
- ));
+ data.insert(
+ "suggest".to_string(),
+ PhpMixed::Array(
+ sorted_suggests
+ .into_iter()
+ .map(|(k, v)| (k, Box::new(PhpMixed::String(v))))
+ .collect(),
+ ),
+ );
}
if let Some(release_date) = package.get_release_date() {
- data.insert("time".to_string(), PhpMixed::String(release_date.to_rfc3339()));
+ data.insert(
+ "time".to_string(),
+ PhpMixed::String(release_date.to_rfc3339()),
+ );
}
if package.is_default_branch() {
@@ -103,7 +176,15 @@ impl ArrayDumper {
// dumpValues for base package keys (corresponds to dynamic PHP dispatch)
let binaries = package.get_binaries();
if !binaries.is_empty() {
- data.insert("bin".to_string(), PhpMixed::List(binaries.into_iter().map(|b| Box::new(PhpMixed::String(b))).collect()));
+ data.insert(
+ "bin".to_string(),
+ PhpMixed::List(
+ binaries
+ .into_iter()
+ .map(|b| Box::new(PhpMixed::String(b)))
+ .collect(),
+ ),
+ );
}
if let Some(pkg_type) = package.get_type() {
if !pkg_type.is_empty() {
@@ -112,103 +193,223 @@ impl ArrayDumper {
}
let extra = package.get_extra();
if !extra.is_empty() {
- data.insert("extra".to_string(), PhpMixed::Array(extra.into_iter().map(|(k, v)| (k, Box::new(v))).collect()));
+ data.insert(
+ "extra".to_string(),
+ PhpMixed::Array(extra.into_iter().map(|(k, v)| (k, Box::new(v))).collect()),
+ );
}
if let Some(installation_source) = package.get_installation_source() {
- data.insert("installation-source".to_string(), PhpMixed::String(installation_source.to_string()));
+ data.insert(
+ "installation-source".to_string(),
+ PhpMixed::String(installation_source.to_string()),
+ );
}
let autoload = package.get_autoload();
if !autoload.is_empty() {
- data.insert("autoload".to_string(), PhpMixed::Array(autoload.into_iter().map(|(k, v)| (k, Box::new(v))).collect()));
+ data.insert(
+ "autoload".to_string(),
+ PhpMixed::Array(
+ autoload
+ .into_iter()
+ .map(|(k, v)| (k, Box::new(v)))
+ .collect(),
+ ),
+ );
}
let dev_autoload = package.get_dev_autoload();
if !dev_autoload.is_empty() {
- data.insert("autoload-dev".to_string(), PhpMixed::Array(dev_autoload.into_iter().map(|(k, v)| (k, Box::new(v))).collect()));
+ data.insert(
+ "autoload-dev".to_string(),
+ PhpMixed::Array(
+ dev_autoload
+ .into_iter()
+ .map(|(k, v)| (k, Box::new(v)))
+ .collect(),
+ ),
+ );
}
if let Some(notification_url) = package.get_notification_url() {
- data.insert("notification-url".to_string(), PhpMixed::String(notification_url.to_string()));
+ data.insert(
+ "notification-url".to_string(),
+ PhpMixed::String(notification_url.to_string()),
+ );
}
let include_paths = package.get_include_paths();
if !include_paths.is_empty() {
- data.insert("include-path".to_string(), PhpMixed::List(include_paths.into_iter().map(|p| Box::new(PhpMixed::String(p))).collect()));
+ data.insert(
+ "include-path".to_string(),
+ PhpMixed::List(
+ include_paths
+ .into_iter()
+ .map(|p| Box::new(PhpMixed::String(p)))
+ .collect(),
+ ),
+ );
}
let php_ext = package.get_php_ext();
if !php_ext.is_empty() {
- data.insert("php-ext".to_string(), PhpMixed::Array(php_ext.into_iter().map(|(k, v)| (k, Box::new(v))).collect()));
+ data.insert(
+ "php-ext".to_string(),
+ PhpMixed::Array(php_ext.into_iter().map(|(k, v)| (k, Box::new(v))).collect()),
+ );
}
- if let Some(complete_pkg) = (package.as_any() as &dyn Any).downcast_ref::<CompletePackage>() {
+ if let Some(complete_pkg) = (package.as_any() as &dyn Any).downcast_ref::<CompletePackage>()
+ {
if let Some(archive_name) = complete_pkg.get_archive_name() {
- let entry = data.entry("archive".to_string()).or_insert_with(|| PhpMixed::Array(IndexMap::new()));
+ let entry = data
+ .entry("archive".to_string())
+ .or_insert_with(|| PhpMixed::Array(IndexMap::new()));
if let PhpMixed::Array(ref mut archive) = entry {
- archive.insert("name".to_string(), Box::new(PhpMixed::String(archive_name.to_string())));
+ archive.insert(
+ "name".to_string(),
+ Box::new(PhpMixed::String(archive_name.to_string())),
+ );
}
}
let archive_excludes = complete_pkg.get_archive_excludes();
if !archive_excludes.is_empty() {
- let entry = data.entry("archive".to_string()).or_insert_with(|| PhpMixed::Array(IndexMap::new()));
+ let entry = data
+ .entry("archive".to_string())
+ .or_insert_with(|| PhpMixed::Array(IndexMap::new()));
if let PhpMixed::Array(ref mut archive) = entry {
- archive.insert("exclude".to_string(), Box::new(PhpMixed::List(
- archive_excludes.into_iter().map(|e| Box::new(PhpMixed::String(e))).collect()
- )));
+ archive.insert(
+ "exclude".to_string(),
+ Box::new(PhpMixed::List(
+ archive_excludes
+ .into_iter()
+ .map(|e| Box::new(PhpMixed::String(e)))
+ .collect(),
+ )),
+ );
}
}
// dumpValues for complete package keys
let scripts = complete_pkg.get_scripts();
if !scripts.is_empty() {
- data.insert("scripts".to_string(), PhpMixed::Array(
- scripts.into_iter().map(|(k, v)| (k, Box::new(PhpMixed::List(v.into_iter().map(|s| Box::new(PhpMixed::String(s))).collect())))).collect()
- ));
+ data.insert(
+ "scripts".to_string(),
+ PhpMixed::Array(
+ scripts
+ .into_iter()
+ .map(|(k, v)| {
+ (
+ k,
+ Box::new(PhpMixed::List(
+ v.into_iter()
+ .map(|s| Box::new(PhpMixed::String(s)))
+ .collect(),
+ )),
+ )
+ })
+ .collect(),
+ ),
+ );
}
let license = complete_pkg.get_license();
if !license.is_empty() {
- data.insert("license".to_string(), PhpMixed::List(license.into_iter().map(|l| Box::new(PhpMixed::String(l))).collect()));
+ data.insert(
+ "license".to_string(),
+ PhpMixed::List(
+ license
+ .into_iter()
+ .map(|l| Box::new(PhpMixed::String(l)))
+ .collect(),
+ ),
+ );
}
let authors = complete_pkg.get_authors();
if !authors.is_empty() {
- data.insert("authors".to_string(), PhpMixed::List(
- authors.into_iter().map(|a| Box::new(PhpMixed::Array(
- a.into_iter().map(|(k, v)| (k, Box::new(PhpMixed::String(v)))).collect()
- ))).collect()
- ));
+ data.insert(
+ "authors".to_string(),
+ PhpMixed::List(
+ authors
+ .into_iter()
+ .map(|a| {
+ Box::new(PhpMixed::Array(
+ a.into_iter()
+ .map(|(k, v)| (k, Box::new(PhpMixed::String(v))))
+ .collect(),
+ ))
+ })
+ .collect(),
+ ),
+ );
}
if let Some(description) = complete_pkg.get_description() {
- data.insert("description".to_string(), PhpMixed::String(description.to_string()));
+ data.insert(
+ "description".to_string(),
+ PhpMixed::String(description.to_string()),
+ );
}
if let Some(homepage) = complete_pkg.get_homepage() {
- data.insert("homepage".to_string(), PhpMixed::String(homepage.to_string()));
+ data.insert(
+ "homepage".to_string(),
+ PhpMixed::String(homepage.to_string()),
+ );
}
let mut keywords = complete_pkg.get_keywords();
if !keywords.is_empty() {
keywords.sort();
- data.insert("keywords".to_string(), PhpMixed::List(keywords.into_iter().map(|k| Box::new(PhpMixed::String(k))).collect()));
+ data.insert(
+ "keywords".to_string(),
+ PhpMixed::List(
+ keywords
+ .into_iter()
+ .map(|k| Box::new(PhpMixed::String(k)))
+ .collect(),
+ ),
+ );
}
let repositories = complete_pkg.get_repositories();
if !repositories.is_empty() {
- data.insert("repositories".to_string(), PhpMixed::List(
- repositories.into_iter().map(|r| Box::new(PhpMixed::Array(
- r.into_iter().map(|(k, v)| (k, Box::new(v))).collect()
- ))).collect()
- ));
+ data.insert(
+ "repositories".to_string(),
+ PhpMixed::List(
+ repositories
+ .into_iter()
+ .map(|r| {
+ Box::new(PhpMixed::Array(
+ r.into_iter().map(|(k, v)| (k, Box::new(v))).collect(),
+ ))
+ })
+ .collect(),
+ ),
+ );
}
let support = complete_pkg.get_support();
if !support.is_empty() {
- data.insert("support".to_string(), PhpMixed::Array(
- support.into_iter().map(|(k, v)| (k, Box::new(PhpMixed::String(v)))).collect()
- ));
+ data.insert(
+ "support".to_string(),
+ PhpMixed::Array(
+ support
+ .into_iter()
+ .map(|(k, v)| (k, Box::new(PhpMixed::String(v))))
+ .collect(),
+ ),
+ );
}
let funding = complete_pkg.get_funding();
if !funding.is_empty() {
- data.insert("funding".to_string(), PhpMixed::List(
- funding.into_iter().map(|f| Box::new(PhpMixed::Array(
- f.into_iter().map(|(k, v)| (k, Box::new(v))).collect()
- ))).collect()
- ));
+ data.insert(
+ "funding".to_string(),
+ PhpMixed::List(
+ funding
+ .into_iter()
+ .map(|f| {
+ Box::new(PhpMixed::Array(
+ f.into_iter().map(|(k, v)| (k, Box::new(v))).collect(),
+ ))
+ })
+ .collect(),
+ ),
+ );
}
if complete_pkg.is_abandoned() {
- let abandoned_value = complete_pkg.get_replacement_package()
+ let abandoned_value = complete_pkg
+ .get_replacement_package()
.map(|r| PhpMixed::String(r.to_string()))
.unwrap_or(PhpMixed::Bool(true));
data.insert("abandoned".to_string(), abandoned_value);
@@ -218,15 +419,24 @@ impl ArrayDumper {
if let Some(root_pkg) = (package.as_any() as &dyn Any).downcast_ref::<RootPackage>() {
let minimum_stability = root_pkg.get_minimum_stability();
if !minimum_stability.is_empty() {
- data.insert("minimum-stability".to_string(), PhpMixed::String(minimum_stability.to_string()));
+ data.insert(
+ "minimum-stability".to_string(),
+ PhpMixed::String(minimum_stability.to_string()),
+ );
}
}
let transport_options = package.get_transport_options();
if !transport_options.is_empty() {
- data.insert("transport-options".to_string(), PhpMixed::Array(
- transport_options.into_iter().map(|(k, v)| (k, Box::new(v))).collect()
- ));
+ data.insert(
+ "transport-options".to_string(),
+ PhpMixed::Array(
+ transport_options
+ .into_iter()
+ .map(|(k, v)| (k, Box::new(v)))
+ .collect(),
+ ),
+ );
}
data
diff --git a/crates/shirabe/src/package/dumper/mod.rs b/crates/shirabe/src/package/dumper/mod.rs
new file mode 100644
index 0000000..b50c878
--- /dev/null
+++ b/crates/shirabe/src/package/dumper/mod.rs
@@ -0,0 +1 @@
+pub mod array_dumper;
diff --git a/crates/shirabe/src/package/link.rs b/crates/shirabe/src/package/link.rs
index 37f8124..2233eb1 100644
--- a/crates/shirabe/src/package/link.rs
+++ b/crates/shirabe/src/package/link.rs
@@ -87,7 +87,10 @@ impl Link {
pub fn get_pretty_constraint(&self) -> anyhow::Result<&str> {
match &self.pretty_constraint {
None => Err(anyhow::anyhow!(UnexpectedValueException {
- message: format!("Link {} has been misconfigured and had no prettyConstraint given.", self.to_string()),
+ message: format!(
+ "Link {} has been misconfigured and had no prettyConstraint given.",
+ self.to_string()
+ ),
code: 0,
})),
Some(s) => Ok(s.as_str()),
@@ -95,7 +98,10 @@ impl Link {
}
pub fn to_string(&self) -> String {
- format!("{} {} {} ({})", self.source, self.description, self.target, self.constraint)
+ format!(
+ "{} {} {} ({})",
+ self.source, self.description, self.target, self.constraint
+ )
}
pub fn get_pretty_string(&self, source_package: &dyn PackageInterface) -> String {
diff --git a/crates/shirabe/src/package/loader/array_loader.rs b/crates/shirabe/src/package/loader/array_loader.rs
index c0dc2a2..72d9754 100644
--- a/crates/shirabe/src/package/loader/array_loader.rs
+++ b/crates/shirabe/src/package/loader/array_loader.rs
@@ -5,9 +5,9 @@ use chrono::{DateTime, TimeZone, Utc};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- is_scalar, is_string, json_encode, ltrim, sprintf, stripos, strpos, strtolower, strval, substr,
- trigger_error, trim, ucfirst, Exception, LogicException, PhpMixed, UnexpectedValueException,
- E_USER_DEPRECATED,
+ E_USER_DEPRECATED, Exception, LogicException, PhpMixed, UnexpectedValueException, is_scalar,
+ is_string, json_encode, ltrim, sprintf, stripos, strpos, strtolower, strval, substr,
+ trigger_error, trim, ucfirst,
};
use crate::package::base_package::{BasePackage, SUPPORTED_LINK_TYPES};
@@ -213,7 +213,9 @@ impl ArrayLoader {
let _name = config.get("name").and_then(|v| v.as_string()).unwrap_or("");
let _pretty_version = config_version.as_string().unwrap_or("").to_string();
let _ = version;
- todo!("phase-b: dynamic class-string instantiation new $class($name, $version, $prettyVersion)")
+ todo!(
+ "phase-b: dynamic class-string instantiation new $class($name, $version, $prettyVersion)"
+ )
}
/// @param CompletePackage $package
@@ -482,9 +484,7 @@ impl ArrayLoader {
if let Some(description) = config.get("description") {
if !shirabe_php_shim::empty(description) && is_string(description) {
- package.set_description(
- description.as_string().unwrap_or("").to_string(),
- );
+ package.set_description(description.as_string().unwrap_or("").to_string());
}
}
@@ -629,10 +629,9 @@ impl ArrayLoader {
let mut links: IndexMap<String, Link> = IndexMap::new();
let entries: IndexMap<String, PhpMixed> = match entry {
- PhpMixed::Array(m) => m
- .iter()
- .map(|(k, v)| (k.clone(), (**v).clone()))
- .collect(),
+ PhpMixed::Array(m) => {
+ m.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect()
+ }
_ => continue,
};
for (pretty_target, constraint) in entries {
@@ -781,10 +780,7 @@ impl ArrayLoader {
/// @param mixed[] $config the entire package config
///
/// @return string|null normalized version of the branch alias or null if there is none
- pub fn get_branch_alias(
- &self,
- config: &IndexMap<String, PhpMixed>,
- ) -> Result<Option<String>> {
+ pub fn get_branch_alias(&self, config: &IndexMap<String, PhpMixed>) -> Result<Option<String>> {
if !config.contains_key("version") || !is_scalar(config.get("version").unwrap()) {
return Err(UnexpectedValueException {
message: "no/invalid version defined".to_string(),
@@ -824,7 +820,8 @@ impl ArrayLoader {
}
// normalize without -dev and ensure it's a numeric branch that is parseable
- let validated_target_branch = if target_branch == VersionParser::DEFAULT_BRANCH_ALIAS
+ let validated_target_branch = if target_branch
+ == VersionParser::DEFAULT_BRANCH_ALIAS
{
VersionParser::DEFAULT_BRANCH_ALIAS.to_string()
} else {
@@ -841,9 +838,12 @@ impl ArrayLoader {
}
// If using numeric aliases ensure the alias is a valid subversion
- let source_prefix =
- self.version_parser.parse_numeric_alias_prefix(&source_branch);
- let target_prefix = self.version_parser.parse_numeric_alias_prefix(&target_branch);
+ let source_prefix = self
+ .version_parser
+ .parse_numeric_alias_prefix(&source_branch);
+ let target_prefix = self
+ .version_parser
+ .parse_numeric_alias_prefix(&target_branch);
if let (Some(sp), Some(tp)) = (source_prefix.as_ref(), target_prefix.as_ref()) {
if stripos(tp, sp) != Some(0) {
continue;
diff --git a/crates/shirabe/src/package/loader/invalid_package_exception.rs b/crates/shirabe/src/package/loader/invalid_package_exception.rs
index 88a7f5f..b0eeb23 100644
--- a/crates/shirabe/src/package/loader/invalid_package_exception.rs
+++ b/crates/shirabe/src/package/loader/invalid_package_exception.rs
@@ -14,7 +14,12 @@ impl InvalidPackageException {
pub fn new(errors: Vec<String>, warnings: Vec<String>, data: Vec<PhpMixed>) -> Self {
let message = format!(
"Invalid package information: \n{}",
- errors.iter().chain(warnings.iter()).cloned().collect::<Vec<_>>().join("\n")
+ errors
+ .iter()
+ .chain(warnings.iter())
+ .cloned()
+ .collect::<Vec<_>>()
+ .join("\n")
);
Self {
inner: Exception { message, code: 0 },
diff --git a/crates/shirabe/src/package/loader/json_loader.rs b/crates/shirabe/src/package/loader/json_loader.rs
index 5e5829a..8f10995 100644
--- a/crates/shirabe/src/package/loader/json_loader.rs
+++ b/crates/shirabe/src/package/loader/json_loader.rs
@@ -1,10 +1,10 @@
//! ref: composer/src/Composer/Package/Loader/JsonLoader.php
-use std::path::Path;
-use anyhow::Result;
use crate::json::json_file::JsonFile;
use crate::package::base_package::BasePackage;
use crate::package::loader::loader_interface::LoaderInterface;
+use anyhow::Result;
+use std::path::Path;
pub enum JsonLoaderInput {
File(JsonFile),
@@ -26,9 +26,7 @@ impl JsonLoader {
JsonLoaderInput::String(ref s) if Path::new(s).exists() => {
JsonFile::parse_json(&std::fs::read_to_string(s)?, Some(s))?
}
- JsonLoaderInput::String(ref s) => {
- JsonFile::parse_json(s, None)?
- }
+ JsonLoaderInput::String(ref s) => JsonFile::parse_json(s, None)?,
};
self.loader.load(config, None)
diff --git a/crates/shirabe/src/package/loader/loader_interface.rs b/crates/shirabe/src/package/loader/loader_interface.rs
index 9f1e6da..530f1eb 100644
--- a/crates/shirabe/src/package/loader/loader_interface.rs
+++ b/crates/shirabe/src/package/loader/loader_interface.rs
@@ -1,9 +1,13 @@
//! ref: composer/src/Composer/Package/Loader/LoaderInterface.php
+use crate::package::base_package::BasePackage;
use indexmap::IndexMap;
use shirabe_php_shim::PhpMixed;
-use crate::package::base_package::BasePackage;
pub trait LoaderInterface {
- fn load(&self, config: IndexMap<String, PhpMixed>, class: Option<String>) -> anyhow::Result<Box<BasePackage>>;
+ fn load(
+ &self,
+ config: IndexMap<String, PhpMixed>,
+ class: Option<String>,
+ ) -> anyhow::Result<Box<BasePackage>>;
}
diff --git a/crates/shirabe/src/package/loader/mod.rs b/crates/shirabe/src/package/loader/mod.rs
new file mode 100644
index 0000000..402b59c
--- /dev/null
+++ b/crates/shirabe/src/package/loader/mod.rs
@@ -0,0 +1,6 @@
+pub mod array_loader;
+pub mod invalid_package_exception;
+pub mod json_loader;
+pub mod loader_interface;
+pub mod root_package_loader;
+pub mod validating_array_loader;
diff --git a/crates/shirabe/src/package/loader/root_package_loader.rs b/crates/shirabe/src/package/loader/root_package_loader.rs
index eef7d70..59c9cf5 100644
--- a/crates/shirabe/src/package/loader/root_package_loader.rs
+++ b/crates/shirabe/src/package/loader/root_package_loader.rs
@@ -2,7 +2,9 @@
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
-use shirabe_php_shim::{strtolower, ucfirst, LogicException, RuntimeException, UnexpectedValueException};
+use shirabe_php_shim::{
+ LogicException, RuntimeException, UnexpectedValueException, strtolower, ucfirst,
+};
use crate::config::Config;
use crate::io::io_interface::IOInterface;
@@ -92,12 +94,16 @@ impl RootPackageLoader {
Box::new(shirabe_php_shim::PhpMixed::String(version)),
);
} else {
- let cwd_str = cwd.map(|s| s.to_string()).unwrap_or_else(|| Platform::get_cwd(true));
+ let cwd_str = cwd
+ .map(|s| s.to_string())
+ .unwrap_or_else(|| Platform::get_cwd(true));
let version_data = self.version_guesser.guess_version(&config, &cwd_str);
if let Some(data) = version_data {
config.insert(
"version".to_string(),
- Box::new(shirabe_php_shim::PhpMixed::String(data.pretty_version.clone())),
+ Box::new(shirabe_php_shim::PhpMixed::String(
+ data.pretty_version.clone(),
+ )),
);
config.insert(
"version_normalized".to_string(),
@@ -110,10 +116,7 @@ impl RootPackageLoader {
if !config.contains_key("version") {
if let Some(ref io) = self.io {
let name = config["name"].as_string().unwrap_or("");
- let package_type = config
- .get("type")
- .and_then(|v| v.as_string())
- .unwrap_or("");
+ let package_type = config.get("type").and_then(|v| v.as_string()).unwrap_or("");
if name != "__root__" && package_type != "project" {
io.warning(&format!(
"Composer could not detect the root package ({}) version, defaulting to '1.0.0'. See https://getcomposer.org/root-version",
@@ -167,42 +170,43 @@ impl RootPackageLoader {
}
}
- let package = self.inner.load(config.clone(), "Composer\\Package\\RootPackage")?;
+ let package = self
+ .inner
+ .load(config.clone(), "Composer\\Package\\RootPackage")?;
- let real_package: &mut RootPackage = if let Some(alias_pkg) =
- package.as_any_mut().downcast_mut::<RootAliasPackage>()
- {
- alias_pkg
- .get_alias_of_mut()
- .as_any_mut()
- .downcast_mut::<RootPackage>()
- .ok_or_else(|| {
- anyhow::anyhow!(LogicException {
- message: "Expecting a Composer\\Package\\RootPackage at this point"
- .to_string(),
- code: 0,
- })
- })?
- } else if let Some(root_pkg) = package.as_any_mut().downcast_mut::<RootPackage>() {
- root_pkg
- } else {
- return Err(anyhow::anyhow!(LogicException {
- message: "Expecting a Composer\\Package\\RootPackage at this point".to_string(),
- code: 0,
- }));
- };
+ let real_package: &mut RootPackage =
+ if let Some(alias_pkg) = package.as_any_mut().downcast_mut::<RootAliasPackage>() {
+ alias_pkg
+ .get_alias_of_mut()
+ .as_any_mut()
+ .downcast_mut::<RootPackage>()
+ .ok_or_else(|| {
+ anyhow::anyhow!(LogicException {
+ message: "Expecting a Composer\\Package\\RootPackage at this point"
+ .to_string(),
+ code: 0,
+ })
+ })?
+ } else if let Some(root_pkg) = package.as_any_mut().downcast_mut::<RootPackage>() {
+ root_pkg
+ } else {
+ return Err(anyhow::anyhow!(LogicException {
+ message: "Expecting a Composer\\Package\\RootPackage at this point".to_string(),
+ code: 0,
+ }));
+ };
if auto_versioned {
- real_package
- .replace_version(real_package.get_version().to_string(), RootPackage::DEFAULT_PRETTY_VERSION.to_string());
+ real_package.replace_version(
+ real_package.get_version().to_string(),
+ RootPackage::DEFAULT_PRETTY_VERSION.to_string(),
+ );
}
- if let Some(min_stability) = config
- .get("minimum-stability")
- .and_then(|v| v.as_string())
- {
- real_package
- .set_minimum_stability(VersionParser::normalize_stability(min_stability).to_string());
+ if let Some(min_stability) = config.get("minimum-stability").and_then(|v| v.as_string()) {
+ real_package.set_minimum_stability(
+ VersionParser::normalize_stability(min_stability).to_string(),
+ );
}
let mut aliases: Vec<IndexMap<String, String>> = vec![];
@@ -362,16 +366,11 @@ impl RootPackageLoader {
}
let stability_names: Vec<&str> = stabilities.keys().copied().collect();
- let pattern = format!(
- "^[^@]*?@({})$",
- stability_names.join("|")
- );
+ let pattern = format!("^[^@]*?@({})$", stability_names.join("|"));
let mut matched = false;
for constraint in &constraints {
- if let Some(Some(m)) =
- Preg::is_match_strict_groups(&pattern, constraint).ok()
- {
+ if let Some(Some(m)) = Preg::is_match_strict_groups(&pattern, constraint).ok() {
let name = strtolower(req_name);
let stability = stabilities[VersionParser::normalize_stability(&m[1])];
diff --git a/crates/shirabe/src/package/loader/validating_array_loader.rs b/crates/shirabe/src/package/loader/validating_array_loader.rs
index 16806d7..c1be9f2 100644
--- a/crates/shirabe/src/package/loader/validating_array_loader.rs
+++ b/crates/shirabe/src/package/loader/validating_array_loader.rs
@@ -6,10 +6,10 @@ use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::composer::spdx_licenses::spdx_licenses::SpdxLicenses;
use shirabe_php_shim::{
- array_intersect_key, array_values, filter_var, get_debug_type, is_array, is_bool, is_int,
- is_numeric, is_scalar, is_string, json_encode, parse_url_all, php_to_string, sprintf,
- str_replace, strcasecmp, strtolower, strtotime, substr, trigger_error, trim, var_export,
- Exception, PhpMixed, E_USER_DEPRECATED, FILTER_VALIDATE_EMAIL, PHP_EOL,
+ E_USER_DEPRECATED, Exception, FILTER_VALIDATE_EMAIL, PHP_EOL, PhpMixed, array_intersect_key,
+ array_values, filter_var, get_debug_type, is_array, is_bool, is_int, is_numeric, is_scalar,
+ is_string, json_encode, parse_url_all, php_to_string, sprintf, str_replace, strcasecmp,
+ strtolower, strtotime, substr, trigger_error, trim, var_export,
};
use shirabe_semver::constraint::constraint::Constraint;
use shirabe_semver::constraint::match_none_constraint::MatchNoneConstraint;
@@ -97,11 +97,8 @@ impl ValidatingArrayLoader {
match self.version_parser.normalize(&version_str, None) {
Ok(_) => {}
Err(e) => {
- self.errors.push(format!(
- "version : invalid value ({}): {}",
- version_str,
- e
- ));
+ self.errors
+ .push(format!("version : invalid value ({}): {}", version_str, e));
self.config.shift_remove("version");
}
}
@@ -173,10 +170,8 @@ impl ValidatingArrayLoader {
release_date = Some(dt);
}
Err(e) => {
- self.errors.push(format!(
- "time : invalid value ({}): {}",
- time_str, e
- ));
+ self.errors
+ .push(format!("time : invalid value ({}): {}", time_str, e));
self.config.shift_remove("time");
}
}
@@ -209,9 +204,7 @@ impl ValidatingArrayLoader {
// check for license validity on newly updated branches/tags
let cutoff = strtotime("-8days").unwrap_or(0);
- if release_date.is_none()
- || release_date.unwrap().timestamp() >= cutoff
- {
+ if release_date.is_none() || release_date.unwrap().timestamp() >= cutoff {
let license_validator = SpdxLicenses::new();
for license in licenses.values() {
let license_str = license.as_string().unwrap_or("").to_string();
@@ -219,10 +212,11 @@ impl ValidatingArrayLoader {
if license_str == "proprietary" {
continue;
}
- let license_to_validate =
- str_replace("proprietary", "MIT", &license_str);
+ let license_to_validate = str_replace("proprietary", "MIT", &license_str);
if !license_validator.validate(&license_to_validate) {
- if license_validator.validate(&trim(&license_to_validate, " \t\n\r\0\u{0B}")) {
+ if license_validator
+ .validate(&trim(&license_to_validate, " \t\n\r\0\u{0B}"))
+ {
self.warnings.push(sprintf(
"License %s must not contain extra spaces, make sure to trim it.",
&[PhpMixed::String(
@@ -258,7 +252,9 @@ impl ValidatingArrayLoader {
} else {
self.warnings.push(sprintf(
"License must be a string or array of strings, got %s.",
- &[PhpMixed::String(json_encode(&*license_val).unwrap_or_default())],
+ &[PhpMixed::String(
+ json_encode(&*license_val).unwrap_or_default(),
+ )],
));
self.config.shift_remove("license");
}
@@ -277,20 +273,15 @@ impl ValidatingArrayLoader {
key,
get_debug_type(&*author)
));
- if let Some(PhpMixed::Array(m)) = self
- .config
- .get_mut("authors")
- .map(|v| v.as_mut())
+ if let Some(PhpMixed::Array(m)) =
+ self.config.get_mut("authors").map(|v| v.as_mut())
{
m.shift_remove(key);
}
continue;
}
for author_data in ["homepage", "email", "name", "role"] {
- let val_opt = author
- .as_array()
- .and_then(|m| m.get(author_data))
- .cloned();
+ let val_opt = author.as_array().and_then(|m| m.get(author_data)).cloned();
if let Some(val) = val_opt {
if !is_string(&*val) {
self.errors.push(format!(
@@ -395,10 +386,8 @@ impl ValidatingArrayLoader {
.cloned();
if let Some(val) = val_opt {
if !is_string(&*val) {
- self.errors.push(format!(
- "support.{} : invalid value, must be a string",
- key
- ));
+ self.errors
+ .push(format!("support.{} : invalid value, must be a string", key));
if let Some(PhpMixed::Array(support)) =
self.config.get_mut("support").map(|v| v.as_mut())
{
@@ -450,7 +439,9 @@ impl ValidatingArrayLoader {
}
}
- for key in ["issues", "forum", "wiki", "source", "docs", "chat", "security"] {
+ for key in [
+ "issues", "forum", "wiki", "source", "docs", "chat", "security",
+ ] {
let url_opt = self
.config
.get("support")
@@ -647,8 +638,11 @@ impl ValidatingArrayLoader {
));
php_ext.shift_remove("download-url-method");
} else {
- let valid_download_url_methods =
- ["composer-default", "pre-packaged-source", "pre-packaged-binary"];
+ let valid_download_url_methods = [
+ "composer-default",
+ "pre-packaged-source",
+ "pre-packaged-binary",
+ ];
let defined_download_url_methods: IndexMap<String, Box<PhpMixed>> =
if is_array(&*v) {
v.as_array().unwrap().clone()
@@ -673,9 +667,9 @@ impl ValidatingArrayLoader {
get_debug_type(&**download_url_method)
));
php_ext.shift_remove("download-url-method");
- } else if !valid_download_url_methods.contains(
- &download_url_method.as_string().unwrap_or(""),
- ) {
+ } else if !valid_download_url_methods
+ .contains(&download_url_method.as_string().unwrap_or(""))
+ {
self.errors.push(format!(
"php-ext.download-url-method.{} : invalid value ({}), must be one of {}",
key,
@@ -718,15 +712,10 @@ impl ValidatingArrayLoader {
));
php_ext.shift_remove(field_name);
} else {
- let field_keys: Vec<String> = field_val
- .as_array()
- .unwrap()
- .keys()
- .cloned()
- .collect();
+ let field_keys: Vec<String> =
+ field_val.as_array().unwrap().keys().cloned().collect();
for key in &field_keys {
- let os_family =
- field_val.as_array().unwrap()[key].clone();
+ let os_family = field_val.as_array().unwrap()[key].clone();
if !is_string(&*os_family) {
self.errors.push(format!(
"php-ext.{}.{} : should be a string, {} given",
@@ -785,8 +774,7 @@ impl ValidatingArrayLoader {
.cloned()
.collect();
for key in &configure_keys {
- let option =
- configure_options.as_array().unwrap()[key].clone();
+ let option = configure_options.as_array().unwrap()[key].clone();
if !is_array(&*option) {
self.errors.push(format!(
"php-ext.configure-options.{} : should be an array, {} given",
@@ -837,9 +825,8 @@ impl ValidatingArrayLoader {
key,
get_debug_type(&*needs_value)
));
- if let Some(PhpMixed::Array(co)) = php_ext
- .get_mut("configure-options")
- .map(|v| v.as_mut())
+ if let Some(PhpMixed::Array(co)) =
+ php_ext.get_mut("configure-options").map(|v| v.as_mut())
{
if let Some(entry) = co.get_mut(key) {
if let PhpMixed::Array(em) = entry.as_mut() {
@@ -850,18 +837,15 @@ impl ValidatingArrayLoader {
}
}
- if let Some(description) =
- option_map.get("description").cloned()
- {
+ if let Some(description) = option_map.get("description").cloned() {
if !is_string(&*description) {
self.errors.push(format!(
"php-ext.configure-options.{}.description : should be a string, {} given",
key,
get_debug_type(&*description)
));
- if let Some(PhpMixed::Array(co)) = php_ext
- .get_mut("configure-options")
- .map(|v| v.as_mut())
+ if let Some(PhpMixed::Array(co)) =
+ php_ext.get_mut("configure-options").map(|v| v.as_mut())
{
if let Some(entry) = co.get_mut(key) {
if let PhpMixed::Array(em) = entry.as_mut() {
@@ -886,10 +870,8 @@ impl ValidatingArrayLoader {
// If php-ext is now empty, unset it
if !php_ext.is_empty() {
- self.config.insert(
- "php-ext".to_string(),
- Box::new(PhpMixed::Array(php_ext)),
- );
+ self.config
+ .insert("php-ext".to_string(), Box::new(PhpMixed::Array(php_ext)));
}
}
}
@@ -938,8 +920,7 @@ impl ValidatingArrayLoader {
arr.shift_remove(&package);
}
} else if constraint.as_string().unwrap_or("") != "self.version" {
- let constraint_str =
- constraint.as_string().unwrap_or("").to_string();
+ let constraint_str = constraint.as_string().unwrap_or("").to_string();
let link_constraint =
match self.version_parser.parse_constraints(&constraint_str) {
Ok(c) => c,
@@ -972,9 +953,7 @@ impl ValidatingArrayLoader {
&& link_constraint
.as_any()
.downcast_ref::<Constraint>()
- .map_or(false, |c| {
- ["==", "="].contains(&c.get_operator())
- })
+ .map_or(false, |c| ["==", "="].contains(&c.get_operator()))
&& Constraint::new(">=", "1.0.0.0-dev")
.matches(link_constraint.as_ref())
{
@@ -1063,7 +1042,13 @@ impl ValidatingArrayLoader {
}
if self.validate_array("autoload", false) && self.config.contains_key("autoload") {
- let types = ["psr-0", "psr-4", "classmap", "files", "exclude-from-classmap"];
+ let types = [
+ "psr-0",
+ "psr-4",
+ "classmap",
+ "files",
+ "exclude-from-classmap",
+ ];
let autoload_keys: Vec<String> = self.config["autoload"]
.as_array()
.map(|m| m.keys().cloned().collect())
@@ -1086,9 +1071,7 @@ impl ValidatingArrayLoader {
if let Some(type_map) = type_config.as_array() {
for (namespace, _dirs) in type_map {
let ns_str = namespace.as_str();
- if ns_str != ""
- && substr(ns_str, -1, None) != "\\"
- {
+ if ns_str != "" && substr(ns_str, -1, None) != "\\" {
self.errors.push(format!(
"autoload.psr-4 : invalid value ({}), namespaces must end with a namespace separator, should be {}\\\\",
ns_str, ns_str
@@ -1112,8 +1095,7 @@ impl ValidatingArrayLoader {
);
// Unset the psr-4 setting, since unsetting target-dir might
// interfere with other settings.
- if let Some(PhpMixed::Array(arr)) =
- self.config.get_mut("autoload").map(|v| v.as_mut())
+ if let Some(PhpMixed::Array(arr)) = self.config.get_mut("autoload").map(|v| v.as_mut())
{
arr.shift_remove("psr-4");
}
@@ -1205,8 +1187,9 @@ impl ValidatingArrayLoader {
if has_branch_alias {
let branch_alias_val = self.config["extra"].as_array().unwrap()["branch-alias"].clone();
if !is_array(&*branch_alias_val) {
- self.errors
- .push("extra.branch-alias : must be an array of versions => aliases".to_string());
+ self.errors.push(
+ "extra.branch-alias : must be an array of versions => aliases".to_string(),
+ );
} else {
let branch_alias_map = branch_alias_val.as_array().cloned().unwrap_or_default();
for (source_branch, target_branch) in &branch_alias_map {
@@ -1255,9 +1238,7 @@ impl ValidatingArrayLoader {
0,
Some((target_branch_str.len() as i64) - 4),
);
- let validated_target_branch = self
- .version_parser
- .normalize_branch(&trimmed);
+ let validated_target_branch = self.version_parser.normalize_branch(&trimmed);
if substr(&validated_target_branch, -4, None) != "-dev" {
self.warnings.push(format!(
"extra.branch-alias.{} : the target branch ({}) must be a parseable number like 2.0-dev",
@@ -1311,15 +1292,13 @@ impl ValidatingArrayLoader {
)));
}
- let package = self
- .loader
- .load(
- self.config
- .iter()
- .map(|(k, v)| (k.clone(), (**v).clone()))
- .collect(),
- Some(class.to_string()),
- )?;
+ let package = self.loader.load(
+ self.config
+ .iter()
+ .map(|(k, v)| (k.clone(), (**v).clone()))
+ .collect(),
+ Some(class.to_string()),
+ )?;
self.config = IndexMap::new();
Ok(package)
@@ -1344,7 +1323,10 @@ impl ValidatingArrayLoader {
)
.unwrap_or(false)
{
- return Some(format!("{} is invalid, it should have a vendor name, a forward slash, and a package name. The vendor and package name can be words separated by -, . or _. The complete name should match \"^[a-z0-9]([_.-]?[a-z0-9]+)*/[a-z0-9](([_.]?|-{{0,2}})[a-z0-9]+)*$\".", name));
+ return Some(format!(
+ "{} is invalid, it should have a vendor name, a forward slash, and a package name. The vendor and package name can be words separated by -, . or _. The complete name should match \"^[a-z0-9]([_.-]?[a-z0-9]+)*/[a-z0-9](([_.]?|-{{0,2}})[a-z0-9]+)*$\".",
+ name
+ ));
}
let reserved_names = [
@@ -1401,7 +1383,10 @@ impl ValidatingArrayLoader {
let value = self.config[property].as_string().unwrap_or("").to_string();
if !Preg::is_match(&format!("{{^{}$}}u", regex), &value).unwrap_or(false) {
- let message = format!("{} : invalid value ({}), must match {}", property, value, regex);
+ let message = format!(
+ "{} : invalid value ({}), must match {}",
+ property, value, regex
+ );
if mandatory {
self.errors.push(message);
} else {
@@ -1428,11 +1413,13 @@ impl ValidatingArrayLoader {
}
let is_empty = !self.config.contains_key(property)
- || trim(self.config[property].as_string().unwrap_or(""), " \t\n\r\0\u{0B}") == "";
+ || trim(
+ self.config[property].as_string().unwrap_or(""),
+ " \t\n\r\0\u{0B}",
+ ) == "";
if is_empty {
if mandatory {
- self.errors
- .push(format!("{} : must be present", property));
+ self.errors.push(format!("{} : must be present", property));
}
self.config.shift_remove(property);
diff --git a/crates/shirabe/src/package/locker.rs b/crates/shirabe/src/package/locker.rs
index a0401ba..b813bbb 100644
--- a/crates/shirabe/src/package/locker.rs
+++ b/crates/shirabe/src/package/locker.rs
@@ -6,10 +6,10 @@ use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::seld::json_lint::parsing_exception::ParsingException;
use shirabe_php_shim::{
- array_intersect, array_keys, array_map, array_merge, call_user_func, file_get_contents,
- filemtime, function_exists, hash, in_array, is_array, is_int, ksort, realpath, reset_first,
- sprintf, strcmp, strtolower, touch, trim, usort, LogicException, PhpMixed, RuntimeException,
- DATE_RFC3339,
+ DATE_RFC3339, LogicException, PhpMixed, RuntimeException, array_intersect, array_keys,
+ array_map, array_merge, call_user_func, file_get_contents, filemtime, function_exists, hash,
+ in_array, is_array, is_int, ksort, realpath, reset_first, sprintf, strcmp, strtolower, touch,
+ trim, usort,
};
use crate::installer::installation_manager::InstallationManager;
@@ -104,19 +104,18 @@ impl Locker {
let mut relevant_content: IndexMap<String, PhpMixed> = IndexMap::new();
let content_keys: Vec<String> = array_keys(&content);
- let relevant_keys_strings: Vec<String> = relevant_keys.iter().map(|s| s.to_string()).collect();
+ let relevant_keys_strings: Vec<String> =
+ relevant_keys.iter().map(|s| s.to_string()).collect();
let intersected = array_intersect(&relevant_keys_strings, &content_keys);
for key in intersected {
if let Some(value) = content.get(&key) {
relevant_content.insert(key, value.clone());
}
}
- let platform_value = content
- .get("config")
- .and_then(|v| match v {
- PhpMixed::Array(m) => m.get("platform").cloned(),
- _ => None,
- });
+ let platform_value = content.get("config").and_then(|v| match v {
+ PhpMixed::Array(m) => m.get("platform").cloned(),
+ _ => None,
+ });
if let Some(platform) = platform_value {
let mut config_map: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
config_map.insert("platform".to_string(), platform);
@@ -174,10 +173,7 @@ impl Locker {
}
/// Searches and returns an array of locked packages, retrieved from registered repositories.
- pub fn get_locked_repository(
- &mut self,
- with_dev_reqs: bool,
- ) -> Result<LockArrayRepository> {
+ pub fn get_locked_repository(&mut self, with_dev_reqs: bool) -> Result<LockArrayRepository> {
let lock_data = self.get_lock_data()?;
let mut packages = LockArrayRepository::new(vec![])?;
@@ -221,8 +217,7 @@ impl Locker {
m.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect();
let package = self.loader.load(info_map, None)?;
packages.add_package(package.clone())?;
- package_by_name
- .insert(package.get_name().to_string(), package.clone());
+ package_by_name.insert(package.get_name().to_string(), package.clone());
// TODO(phase-b): `$package instanceof AliasPackage` downcast
let package_as_alias: Option<&AliasPackage> = None;
@@ -245,8 +240,7 @@ impl Locker {
.and_then(|v| v.as_string())
.unwrap_or("")
.to_string();
- if let Some(base_pkg) = package_by_name.get(&alias_pkg_name).cloned()
- {
+ if let Some(base_pkg) = package_by_name.get(&alias_pkg_name).cloned() {
let mut alias_pkg = CompleteAliasPackage::new(
todo!("phase-b: downcast Box<BasePackage> to CompletePackage"),
m.get("alias_normalized")
@@ -272,8 +266,9 @@ impl Locker {
}
Err(RuntimeException {
- message: "Your composer.lock is invalid. Run \"composer update\" to generate a new one."
- .to_string(),
+ message:
+ "Your composer.lock is invalid. Run \"composer update\" to generate a new one."
+ .to_string(),
code: 0,
}
.into())
@@ -308,7 +303,9 @@ impl Locker {
"1.0.0",
Link::TYPE_REQUIRE,
match platform_value.unwrap() {
- PhpMixed::Array(m) => m.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect(),
+ PhpMixed::Array(m) => {
+ m.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect()
+ }
_ => IndexMap::new(),
},
)?;
@@ -324,7 +321,9 @@ impl Locker {
"1.0.0",
Link::TYPE_REQUIRE,
match platform_dev_value.unwrap() {
- PhpMixed::Array(m) => m.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect(),
+ PhpMixed::Array(m) => {
+ m.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect()
+ }
_ => IndexMap::new(),
},
)?;
@@ -514,10 +513,7 @@ impl Locker {
"content-hash".to_string(),
PhpMixed::String(self.content_hash.clone()),
);
- lock.insert(
- "packages".to_string(),
- self.lock_packages(&packages)?,
- );
+ lock.insert("packages".to_string(), self.lock_packages(&packages)?);
lock.insert("packages-dev".to_string(), PhpMixed::Null);
lock.insert(
"aliases".to_string(),
@@ -526,7 +522,9 @@ impl Locker {
.iter()
.map(|m| {
Box::new(PhpMixed::Array(
- m.iter().map(|(k, v)| (k.clone(), Box::new(v.clone()))).collect(),
+ m.iter()
+ .map(|(k, v)| (k.clone(), Box::new(v.clone())))
+ .collect(),
))
})
.collect(),
@@ -610,11 +608,7 @@ impl Locker {
if !is_locked || Some(&lock) != current_data.as_ref() {
if write {
self.lock_file.write(
- PhpMixed::Array(
- lock.into_iter()
- .map(|(k, v)| (k, Box::new(v)))
- .collect(),
- ),
+ PhpMixed::Array(lock.into_iter().map(|(k, v)| (k, Box::new(v))).collect()),
None,
)?;
self.lock_data_cache = None;
@@ -623,11 +617,7 @@ impl Locker {
self.virtual_file_written = true;
self.lock_data_cache = Some(JsonFile::parse_json(
&JsonFile::encode(
- &PhpMixed::Array(
- lock.into_iter()
- .map(|(k, v)| (k, Box::new(v)))
- .collect(),
- ),
+ &PhpMixed::Array(lock.into_iter().map(|(k, v)| (k, Box::new(v))).collect()),
shirabe_php_shim::JSON_UNESCAPED_SLASHES
| shirabe_php_shim::JSON_PRETTY_PRINT
| shirabe_php_shim::JSON_UNESCAPED_UNICODE,
@@ -886,7 +876,12 @@ impl Locker {
r"{^\s*(\d+)\s*}",
output.as_string().unwrap_or(""),
) {
- let ts = m.get(1).cloned().unwrap_or_default().parse::<i64>().unwrap_or(0);
+ let ts = m
+ .get(1)
+ .cloned()
+ .unwrap_or_default()
+ .parse::<i64>()
+ .unwrap_or(0);
datetime = chrono::DateTime::from_timestamp(ts, 0);
}
}
@@ -941,10 +936,8 @@ impl Locker {
)
.is_empty()
{
- let results = installed_repo.find_packages_with_replacers_and_providers(
- &link.get_target(),
- None,
- );
+ let results = installed_repo
+ .find_packages_with_replacers_and_providers(&link.get_target(), None);
if !results.is_empty() {
let provider = reset_first(&results).unwrap();
diff --git a/crates/shirabe/src/package/mod.rs b/crates/shirabe/src/package/mod.rs
new file mode 100644
index 0000000..77a01a2
--- /dev/null
+++ b/crates/shirabe/src/package/mod.rs
@@ -0,0 +1,17 @@
+pub mod alias_package;
+pub mod archiver;
+pub mod base_package;
+pub mod comparer;
+pub mod complete_alias_package;
+pub mod complete_package;
+pub mod complete_package_interface;
+pub mod dumper;
+pub mod link;
+pub mod loader;
+pub mod locker;
+pub mod package;
+pub mod package_interface;
+pub mod root_alias_package;
+pub mod root_package;
+pub mod root_package_interface;
+pub mod version;
diff --git a/crates/shirabe/src/package/package.rs b/crates/shirabe/src/package/package.rs
index fac6d46..81d6131 100644
--- a/crates/shirabe/src/package/package.rs
+++ b/crates/shirabe/src/package/package.rs
@@ -4,7 +4,7 @@ use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::composer::util::composer_mirror::ComposerMirror;
-use shirabe_php_shim::{strpos, trigger_error, PhpMixed, E_USER_DEPRECATED};
+use shirabe_php_shim::{E_USER_DEPRECATED, PhpMixed, strpos, trigger_error};
use crate::package::base_package::BasePackage;
use crate::package::link::Link;
@@ -109,7 +109,10 @@ impl Package {
}
pub fn get_type(&self) -> String {
- self.r#type.clone().filter(|s| !s.is_empty()).unwrap_or_else(|| "library".to_string())
+ self.r#type
+ .clone()
+ .filter(|s| !s.is_empty())
+ .unwrap_or_else(|| "library".to_string())
}
pub fn get_stability(&self) -> &str {
diff --git a/crates/shirabe/src/package/root_package.rs b/crates/shirabe/src/package/root_package.rs
index f1c3ba8..55a6805 100644
--- a/crates/shirabe/src/package/root_package.rs
+++ b/crates/shirabe/src/package/root_package.rs
@@ -1,9 +1,9 @@
//! ref: composer/src/Composer/Package/RootPackage.php
-use indexmap::IndexMap;
-use shirabe_php_shim::PhpMixed;
use crate::package::complete_package::CompletePackage;
use crate::package::root_package_interface::RootPackageInterface;
+use indexmap::IndexMap;
+use shirabe_php_shim::PhpMixed;
#[derive(Debug)]
pub struct RootPackage {
diff --git a/crates/shirabe/src/package/version/mod.rs b/crates/shirabe/src/package/version/mod.rs
new file mode 100644
index 0000000..a734e23
--- /dev/null
+++ b/crates/shirabe/src/package/version/mod.rs
@@ -0,0 +1,5 @@
+pub mod stability_filter;
+pub mod version_bumper;
+pub mod version_guesser;
+pub mod version_parser;
+pub mod version_selector;
diff --git a/crates/shirabe/src/package/version/stability_filter.rs b/crates/shirabe/src/package/version/stability_filter.rs
index 65f024f..d08492c 100644
--- a/crates/shirabe/src/package/version/stability_filter.rs
+++ b/crates/shirabe/src/package/version/stability_filter.rs
@@ -1,7 +1,7 @@
//! ref: composer/src/Composer/Package/Version/StabilityFilter.php
-use indexmap::IndexMap;
use crate::package::base_package::BasePackage;
+use indexmap::IndexMap;
pub struct StabilityFilter;
diff --git a/crates/shirabe/src/package/version/version_bumper.rs b/crates/shirabe/src/package/version/version_bumper.rs
index 8717d19..5911458 100644
--- a/crates/shirabe/src/package/version/version_bumper.rs
+++ b/crates/shirabe/src/package/version/version_bumper.rs
@@ -1,15 +1,15 @@
//! ref: composer/src/Composer/Package/Version/VersionBumper.php
-use anyhow::Result;
-use indexmap::IndexMap;
-use shirabe_external_packages::composer::pcre::preg::Preg;
-use shirabe_semver::constraint::constraint_interface::ConstraintInterface;
-use shirabe_semver::intervals::Intervals;
use crate::package::dumper::array_dumper::ArrayDumper;
use crate::package::loader::array_loader::ArrayLoader;
use crate::package::package_interface::PackageInterface;
use crate::package::version::version_parser::VersionParser;
use crate::util::platform::Platform;
+use anyhow::Result;
+use indexmap::IndexMap;
+use shirabe_external_packages::composer::pcre::preg::Preg;
+use shirabe_semver::constraint::constraint_interface::ConstraintInterface;
+use shirabe_semver::intervals::Intervals;
#[derive(Debug)]
pub struct VersionBumper;
@@ -46,7 +46,8 @@ impl VersionBumper {
}
let major = Preg::replace(r"{^([1-9][0-9]*|0\.\d+).*}", "$1", version.clone())?;
- let version_without_suffix = Preg::replace(r"{(?:\.(?:0|9999999))+(-dev)?$}", "", version.clone())?;
+ let version_without_suffix =
+ Preg::replace(r"{(?:\.(?:0|9999999))+(-dev)?$}", "", version.clone())?;
let new_pretty_constraint = format!("^{}", version_without_suffix);
if !Preg::is_match(r"{^\^\d+(\.\d+)*$}", &new_pretty_constraint)? {
@@ -82,23 +83,27 @@ impl VersionBumper {
} else {
""
};
- let replacement = if match_str.starts_with('~') && match_str.matches('.').count() != 1 {
- let mut version_bits: Vec<String> =
- version_without_suffix.split('.').map(String::from).collect();
- let needed_len = match_str.matches('.').count() + 1;
- while version_bits.len() < needed_len {
- version_bits.push("0".to_string());
- }
- let dots_in_match = match_str.matches('.').count();
- format!("~{}", version_bits[..dots_in_match + 1].join("."))
- } else if match_str == "*" || match_str.starts_with(">=") {
- format!(">={}{}", version_without_suffix, suffix)
- } else {
- format!("{}{}", new_pretty_constraint, suffix)
- };
+ let replacement =
+ if match_str.starts_with('~') && match_str.matches('.').count() != 1 {
+ let mut version_bits: Vec<String> = version_without_suffix
+ .split('.')
+ .map(String::from)
+ .collect();
+ let needed_len = match_str.matches('.').count() + 1;
+ while version_bits.len() < needed_len {
+ version_bits.push("0".to_string());
+ }
+ let dots_in_match = match_str.matches('.').count();
+ format!("~{}", version_bits[..dots_in_match + 1].join("."))
+ } else if match_str == "*" || match_str.starts_with(">=") {
+ format!(">={}{}", version_without_suffix, suffix)
+ } else {
+ format!("{}{}", new_pretty_constraint, suffix)
+ };
let offset = match_offset as usize;
let length = Platform::strlen(match_str) as usize;
- modified = shirabe_php_shim::substr_replace(&modified, &replacement, offset, length);
+ modified =
+ shirabe_php_shim::substr_replace(&modified, &replacement, offset, length);
}
let new_constraint = parser.parse_constraints(&modified)?;
diff --git a/crates/shirabe/src/package/version/version_guesser.rs b/crates/shirabe/src/package/version/version_guesser.rs
index a97095d..c4e25e0 100644
--- a/crates/shirabe/src/package/version/version_guesser.rs
+++ b/crates/shirabe/src/package/version/version_guesser.rs
@@ -5,9 +5,9 @@ use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::symfony::component::process::process::Process;
use shirabe_php_shim::{
- array_keys, array_map, array_merge, empty, function_exists, implode, is_string, json_encode,
- preg_quote, str_replace, strlen, strnatcasecmp, strpos, substr, trim, usort, PhpMixed,
- RuntimeException, PHP_INT_MAX,
+ PHP_INT_MAX, PhpMixed, RuntimeException, array_keys, array_map, array_merge, empty,
+ function_exists, implode, is_string, json_encode, preg_quote, str_replace, strlen,
+ strnatcasecmp, strpos, substr, trim, usort,
};
use shirabe_semver::version_parser::VersionParser as SemverVersionParser;
@@ -144,7 +144,12 @@ impl VersionGuesser {
.map(|fv| !fv.is_empty())
.unwrap_or(false);
if feature_non_empty
- && "-dev" == substr(version_data.feature_version.as_deref().unwrap_or(""), -4, None)
+ && "-dev"
+ == substr(
+ version_data.feature_version.as_deref().unwrap_or(""),
+ -4,
+ None,
+ )
&& Preg::is_match(
r"{\.9{7}}",
version_data.feature_version.as_deref().unwrap_or(""),
@@ -296,7 +301,11 @@ impl VersionGuesser {
&GitUtil::parse_rev_list_output(&command_output, &self.process),
None,
);
- commit = if parsed.is_empty() { None } else { Some(parsed) };
+ commit = if parsed.is_empty() {
+ None
+ } else {
+ Some(parsed)
+ };
}
}
@@ -386,10 +395,8 @@ impl VersionGuesser {
// TODO(phase-b): clone ProcessExecutor
todo!("self.process.clone()"),
);
- let branches: Vec<String> = array_map(
- |k: &String| k.clone(),
- &array_keys(driver.get_branches()),
- );
+ let branches: Vec<String> =
+ array_map(|k: &String| k.clone(), &array_keys(driver.get_branches()));
// try to find the best (nearest) version branch to assume this feature's version
let mut result = self.guess_feature_version(
@@ -597,11 +604,7 @@ impl VersionGuesser {
// try to fetch current version from fossil tags
let mut output = String::new();
if 0 == self.process.execute(
- &[
- "fossil".to_string(),
- "tag".to_string(),
- "list".to_string(),
- ],
+ &["fossil".to_string(), "tag".to_string(), "list".to_string()],
&mut output,
Some(path.to_string()),
) {
@@ -637,11 +640,7 @@ impl VersionGuesser {
// try to fetch current version from svn
let mut output = String::new();
if 0 == self.process.execute(
- &[
- "svn".to_string(),
- "info".to_string(),
- "--xml".to_string(),
- ],
+ &["svn".to_string(), "info".to_string(), "--xml".to_string()],
&mut output,
Some(path.to_string()),
) {
@@ -670,7 +669,8 @@ impl VersionGuesser {
let m1 = matches.get(1).cloned().unwrap_or_default();
let m2 = matches.get(2).cloned();
let m3 = matches.get(3).cloned();
- if m2.is_some() && m3.is_some()
+ if m2.is_some()
+ && m3.is_some()
&& (branches_path == *m2.as_ref().unwrap()
|| tags_path == *m2.as_ref().unwrap())
{
diff --git a/crates/shirabe/src/package/version/version_parser.rs b/crates/shirabe/src/package/version/version_parser.rs
index dbaa1c9..6bb1004 100644
--- a/crates/shirabe/src/package/version/version_parser.rs
+++ b/crates/shirabe/src/package/version/version_parser.rs
@@ -21,7 +21,10 @@ pub struct VersionParser {
impl VersionParser {
pub const DEFAULT_BRANCH_ALIAS: &'static str = "9999999-dev";
- pub fn parse_constraints(&self, constraints: &str) -> anyhow::Result<Arc<dyn ConstraintInterface + Send + Sync>> {
+ pub fn parse_constraints(
+ &self,
+ constraints: &str,
+ ) -> anyhow::Result<Arc<dyn ConstraintInterface + Send + Sync>> {
let mut cache = CONSTRAINTS.lock().unwrap();
if !cache.contains_key(constraints) {
let parsed = self.inner.parse_constraints(constraints)?;
@@ -30,13 +33,20 @@ impl VersionParser {
Ok(Arc::clone(cache.get(constraints).unwrap()))
}
- pub fn parse_name_version_pairs(&self, pairs: Vec<String>) -> anyhow::Result<Vec<IndexMap<String, String>>> {
+ pub fn parse_name_version_pairs(
+ &self,
+ pairs: Vec<String>,
+ ) -> anyhow::Result<Vec<IndexMap<String, String>>> {
let pairs: Vec<String> = pairs;
let mut result: Vec<IndexMap<String, String>> = Vec::new();
let count = pairs.len();
let mut i = 0_usize;
while i < count {
- let mut pair = Preg::replace(r"{^([^=: ]+)[=: ](.*)$}", "$1 $2", pairs[i].trim().to_string())?;
+ let mut pair = Preg::replace(
+ r"{^([^=: ]+)[=: ](.*)$}",
+ "$1 $2",
+ pairs[i].trim().to_string(),
+ )?;
if !pair.contains(' ')
&& i + 1 < count
&& !pairs[i + 1].contains('/')
diff --git a/crates/shirabe/src/package/version/version_selector.rs b/crates/shirabe/src/package/version/version_selector.rs
index 85ce71d..f665320 100644
--- a/crates/shirabe/src/package/version/version_selector.rs
+++ b/crates/shirabe/src/package/version/version_selector.rs
@@ -5,7 +5,7 @@ use std::any::Any;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- strtolower, version_compare, PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION,
+ PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION, strtolower, version_compare,
};
use shirabe_semver::constraint::constraint::Constraint;
use shirabe_semver::constraint::constraint_interface::ConstraintInterface;
@@ -20,9 +20,9 @@ use crate::package::base_package::BasePackage;
use crate::package::dumper::array_dumper::ArrayDumper;
use crate::package::loader::array_loader::ArrayLoader;
use crate::package::package_interface::PackageInterface;
+use crate::package::version::version_parser::VersionParser;
use crate::repository::platform_repository::PlatformRepository;
use crate::repository::repository_set::RepositorySet;
-use crate::package::version::version_parser::VersionParser;
#[derive(Debug)]
pub struct VersionSelector {
@@ -140,7 +140,8 @@ impl VersionSelector {
if link.get_constraint().matches(provided_constraint.as_ref()) {
continue 'reqs;
}
- let list_filter_opt = (platform_requirement_filter.as_ref() as &dyn Any)
+ let list_filter_opt = (platform_requirement_filter.as_ref()
+ as &dyn Any)
.downcast_ref::<IgnoreListPlatformRequirementFilter>();
if let Some(list_filter) = list_filter_opt {
if list_filter.is_upper_bound_ignored(name) {
@@ -168,8 +169,7 @@ impl VersionSelector {
_ => true,
};
if should_warn {
- let warn_key =
- format!("{}/{}", pkg.get_name(), link.get_target());
+ let warn_key = format!("{}/{}", pkg.get_name(), link.get_target());
let is_first_warning = !already_warned_names.contains_key(&warn_key);
already_warned_names.insert(warn_key, true);
let latest = if is_latest_version {
@@ -222,15 +222,16 @@ impl VersionSelector {
Some(p) => p,
};
- let package = if let Some(alias) = (package.as_ref() as &dyn Any).downcast_ref::<AliasPackage>() {
- if alias.get_version() == VersionParser::DEFAULT_BRANCH_ALIAS {
- alias.get_alias_of()
+ let package =
+ if let Some(alias) = (package.as_ref() as &dyn Any).downcast_ref::<AliasPackage>() {
+ if alias.get_version() == VersionParser::DEFAULT_BRANCH_ALIAS {
+ alias.get_alias_of()
+ } else {
+ package
+ }
} else {
package
- }
- } else {
- package
- };
+ };
Ok(Some(package))
}
@@ -288,7 +289,10 @@ impl VersionSelector {
if semantic_version_parts.len() == 4
&& Preg::is_match(r"{^\d+\D?}", semantic_version_parts[3]).unwrap_or(false)
{
- let mut parts: Vec<String> = semantic_version_parts.iter().map(|s| s.to_string()).collect();
+ let mut parts: Vec<String> = semantic_version_parts
+ .iter()
+ .map(|s| s.to_string())
+ .collect();
let version = if parts[0] == "0" {
parts.truncate(3);
parts.join(".")
diff --git a/crates/shirabe/src/phpstan/mod.rs b/crates/shirabe/src/phpstan/mod.rs
new file mode 100644
index 0000000..5c48ac7
--- /dev/null
+++ b/crates/shirabe/src/phpstan/mod.rs
@@ -0,0 +1,2 @@
+pub mod config_return_type_extension;
+pub mod rule_reason_data_return_type_extension;
diff --git a/crates/shirabe/src/platform/hhvm_detector.rs b/crates/shirabe/src/platform/hhvm_detector.rs
index 634b724..c6a53cb 100644
--- a/crates/shirabe/src/platform/hhvm_detector.rs
+++ b/crates/shirabe/src/platform/hhvm_detector.rs
@@ -1,10 +1,10 @@
//! ref: composer/src/Composer/Platform/HhvmDetector.php
-use std::sync::Mutex;
-use shirabe_external_packages::symfony::process::executable_finder::ExecutableFinder;
-use shirabe_php_shim::{defined, HHVM_VERSION};
use crate::util::platform::Platform;
use crate::util::process_executor::ProcessExecutor;
+use shirabe_external_packages::symfony::process::executable_finder::ExecutableFinder;
+use shirabe_php_shim::{HHVM_VERSION, defined};
+use std::sync::Mutex;
// None = null (uninitialized), Some(None) = false (not found), Some(Some(v)) = version
static HHVM_VERSION_CACHE: Mutex<Option<Option<String>>> = Mutex::new(None);
@@ -15,7 +15,10 @@ pub struct HhvmDetector {
}
impl HhvmDetector {
- pub fn new(executable_finder: Option<ExecutableFinder>, process_executor: Option<ProcessExecutor>) -> Self {
+ pub fn new(
+ executable_finder: Option<ExecutableFinder>,
+ process_executor: Option<ProcessExecutor>,
+ ) -> Self {
Self {
executable_finder,
process_executor,
@@ -41,13 +44,24 @@ impl HhvmDetector {
if cache.as_ref().unwrap().is_none() && !Platform::is_windows() {
*cache = Some(None);
- let finder = self.executable_finder.get_or_insert_with(ExecutableFinder::new);
+ let finder = self
+ .executable_finder
+ .get_or_insert_with(ExecutableFinder::new);
let hhvm_path = finder.find("hhvm");
if let Some(hhvm_path) = hhvm_path {
- let executor = self.process_executor.get_or_insert_with(ProcessExecutor::new);
+ let executor = self
+ .process_executor
+ .get_or_insert_with(ProcessExecutor::new);
let mut version_output = String::new();
let exit_code = executor.execute(
- &[&hhvm_path, "--php", "-d", "hhvm.jit=0", "-r", "echo HHVM_VERSION;"],
+ &[
+ &hhvm_path,
+ "--php",
+ "-d",
+ "hhvm.jit=0",
+ "-r",
+ "echo HHVM_VERSION;",
+ ],
&mut version_output,
);
if exit_code == 0 {
diff --git a/crates/shirabe/src/platform/mod.rs b/crates/shirabe/src/platform/mod.rs
new file mode 100644
index 0000000..35916e5
--- /dev/null
+++ b/crates/shirabe/src/platform/mod.rs
@@ -0,0 +1,3 @@
+pub mod hhvm_detector;
+pub mod runtime;
+pub mod version;
diff --git a/crates/shirabe/src/platform/runtime.rs b/crates/shirabe/src/platform/runtime.rs
index 4c9c3f5..2e04453 100644
--- a/crates/shirabe/src/platform/runtime.rs
+++ b/crates/shirabe/src/platform/runtime.rs
@@ -19,7 +19,11 @@ impl Runtime {
todo!()
}
- pub fn invoke(&self, callable: Box<dyn Fn(Vec<PhpMixed>) -> PhpMixed>, arguments: Vec<PhpMixed>) -> PhpMixed {
+ pub fn invoke(
+ &self,
+ callable: Box<dyn Fn(Vec<PhpMixed>) -> PhpMixed>,
+ arguments: Vec<PhpMixed>,
+ ) -> PhpMixed {
todo!()
}
diff --git a/crates/shirabe/src/platform/version.rs b/crates/shirabe/src/platform/version.rs
index 5c64098..a9566ee 100644
--- a/crates/shirabe/src/platform/version.rs
+++ b/crates/shirabe/src/platform/version.rs
@@ -15,7 +15,10 @@ impl Version {
)?;
let patch = if version_compare(&matches["version"], "3.0.0", "<") {
- format!(".{}", Self::convert_alpha_version_to_int_version(&matches["patch"]))
+ format!(
+ ".{}",
+ Self::convert_alpha_version_to_int_version(&matches["patch"])
+ )
} else {
String::new()
};
@@ -25,25 +28,33 @@ impl Version {
.replace("-fips", "")
.replace("-pre", "-alpha");
- Some(format!("{}{}{}", matches["version"], patch, suffix).trim_end_matches('-').to_string())
+ Some(
+ format!("{}{}{}", matches["version"], patch, suffix)
+ .trim_end_matches('-')
+ .to_string(),
+ )
}
pub fn parse_libjpeg(libjpeg_version: &str) -> Option<String> {
- let matches = Preg::match_strict_groups(
- r"^(?P<major>\d+)(?P<minor>[a-z]*)$",
- libjpeg_version,
- )?;
+ let matches =
+ Preg::match_strict_groups(r"^(?P<major>\d+)(?P<minor>[a-z]*)$", libjpeg_version)?;
- Some(format!("{}.{}", matches["major"], Self::convert_alpha_version_to_int_version(&matches["minor"])))
+ Some(format!(
+ "{}.{}",
+ matches["major"],
+ Self::convert_alpha_version_to_int_version(&matches["minor"])
+ ))
}
pub fn parse_zoneinfo_version(zoneinfo_version: &str) -> Option<String> {
- let matches = Preg::match_strict_groups(
- r"^(?P<year>\d{4})(?P<revision>[a-z]*)$",
- zoneinfo_version,
- )?;
+ let matches =
+ Preg::match_strict_groups(r"^(?P<year>\d{4})(?P<revision>[a-z]*)$", zoneinfo_version)?;
- Some(format!("{}.{}", matches["year"], Self::convert_alpha_version_to_int_version(&matches["revision"])))
+ Some(format!(
+ "{}.{}",
+ matches["year"],
+ Self::convert_alpha_version_to_int_version(&matches["revision"])
+ ))
}
fn convert_alpha_version_to_int_version(alpha: &str) -> i64 {
diff --git a/crates/shirabe/src/plugin/capability/mod.rs b/crates/shirabe/src/plugin/capability/mod.rs
new file mode 100644
index 0000000..c4a6f8b
--- /dev/null
+++ b/crates/shirabe/src/plugin/capability/mod.rs
@@ -0,0 +1,2 @@
+pub mod capability;
+pub mod command_provider;
diff --git a/crates/shirabe/src/plugin/command_event.rs b/crates/shirabe/src/plugin/command_event.rs
index 0eb952a..aa5b366 100644
--- a/crates/shirabe/src/plugin/command_event.rs
+++ b/crates/shirabe/src/plugin/command_event.rs
@@ -1,8 +1,8 @@
//! ref: composer/src/Composer/Plugin/CommandEvent.php
+use crate::event_dispatcher::event::Event;
use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
-use crate::event_dispatcher::event::Event;
use shirabe_php_shim::PhpMixed;
#[derive(Debug)]
@@ -23,7 +23,12 @@ impl CommandEvent {
flags: Vec<PhpMixed>,
) -> Self {
let inner = Event::new(name, args, flags);
- Self { inner, command_name, input, output }
+ Self {
+ inner,
+ command_name,
+ input,
+ output,
+ }
}
pub fn get_input(&self) -> &dyn InputInterface {
diff --git a/crates/shirabe/src/plugin/mod.rs b/crates/shirabe/src/plugin/mod.rs
new file mode 100644
index 0000000..7ff98f3
--- /dev/null
+++ b/crates/shirabe/src/plugin/mod.rs
@@ -0,0 +1,11 @@
+pub mod capability;
+pub mod capable;
+pub mod command_event;
+pub mod plugin_blocked_exception;
+pub mod plugin_events;
+pub mod plugin_interface;
+pub mod plugin_manager;
+pub mod post_file_download_event;
+pub mod pre_command_run_event;
+pub mod pre_file_download_event;
+pub mod pre_pool_create_event;
diff --git a/crates/shirabe/src/plugin/plugin_manager.rs b/crates/shirabe/src/plugin/plugin_manager.rs
index ee1aff5..430b0a4 100644
--- a/crates/shirabe/src/plugin/plugin_manager.rs
+++ b/crates/shirabe/src/plugin/plugin_manager.rs
@@ -8,10 +8,10 @@ use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- array_key_exists, array_reverse, array_search, clone, get_class, implode, in_array, is_a,
- is_array, is_string, ksort, preg_quote, str_replace, strrpos, strtr, substr, trigger_error,
- trim, var_export, version_compare, E_USER_DEPRECATED, PhpMixed, RuntimeException,
- UnexpectedValueException,
+ E_USER_DEPRECATED, PhpMixed, RuntimeException, UnexpectedValueException, array_key_exists,
+ array_reverse, array_search, clone, get_class, implode, in_array, is_a, is_array, is_string,
+ ksort, preg_quote, str_replace, strrpos, strtr, substr, trigger_error, trim, var_export,
+ version_compare,
};
use shirabe_semver::constraint::constraint::Constraint;
@@ -108,12 +108,20 @@ impl PluginManager {
pub fn load_installed_plugins(&mut self) -> anyhow::Result<()> {
// TODO(plugin): plugin loading is part of the plugin API
if !self.are_plugins_disabled("local") {
- let repo = self.composer.get_repository_manager().get_local_repository();
+ let repo = self
+ .composer
+ .get_repository_manager()
+ .get_local_repository();
self.load_repository(&*repo, false, Some(self.composer.get_package()))?;
}
if self.global_composer.is_some() && !self.are_plugins_disabled("global") {
- let repo = self.global_composer.as_ref().unwrap().get_repository_manager().get_local_repository();
+ let repo = self
+ .global_composer
+ .as_ref()
+ .unwrap()
+ .get_repository_manager()
+ .get_local_repository();
self.load_repository(&*repo, true, None)?;
}
Ok(())
@@ -123,12 +131,20 @@ impl PluginManager {
pub fn deactivate_installed_plugins(&mut self) {
// TODO(plugin): deactivation is part of the plugin API
if !self.are_plugins_disabled("local") {
- let repo = self.composer.get_repository_manager().get_local_repository();
+ let repo = self
+ .composer
+ .get_repository_manager()
+ .get_local_repository();
self.deactivate_repository(&*repo, false);
}
if self.global_composer.is_some() && !self.are_plugins_disabled("global") {
- let repo = self.global_composer.as_ref().unwrap().get_repository_manager().get_local_repository();
+ let repo = self
+ .global_composer
+ .as_ref()
+ .unwrap()
+ .get_repository_manager()
+ .get_local_repository();
self.deactivate_repository(&*repo, true);
}
}
@@ -151,16 +167,26 @@ impl PluginManager {
}
/// Register a plugin package, activate it etc.
- pub fn register_package(&mut self, package: &dyn PackageInterface, fail_on_missing_classes: bool, is_global_plugin: bool) -> anyhow::Result<()> {
+ pub fn register_package(
+ &mut self,
+ package: &dyn PackageInterface,
+ fail_on_missing_classes: bool,
+ is_global_plugin: bool,
+ ) -> anyhow::Result<()> {
// TODO(plugin): registerPackage drives the actual plugin loading via eval()
if self.are_plugins_disabled(if is_global_plugin { "global" } else { "local" }) {
- self.io.write_error(&format!("<warning>The \"{}\" plugin was not loaded as plugins are disabled.</warning>", package.get_name()));
+ self.io.write_error(&format!(
+ "<warning>The \"{}\" plugin was not loaded as plugins are disabled.</warning>",
+ package.get_name()
+ ));
return Ok(());
}
if package.get_type() == "composer-plugin" {
- let mut requires_composer: Option<Box<dyn shirabe_semver::constraint::constraint_interface::ConstraintInterface>> = None;
+ let mut requires_composer: Option<
+ Box<dyn shirabe_semver::constraint::constraint_interface::ConstraintInterface>,
+ > = None;
for (_k, link) in &package.get_requires() {
if "composer-plugin-api" == link.get_target() {
requires_composer = Some(link.get_constraint());
@@ -179,7 +205,11 @@ impl PluginManager {
};
let current_plugin_api_version = self.get_plugin_api_version();
- let current_plugin_api_constraint = Constraint::new("==", self.version_parser.normalize(&current_plugin_api_version, None)?);
+ let current_plugin_api_constraint = Constraint::new(
+ "==",
+ self.version_parser
+ .normalize(&current_plugin_api_version, None)?,
+ );
if requires_composer.get_pretty_string() == self.get_plugin_api_version() {
self.io.write_error(&format!("<warning>The \"{}\" plugin requires composer-plugin-api {}, this *WILL* break in the future and it should be fixed ASAP (require ^{} instead for example).</warning>", package.get_name(), self.get_plugin_api_version(), self.get_plugin_api_version()));
@@ -205,11 +235,20 @@ impl PluginManager {
}
}
- let plugin_optional = package.get_extra().get("plugin-optional").map(|v| v.as_bool() == Some(true)).unwrap_or(false);
+ let plugin_optional = package
+ .get_extra()
+ .get("plugin-optional")
+ .map(|v| v.as_bool() == Some(true))
+ .unwrap_or(false);
if !self.is_plugin_allowed(package.get_name(), is_global_plugin, plugin_optional, true)? {
- self.io.write_error(&format!("Skipped loading \"{}\" {}as it is not in config.allow-plugins",
+ self.io.write_error(&format!(
+ "Skipped loading \"{}\" {}as it is not in config.allow-plugins",
package.get_name(),
- if is_global_plugin || self.running_in_global_dir { "(installed globally) " } else { "" }
+ if is_global_plugin || self.running_in_global_dir {
+ "(installed globally) "
+ } else {
+ ""
+ }
));
return Ok(());
}
@@ -232,9 +271,16 @@ impl PluginManager {
}.into());
}
let _classes: Vec<String> = if let Some(arr) = class_value.and_then(|v| v.as_list()) {
- arr.iter().filter_map(|v| v.as_string().map(|s| s.to_string())).collect()
+ arr.iter()
+ .filter_map(|v| v.as_string().map(|s| s.to_string()))
+ .collect()
} else {
- vec![class_value.and_then(|v| v.as_string()).unwrap_or("").to_string()]
+ vec![
+ class_value
+ .and_then(|v| v.as_string())
+ .unwrap_or("")
+ .to_string(),
+ ]
};
// TODO(plugin): everything below this point in the original PHP would create runtime instances:
@@ -255,11 +301,16 @@ impl PluginManager {
return;
}
- let plugins = self.registered_plugins.shift_remove(package.get_name()).unwrap_or_default();
+ let plugins = self
+ .registered_plugins
+ .shift_remove(package.get_name())
+ .unwrap_or_default();
for plugin in plugins {
match plugin {
PluginOrInstaller::Installer(inst) => {
- self.composer.get_installation_manager().remove_installer(&*inst);
+ self.composer
+ .get_installation_manager()
+ .remove_installer(&*inst);
}
PluginOrInstaller::Plugin(p) => {
self.remove_plugin(&*p);
@@ -275,11 +326,16 @@ impl PluginManager {
return;
}
- let plugins = self.registered_plugins.shift_remove(package.get_name()).unwrap_or_default();
+ let plugins = self
+ .registered_plugins
+ .shift_remove(package.get_name())
+ .unwrap_or_default();
for plugin in plugins {
match plugin {
PluginOrInstaller::Installer(inst) => {
- self.composer.get_installation_manager().remove_installer(&*inst);
+ self.composer
+ .get_installation_manager()
+ .remove_installer(&*inst);
}
PluginOrInstaller::Plugin(p) => {
self.remove_plugin(&*p);
@@ -295,22 +351,39 @@ impl PluginManager {
}
/// Adds a plugin, activates it and registers it with the event dispatcher
- pub fn add_plugin(&mut self, plugin: Box<dyn PluginInterface>, is_global_plugin: bool, source_package: Option<&dyn PackageInterface>) -> anyhow::Result<()> {
+ pub fn add_plugin(
+ &mut self,
+ plugin: Box<dyn PluginInterface>,
+ is_global_plugin: bool,
+ source_package: Option<&dyn PackageInterface>,
+ ) -> anyhow::Result<()> {
// TODO(plugin): plugin activation
if self.are_plugins_disabled(if is_global_plugin { "global" } else { "local" }) {
return Ok(());
}
if source_package.is_none() {
- trigger_error("Calling PluginManager::addPlugin without $sourcePackage is deprecated, if you are using this please get in touch with us to explain the use case", E_USER_DEPRECATED);
+ trigger_error(
+ "Calling PluginManager::addPlugin without $sourcePackage is deprecated, if you are using this please get in touch with us to explain the use case",
+ E_USER_DEPRECATED,
+ );
} else {
let sp = source_package.unwrap();
- let plugin_optional = sp.get_extra().get("plugin-optional").map(|v| v.as_bool() == Some(true)).unwrap_or(false);
+ let plugin_optional = sp
+ .get_extra()
+ .get("plugin-optional")
+ .map(|v| v.as_bool() == Some(true))
+ .unwrap_or(false);
if !self.is_plugin_allowed(sp.get_name(), is_global_plugin, plugin_optional, true)? {
- self.io.write_error(&format!("Skipped loading \"{} from {}\" {} as it is not in config.allow-plugins",
+ self.io.write_error(&format!(
+ "Skipped loading \"{} from {}\" {} as it is not in config.allow-plugins",
get_class(&*plugin),
sp.get_name(),
- if is_global_plugin || self.running_in_global_dir { "(installed globally) " } else { "" }
+ if is_global_plugin || self.running_in_global_dir {
+ "(installed globally) "
+ } else {
+ ""
+ }
));
return Ok(());
}
@@ -323,9 +396,14 @@ impl PluginManager {
if is_global_plugin || self.running_in_global_dir {
details.push("installed globally".to_string());
}
- self.io.write_error(&format!("Loading plugin {}{}",
+ self.io.write_error(&format!(
+ "Loading plugin {}{}",
get_class(&*plugin),
- if !details.is_empty() { format!(" ({})", implode(", ", &details)) } else { String::new() }
+ if !details.is_empty() {
+ format!(" ({})", implode(", ", &details))
+ } else {
+ String::new()
+ }
));
plugin.activate(&self.composer, &*self.io);
@@ -347,7 +425,8 @@ impl PluginManager {
None => return,
};
- self.io.write_error(&format!("Unloading plugin {}", get_class(plugin)));
+ self.io
+ .write_error(&format!("Unloading plugin {}", get_class(plugin)));
self.plugins.remove(index as usize);
plugin.deactivate(&self.composer, &*self.io);
@@ -357,11 +436,17 @@ impl PluginManager {
/// Notifies a plugin it is being uninstalled and should clean up
pub fn uninstall_plugin(&self, plugin: &dyn PluginInterface) {
// TODO(plugin): plugin uninstall hook
- self.io.write_error(&format!("Uninstalling plugin {}", get_class(plugin)));
+ self.io
+ .write_error(&format!("Uninstalling plugin {}", get_class(plugin)));
plugin.uninstall(&self.composer, &*self.io);
}
- fn load_repository(&mut self, repo: &dyn RepositoryInterface, is_global_repo: bool, root_package: Option<&dyn RootPackageInterface>) -> anyhow::Result<()> {
+ fn load_repository(
+ &mut self,
+ repo: &dyn RepositoryInterface,
+ is_global_repo: bool,
+ root_package: Option<&dyn RootPackageInterface>,
+ ) -> anyhow::Result<()> {
// TODO(plugin): repository scan for plugin packages
let packages = repo.get_packages();
@@ -370,19 +455,27 @@ impl PluginManager {
if package.get_type() == "composer-plugin" {
let extra = package.get_extra();
if package.get_name() == "composer/installers"
- || extra.get("plugin-modifies-install-path").map(|v| v.as_bool() == Some(true)).unwrap_or(false)
+ || extra
+ .get("plugin-modifies-install-path")
+ .map(|v| v.as_bool() == Some(true))
+ .unwrap_or(false)
{
weights.insert(package.get_name().to_string(), -10000);
}
}
}
- let sorted_packages = PackageSorter::sort_packages(packages.iter().map(|p| p.clone_box()).collect(), weights);
+ let sorted_packages =
+ PackageSorter::sort_packages(packages.iter().map(|p| p.clone_box()).collect(), weights);
let required_packages: Vec<Box<dyn PackageInterface>> = if !is_global_repo {
- RepositoryUtils::filter_required_packages(packages.iter().map(|p| p.as_ref()).collect(), root_package.unwrap(), true)
- .iter()
- .map(|p| p.clone_box())
- .collect()
+ RepositoryUtils::filter_required_packages(
+ packages.iter().map(|p| p.as_ref()).collect(),
+ root_package.unwrap(),
+ true,
+ )
+ .iter()
+ .map(|p| p.clone_box())
+ .collect()
} else {
vec![]
};
@@ -393,12 +486,23 @@ impl PluginManager {
None => continue,
};
- if !in_array(package.get_type(), &vec!["composer-plugin".to_string(), "composer-installer".to_string()], true) {
+ if !in_array(
+ package.get_type(),
+ &vec![
+ "composer-plugin".to_string(),
+ "composer-installer".to_string(),
+ ],
+ true,
+ ) {
continue;
}
if !is_global_repo
- && !in_array(&**package as &dyn PackageInterface, &required_packages.iter().map(|p| &**p).collect::<Vec<_>>(), true)
+ && !in_array(
+ &**package as &dyn PackageInterface,
+ &required_packages.iter().map(|p| &**p).collect::<Vec<_>>(),
+ true,
+ )
&& !self.is_plugin_allowed(package.get_name(), false, true, false)?
{
self.io.write_error(&format!("<warning>The \"{}\" plugin was not loaded as it is not listed in allow-plugins and is not required by the root package anymore.</warning>", package.get_name()));
@@ -419,7 +523,10 @@ impl PluginManager {
fn deactivate_repository(&mut self, repo: &dyn RepositoryInterface, _is_global_repo: bool) {
// TODO(plugin): deactivate plugins from a repository
let packages = repo.get_packages();
- let sorted_packages = array_reverse(PackageSorter::sort_packages(packages.iter().map(|p| p.clone_box()).collect(), IndexMap::new()));
+ let sorted_packages = array_reverse(PackageSorter::sort_packages(
+ packages.iter().map(|p| p.clone_box()).collect(),
+ IndexMap::new(),
+ ));
for package in &sorted_packages {
if package.as_complete_package().is_none() {
@@ -434,13 +541,24 @@ impl PluginManager {
}
}
- fn collect_dependencies(&self, installed_repo: &InstalledRepository, mut collected: IndexMap<String, Box<dyn PackageInterface>>, package: &dyn PackageInterface) -> IndexMap<String, Box<dyn PackageInterface>> {
+ fn collect_dependencies(
+ &self,
+ installed_repo: &InstalledRepository,
+ mut collected: IndexMap<String, Box<dyn PackageInterface>>,
+ package: &dyn PackageInterface,
+ ) -> IndexMap<String, Box<dyn PackageInterface>> {
// TODO(plugin): used by registerPackage to assemble plugin dependency autoload map
for (_k, require_link) in &package.get_requires() {
- for required_package in installed_repo.find_packages_with_replacers_and_providers(require_link.get_target()) {
+ for required_package in
+ installed_repo.find_packages_with_replacers_and_providers(require_link.get_target())
+ {
if !collected.contains_key(required_package.get_name()) {
- collected.insert(required_package.get_name().to_string(), required_package.clone_box());
- collected = self.collect_dependencies(installed_repo, collected, &*required_package);
+ collected.insert(
+ required_package.get_name().to_string(),
+ required_package.clone_box(),
+ );
+ collected =
+ self.collect_dependencies(installed_repo, collected, &*required_package);
}
}
}
@@ -451,14 +569,25 @@ impl PluginManager {
/// Retrieves the path a package is installed to.
fn get_install_path(&self, package: &dyn PackageInterface, global: bool) -> Option<String> {
if !global {
- return self.composer.get_installation_manager().get_install_path(package);
+ return self
+ .composer
+ .get_installation_manager()
+ .get_install_path(package);
}
// PHP: assert(null !== $this->globalComposer);
- self.global_composer.as_ref().unwrap().get_installation_manager().get_install_path(package)
+ self.global_composer
+ .as_ref()
+ .unwrap()
+ .get_installation_manager()
+ .get_install_path(package)
}
- pub(crate) fn get_capability_implementation_class_name(&self, plugin: &dyn PluginInterface, capability: &str) -> anyhow::Result<Option<String>> {
+ pub(crate) fn get_capability_implementation_class_name(
+ &self,
+ plugin: &dyn PluginInterface,
+ capability: &str,
+ ) -> anyhow::Result<Option<String>> {
// TODO(plugin): capability lookup
let capable = match plugin.as_capable() {
Some(c) => c,
@@ -476,37 +605,61 @@ impl PluginManager {
}
if array_key_exists(capability, &capabilities)
- && (capabilities.get(capability).map(|v| v.is_empty()).unwrap_or(true)
+ && (capabilities
+ .get(capability)
+ .map(|v| v.is_empty())
+ .unwrap_or(true)
|| !is_string(capabilities.get(capability).unwrap())
- || trim(capabilities.get(capability).and_then(|v| v.as_string()).unwrap_or(""), " \t\n\r\0\u{0B}").is_empty())
+ || trim(
+ capabilities
+ .get(capability)
+ .and_then(|v| v.as_string())
+ .unwrap_or(""),
+ " \t\n\r\0\u{0B}",
+ )
+ .is_empty())
{
return Err(UnexpectedValueException {
- message: format!("Plugin {} provided invalid capability class name(s), got {}",
+ message: format!(
+ "Plugin {} provided invalid capability class name(s), got {}",
get_class(plugin),
var_export(capabilities.get(capability).unwrap(), true)
),
code: 0,
- }.into());
+ }
+ .into());
}
Ok(None)
}
- pub fn get_plugin_capability(&self, plugin: &dyn PluginInterface, capability_class_name: &str, _ctor_args: IndexMap<String, PhpMixed>) -> anyhow::Result<Option<Box<dyn Capability>>> {
+ pub fn get_plugin_capability(
+ &self,
+ plugin: &dyn PluginInterface,
+ capability_class_name: &str,
+ _ctor_args: IndexMap<String, PhpMixed>,
+ ) -> anyhow::Result<Option<Box<dyn Capability>>> {
// TODO(plugin): instantiate plugin capability via runtime class lookup
- let _capability_class = match self.get_capability_implementation_class_name(plugin, capability_class_name)? {
- Some(c) => c,
- None => return Ok(None),
- };
+ let _capability_class =
+ match self.get_capability_implementation_class_name(plugin, capability_class_name)? {
+ Some(c) => c,
+ None => return Ok(None),
+ };
// PHP: requires class_exists / new $capabilityClass($ctorArgs); cannot be performed in Rust without a runtime registry.
Ok(None)
}
- pub fn get_plugin_capabilities(&self, capability_class_name: &str, ctor_args: IndexMap<String, PhpMixed>) -> Vec<Box<dyn Capability>> {
+ pub fn get_plugin_capabilities(
+ &self,
+ capability_class_name: &str,
+ ctor_args: IndexMap<String, PhpMixed>,
+ ) -> Vec<Box<dyn Capability>> {
// TODO(plugin): aggregate capabilities across all loaded plugins
let mut capabilities: Vec<Box<dyn Capability>> = vec![];
for plugin in &self.get_plugins() {
- if let Ok(Some(capability)) = self.get_plugin_capability(&**plugin, capability_class_name, ctor_args.clone()) {
+ if let Ok(Some(capability)) =
+ self.get_plugin_capability(&**plugin, capability_class_name, ctor_args.clone())
+ {
capabilities.push(capability);
}
}
@@ -514,7 +667,10 @@ impl PluginManager {
capabilities
}
- fn parse_allowed_plugins(allow_plugins_config: PhpMixed, locker: Option<&Locker>) -> Option<IndexMap<String, bool>> {
+ fn parse_allowed_plugins(
+ allow_plugins_config: PhpMixed,
+ locker: Option<&Locker>,
+ ) -> Option<IndexMap<String, bool>> {
// PHP: [] === $allowPluginsConfig && $locker !== null && $locker->isLocked() && version_compare($locker->getPluginApi(), '2.2.0', '<')
let is_empty_array = allow_plugins_config
.as_array()
@@ -543,7 +699,10 @@ impl PluginManager {
let mut rules: IndexMap<String, bool> = IndexMap::new();
if let Some(arr) = allow_plugins_config.as_array() {
for (pattern, allow) in arr {
- rules.insert(BasePackage::package_name_to_regexp(pattern), allow.as_bool().unwrap_or(false));
+ rules.insert(
+ BasePackage::package_name_to_regexp(pattern),
+ allow.as_bool().unwrap_or(false),
+ );
}
}
@@ -563,7 +722,13 @@ impl PluginManager {
self.disable_plugins = DisablePlugins::True;
}
- pub fn is_plugin_allowed(&mut self, package: &str, is_global_plugin: bool, optional: bool, prompt: bool) -> anyhow::Result<bool> {
+ pub fn is_plugin_allowed(
+ &mut self,
+ package: &str,
+ is_global_plugin: bool,
+ optional: bool,
+ prompt: bool,
+ ) -> anyhow::Result<bool> {
// TODO(plugin): allow-plugins authorization flow with interactive prompt
let rules: &mut Option<IndexMap<String, bool>> = if is_global_plugin {
&mut self.allow_global_plugin_rules
@@ -590,7 +755,12 @@ impl PluginManager {
*rules = Some(IndexMap::new());
}
- let rules_snapshot: Vec<(String, bool)> = rules.as_ref().unwrap().iter().map(|(k, v)| (k.clone(), *v)).collect();
+ let rules_snapshot: Vec<(String, bool)> = rules
+ .as_ref()
+ .unwrap()
+ .iter()
+ .map(|(k, v)| (k.clone(), *v))
+ .collect();
for (pattern, allow) in &rules_snapshot {
if Preg::is_match(pattern, package, None).unwrap_or(false) {
return Ok(*allow);
@@ -634,21 +804,40 @@ impl PluginManager {
let allow = answer_str == "y";
// persist answer in current rules to avoid prompting again if the package gets reloaded
- rules.as_mut().unwrap().insert(BasePackage::package_name_to_regexp(package), allow);
+ rules
+ .as_mut()
+ .unwrap()
+ .insert(BasePackage::package_name_to_regexp(package), allow);
// persist answer in composer.json if it wasn't simply discarded
if answer_str == "y" || answer_str == "n" {
- let allow_plugins_value = composer_ref.get_config().get("allow-plugins").clone();
+ let allow_plugins_value =
+ composer_ref.get_config().get("allow-plugins").clone();
if let Some(arr) = allow_plugins_value.as_array() {
let mut allow_plugins = arr.clone();
- allow_plugins.insert(package.to_string(), Box::new(PhpMixed::Bool(allow)));
- if composer_ref.get_config().get("sort-packages").as_bool().unwrap_or(false) {
+ allow_plugins
+ .insert(package.to_string(), Box::new(PhpMixed::Bool(allow)));
+ if composer_ref
+ .get_config()
+ .get("sort-packages")
+ .as_bool()
+ .unwrap_or(false)
+ {
ksort(&mut allow_plugins);
}
- composer_ref.get_config().get_config_source().add_config_setting("allow-plugins", PhpMixed::Array(allow_plugins.clone()));
+ composer_ref
+ .get_config()
+ .get_config_source()
+ .add_config_setting(
+ "allow-plugins",
+ PhpMixed::Array(allow_plugins.clone()),
+ );
let mut wrap: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
let mut inner: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
- inner.insert("allow-plugins".to_string(), Box::new(PhpMixed::Array(allow_plugins)));
+ inner.insert(
+ "allow-plugins".to_string(),
+ Box::new(PhpMixed::Array(allow_plugins)),
+ );
wrap.insert("config".to_string(), Box::new(PhpMixed::Array(inner)));
composer_ref.get_config().merge(PhpMixed::Array(wrap), "");
}
diff --git a/crates/shirabe/src/plugin/pre_command_run_event.rs b/crates/shirabe/src/plugin/pre_command_run_event.rs
index 9b8de26..40672c0 100644
--- a/crates/shirabe/src/plugin/pre_command_run_event.rs
+++ b/crates/shirabe/src/plugin/pre_command_run_event.rs
@@ -1,8 +1,8 @@
//! ref: composer/src/Composer/Plugin/PreCommandRunEvent.php
// TODO(plugin): this event is part of the plugin API and is dispatched before a command runs
-use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
use crate::event_dispatcher::event::Event;
+use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
pub struct PreCommandRunEvent {
inner: Event,
diff --git a/crates/shirabe/src/plugin/pre_pool_create_event.rs b/crates/shirabe/src/plugin/pre_pool_create_event.rs
index 3126119..7363b08 100644
--- a/crates/shirabe/src/plugin/pre_pool_create_event.rs
+++ b/crates/shirabe/src/plugin/pre_pool_create_event.rs
@@ -62,7 +62,9 @@ impl PrePoolCreateEvent {
&self.stability_flags
}
- pub fn get_root_aliases(&self) -> &IndexMap<String, IndexMap<String, IndexMap<String, String>>> {
+ pub fn get_root_aliases(
+ &self,
+ ) -> &IndexMap<String, IndexMap<String, IndexMap<String, String>>> {
&self.root_aliases
}
diff --git a/crates/shirabe/src/question/mod.rs b/crates/shirabe/src/question/mod.rs
new file mode 100644
index 0000000..fe17dc8
--- /dev/null
+++ b/crates/shirabe/src/question/mod.rs
@@ -0,0 +1 @@
+pub mod strict_confirmation_question;
diff --git a/crates/shirabe/src/question/strict_confirmation_question.rs b/crates/shirabe/src/question/strict_confirmation_question.rs
index cfa9c36..eea6629 100644
--- a/crates/shirabe/src/question/strict_confirmation_question.rs
+++ b/crates/shirabe/src/question/strict_confirmation_question.rs
@@ -4,7 +4,7 @@ use anyhow::Result;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::symfony::console::exception::invalid_argument_exception::InvalidArgumentException;
use shirabe_external_packages::symfony::console::question::question::Question;
-use shirabe_php_shim::{empty, is_bool, PhpMixed};
+use shirabe_php_shim::{PhpMixed, empty, is_bool};
pub struct StrictConfirmationQuestion {
inner: Question,
@@ -62,7 +62,8 @@ impl StrictConfirmationQuestion {
return Err(InvalidArgumentException {
message: "Please answer yes, y, no, or n.".to_string(),
code: 0,
- }.into());
+ }
+ .into());
}
Ok(answer.clone())
})
diff --git a/crates/shirabe/src/repository/advisory_provider_interface.rs b/crates/shirabe/src/repository/advisory_provider_interface.rs
index d0aaceb..f9ddeb2 100644
--- a/crates/shirabe/src/repository/advisory_provider_interface.rs
+++ b/crates/shirabe/src/repository/advisory_provider_interface.rs
@@ -1,9 +1,9 @@
//! ref: composer/src/Composer/Repository/AdvisoryProviderInterface.php
-use indexmap::IndexMap;
-use shirabe_semver::constraint::constraint_interface::ConstraintInterface;
use crate::advisory::partial_security_advisory::PartialSecurityAdvisory;
use crate::advisory::security_advisory::SecurityAdvisory;
+use indexmap::IndexMap;
+use shirabe_semver::constraint::constraint_interface::ConstraintInterface;
#[derive(Debug)]
pub enum PartialOrSecurityAdvisory {
@@ -20,5 +20,9 @@ pub struct SecurityAdvisoryResult {
pub trait AdvisoryProviderInterface {
fn has_security_advisories(&self) -> bool;
- fn get_security_advisories(&self, package_constraint_map: IndexMap<String, Box<dyn ConstraintInterface>>, allow_partial_advisories: bool) -> anyhow::Result<SecurityAdvisoryResult>;
+ fn get_security_advisories(
+ &self,
+ package_constraint_map: IndexMap<String, Box<dyn ConstraintInterface>>,
+ allow_partial_advisories: bool,
+ ) -> anyhow::Result<SecurityAdvisoryResult>;
}
diff --git a/crates/shirabe/src/repository/array_repository.rs b/crates/shirabe/src/repository/array_repository.rs
index 5be2a8b..7bb7e81 100644
--- a/crates/shirabe/src/repository/array_repository.rs
+++ b/crates/shirabe/src/repository/array_repository.rs
@@ -7,8 +7,8 @@ use anyhow::Result;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- implode, preg_quote, spl_object_hash, strtolower, Countable, InvalidArgumentException,
- LogicException,
+ Countable, InvalidArgumentException, LogicException, implode, preg_quote, spl_object_hash,
+ strtolower,
};
use shirabe_semver::constraint::constraint::Constraint;
use shirabe_semver::constraint::constraint_interface::ConstraintInterface;
@@ -53,7 +53,10 @@ impl ArrayRepository {
/// Adds a new package to the repository
pub fn add_package(&self, package: Box<dyn PackageInterface>) -> Result<()> {
// PHP: if (!$package instanceof BasePackage) throw new \InvalidArgumentException(...)
- if (package.as_any() as &dyn Any).downcast_ref::<BasePackage>().is_none() {
+ if (package.as_any() as &dyn Any)
+ .downcast_ref::<BasePackage>()
+ .is_none()
+ {
return Err(InvalidArgumentException {
message: "Only subclasses of BasePackage are supported".to_string(),
code: 0,
@@ -61,7 +64,8 @@ impl ArrayRepository {
.into());
}
// TODO(phase-b): convert Box<dyn PackageInterface> to Box<BasePackage>
- let mut package: Box<BasePackage> = todo!("downcast Box<dyn PackageInterface> to Box<BasePackage>");
+ let mut package: Box<BasePackage> =
+ todo!("downcast Box<dyn PackageInterface> to Box<BasePackage>");
if self.packages.borrow().is_none() {
self.initialize();
@@ -101,7 +105,10 @@ impl ArrayRepository {
package = alias_pkg.get_alias_of().clone_box();
}
- if (package.as_any() as &dyn Any).downcast_ref::<CompletePackage>().is_some() {
+ if (package.as_any() as &dyn Any)
+ .downcast_ref::<CompletePackage>()
+ .is_some()
+ {
// TODO(phase-b): construct CompleteAliasPackage/AliasPackage and return as Box<BasePackage>
return todo!("new CompleteAliasPackage(package, alias, pretty_alias)");
}
@@ -291,10 +298,7 @@ impl RepositoryInterface for ArrayRepository {
)
} else {
// vendor/name searches expect the caller to have preg_quoted the query
- format!(
- "{{(?:{})}}i",
- implode("|", &Preg::split("{\\s+}", &query))
- )
+ format!("{{(?:{})}}i", implode("|", &Preg::split("{\\s+}", &query)))
};
let mut matches: IndexMap<String, SearchResult> = IndexMap::new();
@@ -314,8 +318,7 @@ impl RepositoryInterface for ArrayRepository {
}
}
- let complete =
- (package.as_any() as &dyn Any).downcast_ref::<CompletePackage>();
+ let complete = (package.as_any() as &dyn Any).downcast_ref::<CompletePackage>();
let fulltext_match = mode == Self::SEARCH_FULLTEXT
&& complete.is_some()
@@ -397,8 +400,8 @@ impl RepositoryInterface for ArrayRepository {
}
for link in candidate.get_provides().values() {
if package_name == link.get_target() {
- let complete = (candidate.as_any() as &dyn Any)
- .downcast_ref::<CompletePackage>();
+ let complete =
+ (candidate.as_any() as &dyn Any).downcast_ref::<CompletePackage>();
let description = complete.and_then(|c| c.get_description().map(String::from));
result.insert(
candidate.get_name().to_string(),
diff --git a/crates/shirabe/src/repository/artifact_repository.rs b/crates/shirabe/src/repository/artifact_repository.rs
index 988e456..a9832a1 100644
--- a/crates/shirabe/src/repository/artifact_repository.rs
+++ b/crates/shirabe/src/repository/artifact_repository.rs
@@ -3,7 +3,9 @@
use std::path::Path;
use indexmap::IndexMap;
-use shirabe_php_shim::{extension_loaded, hash_file, PhpMixed, RuntimeException, UnexpectedValueException};
+use shirabe_php_shim::{
+ PhpMixed, RuntimeException, UnexpectedValueException, extension_loaded, hash_file,
+};
use crate::io::io_interface::IOInterface;
use crate::json::json_file::JsonFile;
@@ -34,7 +36,10 @@ impl std::fmt::Debug for ArtifactRepository {
}
impl ArtifactRepository {
- pub fn new(repo_config: IndexMap<String, PhpMixed>, io: Box<dyn IOInterface>) -> anyhow::Result<Self> {
+ pub fn new(
+ repo_config: IndexMap<String, PhpMixed>,
+ io: Box<dyn IOInterface>,
+ ) -> anyhow::Result<Self> {
if !extension_loaded("zip") {
return Err(RuntimeException {
message: "The artifact repository requires PHP's zip extension".to_string(),
@@ -101,7 +106,10 @@ impl ArtifactRepository {
match package {
None => {
self.io.write_error(
- &format!("File <comment>{}</comment> doesn't seem to hold a package", basename),
+ &format!(
+ "File <comment>{}</comment> doesn't seem to hold a package",
+ basename
+ ),
true,
IOInterface::VERBOSE,
);
@@ -169,7 +177,8 @@ impl ArtifactRepository {
return Ok(None);
}
- let mut package = JsonFile::parse_json(&json.unwrap(), &format!("{}#composer.json", pathname))?;
+ let mut package =
+ JsonFile::parse_json(&json.unwrap(), &format!("{}#composer.json", pathname))?;
let url_normalized = pathname.replace('\\', '/');
let real_path = file
.canonicalize()
@@ -179,8 +188,14 @@ impl ArtifactRepository {
let shasum = hash_file("sha1", &real_path).unwrap_or_default();
let mut dist = IndexMap::new();
- dist.insert("type".to_string(), Box::new(PhpMixed::String(file_type.to_string())));
- dist.insert("url".to_string(), Box::new(PhpMixed::String(url_normalized)));
+ dist.insert(
+ "type".to_string(),
+ Box::new(PhpMixed::String(file_type.to_string())),
+ );
+ dist.insert(
+ "url".to_string(),
+ Box::new(PhpMixed::String(url_normalized)),
+ );
dist.insert("shasum".to_string(), Box::new(PhpMixed::String(shasum)));
package.insert("dist".to_string(), Box::new(PhpMixed::Array(dist)));
diff --git a/crates/shirabe/src/repository/canonical_packages_trait.rs b/crates/shirabe/src/repository/canonical_packages_trait.rs
index 3fac07e..8fae936 100644
--- a/crates/shirabe/src/repository/canonical_packages_trait.rs
+++ b/crates/shirabe/src/repository/canonical_packages_trait.rs
@@ -1,7 +1,7 @@
//! ref: composer/src/Composer/Repository/CanonicalPackagesTrait.php
-use indexmap::IndexMap;
use crate::package::package_interface::PackageInterface;
+use indexmap::IndexMap;
/// Provides get_canonical_packages() to various repository implementations.
pub trait CanonicalPackagesTrait {
diff --git a/crates/shirabe/src/repository/composer_repository.rs b/crates/shirabe/src/repository/composer_repository.rs
index 9d74e5b..ea73090 100644
--- a/crates/shirabe/src/repository/composer_repository.rs
+++ b/crates/shirabe/src/repository/composer_repository.rs
@@ -5,11 +5,10 @@ use shirabe_external_packages::composer::metadata_minifier::metadata_minifier::M
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use shirabe_php_shim::{
- PhpMixed, InvalidArgumentException, LogicException, RuntimeException,
- UnexpectedValueException, PHP_EOL, JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE,
- extension_loaded, hash, http_build_query, in_array,
- json_decode, parse_url_all, realpath, strtolower, strtr,
- spl_object_hash, urlencode, var_export,
+ InvalidArgumentException, JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE, LogicException,
+ PHP_EOL, PhpMixed, RuntimeException, UnexpectedValueException, extension_loaded, hash,
+ http_build_query, in_array, json_decode, parse_url_all, realpath, spl_object_hash, strtolower,
+ strtr, urlencode, var_export,
};
use shirabe_semver::compiling_matcher::CompilingMatcher;
@@ -190,7 +189,11 @@ impl ComposerRepository {
}
if url_after.starts_with("https?") {
- let scheme = if extension_loaded("openssl") { "https" } else { "http" };
+ let scheme = if extension_loaded("openssl") {
+ "https"
+ } else {
+ "http"
+ };
let rest = &url_after[6..];
repo_config.insert(
"url".to_string(),
@@ -211,10 +214,7 @@ impl ComposerRepository {
.map_or(false, |s| !s.is_empty());
if url_bits_arr.is_none() || !scheme_present {
return Err(UnexpectedValueException {
- message: format!(
- "Invalid url given for Composer repository: {}",
- current_url
- ),
+ message: format!("Invalid url given for Composer repository: {}", current_url),
code: 0,
}
.into());
@@ -255,8 +255,7 @@ impl ComposerRepository {
url = format!("{}://repo.packagist.org", proto);
}
- let base_url_trimmed =
- Preg::replace(r"{(?:/[^/\\]+\.json)?(?:[?#].*)?$}", "", &url)?;
+ let base_url_trimmed = Preg::replace(r"{(?:/[^/\\]+\.json)?(?:[?#].*)?$}", "", &url)?;
let base_url = base_url_trimmed.trim_end_matches('/').to_string();
assert!(!base_url.is_empty());
@@ -503,15 +502,14 @@ impl ComposerRepository {
if self.lazy_providers_url.is_some() {
if let Some(ref available_packages) = self.available_packages.clone() {
if self.available_package_patterns.is_none() {
- let mut package_map: IndexMap<
- String,
- Option<Box<dyn ConstraintInterface>>,
- > = IndexMap::new();
+ let mut package_map: IndexMap<String, Option<Box<dyn ConstraintInterface>>> =
+ IndexMap::new();
for name in available_packages.values() {
package_map.insert(
name.clone(),
- Some(Box::new(MatchAllConstraint::new())
- as Box<dyn ConstraintInterface>),
+ Some(
+ Box::new(MatchAllConstraint::new()) as Box<dyn ConstraintInterface>
+ ),
);
}
@@ -536,10 +534,8 @@ impl ComposerRepository {
let partial = self.partial_packages_by_name.clone().unwrap();
let flat: Vec<IndexMap<String, PhpMixed>> =
partial.into_values().flatten().collect();
- return self.create_packages_flat(
- flat,
- Some("packages.json inline packages".to_string()),
- );
+ return self
+ .create_packages_flat(flat, Some("packages.json inline packages".to_string()));
}
return Err(LogicException {
@@ -643,10 +639,7 @@ impl ComposerRepository {
Ok(vendors)
}
- fn load_package_list(
- &mut self,
- package_filter: Option<&str>,
- ) -> anyhow::Result<Vec<String>> {
+ fn load_package_list(&mut self, package_filter: Option<&str>) -> anyhow::Result<Vec<String>> {
if self.list_url.is_none() {
return Err(LogicException {
message: "Make sure to call loadRootServerFile before loadPackageList".to_string(),
@@ -768,8 +761,7 @@ impl ComposerRepository {
let matches_constraint = match &constraint {
None => true,
Some(c) => {
- let pkg_c =
- Constraint::new("==", candidate.get_version().to_string());
+ let pkg_c = Constraint::new("==", candidate.get_version().to_string());
c.matches(&pkg_c)
}
};
@@ -909,10 +901,7 @@ impl ComposerRepository {
for name in Preg::grep(&regex, &vendor_names)? {
let mut entry = IndexMap::new();
entry.insert("name".to_string(), PhpMixed::String(name));
- entry.insert(
- "description".to_string(),
- PhpMixed::String(String::new()),
- );
+ entry.insert("description".to_string(), PhpMixed::String(String::new()));
results.push(entry);
}
@@ -926,8 +915,7 @@ impl ComposerRepository {
r"{^\^(?P<query>(?P<vendor>[a-z0-9_.-]+)/[a-z0-9_.-]*)\*?$}i",
&query,
&mut match_groups,
- )?
- && self.list_url.is_some()
+ )? && self.list_url.is_some()
{
let q = match_groups.get(1).cloned().unwrap_or_default();
let vendor = match_groups.get(2).cloned().unwrap_or_default();
@@ -951,14 +939,9 @@ impl ComposerRepository {
for name_mixed in list.iter() {
if let Some(name) = name_mixed.as_string() {
let mut entry = IndexMap::new();
- entry.insert(
- "name".to_string(),
- PhpMixed::String(name.to_string()),
- );
- entry.insert(
- "description".to_string(),
- PhpMixed::String(String::new()),
- );
+ entry.insert("name".to_string(), PhpMixed::String(name.to_string()));
+ entry
+ .insert("description".to_string(), PhpMixed::String(String::new()));
results.push(entry);
}
}
@@ -975,10 +958,7 @@ impl ComposerRepository {
for name in Preg::grep(&regex, &package_names)? {
let mut entry = IndexMap::new();
entry.insert("name".to_string(), PhpMixed::String(name));
- entry.insert(
- "description".to_string(),
- PhpMixed::String(String::new()),
- );
+ entry.insert("description".to_string(), PhpMixed::String(String::new()));
results.push(entry);
}
@@ -991,9 +971,10 @@ impl ComposerRepository {
pub fn has_security_advisories(&mut self) -> anyhow::Result<bool> {
self.load_root_server_file(Some(600))?;
- Ok(self.security_advisory_config.as_ref().map_or(false, |c| {
- c.metadata || c.api_url.is_some()
- }))
+ Ok(self
+ .security_advisory_config
+ .as_ref()
+ .map_or(false, |c| c.metadata || c.api_url.is_some()))
}
/// @inheritDoc
@@ -1032,10 +1013,7 @@ impl ComposerRepository {
let repo_name = self.get_repo_name();
let create = |data: &IndexMap<String, PhpMixed>,
name: &str,
- package_constraint_map: &IndexMap<
- String,
- Box<dyn ConstraintInterface>,
- >|
+ package_constraint_map: &IndexMap<String, Box<dyn ConstraintInterface>>|
-> anyhow::Result<Option<PartialOrSecurityAdvisory>> {
let advisory =
PartialSecurityAdvisory::create(name.to_string(), data.clone(), &parser)?;
@@ -1095,8 +1073,7 @@ impl ComposerRepository {
.then_boxed(Box::new({
let advisories_ptr = &mut advisories as *mut _;
let names_found_ptr = &mut names_found as *mut _;
- let package_constraint_map_ptr =
- &mut package_constraint_map as *mut _;
+ let package_constraint_map_ptr = &mut package_constraint_map as *mut _;
let name = name.clone();
let create = &create;
move |spec: PhpMixed| -> anyhow::Result<()> {
@@ -1129,10 +1106,8 @@ impl ComposerRepository {
.iter()
.map(|(k, v)| (k.clone(), (**v).clone()))
.collect();
- let pcm: &IndexMap<
- String,
- Box<dyn ConstraintInterface>,
- > = unsafe { &*package_constraint_map_ptr };
+ let pcm: &IndexMap<String, Box<dyn ConstraintInterface>> =
+ unsafe { &*package_constraint_map_ptr };
if let Some(adv) = create(&data_map, &name, pcm)? {
entries.push(adv);
}
@@ -1183,10 +1158,7 @@ impl ComposerRepository {
headers.push(Box::new(PhpMixed::String(
"Content-type: application/x-www-form-urlencoded".to_string(),
)));
- http_map.insert(
- "header".to_string(),
- Box::new(PhpMixed::List(headers)),
- );
+ http_map.insert("header".to_string(), Box::new(PhpMixed::List(headers)));
http_map.insert("timeout".to_string(), Box::new(PhpMixed::Int(10)));
let packages_list: Vec<(String, String)> = package_constraint_map
.keys()
@@ -1200,10 +1172,7 @@ impl ComposerRepository {
"&",
"=",
);
- http_map.insert(
- "content".to_string(),
- Box::new(PhpMixed::String(body)),
- );
+ http_map.insert("content".to_string(), Box::new(PhpMixed::String(body)));
}
let response = self.http_downloader.get(&api_url, &options)?;
@@ -1240,8 +1209,7 @@ impl ComposerRepository {
.iter()
.map(|(k, v)| (k.clone(), (**v).clone()))
.collect();
- if let Some(adv) =
- create(&data_map, name, &package_constraint_map)?
+ if let Some(adv) = create(&data_map, name, &package_constraint_map)?
{
entries.push(adv);
}
@@ -1312,9 +1280,8 @@ impl ComposerRepository {
if self.has_partial_packages()? {
if self.partial_packages_by_name.is_none() {
return Err(LogicException {
- message:
- "hasPartialPackages failed to initialize $this->partialPackagesByName"
- .to_string(),
+ message: "hasPartialPackages failed to initialize $this->partialPackagesByName"
+ .to_string(),
code: 0,
}
.into());
@@ -1335,10 +1302,7 @@ impl ComposerRepository {
continue;
}
let mut entry: IndexMap<String, PhpMixed> = IndexMap::new();
- entry.insert(
- "name".to_string(),
- PhpMixed::String(candidate_name.clone()),
- );
+ entry.insert("name".to_string(), PhpMixed::String(candidate_name.clone()));
entry.insert(
"description".to_string(),
candidate
@@ -1523,11 +1487,8 @@ impl ComposerRepository {
if let Some(last_modified) =
arr.get("last-modified").and_then(|v| v.as_string())
{
- let response = self.fetch_file_if_last_modified(
- &url,
- &cache_key,
- last_modified,
- )?;
+ let response =
+ self.fetch_file_if_last_modified(&url, &cache_key, last_modified)?;
match response {
FetchFileIfLastModifiedResult::NotModified => {
let map: IndexMap<String, PhpMixed> = arr
@@ -1563,10 +1524,8 @@ impl ComposerRepository {
) {
Ok(p) => {
packages_opt = Some(p);
- packages_source = Some(format!(
- "downloaded file ({})",
- Url::sanitize(url.clone())
- ));
+ packages_source =
+ Some(format!("downloaded file ({})", Url::sanitize(url.clone())));
}
Err(e) => {
// 404s are acceptable for lazy provider repos
@@ -1583,20 +1542,15 @@ impl ComposerRepository {
)
{
let mut p: IndexMap<String, PhpMixed> = IndexMap::new();
- p.insert(
- "packages".to_string(),
- PhpMixed::Array(IndexMap::new()),
- );
+ p.insert("packages".to_string(), PhpMixed::Array(IndexMap::new()));
packages_opt = Some(p);
packages_source = Some(format!(
"not-found file ({})",
Url::sanitize(url.clone())
));
if status_code == 499 {
- self.io.error(&format!(
- "<warning>{}</warning>",
- te.get_message()
- ));
+ self.io
+ .error(&format!("<warning>{}</warning>", te.get_message()));
}
} else {
return Err(e);
@@ -1757,8 +1711,7 @@ impl ComposerRepository {
// load acceptable packages in the providers
let versions_to_load_vec: Vec<IndexMap<String, PhpMixed>> =
versions_to_load.values().cloned().collect();
- let loaded_packages =
- self.create_packages_flat(versions_to_load_vec, packages_source)?;
+ let loaded_packages = self.create_packages_flat(versions_to_load_vec, packages_source)?;
let uids: Vec<String> = versions_to_load.keys().cloned().collect();
for (index, mut package) in loaded_packages.into_iter().enumerate() {
@@ -1785,7 +1738,10 @@ impl ComposerRepository {
let repo_data = self.load_data_from_server()?;
- let source = format!("root file ({})", Url::sanitize(self.get_packages_json_url()));
+ let source = format!(
+ "root file ({})",
+ Url::sanitize(self.get_packages_json_url())
+ );
for package in self.create_packages_flat(repo_data, Some(source))? {
self.add_package(package);
}
@@ -1815,9 +1771,12 @@ impl ComposerRepository {
if self.lazy_providers_url.is_none() {
return Err(LogicException {
- message: "loadAsyncPackages only supports v2 protocol composer repos with a metadata-url".to_string(),
+ message:
+ "loadAsyncPackages only supports v2 protocol composer repos with a metadata-url"
+ .to_string(),
code: 0,
- }.into());
+ }
+ .into());
}
// load ~dev versions of the packages as well if needed
@@ -1836,8 +1795,7 @@ impl ComposerRepository {
package_names.insert(format!("{}~dev", name), constraint);
}
// if only dev stability is requested, we skip loading the non dev file
- if acceptable_stabilities
- .map_or(false, |m| m.contains_key("dev") && m.len() == 1)
+ if acceptable_stabilities.map_or(false, |m| m.contains_key("dev") && m.len() == 1)
&& stability_flags.map_or(false, |m| m.is_empty())
{
package_names.shift_remove(&name);
@@ -2043,7 +2001,9 @@ impl ComposerRepository {
}
let name = strtolower(file_name);
- let package_name = package_name.map(|s| s.to_string()).unwrap_or_else(|| name.clone());
+ let package_name = package_name
+ .map(|s| s.to_string())
+ .unwrap_or_else(|| name.clone());
let url = self
.lazy_providers_url
@@ -2091,9 +2051,7 @@ impl ComposerRepository {
contents
.clone()
.map(|m| {
- PhpMixed::Array(
- m.into_iter().map(|(k, v)| (k, Box::new(v))).collect(),
- )
+ PhpMixed::Array(m.into_iter().map(|(k, v)| (k, Box::new(v))).collect())
})
.unwrap_or(PhpMixed::Null)
} else {
@@ -2105,8 +2063,8 @@ impl ComposerRepository {
.and_then(|a| a.get("packages"))
.and_then(|v| v.as_array())
.map_or(false, |a| a.contains_key(&package_name));
- let has_advisories = response_arr
- .map_or(false, |a| a.contains_key("security-advisories"));
+ let has_advisories =
+ response_arr.map_or(false, |a| a.contains_key("security-advisories"));
if !has_pkg && !has_advisories {
return Ok(PhpMixed::List(vec![
Box::new(PhpMixed::Null),
@@ -2166,11 +2124,13 @@ impl ComposerRepository {
acceptable_stabilities: Option<&IndexMap<String, i64>>,
stability_flags: Option<&IndexMap<String, i64>>,
) -> anyhow::Result<bool> {
- let mut versions: Vec<String> = vec![version_data
- .get("version_normalized")
- .and_then(|v| v.as_string())
- .unwrap_or("")
- .to_string()];
+ let mut versions: Vec<String> = vec![
+ version_data
+ .get("version_normalized")
+ .and_then(|v| v.as_string())
+ .unwrap_or("")
+ .to_string(),
+ ];
if let Some(alias) = loader.get_branch_alias(version_data) {
versions.push(alias);
@@ -2216,10 +2176,7 @@ impl ComposerRepository {
format!("{}/packages.json", self.url)
}
- fn load_root_server_file(
- &mut self,
- root_max_age: Option<i64>,
- ) -> anyhow::Result<RootData> {
+ fn load_root_server_file(&mut self, root_max_age: Option<i64>) -> anyhow::Result<RootData> {
if let Some(rd) = &self.root_data {
return Ok(clone_root_data(rd));
}
@@ -2243,9 +2200,7 @@ impl ComposerRepository {
.map(|(k, v)| (k.clone(), (**v).clone()))
.collect();
let age = self.cache.get_age("packages.json");
- if root_max_age.is_some()
- && age.is_some()
- && age.unwrap() <= root_max_age.unwrap()
+ if root_max_age.is_some() && age.is_some() && age.unwrap() <= root_max_age.unwrap()
{
data = Some(cached_data);
} else if let Some(last_modified) = cached_data
@@ -2550,16 +2505,13 @@ impl ComposerRepository {
return Err(InvalidArgumentException {
message: "Expected a string with a value and not an empty string".to_string(),
code: 0,
- }.into());
+ }
+ .into());
}
if url.starts_with('/') {
let mut matches: Vec<String> = Vec::new();
- if Preg::is_match_with_matches(
- r"{^[^:]++://[^/]*+}",
- &self.url,
- &mut matches,
- )? {
+ if Preg::is_match_with_matches(r"{^[^:]++://[^/]*+}", &self.url, &mut matches)? {
return Ok(format!(
"{}{}",
matches.get(0).cloned().unwrap_or_default(),
@@ -2581,7 +2533,8 @@ impl ComposerRepository {
message: "loadRootServerFile should not return true during initialization"
.to_string(),
code: 0,
- }.into());
+ }
+ .into());
}
RootData::Data(d) => d,
};
@@ -2597,10 +2550,7 @@ impl ComposerRepository {
Ok(self.has_partial_packages)
}
- fn load_provider_listings(
- &mut self,
- data: &IndexMap<String, PhpMixed>,
- ) -> anyhow::Result<()> {
+ fn load_provider_listings(&mut self, data: &IndexMap<String, PhpMixed>) -> anyhow::Result<()> {
if let Some(providers) = data.get("providers").and_then(|v| v.as_array()) {
if self.provider_listing.is_none() {
self.provider_listing = Some(IndexMap::new());
@@ -2636,11 +2586,7 @@ impl ComposerRepository {
.and_then(|v| v.as_string())
.unwrap_or("")
.to_string();
- let url = format!(
- "{}/{}",
- self.base_url,
- include.replace("%hash%", &sha256)
- );
+ let url = format!("{}/{}", self.base_url, include.replace("%hash%", &sha256));
let cache_key = include.replace("%hash%", "").replace("$", "");
let included_data: IndexMap<String, PhpMixed> =
if self.cache.sha256(&cache_key).as_deref() == Some(sha256.as_str()) {
@@ -2649,9 +2595,7 @@ impl ComposerRepository {
decoded
.as_array()
.map(|a| {
- a.iter()
- .map(|(k, v)| (k.clone(), (**v).clone()))
- .collect()
+ a.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect()
})
.unwrap_or_default()
} else {
@@ -2681,11 +2625,8 @@ impl ComposerRepository {
if let Some(versions) = pkg.get("versions").and_then(|v| v.as_array()) {
for (_, metadata) in versions.iter() {
if let Some(m) = metadata.as_array() {
- packages.push(
- m.iter()
- .map(|(k, v)| (k.clone(), (**v).clone()))
- .collect(),
- );
+ packages
+ .push(m.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect());
}
}
}
@@ -2745,11 +2686,7 @@ impl ComposerRepository {
let decoded = json_decode(&raw, true)?;
decoded
.as_array()
- .map(|a| {
- a.iter()
- .map(|(k, v)| (k.clone(), (**v).clone()))
- .collect()
- })
+ .map(|a| a.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect())
.unwrap_or_default()
} else {
self.fetch_file(include, None, None, false)?
@@ -2795,10 +2732,8 @@ impl ComposerRepository {
let mut results: Vec<Box<BasePackage>> = Vec::new();
for mut package in package_instances.into_iter() {
if let Some(src_type) = package.get_source_type() {
- if let Some(mirrors) = self
- .source_mirrors
- .as_ref()
- .and_then(|m| m.get(src_type))
+ if let Some(mirrors) =
+ self.source_mirrors.as_ref().and_then(|m| m.get(src_type))
{
package.set_source_mirrors(mirrors);
}
@@ -2954,11 +2889,7 @@ impl ComposerRepository {
let decoded = response.decode_json()?;
let mut data_local: IndexMap<String, PhpMixed> = decoded
.as_array()
- .map(|a| {
- a.iter()
- .map(|(k, v)| (k.clone(), (**v).clone()))
- .collect()
- })
+ .map(|a| a.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect())
.unwrap_or_default();
HttpDownloader::output_warnings(&*self.io, &self.url, &data_local);
@@ -3025,9 +2956,7 @@ impl ComposerRepository {
let map: IndexMap<String, PhpMixed> = parsed
.as_array()
.map(|a| {
- a.iter()
- .map(|(k, v)| (k.clone(), (**v).clone()))
- .collect()
+ a.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect()
})
.unwrap_or_default();
data = Some(map);
@@ -3061,7 +2990,8 @@ impl ComposerRepository {
return Err(InvalidArgumentException {
message: "$filename should not be an empty string".to_string(),
code: 0,
- }.into());
+ }
+ .into());
}
let mut filename = filename.to_string();
@@ -3143,11 +3073,7 @@ impl ComposerRepository {
let decoded = response.decode_json()?;
let mut data: IndexMap<String, PhpMixed> = decoded
.as_array()
- .map(|a| {
- a.iter()
- .map(|(k, v)| (k.clone(), (**v).clone()))
- .collect()
- })
+ .map(|a| a.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect())
.unwrap_or_default();
HttpDownloader::output_warnings(&*self.io, &self.url, &data);
@@ -3205,7 +3131,8 @@ impl ComposerRepository {
return Err(InvalidArgumentException {
message: "$filename should not be an empty string".to_string(),
code: 0,
- }.into());
+ }
+ .into());
}
if self.packagesNotFoundCache.contains_key(filename) {
@@ -3318,11 +3245,7 @@ impl ComposerRepository {
let decoded = response.decode_json()?;
let mut data: IndexMap<String, PhpMixed> = decoded
.as_array()
- .map(|a| {
- a.iter()
- .map(|(k, v)| (k.clone(), (**v).clone()))
- .collect()
- })
+ .map(|a| a.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect())
.unwrap_or_default();
let io_ref = unsafe { &*io_ptr };
HttpDownloader::output_warnings(io_ref, &url_owned, &data);
@@ -3420,7 +3343,11 @@ impl ComposerRepository {
};
self.partial_packages_by_name = Some(IndexMap::new());
- if let Some(packages) = root_data.get("packages").and_then(|v| v.as_array()).cloned() {
+ if let Some(packages) = root_data
+ .get("packages")
+ .and_then(|v| v.as_array())
+ .cloned()
+ {
for (package, versions_mixed) in packages.iter() {
let versions = match versions_mixed.as_array() {
Some(a) => a.clone(),
diff --git a/crates/shirabe/src/repository/composite_repository.rs b/crates/shirabe/src/repository/composite_repository.rs
index 9787b6a..5413bbe 100644
--- a/crates/shirabe/src/repository/composite_repository.rs
+++ b/crates/shirabe/src/repository/composite_repository.rs
@@ -18,7 +18,9 @@ pub struct CompositeRepository {
impl CompositeRepository {
pub fn new(repositories: Vec<Box<dyn RepositoryInterface>>) -> Self {
- let mut this = Self { repositories: vec![] };
+ let mut this = Self {
+ repositories: vec![],
+ };
for repo in repositories {
this.add_repository(repo);
}
@@ -37,7 +39,9 @@ impl CompositeRepository {
}
pub fn add_repository(&mut self, repository: Box<dyn RepositoryInterface>) {
- if let Some(composite) = (repository.as_any() as &dyn Any).downcast_ref::<CompositeRepository>() {
+ if let Some(composite) =
+ (repository.as_any() as &dyn Any).downcast_ref::<CompositeRepository>()
+ {
for repo in composite.get_repositories() {
self.repositories.push(repo.clone_box());
}
@@ -55,7 +59,11 @@ impl shirabe_php_shim::Countable for CompositeRepository {
impl RepositoryInterface for CompositeRepository {
fn get_repo_name(&self) -> String {
- let names: Vec<String> = self.repositories.iter().map(|r| r.get_repo_name()).collect();
+ let names: Vec<String> = self
+ .repositories
+ .iter()
+ .map(|r| r.get_repo_name())
+ .collect();
format!("composite repo ({})", names.join(", "))
}
@@ -68,7 +76,11 @@ impl RepositoryInterface for CompositeRepository {
false
}
- fn find_package(&self, name: String, constraint: FindPackageConstraint) -> Option<Box<BasePackage>> {
+ fn find_package(
+ &self,
+ name: String,
+ constraint: FindPackageConstraint,
+ ) -> Option<Box<BasePackage>> {
for repository in &self.repositories {
let package = repository.find_package(name.clone(), constraint.clone());
if package.is_some() {
@@ -78,7 +90,11 @@ impl RepositoryInterface for CompositeRepository {
None
}
- fn find_packages(&self, name: String, constraint: Option<FindPackageConstraint>) -> Vec<Box<BasePackage>> {
+ fn find_packages(
+ &self,
+ name: String,
+ constraint: Option<FindPackageConstraint>,
+ ) -> Vec<Box<BasePackage>> {
let mut packages = vec![];
for repository in &self.repositories {
packages.extend(repository.find_packages(name.clone(), constraint.clone()));
diff --git a/crates/shirabe/src/repository/filesystem_repository.rs b/crates/shirabe/src/repository/filesystem_repository.rs
index 5cbff22..4ca5ab1 100644
--- a/crates/shirabe/src/repository/filesystem_repository.rs
+++ b/crates/shirabe/src/repository/filesystem_repository.rs
@@ -6,10 +6,10 @@ use anyhow::Result;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- array_flip, dirname, file_get_contents, get_class, get_debug_type, in_array, is_array,
- is_int, is_null, is_string, ksort, php_dir, r#eval, realpath, sort, sort_with_flags,
- str_repeat, strtr, trim, usort, var_export, InvalidArgumentException, LogicException,
- PhpMixed, Silencer, UnexpectedValueException, SORT_NATURAL,
+ InvalidArgumentException, LogicException, PhpMixed, SORT_NATURAL, Silencer,
+ UnexpectedValueException, array_flip, dirname, r#eval, file_get_contents, get_class,
+ get_debug_type, in_array, is_array, is_int, is_null, is_string, ksort, php_dir, realpath, sort,
+ sort_with_flags, str_repeat, strtr, trim, usort, var_export,
};
use crate::installed_versions::InstalledVersions;
@@ -141,12 +141,18 @@ impl FilesystemRepository {
let mut loader = ArrayLoader::new(None, true);
if let Some(packages_list) = packages.as_list() {
for package_data in packages_list.iter() {
- let package = loader.load((**package_data).clone(), "Composer\\Package\\CompletePackage")?;
+ let package = loader.load(
+ (**package_data).clone(),
+ "Composer\\Package\\CompletePackage",
+ )?;
self.inner.add_package(package)?;
}
} else if let Some(packages_array) = packages.as_array() {
for (_, package_data) in packages_array.iter() {
- let package = loader.load((**package_data).clone(), "Composer\\Package\\CompletePackage")?;
+ let package = loader.load(
+ (**package_data).clone(),
+ "Composer\\Package\\CompletePackage",
+ )?;
self.inner.add_package(package)?;
}
}
@@ -179,9 +185,9 @@ impl FilesystemRepository {
let repo_dir = dirname(self.file.get_path());
self.filesystem.ensure_directory_exists(&repo_dir);
- let repo_dir = self.filesystem.normalize_path(
- &realpath(&repo_dir).unwrap_or_default(),
- );
+ let repo_dir = self
+ .filesystem
+ .normalize_path(&realpath(&repo_dir).unwrap_or_default());
let mut install_paths: IndexMap<String, Option<String>> = IndexMap::new();
for package in self.inner.get_canonical_packages() {
@@ -190,13 +196,18 @@ impl FilesystemRepository {
let mut install_path: Option<String> = None;
if let Some(path_str) = &path {
if !path_str.is_empty() {
- let normalized_path = self.filesystem.normalize_path(
- &if self.filesystem.is_absolute_path(path_str) {
- path_str.clone()
- } else {
- format!("{}/{}", Platform::get_cwd(false).unwrap_or_default(), path_str)
- },
- );
+ let normalized_path = self.filesystem.normalize_path(&if self
+ .filesystem
+ .is_absolute_path(path_str)
+ {
+ path_str.clone()
+ } else {
+ format!(
+ "{}/{}",
+ Platform::get_cwd(false).unwrap_or_default(),
+ path_str
+ )
+ });
install_path = Some(self.filesystem.find_shortest_path(
&repo_dir,
&normalized_path,
@@ -215,7 +226,10 @@ impl FilesystemRepository {
);
if let Some(PhpMixed::List(list)) = data.get_mut("packages") {
list.push(Box::new(PhpMixed::Array(
- pkg_array.into_iter().map(|(k, v)| (k, Box::new(v))).collect(),
+ pkg_array
+ .into_iter()
+ .map(|(k, v)| (k, Box::new(v)))
+ .collect(),
)));
}
@@ -273,20 +287,19 @@ impl FilesystemRepository {
)?;
if self.dump_versions {
- let versions =
- self.generate_installed_versions(installation_manager, &install_paths, dev_mode, &repo_dir)?;
+ let versions = self.generate_installed_versions(
+ installation_manager,
+ &install_paths,
+ dev_mode,
+ &repo_dir,
+ )?;
self.filesystem.file_put_contents_if_modified(
&format!("{}/installed.php", repo_dir),
- &format!(
- "<?php return {};\n",
- self.dump_to_php_code(&versions, 0),
- ),
+ &format!("<?php return {};\n", self.dump_to_php_code(&versions, 0),),
);
- let installed_versions_class = file_get_contents(&format!(
- "{}/../InstalledVersions.php",
- php_dir(),
- ));
+ let installed_versions_class =
+ file_get_contents(&format!("{}/../InstalledVersions.php", php_dir(),));
// this normally should not happen but during upgrades of Composer when it is installed in the project it is a possibility
if let Some(class_content) = installed_versions_class {
@@ -328,7 +341,7 @@ impl FilesystemRepository {
let mixed = PhpMixed::String(data.clone());
if is_string(&mixed) && Preg::is_match(pattern, &trim(&data, None)) {
let replaced = Preg::replace(
- r"{=>\s*+__DIR__\s*+\.\s*+(['\"])}",
+ r#"{=>\s*+__DIR__\s*+\.\s*+(['\"])}"#,
&format!(
"=> {} . $1",
var_export(&PhpMixed::String(dirname(path)), true),
@@ -391,10 +404,7 @@ impl FilesystemRepository {
} else if key == "install_path" && is_string(value) {
let s = value.as_string().unwrap_or("").to_string();
if self.filesystem.is_absolute_path(&s) {
- lines.push_str(&format!(
- "{},\n",
- var_export(&PhpMixed::String(s), true),
- ));
+ lines.push_str(&format!("{},\n", var_export(&PhpMixed::String(s), true),));
} else {
lines.push_str(&format!(
"__DIR__ . {},\n",
@@ -447,7 +457,9 @@ impl FilesystemRepository {
let mut root_package = match &self.root_package {
None => {
return Err(LogicException {
- message: "It should not be possible to dump packages if no root package is given".to_string(),
+ message:
+ "It should not be possible to dump packages if no root package is given"
+ .to_string(),
code: 0,
}
.into());
@@ -460,8 +472,11 @@ impl FilesystemRepository {
let mut current_root: Box<dyn RootPackageInterface> = root_package;
// packages.push(current_root.clone_box());
- while let Some(_alias) = (current_root.as_any() as &dyn Any).downcast_ref::<RootAliasPackage>() {
- current_root = todo!("RootAliasPackage::get_alias_of() returning Box<dyn RootPackageInterface>");
+ while let Some(_alias) =
+ (current_root.as_any() as &dyn Any).downcast_ref::<RootAliasPackage>()
+ {
+ current_root =
+ todo!("RootAliasPackage::get_alias_of() returning Box<dyn RootPackageInterface>");
// packages.push(current_root.clone_box());
}
let mut versions: IndexMap<String, PhpMixed> = IndexMap::new();
@@ -480,18 +495,19 @@ impl FilesystemRepository {
.collect(),
),
);
- versions.insert(
- "versions".to_string(),
- PhpMixed::Array(IndexMap::new()),
- );
+ versions.insert("versions".to_string(), PhpMixed::Array(IndexMap::new()));
// add real installed packages
for package in &packages {
- if (package.as_any() as &dyn Any).downcast_ref::<AliasPackage>().is_some() {
+ if (package.as_any() as &dyn Any)
+ .downcast_ref::<AliasPackage>()
+ .is_some()
+ {
continue;
}
- let dumped = self.dump_installed_package(&**package, install_paths, repo_dir, &dev_packages);
+ let dumped =
+ self.dump_installed_package(&**package, install_paths, repo_dir, &dev_packages);
if let Some(PhpMixed::Array(versions_map)) = versions.get_mut("versions") {
versions_map.insert(
package.get_name().to_string(),
@@ -552,7 +568,10 @@ impl FilesystemRepository {
};
// TODO(phase-b): mutate nested versions['versions'][name]['aliases']
todo!("append alias->getPrettyVersion() to versions['versions'][name]['aliases']");
- if (package.as_any() as &dyn Any).downcast_ref::<dyn RootPackageInterface>().is_some() {
+ if (package.as_any() as &dyn Any)
+ .downcast_ref::<dyn RootPackageInterface>()
+ .is_some()
+ {
// TODO(phase-b): same mutation on versions['root']['aliases']
todo!("append alias->getPrettyVersion() to versions['root']['aliases']");
}
@@ -614,17 +633,16 @@ impl FilesystemRepository {
};
}
- let install_path = if (package.as_any() as &dyn Any).downcast_ref::<dyn RootPackageInterface>().is_some() {
+ let install_path = if (package.as_any() as &dyn Any)
+ .downcast_ref::<dyn RootPackageInterface>()
+ .is_some()
+ {
let to = self.filesystem.normalize_path(
- &realpath(&Platform::get_cwd(false).unwrap_or_default())
- .unwrap_or_default(),
+ &realpath(&Platform::get_cwd(false).unwrap_or_default()).unwrap_or_default(),
);
Some(self.filesystem.find_shortest_path(repo_dir, &to, true))
} else {
- install_paths
- .get(package.get_name())
- .cloned()
- .flatten()
+ install_paths.get(package.get_name()).cloned().flatten()
};
let mut data: IndexMap<String, PhpMixed> = IndexMap::new();
@@ -690,7 +708,9 @@ impl FilesystemRepository {
);
result.insert(
"pretty_version".to_string(),
- data.get("pretty_version").cloned().unwrap_or(PhpMixed::Null),
+ data.get("pretty_version")
+ .cloned()
+ .unwrap_or(PhpMixed::Null),
);
result.insert(
"version".to_string(),
@@ -710,7 +730,9 @@ impl FilesystemRepository {
);
result.insert(
"aliases".to_string(),
- data.get("aliases").cloned().unwrap_or(PhpMixed::List(vec![])),
+ data.get("aliases")
+ .cloned()
+ .unwrap_or(PhpMixed::List(vec![])),
);
result.insert("dev".to_string(), PhpMixed::Bool(dev_mode));
diff --git a/crates/shirabe/src/repository/filter_repository.rs b/crates/shirabe/src/repository/filter_repository.rs
index 3a65ef2..eeb1306 100644
--- a/crates/shirabe/src/repository/filter_repository.rs
+++ b/crates/shirabe/src/repository/filter_repository.rs
@@ -1,16 +1,18 @@
//! ref: composer/src/Composer/Repository/FilterRepository.php
-use anyhow::Result;
-use indexmap::IndexMap;
-use shirabe_php_shim::{InvalidArgumentException, PhpMixed};
-use shirabe_external_packages::composer::pcre::preg::Preg;
-use shirabe_semver::constraint::constraint_interface::ConstraintInterface;
use crate::package::base_package::BasePackage;
use crate::package::package_interface::PackageInterface;
-use crate::repository::advisory_provider_interface::{AdvisoryProviderInterface, SecurityAdvisoryResult};
+use crate::repository::advisory_provider_interface::{
+ AdvisoryProviderInterface, SecurityAdvisoryResult,
+};
use crate::repository::repository_interface::{
FindPackageConstraint, LoadPackagesResult, ProviderInfo, RepositoryInterface, SearchResult,
};
+use anyhow::Result;
+use indexmap::IndexMap;
+use shirabe_external_packages::composer::pcre::preg::Preg;
+use shirabe_php_shim::{InvalidArgumentException, PhpMixed};
+use shirabe_semver::constraint::constraint_interface::ConstraintInterface;
#[derive(Debug)]
pub struct FilterRepository {
@@ -21,7 +23,10 @@ pub struct FilterRepository {
}
impl FilterRepository {
- pub fn new(repo: Box<dyn RepositoryInterface>, options: IndexMap<String, PhpMixed>) -> Result<Self> {
+ pub fn new(
+ repo: Box<dyn RepositoryInterface>,
+ options: IndexMap<String, PhpMixed>,
+ ) -> Result<Self> {
let mut only: Option<String> = None;
let mut exclude: Option<String> = None;
let mut canonical = true;
@@ -29,40 +34,66 @@ impl FilterRepository {
if let Some(only_val) = options.get("only") {
match only_val {
PhpMixed::List(list) => {
- let names: Vec<String> = list.iter().filter_map(|v| {
- if let PhpMixed::String(s) = v.as_ref() { Some(s.clone()) } else { None }
- }).collect();
+ let names: Vec<String> = list
+ .iter()
+ .filter_map(|v| {
+ if let PhpMixed::String(s) = v.as_ref() {
+ Some(s.clone())
+ } else {
+ None
+ }
+ })
+ .collect();
only = Some(BasePackage::package_names_to_regexp(&names));
}
_ => {
return Err(InvalidArgumentException {
- message: format!(r#""only" key for repository {} should be an array"#, repo.get_repo_name()),
+ message: format!(
+ r#""only" key for repository {} should be an array"#,
+ repo.get_repo_name()
+ ),
code: 0,
- }.into());
+ }
+ .into());
}
}
}
if let Some(exclude_val) = options.get("exclude") {
match exclude_val {
PhpMixed::List(list) => {
- let names: Vec<String> = list.iter().filter_map(|v| {
- if let PhpMixed::String(s) = v.as_ref() { Some(s.clone()) } else { None }
- }).collect();
+ let names: Vec<String> = list
+ .iter()
+ .filter_map(|v| {
+ if let PhpMixed::String(s) = v.as_ref() {
+ Some(s.clone())
+ } else {
+ None
+ }
+ })
+ .collect();
exclude = Some(BasePackage::package_names_to_regexp(&names));
}
_ => {
return Err(InvalidArgumentException {
- message: format!(r#""exclude" key for repository {} should be an array"#, repo.get_repo_name()),
+ message: format!(
+ r#""exclude" key for repository {} should be an array"#,
+ repo.get_repo_name()
+ ),
code: 0,
- }.into());
+ }
+ .into());
}
}
}
if exclude.is_some() && only.is_some() {
return Err(InvalidArgumentException {
- message: format!(r#"Only one of "only" and "exclude" can be specified for repository {}"#, repo.get_repo_name()),
+ message: format!(
+ r#"Only one of "only" and "exclude" can be specified for repository {}"#,
+ repo.get_repo_name()
+ ),
code: 0,
- }.into());
+ }
+ .into());
}
if let Some(canonical_val) = options.get("canonical") {
match canonical_val {
@@ -71,14 +102,23 @@ impl FilterRepository {
}
_ => {
return Err(InvalidArgumentException {
- message: format!(r#""canonical" key for repository {} should be a boolean"#, repo.get_repo_name()),
+ message: format!(
+ r#""canonical" key for repository {} should be a boolean"#,
+ repo.get_repo_name()
+ ),
code: 0,
- }.into());
+ }
+ .into());
}
}
}
- Ok(Self { only, exclude, canonical, repo })
+ Ok(Self {
+ only,
+ exclude,
+ canonical,
+ repo,
+ })
}
pub fn get_repository(&self) -> &dyn RepositoryInterface {
@@ -117,7 +157,11 @@ impl RepositoryInterface for FilterRepository {
self.repo.has_package(package)
}
- fn find_package(&self, name: String, constraint: FindPackageConstraint) -> Option<Box<BasePackage>> {
+ fn find_package(
+ &self,
+ name: String,
+ constraint: FindPackageConstraint,
+ ) -> Option<Box<BasePackage>> {
if !self.is_allowed(&name) {
return None;
}
@@ -125,7 +169,11 @@ impl RepositoryInterface for FilterRepository {
self.repo.find_package(name, constraint)
}
- fn find_packages(&self, name: String, constraint: Option<FindPackageConstraint>) -> Vec<Box<BasePackage>> {
+ fn find_packages(
+ &self,
+ name: String,
+ constraint: Option<FindPackageConstraint>,
+ ) -> Vec<Box<BasePackage>> {
if !self.is_allowed(&name) {
return Vec::new();
}
@@ -143,10 +191,18 @@ impl RepositoryInterface for FilterRepository {
package_name_map.retain(|name, _| self.is_allowed(name));
if package_name_map.is_empty() {
- return LoadPackagesResult { names_found: Vec::new(), packages: Vec::new() };
+ return LoadPackagesResult {
+ names_found: Vec::new(),
+ packages: Vec::new(),
+ };
}
- let mut result = self.repo.load_packages(package_name_map, acceptable_stabilities, stability_flags, already_loaded);
+ let mut result = self.repo.load_packages(
+ package_name_map,
+ acceptable_stabilities,
+ stability_flags,
+ already_loaded,
+ );
if !self.canonical {
result.names_found = Vec::new();
}
@@ -219,7 +275,10 @@ impl AdvisoryProviderInterface for FilterRepository {
package_constraint_map.retain(|name, _| self.is_allowed(name));
advisory_repo.get_security_advisories(package_constraint_map, allow_partial_advisories)
} else {
- Ok(SecurityAdvisoryResult { names_found: Vec::new(), advisories: IndexMap::new() })
+ Ok(SecurityAdvisoryResult {
+ names_found: Vec::new(),
+ advisories: IndexMap::new(),
+ })
}
}
}
diff --git a/crates/shirabe/src/repository/installed_repository.rs b/crates/shirabe/src/repository/installed_repository.rs
index f3b53ae..bb56c94 100644
--- a/crates/shirabe/src/repository/installed_repository.rs
+++ b/crates/shirabe/src/repository/installed_repository.rs
@@ -223,11 +223,7 @@ impl InstalledRepository {
for pkg in self.find_packages(link.get_target().to_string(), None) {
let version = Constraint::new("=", pkg.get_version());
if link.get_constraint().matches(&version) == invert {
- results.push(DependentsEntry(
- package.clone_box(),
- link.clone(),
- None,
- ));
+ results.push(DependentsEntry(package.clone_box(), link.clone(), None));
}
}
}
@@ -238,11 +234,7 @@ impl InstalledRepository {
for pkg in self.find_packages(link.get_target().to_string(), None) {
let version = Constraint::new("=", pkg.get_version());
if link.get_constraint().matches(&version) == invert {
- results.push(DependentsEntry(
- package.clone_box(),
- link.clone(),
- None,
- ));
+ results.push(DependentsEntry(package.clone_box(), link.clone(), None));
}
}
}
@@ -327,9 +319,7 @@ impl InstalledRepository {
}
for root_req in root_reqs.values() {
if pkg.get_names().contains(&root_req.get_target().to_string())
- && !root_req
- .get_constraint()
- .matches(link.get_constraint())
+ && !root_req.get_constraint().matches(link.get_constraint())
{
results.push(DependentsEntry(
package.clone_box(),
diff --git a/crates/shirabe/src/repository/mod.rs b/crates/shirabe/src/repository/mod.rs
new file mode 100644
index 0000000..e570051
--- /dev/null
+++ b/crates/shirabe/src/repository/mod.rs
@@ -0,0 +1,31 @@
+pub mod advisory_provider_interface;
+pub mod array_repository;
+pub mod artifact_repository;
+pub mod canonical_packages_trait;
+pub mod composer_repository;
+pub mod composite_repository;
+pub mod configurable_repository_interface;
+pub mod filesystem_repository;
+pub mod filter_repository;
+pub mod installed_array_repository;
+pub mod installed_filesystem_repository;
+pub mod installed_repository;
+pub mod installed_repository_interface;
+pub mod invalid_repository_exception;
+pub mod lock_array_repository;
+pub mod package_repository;
+pub mod path_repository;
+pub mod pear_repository;
+pub mod platform_repository;
+pub mod repository_factory;
+pub mod repository_interface;
+pub mod repository_manager;
+pub mod repository_security_exception;
+pub mod repository_set;
+pub mod repository_utils;
+pub mod root_package_repository;
+pub mod vcs;
+pub mod vcs_repository;
+pub mod version_cache_interface;
+pub mod writable_array_repository;
+pub mod writable_repository_interface;
diff --git a/crates/shirabe/src/repository/path_repository.rs b/crates/shirabe/src/repository/path_repository.rs
index f2b470d..c148880 100644
--- a/crates/shirabe/src/repository/path_repository.rs
+++ b/crates/shirabe/src/repository/path_repository.rs
@@ -3,8 +3,8 @@
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- defined, file_exists, file_get_contents, glob_with_flags, hash, realpath, serialize,
- PhpMixed, RuntimeException, DIRECTORY_SEPARATOR, GLOB_BRACE, GLOB_MARK, GLOB_ONLYDIR,
+ DIRECTORY_SEPARATOR, GLOB_BRACE, GLOB_MARK, GLOB_ONLYDIR, PhpMixed, RuntimeException, defined,
+ file_exists, file_get_contents, glob_with_flags, hash, realpath, serialize,
};
use crate::config::Config;
@@ -65,8 +65,7 @@ impl PathRepository {
.to_string();
let url = Platform::expand_path(&url_str);
let process = process.unwrap_or_else(|| ProcessExecutor::new(&*io));
- let version_guesser =
- VersionGuesser::new(&config, &process, VersionParser::new(), &*io);
+ let version_guesser = VersionGuesser::new(&config, &process, VersionParser::new(), &*io);
let mut options = repo_config
.get("options")
.and_then(|v| v.as_array())
@@ -133,10 +132,7 @@ impl PathRepository {
}
for url in url_matches {
- let path = format!(
- "{}/",
- realpath(&url).unwrap_or_default()
- );
+ let path = format!("{}/", realpath(&url).unwrap_or_default());
let composer_file_path = format!("{}composer.json", path);
if !file_exists(&composer_file_path) {
@@ -144,11 +140,14 @@ impl PathRepository {
}
let json = file_get_contents(&composer_file_path).unwrap_or_default();
- let mut package = JsonFile::parse_json(&json, Some(&composer_file_path))?
- .unwrap_or_default();
+ let mut package =
+ JsonFile::parse_json(&json, Some(&composer_file_path))?.unwrap_or_default();
let dist = {
let mut dist = IndexMap::new();
- dist.insert("type".to_string(), Box::new(PhpMixed::String("path".to_string())));
+ dist.insert(
+ "type".to_string(),
+ Box::new(PhpMixed::String("path".to_string())),
+ );
dist.insert("url".to_string(), Box::new(PhpMixed::String(url.clone())));
dist
};
@@ -193,7 +192,11 @@ impl PathRepository {
);
// use the version provided as option if available
- if let Some(name) = package.get("name").and_then(|v| v.as_string()).map(|s| s.to_string()) {
+ if let Some(name) = package
+ .get("name")
+ .and_then(|v| v.as_string())
+ .map(|s| s.to_string())
+ {
if let Some(version) = self
.options
.get("versions")
@@ -226,9 +229,7 @@ impl PathRepository {
{
package.insert(
"version".to_string(),
- PhpMixed::String(
- self.version_guesser.get_root_version_from_env(),
- ),
+ PhpMixed::String(self.version_guesser.get_root_version_from_env()),
);
}
}
@@ -236,20 +237,25 @@ impl PathRepository {
}
let mut output = String::new();
- let command = GitUtil::build_rev_list_command(
- &self.process,
- {
- let mut args = vec!["-n1".to_string(), "--format=%H".to_string(), "HEAD".to_string()];
- args.extend(GitUtil::get_no_show_signature_flags(&self.process));
- args
- },
- );
+ let command = GitUtil::build_rev_list_command(&self.process, {
+ let mut args = vec![
+ "-n1".to_string(),
+ "--format=%H".to_string(),
+ "HEAD".to_string(),
+ ];
+ args.extend(GitUtil::get_no_show_signature_flags(&self.process));
+ args
+ });
if reference == "auto"
&& shirabe_php_shim::is_dir(&format!("{}/.git", path.trim_end_matches('/')))
- && self.process.execute(&command, &mut output, Some(path.clone())) == 0
+ && self
+ .process
+ .execute(&command, &mut output, Some(path.clone()))
+ == 0
{
- let ref_val =
- GitUtil::parse_rev_list_output(&output, &self.process).trim().to_string();
+ let ref_val = GitUtil::parse_rev_list_output(&output, &self.process)
+ .trim()
+ .to_string();
if let Some(PhpMixed::Array(ref mut dist)) = package.get_mut("dist") {
dist.insert("reference".to_string(), Box::new(PhpMixed::String(ref_val)));
}
@@ -294,12 +300,17 @@ impl PathRepository {
}
self.inner
- .add_package(self.loader.load(package.clone()).map_err(|e| {
- RuntimeException {
- message: format!("Failed loading the package in {}", composer_file_path),
- code: 0,
- }
- })?);
+ .add_package(
+ self.loader
+ .load(package.clone())
+ .map_err(|e| RuntimeException {
+ message: format!(
+ "Failed loading the package in {}",
+ composer_file_path
+ ),
+ code: 0,
+ })?,
+ );
}
Ok(())
@@ -324,7 +335,11 @@ impl PathRepository {
// Ensure environment-specific path separators are normalized to URL separators
Ok(glob_with_flags(&self.url, flags)
.into_iter()
- .map(|val| val.replace(DIRECTORY_SEPARATOR, "/").trim_end_matches('/').to_string())
+ .map(|val| {
+ val.replace(DIRECTORY_SEPARATOR, "/")
+ .trim_end_matches('/')
+ .to_string()
+ })
.collect())
}
}
diff --git a/crates/shirabe/src/repository/platform_repository.rs b/crates/shirabe/src/repository/platform_repository.rs
index 6f3f774..5c6bec7 100644
--- a/crates/shirabe/src/repository/platform_repository.rs
+++ b/crates/shirabe/src/repository/platform_repository.rs
@@ -7,9 +7,9 @@ use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::composer::xdebug_handler::xdebug_handler::XdebugHandler;
use shirabe_php_shim::{
- array_map_str_fn, array_slice, array_slice_strs, explode, get_class, implode, in_array,
- is_string, sprintf, str_replace, str_starts_with, strpos, strtolower, var_export,
- InvalidArgumentException, PhpMixed, UnexpectedValueException,
+ InvalidArgumentException, PhpMixed, UnexpectedValueException, array_map_str_fn, array_slice,
+ array_slice_strs, explode, get_class, implode, in_array, is_string, sprintf, str_replace,
+ str_starts_with, strpos, strtolower, var_export,
};
use shirabe_semver::constraint::constraint::Constraint;
@@ -27,8 +27,7 @@ use crate::repository::array_repository::ArrayRepository;
use crate::repository::repository_interface::RepositoryInterface;
use crate::util::silencer::Silencer;
-static LAST_SEEN_PLATFORM_PHP: LazyLock<Mutex<Option<String>>> =
- LazyLock::new(|| Mutex::new(None));
+static LAST_SEEN_PLATFORM_PHP: LazyLock<Mutex<Option<String>>> = LazyLock::new(|| Mutex::new(None));
static IS_PLATFORM_PACKAGE_CACHE: LazyLock<Mutex<IndexMap<String, bool>>> =
LazyLock::new(|| Mutex::new(IndexMap::new()));
@@ -153,7 +152,11 @@ impl PlatformRepository {
.as_ref()
.unwrap()
.normalize(&pretty_version, None)?;
- let mut composer = CompletePackage::new("composer".to_string(), version.clone(), pretty_version.clone());
+ let mut composer = CompletePackage::new(
+ "composer".to_string(),
+ version.clone(),
+ pretty_version.clone(),
+ );
composer.set_description("Composer package".to_string());
self.add_package(Box::new(composer))?;
@@ -163,8 +166,11 @@ impl PlatformRepository {
.as_ref()
.unwrap()
.normalize(&pretty_version, None)?;
- let mut composer_plugin_api =
- CompletePackage::new("composer-plugin-api".to_string(), version.clone(), pretty_version.clone());
+ let mut composer_plugin_api = CompletePackage::new(
+ "composer-plugin-api".to_string(),
+ version.clone(),
+ pretty_version.clone(),
+ );
composer_plugin_api.set_description("The Composer Plugin API".to_string());
self.add_package(Box::new(composer_plugin_api))?;
@@ -174,8 +180,11 @@ impl PlatformRepository {
.as_ref()
.unwrap()
.normalize(&pretty_version, None)?;
- let mut composer_runtime_api =
- CompletePackage::new("composer-runtime-api".to_string(), version.clone(), pretty_version.clone());
+ let mut composer_runtime_api = CompletePackage::new(
+ "composer-runtime-api".to_string(),
+ version.clone(),
+ pretty_version.clone(),
+ );
composer_runtime_api.set_description("The Composer Runtime API".to_string());
self.add_package(Box::new(composer_runtime_api))?;
@@ -195,8 +204,8 @@ impl PlatformRepository {
version = v;
}
Err(_) => {
- pretty_version =
- Preg::replace("#^([^~+-]+).*$#", "$1", &php_version_str).unwrap_or(php_version_str);
+ pretty_version = Preg::replace("#^([^~+-]+).*$#", "$1", &php_version_str)
+ .unwrap_or(php_version_str);
version = self
.version_parser
.as_ref()
@@ -205,22 +214,38 @@ impl PlatformRepository {
}
}
- let mut php = CompletePackage::new("php".to_string(), version.clone(), pretty_version.clone());
+ let mut php =
+ CompletePackage::new("php".to_string(), version.clone(), pretty_version.clone());
php.set_description("The PHP interpreter".to_string());
self.add_package(Box::new(php))?;
- if self.runtime.get_constant("PHP_DEBUG", None).as_bool().unwrap_or(false) {
- let mut phpdebug =
- CompletePackage::new("php-debug".to_string(), version.clone(), pretty_version.clone());
+ if self
+ .runtime
+ .get_constant("PHP_DEBUG", None)
+ .as_bool()
+ .unwrap_or(false)
+ {
+ let mut phpdebug = CompletePackage::new(
+ "php-debug".to_string(),
+ version.clone(),
+ pretty_version.clone(),
+ );
phpdebug.set_description("The PHP interpreter, with debugging symbols".to_string());
self.add_package(Box::new(phpdebug))?;
}
if self.runtime.has_constant("PHP_ZTS", None)
- && self.runtime.get_constant("PHP_ZTS", None).as_bool().unwrap_or(false)
+ && self
+ .runtime
+ .get_constant("PHP_ZTS", None)
+ .as_bool()
+ .unwrap_or(false)
{
- let mut phpzts =
- CompletePackage::new("php-zts".to_string(), version.clone(), pretty_version.clone());
+ let mut phpzts = CompletePackage::new(
+ "php-zts".to_string(),
+ version.clone(),
+ pretty_version.clone(),
+ );
phpzts.set_description("The PHP interpreter, with Zend Thread Safety".to_string());
self.add_package(Box::new(phpzts))?;
}
@@ -232,8 +257,11 @@ impl PlatformRepository {
.map(|v| v == 8)
.unwrap_or(false)
{
- let mut php64 =
- CompletePackage::new("php-64bit".to_string(), version.clone(), pretty_version.clone());
+ let mut php64 = CompletePackage::new(
+ "php-64bit".to_string(),
+ version.clone(),
+ pretty_version.clone(),
+ );
php64.set_description("The PHP interpreter, 64bit".to_string());
self.add_package(Box::new(php64))?;
}
@@ -254,8 +282,11 @@ impl PlatformRepository {
})
.unwrap_or(PhpMixed::Bool(false));
if has_inet6 || !matches!(inet_pton_check, PhpMixed::Bool(false)) {
- let mut php_ipv6 =
- CompletePackage::new("php-ipv6".to_string(), version.clone(), pretty_version.clone());
+ let mut php_ipv6 = CompletePackage::new(
+ "php-ipv6".to_string(),
+ version.clone(),
+ pretty_version.clone(),
+ );
php_ipv6.set_description("The PHP interpreter, with IPv6 support".to_string());
self.add_package(Box::new(php_ipv6))?;
}
@@ -376,16 +407,9 @@ impl PlatformRepository {
.unwrap_or_default();
self.add_library(
&mut libraries,
- &format!(
- "{}-openssl{}",
- name,
- if is_fips { "-fips" } else { "" }
- ),
+ &format!("{}-openssl{}", name, if is_fips { "-fips" } else { "" }),
Some(&parsed_version),
- Some(&format!(
- "curl OpenSSL version ({})",
- parsed_version
- )),
+ Some(&format!("curl OpenSSL version ({})", parsed_version)),
&[],
if is_fips {
&["curl-openssl".to_string()]
@@ -442,10 +466,9 @@ impl PlatformRepository {
}
// ZLib Version => 1.2.8
- if let Ok(Some(zlib_matches)) = Preg::is_match_strict_groups(
- "{^ZLib Version => (?<version>.+)$}im",
- &info,
- ) {
+ if let Ok(Some(zlib_matches)) =
+ Preg::is_match_strict_groups("{^ZLib Version => (?<version>.+)$}im", &info)
+ {
self.add_library(
&mut libraries,
&format!("{}-zlib", name),
@@ -486,9 +509,7 @@ impl PlatformRepository {
&info,
) {
// If the timezonedb is provided by ext/timezonedb, register that version as a replacement
- if external
- && loaded_extensions.iter().any(|n| n == "timezonedb")
- {
+ if external && loaded_extensions.iter().any(|n| n == "timezonedb") {
self.add_library(
&mut libraries,
"timezonedb-zoneinfo",
@@ -552,8 +573,8 @@ impl PlatformRepository {
"/^libJPEG Version => (?<version>.+?)(?: compatible)?$/im",
&info,
) {
- let parsed = Version::parse_libjpeg(&libjpeg_matches["version"])
- .unwrap_or_default();
+ let parsed =
+ Version::parse_libjpeg(&libjpeg_matches["version"]).unwrap_or_default();
self.add_library(
&mut libraries,
&format!("{}-libjpeg", name),
@@ -596,8 +617,7 @@ impl PlatformRepository {
"/^libXpm Version => (?<versionId>\\d+)$/im",
&info,
) {
- let version_id: i64 =
- libxpm_matches["versionId"].parse().unwrap_or(0);
+ let version_id: i64 = libxpm_matches["versionId"].parse().unwrap_or(0);
let converted =
Version::convert_libxpm_version_id(version_id).unwrap_or_default();
self.add_library(
@@ -649,8 +669,7 @@ impl PlatformRepository {
let description = "The ICU unicode and globalization support library";
// Truthy check is for testing only so we can make the condition fail
if self.runtime.has_constant("INTL_ICU_VERSION", None) {
- let intl_icu_version =
- self.runtime.get_constant("INTL_ICU_VERSION", None);
+ let intl_icu_version = self.runtime.get_constant("INTL_ICU_VERSION", None);
let intl_icu_str = match &intl_icu_version {
PhpMixed::String(s) => Some(s.clone()),
_ => None,
@@ -663,10 +682,9 @@ impl PlatformRepository {
&[],
&[],
)?;
- } else if let Ok(Some(matches)) = Preg::is_match_strict_groups(
- "/^ICU version => (?<version>.+)$/im",
- &info,
- ) {
+ } else if let Ok(Some(matches)) =
+ Preg::is_match_strict_groups("/^ICU version => (?<version>.+)$/im", &info)
+ {
self.add_library(
&mut libraries,
"icu",
@@ -740,8 +758,7 @@ impl PlatformRepository {
])],
);
let sliced = array_slice(&intl_char_versions, 0, Some(3));
- let joined =
- implode(".", &Self::php_array_to_string_vec(&sliced));
+ let joined = implode(".", &Self::php_array_to_string_vec(&sliced));
self.add_library(
&mut libraries,
"icu-unicode",
@@ -754,10 +771,7 @@ impl PlatformRepository {
}
"imagick" => {
- let image_magick_version = self.runtime.construct(
- "Imagick",
- Vec::new(),
- )?;
+ let image_magick_version = self.runtime.construct("Imagick", Vec::new())?;
// TODO(plugin): `->getVersion()` is a dynamic method call on Imagick
let image_magick_version_str =
Self::imagick_get_version_string(&image_magick_version);
@@ -791,10 +805,7 @@ impl PlatformRepository {
"/^Vendor Version => (?<versionId>\\d+)$/im",
&info,
),
- Preg::is_match_strict_groups(
- "/^Vendor Name => (?<vendor>.+)$/im",
- &info,
- ),
+ Preg::is_match_strict_groups("/^Vendor Name => (?<vendor>.+)$/im", &info),
) {
let version_id: i64 = matches["versionId"].parse().unwrap_or(0);
let converted =
@@ -1102,15 +1113,9 @@ impl PlatformRepository {
let version_built = sprintf(
"%d.%d.%d",
&[
- PhpMixed::Int(
- (lib_rd_kafka_version_int & 0x7F000000) >> 24,
- ),
- PhpMixed::Int(
- (lib_rd_kafka_version_int & 0x00FF0000) >> 16,
- ),
- PhpMixed::Int(
- (lib_rd_kafka_version_int & 0x0000FF00) >> 8,
- ),
+ PhpMixed::Int((lib_rd_kafka_version_int & 0x7F000000) >> 24),
+ PhpMixed::Int((lib_rd_kafka_version_int & 0x00FF0000) >> 16),
+ PhpMixed::Int((lib_rd_kafka_version_int & 0x0000FF00) >> 8),
],
);
self.add_library(
@@ -1236,7 +1241,10 @@ impl PlatformRepository {
}
"zip" => {
- if self.runtime.has_constant("LIBZIP_VERSION", Some("ZipArchive")) {
+ if self
+ .runtime
+ .has_constant("LIBZIP_VERSION", Some("ZipArchive"))
+ {
let libzip = self
.runtime
.get_constant("LIBZIP_VERSION", Some("ZipArchive"));
@@ -1308,8 +1316,8 @@ impl PlatformRepository {
version = v;
}
Err(_) => {
- pretty_version =
- Preg::replace("#^([^~+-]+).*$#", "$1", &hhvm_version).unwrap_or(hhvm_version);
+ pretty_version = Preg::replace("#^([^~+-]+).*$#", "$1", &hhvm_version)
+ .unwrap_or(hhvm_version);
version = self
.version_parser
.as_ref()
@@ -1373,8 +1381,10 @@ impl PlatformRepository {
name: self.overrides["php"].name.clone(),
version: self.overrides["php"].version.clone(),
};
- let mut overrider =
- self.add_overridden_package(&php_override, Some(package.get_pretty_name().to_string()))?;
+ let mut overrider = self.add_overridden_package(
+ &php_override,
+ Some(package.get_pretty_name().to_string()),
+ )?;
let actual_text = if package.get_version() == overrider.get_version() {
"same as actual".to_string()
} else {
@@ -1457,8 +1467,7 @@ impl PlatformRepository {
{
Ok(v) => v,
Err(_) => {
- extra_description =
- Some(format!(" (actual version: {})", pretty_version));
+ extra_description = Some(format!(" (actual version: {})", pretty_version));
if let Ok(Some(m)) = Preg::is_match_strict_groups(
"{^(\\d+\\.\\d+\\.\\d+(?:\\.\\d+)?)}",
&pretty_version,
@@ -1540,7 +1549,11 @@ impl PlatformRepository {
.map(|s| s.to_string())
.unwrap_or_else(|| format!("The {} library", name));
- let mut lib = CompletePackage::new(format!("lib-{}", name), version.clone(), pretty_version.to_string());
+ let mut lib = CompletePackage::new(
+ format!("lib-{}", name),
+ version.clone(),
+ pretty_version.to_string(),
+ );
lib.set_description(description);
let mut replace_links: IndexMap<String, Link> = IndexMap::new();
diff --git a/crates/shirabe/src/repository/repository_factory.rs b/crates/shirabe/src/repository/repository_factory.rs
index feb2f3d..794cd3f 100644
--- a/crates/shirabe/src/repository/repository_factory.rs
+++ b/crates/shirabe/src/repository/repository_factory.rs
@@ -2,7 +2,9 @@
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
-use shirabe_php_shim::{get_debug_type, json_encode, InvalidArgumentException, PhpMixed, UnexpectedValueException};
+use shirabe_php_shim::{
+ InvalidArgumentException, PhpMixed, UnexpectedValueException, get_debug_type, json_encode,
+};
use crate::config::Config;
use crate::event_dispatcher::event_dispatcher::EventDispatcher;
@@ -18,7 +20,12 @@ use crate::util::process_executor::ProcessExecutor;
pub struct RepositoryFactory;
impl RepositoryFactory {
- pub fn config_from_string(io: &dyn IOInterface, config: &Config, repository: &str, allow_filesystem: bool) -> anyhow::Result<IndexMap<String, PhpMixed>> {
+ pub fn config_from_string(
+ io: &dyn IOInterface,
+ config: &Config,
+ repository: &str,
+ allow_filesystem: bool,
+ ) -> anyhow::Result<IndexMap<String, PhpMixed>> {
if repository.starts_with("http") {
let mut repo_config = IndexMap::new();
repo_config.insert("type".to_string(), PhpMixed::String("composer".to_string()));
@@ -32,23 +39,35 @@ impl RepositoryFactory {
.unwrap_or("");
if extension == "json" {
- let json = JsonFile::new(repository.to_string(), Some(Factory::create_http_downloader(io, config)?));
+ let json = JsonFile::new(
+ repository.to_string(),
+ Some(Factory::create_http_downloader(io, config)?),
+ );
let data = json.read()?;
let has_packages = data.get("packages").map_or(false, |v| !v.is_null());
let has_includes = data.get("includes").map_or(false, |v| !v.is_null());
- let has_provider_includes = data.get("provider-includes").map_or(false, |v| !v.is_null());
+ let has_provider_includes = data
+ .get("provider-includes")
+ .map_or(false, |v| !v.is_null());
if has_packages || has_includes || has_provider_includes {
- let real_path = std::fs::canonicalize(repository).ok()
+ let real_path = std::fs::canonicalize(repository)
+ .ok()
.and_then(|p| p.to_str().map(|s| s.to_string()))
.unwrap_or_else(|| repository.to_string())
.replace('\\', "/");
let mut repo_config = IndexMap::new();
repo_config.insert("type".to_string(), PhpMixed::String("composer".to_string()));
- repo_config.insert("url".to_string(), PhpMixed::String(format!("file://{}", real_path)));
+ repo_config.insert(
+ "url".to_string(),
+ PhpMixed::String(format!("file://{}", real_path)),
+ );
return Ok(repo_config);
} else if allow_filesystem {
let mut repo_config = IndexMap::new();
- repo_config.insert("type".to_string(), PhpMixed::String("filesystem".to_string()));
+ repo_config.insert(
+ "type".to_string(),
+ PhpMixed::String("filesystem".to_string()),
+ );
repo_config.insert("json".to_string(), PhpMixed::String(repository.to_string()));
return Ok(repo_config);
} else {
@@ -70,12 +89,23 @@ impl RepositoryFactory {
}.into())
}
- pub fn from_string(io: &dyn IOInterface, config: &Config, repository: &str, allow_filesystem: bool, rm: Option<&mut RepositoryManager>) -> anyhow::Result<Box<dyn RepositoryInterface>> {
+ pub fn from_string(
+ io: &dyn IOInterface,
+ config: &Config,
+ repository: &str,
+ allow_filesystem: bool,
+ rm: Option<&mut RepositoryManager>,
+ ) -> anyhow::Result<Box<dyn RepositoryInterface>> {
let repo_config = Self::config_from_string(io, config, repository, allow_filesystem)?;
Self::create_repo(io, config, repo_config, rm)
}
- pub fn create_repo(io: &dyn IOInterface, config: &Config, repo_config: IndexMap<String, PhpMixed>, rm: Option<&mut RepositoryManager>) -> anyhow::Result<Box<dyn RepositoryInterface>> {
+ pub fn create_repo(
+ io: &dyn IOInterface,
+ config: &Config,
+ repo_config: IndexMap<String, PhpMixed>,
+ rm: Option<&mut RepositoryManager>,
+ ) -> anyhow::Result<Box<dyn RepositoryInterface>> {
let mut owned_rm;
let rm = if let Some(rm) = rm {
rm
@@ -83,13 +113,23 @@ impl RepositoryFactory {
owned_rm = Self::manager(io, config, None, None, None)?;
&mut owned_rm
};
- let mut repos = Self::create_repos(rm, vec![PhpMixed::Array(
- repo_config.into_iter().map(|(k, v)| (k, Box::new(v))).collect()
- )])?;
+ let mut repos = Self::create_repos(
+ rm,
+ vec![PhpMixed::Array(
+ repo_config
+ .into_iter()
+ .map(|(k, v)| (k, Box::new(v)))
+ .collect(),
+ )],
+ )?;
Ok(repos.remove(0))
}
- pub fn default_repos(io: Option<&dyn IOInterface>, config: Option<Config>, rm: Option<&mut RepositoryManager>) -> anyhow::Result<Vec<Box<dyn RepositoryInterface>>> {
+ pub fn default_repos(
+ io: Option<&dyn IOInterface>,
+ config: Option<Config>,
+ rm: Option<&mut RepositoryManager>,
+ ) -> anyhow::Result<Vec<Box<dyn RepositoryInterface>>> {
let config = match config {
Some(c) => c,
None => Factory::create_config(None, None)?,
@@ -103,10 +143,17 @@ impl RepositoryFactory {
rm
} else {
let io = io.ok_or_else(|| InvalidArgumentException {
- message: "This function requires either an IOInterface or a RepositoryManager".to_string(),
+ message: "This function requires either an IOInterface or a RepositoryManager"
+ .to_string(),
code: 0,
})?;
- owned_rm = Self::manager(io, &config, Some(Factory::create_http_downloader(io, &config)?), None, None)?;
+ owned_rm = Self::manager(
+ io,
+ &config,
+ Some(Factory::create_http_downloader(io, &config)?),
+ None,
+ None,
+ )?;
&mut owned_rm
};
@@ -114,7 +161,13 @@ impl RepositoryFactory {
Self::create_repos(rm, repo_configs)
}
- pub fn manager(io: &dyn IOInterface, config: &Config, http_downloader: Option<HttpDownloader>, event_dispatcher: Option<EventDispatcher>, process: Option<ProcessExecutor>) -> anyhow::Result<RepositoryManager> {
+ pub fn manager(
+ io: &dyn IOInterface,
+ config: &Config,
+ http_downloader: Option<HttpDownloader>,
+ event_dispatcher: Option<EventDispatcher>,
+ process: Option<ProcessExecutor>,
+ ) -> anyhow::Result<RepositoryManager> {
let http_downloader = match http_downloader {
Some(h) => h,
None => Factory::create_http_downloader(io, config)?,
@@ -148,14 +201,19 @@ impl RepositoryFactory {
Ok(rm)
}
- pub fn default_repos_with_default_manager(io: &dyn IOInterface) -> anyhow::Result<Vec<Box<dyn RepositoryInterface>>> {
+ pub fn default_repos_with_default_manager(
+ io: &dyn IOInterface,
+ ) -> anyhow::Result<Vec<Box<dyn RepositoryInterface>>> {
let config = Factory::create_config(Some(io), None)?;
let mut manager = Self::manager(io, &config, None, None, None)?;
io.load_configuration(&config);
Self::default_repos(Some(io), Some(config), Some(&mut manager))
}
- fn create_repos(rm: &mut RepositoryManager, repo_configs: Vec<PhpMixed>) -> anyhow::Result<Vec<Box<dyn RepositoryInterface>>> {
+ fn create_repos(
+ rm: &mut RepositoryManager,
+ repo_configs: Vec<PhpMixed>,
+ ) -> anyhow::Result<Vec<Box<dyn RepositoryInterface>>> {
let mut repo_map: IndexMap<String, Box<dyn RepositoryInterface>> = IndexMap::new();
for (index, repo) in repo_configs.into_iter().enumerate() {
@@ -169,27 +227,51 @@ impl RepositoryFactory {
PhpMixed::Array(repo_arr) => {
if !repo_arr.contains_key("type") {
return Err(UnexpectedValueException {
- message: format!("Repository \"{}\" ({}) must have a type defined", index, json_encode(&repo).unwrap_or_default()),
+ message: format!(
+ "Repository \"{}\" ({}) must have a type defined",
+ index,
+ json_encode(&repo).unwrap_or_default()
+ ),
code: 0,
- }.into());
+ }
+ .into());
}
- let repo_type = repo_arr.get("type").and_then(|v| v.as_string()).unwrap_or("").to_string();
- let repo_config_map: IndexMap<String, PhpMixed> = repo_arr.iter().map(|(k, v)| (k.clone(), *v.clone())).collect();
- let name = Self::generate_repository_name_indexed(index, &repo_config_map, &repo_map);
+ let repo_type = repo_arr
+ .get("type")
+ .and_then(|v| v.as_string())
+ .unwrap_or("")
+ .to_string();
+ let repo_config_map: IndexMap<String, PhpMixed> = repo_arr
+ .iter()
+ .map(|(k, v)| (k.clone(), *v.clone()))
+ .collect();
+ let name =
+ Self::generate_repository_name_indexed(index, &repo_config_map, &repo_map);
if repo_type == "filesystem" {
- let json_path = repo_arr.get("json").and_then(|v| v.as_string()).unwrap_or("").to_string();
+ let json_path = repo_arr
+ .get("json")
+ .and_then(|v| v.as_string())
+ .unwrap_or("")
+ .to_string();
repo_map.insert(name, Box::new(FilesystemRepository::new(json_path)?));
} else {
- let created = rm.create_repository(&repo_type, repo_config_map, &index.to_string())?;
+ let created =
+ rm.create_repository(&repo_type, repo_config_map, &index.to_string())?;
repo_map.insert(name, created);
}
}
_ => {
return Err(UnexpectedValueException {
- message: format!("Repository \"{}\" ({}) should be an array, {} given", index, json_encode(&repo).unwrap_or_default(), get_debug_type(&repo)),
+ message: format!(
+ "Repository \"{}\" ({}) should be an array, {} given",
+ index,
+ json_encode(&repo).unwrap_or_default(),
+ get_debug_type(&repo)
+ ),
code: 0,
- }.into());
+ }
+ .into());
}
}
}
@@ -197,7 +279,11 @@ impl RepositoryFactory {
Ok(repo_map.into_values().collect())
}
- pub fn generate_repository_name(index: &PhpMixed, repo: &IndexMap<String, PhpMixed>, existing_repos: &IndexMap<String, Box<dyn RepositoryInterface>>) -> String {
+ pub fn generate_repository_name(
+ index: &PhpMixed,
+ repo: &IndexMap<String, PhpMixed>,
+ existing_repos: &IndexMap<String, Box<dyn RepositoryInterface>>,
+ ) -> String {
let mut name = match index {
PhpMixed::Int(_) => {
if let Some(url) = repo.get("url").and_then(|v| v.as_string()) {
@@ -214,7 +300,11 @@ impl RepositoryFactory {
name
}
- fn generate_repository_name_indexed(index: usize, repo: &IndexMap<String, PhpMixed>, existing_repos: &IndexMap<String, Box<dyn RepositoryInterface>>) -> String {
+ fn generate_repository_name_indexed(
+ index: usize,
+ repo: &IndexMap<String, PhpMixed>,
+ existing_repos: &IndexMap<String, Box<dyn RepositoryInterface>>,
+ ) -> String {
let mut name = if let Some(url) = repo.get("url").and_then(|v| v.as_string()) {
Preg::replace("{^https?://}i", "", url, -1).unwrap_or_else(|_| url.to_string())
} else {
diff --git a/crates/shirabe/src/repository/repository_interface.rs b/crates/shirabe/src/repository/repository_interface.rs
index f284afd..15c85f0 100644
--- a/crates/shirabe/src/repository/repository_interface.rs
+++ b/crates/shirabe/src/repository/repository_interface.rs
@@ -1,11 +1,11 @@
//! ref: composer/src/Composer/Repository/RepositoryInterface.php
-use indexmap::IndexMap;
-use shirabe_php_shim::Countable;
-use shirabe_semver::constraint::constraint_interface::ConstraintInterface;
use crate::package::base_package::BasePackage;
use crate::package::package_interface::PackageInterface;
use crate::repository::advisory_provider_interface::AdvisoryProviderInterface;
+use indexmap::IndexMap;
+use shirabe_php_shim::Countable;
+use shirabe_semver::constraint::constraint_interface::ConstraintInterface;
pub enum FindPackageConstraint {
String(String),
@@ -42,9 +42,17 @@ pub trait RepositoryInterface: Countable {
fn has_package(&self, package: &dyn PackageInterface) -> bool;
- fn find_package(&self, name: String, constraint: FindPackageConstraint) -> Option<Box<BasePackage>>;
+ fn find_package(
+ &self,
+ name: String,
+ constraint: FindPackageConstraint,
+ ) -> Option<Box<BasePackage>>;
- fn find_packages(&self, name: String, constraint: Option<FindPackageConstraint>) -> Vec<Box<BasePackage>>;
+ fn find_packages(
+ &self,
+ name: String,
+ constraint: Option<FindPackageConstraint>,
+ ) -> Vec<Box<BasePackage>>;
fn get_packages(&self) -> Vec<Box<BasePackage>>;
diff --git a/crates/shirabe/src/repository/repository_manager.rs b/crates/shirabe/src/repository/repository_manager.rs
index fd60e7b..cc43aed 100644
--- a/crates/shirabe/src/repository/repository_manager.rs
+++ b/crates/shirabe/src/repository/repository_manager.rs
@@ -1,7 +1,7 @@
//! ref: composer/src/Composer/Repository/RepositoryManager.php
use indexmap::IndexMap;
-use shirabe_php_shim::{json_encode, InvalidArgumentException, PhpMixed};
+use shirabe_php_shim::{InvalidArgumentException, PhpMixed, json_encode};
use shirabe_semver::constraint::constraint_interface::ConstraintInterface;
use crate::config::Config;
@@ -26,7 +26,13 @@ pub struct RepositoryManager {
}
impl RepositoryManager {
- pub fn new(io: &dyn IOInterface, config: &Config, http_downloader: HttpDownloader, event_dispatcher: Option<EventDispatcher>, process: Option<ProcessExecutor>) -> Self {
+ pub fn new(
+ io: &dyn IOInterface,
+ config: &Config,
+ http_downloader: HttpDownloader,
+ event_dispatcher: Option<EventDispatcher>,
+ process: Option<ProcessExecutor>,
+ ) -> Self {
let process = process.unwrap_or_else(|| ProcessExecutor::new(io));
Self {
local_repository: None,
@@ -40,7 +46,11 @@ impl RepositoryManager {
}
}
- pub fn find_package(&self, name: &str, constraint: &dyn ConstraintInterface) -> Option<Box<dyn PackageInterface>> {
+ pub fn find_package(
+ &self,
+ name: &str,
+ constraint: &dyn ConstraintInterface,
+ ) -> Option<Box<dyn PackageInterface>> {
for repository in &self.repositories {
if let Some(package) = repository.find_package(name, constraint) {
return Some(package);
@@ -49,7 +59,11 @@ impl RepositoryManager {
None
}
- pub fn find_packages(&self, name: &str, constraint: &dyn ConstraintInterface) -> Vec<Box<dyn PackageInterface>> {
+ pub fn find_packages(
+ &self,
+ name: &str,
+ constraint: &dyn ConstraintInterface,
+ ) -> Vec<Box<dyn PackageInterface>> {
let mut packages: Vec<Box<dyn PackageInterface>> = vec![];
for repository in self.get_repositories() {
packages.extend(repository.find_packages(name, constraint));
@@ -65,23 +79,41 @@ impl RepositoryManager {
self.repositories.insert(0, repository);
}
- pub fn create_repository(&self, r#type: &str, config: IndexMap<String, PhpMixed>, name: Option<&str>) -> anyhow::Result<Box<dyn RepositoryInterface>> {
+ pub fn create_repository(
+ &self,
+ r#type: &str,
+ config: IndexMap<String, PhpMixed>,
+ name: Option<&str>,
+ ) -> anyhow::Result<Box<dyn RepositoryInterface>> {
if !self.repository_classes.contains_key(r#type) {
return Err(InvalidArgumentException {
message: format!("Repository type is not registered: {}", r#type),
code: 0,
- }.into());
+ }
+ .into());
}
if config.get("packagist").and_then(|v| v.as_bool()) == Some(false) {
- let config_json = json_encode(&PhpMixed::Array(config.iter().map(|(k, v)| (k.clone(), Box::new(v.clone()))).collect())).unwrap_or_default();
+ let config_json = json_encode(&PhpMixed::Array(
+ config
+ .iter()
+ .map(|(k, v)| (k.clone(), Box::new(v.clone())))
+ .collect(),
+ ))
+ .unwrap_or_default();
self.io.write_error(&format!("<warning>Repository \"{}\" ({}) has a packagist key which should be in its own repository definition</warning>", name.unwrap_or(""), config_json));
}
let class = self.repository_classes[r#type].clone();
- let has_filter = config.contains_key("only") || config.contains_key("exclude") || config.contains_key("canonical");
- let filter_config = if has_filter { Some(config.clone()) } else { None };
+ let has_filter = config.contains_key("only")
+ || config.contains_key("exclude")
+ || config.contains_key("canonical");
+ let filter_config = if has_filter {
+ Some(config.clone())
+ } else {
+ None
+ };
let mut cleaned_config = config;
cleaned_config.remove("only");
@@ -98,12 +130,17 @@ impl RepositoryManager {
Ok(repository)
}
- fn create_repository_by_class(&self, _class: &str, _config: IndexMap<String, PhpMixed>) -> anyhow::Result<Box<dyn RepositoryInterface>> {
+ fn create_repository_by_class(
+ &self,
+ _class: &str,
+ _config: IndexMap<String, PhpMixed>,
+ ) -> anyhow::Result<Box<dyn RepositoryInterface>> {
todo!("Phase B: dynamic class instantiation by class name")
}
pub fn set_repository_class(&mut self, r#type: &str, class: &str) {
- self.repository_classes.insert(r#type.to_string(), class.to_string());
+ self.repository_classes
+ .insert(r#type.to_string(), class.to_string());
}
pub fn get_repositories(&self) -> &Vec<Box<dyn RepositoryInterface>> {
diff --git a/crates/shirabe/src/repository/repository_set.rs b/crates/shirabe/src/repository/repository_set.rs
index 7134ed7..e25bd29 100644
--- a/crates/shirabe/src/repository/repository_set.rs
+++ b/crates/shirabe/src/repository/repository_set.rs
@@ -5,8 +5,8 @@ use std::any::Any;
use anyhow::Result;
use indexmap::IndexMap;
use shirabe_php_shim::{
- array_merge, array_merge_recursive, ksort, strtolower, LogicException, PhpMixed,
- RuntimeException,
+ LogicException, PhpMixed, RuntimeException, array_merge, array_merge_recursive, ksort,
+ strtolower,
};
use shirabe_semver::constraint::constraint::Constraint;
use shirabe_semver::constraint::constraint_interface::ConstraintInterface;
@@ -184,7 +184,11 @@ impl RepositorySet {
(repo.as_any() as &dyn Any).downcast_ref::<CompositeRepository>()
{
// TODO(phase-b): clone composite.get_repositories() — Box<dyn RepositoryInterface> cloning
- composite.get_repositories().iter().map(|r| r.clone_box()).collect()
+ composite
+ .get_repositories()
+ .iter()
+ .map(|r| r.clone_box())
+ .collect()
} else {
vec![repo]
};
@@ -479,7 +483,8 @@ impl RepositorySet {
.is_some();
if is_installed && !self.allow_installed_repositories {
return Err(LogicException {
- message: "The pool can not accept packages from an installed repository".to_string(),
+ message: "The pool can not accept packages from an installed repository"
+ .to_string(),
code: 0,
}
.into());
@@ -503,7 +508,8 @@ impl RepositorySet {
.is_some();
if is_installed && !self.allow_installed_repositories {
return Err(LogicException {
- message: "The pool can not accept packages from an installed repository".to_string(),
+ message: "The pool can not accept packages from an installed repository"
+ .to_string(),
code: 0,
}
.into());
@@ -548,7 +554,14 @@ impl RepositorySet {
}
// TODO(phase-b): Pool::new signature
- Ok(Pool::new(packages, vec![], IndexMap::new(), IndexMap::new(), IndexMap::new(), IndexMap::new()))
+ Ok(Pool::new(
+ packages,
+ vec![],
+ IndexMap::new(),
+ IndexMap::new(),
+ IndexMap::new(),
+ IndexMap::new(),
+ ))
}
pub fn create_pool_for_package(
@@ -587,7 +600,15 @@ impl RepositorySet {
request.restrict_packages(allowed_packages);
}
- self.create_pool(request, Box::new(NullIO::new()), None, None, vec![], None, None)
+ self.create_pool(
+ request,
+ Box::new(NullIO::new()),
+ None,
+ None,
+ vec![],
+ None,
+ None,
+ )
}
/// @param array[] $aliases
diff --git a/crates/shirabe/src/repository/repository_utils.rs b/crates/shirabe/src/repository/repository_utils.rs
index 1ca98ee..526fae7 100644
--- a/crates/shirabe/src/repository/repository_utils.rs
+++ b/crates/shirabe/src/repository/repository_utils.rs
@@ -1,12 +1,12 @@
//! ref: composer/src/Composer/Repository/RepositoryUtils.php
-use std::any::Any;
-use indexmap::IndexMap;
use crate::package::link::Link;
use crate::package::package_interface::PackageInterface;
use crate::repository::composite_repository::CompositeRepository;
use crate::repository::filter_repository::FilterRepository;
use crate::repository::repository_interface::RepositoryInterface;
+use indexmap::IndexMap;
+use std::any::Any;
pub struct RepositoryUtils;
@@ -33,7 +33,12 @@ impl RepositoryUtils {
});
if !already_in_bucket {
bucket.push(candidate.clone_box());
- bucket = Self::filter_required_packages(packages, candidate.as_ref(), false, bucket);
+ bucket = Self::filter_required_packages(
+ packages,
+ candidate.as_ref(),
+ false,
+ bucket,
+ );
}
break;
}
@@ -48,7 +53,9 @@ impl RepositoryUtils {
unwrap_filter_repos: bool,
) -> Vec<Box<dyn RepositoryInterface>> {
let repo: Box<dyn RepositoryInterface> = if unwrap_filter_repos {
- if let Some(filter_repo) = (repo.as_any() as &dyn Any).downcast_ref::<FilterRepository>() {
+ if let Some(filter_repo) =
+ (repo.as_any() as &dyn Any).downcast_ref::<FilterRepository>()
+ {
filter_repo.get_repository()
} else {
repo
@@ -57,7 +64,9 @@ impl RepositoryUtils {
repo
};
- if let Some(composite_repo) = (repo.as_any() as &dyn Any).downcast_ref::<CompositeRepository>() {
+ if let Some(composite_repo) =
+ (repo.as_any() as &dyn Any).downcast_ref::<CompositeRepository>()
+ {
let mut repos = Vec::new();
for r in composite_repo.get_repositories() {
for r2 in Self::flatten_repositories(r, unwrap_filter_repos) {
diff --git a/crates/shirabe/src/repository/vcs/forgejo_driver.rs b/crates/shirabe/src/repository/vcs/forgejo_driver.rs
index 5d482b2..74f1e11 100644
--- a/crates/shirabe/src/repository/vcs/forgejo_driver.rs
+++ b/crates/shirabe/src/repository/vcs/forgejo_driver.rs
@@ -4,7 +4,7 @@ use anyhow::Result;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- base64_decode, extension_loaded, explode, urlencode, PhpMixed, RuntimeException,
+ PhpMixed, RuntimeException, base64_decode, explode, extension_loaded, urlencode,
};
use crate::cache::Cache;
@@ -215,8 +215,7 @@ impl ForgejoDriver {
if self.branches.is_none() {
let mut branches = IndexMap::new();
let api_url = self.forgejo_url.as_ref().unwrap().api_url.clone();
- let mut resource: Option<String> =
- Some(format!("{}/branches?per_page=100", api_url));
+ let mut resource: Option<String> = Some(format!("{}/branches?per_page=100", api_url));
while let Some(url) = resource {
let response = self
@@ -259,8 +258,7 @@ impl ForgejoDriver {
if self.tags.is_none() {
let mut tags = IndexMap::new();
let api_url = self.forgejo_url.as_ref().unwrap().api_url.clone();
- let mut resource: Option<String> =
- Some(format!("{}/tags?per_page=100", api_url));
+ let mut resource: Option<String> = Some(format!("{}/tags?per_page=100", api_url));
while let Some(url) = resource {
let response = self
@@ -330,7 +328,10 @@ impl ForgejoDriver {
shirabe_php_shim::JSON_UNESCAPED_UNICODE
| shirabe_php_shim::JSON_UNESCAPED_SLASHES,
);
- self.inner.cache.as_ref().map(|c| c.write(identifier, &encoded));
+ self.inner
+ .cache
+ .as_ref()
+ .map(|c| c.write(identifier, &encoded));
}
}
c
@@ -347,8 +348,7 @@ impl ForgejoDriver {
.get("support")
.map_or(false, |v| v.as_array().is_none());
if support_not_array {
- composer_map
- .insert("support".to_string(), PhpMixed::Array(IndexMap::new()));
+ composer_map.insert("support".to_string(), PhpMixed::Array(IndexMap::new()));
}
let has_source = composer_map
@@ -366,28 +366,26 @@ impl ForgejoDriver {
let tags = self.get_tags()?;
let branches = self.get_branches()?;
- let source_url = if let Some(label) =
- tags.into_iter().find(|(_, v)| v == identifier).map(|(k, _)| k)
+ let source_url = if let Some(label) = tags
+ .into_iter()
+ .find(|(_, v)| v == identifier)
+ .map(|(k, _)| k)
{
format!("{}/tag/{}", html_url, label)
- } else if let Some(label) =
- branches
- .into_iter()
- .find(|(_, v)| v == identifier)
- .map(|(k, _)| k)
+ } else if let Some(label) = branches
+ .into_iter()
+ .find(|(_, v)| v == identifier)
+ .map(|(k, _)| k)
{
format!("{}/branch/{}", html_url, label)
} else {
format!("{}/commit/{}", html_url, identifier)
};
- if let Some(PhpMixed::Array(ref mut support)) =
- composer_map.get_mut("support")
+ if let Some(PhpMixed::Array(ref mut support)) = composer_map.get_mut("support")
{
- support.insert(
- "source".to_string(),
- Box::new(PhpMixed::String(source_url)),
- );
+ support
+ .insert("source".to_string(), Box::new(PhpMixed::String(source_url)));
}
}
@@ -409,13 +407,10 @@ impl ForgejoDriver {
.map(|r| r.html_url.clone())
.unwrap_or_default()
);
- if let Some(PhpMixed::Array(ref mut support)) =
- composer_map.get_mut("support")
+ if let Some(PhpMixed::Array(ref mut support)) = composer_map.get_mut("support")
{
- support.insert(
- "issues".to_string(),
- Box::new(PhpMixed::String(issues_url)),
- );
+ support
+ .insert("issues".to_string(), Box::new(PhpMixed::String(issues_url)));
}
}
@@ -429,10 +424,16 @@ impl ForgejoDriver {
}
}
- self.inner.info_cache.insert(identifier.to_string(), composer);
+ self.inner
+ .info_cache
+ .insert(identifier.to_string(), composer);
}
- Ok(self.inner.info_cache.get(identifier).and_then(|v| v.clone()))
+ Ok(self
+ .inner
+ .info_cache
+ .get(identifier)
+ .and_then(|v| v.clone()))
}
pub fn get_source(&mut self, identifier: &str) -> IndexMap<String, String> {
@@ -470,8 +471,9 @@ impl ForgejoDriver {
let forgejo_domains = config.get("forgejo-domains");
let in_domains = if let Some(list) = forgejo_domains.as_list() {
list.iter().any(|d| {
- d.as_string()
- .map_or(false, |s| s.to_lowercase() == forgejo_url.origin_url.to_lowercase())
+ d.as_string().map_or(false, |s| {
+ s.to_lowercase() == forgejo_url.origin_url.to_lowercase()
+ })
})
} else {
false
@@ -570,82 +572,73 @@ impl ForgejoDriver {
) -> anyhow::Result<Response, TransportException> {
match self.inner.get_contents(url) {
Ok(response) => Ok(response),
- Err(e) => {
- match e.get_code() {
- 401 | 403 | 404 | 429 => {
- if !fetching_repo_data {
- return Err(e);
- }
+ Err(e) => match e.get_code() {
+ 401 | 403 | 404 | 429 => {
+ if !fetching_repo_data {
+ return Err(e);
+ }
- if !self.inner.io.is_interactive() {
- self.attempt_clone_fallback()
- .map_err(|inner_e| TransportException {
- message: inner_e.to_string(),
- code: 0,
- headers: None,
- response: None,
- status_code: None,
- response_info: vec![],
- })?;
+ if !self.inner.io.is_interactive() {
+ self.attempt_clone_fallback()
+ .map_err(|inner_e| TransportException {
+ message: inner_e.to_string(),
+ code: 0,
+ headers: None,
+ response: None,
+ status_code: None,
+ response_info: vec![],
+ })?;
- return Ok(Response::new(
- {
- let mut m = IndexMap::new();
- m.insert(
- "url".to_string(),
- PhpMixed::String("dummy".to_string()),
- );
- m
- },
- Some(200),
- vec![],
- Some("null".to_string()),
- )
- .unwrap()
- .unwrap());
- }
+ return Ok(Response::new(
+ {
+ let mut m = IndexMap::new();
+ m.insert("url".to_string(), PhpMixed::String("dummy".to_string()));
+ m
+ },
+ Some(200),
+ vec![],
+ Some("null".to_string()),
+ )
+ .unwrap()
+ .unwrap());
+ }
- if !self.inner.io.has_authentication(&self.inner.origin_url) {
- let origin_url =
- self.forgejo_url.as_ref().unwrap().origin_url.clone();
- let message = if e.get_code() == 429 {
- Some(format!(
- "API limit exhausted. Enter your Forgejo credentials to get a larger API limit (<info>{}</info>)",
- self.inner.url
- ))
- } else {
- None
- };
+ if !self.inner.io.has_authentication(&self.inner.origin_url) {
+ let origin_url = self.forgejo_url.as_ref().unwrap().origin_url.clone();
+ let message = if e.get_code() == 429 {
+ Some(format!(
+ "API limit exhausted. Enter your Forgejo credentials to get a larger API limit (<info>{}</info>)",
+ self.inner.url
+ ))
+ } else {
+ None
+ };
- let mut forgejo = Forgejo::new(
- todo!("clone io for Forgejo OAuth"),
- self.inner.config.clone(),
- self.inner.http_downloader.clone(),
- );
- let auth_result = forgejo
- .authorize_o_auth_interactively(
- &origin_url,
- message.as_deref(),
- )
- .map_err(|inner_e| TransportException {
- message: inner_e.to_string(),
- code: 0,
- headers: None,
- response: None,
- status_code: None,
- response_info: vec![],
- })?;
+ let mut forgejo = Forgejo::new(
+ todo!("clone io for Forgejo OAuth"),
+ self.inner.config.clone(),
+ self.inner.http_downloader.clone(),
+ );
+ let auth_result = forgejo
+ .authorize_o_auth_interactively(&origin_url, message.as_deref())
+ .map_err(|inner_e| TransportException {
+ message: inner_e.to_string(),
+ code: 0,
+ headers: None,
+ response: None,
+ status_code: None,
+ response_info: vec![],
+ })?;
- if let Ok(true) = auth_result {
- return self.inner.get_contents(url);
- }
+ if let Ok(true) = auth_result {
+ return self.inner.get_contents(url);
}
-
- Err(e)
}
- _ => Err(e),
+
+ Err(e)
}
- }
+ _ => Err(e),
+ },
}
}
diff --git a/crates/shirabe/src/repository/vcs/fossil_driver.rs b/crates/shirabe/src/repository/vcs/fossil_driver.rs
index da81548..6e99f5f 100644
--- a/crates/shirabe/src/repository/vcs/fossil_driver.rs
+++ b/crates/shirabe/src/repository/vcs/fossil_driver.rs
@@ -3,7 +3,7 @@
use chrono::{DateTime, Utc};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
-use shirabe_php_shim::{dirname, is_dir, is_file, is_writable, PhpMixed, RuntimeException};
+use shirabe_php_shim::{PhpMixed, RuntimeException, dirname, is_dir, is_file, is_writable};
use crate::cache::Cache;
use crate::config::Config;
@@ -28,15 +28,29 @@ impl FossilDriver {
self.check_fossil()?;
// Ensure we are allowed to use this URL by config.
- self.inner.config.prohibit_url_by_config(&self.inner.url, &*self.inner.io)?;
+ self.inner
+ .config
+ .prohibit_url_by_config(&self.inner.url, &*self.inner.io)?;
// Only if url points to a locally accessible directory, assume it's the checkout directory.
// Otherwise, it should be something fossil can clone from.
if Filesystem::is_local_path(&self.inner.url) && is_dir(&self.inner.url) {
self.checkout_dir = self.inner.url.clone();
} else {
- let cache_repo_dir = self.inner.config.get("cache-repo-dir").as_string().unwrap_or("").to_string();
- let cache_vcs_dir = self.inner.config.get("cache-vcs-dir").as_string().unwrap_or("").to_string();
+ let cache_repo_dir = self
+ .inner
+ .config
+ .get("cache-repo-dir")
+ .as_string()
+ .unwrap_or("")
+ .to_string();
+ let cache_vcs_dir = self
+ .inner
+ .config
+ .get("cache-vcs-dir")
+ .as_string()
+ .unwrap_or("")
+ .to_string();
if !Cache::is_usable(&cache_repo_dir) || !Cache::is_usable(&cache_vcs_dir) {
return Err(RuntimeException {
message: "FossilDriver requires a usable cache directory, and it looks like you set it to be disabled".to_string(),
diff --git a/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs b/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs
index 495b427..dc3b5f3 100644
--- a/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs
+++ b/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs
@@ -5,9 +5,9 @@ use chrono::{DateTime, Utc};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- array_key_exists, array_search_mixed, extension_loaded, http_build_query_mixed, implode,
- in_array, is_array, sprintf, strpos, InvalidArgumentException, LogicException, PhpMixed,
- RuntimeException,
+ InvalidArgumentException, LogicException, PhpMixed, RuntimeException, array_key_exists,
+ array_search_mixed, extension_loaded, http_build_query_mixed, implode, in_array, is_array,
+ sprintf, strpos,
};
use crate::cache::Cache;
@@ -94,11 +94,13 @@ impl GitBitbucketDriver {
),
None,
));
- self.inner
- .cache
- .as_mut()
- .unwrap()
- .set_read_only(self.inner.config.get("cache-read-only").as_bool().unwrap_or(false));
+ self.inner.cache.as_mut().unwrap().set_read_only(
+ self.inner
+ .config
+ .get("cache-read-only")
+ .as_bool()
+ .unwrap_or(false),
+ );
Ok(())
}
@@ -153,7 +155,11 @@ impl GitBitbucketDriver {
self.parse_clone_urls(clone_links);
self.has_issues = !shirabe_php_shim::empty(
- repo_data.get("has_issues").cloned().as_ref().unwrap_or(&PhpMixed::Null),
+ repo_data
+ .get("has_issues")
+ .cloned()
+ .as_ref()
+ .unwrap_or(&PhpMixed::Null),
);
self.branches_url = repo_data
.get("links")
@@ -214,21 +220,19 @@ impl GitBitbucketDriver {
if !self.inner.info_cache.contains_key(identifier) {
let mut composer: Option<IndexMap<String, PhpMixed>> = None;
- if self.inner.should_cache(identifier)
- && {
- let res = self
- .inner
- .cache
- .as_ref()
- .and_then(|c| c.read(identifier).ok().flatten());
- if let Some(res) = res {
- composer = Some(JsonFile::parse_json(&res, None)?);
- true
- } else {
- false
- }
+ if self.inner.should_cache(identifier) && {
+ let res = self
+ .inner
+ .cache
+ .as_ref()
+ .and_then(|c| c.read(identifier).ok().flatten());
+ if let Some(res) = res {
+ composer = Some(JsonFile::parse_json(&res, None)?);
+ true
+ } else {
+ false
}
- {
+ } {
// composer already set above
} else {
composer = self.inner.get_base_composer_information(identifier)?;
@@ -258,10 +262,7 @@ impl GitBitbucketDriver {
if composer_map.contains_key("support")
&& !is_array(composer_map.get("support").unwrap())
{
- composer_map.insert(
- "support".to_string(),
- PhpMixed::Array(IndexMap::new()),
- );
+ composer_map.insert("support".to_string(), PhpMixed::Array(IndexMap::new()));
}
let support_has_source = composer_map
.get("support")
@@ -379,18 +380,16 @@ impl GitBitbucketDriver {
composer = Some(composer_map);
}
- self.inner.info_cache.insert(identifier.to_string(), composer);
+ self.inner
+ .info_cache
+ .insert(identifier.to_string(), composer);
}
Ok(self.inner.info_cache.get(identifier).cloned().flatten())
}
/// @inheritDoc
- pub fn get_file_content(
- &mut self,
- file: &str,
- identifier: &str,
- ) -> Result<Option<String>> {
+ pub fn get_file_content(&mut self, file: &str, identifier: &str) -> Result<Option<String>> {
if let Some(fallback) = self.fallback_driver.as_mut() {
return fallback.get_file_content(file, identifier);
}
@@ -446,10 +445,7 @@ impl GitBitbucketDriver {
.decode_json()?;
// TODO(phase-b): port PHP `new \DateTimeImmutable($commit['date'])`
- let date_str = commit
- .get("date")
- .and_then(|v| v.as_string())
- .unwrap_or("");
+ let date_str = commit.get("date").and_then(|v| v.as_string()).unwrap_or("");
let date: DateTime<Utc> = chrono::DateTime::parse_from_rfc3339(date_str)
.map_err(|e| anyhow::anyhow!(e))?
.with_timezone(&Utc);
@@ -513,9 +509,7 @@ impl GitBitbucketDriver {
m.insert("pagelen".to_string(), PhpMixed::Int(100));
m.insert(
"fields".to_string(),
- PhpMixed::String(
- "values.name,values.target.hash,next".to_string(),
- ),
+ PhpMixed::String("values.name,values.target.hash,next".to_string()),
);
m.insert(
"sort".to_string(),
@@ -556,7 +550,11 @@ impl GitBitbucketDriver {
}
}
if shirabe_php_shim::empty(
- tags_data.get("next").cloned().as_ref().unwrap_or(&PhpMixed::Null),
+ tags_data
+ .get("next")
+ .cloned()
+ .as_ref()
+ .unwrap_or(&PhpMixed::Null),
) {
has_next = false;
} else {
@@ -593,8 +591,7 @@ impl GitBitbucketDriver {
m.insert(
"fields".to_string(),
PhpMixed::String(
- "values.name,values.target.hash,values.heads,next"
- .to_string(),
+ "values.name,values.target.hash,values.heads,next".to_string(),
),
);
m.insert(
@@ -636,7 +633,11 @@ impl GitBitbucketDriver {
}
}
if shirabe_php_shim::empty(
- branch_data.get("next").cloned().as_ref().unwrap_or(&PhpMixed::Null),
+ branch_data
+ .get("next")
+ .cloned()
+ .as_ref()
+ .unwrap_or(&PhpMixed::Null),
) {
has_next = false;
} else {
@@ -684,7 +685,9 @@ impl GitBitbucketDriver {
true,
);
if in_set
- || (401 == code && strpos(te.get_message(), "Could not authenticate against") == Some(0))
+ || (401 == code
+ && strpos(te.get_message(), "Could not authenticate against")
+ == Some(0))
{
if !self.inner.io.has_authentication(&self.inner.origin_url)
&& bitbucket_util.authorize_oauth(&self.inner.origin_url)
@@ -696,11 +699,14 @@ impl GitBitbucketDriver {
self.attempt_clone_fallback()?;
let mut headers: IndexMap<String, PhpMixed> = IndexMap::new();
- headers.insert(
- "url".to_string(),
- PhpMixed::String("dummy".to_string()),
- );
- return Ok(Response::new(headers, 200, IndexMap::new(), "null".to_string()));
+ headers
+ .insert("url".to_string(), PhpMixed::String("dummy".to_string()));
+ return Ok(Response::new(
+ headers,
+ 200,
+ IndexMap::new(),
+ "null".to_string(),
+ ));
}
}
}
@@ -785,9 +791,8 @@ impl GitBitbucketDriver {
if !self.get_repo_data()? {
if self.fallback_driver.is_none() {
return Err(LogicException {
- message:
- "A fallback driver should be setup if getRepoData returns false"
- .to_string(),
+ message: "A fallback driver should be setup if getRepoData returns false"
+ .to_string(),
code: 0,
}
.into());
@@ -823,12 +828,7 @@ impl GitBitbucketDriver {
}
/// @inheritDoc
- pub fn supports(
- io: &dyn IOInterface,
- _config: &Config,
- url: &str,
- _deep: bool,
- ) -> bool {
+ pub fn supports(io: &dyn IOInterface, _config: &Config, url: &str, _deep: bool) -> bool {
if !Preg::is_match(
r"#^https?://bitbucket\.org/([^/]+)/([^/]+?)(\.git|/?)?$#i",
url,
diff --git a/crates/shirabe/src/repository/vcs/git_driver.rs b/crates/shirabe/src/repository/vcs/git_driver.rs
index 5e2e547..0f8f841 100644
--- a/crates/shirabe/src/repository/vcs/git_driver.rs
+++ b/crates/shirabe/src/repository/vcs/git_driver.rs
@@ -5,8 +5,8 @@ use chrono::{DateTime, Utc};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- dirname, is_dir, is_writable, realpath, sys_get_temp_dir, InvalidArgumentException,
- RuntimeException,
+ InvalidArgumentException, RuntimeException, dirname, is_dir, is_writable, realpath,
+ sys_get_temp_dir,
};
use crate::cache::Cache;
@@ -31,8 +31,7 @@ impl GitDriver {
pub fn initialize(&mut self) -> anyhow::Result<()> {
let cache_url;
if Filesystem::is_local_path(&self.inner.url) {
- self.inner.url =
- Preg::replace(r"{[\\/]\.git/?$}", "", self.inner.url.clone())?;
+ self.inner.url = Preg::replace(r"{[\\/]\.git/?$}", "", self.inner.url.clone())?;
if !is_dir(&self.inner.url) {
return Err(RuntimeException {
message: format!(
@@ -64,11 +63,7 @@ impl GitDriver {
self.repo_dir = format!(
"{}/{}/",
cache_vcs_dir,
- Preg::replace(
- r"{[^a-z0-9.]}i",
- "-",
- Url::sanitize(self.inner.url.clone())
- )?
+ Preg::replace(r"{[^a-z0-9.]}i", "-", Url::sanitize(self.inner.url.clone()))?
);
GitUtil::clean_env(&self.inner.process);
@@ -88,9 +83,7 @@ impl GitDriver {
.into());
}
- if Preg::is_match(r"{^ssh://[^@]+@[^:]+:[^0-9]+}", &self.inner.url)
- .unwrap_or(false)
- {
+ if Preg::is_match(r"{^ssh://[^@]+@[^:]+:[^0-9]+}", &self.inner.url).unwrap_or(false) {
return Err(InvalidArgumentException {
message: format!(
"The source URL {} is invalid, ssh URLs should have a port number after \":\".\nUse ssh://git@example.com:22/path or just git@example.com:path if you do not want to provide a password or custom port.",
@@ -173,11 +166,8 @@ impl GitDriver {
&Filesystem::new(),
);
if !Filesystem::is_local_path(&self.inner.url) {
- let default_branch = git_util.get_mirror_default_branch(
- &self.inner.url,
- &self.repo_dir,
- false,
- )?;
+ let default_branch =
+ git_util.get_mirror_default_branch(&self.inner.url, &self.repo_dir, false)?;
if let Some(branch) = default_branch {
self.root_identifier = Some(branch.clone());
return Ok(branch);
@@ -198,9 +188,7 @@ impl GitDriver {
if !branches.contains(&"* master".to_string()) {
for branch in &branches {
if !branch.is_empty() {
- if let Some(caps) =
- Preg::match_strict_groups(r"{^\* +(\S+)}", branch)
- {
+ if let Some(caps) = Preg::match_strict_groups(r"{^\* +(\S+)}", branch) {
if let Some(name) = caps.get("1") {
self.root_identifier = Some(name.clone());
break;
@@ -264,10 +252,7 @@ impl GitDriver {
Ok(Some(content))
}
- pub fn get_change_date(
- &mut self,
- identifier: &str,
- ) -> anyhow::Result<Option<DateTime<Utc>>> {
+ pub fn get_change_date(&mut self, identifier: &str) -> anyhow::Result<Option<DateTime<Utc>>> {
if identifier.starts_with('-') {
return Err(RuntimeException {
message: format!(
@@ -292,8 +277,7 @@ impl GitDriver {
.process
.execute(&command, &mut output, Some(self.repo_dir.clone()));
- let timestamp_str =
- GitUtil::parse_rev_list_output(&output, &self.inner.process);
+ let timestamp_str = GitUtil::parse_rev_list_output(&output, &self.inner.process);
let timestamp: i64 = timestamp_str.trim().parse().unwrap_or(0);
Ok(Some(Utc.timestamp_opt(timestamp, 0).unwrap()))
}
@@ -319,9 +303,7 @@ impl GitDriver {
r"{^([a-f0-9]{40}) refs/tags/(\S+?)(\^\{\})?$}",
&tag,
) {
- if let (Some(hash), Some(name)) =
- (caps.get("1"), caps.get("2"))
- {
+ if let (Some(hash), Some(name)) = (caps.get("1"), caps.get("2")) {
self.tags
.as_mut()
.unwrap()
@@ -359,8 +341,7 @@ impl GitDriver {
r"{^(?:\* )? *(\S+) *([a-f0-9]+)(?: .*)?$}",
&branch,
) {
- if let (Some(name), Some(hash)) = (caps.get("1"), caps.get("2"))
- {
+ if let (Some(name), Some(hash)) = (caps.get("1"), caps.get("2")) {
if !name.starts_with('-') {
branches.insert(name.clone(), hash.clone());
}
diff --git a/crates/shirabe/src/repository/vcs/github_driver.rs b/crates/shirabe/src/repository/vcs/github_driver.rs
index a75e2a0..bd2e2ad 100644
--- a/crates/shirabe/src/repository/vcs/github_driver.rs
+++ b/crates/shirabe/src/repository/vcs/github_driver.rs
@@ -5,9 +5,9 @@ use chrono::{DateTime, Utc};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- array_diff, array_key_exists, array_map, array_search_mixed, base64_decode, basename, count,
- empty, explode, extension_loaded, in_array, parse_url_all, sprintf, strpos, strtolower, substr,
- trim, urlencode, InvalidArgumentException, PhpMixed, RuntimeException,
+ InvalidArgumentException, PhpMixed, RuntimeException, array_diff, array_key_exists, array_map,
+ array_search_mixed, base64_decode, basename, count, empty, explode, extension_loaded, in_array,
+ parse_url_all, sprintf, strpos, strtolower, substr, trim, urlencode,
};
use crate::cache::Cache;
@@ -255,10 +255,7 @@ impl GitHubDriver {
if composer.contains_key("support")
&& !matches!(composer.get("support"), Some(PhpMixed::Array(_)))
{
- composer.insert(
- "support".to_string(),
- PhpMixed::Array(IndexMap::new()),
- );
+ composer.insert("support".to_string(), PhpMixed::Array(IndexMap::new()));
}
let support_source_missing = !composer
.get("support")
@@ -294,12 +291,10 @@ impl GitHubDriver {
.filter(|v| !matches!(v, PhpMixed::Bool(false) | PhpMixed::Null))
.unwrap_or_else(|| PhpMixed::String(identifier.to_string()));
let label_str = label.as_string().unwrap_or(identifier).to_string();
- if let Some(support) =
- composer.get_mut("support").and_then(|v| match v {
- PhpMixed::Array(m) => Some(m),
- _ => None,
- })
- {
+ if let Some(support) = composer.get_mut("support").and_then(|v| match v {
+ PhpMixed::Array(m) => Some(m),
+ _ => None,
+ }) {
support.insert(
"source".to_string(),
Box::new(PhpMixed::String(sprintf(
@@ -320,12 +315,10 @@ impl GitHubDriver {
.map(|m| m.contains_key("issues"))
.unwrap_or(false);
if issues_missing && self.has_issues {
- if let Some(support) =
- composer.get_mut("support").and_then(|v| match v {
- PhpMixed::Array(m) => Some(m),
- _ => None,
- })
- {
+ if let Some(support) = composer.get_mut("support").and_then(|v| match v {
+ PhpMixed::Array(m) => Some(m),
+ _ => None,
+ }) {
support.insert(
"issues".to_string(),
Box::new(PhpMixed::String(sprintf(
@@ -390,15 +383,10 @@ impl GitHubDriver {
] {
let mut options: IndexMap<String, PhpMixed> = IndexMap::new();
options.insert("retry-auth-failure".to_string(), PhpMixed::Bool(false));
- let response = self
- .inner
- .http_downloader
- .get(file_url, &PhpMixed::Array(
- options
- .into_iter()
- .map(|(k, v)| (k, Box::new(v)))
- .collect(),
- ));
+ let response = self.inner.http_downloader.get(
+ file_url,
+ &PhpMixed::Array(options.into_iter().map(|(k, v)| (k, Box::new(v))).collect()),
+ );
let response = match response {
Ok(r) => r,
Err(_) => continue,
@@ -417,10 +405,8 @@ impl GitHubDriver {
.and_then(|v| v.as_string())
.map(|s| s.is_empty())
.unwrap_or(true);
- let encoding_not_base64 = response_map
- .get("encoding")
- .and_then(|v| v.as_string())
- != Some("base64");
+ let encoding_not_base64 =
+ response_map.get("encoding").and_then(|v| v.as_string()) != Some("base64");
if content_empty || encoding_not_base64 {
continue;
}
@@ -451,23 +437,18 @@ impl GitHubDriver {
let mut key: Option<String> = None;
for line in Preg::split(r"{\r?\n}", &funding) {
let line = trim(&line, None);
- if let Some(m) =
- Preg::is_match_strict_groups(r"{^(\w+)\s*:\s*(.+)$}", &line)
- {
+ if let Some(m) = Preg::is_match_strict_groups(r"{^(\w+)\s*:\s*(.+)$}", &line) {
let g1 = m.get(1).cloned().unwrap_or_default();
let g2 = m.get(2).cloned().unwrap_or_default();
if g2 == "[" {
key = Some(g1);
continue;
}
- if let Some(m2) = Preg::is_match_strict_groups(
- r"{^\[(.*?)\](?:\s*#.*)?$}",
- &g2,
- ) {
+ if let Some(m2) = Preg::is_match_strict_groups(r"{^\[(.*?)\](?:\s*#.*)?$}", &g2) {
let inner = m2.get(1).cloned().unwrap_or_default();
for item in array_map(
|s: &String| trim(s, None),
- &Preg::split(r"{[\'\"]?\s*,\s*[\'\"]?}", &inner),
+ &Preg::split(r#"{[\'\"]?\s*,\s*[\'\"]?}"#, &inner),
) {
let mut entry = IndexMap::new();
entry.insert("type".to_string(), PhpMixed::String(g1.clone()));
@@ -477,10 +458,9 @@ impl GitHubDriver {
);
result.push(entry);
}
- } else if let Some(m2) = Preg::is_match_strict_groups(
- r"{^([^#].*?)(?:\s+#.*)?$}",
- &g2,
- ) {
+ } else if let Some(m2) =
+ Preg::is_match_strict_groups(r"{^([^#].*?)(?:\s+#.*)?$}", &g2)
+ {
let mut entry = IndexMap::new();
entry.insert("type".to_string(), PhpMixed::String(g1.clone()));
entry.insert(
@@ -493,15 +473,11 @@ impl GitHubDriver {
result.push(entry);
}
key = None;
- } else if let Some(m) =
- Preg::is_match_strict_groups(r"{^(\w+)\s*:\s*#\s*$}", &line)
- {
+ } else if let Some(m) = Preg::is_match_strict_groups(r"{^(\w+)\s*:\s*#\s*$}", &line) {
key = Some(m.get(1).cloned().unwrap_or_default());
} else if key.is_some()
- && (Preg::is_match_strict_groups(r"{^-\s*(.+)(?:\s+#.*)?$}", &line)
- .is_some()
- || Preg::is_match_strict_groups(r"{^(.+),(?:\s*#.*)?$}", &line)
- .is_some())
+ && (Preg::is_match_strict_groups(r"{^-\s*(.+)(?:\s+#.*)?$}", &line).is_some()
+ || Preg::is_match_strict_groups(r"{^(.+),(?:\s*#.*)?$}", &line).is_some())
{
let m = Preg::is_match_strict_groups(r"{^-\s*(.+)(?:\s+#.*)?$}", &line)
.or_else(|| Preg::is_match_strict_groups(r"{^(.+),(?:\s*#.*)?$}", &line))
@@ -513,10 +489,7 @@ impl GitHubDriver {
);
entry.insert(
"url".to_string(),
- PhpMixed::String(trim(
- &m.get(1).cloned().unwrap_or_default(),
- Some("\"' "),
- )),
+ PhpMixed::String(trim(&m.get(1).cloned().unwrap_or_default(), Some("\"' "))),
);
result.push(entry);
} else if key.is_some() && line == "]" {
@@ -568,10 +541,7 @@ impl GitHubDriver {
"liberapay" => {
result[key_idx].insert(
"url".to_string(),
- PhpMixed::String(format!(
- "https://liberapay.com/{}",
- basename(&item_url)
- )),
+ PhpMixed::String(format!("https://liberapay.com/{}", basename(&item_url))),
);
}
"open_collective" => {
@@ -625,10 +595,7 @@ impl GitHubDriver {
"otechie" => {
result[key_idx].insert(
"url".to_string(),
- PhpMixed::String(format!(
- "https://otechie.com/{}",
- basename(&item_url)
- )),
+ PhpMixed::String(format!("https://otechie.com/{}", basename(&item_url))),
);
}
"custom" => {
@@ -712,16 +679,16 @@ impl GitHubDriver {
PhpMixed::Array(ref m) => m.clone(),
_ => IndexMap::new(),
};
- let needs_git_url = (resource_map.get("content").and_then(|v| v.as_string()).is_none()
+ let needs_git_url = (resource_map
+ .get("content")
+ .and_then(|v| v.as_string())
+ .is_none()
|| resource_map
.get("content")
.and_then(|v| v.as_string())
.map(|s| s.is_empty())
.unwrap_or(false))
- && resource_map
- .get("encoding")
- .and_then(|v| v.as_string())
- == Some("none")
+ && resource_map.get("encoding").and_then(|v| v.as_string()) == Some("none")
&& resource_map.contains_key("git_url");
if needs_git_url {
let git_url = resource_map
@@ -740,10 +707,8 @@ impl GitHubDriver {
_ => IndexMap::new(),
};
let has_content = resource_map.contains_key("content");
- let encoding_base64 = resource_map
- .get("encoding")
- .and_then(|v| v.as_string())
- == Some("base64");
+ let encoding_base64 =
+ resource_map.get("encoding").and_then(|v| v.as_string()) == Some("base64");
let content = if has_content && encoding_base64 {
base64_decode(
resource_map
@@ -922,11 +887,7 @@ impl GitHubDriver {
.filter(|s| !s.is_empty())
.unwrap_or_else(|| matches.get(3).cloned().unwrap_or_default());
if !in_array(
- PhpMixed::String(strtolower(&Preg::replace(
- r"{^www\.}i",
- "",
- origin_url,
- ))),
+ PhpMixed::String(strtolower(&Preg::replace(r"{^www\.}i", "", origin_url))),
&config.get("github-domains"),
false,
) {
@@ -1001,20 +962,23 @@ impl GitHubDriver {
}
if !self.inner.io.is_interactive() {
- self.attempt_clone_fallback(Some(&e))
- .map_err(|err| TransportException {
+ self.attempt_clone_fallback(Some(&e)).map_err(|err| {
+ TransportException {
message: err.to_string(),
code: 0,
- })?;
+ }
+ })?;
let mut req = IndexMap::new();
- req.insert(
- "url".to_string(),
- PhpMixed::String("dummy".to_string()),
- );
- return Ok(Response::new(req, Some(200), vec![], Some("null".to_string()))
- .unwrap()
- .unwrap());
+ req.insert("url".to_string(), PhpMixed::String("dummy".to_string()));
+ return Ok(Response::new(
+ req,
+ Some(200),
+ vec![],
+ Some("null".to_string()),
+ )
+ .unwrap()
+ .unwrap());
}
let mut scopes_issued: Vec<String> = vec![];
@@ -1068,20 +1032,23 @@ impl GitHubDriver {
}
if !self.inner.io.is_interactive() && fetching_repo_data {
- self.attempt_clone_fallback(Some(&e))
- .map_err(|err| TransportException {
+ self.attempt_clone_fallback(Some(&e)).map_err(|err| {
+ TransportException {
message: err.to_string(),
code: 0,
- })?;
+ }
+ })?;
let mut req = IndexMap::new();
- req.insert(
- "url".to_string(),
- PhpMixed::String("dummy".to_string()),
- );
- return Ok(Response::new(req, Some(200), vec![], Some("null".to_string()))
- .unwrap()
- .unwrap());
+ req.insert("url".to_string(), PhpMixed::String("dummy".to_string()));
+ return Ok(Response::new(
+ req,
+ Some(200),
+ vec![],
+ Some("null".to_string()),
+ )
+ .unwrap()
+ .unwrap());
}
let rate_limited = git_hub_util
@@ -1186,11 +1153,8 @@ impl GitHubDriver {
.unwrap_or("")
.to_string();
- self.is_private = !empty(
- &repo_data.get("private").cloned().unwrap_or(PhpMixed::Null),
- );
- if let Some(default_branch) = repo_data.get("default_branch").and_then(|v| v.as_string())
- {
+ self.is_private = !empty(&repo_data.get("private").cloned().unwrap_or(PhpMixed::Null));
+ if let Some(default_branch) = repo_data.get("default_branch").and_then(|v| v.as_string()) {
self.root_identifier = default_branch.to_string();
} else if let Some(master_branch) =
repo_data.get("master_branch").and_then(|v| v.as_string())
@@ -1205,12 +1169,7 @@ impl GitHubDriver {
.cloned()
.unwrap_or(PhpMixed::Null),
);
- self.is_archived = !empty(
- &repo_data
- .get("archived")
- .cloned()
- .unwrap_or(PhpMixed::Null),
- );
+ self.is_archived = !empty(&repo_data.get("archived").cloned().unwrap_or(PhpMixed::Null));
Ok(())
}
diff --git a/crates/shirabe/src/repository/vcs/gitlab_driver.rs b/crates/shirabe/src/repository/vcs/gitlab_driver.rs
index 54147e9..cb0d0a2 100644
--- a/crates/shirabe/src/repository/vcs/gitlab_driver.rs
+++ b/crates/shirabe/src/repository/vcs/gitlab_driver.rs
@@ -5,9 +5,9 @@ use chrono::{DateTime, Utc};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- array_search_mixed, array_shift, ctype_alnum, empty, explode, extension_loaded, implode,
- in_array, is_array, is_string, ord, sprintf, strpos, strtolower, InvalidArgumentException,
- LogicException, PhpMixed, RuntimeException,
+ InvalidArgumentException, LogicException, PhpMixed, RuntimeException, array_search_mixed,
+ array_shift, ctype_alnum, empty, explode, extension_loaded, implode, in_array, is_array,
+ is_string, ord, sprintf, strpos, strtolower,
};
use crate::cache::Cache;
@@ -76,7 +76,8 @@ impl GitLabDriver {
.filter(|s| !s.is_empty())
.unwrap_or_else(|| match_.get("domain2").cloned().unwrap_or_default());
let configured_domains = self.inner.config.get("gitlab-domains");
- let mut url_parts: Vec<String> = explode("/", &match_.get("parts").cloned().unwrap_or_default());
+ let mut url_parts: Vec<String> =
+ explode("/", &match_.get("parts").cloned().unwrap_or_default());
let scheme_match = match_.get("scheme").cloned().unwrap_or_default();
self.scheme = if in_array(
@@ -122,7 +123,10 @@ impl GitLabDriver {
self.inner.origin_url = origin;
let protocol_value = self.inner.config.get("gitlab-protocol");
- if let Some(protocol) = protocol_value.as_string().filter(|_| is_string(&protocol_value)) {
+ if let Some(protocol) = protocol_value
+ .as_string()
+ .filter(|_| is_string(&protocol_value))
+ {
// https treated as a synonym for http.
if !in_array(
PhpMixed::String(protocol.to_string()),
@@ -250,10 +254,7 @@ impl GitLabDriver {
if composer.contains_key("support")
&& !is_array(composer.get("support").cloned().unwrap_or(PhpMixed::Null))
{
- composer.insert(
- "support".to_string(),
- PhpMixed::Array(IndexMap::new()),
- );
+ composer.insert("support".to_string(), PhpMixed::Array(IndexMap::new()));
}
let project = self.project.clone().unwrap_or_default();
let has_web_url = project.contains_key("web_url");
@@ -278,7 +279,8 @@ impl GitLabDriver {
array_search_mixed(
&PhpMixed::String(identifier.to_string()),
&PhpMixed::Array(
- self.get_branches().unwrap_or_default()
+ self.get_branches()
+ .unwrap_or_default()
.into_iter()
.map(|(k, v)| (k, Box::new(PhpMixed::String(v))))
.collect(),
@@ -294,20 +296,15 @@ impl GitLabDriver {
.and_then(|v| v.as_string())
.unwrap_or("")
.to_string();
- if let Some(support) = composer.get_mut("support").and_then(|v| {
- match v {
- PhpMixed::Array(m) => Some(m),
- _ => None,
- }
+ if let Some(support) = composer.get_mut("support").and_then(|v| match v {
+ PhpMixed::Array(m) => Some(m),
+ _ => None,
}) {
support.insert(
"source".to_string(),
Box::new(PhpMixed::String(sprintf(
"%s/-/tree/%s",
- &[
- PhpMixed::String(web_url),
- PhpMixed::String(label_str),
- ],
+ &[PhpMixed::String(web_url), PhpMixed::String(label_str)],
))),
);
}
@@ -343,12 +340,7 @@ impl GitLabDriver {
}
}
if !composer.contains_key("abandoned")
- && !empty(
- &project
- .get("archived")
- .cloned()
- .unwrap_or(PhpMixed::Null),
- )
+ && !empty(&project.get("archived").cloned().unwrap_or(PhpMixed::Null))
{
composer.insert("abandoned".to_string(), PhpMixed::Bool(true));
}
@@ -559,12 +551,8 @@ impl GitLabDriver {
Box::new(PhpMixed::String("_".to_string())),
]),
true,
- )
- {
- format!(
- "%{}",
- sprintf("%02X", &[PhpMixed::Int(ord(&character))])
- )
+ ) {
+ format!("%{}", sprintf("%02X", &[PhpMixed::Int(ord(&character))]))
} else {
character
};
@@ -774,15 +762,13 @@ impl GitLabDriver {
// Check both access levels (e.g. project, group)
// - value will be null if no access is set
// - value will be array with key access_level if set
- if let Some(permissions) = json_map
- .get("permissions")
- .and_then(|v| v.as_array())
+ if let Some(permissions) =
+ json_map.get("permissions").and_then(|v| v.as_array())
{
for (_, permission) in permissions {
if let Some(perm_map) = permission.as_array() {
- if let Some(level) = perm_map
- .get("access_level")
- .and_then(|v| v.as_int())
+ if let Some(level) =
+ perm_map.get("access_level").and_then(|v| v.as_int())
{
if level >= 20 {
more_than_guest_access = true;
@@ -809,13 +795,15 @@ impl GitLabDriver {
})?;
let mut req = IndexMap::new();
- req.insert(
- "url".to_string(),
- PhpMixed::String("dummy".to_string()),
- );
- return Ok(Response::new(req, Some(200), vec![], Some("null".to_string()))
- .unwrap()
- .unwrap());
+ req.insert("url".to_string(), PhpMixed::String("dummy".to_string()));
+ return Ok(Response::new(
+ req,
+ Some(200),
+ vec![],
+ Some("null".to_string()),
+ )
+ .unwrap()
+ .unwrap());
}
}
@@ -834,9 +822,7 @@ impl GitLabDriver {
});
}
- if !empty(
- &json_map.get("id").cloned().unwrap_or(PhpMixed::Null),
- ) {
+ if !empty(&json_map.get("id").cloned().unwrap_or(PhpMixed::Null)) {
self.is_private = false;
}
@@ -885,13 +871,15 @@ impl GitLabDriver {
})?;
let mut req = IndexMap::new();
- req.insert(
- "url".to_string(),
- PhpMixed::String("dummy".to_string()),
- );
- return Ok(Response::new(req, Some(200), vec![], Some("null".to_string()))
- .unwrap()
- .unwrap());
+ req.insert("url".to_string(), PhpMixed::String("dummy".to_string()));
+ return Ok(Response::new(
+ req,
+ Some(200),
+ vec![],
+ Some("null".to_string()),
+ )
+ .unwrap()
+ .unwrap());
}
self.inner.io.write_error(
PhpMixed::String(format!(
@@ -927,13 +915,15 @@ impl GitLabDriver {
})?;
let mut req = IndexMap::new();
- req.insert(
- "url".to_string(),
- PhpMixed::String("dummy".to_string()),
- );
- return Ok(Response::new(req, Some(200), vec![], Some("null".to_string()))
- .unwrap()
- .unwrap());
+ req.insert("url".to_string(), PhpMixed::String("dummy".to_string()));
+ return Ok(Response::new(
+ req,
+ Some(200),
+ vec![],
+ Some("null".to_string()),
+ )
+ .unwrap()
+ .unwrap());
}
Err(e)
@@ -1002,9 +992,7 @@ impl GitLabDriver {
let links = explode(",", &header);
for link in &links {
- if let Some(match_) =
- Preg::is_match_strict_groups(r#"{<(.+?)>; *rel="next"}"#, link)
- {
+ if let Some(match_) = Preg::is_match_strict_groups(r#"{<(.+?)>; *rel="next"}"#, link) {
return Some(match_.get(1).cloned().unwrap_or_default());
}
}
@@ -1059,11 +1047,7 @@ impl GitLabDriver {
false,
) || (port_number.is_some()
&& in_array(
- PhpMixed::String(Preg::replace(
- r"{:\d+}",
- "",
- guessed_domain.clone(),
- )),
+ PhpMixed::String(Preg::replace(r"{:\d+}", "", guessed_domain.clone())),
configured_domains,
false,
))
@@ -1075,4 +1059,3 @@ impl GitLabDriver {
None
}
}
-
diff --git a/crates/shirabe/src/repository/vcs/hg_driver.rs b/crates/shirabe/src/repository/vcs/hg_driver.rs
index 7dc85e2..6b32a0a 100644
--- a/crates/shirabe/src/repository/vcs/hg_driver.rs
+++ b/crates/shirabe/src/repository/vcs/hg_driver.rs
@@ -1,9 +1,5 @@
//! ref: composer/src/Composer/Repository/Vcs/HgDriver.php
-use chrono::{DateTime, Utc};
-use indexmap::IndexMap;
-use shirabe_external_packages::composer::pcre::preg::Preg;
-use shirabe_php_shim::{dirname, is_dir, is_writable, RuntimeException};
use crate::cache::Cache;
use crate::config::Config;
use crate::io::io_interface::IOInterface;
@@ -11,6 +7,10 @@ use crate::repository::vcs::vcs_driver::VcsDriver;
use crate::util::filesystem::Filesystem;
use crate::util::hg::Hg as HgUtils;
use crate::util::url::Url;
+use chrono::{DateTime, Utc};
+use indexmap::IndexMap;
+use shirabe_external_packages::composer::pcre::preg::Preg;
+use shirabe_php_shim::{RuntimeException, dirname, is_dir, is_writable};
#[derive(Debug)]
pub struct HgDriver {
@@ -26,7 +26,13 @@ impl HgDriver {
if Filesystem::is_local_path(&self.inner.url) {
self.repo_dir = self.inner.url.clone();
} else {
- let cache_vcs_dir = self.inner.config.get("cache-vcs-dir").as_string().unwrap_or("").to_string();
+ let cache_vcs_dir = self
+ .inner
+ .config
+ .get("cache-vcs-dir")
+ .as_string()
+ .unwrap_or("")
+ .to_string();
if !Cache::is_usable(&cache_vcs_dir) {
return Err(RuntimeException {
message: "HgDriver requires a usable cache directory, and it looks like you set it to be disabled".to_string(),
@@ -34,7 +40,8 @@ impl HgDriver {
}.into());
}
- let sanitized = Preg::replace(r"{[^a-z0-9]}i", "-", Url::sanitize(self.inner.url.clone()));
+ let sanitized =
+ Preg::replace(r"{[^a-z0-9]}i", "-", Url::sanitize(self.inner.url.clone()));
self.repo_dir = format!("{}/{}/", cache_vcs_dir, sanitized);
let fs = Filesystem::new();
@@ -50,12 +57,25 @@ impl HgDriver {
}.into());
}
- self.inner.config.prohibit_url_by_config(&self.inner.url, &*self.inner.io)?;
+ self.inner
+ .config
+ .prohibit_url_by_config(&self.inner.url, &*self.inner.io)?;
let hg_utils = HgUtils::new(&*self.inner.io, &self.inner.config, &self.inner.process);
- if is_dir(&self.repo_dir) && self.inner.process.execute(&["hg", "summary"].map(|s| s.to_string()).to_vec(), &mut String::new(), Some(self.repo_dir.clone())) == 0 {
- if self.inner.process.execute(&["hg", "pull"].map(|s| s.to_string()).to_vec(), &mut String::new(), Some(self.repo_dir.clone())) != 0 {
+ if is_dir(&self.repo_dir)
+ && self.inner.process.execute(
+ &["hg", "summary"].map(|s| s.to_string()).to_vec(),
+ &mut String::new(),
+ Some(self.repo_dir.clone()),
+ ) == 0
+ {
+ if self.inner.process.execute(
+ &["hg", "pull"].map(|s| s.to_string()).to_vec(),
+ &mut String::new(),
+ Some(self.repo_dir.clone()),
+ ) != 0
+ {
self.inner.io.write_error(
format!("<error>Failed to update {}, package information from this repository may be outdated ({})</error>", self.inner.url, self.inner.process.get_error_output()).into(),
true,
@@ -68,7 +88,14 @@ impl HgDriver {
let repo_dir = self.repo_dir.clone();
let command = move |url: String| -> Vec<String> {
- vec!["hg".to_string(), "clone".to_string(), "--noupdate".to_string(), "--".to_string(), url, repo_dir.clone()]
+ vec![
+ "hg".to_string(),
+ "clone".to_string(),
+ "--noupdate".to_string(),
+ "--".to_string(),
+ url,
+ repo_dir.clone(),
+ ]
};
hg_utils.run_command(command, self.inner.url.clone(), None)?;
@@ -85,7 +112,9 @@ impl HgDriver {
if self.root_identifier.is_none() {
let mut output = String::new();
self.inner.process.execute(
- &["hg", "tip", "--template", "{node}"].map(|s| s.to_string()).to_vec(),
+ &["hg", "tip", "--template", "{node}"]
+ .map(|s| s.to_string())
+ .to_vec(),
&mut output,
Some(self.repo_dir.clone()),
);
@@ -115,17 +144,27 @@ impl HgDriver {
pub fn get_file_content(&self, file: &str, identifier: &str) -> anyhow::Result<Option<String>> {
if identifier.starts_with('-') {
return Err(RuntimeException {
- message: format!("Invalid hg identifier detected. Identifier must not start with a -, given: {}", identifier),
+ message: format!(
+ "Invalid hg identifier detected. Identifier must not start with a -, given: {}",
+ identifier
+ ),
code: 0,
- }.into());
+ }
+ .into());
}
let resource = vec![
- "hg".to_string(), "cat".to_string(), "-r".to_string(), identifier.to_string(),
- "--".to_string(), file.to_string(),
+ "hg".to_string(),
+ "cat".to_string(),
+ "-r".to_string(),
+ identifier.to_string(),
+ "--".to_string(),
+ file.to_string(),
];
let mut content = String::new();
- self.inner.process.execute(&resource, &mut content, Some(self.repo_dir.clone()));
+ self.inner
+ .process
+ .execute(&resource, &mut content, Some(self.repo_dir.clone()));
if content.trim().is_empty() {
return Ok(None);
@@ -137,22 +176,32 @@ impl HgDriver {
pub fn get_change_date(&self, identifier: &str) -> anyhow::Result<Option<DateTime<Utc>>> {
if identifier.starts_with('-') {
return Err(RuntimeException {
- message: format!("Invalid hg identifier detected. Identifier must not start with a -, given: {}", identifier),
+ message: format!(
+ "Invalid hg identifier detected. Identifier must not start with a -, given: {}",
+ identifier
+ ),
code: 0,
- }.into());
+ }
+ .into());
}
let mut output = String::new();
self.inner.process.execute(
- &["hg", "log", "--template", "{date|rfc3339date}", "-r", identifier]
- .map(|s| s.to_string())
- .to_vec(),
+ &[
+ "hg",
+ "log",
+ "--template",
+ "{date|rfc3339date}",
+ "-r",
+ identifier,
+ ]
+ .map(|s| s.to_string())
+ .to_vec(),
&mut output,
Some(self.repo_dir.clone()),
);
- let date = DateTime::parse_from_rfc3339(output.trim())
- .map(|d| d.with_timezone(&Utc))?;
+ let date = DateTime::parse_from_rfc3339(output.trim()).map(|d| d.with_timezone(&Utc))?;
Ok(Some(date))
}
@@ -231,7 +280,12 @@ impl HgDriver {
}
pub fn supports(io: &dyn IOInterface, config: &Config, url: &str, deep: bool) -> bool {
- if Preg::is_match(r"#(^(?:https?|ssh)://(?:[^@]+@)?bitbucket.org|https://(?:.*?)\.kilnhg.com)#i", url).unwrap_or(false) {
+ if Preg::is_match(
+ r"#(^(?:https?|ssh)://(?:[^@]+@)?bitbucket.org|https://(?:.*?)\.kilnhg.com)#i",
+ url,
+ )
+ .unwrap_or(false)
+ {
return true;
}
@@ -243,7 +297,12 @@ impl HgDriver {
let process = crate::util::process_executor::ProcessExecutor::new(io);
let mut output = String::new();
- if process.execute(&["hg", "summary"].map(|s| s.to_string()).to_vec(), &mut output, Some(url)) == 0 {
+ if process.execute(
+ &["hg", "summary"].map(|s| s.to_string()).to_vec(),
+ &mut output,
+ Some(url),
+ ) == 0
+ {
return true;
}
}
@@ -254,7 +313,13 @@ impl HgDriver {
let process = crate::util::process_executor::ProcessExecutor::new(io);
let mut ignored = String::new();
- let exit = process.execute(&["hg", "identify", "--", url].map(|s| s.to_string()).to_vec(), &mut ignored, None);
+ let exit = process.execute(
+ &["hg", "identify", "--", url]
+ .map(|s| s.to_string())
+ .to_vec(),
+ &mut ignored,
+ None,
+ );
exit == 0
}
diff --git a/crates/shirabe/src/repository/vcs/mod.rs b/crates/shirabe/src/repository/vcs/mod.rs
new file mode 100644
index 0000000..4bbf4a6
--- /dev/null
+++ b/crates/shirabe/src/repository/vcs/mod.rs
@@ -0,0 +1,11 @@
+pub mod forgejo_driver;
+pub mod fossil_driver;
+pub mod git_bitbucket_driver;
+pub mod git_driver;
+pub mod github_driver;
+pub mod gitlab_driver;
+pub mod hg_driver;
+pub mod perforce_driver;
+pub mod svn_driver;
+pub mod vcs_driver;
+pub mod vcs_driver_interface;
diff --git a/crates/shirabe/src/repository/vcs/perforce_driver.rs b/crates/shirabe/src/repository/vcs/perforce_driver.rs
index f32f895..cd3b32b 100644
--- a/crates/shirabe/src/repository/vcs/perforce_driver.rs
+++ b/crates/shirabe/src/repository/vcs/perforce_driver.rs
@@ -22,12 +22,20 @@ pub struct PerforceDriver {
impl PerforceDriver {
pub fn initialize(&mut self) -> anyhow::Result<()> {
- self.depot = self.inner.repo_config.get("depot")
+ self.depot = self
+ .inner
+ .repo_config
+ .get("depot")
.and_then(|v| v.as_string())
.unwrap_or("")
.to_string();
self.branch = String::new();
- if let Some(branch) = self.inner.repo_config.get("branch").and_then(|v| v.as_string()) {
+ if let Some(branch) = self
+ .inner
+ .repo_config
+ .get("branch")
+ .and_then(|v| v.as_string())
+ {
if !branch.is_empty() {
self.branch = branch.to_string();
}
@@ -48,7 +56,13 @@ impl PerforceDriver {
return Ok(());
}
- let cache_vcs_dir = self.inner.config.get("cache-vcs-dir").as_string().unwrap_or("").to_string();
+ let cache_vcs_dir = self
+ .inner
+ .config
+ .get("cache-vcs-dir")
+ .as_string()
+ .unwrap_or("")
+ .to_string();
if !Cache::is_usable(&cache_vcs_dir) {
return Err(RuntimeException {
message: "PerforceDriver requires a usable cache directory, and it looks like you set it to be disabled".to_string(),
@@ -57,16 +71,28 @@ impl PerforceDriver {
}
let repo_dir = format!("{}/{}", cache_vcs_dir, self.depot);
- self.perforce = Some(Perforce::create(repo_config, &self.inner.url, &repo_dir, &self.inner.process, self.inner.io.as_ref())?);
+ self.perforce = Some(Perforce::create(
+ repo_config,
+ &self.inner.url,
+ &repo_dir,
+ &self.inner.process,
+ self.inner.io.as_ref(),
+ )?);
Ok(())
}
pub fn get_file_content(&self, file: &str, identifier: &str) -> anyhow::Result<Option<String>> {
- self.perforce.as_ref().unwrap().get_file_content(file, identifier)
+ self.perforce
+ .as_ref()
+ .unwrap()
+ .get_file_content(file, identifier)
}
- pub fn get_change_date(&self, _identifier: &str) -> anyhow::Result<Option<chrono::DateTime<chrono::Utc>>> {
+ pub fn get_change_date(
+ &self,
+ _identifier: &str,
+ ) -> anyhow::Result<Option<chrono::DateTime<chrono::Utc>>> {
Ok(None)
}
@@ -89,9 +115,22 @@ impl PerforceDriver {
pub fn get_source(&self, identifier: &str) -> IndexMap<String, PhpMixed> {
let mut source = IndexMap::new();
source.insert("type".to_string(), PhpMixed::String("perforce".to_string()));
- source.insert("url".to_string(), self.inner.repo_config.get("url").cloned().unwrap_or(PhpMixed::Null));
- source.insert("reference".to_string(), PhpMixed::String(identifier.to_string()));
- source.insert("p4user".to_string(), PhpMixed::String(self.perforce.as_ref().unwrap().get_user().to_string()));
+ source.insert(
+ "url".to_string(),
+ self.inner
+ .repo_config
+ .get("url")
+ .cloned()
+ .unwrap_or(PhpMixed::Null),
+ );
+ source.insert(
+ "reference".to_string(),
+ PhpMixed::String(identifier.to_string()),
+ );
+ source.insert(
+ "p4user".to_string(),
+ PhpMixed::String(self.perforce.as_ref().unwrap().get_user().to_string()),
+ );
source
}
@@ -101,14 +140,19 @@ impl PerforceDriver {
pub fn has_composer_file(&self, identifier: &str) -> bool {
let path = format!("//{}/{}", self.depot, identifier);
- self.perforce.as_ref().unwrap().get_composer_information(&path).map_or(false, |info| !info.is_empty())
+ self.perforce
+ .as_ref()
+ .unwrap()
+ .get_composer_information(&path)
+ .map_or(false, |info| !info.is_empty())
}
pub fn get_contents(&self, _url: &str) -> anyhow::Result<Response> {
Err(BadMethodCallException {
message: "Not implemented/used in PerforceDriver".to_string(),
code: 0,
- }.into())
+ }
+ .into())
}
pub fn supports(io: &dyn IOInterface, config: &Config, url: &str, deep: bool) -> bool {
diff --git a/crates/shirabe/src/repository/vcs/svn_driver.rs b/crates/shirabe/src/repository/vcs/svn_driver.rs
index 4bfcf91..7c32e4a 100644
--- a/crates/shirabe/src/repository/vcs/svn_driver.rs
+++ b/crates/shirabe/src/repository/vcs/svn_driver.rs
@@ -5,8 +5,8 @@ use chrono::{DateTime, TimeZone, Utc};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- array_key_exists, is_array, max, sprintf, stripos, strrpos, strtr, substr, trim, PhpMixed,
- RuntimeException, JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE,
+ JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE, PhpMixed, RuntimeException, array_key_exists,
+ is_array, max, sprintf, stripos, strrpos, strtr, substr, trim,
};
use crate::cache::Cache;
@@ -51,9 +51,7 @@ pub struct SvnDriver {
impl SvnDriver {
pub fn initialize(&mut self) -> Result<()> {
let normalized = Self::normalize_url(&self.inner.url);
- self.inner.url = normalized
- .trim_end_matches('/')
- .to_string();
+ self.inner.url = normalized.trim_end_matches('/').to_string();
self.base_url = self.inner.url.clone();
SvnUtil::clean_env();
@@ -90,24 +88,24 @@ impl SvnDriver {
todo!("self.inner.io clone"),
&format!(
"{}/{}",
- self.inner.config.get("cache-repo-dir").as_string().unwrap_or(""),
+ self.inner
+ .config
+ .get("cache-repo-dir")
+ .as_string()
+ .unwrap_or(""),
Preg::replace(r"{[^a-z0-9.]}i", "-", Url::sanitize(self.base_url.clone())),
),
None,
None,
false,
));
- self.inner
- .cache
- .as_mut()
- .unwrap()
- .set_read_only(
- self.inner
- .config
- .get("cache-read-only")
- .as_bool()
- .unwrap_or(false),
- );
+ self.inner.cache.as_mut().unwrap().set_read_only(
+ self.inner
+ .config
+ .get("cache-read-only")
+ .as_bool()
+ .unwrap_or(false),
+ );
self.get_branches();
self.get_tags();
@@ -172,24 +170,22 @@ impl SvnDriver {
}
// TODO(phase-b): use anyhow::Result<Result<T, E>> to model PHP try/catch
- let composer: Option<IndexMap<String, PhpMixed>> = match self
- .inner
- .get_base_composer_information(identifier)
- {
- Ok(c) => c,
- Err(e) => {
- // TODO(phase-b): downcast to TransportException
- let _te: &TransportException = todo!("downcast e to TransportException");
- let message = e.to_string();
- if stripos(&message, "path not found").is_none()
- && stripos(&message, "svn: warning: W160013").is_none()
- {
- return Err(e);
+ let composer: Option<IndexMap<String, PhpMixed>> =
+ match self.inner.get_base_composer_information(identifier) {
+ Ok(c) => c,
+ Err(e) => {
+ // TODO(phase-b): downcast to TransportException
+ let _te: &TransportException = todo!("downcast e to TransportException");
+ let message = e.to_string();
+ if stripos(&message, "path not found").is_none()
+ && stripos(&message, "svn: warning: W160013").is_none()
+ {
+ return Err(e);
+ }
+ // remember a not-existent composer.json
+ None
}
- // remember a not-existent composer.json
- None
- }
- };
+ };
if self.should_cache(identifier) {
let encoded = JsonFile::encode(
@@ -221,10 +217,7 @@ impl SvnDriver {
if cached.is_none()
|| !is_array(
// TODO(phase-b): wrap IndexMap to PhpMixed for is_array check
- &cached
- .clone()
- .map(PhpMixed::from)
- .unwrap_or(PhpMixed::Null),
+ &cached.clone().map(PhpMixed::from).unwrap_or(PhpMixed::Null),
)
{
return Ok(None);
@@ -233,11 +226,7 @@ impl SvnDriver {
Ok(cached)
}
- pub fn get_file_content(
- &mut self,
- file: &str,
- identifier: &str,
- ) -> Result<Option<String>> {
+ pub fn get_file_content(&mut self, file: &str, identifier: &str) -> Result<Option<String>> {
let identifier = format!("/{}/", trim(identifier, Some("/")));
let (path, rev) = if let Ok(Some(m)) =
@@ -296,10 +285,9 @@ impl SvnDriver {
)?;
for line in self.inner.process.split_lines(&output) {
if !line.is_empty() {
- if let Some(m) = Preg::is_match_strict_groups(
- r"{^Last Changed Date: ([^(]+)}",
- &line,
- ) {
+ if let Some(m) =
+ Preg::is_match_strict_groups(r"{^Last Changed Date: ([^(]+)}", &line)
+ {
let date_str = m.get(1).cloned().unwrap_or_default();
// PHP: new \DateTimeImmutable($match[1], new \DateTimeZone('UTC'))
return Ok(Utc
@@ -318,24 +306,22 @@ impl SvnDriver {
// PHP: if ($this->tagsPath !== false) — tagsPath is "string"; treat empty string as false
if !self.tags_path.is_empty() {
- let output = self.execute(
- vec![
- "svn".to_string(),
- "ls".to_string(),
- "--verbose".to_string(),
- ],
- &format!("{}/{}", self.base_url, self.tags_path),
- ).unwrap_or_default();
+ let output = self
+ .execute(
+ vec!["svn".to_string(), "ls".to_string(), "--verbose".to_string()],
+ &format!("{}/{}", self.base_url, self.tags_path),
+ )
+ .unwrap_or_default();
if !output.is_empty() {
let mut last_rev: i64 = 0;
for line in self.inner.process.split_lines(&output) {
let line = trim(&line, None);
if !line.is_empty() {
- if let Some(m) = Preg::is_match_strict_groups(
- r"{^\s*(\S+).*?(\S+)\s*$}",
- &line,
- ) {
- let rev: i64 = m.get(1).map(|s| s.parse().unwrap_or(0)).unwrap_or(0);
+ if let Some(m) =
+ Preg::is_match_strict_groups(r"{^\s*(\S+).*?(\S+)\s*$}", &line)
+ {
+ let rev: i64 =
+ m.get(1).map(|s| s.parse().unwrap_or(0)).unwrap_or(0);
let path = m.get(2).cloned().unwrap_or_default();
if path == "./" {
last_rev = rev;
@@ -370,11 +356,7 @@ impl SvnDriver {
let output = self
.execute(
- vec![
- "svn".to_string(),
- "ls".to_string(),
- "--verbose".to_string(),
- ],
+ vec!["svn".to_string(), "ls".to_string(), "--verbose".to_string()],
&trunk_parent,
)
.unwrap_or_default();
@@ -382,10 +364,9 @@ impl SvnDriver {
for line in self.inner.process.split_lines(&output) {
let line = trim(&line, None);
if !line.is_empty() {
- if let Some(m) = Preg::is_match_strict_groups(
- r"{^\s*(\S+).*?(\S+)\s*$}",
- &line,
- ) {
+ if let Some(m) =
+ Preg::is_match_strict_groups(r"{^\s*(\S+).*?(\S+)\s*$}", &line)
+ {
let rev: i64 = m.get(1).map(|s| s.parse().unwrap_or(0)).unwrap_or(0);
let path = m.get(2).cloned().unwrap_or_default();
if path == "./" {
@@ -407,11 +388,7 @@ impl SvnDriver {
if !self.branches_path.is_empty() {
let output = self
.execute(
- vec![
- "svn".to_string(),
- "ls".to_string(),
- "--verbose".to_string(),
- ],
+ vec!["svn".to_string(), "ls".to_string(), "--verbose".to_string()],
&format!("{}/{}", self.base_url, self.branches_path),
)
.unwrap_or_default();
@@ -420,10 +397,9 @@ impl SvnDriver {
for line in self.inner.process.split_lines(&trim(&output, None)) {
let line = trim(&line, None);
if !line.is_empty() {
- if let Some(m) = Preg::is_match_strict_groups(
- r"{^\s*(\S+).*?(\S+)\s*$}",
- &line,
- ) {
+ if let Some(m) =
+ Preg::is_match_strict_groups(r"{^\s*(\S+).*?(\S+)\s*$}", &line)
+ {
let rev: i64 =
m.get(1).map(|s| s.parse().unwrap_or(0)).unwrap_or(0);
let path = m.get(2).cloned().unwrap_or_default();
@@ -528,7 +504,12 @@ impl SvnDriver {
}
// TODO(phase-b): use anyhow::Result<Result<T, E>> to model PHP try/catch
- match self.util.as_mut().unwrap().execute(command, url, None, None, false) {
+ match self
+ .util
+ .as_mut()
+ .unwrap()
+ .execute(command, url, None, None, false)
+ {
Ok(o) => Ok(o),
Err(e) => {
if self.util.as_mut().unwrap().binary_version().is_none() {
diff --git a/crates/shirabe/src/repository/vcs/vcs_driver.rs b/crates/shirabe/src/repository/vcs/vcs_driver.rs
index 8db411d..a16930f 100644
--- a/crates/shirabe/src/repository/vcs/vcs_driver.rs
+++ b/crates/shirabe/src/repository/vcs/vcs_driver.rs
@@ -2,7 +2,9 @@
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
-use shirabe_php_shim::{extension_loaded, PhpMixed, JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE};
+use shirabe_php_shim::{
+ JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE, PhpMixed, extension_loaded,
+};
use crate::cache::Cache;
use crate::config::Config;
@@ -42,7 +44,11 @@ impl VcsDriver {
}
}
- let url = repo_config.get("url").and_then(|v| v.as_string()).unwrap_or("").to_string();
+ let url = repo_config
+ .get("url")
+ .and_then(|v| v.as_string())
+ .unwrap_or("")
+ .to_string();
Self {
origin_url: url.clone(),
@@ -61,7 +67,10 @@ impl VcsDriver {
self.cache.is_some() && Preg::is_match("{^[a-f0-9]{40}$}iD", identifier).unwrap_or(false)
}
- pub fn get_composer_information(&mut self, identifier: &str) -> anyhow::Result<Option<IndexMap<String, PhpMixed>>> {
+ pub fn get_composer_information(
+ &mut self,
+ identifier: &str,
+ ) -> anyhow::Result<Option<IndexMap<String, PhpMixed>>> {
if !self.info_cache.contains_key(identifier) {
if self.should_cache(identifier) {
if let Some(res) = self.cache.as_ref().and_then(|c| c.read(identifier)) {
@@ -75,7 +84,10 @@ impl VcsDriver {
if self.should_cache(identifier) {
if let Some(ref composer_map) = composer {
- let encoded = JsonFile::encode_with_options(composer_map, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
+ let encoded = JsonFile::encode_with_options(
+ composer_map,
+ JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES,
+ );
self.cache.as_ref().map(|c| c.write(identifier, &encoded));
}
}
@@ -86,7 +98,10 @@ impl VcsDriver {
Ok(self.info_cache.get(identifier).and_then(|v| v.clone()))
}
- pub(crate) fn get_base_composer_information(&mut self, identifier: &str) -> anyhow::Result<Option<IndexMap<String, PhpMixed>>> {
+ pub(crate) fn get_base_composer_information(
+ &mut self,
+ identifier: &str,
+ ) -> anyhow::Result<Option<IndexMap<String, PhpMixed>>> {
let composer_file_content = self.get_file_content("composer.json", identifier)?;
let composer_file_content = match composer_file_content {
@@ -95,7 +110,10 @@ impl VcsDriver {
Some(c) => c,
};
- let composer = JsonFile::parse_json(&composer_file_content, Some(&format!("{}:composer.json", identifier)))?;
+ let composer = JsonFile::parse_json(
+ &composer_file_content,
+ Some(&format!("{}:composer.json", identifier)),
+ )?;
let mut composer = match composer {
None => return Ok(None),
@@ -103,9 +121,16 @@ impl VcsDriver {
Some(c) => c,
};
- if !composer.contains_key("time") || composer.get("time").map_or(true, |v| v.as_string().map_or(true, |s| s.is_empty())) {
+ if !composer.contains_key("time")
+ || composer
+ .get("time")
+ .map_or(true, |v| v.as_string().map_or(true, |s| s.is_empty()))
+ {
if let Some(change_date) = self.get_change_date(identifier)? {
- composer.insert("time".to_string(), PhpMixed::String(change_date.to_rfc3339()));
+ composer.insert(
+ "time".to_string(),
+ PhpMixed::String(change_date.to_rfc3339()),
+ );
}
}
@@ -127,18 +152,29 @@ impl VcsDriver {
}
pub(crate) fn get_contents(&self, url: &str) -> anyhow::Result<Response, TransportException> {
- let options = self.repo_config.get("options").cloned().unwrap_or(PhpMixed::Array(IndexMap::new()));
+ let options = self
+ .repo_config
+ .get("options")
+ .cloned()
+ .unwrap_or(PhpMixed::Array(IndexMap::new()));
self.http_downloader.get(url, &options)
}
pub fn cleanup(&self) {}
// abstract methods to be implemented by subclasses (via VcsDriverInterface trait)
- pub(crate) fn get_file_content(&self, file: &str, identifier: &str) -> anyhow::Result<Option<String>> {
+ pub(crate) fn get_file_content(
+ &self,
+ file: &str,
+ identifier: &str,
+ ) -> anyhow::Result<Option<String>> {
todo!()
}
- pub(crate) fn get_change_date(&self, identifier: &str) -> anyhow::Result<Option<chrono::DateTime<chrono::Utc>>> {
+ pub(crate) fn get_change_date(
+ &self,
+ identifier: &str,
+ ) -> anyhow::Result<Option<chrono::DateTime<chrono::Utc>>> {
todo!()
}
}
diff --git a/crates/shirabe/src/repository/vcs/vcs_driver_interface.rs b/crates/shirabe/src/repository/vcs/vcs_driver_interface.rs
index a17acad..5b15c2c 100644
--- a/crates/shirabe/src/repository/vcs/vcs_driver_interface.rs
+++ b/crates/shirabe/src/repository/vcs/vcs_driver_interface.rs
@@ -1,15 +1,18 @@
//! ref: composer/src/Composer/Repository/Vcs/VcsDriverInterface.php
+use crate::config::Config;
+use crate::io::io_interface::IOInterface;
use chrono::{DateTime, Utc};
use indexmap::IndexMap;
use shirabe_php_shim::PhpMixed;
-use crate::config::Config;
-use crate::io::io_interface::IOInterface;
pub trait VcsDriverInterface {
fn initialize(&mut self) -> anyhow::Result<()>;
- fn get_composer_information(&self, identifier: &str) -> anyhow::Result<Option<IndexMap<String, PhpMixed>>>;
+ fn get_composer_information(
+ &self,
+ identifier: &str,
+ ) -> anyhow::Result<Option<IndexMap<String, PhpMixed>>>;
fn get_file_content(&self, file: &str, identifier: &str) -> anyhow::Result<Option<String>>;
diff --git a/crates/shirabe/src/repository/vcs_repository.rs b/crates/shirabe/src/repository/vcs_repository.rs
index fcfd101..57e44a5 100644
--- a/crates/shirabe/src/repository/vcs_repository.rs
+++ b/crates/shirabe/src/repository/vcs_repository.rs
@@ -4,8 +4,8 @@ use anyhow::Result;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- array_search_mixed, count, get_class, in_array, str_replace, strpos, InvalidArgumentException,
- PhpMixed,
+ InvalidArgumentException, PhpMixed, array_search_mixed, count, get_class, in_array,
+ str_replace, strpos,
};
use shirabe_semver::constraint::constraint::Constraint;
@@ -135,7 +135,10 @@ impl VcsRepository {
});
let url = Platform::expand_path(
- repo_config.get("url").and_then(|v| v.as_string()).unwrap_or(""),
+ repo_config
+ .get("url")
+ .and_then(|v| v.as_string())
+ .unwrap_or(""),
);
repo_config.insert("url".to_string(), PhpMixed::String(url.clone()));
let r#type = repo_config
@@ -145,7 +148,8 @@ impl VcsRepository {
.to_string();
let is_verbose = io.is_verbose();
let is_very_verbose = io.is_very_verbose();
- let process_executor = process.unwrap_or_else(|| ProcessExecutor::new(Some(Box::new(&*io)), None));
+ let process_executor =
+ process.unwrap_or_else(|| ProcessExecutor::new(Some(Box::new(&*io)), None));
Ok(Self {
inner,
@@ -189,11 +193,7 @@ impl VcsRepository {
.unwrap_or(driver_class);
let _ = driver;
- format!(
- "vcs repo ({} {})",
- driver_type,
- Url::sanitize(&self.url)
- )
+ format!("vcs repo ({} {})", driver_type, Url::sanitize(&self.url))
}
pub fn get_repo_config(&self) -> &IndexMap<String, PhpMixed> {
@@ -292,7 +292,12 @@ impl VcsRepository {
let mut has_root_identifier_composer_json = false;
let root_identifier_result = self.driver.as_mut().unwrap().get_root_identifier();
if let Ok(root_identifier) = root_identifier_result {
- match self.driver.as_mut().unwrap().has_composer_file(&root_identifier) {
+ match self
+ .driver
+ .as_mut()
+ .unwrap()
+ .has_composer_file(&root_identifier)
+ {
Ok(b) => {
has_root_identifier_composer_json = b;
if has_root_identifier_composer_json {
@@ -348,7 +353,9 @@ impl VcsRepository {
let mut tag = tag;
let msg = format!(
"Reading composer.json of <info>{}</info> (<comment>{}</comment>)",
- self.package_name.clone().unwrap_or_else(|| self.url.clone()),
+ self.package_name
+ .clone()
+ .unwrap_or_else(|| self.url.clone()),
tag
);
@@ -411,14 +418,12 @@ impl VcsRepository {
// manually versioned package
if data.contains_key("version") {
- let normalized = self
- .version_parser
- .as_ref()
- .unwrap()
- .normalize(
- data.get("version").and_then(|v| v.as_string()).unwrap_or(""),
- None,
- )?;
+ let normalized = self.version_parser.as_ref().unwrap().normalize(
+ data.get("version")
+ .and_then(|v| v.as_string())
+ .unwrap_or(""),
+ None,
+ )?;
data.insert(
"version_normalized".to_string(),
PhpMixed::String(normalized),
@@ -438,7 +443,9 @@ impl VcsRepository {
PhpMixed::String(Preg::replace(
r"{[.-]?dev$}i",
"",
- data.get("version").and_then(|v| v.as_string()).unwrap_or(""),
+ data.get("version")
+ .and_then(|v| v.as_string())
+ .unwrap_or(""),
)),
);
data.insert(
@@ -503,16 +510,14 @@ impl VcsRepository {
}
if is_very_verbose {
- self.io.write_error(&format!(
- "Importing tag {} ({})",
- tag, version_normalized
- ));
+ self.io
+ .write_error(&format!("Importing tag {} ({})", tag, version_normalized));
}
let driver = self.driver.as_mut().unwrap();
let processed = self.pre_process(&**driver, data, &identifier)?;
let loaded = self.loader.as_ref().unwrap().load(processed, None)?;
- self.inner.add_package(Box::new(loaded as Box<dyn _>))?;
+ self.inner.add_package(Box::new(loaded))?;
Ok(())
})();
if let Err(e) = result {
@@ -575,7 +580,9 @@ impl VcsRepository {
for (branch, identifier) in branches {
let msg = format!(
"Reading composer.json of <info>{}</info> (<comment>{}</comment>)",
- self.package_name.clone().unwrap_or_else(|| self.url.clone()),
+ self.package_name
+ .clone()
+ .unwrap_or_else(|| self.url.clone()),
branch
);
if is_very_verbose {
@@ -609,7 +616,11 @@ impl VcsRepository {
version = format!("dev-{}", str_replace("#", "+", &branch));
parsed_branch = str_replace("#", "+", &parsed_branch);
} else {
- let prefix = if strpos(&branch, "v") == Some(0) { "v" } else { "" };
+ let prefix = if strpos(&branch, "v") == Some(0) {
+ "v"
+ } else {
+ ""
+ };
version = format!(
"{}{}",
prefix,
@@ -617,8 +628,7 @@ impl VcsRepository {
);
}
- let is_default_branch =
- self.driver.as_mut().unwrap().get_root_identifier()? == branch;
+ let is_default_branch = self.driver.as_mut().unwrap().get_root_identifier()? == branch;
let cached_package = self.get_cached_package_version(
&version,
&identifier,
@@ -666,26 +676,29 @@ impl VcsRepository {
self.io.write_error(&format!(
"Importing branch {} ({})",
branch,
- data.get("version").and_then(|v| v.as_string()).unwrap_or("")
+ data.get("version")
+ .and_then(|v| v.as_string())
+ .unwrap_or("")
));
}
let package_data = self.pre_process(&**driver, data, &identifier)?;
- let package = self.loader.as_ref().unwrap().load(package_data.clone(), None)?;
+ let package = self
+ .loader
+ .as_ref()
+ .unwrap()
+ .load(package_data.clone(), None)?;
// TODO(phase-b): `$this->loader instanceof ValidatingArrayLoader` downcast
let loader_as_validating: Option<&ValidatingArrayLoader> = None;
if let Some(validating) = loader_as_validating {
if count(&PhpMixed::Null) > 0 {
let _ = validating;
- return Err(InvalidPackageException::new(
- vec![],
- vec![],
- package_data,
- )
- .into());
+ return Err(
+ InvalidPackageException::new(vec![], vec![], package_data).into()
+ );
}
}
- self.inner.add_package(Box::new(package as Box<dyn _>))?;
+ self.inner.add_package(Box::new(package))?;
Ok(())
})();
if let Err(e) = result {
@@ -712,10 +725,8 @@ impl VcsRepository {
self.io.write_error("");
}
self.branch_error_occurred = true;
- self.io.write_error(&format!(
- "<error>Skipped branch {}, {}</error>",
- branch, e
- ));
+ self.io
+ .write_error(&format!("<error>Skipped branch {}, {}</error>", branch, e));
self.io.write_error("");
continue;
}
@@ -810,12 +821,10 @@ impl VcsRepository {
_ => None,
})
.unwrap_or(false);
- let source_reference = data
- .get("source")
- .and_then(|v| match v {
- PhpMixed::Array(m) => m.get("reference").cloned(),
- _ => None,
- });
+ let source_reference = data.get("source").and_then(|v| match v {
+ PhpMixed::Array(m) => m.get("reference").cloned(),
+ _ => None,
+ });
if dist_is_array && dist_lacks_reference && source_reference.is_some() {
if let Some(PhpMixed::Array(dist_map)) = data.get_mut("dist") {
dist_map.insert("reference".to_string(), source_reference.unwrap());
@@ -889,7 +898,9 @@ impl VcsRepository {
if let VersionCacheResult::Package(ref mut data) = cached_package {
let msg = format!(
"Found cached composer.json of <info>{}</info> (<comment>{}</comment>)",
- self.package_name.clone().unwrap_or_else(|| self.url.clone()),
+ self.package_name
+ .clone()
+ .unwrap_or_else(|| self.url.clone()),
version
);
if is_very_verbose {
@@ -908,7 +919,11 @@ impl VcsRepository {
data.insert("default-branch".to_string(), PhpMixed::Bool(true));
}
- let name = data.get("name").and_then(|v| v.as_string()).unwrap_or("").to_string();
+ let name = data
+ .get("name")
+ .and_then(|v| v.as_string())
+ .unwrap_or("")
+ .to_string();
let version_normalized = data
.get("version_normalized")
.and_then(|v| v.as_string())
@@ -930,7 +945,7 @@ impl VcsRepository {
if let VersionCacheResult::Package(data) = cached_package {
let loaded = self.loader.as_ref().unwrap().load(data, None)?;
- return Ok(CachedPackageResult::Package(Box::new(loaded as Box<dyn _>)));
+ return Ok(CachedPackageResult::Package(Box::new(loaded)));
}
Ok(CachedPackageResult::None)
diff --git a/crates/shirabe/src/repository/writable_array_repository.rs b/crates/shirabe/src/repository/writable_array_repository.rs
index 54e4b04..5d77fee 100644
--- a/crates/shirabe/src/repository/writable_array_repository.rs
+++ b/crates/shirabe/src/repository/writable_array_repository.rs
@@ -1,8 +1,8 @@
//! ref: composer/src/Composer/Repository/WritableArrayRepository.php
-use anyhow::Result;
use crate::installer::installation_manager::InstallationManager;
use crate::repository::array_repository::ArrayRepository;
+use anyhow::Result;
#[derive(Debug)]
pub struct WritableArrayRepository {
@@ -25,7 +25,11 @@ impl WritableArrayRepository {
&self.dev_package_names
}
- pub fn write(&mut self, dev_mode: bool, _installation_manager: &InstallationManager) -> Result<()> {
+ pub fn write(
+ &mut self,
+ dev_mode: bool,
+ _installation_manager: &InstallationManager,
+ ) -> Result<()> {
self.dev_mode = Some(dev_mode);
Ok(())
}
diff --git a/crates/shirabe/src/repository/writable_repository_interface.rs b/crates/shirabe/src/repository/writable_repository_interface.rs
index 3cb8b00..5648ef5 100644
--- a/crates/shirabe/src/repository/writable_repository_interface.rs
+++ b/crates/shirabe/src/repository/writable_repository_interface.rs
@@ -1,9 +1,9 @@
//! ref: composer/src/Composer/Repository/WritableRepositoryInterface.php
-use anyhow::Result;
use crate::installer::installation_manager::InstallationManager;
use crate::package::package_interface::PackageInterface;
use crate::repository::repository_interface::RepositoryInterface;
+use anyhow::Result;
pub trait WritableRepositoryInterface: RepositoryInterface {
fn write(&mut self, dev_mode: bool, installation_manager: &InstallationManager) -> Result<()>;
diff --git a/crates/shirabe/src/script/event.rs b/crates/shirabe/src/script/event.rs
index aeb63f0..4be0814 100644
--- a/crates/shirabe/src/script/event.rs
+++ b/crates/shirabe/src/script/event.rs
@@ -1,10 +1,10 @@
//! ref: composer/src/Composer/Script/Event.php
-use indexmap::IndexMap;
-use shirabe_php_shim::PhpMixed;
use crate::composer::Composer;
use crate::event_dispatcher::event::Event as BaseEvent;
use crate::io::io_interface::IOInterface;
+use indexmap::IndexMap;
+use shirabe_php_shim::PhpMixed;
#[derive(Debug)]
pub struct Event {
diff --git a/crates/shirabe/src/script/mod.rs b/crates/shirabe/src/script/mod.rs
new file mode 100644
index 0000000..9b83051
--- /dev/null
+++ b/crates/shirabe/src/script/mod.rs
@@ -0,0 +1,2 @@
+pub mod event;
+pub mod script_events;
diff --git a/crates/shirabe/src/self_update/mod.rs b/crates/shirabe/src/self_update/mod.rs
new file mode 100644
index 0000000..4f9f188
--- /dev/null
+++ b/crates/shirabe/src/self_update/mod.rs
@@ -0,0 +1,2 @@
+pub mod keys;
+pub mod versions;
diff --git a/crates/shirabe/src/self_update/versions.rs b/crates/shirabe/src/self_update/versions.rs
index bffb284..f5ba5d2 100644
--- a/crates/shirabe/src/self_update/versions.rs
+++ b/crates/shirabe/src/self_update/versions.rs
@@ -1,11 +1,14 @@
//! ref: composer/src/Composer/SelfUpdate/Versions.php
-use indexmap::IndexMap;
-use shirabe_external_packages::composer::pcre::preg::Preg;
-use shirabe_php_shim::{InvalidArgumentException, PhpMixed, UnexpectedValueException, PHP_EOL, PHP_VERSION, PHP_VERSION_ID};
use crate::config::Config;
use crate::io::io_interface::IOInterface;
use crate::util::http_downloader::HttpDownloader;
+use indexmap::IndexMap;
+use shirabe_external_packages::composer::pcre::preg::Preg;
+use shirabe_php_shim::{
+ InvalidArgumentException, PHP_EOL, PHP_VERSION, PHP_VERSION_ID, PhpMixed,
+ UnexpectedValueException,
+};
pub struct Versions {
pub channels: Vec<String>,
@@ -24,7 +27,8 @@ impl std::fmt::Debug for Versions {
}
impl Versions {
- pub const CHANNELS: &'static [&'static str] = &["stable", "preview", "snapshot", "1", "2", "2.2"];
+ pub const CHANNELS: &'static [&'static str] =
+ &["stable", "preview", "snapshot", "1", "2", "2.2"];
pub fn new(config: Config, http_downloader: HttpDownloader) -> Self {
Self {
@@ -54,7 +58,11 @@ impl Versions {
Ok("stable".to_string())
}
- pub fn set_channel(&mut self, channel: String, io: Option<&dyn IOInterface>) -> anyhow::Result<Result<(), InvalidArgumentException>> {
+ pub fn set_channel(
+ &mut self,
+ channel: String,
+ io: Option<&dyn IOInterface>,
+ ) -> anyhow::Result<Result<(), InvalidArgumentException>> {
if !Self::CHANNELS.contains(&channel.as_str()) {
return Ok(Err(InvalidArgumentException {
message: format!(
@@ -95,7 +103,10 @@ impl Versions {
Ok(Ok(()))
}
- pub fn get_latest(&mut self, channel: Option<&str>) -> anyhow::Result<Result<IndexMap<String, PhpMixed>, UnexpectedValueException>> {
+ pub fn get_latest(
+ &mut self,
+ channel: Option<&str>,
+ ) -> anyhow::Result<Result<IndexMap<String, PhpMixed>, UnexpectedValueException>> {
let versions = self.get_versions_data()?;
let effective_channel = match channel {
Some(c) => c.to_string(),
@@ -107,11 +118,12 @@ impl Versions {
if let PhpMixed::List(ref list) = **channel_versions {
for version in list {
if let PhpMixed::Array(ref v) = **version {
- let min_php = v.get("min-php")
- .and_then(|p| p.as_int())
- .unwrap_or(0);
+ let min_php = v.get("min-php").and_then(|p| p.as_int()).unwrap_or(0);
if min_php <= PHP_VERSION_ID {
- return Ok(Ok(v.iter().map(|(k, val)| (k.clone(), *val.clone())).collect()));
+ return Ok(Ok(v
+ .iter()
+ .map(|(k, val)| (k.clone(), *val.clone()))
+ .collect()));
}
}
}
@@ -139,7 +151,7 @@ impl Versions {
self.versions_data = Some(
self.http_downloader
.get(&format!("{}://getcomposer.org/versions", protocol))?
- .decode_json()?
+ .decode_json()?,
);
}
diff --git a/crates/shirabe/src/util/auth_helper.rs b/crates/shirabe/src/util/auth_helper.rs
index 6368e58..98c2471 100644
--- a/crates/shirabe/src/util/auth_helper.rs
+++ b/crates/shirabe/src/util/auth_helper.rs
@@ -4,9 +4,9 @@ use anyhow::Result;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- base64_encode, explode, in_array, is_array, is_string, json_decode, parse_url, sprintf,
- str_replace, strpos, strtolower, substr, trigger_error, trim, PhpMixed, E_USER_DEPRECATED,
- PHP_URL_HOST, PHP_URL_PATH, PHP_URL_SCHEME,
+ E_USER_DEPRECATED, PHP_URL_HOST, PHP_URL_PATH, PHP_URL_SCHEME, PhpMixed, base64_encode,
+ explode, in_array, is_array, is_string, json_decode, parse_url, sprintf, str_replace, strpos,
+ strtolower, substr, trigger_error, trim,
};
use crate::config::Config;
@@ -208,8 +208,7 @@ impl AuthHelper {
if let Some(arr) = decoded.as_array() {
if let Some(msg) = arr.get("message") {
if is_string(msg) {
- git_hub_api_message =
- msg.as_string().map(|s| s.to_string());
+ git_hub_api_message = msg.as_string().map(|s| s.to_string());
}
}
}
@@ -452,9 +451,7 @@ impl AuthHelper {
IOInterface::NORMAL,
);
let username = self.io.ask(" Username: ".to_string(), PhpMixed::Null);
- let password = self
- .io
- .ask_and_hide_answer(" Password: ".to_string());
+ let password = self.io.ask_and_hide_answer(" Password: ".to_string());
self.io.set_authentication(
origin.to_string(),
username.as_string().unwrap_or("").to_string(),
@@ -538,10 +535,7 @@ impl AuthHelper {
};
if !http_has_header {
if let Some(PhpMixed::Array(http)) = options.get_mut("http") {
- http.insert(
- "header".to_string(),
- Box::new(PhpMixed::List(vec![])),
- );
+ http.insert("header".to_string(), Box::new(PhpMixed::List(vec![])));
}
}
}
@@ -691,20 +685,14 @@ impl AuthHelper {
]),
true,
) {
- return self.add_authentication_options(
- options,
- &str_replace("api.", "", origin),
- url,
- );
+ return self.add_authentication_options(options, &str_replace("api.", "", origin), url);
}
// write headers back into options['http']['header']
if let Some(PhpMixed::Array(http)) = options.get_mut("http") {
http.insert(
"header".to_string(),
- Box::new(PhpMixed::List(
- headers.into_iter().map(Box::new).collect(),
- )),
+ Box::new(PhpMixed::List(headers.into_iter().map(Box::new).collect())),
);
}
diff --git a/crates/shirabe/src/util/bitbucket.rs b/crates/shirabe/src/util/bitbucket.rs
index 42bfea5..fd7aafc 100644
--- a/crates/shirabe/src/util/bitbucket.rs
+++ b/crates/shirabe/src/util/bitbucket.rs
@@ -1,10 +1,10 @@
//! ref: composer/src/Composer/Util/Bitbucket.php
use indexmap::IndexMap;
-use shirabe_php_shim::{time, LogicException, PhpMixed};
+use shirabe_php_shim::{LogicException, PhpMixed, time};
-use crate::config::config_source_interface::ConfigSourceInterface;
use crate::config::Config;
+use crate::config::config_source_interface::ConfigSourceInterface;
use crate::downloader::transport_exception::TransportException;
use crate::factory::Factory;
use crate::io::io_interface::IOInterface;
@@ -102,75 +102,71 @@ impl Bitbucket {
"retry-auth-failure".to_string(),
Box::new(PhpMixed::Bool(false)),
);
- options.insert(
- "http".to_string(),
- Box::new(PhpMixed::Array(http)),
- );
+ options.insert("http".to_string(), Box::new(PhpMixed::Array(http)));
let options = PhpMixed::Array(options);
- let response =
- match self
- .http_downloader
- .get(Self::OAUTH2_ACCESS_TOKEN_URL, &options)
- {
- Ok(r) => r,
- Err(te) => {
- if te.code == 400 {
- self.io.write_error(
- PhpMixed::String(
- "<error>Invalid OAuth consumer provided.</error>".to_string(),
- ),
- true,
- IOInterface::NORMAL,
- );
- self.io.write_error(
- PhpMixed::String("This can have three reasons:".to_string()),
- true,
- IOInterface::NORMAL,
- );
- self.io.write_error(
+ let response = match self
+ .http_downloader
+ .get(Self::OAUTH2_ACCESS_TOKEN_URL, &options)
+ {
+ Ok(r) => r,
+ Err(te) => {
+ if te.code == 400 {
+ self.io.write_error(
+ PhpMixed::String(
+ "<error>Invalid OAuth consumer provided.</error>".to_string(),
+ ),
+ true,
+ IOInterface::NORMAL,
+ );
+ self.io.write_error(
+ PhpMixed::String("This can have three reasons:".to_string()),
+ true,
+ IOInterface::NORMAL,
+ );
+ self.io.write_error(
PhpMixed::String(
"1. You are authenticating with a bitbucket username/password combination".to_string(),
),
true,
IOInterface::NORMAL,
);
- self.io.write_error(
+ self.io.write_error(
PhpMixed::String(
"2. You are using an OAuth consumer, but didn't configure a (dummy) callback url".to_string(),
),
true,
IOInterface::NORMAL,
);
- self.io.write_error(
+ self.io.write_error(
PhpMixed::String(
"3. You are using an OAuth consumer, but didn't configure it as private consumer".to_string(),
),
true,
IOInterface::NORMAL,
);
- return Ok(false);
- }
- if te.code == 403 || te.code == 401 {
- self.io.write_error(
- PhpMixed::String(
- "<error>Invalid OAuth consumer provided.</error>".to_string(),
- ),
- true,
- IOInterface::NORMAL,
- );
- self.io.write_error(
+ return Ok(false);
+ }
+ if te.code == 403 || te.code == 401 {
+ self.io.write_error(
+ PhpMixed::String(
+ "<error>Invalid OAuth consumer provided.</error>".to_string(),
+ ),
+ true,
+ IOInterface::NORMAL,
+ );
+ self.io.write_error(
PhpMixed::String(
"You can also add it manually later by using \"composer config --global --auth bitbucket-oauth.bitbucket.org <consumer-key> <consumer-secret>\"".to_string(),
),
true,
IOInterface::NORMAL,
);
- return Ok(false);
- }
- return Err(te.into());
+ return Ok(false);
}
- };
+ return Err(te.into());
+ }
+ };
let token = response.decode_json()?;
let token_map = match token {
@@ -196,12 +192,7 @@ impl Bitbucket {
}
.into());
}
- self.token = Some(
- token_map
- .into_iter()
- .map(|(k, v)| (k, *v))
- .collect(),
- );
+ self.token = Some(token_map.into_iter().map(|(k, v)| (k, *v)).collect());
Ok(true)
}
@@ -212,11 +203,8 @@ impl Bitbucket {
message: Option<&str>,
) -> anyhow::Result<bool> {
if let Some(msg) = message {
- self.io.write_error(
- PhpMixed::String(msg.to_string()),
- true,
- IOInterface::NORMAL,
- );
+ self.io
+ .write_error(PhpMixed::String(msg.to_string()), true, IOInterface::NORMAL);
}
let local_auth_config = self.config.get_local_auth_config_source();
@@ -227,11 +215,8 @@ impl Bitbucket {
true,
IOInterface::NORMAL,
);
- self.io.write_error(
- PhpMixed::String(url.to_string()),
- true,
- IOInterface::NORMAL,
- );
+ self.io
+ .write_error(PhpMixed::String(url.to_string()), true, IOInterface::NORMAL);
let auth_config_source_name = self.config.get_auth_config_source().get_name();
let local_name_prefix = local_auth_config
.as_ref()
@@ -271,9 +256,7 @@ impl Bitbucket {
if consumer_key.is_empty() {
self.io.write_error(
- PhpMixed::String(
- "<warning>No consumer key given, aborting.</warning>".to_string(),
- ),
+ PhpMixed::String("<warning>No consumer key given, aborting.</warning>".to_string()),
true,
IOInterface::NORMAL,
);
@@ -322,7 +305,8 @@ impl Bitbucket {
return Ok(false);
}
- let use_local = store_in_local_auth_config && self.config.get_local_auth_config_source().is_some();
+ let use_local =
+ store_in_local_auth_config && self.config.get_local_auth_config_source().is_some();
if use_local {
let mut auth_config_source = self.config.get_local_auth_config_source().unwrap();
self.store_in_auth_config(
@@ -428,9 +412,7 @@ impl Bitbucket {
.remove_config_setting(&format!("bitbucket-oauth.{}", origin_url))?;
let token = self.token.as_ref().ok_or_else(|| LogicException {
- message: format!(
- "Expected a token configured with expires_in present, got null",
- ),
+ message: format!("Expected a token configured with expires_in present, got null",),
code: 0,
})?;
let expires_in = token
@@ -438,7 +420,10 @@ impl Bitbucket {
.and_then(|v| v.as_int())
.ok_or_else(|| {
let token_mixed = PhpMixed::Array(
- token.iter().map(|(k, v)| (k.clone(), Box::new(v.clone()))).collect(),
+ token
+ .iter()
+ .map(|(k, v)| (k.clone(), Box::new(v.clone())))
+ .collect(),
);
LogicException {
message: format!(
@@ -461,24 +446,17 @@ impl Bitbucket {
);
consumer.insert(
"access-token".to_string(),
- Box::new(
- token
- .get("access_token")
- .cloned()
- .unwrap_or(PhpMixed::Null),
- ),
+ Box::new(token.get("access_token").cloned().unwrap_or(PhpMixed::Null)),
);
consumer.insert(
"access-token-expiration".to_string(),
Box::new(PhpMixed::Int(t + expires_in)),
);
- self.config
- .get_auth_config_source()
- .add_config_setting(
- &format!("bitbucket-oauth.{}", origin_url),
- PhpMixed::Array(consumer),
- )?;
+ self.config.get_auth_config_source().add_config_setting(
+ &format!("bitbucket-oauth.{}", origin_url),
+ PhpMixed::Array(consumer),
+ )?;
Ok(())
}
diff --git a/crates/shirabe/src/util/composer_mirror.rs b/crates/shirabe/src/util/composer_mirror.rs
index 1ec3e56..0743e9f 100644
--- a/crates/shirabe/src/util/composer_mirror.rs
+++ b/crates/shirabe/src/util/composer_mirror.rs
@@ -39,7 +39,10 @@ impl ComposerMirror {
to.push(pv);
}
- let url = from.iter().zip(to.iter()).fold(mirror_url.to_string(), |acc, (f, t)| acc.replace(f, t));
+ let url = from
+ .iter()
+ .zip(to.iter())
+ .fold(mirror_url.to_string(), |acc, (f, t)| acc.replace(f, t));
assert!(!url.is_empty());
url
}
@@ -50,9 +53,14 @@ impl ComposerMirror {
url: &str,
r#type: Option<&str>,
) -> String {
- let normalized_url = if let Some(m) = Preg::match_(r"^(?:(?:https?|git)://github\.com/|git@github\.com:)([^/]+)/(.+?)(?:\.git)?$", url) {
+ let normalized_url = if let Some(m) = Preg::match_(
+ r"^(?:(?:https?|git)://github\.com/|git@github\.com:)([^/]+)/(.+?)(?:\.git)?$",
+ url,
+ ) {
format!("gh-{}/{}", m[1], m[2])
- } else if let Some(m) = Preg::match_(r"^https://bitbucket\.org/([^/]+)/(.+?)(?:\.git)?/?$", url) {
+ } else if let Some(m) =
+ Preg::match_(r"^https://bitbucket\.org/([^/]+)/(.+?)(?:\.git)?/?$", url)
+ {
format!("bb-{}/{}", m[1], m[2])
} else {
Preg::replace(r"[^a-z0-9_.-]", "-", url.trim_matches('/'))
@@ -64,12 +72,7 @@ impl ComposerMirror {
.fold(mirror_url.to_string(), |acc, (f, t)| acc.replace(f, t))
}
- pub fn process_hg_url(
- mirror_url: &str,
- package_name: &str,
- url: &str,
- r#type: &str,
- ) -> String {
+ pub fn process_hg_url(mirror_url: &str, package_name: &str, url: &str, r#type: &str) -> String {
Self::process_git_url(mirror_url, package_name, url, Some(r#type))
}
}
diff --git a/crates/shirabe/src/util/config_validator.rs b/crates/shirabe/src/util/config_validator.rs
index c5636ad..cbba32b 100644
--- a/crates/shirabe/src/util/config_validator.rs
+++ b/crates/shirabe/src/util/config_validator.rs
@@ -1,17 +1,17 @@
//! ref: composer/src/Composer/Util/ConfigValidator.php
-use indexmap::IndexMap;
-use shirabe_php_shim::PhpMixed;
-use shirabe_external_packages::composer::pcre::preg::Preg;
-use shirabe_external_packages::composer::spdx_licenses::spdx_licenses::SpdxLicenses;
-use shirabe_external_packages::seld::json_lint::duplicate_key_exception::DuplicateKeyException;
-use shirabe_external_packages::seld::json_lint::json_parser::JsonParser;
use crate::io::io_interface::IOInterface;
use crate::json::json_file::JsonFile;
use crate::json::json_validation_exception::JsonValidationException;
use crate::package::loader::array_loader::ArrayLoader;
use crate::package::loader::invalid_package_exception::InvalidPackageException;
use crate::package::loader::validating_array_loader::ValidatingArrayLoader;
+use indexmap::IndexMap;
+use shirabe_external_packages::composer::pcre::preg::Preg;
+use shirabe_external_packages::composer::spdx_licenses::spdx_licenses::SpdxLicenses;
+use shirabe_external_packages::seld::json_lint::duplicate_key_exception::DuplicateKeyException;
+use shirabe_external_packages::seld::json_lint::json_parser::JsonParser;
+use shirabe_php_shim::PhpMixed;
#[derive(Debug)]
pub struct ConfigValidator {
@@ -25,7 +25,12 @@ impl ConfigValidator {
Self { io }
}
- pub fn validate(&self, file: &str, array_loader_validation_flags: i64, flags: i64) -> (Vec<String>, Vec<String>, Vec<String>) {
+ pub fn validate(
+ &self,
+ file: &str,
+ array_loader_validation_flags: i64,
+ flags: i64,
+ ) -> (Vec<String>, Vec<String>, Vec<String>) {
let mut errors: Vec<String> = Vec::new();
let mut publish_errors: Vec<String> = Vec::new();
let mut warnings: Vec<String> = Vec::new();
@@ -71,7 +76,10 @@ impl ConfigValidator {
Err(e) => {
if let Some(dup_e) = e.downcast_ref::<DuplicateKeyException>() {
let details = dup_e.get_details();
- warnings.push(format!("Key {} is a duplicate in {} at line {}", details["key"], file, details["line"]));
+ warnings.push(format!(
+ "Key {} is a duplicate in {} at line {}",
+ details["key"], file, details["line"]
+ ));
}
}
}
@@ -83,20 +91,34 @@ impl ConfigValidator {
};
// validate actual data
- if manifest.get("license").map_or(true, |v| matches!(v, PhpMixed::Null)) || !manifest.contains_key("license") {
+ if manifest
+ .get("license")
+ .map_or(true, |v| matches!(v, PhpMixed::Null))
+ || !manifest.contains_key("license")
+ {
warnings.push("No license specified, it is recommended to do so. For closed-source software you may use \"proprietary\" as license.".to_string());
} else {
let license_val = manifest.get("license").unwrap();
let licenses: Vec<String> = match license_val {
PhpMixed::String(s) => vec![s.clone()],
- PhpMixed::List(list) => list.iter().filter_map(|v| {
- if let PhpMixed::String(s) = v.as_ref() { Some(s.clone()) } else { None }
- }).collect(),
+ PhpMixed::List(list) => list
+ .iter()
+ .filter_map(|v| {
+ if let PhpMixed::String(s) = v.as_ref() {
+ Some(s.clone())
+ } else {
+ None
+ }
+ })
+ .collect(),
_ => Vec::new(),
};
// strip proprietary since it's not a valid SPDX identifier, but is accepted by composer
- let licenses: Vec<String> = licenses.into_iter().filter(|l| l != "proprietary").collect();
+ let licenses: Vec<String> = licenses
+ .into_iter()
+ .filter(|l| l != "proprietary")
+ .collect();
let license_validator = SpdxLicenses::new();
for license in &licenses {
@@ -131,7 +153,11 @@ impl ConfigValidator {
if let Some(PhpMixed::String(name)) = manifest.get("name") {
if !name.is_empty() && Preg::is_match(r"{[A-Z]}", name) {
- let suggest_name = Preg::replace(r"{(?:([a-z])([A-Z])|([A-Z])([A-Z][a-z]))}", r"\1\3-\2\4", name);
+ let suggest_name = Preg::replace(
+ r"{(?:([a-z])([A-Z])|([A-Z])([A-Z][a-z]))}",
+ r"\1\3-\2\4",
+ name,
+ );
let suggest_name = suggest_name.to_lowercase();
publish_errors.push(format!(
@@ -148,14 +174,21 @@ impl ConfigValidator {
}
// check for require-dev overrides
- if let (Some(PhpMixed::Array(require)), Some(PhpMixed::Array(require_dev))) = (manifest.get("require"), manifest.get("require-dev")) {
- let require_overrides: Vec<String> = require.keys()
+ if let (Some(PhpMixed::Array(require)), Some(PhpMixed::Array(require_dev))) =
+ (manifest.get("require"), manifest.get("require-dev"))
+ {
+ let require_overrides: Vec<String> = require
+ .keys()
.filter(|k| require_dev.contains_key(*k))
.cloned()
.collect();
if !require_overrides.is_empty() {
- let plural = if require_overrides.len() > 1 { "are" } else { "is" };
+ let plural = if require_overrides.len() > 1 {
+ "are"
+ } else {
+ "is"
+ };
warnings.push(format!(
"{} {} required both in require and require-dev, this can lead to unexpected behavior",
require_overrides.join(", "),
@@ -250,13 +283,21 @@ impl ConfigValidator {
}
}
- let loader = ValidatingArrayLoader::new(ArrayLoader::new(), true, None, array_loader_validation_flags);
+ let loader = ValidatingArrayLoader::new(
+ ArrayLoader::new(),
+ true,
+ None,
+ array_loader_validation_flags,
+ );
let mut manifest_for_load = manifest.clone();
if !manifest_for_load.contains_key("version") {
manifest_for_load.insert("version".to_string(), PhpMixed::String("1.0.0".to_string()));
}
if !manifest_for_load.contains_key("name") {
- manifest_for_load.insert("name".to_string(), PhpMixed::String("dummy/dummy".to_string()));
+ manifest_for_load.insert(
+ "name".to_string(),
+ PhpMixed::String("dummy/dummy".to_string()),
+ );
}
match loader.load(manifest_for_load) {
Ok(_) => {}
diff --git a/crates/shirabe/src/util/error_handler.rs b/crates/shirabe/src/util/error_handler.rs
index 2f8c699..aff263e 100644
--- a/crates/shirabe/src/util/error_handler.rs
+++ b/crates/shirabe/src/util/error_handler.rs
@@ -1,12 +1,12 @@
//! ref: composer/src/Composer/Util/ErrorHandler.php
-use std::sync::{Mutex, OnceLock};
+use crate::io::io_interface::IOInterface;
use shirabe_php_shim::{
- debug_backtrace, error_reporting, filter_var, ini_get, is_resource,
- set_error_handler, E_ALL, E_DEPRECATED, E_USER_DEPRECATED, E_WARNING, E_USER_WARNING,
- FILTER_VALIDATE_BOOLEAN, PHP_EOL, STDERR, PhpMixed, ErrorException,
+ E_ALL, E_DEPRECATED, E_USER_DEPRECATED, E_USER_WARNING, E_WARNING, ErrorException,
+ FILTER_VALIDATE_BOOLEAN, PHP_EOL, PhpMixed, STDERR, debug_backtrace, error_reporting,
+ filter_var, ini_get, is_resource, set_error_handler,
};
-use crate::io::io_interface::IOInterface;
+use std::sync::{Mutex, OnceLock};
static IO: OnceLock<Mutex<Option<Box<dyn IOInterface + Send>>>> = OnceLock::new();
static HAS_SHOWN_DEPRECATION_NOTICE: Mutex<i64> = Mutex::new(0);
@@ -18,7 +18,12 @@ fn io() -> &'static Mutex<Option<Box<dyn IOInterface + Send>>> {
pub struct ErrorHandler;
impl ErrorHandler {
- pub fn handle(level: i64, message: String, file: String, line: i64) -> Result<bool, ErrorException> {
+ pub fn handle(
+ level: i64,
+ message: String,
+ file: String,
+ line: i64,
+ ) -> Result<bool, ErrorException> {
let is_deprecation_notice = level == E_DEPRECATED || level == E_USER_DEPRECATED;
// error code is not included in error_reporting
@@ -37,10 +42,15 @@ impl ErrorHandler {
// ignore some newly introduced warnings in new php versions until dependencies
// can be fixed as we do not want to abort execution for those
if (level == E_WARNING || level == E_USER_WARNING)
- && message.contains("should either be used or intentionally ignored by casting it as (void)")
+ && message.contains(
+ "should either be used or intentionally ignored by casting it as (void)",
+ )
{
Self::output_warning(
- &format!("Ignored new PHP warning but it should be reported and fixed: {} in {}:{}", message, file, line),
+ &format!(
+ "Ignored new PHP warning but it should be reported and fixed: {} in {}:{}",
+ message, file, line
+ ),
true,
);
return Ok(true);
@@ -67,7 +77,10 @@ impl ErrorHandler {
}
*HAS_SHOWN_DEPRECATION_NOTICE.lock().unwrap() = 1;
drop(io_guard);
- Self::output_warning(&format!("Deprecation Notice: {} in {}:{}", message, file, line), false);
+ Self::output_warning(
+ &format!("Deprecation Notice: {} in {}:{}", message, file, line),
+ false,
+ );
}
Ok(true)
@@ -92,7 +105,10 @@ impl ErrorHandler {
.skip(2)
.filter_map(|frame| {
let line = frame.get("line").and_then(|v| v.as_int());
- let file = frame.get("file").and_then(|v| v.as_string()).map(|s| s.to_string());
+ let file = frame
+ .get("file")
+ .and_then(|v| v.as_string())
+ .map(|s| s.to_string());
if let (Some(line), Some(file)) = (line, file) {
Some(format!("<warning> {}:{}</warning>", file, line))
} else {
@@ -110,7 +126,11 @@ impl ErrorHandler {
if output_even_without_io {
if is_resource(&PhpMixed::Int(STDERR)) {
- shirabe_php_shim::fwrite(PhpMixed::Int(STDERR), &format!("Warning: {}{}", message, PHP_EOL), -1);
+ shirabe_php_shim::fwrite(
+ PhpMixed::Int(STDERR),
+ &format!("Warning: {}{}", message, PHP_EOL),
+ -1,
+ );
} else {
print!("Warning: {}{}", message, PHP_EOL);
}
diff --git a/crates/shirabe/src/util/filesystem.rs b/crates/shirabe/src/util/filesystem.rs
index 98a54c4..6ca20cc 100644
--- a/crates/shirabe/src/util/filesystem.rs
+++ b/crates/shirabe/src/util/filesystem.rs
@@ -5,14 +5,14 @@ use shirabe_external_packages::react::promise::promise_interface::PromiseInterfa
use shirabe_external_packages::symfony::component::filesystem::exception::io_exception::IOException;
use shirabe_external_packages::symfony::component::finder::finder::Finder;
use shirabe_php_shim::{
- array_pop, basename, chdir, clearstatcache, copy, count, dirname, end, error_get_last,
- explode, fclose, feof, file_exists, file_get_contents, file_put_contents, filemtime, fileatime,
- filesize, fopen, fread, function_exists, fwrite, implode, is_array, is_dir, is_file, is_link,
- is_readable, lstat, mkdir, react_promise_resolve, rename, rmdir, rtrim, sprintf,
- str_contains, str_repeat, str_replace, str_starts_with, strlen, strpos, strtolower,
- strtoupper, strtr, substr, substr_count, symlink, touch, unlink, usleep, var_export,
DIRECTORY_SEPARATOR, ErrorException, InvalidArgumentException, LogicException, PhpMixed,
- RuntimeException, UnexpectedValueException,
+ RuntimeException, UnexpectedValueException, array_pop, basename, chdir, clearstatcache, copy,
+ count, dirname, end, error_get_last, explode, fclose, feof, file_exists, file_get_contents,
+ file_put_contents, fileatime, filemtime, filesize, fopen, fread, function_exists, fwrite,
+ implode, is_array, is_dir, is_file, is_link, is_readable, lstat, mkdir, react_promise_resolve,
+ rename, rmdir, rtrim, sprintf, str_contains, str_repeat, str_replace, str_starts_with, strlen,
+ strpos, strtolower, strtoupper, strtr, substr, substr_count, symlink, touch, unlink, usleep,
+ var_export,
};
use crate::util::platform::Platform;
@@ -54,7 +54,11 @@ impl Filesystem {
count(&finder) == 0
}
- pub fn empty_directory(&mut self, dir: &str, ensure_directory_exists: bool) -> anyhow::Result<()> {
+ pub fn empty_directory(
+ &mut self,
+ dir: &str,
+ ensure_directory_exists: bool,
+ ) -> anyhow::Result<()> {
if is_link(dir) && file_exists(dir) {
self.unlink(dir)?;
}
@@ -115,7 +119,10 @@ impl Filesystem {
///
/// Uses the process component if proc_open is enabled on the PHP
/// installation.
- pub fn remove_directory_async(&mut self, directory: &str) -> anyhow::Result<Box<dyn PromiseInterface>> {
+ pub fn remove_directory_async(
+ &mut self,
+ directory: &str,
+ ) -> anyhow::Result<Box<dyn PromiseInterface>> {
let edge_case_result = self.remove_edge_cases(directory, true)?;
if let Some(r) = edge_case_result {
return Ok(react_promise_resolve(PhpMixed::Bool(r)));
@@ -136,25 +143,38 @@ impl Filesystem {
let directory_owned = directory.to_string();
// TODO(plugin): closure capture of $this in PHP — port wires the same logic via a callback handle.
- Ok(promise.then(Box::new(move |process: PhpMixed| -> Box<dyn PromiseInterface> {
- // clear stat cache because external processes aren't tracked by the php stat cache
- clearstatcache(false, "");
+ Ok(promise.then(Box::new(
+ move |process: PhpMixed| -> Box<dyn PromiseInterface> {
+ // clear stat cache because external processes aren't tracked by the php stat cache
+ clearstatcache(false, "");
- let is_successful = process.as_object().map(|o| o.call_method("isSuccessful", &[]).as_bool().unwrap_or(false)).unwrap_or(false);
- if is_successful && !is_dir(&directory_owned) {
- return react_promise_resolve(PhpMixed::Bool(true));
- }
+ let is_successful = process
+ .as_object()
+ .map(|o| {
+ o.call_method("isSuccessful", &[])
+ .as_bool()
+ .unwrap_or(false)
+ })
+ .unwrap_or(false);
+ if is_successful && !is_dir(&directory_owned) {
+ return react_promise_resolve(PhpMixed::Bool(true));
+ }
- // PHP: \React\Promise\resolve($this->removeDirectoryPhp($directory))
- // The recursive PHP call doesn't have a clean async equivalent; we resort to a sync call.
- let mut fs = Filesystem::new(None);
- let res = fs.remove_directory_php(&directory_owned).unwrap_or(false);
- react_promise_resolve(PhpMixed::Bool(res))
- })))
+ // PHP: \React\Promise\resolve($this->removeDirectoryPhp($directory))
+ // The recursive PHP call doesn't have a clean async equivalent; we resort to a sync call.
+ let mut fs = Filesystem::new(None);
+ let res = fs.remove_directory_php(&directory_owned).unwrap_or(false);
+ react_promise_resolve(PhpMixed::Bool(res))
+ },
+ )))
}
/// Returns null when no edge case was hit. Otherwise a bool whether removal was successful
- fn remove_edge_cases(&mut self, directory: &str, fallback_to_php: bool) -> anyhow::Result<Option<bool>> {
+ fn remove_edge_cases(
+ &mut self,
+ directory: &str,
+ fallback_to_php: bool,
+ ) -> anyhow::Result<Option<bool>> {
if self.is_symlinked_directory(directory) {
return Ok(Some(self.unlink_symlinked_directory(directory)?));
}
@@ -198,7 +218,8 @@ impl Filesystem {
}
// PHP: $it = new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS);
- let mut it_result = shirabe_php_shim::recursive_directory_iterator(directory, shirabe_php_shim::SKIP_DOTS);
+ let mut it_result =
+ shirabe_php_shim::recursive_directory_iterator(directory, shirabe_php_shim::SKIP_DOTS);
if let Err(e) = &it_result {
if e.downcast_ref::<UnexpectedValueException>().is_some() {
// re-try once after clearing the stat cache if it failed as it
@@ -208,7 +229,10 @@ impl Filesystem {
if !is_dir(directory) {
return Ok(true);
}
- it_result = shirabe_php_shim::recursive_directory_iterator(directory, shirabe_php_shim::SKIP_DOTS);
+ it_result = shirabe_php_shim::recursive_directory_iterator(
+ directory,
+ shirabe_php_shim::SKIP_DOTS,
+ );
}
}
let it = it_result?;
@@ -243,7 +267,10 @@ impl Filesystem {
message: format!(
"Could not delete symbolic link {}: {}",
directory,
- error_get_last().get("message").and_then(|v| v.as_string()).unwrap_or("")
+ error_get_last()
+ .get("message")
+ .and_then(|v| v.as_string())
+ .unwrap_or("")
),
code: 0,
}
@@ -255,7 +282,10 @@ impl Filesystem {
message: format!(
"{} does not exist and could not be created: {}",
directory,
- error_get_last().get("message").and_then(|v| v.as_string()).unwrap_or("")
+ error_get_last()
+ .get("message")
+ .and_then(|v| v.as_string())
+ .unwrap_or("")
),
code: 0,
};
@@ -293,7 +323,10 @@ impl Filesystem {
let mut message = format!(
"Could not delete {}: {}",
path,
- error.get("message").and_then(|v| v.as_string()).unwrap_or("")
+ error
+ .get("message")
+ .and_then(|v| v.as_string())
+ .unwrap_or("")
);
if Platform::is_windows() {
message.push_str("\nThis can be due to an antivirus or the Windows Search Indexer locking the file while they are analyzed");
@@ -321,7 +354,10 @@ impl Filesystem {
let mut message = format!(
"Could not delete {}: {}",
path,
- error.get("message").and_then(|v| v.as_string()).unwrap_or("")
+ error
+ .get("message")
+ .and_then(|v| v.as_string())
+ .unwrap_or("")
);
if Platform::is_windows() {
message.push_str("\nThis can be due to an antivirus or the Windows Search Indexer locking the file while they are analyzed");
@@ -356,7 +392,8 @@ impl Filesystem {
let target = self.normalize_path(target);
if !is_dir(source) {
- let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| copy(source, &target)));
+ let result =
+ std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| copy(source, &target)));
match result {
Ok(b) => return Ok(b),
Err(payload) => {
@@ -390,7 +427,8 @@ impl Filesystem {
}
}
- let it = shirabe_php_shim::recursive_directory_iterator(source, shirabe_php_shim::SKIP_DOTS)?;
+ let it =
+ shirabe_php_shim::recursive_directory_iterator(source, shirabe_php_shim::SKIP_DOTS)?;
let ri = shirabe_php_shim::recursive_iterator_iterator(it, shirabe_php_shim::SELF_FIRST);
self.ensure_directory_exists(&target)?;
@@ -461,7 +499,13 @@ impl Filesystem {
}
/// Returns the shortest path from $from to $to
- pub fn find_shortest_path(&self, from: &str, to: &str, directories: bool, prefer_relative: bool) -> String {
+ pub fn find_shortest_path(
+ &self,
+ from: &str,
+ to: &str,
+ directories: bool,
+ prefer_relative: bool,
+ ) -> String {
if !self.is_absolute_path(from) || !self.is_absolute_path(to) {
// PHP throws InvalidArgumentException
// Returning early-formatted Result is not possible without changing signature; panic to surface in tests.
@@ -499,7 +543,8 @@ impl Filesystem {
}
common_path = format!("{}/", rtrim(&common_path, "/"));
- let source_path_depth = substr_count(&substr(&from, strlen(&common_path) as isize, None), "/");
+ let source_path_depth =
+ substr_count(&substr(&from, strlen(&common_path) as isize, None), "/");
let common_path_code = str_repeat("../", source_path_depth);
// allow top level /foo & /bar dirs to be addressed relatively as this is common in Docker setups
@@ -507,7 +552,11 @@ impl Filesystem {
return to;
}
- let result = format!("{}{}", common_path_code, substr(&to, strlen(&common_path) as isize, None));
+ let result = format!(
+ "{}{}",
+ common_path_code,
+ substr(&to, strlen(&common_path) as isize, None)
+ );
if strlen(&result) == 0 {
return "./".to_string();
}
@@ -516,7 +565,14 @@ impl Filesystem {
}
/// Returns PHP code that, when executed in $from, will return the path to $to
- pub fn find_shortest_path_code(&self, from: &str, to: &str, directories: bool, static_code: bool, prefer_relative: bool) -> String {
+ pub fn find_shortest_path_code(
+ &self,
+ from: &str,
+ to: &str,
+ directories: bool,
+ static_code: bool,
+ prefer_relative: bool,
+ ) -> String {
if !self.is_absolute_path(from) || !self.is_absolute_path(to) {
panic!(
"{}",
@@ -552,11 +608,15 @@ impl Filesystem {
if str_starts_with(&to, &format!("{}/", from)) {
return format!(
"__DIR__ . {}",
- var_export(&PhpMixed::String(substr(&to, strlen(&from) as isize, None)), true)
+ var_export(
+ &PhpMixed::String(substr(&to, strlen(&from) as isize, None)),
+ true
+ )
);
}
- let source_path_depth = (substr_count(&substr(&from, strlen(&common_path) as isize, None), "/") as i64)
- + (if directories { 1 } else { 0 });
+ let source_path_depth =
+ (substr_count(&substr(&from, strlen(&common_path) as isize, None), "/") as i64)
+ + (if directories { 1 } else { 0 });
// allow top level /foo & /bar dirs to be addressed relatively as this is common in Docker setups
if !prefer_relative && "/" == common_path && source_path_depth > 1 {
@@ -564,7 +624,10 @@ impl Filesystem {
}
let common_path_code = if static_code {
- format!("__DIR__ . '{}'", str_repeat("/..", source_path_depth as usize))
+ format!(
+ "__DIR__ . '{}'",
+ str_repeat("/..", source_path_depth as usize)
+ )
} else {
format!(
"{}{}{}",
@@ -683,10 +746,20 @@ impl Filesystem {
// on windows, \\foo indicates network paths so we exclude those from local paths, however it is unsafe
// on linux as file:////foo (which would be a network path \\foo on windows) will resolve to /foo which could be a local path
if Platform::is_windows() {
- return Preg::is_match("{^(file://(?!//)|/(?!/)|/?[a-z]:[\\\\/]|\\.\\.[\\\\/]|[a-z0-9_.-]+[\\\\/])}i", path, None).unwrap_or(false);
+ return Preg::is_match(
+ "{^(file://(?!//)|/(?!/)|/?[a-z]:[\\\\/]|\\.\\.[\\\\/]|[a-z0-9_.-]+[\\\\/])}i",
+ path,
+ None,
+ )
+ .unwrap_or(false);
}
- Preg::is_match("{^(file://|/|/?[a-z]:[\\\\/]|\\.\\.[\\\\/]|[a-z0-9_.-]+[\\\\/])}i", path, None).unwrap_or(false)
+ Preg::is_match(
+ "{^(file://|/|/?[a-z]:[\\\\/]|\\.\\.[\\\\/]|[a-z0-9_.-]+[\\\\/])}i",
+ path,
+ None,
+ )
+ .unwrap_or(false)
}
pub fn get_platform_path(path: &str) -> String {
@@ -708,15 +781,12 @@ impl Filesystem {
}
if is_file(path) {
- return Silencer::call(|| {
- Ok(file_get_contents(path).is_some())
- }).unwrap_or(false);
+ return Silencer::call(|| Ok(file_get_contents(path).is_some())).unwrap_or(false);
}
if is_dir(path) {
- return Silencer::call(|| {
- Ok(shirabe_php_shim::opendir(path).is_some())
- }).unwrap_or(false);
+ return Silencer::call(|| Ok(shirabe_php_shim::opendir(path).is_some()))
+ .unwrap_or(false);
}
// assume false otherwise
@@ -724,7 +794,9 @@ impl Filesystem {
}
pub(crate) fn directory_size(&self, directory: &str) -> i64 {
- let it = shirabe_php_shim::recursive_directory_iterator(directory, shirabe_php_shim::SKIP_DOTS).unwrap();
+ let it =
+ shirabe_php_shim::recursive_directory_iterator(directory, shirabe_php_shim::SKIP_DOTS)
+ .unwrap();
let ri = shirabe_php_shim::recursive_iterator_iterator(it, shirabe_php_shim::CHILD_FIRST);
let mut size: i64 = 0;
@@ -809,14 +881,20 @@ impl Filesystem {
pub fn junction(&mut self, target: &str, junction: &str) -> anyhow::Result<()> {
if !Platform::is_windows() {
return Err(LogicException {
- message: format!("Function {} is not available on non-Windows platform", "Composer\\Util\\Filesystem"),
+ message: format!(
+ "Function {} is not available on non-Windows platform",
+ "Composer\\Util\\Filesystem"
+ ),
code: 0,
}
.into());
}
if !is_dir(target) {
return Err(IOException::new(
- format!("Cannot junction to \"{}\" as it is not a directory.", target),
+ format!(
+ "Cannot junction to \"{}\" as it is not a directory.",
+ target
+ ),
0,
None,
Some(target.to_string()),
@@ -838,7 +916,10 @@ impl Filesystem {
let mut output = String::new();
if self.get_process().execute(&cmd, &mut output) != 0 {
return Err(IOException::new(
- format!("Failed to create junction to \"{}\" at \"{}\".", target, junction),
+ format!(
+ "Failed to create junction to \"{}\" at \"{}\".",
+ target, junction
+ ),
0,
None,
Some(target.to_string()),
@@ -891,10 +972,16 @@ impl Filesystem {
if !Platform::is_windows() {
return Ok(false);
}
- let junction = rtrim(&str_replace("/", DIRECTORY_SEPARATOR, junction), DIRECTORY_SEPARATOR);
+ let junction = rtrim(
+ &str_replace("/", DIRECTORY_SEPARATOR, junction),
+ DIRECTORY_SEPARATOR,
+ );
if !self.is_junction(&junction) {
return Err(IOException::new(
- format!("{} is not a junction and thus cannot be removed as one", junction),
+ format!(
+ "{} is not a junction and thus cannot be removed as one",
+ junction
+ ),
0,
None,
None,
@@ -906,7 +993,8 @@ impl Filesystem {
}
pub fn file_put_contents_if_modified(&self, path: &str, content: &str) -> anyhow::Result<i64> {
- let current_content = Silencer::call(|| Ok(file_get_contents(path).unwrap_or_default())).unwrap_or_default();
+ let current_content =
+ Silencer::call(|| Ok(file_get_contents(path).unwrap_or_default())).unwrap_or_default();
if current_content.is_empty() || current_content != content {
return Ok(file_put_contents(path, content) as i64);
}
@@ -917,8 +1005,10 @@ impl Filesystem {
/// Copy file using stream_copy_to_stream to work around https://bugs.php.net/bug.php?id=6463
pub fn safe_copy(&self, source: &str, target: &str) -> anyhow::Result<()> {
if !file_exists(target) || !file_exists(source) || !self.files_are_equal(source, target) {
- let source_handle = fopen(source, "r").ok_or_else(|| anyhow::anyhow!("Could not open \"{}\" for reading.", source))?;
- let target_handle = fopen(target, "w+").ok_or_else(|| anyhow::anyhow!("Could not open \"{}\" for writing.", target))?;
+ let source_handle = fopen(source, "r")
+ .ok_or_else(|| anyhow::anyhow!("Could not open \"{}\" for reading.", source))?;
+ let target_handle = fopen(target, "w+")
+ .ok_or_else(|| anyhow::anyhow!("Could not open \"{}\" for writing.", target))?;
shirabe_php_shim::stream_copy_to_stream(&source_handle, &target_handle);
fclose(&source_handle);
diff --git a/crates/shirabe/src/util/forgejo.rs b/crates/shirabe/src/util/forgejo.rs
index 56265b7..7f62fb9 100644
--- a/crates/shirabe/src/util/forgejo.rs
+++ b/crates/shirabe/src/util/forgejo.rs
@@ -135,8 +135,11 @@ impl Forgejo {
},
);
- self.io
- .write_error("<info>Token stored successfully.</info>", true, IOInterface::NORMAL);
+ self.io.write_error(
+ "<info>Token stored successfully.</info>",
+ true,
+ IOInterface::NORMAL,
+ );
Ok(Ok(true))
}
diff --git a/crates/shirabe/src/util/forgejo_url.rs b/crates/shirabe/src/util/forgejo_url.rs
index ef57e25..3b42f13 100644
--- a/crates/shirabe/src/util/forgejo_url.rs
+++ b/crates/shirabe/src/util/forgejo_url.rs
@@ -12,10 +12,16 @@ pub struct ForgejoUrl {
}
impl ForgejoUrl {
- pub const URL_REGEX: &'static str = r"^(?:(?:https?|git)://([^/]+)/|git@([^:]+):/?)([^/]+)/([^/]+?)(?:\.git|/)?$";
+ pub const URL_REGEX: &'static str =
+ r"^(?:(?:https?|git)://([^/]+)/|git@([^:]+):/?)([^/]+)/([^/]+?)(?:\.git|/)?$";
fn new(owner: String, repository: String, origin_url: String, api_url: String) -> Self {
- Self { owner, repository, origin_url, api_url }
+ Self {
+ owner,
+ repository,
+ origin_url,
+ api_url,
+ }
}
pub fn create(repo_url: &str) -> Result<Self> {
@@ -24,7 +30,8 @@ impl ForgejoUrl {
None => Err(InvalidArgumentException {
message: format!("This is not a valid Forgejo URL: {}", repo_url),
code: 0,
- }.into()),
+ }
+ .into()),
}
}
@@ -32,7 +39,12 @@ impl ForgejoUrl {
let repo_url = repo_url?;
let m = Preg::match_(Self::URL_REGEX, repo_url)?;
- let origin_url = if !m[1].is_empty() { m[1].clone() } else { m[2].clone() }.to_lowercase();
+ let origin_url = if !m[1].is_empty() {
+ m[1].clone()
+ } else {
+ m[2].clone()
+ }
+ .to_lowercase();
let api_base = format!("{}/api/v1", origin_url);
Some(Self::new(
@@ -44,6 +56,9 @@ impl ForgejoUrl {
}
pub fn generate_ssh_url(&self) -> String {
- format!("git@{}:{}/{}.git", self.origin_url, self.owner, self.repository)
+ format!(
+ "git@{}:{}/{}.git",
+ self.origin_url, self.owner, self.repository
+ )
}
}
diff --git a/crates/shirabe/src/util/git.rs b/crates/shirabe/src/util/git.rs
index 16a1143..62d1e0e 100644
--- a/crates/shirabe/src/util/git.rs
+++ b/crates/shirabe/src/util/git.rs
@@ -6,10 +6,10 @@ use std::sync::Mutex;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- array_map, array_merge_recursive, clearstatcache, count, explode, implode, in_array, is_array,
+ InvalidArgumentException, PHP_EOL, PhpMixed, RuntimeException, array_map,
+ array_merge_recursive, clearstatcache, count, explode, implode, in_array, is_array,
is_callable, is_dir, preg_quote, rawurldecode, rawurlencode, str_contains, str_ends_with,
str_replace, str_replace_array, strlen, strpos, substr, trim, version_compare,
- InvalidArgumentException, PhpMixed, RuntimeException, PHP_EOL,
};
use crate::config::Config;
@@ -157,7 +157,11 @@ impl Git {
let cwd_string = cwd.map(|s| s.to_string());
// PHP closure: $runCommands = function ($url) use (...) { ... };
- let mut run_commands_inline = |url_arg: &str, this_process: &mut ProcessExecutor, last_cmd: &mut PhpMixed, command_output: Option<&mut PhpMixed>| -> i64 {
+ let mut run_commands_inline = |url_arg: &str,
+ this_process: &mut ProcessExecutor,
+ last_cmd: &mut PhpMixed,
+ command_output: Option<&mut PhpMixed>|
+ -> i64 {
let collect_outputs = !command_output
.as_ref()
.map(|v| is_callable(v))
@@ -358,7 +362,9 @@ impl Git {
self.io.as_ref(),
&self.config,
&self.process,
- self.http_downloader.as_ref().unwrap_or(&HttpDownloader::default()),
+ self.http_downloader
+ .as_ref()
+ .unwrap_or(&HttpDownloader::default()),
);
let message = "Cloning failed using an ssh key for authentication, enter your GitHub credentials to access private repos";
@@ -412,7 +418,9 @@ impl Git {
self.io.as_ref(),
&self.config,
&self.process,
- self.http_downloader.as_ref().unwrap_or(&HttpDownloader::default()),
+ self.http_downloader
+ .as_ref()
+ .unwrap_or(&HttpDownloader::default()),
);
let domain = m.get(2).cloned().unwrap_or_default();
@@ -573,9 +581,12 @@ impl Git {
self.io.as_ref(),
&self.config,
&self.process,
- self.http_downloader.as_ref().unwrap_or(&HttpDownloader::default()),
+ self.http_downloader
+ .as_ref()
+ .unwrap_or(&HttpDownloader::default()),
);
- let message = "Cloning failed, enter your GitLab credentials to access private repos";
+ let message =
+ "Cloning failed, enter your GitLab credentials to access private repos";
if !git_lab_util.authorize_oauth(&m2) && self.io.is_interactive() {
git_lab_util.authorize_oauth_interactively(&m1, &m2, Some(message));
@@ -671,10 +682,7 @@ impl Git {
IOInterface::NORMAL,
);
self.io.write_error(
- PhpMixed::String(format!(
- "<warning>{}</warning>",
- trim(&error_msg, None)
- )),
+ PhpMixed::String(format!("<warning>{}</warning>", trim(&error_msg, None))),
true,
IOInterface::VERBOSE,
);
@@ -822,11 +830,7 @@ impl Git {
"--prune".to_string(),
"origin".to_string(),
],
- vec![
- "git".to_string(),
- "gc".to_string(),
- "--auto".to_string(),
- ],
+ vec!["git".to_string(), "gc".to_string(), "--auto".to_string()],
];
self.run_commands(commands, url, Some(dir), false, None)?;
@@ -851,10 +855,7 @@ impl Git {
if let Err(e) = try_result {
self.io.write_error(
- PhpMixed::String(format!(
- "<error>Sync mirror failed: {}</error>",
- e
- )),
+ PhpMixed::String(format!("<error>Sync mirror failed: {}</error>", e)),
true,
IOInterface::DEBUG,
);
diff --git a/crates/shirabe/src/util/github.rs b/crates/shirabe/src/util/github.rs
index 23d5b1f..9911084 100644
--- a/crates/shirabe/src/util/github.rs
+++ b/crates/shirabe/src/util/github.rs
@@ -1,7 +1,7 @@
//! ref: composer/src/Composer/Util/GitHub.php
use shirabe_external_packages::composer::pcre::preg::Preg;
-use shirabe_php_shim::{date, stripos, strtolower, PhpMixed};
+use shirabe_php_shim::{PhpMixed, date, stripos, strtolower};
use crate::config::Config;
use crate::downloader::transport_exception::TransportException;
@@ -47,9 +47,7 @@ impl GitHub {
Some(arr) => arr.clone(),
None => return false,
};
- let origin_in_domains = domains
- .values()
- .any(|v| v.as_string() == Some(origin_url));
+ let origin_in_domains = domains.values().any(|v| v.as_string() == Some(origin_url));
if !origin_in_domains {
return false;
}
@@ -82,11 +80,8 @@ impl GitHub {
message: Option<&str>,
) -> anyhow::Result<bool> {
if let Some(msg) = message {
- self.io.write_error(
- PhpMixed::String(msg.to_string()),
- true,
- IOInterface::NORMAL,
- );
+ self.io
+ .write_error(PhpMixed::String(msg.to_string()), true, IOInterface::NORMAL);
}
let mut note = "Composer".to_string();
@@ -286,7 +281,8 @@ impl GitHub {
}
}
- let use_local = store_in_local_auth_config && self.config.get_local_auth_config_source().is_some();
+ let use_local =
+ store_in_local_auth_config && self.config.get_local_auth_config_source().is_some();
let auth_config_source_name;
if use_local {
let mut auth_config_source = self.config.get_local_auth_config_source().unwrap();
@@ -367,9 +363,7 @@ impl GitHub {
pub fn is_rate_limited(&self, headers: &[String]) -> bool {
for header in headers {
- if Preg::is_match(r"{^x-ratelimit-remaining: *0$}i", header.trim())
- .unwrap_or(false)
- {
+ if Preg::is_match(r"{^x-ratelimit-remaining: *0$}i", header.trim()).unwrap_or(false) {
return true;
}
}
@@ -379,9 +373,7 @@ impl GitHub {
pub fn requires_sso(&self, headers: &[String]) -> bool {
for header in headers {
- if Preg::is_match(r"{^x-github-sso: required}i", header.trim())
- .unwrap_or(false)
- {
+ if Preg::is_match(r"{^x-github-sso: required}i", header.trim()).unwrap_or(false) {
return true;
}
}
diff --git a/crates/shirabe/src/util/gitlab.rs b/crates/shirabe/src/util/gitlab.rs
index b245fb9..054dc9a 100644
--- a/crates/shirabe/src/util/gitlab.rs
+++ b/crates/shirabe/src/util/gitlab.rs
@@ -2,7 +2,7 @@
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
-use shirabe_php_shim::{http_build_query, json_decode, time, PhpMixed, RuntimeException};
+use shirabe_php_shim::{PhpMixed, RuntimeException, http_build_query, json_decode, time};
use crate::config::Config;
use crate::downloader::transport_exception::TransportException;
@@ -41,8 +41,8 @@ impl GitLab {
pub fn authorize_oauth(&mut self, origin_url: &str) -> bool {
// before composer 1.9, origin URLs had no port number in them
- let bc_origin_url = Preg::replace("{:\\d+}", "", origin_url)
- .unwrap_or_else(|_| origin_url.to_string());
+ let bc_origin_url =
+ Preg::replace("{:\\d+}", "", origin_url).unwrap_or_else(|_| origin_url.to_string());
let gitlab_domains = self.config.get("gitlab-domains");
let domains = match gitlab_domains.as_array() {
@@ -50,7 +50,9 @@ impl GitLab {
None => return false,
};
let origin_in_domains = domains.values().any(|v| v.as_string() == Some(origin_url));
- let bc_in_domains = domains.values().any(|v| v.as_string() == Some(bc_origin_url.as_str()));
+ let bc_in_domains = domains
+ .values()
+ .any(|v| v.as_string() == Some(bc_origin_url.as_str()));
if !origin_in_domains && !bc_in_domains {
return false;
}
@@ -246,9 +248,8 @@ impl GitLab {
match e.downcast::<TransportException>() {
Ok(te) if te.code == 403 || te.code == 401 => {
if te.code == 401 {
- let response = te
- .get_response()
- .and_then(|r| json_decode(r, true).ok());
+ let response =
+ te.get_response().and_then(|r| json_decode(r, true).ok());
let is_invalid_grant = response
.as_ref()
.and_then(|r| r.as_array())
@@ -371,10 +372,7 @@ impl GitLab {
Err(e) => match e.downcast::<TransportException>() {
Ok(te) => {
self.io.write_error(
- PhpMixed::String(format!(
- "Couldn't refresh access token: {}",
- te.message
- )),
+ PhpMixed::String(format!("Couldn't refresh access token: {}", te.message)),
true,
IOInterface::NORMAL,
);
@@ -398,21 +396,15 @@ impl GitLab {
);
// store value in user config in auth file
- self.config
- .get_auth_config_source()
- .add_config_setting(
- &format!("gitlab-oauth.{}", origin_url),
- Self::build_oauth_config(&response, &access_token),
- )?;
+ self.config.get_auth_config_source().add_config_setting(
+ &format!("gitlab-oauth.{}", origin_url),
+ Self::build_oauth_config(&response, &access_token),
+ )?;
Ok(true)
}
- fn create_token(
- &mut self,
- scheme: &str,
- origin_url: &str,
- ) -> anyhow::Result<PhpMixed> {
+ fn create_token(&mut self, scheme: &str, origin_url: &str) -> anyhow::Result<PhpMixed> {
let username = match self.io.ask("Username: ".to_string(), PhpMixed::Null) {
PhpMixed::String(s) => s,
_ => String::new(),
@@ -448,10 +440,7 @@ impl GitLab {
.collect(),
)),
);
- http_inner.insert(
- "content".to_string(),
- Box::new(PhpMixed::String(data)),
- );
+ http_inner.insert("content".to_string(), Box::new(PhpMixed::String(data)));
let mut options: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
options.insert(
"retry-auth-failure".to_string(),
@@ -495,11 +484,7 @@ impl GitLab {
false
}
- fn refresh_token(
- &mut self,
- scheme: &str,
- origin_url: &str,
- ) -> anyhow::Result<PhpMixed> {
+ fn refresh_token(&mut self, scheme: &str, origin_url: &str) -> anyhow::Result<PhpMixed> {
let auth_tokens = self.config.get("gitlab-oauth");
let refresh_token = auth_tokens
.as_array()
@@ -513,13 +498,10 @@ impl GitLab {
Some(t) => t,
None => {
return Err(RuntimeException {
- message: format!(
- "No GitLab refresh token present for {}.",
- origin_url
- ),
+ message: format!("No GitLab refresh token present for {}.", origin_url),
code: 0,
}
- .into())
+ .into());
}
};
@@ -547,10 +529,7 @@ impl GitLab {
.collect(),
)),
);
- http_inner.insert(
- "content".to_string(),
- Box::new(PhpMixed::String(data)),
- );
+ http_inner.insert("content".to_string(), Box::new(PhpMixed::String(data)));
let mut options: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
options.insert(
"retry-auth-failure".to_string(),
diff --git a/crates/shirabe/src/util/hg.rs b/crates/shirabe/src/util/hg.rs
index d5e867c..c3f4b6e 100644
--- a/crates/shirabe/src/util/hg.rs
+++ b/crates/shirabe/src/util/hg.rs
@@ -1,13 +1,13 @@
//! ref: composer/src/Composer/Util/Hg.php
-use std::sync::OnceLock;
-use anyhow::Result;
-use shirabe_php_shim::rawurlencode;
-use shirabe_external_packages::composer::pcre::preg::Preg;
use crate::config::Config;
use crate::io::io_interface::IOInterface;
use crate::util::process_executor::ProcessExecutor;
use crate::util::url::Url;
+use anyhow::Result;
+use shirabe_external_packages::composer::pcre::preg::Preg;
+use shirabe_php_shim::rawurlencode;
+use std::sync::OnceLock;
static VERSION: OnceLock<Option<String>> = OnceLock::new();
@@ -34,7 +34,11 @@ impl Hg {
// Try as is
let command = command_callable(url.clone());
let mut ignored_output = String::new();
- if self.process.execute(&command, &mut ignored_output, cwd.clone()) == 0 {
+ if self
+ .process
+ .execute(&command, &mut ignored_output, cwd.clone())
+ == 0
+ {
return Ok(());
}
@@ -45,7 +49,10 @@ impl Hg {
)?;
if let Some(matches) = matches {
- if self.io.has_authentication(matches.get("host").map(|s| s.as_str()).unwrap_or("")) {
+ if self
+ .io
+ .has_authentication(matches.get("host").map(|s| s.as_str()).unwrap_or(""))
+ {
let authenticated_url = if matches.get("proto").map(|s| s.as_str()) == Some("ssh") {
let user = if let Some(u) = matches.get("user") {
format!("{}@", rawurlencode(u))
@@ -60,7 +67,9 @@ impl Hg {
matches.get("path").unwrap_or(&String::new()),
)
} else {
- let auth = self.io.get_authentication(matches.get("host").map(|s| s.as_str()).unwrap_or(""));
+ let auth = self
+ .io
+ .get_authentication(matches.get("host").map(|s| s.as_str()).unwrap_or(""));
format!(
"{}://{}:{}@{}{}",
matches.get("proto").unwrap_or(&String::new()),
@@ -78,7 +87,8 @@ impl Hg {
}
let error = self.process.get_error_output();
- return self.throw_exception(&format!("Failed to clone {}, \n\n{}", url, error), &url);
+ return self
+ .throw_exception(&format!("Failed to clone {}, \n\n{}", url, error), &url);
}
}
@@ -91,32 +101,38 @@ impl Hg {
fn throw_exception(&self, message: &str, url: &str) -> Result<()> {
if Self::get_version(&self.process).is_none() {
- anyhow::bail!("{}", Url::sanitize(&format!(
- "Failed to clone {}, hg was not found, check that it is installed and in your PATH env.\n\n{}",
- url,
- self.process.get_error_output()
- )));
+ anyhow::bail!(
+ "{}",
+ Url::sanitize(&format!(
+ "Failed to clone {}, hg was not found, check that it is installed and in your PATH env.\n\n{}",
+ url,
+ self.process.get_error_output()
+ ))
+ );
}
anyhow::bail!("{}", Url::sanitize(message));
}
pub fn get_version(process: &ProcessExecutor) -> Option<&'static str> {
- VERSION.get_or_init(|| {
- let mut output = String::new();
- if process.execute(
- &["hg".to_string(), "--version".to_string()],
- &mut output,
- None,
- ) == 0 {
- if let Ok(Some(matches)) = Preg::is_match_with_indexed_captures(
- r"/^.+? (\d+(?:\.\d+)+)(?:\+.*?)?\)?\r?\n/",
- &output,
- ) {
- return matches.into_iter().nth(1);
+ VERSION
+ .get_or_init(|| {
+ let mut output = String::new();
+ if process.execute(
+ &["hg".to_string(), "--version".to_string()],
+ &mut output,
+ None,
+ ) == 0
+ {
+ if let Ok(Some(matches)) = Preg::is_match_with_indexed_captures(
+ r"/^.+? (\d+(?:\.\d+)+)(?:\+.*?)?\)?\r?\n/",
+ &output,
+ ) {
+ return matches.into_iter().nth(1);
+ }
}
- }
- None
- }).as_deref()
+ None
+ })
+ .as_deref()
}
}
diff --git a/crates/shirabe/src/util/http/curl_downloader.rs b/crates/shirabe/src/util/http/curl_downloader.rs
index 4105f5e..e4d8b78 100644
--- a/crates/shirabe/src/util/http/curl_downloader.rs
+++ b/crates/shirabe/src/util/http/curl_downloader.rs
@@ -6,22 +6,23 @@ use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- array_diff, array_diff_key, array_merge, count, curl_errno, curl_error, curl_getinfo,
- curl_handle_id, curl_init, curl_multi_add_handle, curl_multi_exec, curl_multi_info_read,
- curl_multi_init, curl_multi_select, curl_multi_setopt, curl_setopt, curl_setopt_array,
- curl_share_init, curl_share_setopt, curl_strerror, curl_version, defined, explode, fclose,
- fopen, function_exists, implode, in_array, ini_get, is_resource, json_decode, max, parse_url,
- preg_quote, rename, restore_error_handler, rewind, rtrim, set_error_handler_closure, sprintf,
- str_contains, strpos, stream_get_contents, stream_get_contents_with_max, stripos, substr,
- unlink_silent, usleep, var_export, CurlMultiHandle, CurlShareHandle, LogicException, PhpMixed,
- RuntimeException, CURL_HTTP_VERSION_2_0, CURL_HTTP_VERSION_3, CURL_IPRESOLVE_V4,
- CURL_IPRESOLVE_V6, CURL_LOCK_DATA_COOKIE, CURL_LOCK_DATA_DNS, CURL_LOCK_DATA_SSL_SESSION,
- CURL_VERSION_HTTP2, CURL_VERSION_HTTP3, CURL_VERSION_LIBZ, CURLE_OK, CURLM_BAD_EASY_HANDLE,
- CURLM_BAD_HANDLE, CURLM_CALL_MULTI_PERFORM, CURLM_INTERNAL_ERROR, CURLM_OK, CURLM_OUT_OF_MEMORY,
+ CURL_HTTP_VERSION_2_0, CURL_HTTP_VERSION_3, CURL_IPRESOLVE_V4, CURL_IPRESOLVE_V6,
+ CURL_LOCK_DATA_COOKIE, CURL_LOCK_DATA_DNS, CURL_LOCK_DATA_SSL_SESSION, CURL_VERSION_HTTP2,
+ CURL_VERSION_HTTP3, CURL_VERSION_LIBZ, CURLE_OK, CURLM_BAD_EASY_HANDLE, CURLM_BAD_HANDLE,
+ CURLM_CALL_MULTI_PERFORM, CURLM_INTERNAL_ERROR, CURLM_OK, CURLM_OUT_OF_MEMORY,
CURLMOPT_MAX_HOST_CONNECTIONS, CURLMOPT_PIPELINING, CURLOPT_CONNECTTIMEOUT, CURLOPT_ENCODING,
CURLOPT_FILE, CURLOPT_FOLLOWLOCATION, CURLOPT_HTTP_VERSION, CURLOPT_IPRESOLVE,
CURLOPT_PROTOCOLS, CURLOPT_SHARE, CURLOPT_TIMEOUT, CURLOPT_URL, CURLOPT_WRITEHEADER,
- CURLPROTO_HTTP, CURLPROTO_HTTPS, CURLSHOPT_SHARE, PHP_VERSION_ID,
+ CURLPROTO_HTTP, CURLPROTO_HTTPS, CURLSHOPT_SHARE, CurlMultiHandle, CurlShareHandle,
+ LogicException, PHP_VERSION_ID, PhpMixed, RuntimeException, array_diff, array_diff_key,
+ array_merge, count, curl_errno, curl_error, curl_getinfo, curl_handle_id, curl_init,
+ curl_multi_add_handle, curl_multi_exec, curl_multi_info_read, curl_multi_init,
+ curl_multi_select, curl_multi_setopt, curl_setopt, curl_setopt_array, curl_share_init,
+ curl_share_setopt, curl_strerror, curl_version, defined, explode, fclose, fopen,
+ function_exists, implode, in_array, ini_get, is_resource, json_decode, max, parse_url,
+ preg_quote, rename, restore_error_handler, rewind, rtrim, set_error_handler_closure, sprintf,
+ str_contains, stream_get_contents, stream_get_contents_with_max, stripos, strpos, substr,
+ unlink_silent, usleep, var_export,
};
use crate::config::Config;
@@ -72,7 +73,10 @@ const BAD_MULTIPLEXING_CURL_VERSIONS: &[&str] = &["7.87.0", "7.88.0", "7.88.1"];
/// @var mixed[]
fn options_static() -> IndexMap<String, IndexMap<String, i64>> {
let mut http: IndexMap<String, i64> = IndexMap::new();
- http.insert("method".to_string(), shirabe_php_shim::CURLOPT_CUSTOMREQUEST);
+ http.insert(
+ "method".to_string(),
+ shirabe_php_shim::CURLOPT_CUSTOMREQUEST,
+ );
http.insert("content".to_string(), shirabe_php_shim::CURLOPT_POSTFIELDS);
http.insert("header".to_string(), shirabe_php_shim::CURLOPT_HTTPHEADER);
http.insert("timeout".to_string(), CURLOPT_TIMEOUT);
@@ -80,11 +84,20 @@ fn options_static() -> IndexMap<String, IndexMap<String, i64>> {
let mut ssl: IndexMap<String, i64> = IndexMap::new();
ssl.insert("cafile".to_string(), shirabe_php_shim::CURLOPT_CAINFO);
ssl.insert("capath".to_string(), shirabe_php_shim::CURLOPT_CAPATH);
- ssl.insert("verify_peer".to_string(), shirabe_php_shim::CURLOPT_SSL_VERIFYPEER);
- ssl.insert("verify_peer_name".to_string(), shirabe_php_shim::CURLOPT_SSL_VERIFYHOST);
+ ssl.insert(
+ "verify_peer".to_string(),
+ shirabe_php_shim::CURLOPT_SSL_VERIFYPEER,
+ );
+ ssl.insert(
+ "verify_peer_name".to_string(),
+ shirabe_php_shim::CURLOPT_SSL_VERIFYHOST,
+ );
ssl.insert("local_cert".to_string(), shirabe_php_shim::CURLOPT_SSLCERT);
ssl.insert("local_pk".to_string(), shirabe_php_shim::CURLOPT_SSLKEY);
- ssl.insert("passphrase".to_string(), shirabe_php_shim::CURLOPT_SSLKEYPASSWD);
+ ssl.insert(
+ "passphrase".to_string(),
+ shirabe_php_shim::CURLOPT_SSLKEYPASSWD,
+ );
let mut out: IndexMap<String, IndexMap<String, i64>> = IndexMap::new();
out.insert("http".to_string(), http);
@@ -164,7 +177,11 @@ impl CurlDownloader {
);
}
if defined("CURLMOPT_MAX_HOST_CONNECTIONS") && !defined("HHVM_VERSION") {
- curl_multi_setopt(&multi_handle, CURLMOPT_MAX_HOST_CONNECTIONS, PhpMixed::Int(8));
+ curl_multi_setopt(
+ &multi_handle,
+ CURLMOPT_MAX_HOST_CONNECTIONS,
+ PhpMixed::Int(8),
+ );
}
}
@@ -172,14 +189,17 @@ impl CurlDownloader {
let sh = curl_share_init();
curl_share_setopt(&sh, CURLSHOPT_SHARE, PhpMixed::Int(CURL_LOCK_DATA_COOKIE));
curl_share_setopt(&sh, CURLSHOPT_SHARE, PhpMixed::Int(CURL_LOCK_DATA_DNS));
- curl_share_setopt(&sh, CURLSHOPT_SHARE, PhpMixed::Int(CURL_LOCK_DATA_SSL_SESSION));
+ curl_share_setopt(
+ &sh,
+ CURLSHOPT_SHARE,
+ PhpMixed::Int(CURL_LOCK_DATA_SSL_SESSION),
+ );
share_handle = Some(sh);
}
// TODO(phase-b): clone io/config for AuthHelper construction without consuming.
- let auth_helper = AuthHelper::new(unsafe { std::mem::zeroed() }, unsafe {
- std::mem::zeroed()
- });
+ let auth_helper =
+ AuthHelper::new(unsafe { std::mem::zeroed() }, unsafe { std::mem::zeroed() });
let mut multi_errors: IndexMap<i64, Vec<String>> = IndexMap::new();
multi_errors.insert(
@@ -385,7 +405,11 @@ impl CurlDownloader {
);
curl_setopt(&curl_handle, CURLOPT_WRITEHEADER, header_handle.clone());
curl_setopt(&curl_handle, CURLOPT_FILE, body_handle.clone());
- curl_setopt(&curl_handle, CURLOPT_ENCODING, PhpMixed::String(String::new())); // let cURL set the Accept-Encoding header to what it supports
+ curl_setopt(
+ &curl_handle,
+ CURLOPT_ENCODING,
+ PhpMixed::String(String::new()),
+ ); // let cURL set the Accept-Encoding header to what it supports
curl_setopt(
&curl_handle,
CURLOPT_PROTOCOLS,
@@ -393,9 +417,17 @@ impl CurlDownloader {
);
if attributes.get("ipResolve").and_then(|v| v.as_int()) == Some(4) {
- curl_setopt(&curl_handle, CURLOPT_IPRESOLVE, PhpMixed::Int(CURL_IPRESOLVE_V4));
+ curl_setopt(
+ &curl_handle,
+ CURLOPT_IPRESOLVE,
+ PhpMixed::Int(CURL_IPRESOLVE_V4),
+ );
} else if attributes.get("ipResolve").and_then(|v| v.as_int()) == Some(6) {
- curl_setopt(&curl_handle, CURLOPT_IPRESOLVE, PhpMixed::Int(CURL_IPRESOLVE_V6));
+ curl_setopt(
+ &curl_handle,
+ CURLOPT_IPRESOLVE,
+ PhpMixed::Int(CURL_IPRESOLVE_V6),
+ );
}
if function_exists("curl_share_init") {
@@ -416,10 +448,7 @@ impl CurlDownloader {
.entry("http".to_string())
.or_insert(PhpMixed::Array(IndexMap::new()));
if let PhpMixed::Array(a) = http {
- a.insert(
- "header".to_string(),
- Box::new(PhpMixed::List(Vec::new())),
- );
+ a.insert("header".to_string(), Box::new(PhpMixed::List(Vec::new())));
}
}
@@ -440,7 +469,9 @@ impl CurlDownloader {
.into_iter()
.map(|s| Box::new(PhpMixed::String(s)))
.collect();
- new_list.push(Box::new(PhpMixed::String("Connection: keep-alive".to_string())));
+ new_list.push(Box::new(PhpMixed::String(
+ "Connection: keep-alive".to_string(),
+ )));
*list = new_list;
}
}
@@ -601,10 +632,7 @@ impl CurlDownloader {
.collect(),
),
);
- job.insert(
- "progress".to_string(),
- PhpMixed::Array(progress.clone()),
- );
+ job.insert("progress".to_string(), PhpMixed::Array(progress.clone()));
// curlHandle, headerHandle, bodyHandle, resolve, reject are PHP resources/callables;
// stored as opaque PhpMixed::Null placeholders (real values live in Rust-side fields).
// TODO(phase-b): wire handle/closure storage properly.
@@ -644,12 +672,12 @@ impl CurlDownloader {
_ => None,
})
.unwrap_or_default();
- let if_modified =
- if stripos(&implode(",", &header_strings), "if-modified-since:").is_some() {
- " if modified"
- } else {
- ""
- };
+ let if_modified = if stripos(&implode(",", &header_strings), "if-modified-since:").is_some()
+ {
+ " if modified"
+ } else {
+ ""
+ };
if attributes.get("redirects").and_then(|v| v.as_int()) == Some(0)
&& attributes.get("retries").and_then(|v| v.as_int()) == Some(0)
{
@@ -737,10 +765,7 @@ impl CurlDownloader {
.get("handle")
.map(|b| (**b).clone())
.unwrap_or(PhpMixed::Null);
- let result_code: i64 = progress
- .get("result")
- .and_then(|b| b.as_int())
- .unwrap_or(0);
+ let result_code: i64 = progress.get("result").and_then(|b| b.as_int()).unwrap_or(0);
// TODO(phase-b): correlate handle in `progress['handle']` to its job id.
let i: i64 = 0;
if !self.jobs.contains_key(&i) {
@@ -908,7 +933,9 @@ impl CurlDownloader {
}
// TODO: Remove this as soon as https://github.com/curl/curl/issues/10591 is resolved
- if errno == 55 /* CURLE_SEND_ERROR */ {
+ if errno == 55
+ /* CURLE_SEND_ERROR */
+ {
self.io.write_error(
PhpMixed::String(format!(
"Retrying ({}) {} due to curl error {}",
@@ -966,28 +993,18 @@ impl CurlDownloader {
)));
}
status_code = progress.get("http_code").and_then(|b| b.as_int());
- rewind(
- job.get("headerHandle")
- .cloned()
- .unwrap_or(PhpMixed::Null),
- );
+ rewind(job.get("headerHandle").cloned().unwrap_or(PhpMixed::Null));
headers = Some(explode(
"\r\n",
&rtrim(
&stream_get_contents(
- job.get("headerHandle")
- .cloned()
- .unwrap_or(PhpMixed::Null),
+ job.get("headerHandle").cloned().unwrap_or(PhpMixed::Null),
)
.unwrap_or_default(),
None,
),
));
- fclose(
- job.get("headerHandle")
- .cloned()
- .unwrap_or(PhpMixed::Null),
- );
+ fclose(job.get("headerHandle").cloned().unwrap_or(PhpMixed::Null));
if status_code == Some(0) {
anyhow::bail!(
@@ -1025,16 +1042,10 @@ impl CurlDownloader {
if let Some(PhpMixed::String(filename)) = job.get("filename") {
let mut c: PhpMixed = PhpMixed::String(format!("{}~", filename));
if status_code.unwrap_or(0) >= 300 {
- rewind(
- job.get("bodyHandle")
- .cloned()
- .unwrap_or(PhpMixed::Null),
- );
+ rewind(job.get("bodyHandle").cloned().unwrap_or(PhpMixed::Null));
c = PhpMixed::String(
stream_get_contents(
- job.get("bodyHandle")
- .cloned()
- .unwrap_or(PhpMixed::Null),
+ job.get("bodyHandle").cloned().unwrap_or(PhpMixed::Null),
)
.unwrap_or_default(),
);
@@ -1079,16 +1090,10 @@ impl CurlDownloader {
.and_then(|v| v.as_array())
.and_then(|a| a.get("max_file_size"))
.and_then(|b| b.as_int());
- rewind(
- job.get("bodyHandle")
- .cloned()
- .unwrap_or(PhpMixed::Null),
- );
+ rewind(job.get("bodyHandle").cloned().unwrap_or(PhpMixed::Null));
if let Some(max_file_size) = max_file_size {
let c = stream_get_contents_with_max(
- job.get("bodyHandle")
- .cloned()
- .unwrap_or(PhpMixed::Null),
+ job.get("bodyHandle").cloned().unwrap_or(PhpMixed::Null),
Some(max_file_size),
);
// Gzipped responses with missing Content-Length header cannot be detected during the file download
@@ -1113,9 +1118,7 @@ impl CurlDownloader {
} else {
contents = PhpMixed::String(
stream_get_contents(
- job.get("bodyHandle")
- .cloned()
- .unwrap_or(PhpMixed::Null),
+ job.get("bodyHandle").cloned().unwrap_or(PhpMixed::Null),
)
.unwrap_or_default(),
);
@@ -1155,11 +1158,7 @@ impl CurlDownloader {
<dyn IOInterface>::DEBUG,
);
}
- fclose(
- job.get("bodyHandle")
- .cloned()
- .unwrap_or(PhpMixed::Null),
- );
+ fclose(job.get("bodyHandle").cloned().unwrap_or(PhpMixed::Null));
let response_ref = response.as_ref().unwrap();
if response_ref.inner.get_status_code() >= 300
@@ -1169,10 +1168,7 @@ impl CurlDownloader {
HttpDownloader::output_warnings(
&*self.io,
job.get("origin").and_then(|v| v.as_string()).unwrap_or(""),
- &match json_decode(
- response_ref.inner.get_body().unwrap_or(""),
- true,
- )? {
+ &match json_decode(response_ref.inner.get_body().unwrap_or(""), true)? {
PhpMixed::Array(a) => a.into_iter().map(|(k, v)| (k, *v)).collect(),
_ => IndexMap::new(),
},
@@ -1330,10 +1326,7 @@ impl CurlDownloader {
return Ok(Ok(()));
}
- let status_msg = response_ref
- .inner
- .get_status_message()
- .unwrap_or_default();
+ let status_msg = response_ref.inner.get_status_message().unwrap_or_default();
return Ok(Err(self.fail_response(
&job,
response.as_ref().unwrap(),
@@ -1514,29 +1507,29 @@ impl CurlDownloader {
let job = self.jobs.get(&i).cloned().unwrap_or_default();
self.reject_job(
&job,
- anyhow::anyhow!(TransportException::new(
- sprintf(
- "IP \"%s\" is blocked for \"%s\".",
- &[
- (**primary_ip).clone(),
- progress_now
- .get("url")
- .map(|b| (**b).clone())
- .unwrap_or(PhpMixed::Null),
- ],
- ),
- 0,
- )
- .message),
+ anyhow::anyhow!(
+ TransportException::new(
+ sprintf(
+ "IP \"%s\" is blocked for \"%s\".",
+ &[
+ (**primary_ip).clone(),
+ progress_now
+ .get("url")
+ .map(|b| (**b).clone())
+ .unwrap_or(PhpMixed::Null),
+ ],
+ ),
+ 0,
+ )
+ .message
+ ),
);
}
if let Some(job) = self.jobs.get_mut(&i) {
job.insert(
"primaryIp".to_string(),
- PhpMixed::String(
- primary_ip.as_string().unwrap_or("").to_string(),
- ),
+ PhpMixed::String(primary_ip.as_string().unwrap_or("").to_string()),
);
}
}
@@ -1688,7 +1681,10 @@ impl CurlDownloader {
|| substr(location_header.as_deref().unwrap_or(""), -4, None) != ".zip")
&& Preg::is_match(
r"{^text/html\b}i",
- &response.inner.get_header("content-type").unwrap_or_default(),
+ &response
+ .inner
+ .get_header("content-type")
+ .unwrap_or_default(),
)
{
needs_auth_retry = Some("Bitbucket requires authentication and it was not provided");
@@ -1857,7 +1853,9 @@ impl CurlDownloader {
),
&PhpMixed::List(vec![
Box::new(PhpMixed::String("application/json".to_string())),
- Box::new(PhpMixed::String("application/json; charset=utf-8".to_string())),
+ Box::new(PhpMixed::String(
+ "application/json; charset=utf-8".to_string(),
+ )),
]),
true,
) {
@@ -1924,10 +1922,7 @@ impl CurlDownloader {
}
}
-fn maps_equal(
- a: &IndexMap<String, Box<PhpMixed>>,
- b: &IndexMap<String, Box<PhpMixed>>,
-) -> bool {
+fn maps_equal(a: &IndexMap<String, Box<PhpMixed>>, b: &IndexMap<String, Box<PhpMixed>>) -> bool {
if a.len() != b.len() {
return false;
}
diff --git a/crates/shirabe/src/util/http/mod.rs b/crates/shirabe/src/util/http/mod.rs
new file mode 100644
index 0000000..4ee97c5
--- /dev/null
+++ b/crates/shirabe/src/util/http/mod.rs
@@ -0,0 +1,6 @@
+pub mod curl_downloader;
+pub mod curl_response;
+pub mod proxy_item;
+pub mod proxy_manager;
+pub mod request_proxy;
+pub mod response;
diff --git a/crates/shirabe/src/util/http/proxy_item.rs b/crates/shirabe/src/util/http/proxy_item.rs
index f32325d..0e30c44 100644
--- a/crates/shirabe/src/util/http/proxy_item.rs
+++ b/crates/shirabe/src/util/http/proxy_item.rs
@@ -1,10 +1,10 @@
//! ref: composer/src/Composer/Util/Http/ProxyItem.php
+use crate::util::http::request_proxy::RequestProxy;
use indexmap::IndexMap;
use shirabe_php_shim::{
- base64_encode, parse_url_all, rawurldecode, strpbrk, PhpMixed, RuntimeException,
+ PhpMixed, RuntimeException, base64_encode, parse_url_all, rawurldecode, strpbrk,
};
-use crate::util::http::request_proxy::RequestProxy;
#[derive(Debug)]
pub struct ProxyItem {
@@ -20,12 +20,20 @@ impl ProxyItem {
let syntax_error = format!("unsupported `{}` syntax", env_name);
if strpbrk(&proxy_url, "\r\n\t").is_some() {
- return Err(RuntimeException { message: syntax_error, code: 0 });
+ return Err(RuntimeException {
+ message: syntax_error,
+ code: 0,
+ });
}
let proxy_parsed = parse_url_all(&proxy_url);
let proxy = match proxy_parsed.as_array() {
- None => return Err(RuntimeException { message: syntax_error, code: 0 }),
+ None => {
+ return Err(RuntimeException {
+ message: syntax_error,
+ code: 0,
+ });
+ }
Some(a) => a.clone(),
};
@@ -37,7 +45,10 @@ impl ProxyItem {
}
let scheme = if proxy.contains_key("scheme") {
- format!("{}://", proxy["scheme"].as_string().unwrap_or("").to_lowercase())
+ format!(
+ "{}://",
+ proxy["scheme"].as_string().unwrap_or("").to_lowercase()
+ )
} else {
"http://".to_string()
};
@@ -92,13 +103,13 @@ impl ProxyItem {
return Err(RuntimeException {
message: format!("unable to find proxy port in {}", env_name),
code: 0,
- })
+ });
}
Some(0) => {
return Err(RuntimeException {
message: format!("port 0 is reserved in {}", env_name),
code: 0,
- })
+ });
}
Some(p) => p,
};
diff --git a/crates/shirabe/src/util/http/proxy_manager.rs b/crates/shirabe/src/util/http/proxy_manager.rs
index 319a2c4..e2838e6 100644
--- a/crates/shirabe/src/util/http/proxy_manager.rs
+++ b/crates/shirabe/src/util/http/proxy_manager.rs
@@ -45,9 +45,15 @@ impl ProxyManager {
self.http_proxy.is_some() || self.https_proxy.is_some()
}
- pub fn get_proxy_for_request(&self, request_url: &str) -> Result<RequestProxy, TransportException> {
+ pub fn get_proxy_for_request(
+ &self,
+ request_url: &str,
+ ) -> Result<RequestProxy, TransportException> {
if let Some(ref error) = self.error {
- return Err(TransportException::new(format!("Unable to use a proxy: {}", error)));
+ return Err(TransportException::new(format!(
+ "Unable to use a proxy: {}",
+ error
+ )));
}
let scheme = request_url.split("://").next().unwrap_or("").to_string();
diff --git a/crates/shirabe/src/util/http/request_proxy.rs b/crates/shirabe/src/util/http/request_proxy.rs
index 1405a32..5bbf5ce 100644
--- a/crates/shirabe/src/util/http/request_proxy.rs
+++ b/crates/shirabe/src/util/http/request_proxy.rs
@@ -2,9 +2,9 @@
use indexmap::IndexMap;
use shirabe_php_shim::{
- curl_version, PhpMixed, CURLAUTH_BASIC, CURL_VERSION_HTTPS_PROXY, CURLOPT_NOPROXY,
- CURLOPT_PROXY, CURLOPT_PROXY_CAINFO, CURLOPT_PROXY_CAPATH, CURLOPT_PROXYAUTH,
- CURLOPT_PROXYUSERPWD, InvalidArgumentException,
+ CURL_VERSION_HTTPS_PROXY, CURLAUTH_BASIC, CURLOPT_NOPROXY, CURLOPT_PROXY, CURLOPT_PROXY_CAINFO,
+ CURLOPT_PROXY_CAPATH, CURLOPT_PROXYAUTH, CURLOPT_PROXYUSERPWD, InvalidArgumentException,
+ PhpMixed, curl_version,
};
use crate::downloader::transport_exception::TransportException;
@@ -21,8 +21,18 @@ pub struct RequestProxy {
}
impl RequestProxy {
- pub fn new(url: Option<String>, auth: Option<String>, context_options: Option<ContextOptions>, status: Option<String>) -> Self {
- Self { url, auth, context_options, status }
+ pub fn new(
+ url: Option<String>,
+ auth: Option<String>,
+ context_options: Option<ContextOptions>,
+ status: Option<String>,
+ ) -> Self {
+ Self {
+ url,
+ auth,
+ context_options,
+ status,
+ }
}
pub fn none() -> Self {
@@ -37,13 +47,22 @@ impl RequestProxy {
self.context_options.as_ref()
}
- pub fn get_curl_options(&self, ssl_options: &IndexMap<String, PhpMixed>) -> Result<IndexMap<i64, PhpMixed>, TransportException> {
+ pub fn get_curl_options(
+ &self,
+ ssl_options: &IndexMap<String, PhpMixed>,
+ ) -> Result<IndexMap<i64, PhpMixed>, TransportException> {
if self.is_secure() && !self.supports_secure_proxy() {
- return Err(TransportException::new("Cannot use an HTTPS proxy. PHP >= 7.3 and cUrl >= 7.52.0 are required.".to_string()));
+ return Err(TransportException::new(
+ "Cannot use an HTTPS proxy. PHP >= 7.3 and cUrl >= 7.52.0 are required."
+ .to_string(),
+ ));
}
let mut options: IndexMap<i64, PhpMixed> = IndexMap::new();
- options.insert(CURLOPT_PROXY, PhpMixed::String(self.url.as_deref().unwrap_or("").to_string()));
+ options.insert(
+ CURLOPT_PROXY,
+ PhpMixed::String(self.url.as_deref().unwrap_or("").to_string()),
+ );
if self.url.is_some() {
options.insert(CURLOPT_NOPROXY, PhpMixed::String(String::new()));
@@ -100,7 +119,10 @@ impl RequestProxy {
return false;
}
- let features = version.get("features").and_then(|v| v.as_int()).unwrap_or(0);
+ let features = version
+ .get("features")
+ .and_then(|v| v.as_int())
+ .unwrap_or(0);
(features & CURL_VERSION_HTTPS_PROXY) != 0
}
}
diff --git a/crates/shirabe/src/util/http/response.rs b/crates/shirabe/src/util/http/response.rs
index ff3af06..6a60540 100644
--- a/crates/shirabe/src/util/http/response.rs
+++ b/crates/shirabe/src/util/http/response.rs
@@ -1,9 +1,9 @@
//! ref: composer/src/Composer/Util/Http/Response.php
+use crate::json::json_file::JsonFile;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{LogicException, PhpMixed, preg_quote};
-use crate::json::json_file::JsonFile;
#[derive(Debug)]
pub struct Response {
@@ -63,7 +63,9 @@ impl Response {
}
pub fn decode_json(&self) -> anyhow::Result<PhpMixed> {
- let url = self.request.get("url")
+ let url = self
+ .request
+ .get("url")
.and_then(|u| u.as_string())
.unwrap_or("");
JsonFile::parse_json(self.body.as_deref(), Some(url))
diff --git a/crates/shirabe/src/util/http_downloader.rs b/crates/shirabe/src/util/http_downloader.rs
index e822630..eb28ca0 100644
--- a/crates/shirabe/src/util/http_downloader.rs
+++ b/crates/shirabe/src/util/http_downloader.rs
@@ -7,9 +7,9 @@ use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::react::promise::promise::Promise;
use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use shirabe_php_shim::{
- array_replace_recursive, chr, extension_loaded, file_get_contents, function_exists, implode,
- is_numeric, max, min, rawurldecode, stream_context_create, stripos, strpos, substr, ucfirst,
- InvalidArgumentException, LogicException, PhpMixed, Silencer,
+ InvalidArgumentException, LogicException, PhpMixed, Silencer, array_replace_recursive, chr,
+ extension_loaded, file_get_contents, function_exists, implode, is_numeric, max, min,
+ rawurldecode, stream_context_create, stripos, strpos, substr, ucfirst,
};
use shirabe_semver::constraint::constraint::Constraint;
@@ -119,11 +119,7 @@ impl HttpDownloader {
),
)
.as_array()
- .map(|m| {
- m.iter()
- .map(|(k, v)| (k.clone(), (**v).clone()))
- .collect()
- })
+ .map(|m| m.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect())
.unwrap_or_default();
let curl = if Self::is_curl_enabled() {
@@ -149,7 +145,10 @@ impl HttpDownloader {
if is_numeric(&max_jobs_env) {
max_jobs = max(
1,
- min(50, max_jobs_env.as_string().unwrap_or("0").parse().unwrap_or(0)),
+ min(
+ 50,
+ max_jobs_env.as_string().unwrap_or("0").parse().unwrap_or(0),
+ ),
);
}
@@ -169,11 +168,7 @@ impl HttpDownloader {
}
/// Download a file synchronously
- pub fn get(
- &mut self,
- url: &str,
- options: IndexMap<String, PhpMixed>,
- ) -> Result<Response> {
+ pub fn get(&mut self, url: &str, options: IndexMap<String, PhpMixed>) -> Result<Response> {
if "" == url {
return Err(InvalidArgumentException {
message: "$url must not be an empty string".to_string(),
@@ -296,19 +291,10 @@ impl HttpDownloader {
.map(|(k, v)| (k, Box::new(v)))
.collect(),
),
- PhpMixed::Array(
- options
- .into_iter()
- .map(|(k, v)| (k, Box::new(v)))
- .collect(),
- ),
+ PhpMixed::Array(options.into_iter().map(|(k, v)| (k, Box::new(v))).collect()),
)
.as_array()
- .map(|m| {
- m.iter()
- .map(|(k, v)| (k.clone(), (**v).clone()))
- .collect()
- })
+ .map(|m| m.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect())
.unwrap_or_default();
}
@@ -336,11 +322,7 @@ impl HttpDownloader {
),
)
.as_array()
- .map(|m| {
- m.iter()
- .map(|(k, v)| (k.clone(), (**v).clone()))
- .collect()
- })
+ .map(|m| m.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect())
.unwrap_or_default();
let id = self.id_gen;
@@ -371,10 +353,9 @@ impl HttpDownloader {
}
// capture username/password from URL if there is one
- if let Some(m) = Preg::is_match_strict_groups(
- r"{^https?://([^:/]+):([^@/]+)@([^/]+)}i",
- &request.url,
- ) {
+ if let Some(m) =
+ Preg::is_match_strict_groups(r"{^https?://([^:/]+):([^@/]+)@([^/]+)}i", &request.url)
+ {
self.io.set_authentication(
origin.clone(),
rawurldecode(m.get(1).cloned().unwrap_or_default().as_str()),
@@ -391,19 +372,13 @@ impl HttpDownloader {
let canceler: Box<dyn Fn()> = Box::new(|| {
// PHP canceler logic — TODO(phase-b)
let _ = IrrecoverableDownloadException {
- inner: TransportException::new(
- "Download canceled".to_string(),
- 0,
- ),
+ inner: TransportException::new("Download canceled".to_string(), 0),
};
let _ = Url::sanitize("");
});
let _ = (resolver, canceler);
- let promise = Promise::new(
- Box::new(|_resolve, _reject| {}),
- Box::new(|| {}),
- );
+ let promise = Promise::new(Box::new(|_resolve, _reject| {}), Box::new(|| {}));
// TODO(phase-b): wire promise.then() side-effects: mark job done & store response/exception
let promise: Box<dyn PromiseInterface> = Box::new(promise);
@@ -430,7 +405,11 @@ impl HttpDownloader {
let (request, origin, copy_to) = {
let job = self.jobs.get(&id).unwrap();
- (job.request.clone(), job.origin.clone(), job.request.copy_to.clone())
+ (
+ job.request.clone(),
+ job.origin.clone(),
+ job.request.copy_to.clone(),
+ )
};
let url = request.url.clone();
let options = request.options.clone();
@@ -473,7 +452,10 @@ impl HttpDownloader {
// job.resolve(response) — TODO(phase-b)
} else {
let mut e = TransportException::new(
- format!("Network disabled, request canceled: {}", Url::sanitize(&url)),
+ format!(
+ "Network disabled, request canceled: {}",
+ Url::sanitize(&url)
+ ),
499,
);
e.set_status_code(499);
@@ -601,11 +583,7 @@ impl HttpDownloader {
) -> Result<()> {
let clean_message = |msg: &str| -> String {
if !io.is_decorated() {
- return Preg::replace(
- &format!("{{{}{}}}u", chr(27), "\\[[;\\d]*m"),
- "",
- msg,
- );
+ return Preg::replace(&format!("{{{}{}}}u", chr(27), "\\[[;\\d]*m"), "", msg);
}
msg.to_string()
@@ -711,7 +689,10 @@ impl HttpDownloader {
ssl_map.insert("verify_peer".to_string(), Box::new(PhpMixed::Bool(false)));
ctx_options.insert("ssl".to_string(), PhpMixed::Array(ssl_map));
let mut http_map: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
- http_map.insert("follow_location".to_string(), Box::new(PhpMixed::Bool(false)));
+ http_map.insert(
+ "follow_location".to_string(),
+ Box::new(PhpMixed::Bool(false)),
+ );
http_map.insert("ignore_errors".to_string(), Box::new(PhpMixed::Bool(true)));
ctx_options.insert("http".to_string(), PhpMixed::Array(http_map));
let test_connectivity = file_get_contents(
@@ -744,14 +725,10 @@ impl HttpDownloader {
return false;
}
- let allow_self_signed = job
- .request
- .options
- .get("ssl")
- .and_then(|v| match v {
- PhpMixed::Array(m) => m.get("allow_self_signed").cloned(),
- _ => None,
- });
+ let allow_self_signed = job.request.options.get("ssl").and_then(|v| match v {
+ PhpMixed::Array(m) => m.get("allow_self_signed").cloned(),
+ _ => None,
+ });
if let Some(v) = allow_self_signed {
if !shirabe_php_shim::empty(&v) {
return false;
diff --git a/crates/shirabe/src/util/loop.rs b/crates/shirabe/src/util/loop.rs
index 41e1f25..189b8a3 100644
--- a/crates/shirabe/src/util/loop.rs
+++ b/crates/shirabe/src/util/loop.rs
@@ -1,12 +1,12 @@
//! ref: composer/src/Composer/Util/Loop.php
+use crate::util::http_downloader::HttpDownloader;
+use crate::util::process_executor::ProcessExecutor;
use anyhow::Result;
use indexmap::IndexMap;
-use shirabe_php_shim::microtime;
use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use shirabe_external_packages::symfony::component::console::helper::progress_bar::ProgressBar;
-use crate::util::http_downloader::HttpDownloader;
-use crate::util::process_executor::ProcessExecutor;
+use shirabe_php_shim::microtime;
#[derive(Debug)]
pub struct Loop {
@@ -17,7 +17,10 @@ pub struct Loop {
}
impl Loop {
- pub fn new(mut http_downloader: HttpDownloader, process_executor: Option<ProcessExecutor>) -> Self {
+ pub fn new(
+ mut http_downloader: HttpDownloader,
+ process_executor: Option<ProcessExecutor>,
+ ) -> Self {
http_downloader.enable_async();
let process_executor = process_executor.map(|mut pe| {
@@ -41,7 +44,11 @@ impl Loop {
self.process_executor.as_ref()
}
- pub fn wait(&mut self, promises: Vec<Box<dyn PromiseInterface>>, progress: Option<&mut ProgressBar>) -> Result<()> {
+ pub fn wait(
+ &mut self,
+ promises: Vec<Box<dyn PromiseInterface>>,
+ progress: Option<&mut ProgressBar>,
+ ) -> Result<()> {
let mut uncaught: Option<anyhow::Error> = None;
shirabe_external_packages::react::promise::all(&promises).then(
diff --git a/crates/shirabe/src/util/mod.rs b/crates/shirabe/src/util/mod.rs
new file mode 100644
index 0000000..6a2d55e
--- /dev/null
+++ b/crates/shirabe/src/util/mod.rs
@@ -0,0 +1,33 @@
+pub mod auth_helper;
+pub mod bitbucket;
+pub mod composer_mirror;
+pub mod config_validator;
+pub mod error_handler;
+pub mod filesystem;
+pub mod forgejo;
+pub mod forgejo_repository_data;
+pub mod forgejo_url;
+pub mod git;
+pub mod github;
+pub mod gitlab;
+pub mod hg;
+pub mod http;
+pub mod http_downloader;
+pub mod ini_helper;
+pub mod r#loop;
+pub mod metadata_minifier;
+pub mod no_proxy_pattern;
+pub mod package_info;
+pub mod package_sorter;
+pub mod perforce;
+pub mod platform;
+pub mod process_executor;
+pub mod remote_filesystem;
+pub mod silencer;
+pub mod stream_context_factory;
+pub mod svn;
+pub mod sync_helper;
+pub mod tar;
+pub mod tls_helper;
+pub mod url;
+pub mod zip;
diff --git a/crates/shirabe/src/util/no_proxy_pattern.rs b/crates/shirabe/src/util/no_proxy_pattern.rs
index b3fc3fa..7fbfd0f 100644
--- a/crates/shirabe/src/util/no_proxy_pattern.rs
+++ b/crates/shirabe/src/util/no_proxy_pattern.rs
@@ -4,10 +4,10 @@ use anyhow::Result;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- array_key_exists, chr, empty, explode, filter_var, filter_var_with_options, floor, inet_pton,
- ltrim, parse_url, str_pad, str_repeat, stripos, strlen, strpbrk, strpos, substr, substr_count,
- unpack, PhpMixed, RuntimeException, FILTER_VALIDATE_INT, FILTER_VALIDATE_IP, PHP_URL_HOST,
- PHP_URL_PORT, PHP_URL_SCHEME,
+ FILTER_VALIDATE_INT, FILTER_VALIDATE_IP, PHP_URL_HOST, PHP_URL_PORT, PHP_URL_SCHEME, PhpMixed,
+ RuntimeException, array_key_exists, chr, empty, explode, filter_var, filter_var_with_options,
+ floor, inet_pton, ltrim, parse_url, str_pad, str_repeat, stripos, strlen, strpbrk, strpos,
+ substr, substr_count, unpack,
};
/// Tests URLs against NO_PROXY patterns
@@ -111,12 +111,7 @@ impl NoProxyPattern {
}
/// Returns true if the url is matched by a rule
- pub(crate) fn r#match(
- &mut self,
- index: i64,
- host_name: &str,
- url: &UrlData,
- ) -> Result<bool> {
+ pub(crate) fn r#match(&mut self, index: i64, host_name: &str, url: &UrlData) -> Result<bool> {
let rule = match self.get_rule(index, host_name)? {
Some(r) => r,
None => {
@@ -154,10 +149,7 @@ impl NoProxyPattern {
/// Returns true if the target ip is in the network range
pub(crate) fn match_range(&self, network: &IpData, target: &IpData) -> Result<bool> {
let net = unpack("C*", &network.ip);
- let mask = unpack(
- "C*",
- network.netmask.as_deref().unwrap_or_default(),
- );
+ let mask = unpack("C*", network.netmask.as_deref().unwrap_or_default());
let ip = unpack("C*", &target.ip);
let net = match net {
Some(n) => n,
@@ -209,10 +201,7 @@ impl NoProxyPattern {
.get(&i.to_string())
.and_then(|v| v.as_int())
.unwrap_or(0);
- let ip_byte = ip
- .get(&i.to_string())
- .and_then(|v| v.as_int())
- .unwrap_or(0);
+ let ip_byte = ip.get(&i.to_string()).and_then(|v| v.as_int()).unwrap_or(0);
if (net_byte & mask_byte) != (ip_byte & mask_byte) {
return Ok(false);
}
@@ -335,7 +324,12 @@ impl NoProxyPattern {
mask.push_str(&chr(0xff ^ (0xff >> remainder)));
}
- let mask = str_pad(&mask, size as usize, &chr(0), shirabe_php_shim::STR_PAD_RIGHT);
+ let mask = str_pad(
+ &mask,
+ size as usize,
+ &chr(0),
+ shirabe_php_shim::STR_PAD_RIGHT,
+ );
self.ip_map_to_6(mask.as_bytes(), size)
}
@@ -387,10 +381,7 @@ impl NoProxyPattern {
};
for i in 1..17 {
- let ip_byte = ip
- .get(&i.to_string())
- .and_then(|v| v.as_int())
- .unwrap_or(0);
+ let ip_byte = ip.get(&i.to_string()).and_then(|v| v.as_int()).unwrap_or(0);
let mask_byte = mask
.get(&i.to_string())
.and_then(|v| v.as_int())
@@ -468,9 +459,7 @@ impl NoProxyPattern {
ip6 = substr(&host_name, 1, Some((index as i64) - 1));
host_name = substr(&host_name, (index as i64) + 1, None);
- if strpbrk(&host_name, "[]").is_some()
- || substr_count(&host_name, ":") > 1
- {
+ if strpbrk(&host_name, "[]").is_some() || substr_count(&host_name, ":") > 1 {
return Ok(error);
}
}
@@ -500,12 +489,7 @@ impl NoProxyPattern {
inner.insert("max_range".to_string(), PhpMixed::Int(max));
options.insert(
"options".to_string(),
- PhpMixed::Array(
- inner
- .into_iter()
- .map(|(k, v)| (k, Box::new(v)))
- .collect(),
- ),
+ PhpMixed::Array(inner.into_iter().map(|(k, v)| (k, Box::new(v))).collect()),
);
!matches!(
diff --git a/crates/shirabe/src/util/package_info.rs b/crates/shirabe/src/util/package_info.rs
index 82fac57..1046f0e 100644
--- a/crates/shirabe/src/util/package_info.rs
+++ b/crates/shirabe/src/util/package_info.rs
@@ -21,7 +21,9 @@ impl PackageInfo {
pub fn get_view_source_or_homepage_url(package: &dyn PackageInterface) -> Option<String> {
let url = Self::get_view_source_url(package).or_else(|| {
- package.as_complete_package_interface().and_then(|complete| complete.get_homepage())
+ package
+ .as_complete_package_interface()
+ .and_then(|complete| complete.get_homepage())
});
if url.as_deref() == Some("") {
diff --git a/crates/shirabe/src/util/package_sorter.rs b/crates/shirabe/src/util/package_sorter.rs
index 5a7aa84..2f38910 100644
--- a/crates/shirabe/src/util/package_sorter.rs
+++ b/crates/shirabe/src/util/package_sorter.rs
@@ -12,7 +12,9 @@ use crate::package::root_package::RootPackage;
pub struct PackageSorter;
impl PackageSorter {
- pub fn get_most_current_version(packages: Vec<Box<dyn PackageInterface>>) -> Option<Box<dyn PackageInterface>> {
+ pub fn get_most_current_version(
+ packages: Vec<Box<dyn PackageInterface>>,
+ ) -> Option<Box<dyn PackageInterface>> {
if packages.is_empty() {
return None;
}
@@ -31,23 +33,32 @@ impl PackageSorter {
Some(highest)
}
- pub fn sort_packages_alphabetically(mut packages: Vec<Box<dyn PackageInterface>>) -> Vec<Box<dyn PackageInterface>> {
+ pub fn sort_packages_alphabetically(
+ mut packages: Vec<Box<dyn PackageInterface>>,
+ ) -> Vec<Box<dyn PackageInterface>> {
packages.sort_by_key(|p| p.get_name());
packages
}
- pub fn sort_packages(packages: Vec<Box<dyn PackageInterface>>, weights: IndexMap<String, i64>) -> Vec<Box<dyn PackageInterface>> {
+ pub fn sort_packages(
+ packages: Vec<Box<dyn PackageInterface>>,
+ weights: IndexMap<String, i64>,
+ ) -> Vec<Box<dyn PackageInterface>> {
let mut usage_list: IndexMap<String, Vec<String>> = IndexMap::new();
for package in &packages {
let mut links: IndexMap<String, Link> = package.get_requires();
// TODO: check for RootAliasPackage as well
- if let Some(root_package) = (package.as_any() as &dyn Any).downcast_ref::<RootPackage>() {
+ if let Some(root_package) = (package.as_any() as &dyn Any).downcast_ref::<RootPackage>()
+ {
links.extend(root_package.get_dev_requires());
}
for link in links.values() {
let target = link.get_target().to_string();
- usage_list.entry(target).or_default().push(package.get_name().to_string());
+ usage_list
+ .entry(target)
+ .or_default()
+ .push(package.get_name().to_string());
}
}
@@ -73,7 +84,8 @@ impl PackageSorter {
}
});
- let mut packages: Vec<Option<Box<dyn PackageInterface>>> = packages.into_iter().map(Some).collect();
+ let mut packages: Vec<Option<Box<dyn PackageInterface>>> =
+ packages.into_iter().map(Some).collect();
weighted_packages
.into_iter()
.map(|(_, _, index)| packages[index].take().unwrap())
diff --git a/crates/shirabe/src/util/perforce.rs b/crates/shirabe/src/util/perforce.rs
index 0e905c6..a647dbb 100644
--- a/crates/shirabe/src/util/perforce.rs
+++ b/crates/shirabe/src/util/perforce.rs
@@ -6,9 +6,9 @@ use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::symfony::component::process::executable_finder::ExecutableFinder;
use shirabe_external_packages::symfony::component::process::process::Process;
use shirabe_php_shim::{
- chdir, count, date, explode, fclose, feof, fgets, file_get_contents, fopen, fwrite,
- gethostname, json_decode, str_replace_array, strcmp, strlen, strpos, strrpos, substr, time,
- trim, Exception, PhpMixed, PHP_EOL,
+ Exception, PHP_EOL, PhpMixed, chdir, count, date, explode, fclose, feof, fgets,
+ file_get_contents, fopen, fwrite, gethostname, json_decode, str_replace_array, strcmp, strlen,
+ strpos, strrpos, substr, time, trim,
};
use crate::io::io_interface::IOInterface;
@@ -334,11 +334,7 @@ impl Perforce {
/// @internal
/// @param non-empty-list<string> $arguments Additional arguments for git rev-list
/// @return non-empty-list<string>
- pub fn generate_p4_command(
- &mut self,
- arguments: Vec<String>,
- use_client: bool,
- ) -> Vec<String> {
+ pub fn generate_p4_command(&mut self, arguments: Vec<String>, use_client: bool) -> Vec<String> {
let mut p4_command: Vec<String> = vec![Self::get_p4_executable()];
if self.get_user().is_some() {
p4_command.push("-u".to_string());
@@ -357,8 +353,7 @@ impl Perforce {
}
pub fn is_logged_in(&mut self) -> Result<bool> {
- let command =
- self.generate_p4_command(vec!["login".to_string(), "-s".to_string()], false);
+ let command = self.generate_p4_command(vec!["login".to_string(), "-s".to_string()], false);
let exit_code = self.execute_command(PhpMixed::List(
command
.into_iter()
@@ -592,10 +587,7 @@ impl Perforce {
if !process.is_successful() {
return Err(Exception {
- message: format!(
- "Error logging in:{}",
- self.process.get_error_output()
- ),
+ message: format!("Error logging in:{}", self.process.get_error_output()),
code: 0,
}
.into());
@@ -815,10 +807,8 @@ impl Perforce {
pub(crate) fn get_change_list(&mut self, reference: &str) -> Option<String> {
let index = strpos(reference, "@")?;
let label = substr(reference, index as i64, None);
- let command = self.generate_p4_command(
- vec!["changes".to_string(), "-m1".to_string(), label],
- true,
- );
+ let command =
+ self.generate_p4_command(vec!["changes".to_string(), "-m1".to_string(), label], true);
self.execute_command(PhpMixed::List(
command
.into_iter()
@@ -835,11 +825,7 @@ impl Perforce {
}
/// @return mixed|null
- pub fn get_commit_logs(
- &mut self,
- from_reference: &str,
- to_reference: &str,
- ) -> Option<String> {
+ pub fn get_commit_logs(&mut self, from_reference: &str, to_reference: &str) -> Option<String> {
let from_change_list = self.get_change_list(from_reference)?;
let to_change_list = self.get_change_list(to_reference)?;
let index = strpos(from_reference, "@").unwrap_or(0);
@@ -879,9 +865,10 @@ impl Perforce {
P4_EXECUTABLE
.get_or_init(|| {
let finder = ExecutableFinder::new();
- finder.find("p4", None, vec![]).unwrap_or_else(|| "p4".to_string())
+ finder
+ .find("p4", None, vec![])
+ .unwrap_or_else(|| "p4".to_string())
})
.clone()
}
}
-
diff --git a/crates/shirabe/src/util/platform.rs b/crates/shirabe/src/util/platform.rs
index e8f5dad..96e564f 100644
--- a/crates/shirabe/src/util/platform.rs
+++ b/crates/shirabe/src/util/platform.rs
@@ -5,11 +5,11 @@ use std::sync::Mutex;
use anyhow::Result;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- defined, env_contains_key, env_get, env_set, env_unset, file_exists, file_get_contents,
- fopen, fstat, function_exists, getcwd, getenv, in_array, ini_get, is_array, is_readable,
- mb_strlen, posix_geteuid, posix_getpwuid, posix_getuid, posix_isatty, putenv, realpath,
- server_argv, server_contains_key, server_get, server_set, server_unset, stream_isatty,
- stripos, strlen, strtoupper, substr, usleep, PhpMixed, RuntimeException,
+ PhpMixed, RuntimeException, defined, env_contains_key, env_get, env_set, env_unset,
+ file_exists, file_get_contents, fopen, fstat, function_exists, getcwd, getenv, in_array,
+ ini_get, is_array, is_readable, mb_strlen, posix_geteuid, posix_getpwuid, posix_getuid,
+ posix_isatty, putenv, realpath, server_argv, server_contains_key, server_get, server_set,
+ server_unset, stream_isatty, stripos, strlen, strtoupper, substr, usleep,
};
use crate::util::process_executor::ProcessExecutor;
@@ -93,7 +93,11 @@ impl Platform {
/// Parses tildes and environment variables in paths.
pub fn expand_path(path: &str) -> String {
if Preg::is_match(r"#^~[\\/]#", path) {
- return format!("{}{}", Self::get_user_directory().unwrap(), substr(path, 1, None));
+ return format!(
+ "{}{}",
+ Self::get_user_directory().unwrap(),
+ substr(path, 1, None)
+ );
}
Preg::replace_callback(
@@ -180,7 +184,9 @@ impl Platform {
.ok()
.flatten()
.unwrap_or_default();
- if !(ini_get("open_basedir").map(|s| !s.is_empty()).unwrap_or(false))
+ if !(ini_get("open_basedir")
+ .map(|s| !s.is_empty())
+ .unwrap_or(false))
&& is_readable("/proc/version")
&& stripos(&file_contents, "microsoft").is_some()
&& !Self::is_docker()
@@ -206,7 +212,10 @@ impl Platform {
}
// cannot check so assume no
- if ini_get("open_basedir").map(|s| !s.is_empty()).unwrap_or(false) {
+ if ini_get("open_basedir")
+ .map(|s| !s.is_empty())
+ .unwrap_or(false)
+ {
*cached = Some(false);
return false;
}
@@ -294,9 +303,7 @@ impl Platform {
// detect msysgit/mingw and assume this is a tty because detection
// does not work correctly, see https://github.com/composer/composer/issues/9690
if in_array(
- PhpMixed::String(strtoupper(
- &Self::get_env("MSYSTEM").unwrap_or_default(),
- )),
+ PhpMixed::String(strtoupper(&Self::get_env("MSYSTEM").unwrap_or_default())),
&PhpMixed::List(vec![
Box::new(PhpMixed::String("MINGW32".to_string())),
Box::new(PhpMixed::String("MINGW64".to_string())),
diff --git a/crates/shirabe/src/util/process_executor.rs b/crates/shirabe/src/util/process_executor.rs
index 29c2bfa..2d97322 100644
--- a/crates/shirabe/src/util/process_executor.rs
+++ b/crates/shirabe/src/util/process_executor.rs
@@ -13,10 +13,10 @@ use shirabe_external_packages::symfony::component::process::exception::runtime_e
use shirabe_external_packages::symfony::component::process::executable_finder::ExecutableFinder;
use shirabe_external_packages::symfony::component::process::process::Process;
use shirabe_php_shim::{
- array_intersect, array_map, call_user_func, defined, escapeshellarg, explode, implode,
- in_array, is_array, is_callable, is_dir, is_numeric, is_string, max, min, rtrim, sprintf,
- str_replace, strcspn, strlen, strpbrk, strtolower, strtr, substr_replace, trim, usleep,
- LogicException, PhpMixed, RuntimeException,
+ LogicException, PhpMixed, RuntimeException, array_intersect, array_map, call_user_func,
+ defined, escapeshellarg, explode, implode, in_array, is_array, is_callable, is_dir, is_numeric,
+ is_string, max, min, rtrim, sprintf, str_replace, strcspn, strlen, strpbrk, strtolower, strtr,
+ substr_replace, trim, usleep,
};
use crate::io::io_interface::IOInterface;
@@ -71,17 +71,12 @@ impl ProcessExecutor {
"echo", "endlocal", "erase", "exit", "for", "ftype", "goto", "help", "if", "label", "md",
"mkdir", "mklink", "move", "path", "pause", "popd", "prompt", "pushd", "rd", "rem", "ren",
"rename", "rmdir", "set", "setlocal", "shift", "start", "time", "title", "type", "ver",
- "vol",
- // unused slots to make 47 above explicit
+ "vol", // unused slots to make 47 above explicit
"", "", "",
];
- const GIT_CMDS_NEED_GIT_DIR: &'static [&'static [&'static str]] = &[
- &["show"],
- &["log"],
- &["branch"],
- &["remote", "set-url"],
- ];
+ const GIT_CMDS_NEED_GIT_DIR: &'static [&'static [&'static str]] =
+ &[&["show"], &["log"], &["branch"], &["remote", "set-url"]];
pub fn new(io: Option<Box<dyn IOInterface>>, _: Option<()>) -> Self {
let mut this = Self {
@@ -170,8 +165,7 @@ impl ProcessExecutor {
.iter()
.map(|v| v.as_string().unwrap_or("").to_string())
.collect();
- if Platform::is_windows()
- && strlen(&cmd_vec[0]) == strcspn(&cmd_vec[0], ":/\\") as i64
+ if Platform::is_windows() && strlen(&cmd_vec[0]) == strcspn(&cmd_vec[0], ":/\\") as i64
{
cmd_vec[0] = Self::get_executable(&cmd_vec[0]);
}
@@ -206,7 +200,11 @@ impl ProcessExecutor {
let io_for_signal = self.io.as_ref().map(|b| &**b as *const dyn IOInterface);
let signal_handler = SignalHandler::create(
- vec![SignalHandler::SIGINT, SignalHandler::SIGTERM, SignalHandler::SIGHUP],
+ vec![
+ SignalHandler::SIGINT,
+ SignalHandler::SIGTERM,
+ SignalHandler::SIGHUP,
+ ],
Box::new(move |signal: String, _h: &SignalHandler| {
if let Some(io_ptr) = io_for_signal {
let io = unsafe { &*io_ptr };
@@ -335,10 +333,7 @@ impl ProcessExecutor {
});
let _ = (resolver, canceler);
- let promise = Promise::new(
- Box::new(|_resolve, _reject| {}),
- Box::new(|| {}),
- );
+ let promise = Promise::new(Box::new(|_resolve, _reject| {}), Box::new(|| {}));
// TODO(phase-b): wire promise.then() side-effects: mark job done & update status
let promise: Box<dyn PromiseInterface> = Box::new(promise);
@@ -601,10 +596,16 @@ impl ProcessExecutor {
r"{://(?P<user>[^:/\s]+):(?P<password>[^@\s/]+)@}i",
|m: &IndexMap<String, String>| -> String {
// if the username looks like a long (12char+) hex string, or a modern github token (e.g. ghp_xxx, github_pat_xxx) we obfuscate that
- if Preg::is_match(GitHub::GITHUB_TOKEN_REGEX, m.get("user").cloned().unwrap_or_default().as_str()) {
+ if Preg::is_match(
+ GitHub::GITHUB_TOKEN_REGEX,
+ m.get("user").cloned().unwrap_or_default().as_str(),
+ ) {
return "://***:***@".to_string();
}
- if Preg::is_match(r"{^[a-f0-9]{12,}$}", m.get("user").cloned().unwrap_or_default().as_str()) {
+ if Preg::is_match(
+ r"{^[a-f0-9]{12,}$}",
+ m.get("user").cloned().unwrap_or_default().as_str(),
+ ) {
return "://***:***@".to_string();
}
@@ -664,13 +665,8 @@ impl ProcessExecutor {
let mut quote = strpbrk(&argument, " \t,").is_some();
let mut dquotes: i64 = 0;
// PHP: Preg::replace('/(\\\\*)"/', '$1$1\\"', $argument, -1, $dquotes)
- argument = Preg::replace_with_count(
- r#"/(\\*)"/"#,
- r#"$1$1\""#,
- &argument,
- -1,
- &mut dquotes,
- );
+ argument =
+ Preg::replace_with_count(r#"/(\\*)"/"#, r#"$1$1\""#, &argument, -1, &mut dquotes);
let meta = dquotes > 0 || Preg::is_match(r"/%[^%]+%|![^!]+!/", &argument);
if !meta && !quote {
@@ -695,8 +691,14 @@ impl ProcessExecutor {
explode(" ", command.as_string().unwrap_or(""))
} else {
match command {
- PhpMixed::List(l) => l.iter().map(|v| v.as_string().unwrap_or("").to_string()).collect(),
- PhpMixed::Array(m) => m.values().map(|v| v.as_string().unwrap_or("").to_string()).collect(),
+ PhpMixed::List(l) => l
+ .iter()
+ .map(|v| v.as_string().unwrap_or("").to_string())
+ .collect(),
+ PhpMixed::Array(m) => m
+ .values()
+ .map(|v| v.as_string().unwrap_or("").to_string())
+ .collect(),
_ => vec![],
}
};
@@ -738,7 +740,10 @@ impl ProcessExecutor {
}
}
- executables.get(name).cloned().unwrap_or_else(|| name.to_string())
+ executables
+ .get(name)
+ .cloned()
+ .unwrap_or_else(|| name.to_string())
}
}
diff --git a/crates/shirabe/src/util/remote_filesystem.rs b/crates/shirabe/src/util/remote_filesystem.rs
index 2c377d7..14b771d 100644
--- a/crates/shirabe/src/util/remote_filesystem.rs
+++ b/crates/shirabe/src/util/remote_filesystem.rs
@@ -4,10 +4,10 @@ use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- array_replace_recursive, base64_encode, explode, extension_loaded, file_put_contents,
- filter_var, ini_get, json_decode, parse_url, preg_quote, restore_error_handler,
- set_error_handler, sprintf, strpos, strtolower, strtr, substr, trim,
- PhpMixed, RuntimeException, FILTER_VALIDATE_BOOLEAN, PHP_URL_HOST, PHP_URL_PATH, PHP_VERSION_ID,
+ FILTER_VALIDATE_BOOLEAN, PHP_URL_HOST, PHP_URL_PATH, PHP_VERSION_ID, PhpMixed,
+ RuntimeException, array_replace_recursive, base64_encode, explode, extension_loaded,
+ file_put_contents, filter_var, ini_get, json_decode, parse_url, preg_quote,
+ restore_error_handler, set_error_handler, sprintf, strpos, strtolower, strtr, substr, trim,
};
use crate::config::Config;
@@ -61,7 +61,10 @@ impl RemoteFilesystem {
auth_helper: Option<AuthHelper>,
) -> Self {
let (computed_options, disable_tls_set) = if !disable_tls {
- (StreamContextFactory::get_tls_defaults(&options, &*io), false)
+ (
+ StreamContextFactory::get_tls_defaults(&options, &*io),
+ false,
+ )
} else {
(IndexMap::new(), true)
};
@@ -99,7 +102,13 @@ impl RemoteFilesystem {
progress: bool,
options: IndexMap<String, PhpMixed>,
) -> anyhow::Result<GetResult> {
- self.get(origin_url, file_url, options, Some(file_name.to_string()), progress)
+ self.get(
+ origin_url,
+ file_url,
+ options,
+ Some(file_name.to_string()),
+ progress,
+ )
}
pub fn get_contents(
@@ -131,9 +140,7 @@ impl RemoteFilesystem {
pub fn find_status_code(headers: &[String]) -> Option<i64> {
let mut value: Option<i64> = None;
for header in headers {
- if let Ok(Some(m)) =
- Preg::is_match_strict_groups("{^HTTP/\\S+ (\\d+)}i", header)
- {
+ if let Ok(Some(m)) = Preg::is_match_strict_groups("{^HTTP/\\S+ (\\d+)}i", header) {
value = Some(m["1"].parse().unwrap_or(0));
}
}
@@ -219,10 +226,7 @@ impl RemoteFilesystem {
if let Some(http_opts) = options.get_mut("http") {
if let PhpMixed::Array(m) = http_opts {
- m.insert(
- "ignore_errors".to_string(),
- Box::new(PhpMixed::Bool(true)),
- );
+ m.insert("ignore_errors".to_string(), Box::new(PhpMixed::Bool(true)));
}
}
@@ -380,7 +384,10 @@ impl RemoteFilesystem {
FILTER_VALIDATE_BOOLEAN,
)
{
- error_message = format!("allow_url_fopen must be enabled in php.ini ({})", error_message);
+ error_message = format!(
+ "allow_url_fopen must be enabled in php.ini ({})",
+ error_message
+ );
}
restore_error_handler();
if let Some(e) = caught_e {
@@ -428,7 +435,9 @@ impl RemoteFilesystem {
}
let bitbucket_login_match = origin_url == "bitbucket.org"
- && !self.auth_helper.is_public_bit_bucket_download(&self.file_url)
+ && !self
+ .auth_helper
+ .is_public_bit_bucket_download(&self.file_url)
&& substr(&self.file_url, -4, None) == ".zip"
&& (location_header.is_none()
|| substr(
@@ -582,10 +591,8 @@ impl RemoteFilesystem {
let put_error_message = String::new();
// TODO(phase-b): set_error_handler closure that captures `put_error_message` by reference
set_error_handler(|_code, _msg, _file, _line| true);
- let write_result = file_put_contents(
- file_name.as_deref().unwrap(),
- result_str.as_bytes(),
- );
+ let write_result =
+ file_put_contents(file_name.as_deref().unwrap(), result_str.as_bytes());
restore_error_handler();
if write_result.is_none() {
return Err(anyhow::anyhow!(TransportException::new(format!(
@@ -800,7 +807,9 @@ impl RemoteFilesystem {
self.retry = result.retry;
if self.retry {
- return Err(anyhow::anyhow!(TransportException::new("RETRY".to_string())));
+ return Err(anyhow::anyhow!(TransportException::new(
+ "RETRY".to_string()
+ )));
}
Ok(())
}
@@ -856,9 +865,9 @@ impl RemoteFilesystem {
);
}
}
- options =
- self.auth_helper
- .add_authentication_options(options, origin_url, &self.file_url);
+ options = self
+ .auth_helper
+ .add_authentication_options(options, origin_url, &self.file_url);
let http_entry = options
.entry("http".to_string())
@@ -888,9 +897,7 @@ impl RemoteFilesystem {
result: Option<String>,
) -> anyhow::Result<Option<String>> {
let mut target_url: Option<String> = None;
- if let Some(location_header) =
- Response::find_header_value(response_headers, "location")
- {
+ if let Some(location_header) = Response::find_header_value(response_headers, "location") {
// TODO(phase-b): use PHP_URL_SCHEME once available to detect absolute URLs.
if !parse_url(&location_header, PHP_URL_HOST)
.as_string()
@@ -954,10 +961,7 @@ impl RemoteFilesystem {
<dyn IOInterface>::DEBUG,
);
- additional_options.insert(
- "redirects".to_string(),
- PhpMixed::Int(self.redirects),
- );
+ additional_options.insert("redirects".to_string(), PhpMixed::Int(self.redirects));
let host = parse_url(&target_url, PHP_URL_HOST)
.as_string()
diff --git a/crates/shirabe/src/util/silencer.rs b/crates/shirabe/src/util/silencer.rs
index 39ec1db..f5ee64d 100644
--- a/crates/shirabe/src/util/silencer.rs
+++ b/crates/shirabe/src/util/silencer.rs
@@ -1,11 +1,11 @@
//! ref: composer/src/Composer/Util/Silencer.php
-use std::sync::Mutex;
use anyhow::Result;
use shirabe_php_shim::{
+ E_DEPRECATED, E_NOTICE, E_USER_DEPRECATED, E_USER_NOTICE, E_USER_WARNING, E_WARNING,
error_reporting,
- E_WARNING, E_NOTICE, E_USER_WARNING, E_USER_NOTICE, E_DEPRECATED, E_USER_DEPRECATED,
};
+use std::sync::Mutex;
static STACK: Mutex<Vec<i64>> = Mutex::new(Vec::new());
@@ -13,7 +13,14 @@ pub struct Silencer;
impl Silencer {
pub fn suppress(mask: Option<i64>) -> i64 {
- let mask = mask.unwrap_or(E_WARNING | E_NOTICE | E_USER_WARNING | E_USER_NOTICE | E_DEPRECATED | E_USER_DEPRECATED);
+ let mask = mask.unwrap_or(
+ E_WARNING
+ | E_NOTICE
+ | E_USER_WARNING
+ | E_USER_NOTICE
+ | E_DEPRECATED
+ | E_USER_DEPRECATED,
+ );
let old = error_reporting(None);
STACK.lock().unwrap().push(old);
error_reporting(Some(old & !mask));
diff --git a/crates/shirabe/src/util/stream_context_factory.rs b/crates/shirabe/src/util/stream_context_factory.rs
index aba3a50..a81a68a 100644
--- a/crates/shirabe/src/util/stream_context_factory.rs
+++ b/crates/shirabe/src/util/stream_context_factory.rs
@@ -4,9 +4,9 @@ use indexmap::IndexMap;
use shirabe_external_packages::composer::ca_bundle::ca_bundle::CaBundle;
use shirabe_external_packages::psr::log::logger_interface::LoggerInterface;
use shirabe_php_shim::{
- array_replace_recursive, curl_version, extension_loaded, function_exists, php_uname,
- stream_context_create, stripos, uasort, PhpMixed, RuntimeException,
- HHVM_VERSION, PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION,
+ HHVM_VERSION, PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION, PhpMixed,
+ RuntimeException, array_replace_recursive, curl_version, extension_loaded, function_exists,
+ php_uname, stream_context_create, stripos, uasort,
};
use crate::composer::Composer;
@@ -31,13 +31,17 @@ impl StreamContextFactory {
http.insert("follow_location".to_string(), PhpMixed::Int(1));
http.insert("max_redirects".to_string(), PhpMixed::Int(20));
let mut o = IndexMap::new();
- o.insert("http".to_string(), PhpMixed::Array(
- http.into_iter().map(|(k, v)| (k, Box::new(v))).collect()
- ));
+ o.insert(
+ "http".to_string(),
+ PhpMixed::Array(http.into_iter().map(|(k, v)| (k, Box::new(v))).collect()),
+ );
o
};
- options = array_replace_recursive(options, Self::init_options(url, default_options.clone(), false)?);
+ options = array_replace_recursive(
+ options,
+ Self::init_options(url, default_options.clone(), false)?,
+ );
let default_options = {
let mut o = default_options;
if let Some(PhpMixed::Array(ref mut http)) = o.get_mut("http") {
@@ -53,7 +57,10 @@ impl StreamContextFactory {
http.insert(
"header".to_string(),
Box::new(PhpMixed::List(
- fixed.into_iter().map(|s| Box::new(PhpMixed::String(s))).collect(),
+ fixed
+ .into_iter()
+ .map(|s| Box::new(PhpMixed::String(s)))
+ .collect(),
)),
);
}
@@ -75,10 +82,7 @@ impl StreamContextFactory {
.unwrap_or(false);
if !has_header {
if let Some(PhpMixed::Array(ref mut http)) = options.get_mut("http") {
- http.insert(
- "header".to_string(),
- Box::new(PhpMixed::List(vec![])),
- );
+ http.insert("header".to_string(), Box::new(PhpMixed::List(vec![])));
}
}
// Convert string header to array
@@ -112,7 +116,8 @@ impl StreamContextFactory {
if proxy.is_secure() {
if !extension_loaded("openssl") {
return Err(TransportException::new(
- "You must enable the openssl extension to use a secure proxy.".to_string(),
+ "You must enable the openssl extension to use a secure proxy."
+ .to_string(),
));
}
if is_https_request {
@@ -130,7 +135,9 @@ impl StreamContextFactory {
let proxy_http = proxy_options.get("http");
if let Some(proxy_header) = proxy_http.and_then(|h| h.get("header")) {
if let Some(PhpMixed::Array(ref mut http)) = options.get_mut("http") {
- if let Some(PhpMixed::List(ref mut headers)) = http.get_mut("header").map(|v| &mut **v) {
+ if let Some(PhpMixed::List(ref mut headers)) =
+ http.get_mut("header").map(|v| &mut **v)
+ {
headers.push(Box::new(*proxy_header.clone()));
}
}
@@ -194,18 +201,32 @@ impl StreamContextFactory {
let user_agent = format!(
"User-Agent: Composer/{} ({os}; {release}; {php_version}; {http_version}{platform}{ci})",
Composer::get_version(),
- os = if function_exists("php_uname") { php_uname("s") } else { "Unknown".to_string() },
- release = if function_exists("php_uname") { php_uname("r") } else { "Unknown".to_string() },
+ os = if function_exists("php_uname") {
+ php_uname("s")
+ } else {
+ "Unknown".to_string()
+ },
+ release = if function_exists("php_uname") {
+ php_uname("r")
+ } else {
+ "Unknown".to_string()
+ },
php_version = php_version,
http_version = http_version,
platform = platform_php_version
.as_deref()
.map(|v| format!("; Platform-PHP {}", v))
.unwrap_or_default(),
- ci = if Platform::get_env("CI").is_some() { "; CI" } else { "" },
+ ci = if Platform::get_env("CI").is_some() {
+ "; CI"
+ } else {
+ ""
+ },
);
if let Some(PhpMixed::Array(ref mut http)) = options.get_mut("http") {
- if let Some(PhpMixed::List(ref mut headers)) = http.get_mut("header").map(|v| &mut **v) {
+ if let Some(PhpMixed::List(ref mut headers)) =
+ http.get_mut("header").map(|v| &mut **v)
+ {
headers.push(Box::new(PhpMixed::String(user_agent)));
}
}
@@ -279,9 +300,15 @@ impl StreamContextFactory {
let mut defaults: IndexMap<String, PhpMixed> = {
let mut d = IndexMap::new();
- d.insert("ssl".to_string(), PhpMixed::Array(
- ssl_defaults.into_iter().map(|(k, v)| (k, Box::new(v))).collect()
- ));
+ d.insert(
+ "ssl".to_string(),
+ PhpMixed::Array(
+ ssl_defaults
+ .into_iter()
+ .map(|(k, v)| (k, Box::new(v)))
+ .collect(),
+ ),
+ );
d
};
@@ -322,7 +349,9 @@ impl StreamContextFactory {
}
}
- let cafile = defaults.get("ssl").and_then(|v| v.as_array())
+ let cafile = defaults
+ .get("ssl")
+ .and_then(|v| v.as_array())
.and_then(|a| a.get("cafile"))
.and_then(|v| v.as_string())
.map(|s| s.to_string());
@@ -334,7 +363,9 @@ impl StreamContextFactory {
}
}
- let capath = defaults.get("ssl").and_then(|v| v.as_array())
+ let capath = defaults
+ .get("ssl")
+ .and_then(|v| v.as_array())
.and_then(|a| a.get("capath"))
.and_then(|v| v.as_string())
.map(|s| s.to_string());
diff --git a/crates/shirabe/src/util/svn.rs b/crates/shirabe/src/util/svn.rs
index 2277c68..f1a900c 100644
--- a/crates/shirabe/src/util/svn.rs
+++ b/crates/shirabe/src/util/svn.rs
@@ -6,8 +6,8 @@ use anyhow::Result;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- empty, implode, parse_url, parse_url_all, stripos, strpos, trim, LogicException, PhpMixed,
- RuntimeException, PHP_URL_HOST,
+ LogicException, PHP_URL_HOST, PhpMixed, RuntimeException, empty, implode, parse_url,
+ parse_url_all, stripos, strpos, trim,
};
use crate::config::Config;
@@ -148,17 +148,16 @@ impl Svn {
};
// TODO(phase-b): pass handler callback to process.execute
let mut handler_output = String::new();
- let status = self.process.execute(&command, &mut handler_output, cwd.map(String::from));
+ let status = self
+ .process
+ .execute(&command, &mut handler_output, cwd.map(String::from));
if 0 == status {
return Ok(output);
}
let error_output = self.process.get_error_output();
let full_output = trim(
- &implode(
- "\n",
- &[output.clone().unwrap_or_default(), error_output],
- ),
+ &implode("\n", &[output.clone().unwrap_or_default(), error_output]),
None,
);
@@ -425,10 +424,9 @@ impl Svn {
None,
) {
// TODO(phase-b): Preg::is_match with captures should populate $match
- if let Ok(Some(matches)) = Preg::is_match_with_indexed_captures(
- r"{(\d+(?:\.\d+)+)}",
- &output,
- ) {
+ if let Ok(Some(matches)) =
+ Preg::is_match_with_indexed_captures(r"{(\d+(?:\.\d+)+)}", &output)
+ {
*cached = Some(matches.get(1).cloned().unwrap_or_default());
}
}
@@ -437,4 +435,3 @@ impl Svn {
cached.clone()
}
}
-
diff --git a/crates/shirabe/src/util/sync_helper.rs b/crates/shirabe/src/util/sync_helper.rs
index c5ab889..1be9075 100644
--- a/crates/shirabe/src/util/sync_helper.rs
+++ b/crates/shirabe/src/util/sync_helper.rs
@@ -1,11 +1,11 @@
//! ref: composer/src/Composer/Util/SyncHelper.php
-use anyhow::Result;
-use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use crate::downloader::download_manager::DownloadManager;
use crate::downloader::downloader_interface::DownloaderInterface;
use crate::package::package_interface::PackageInterface;
use crate::util::r#loop::Loop;
+use anyhow::Result;
+use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
pub enum DownloaderOrManager<'a> {
Interface(&'a dyn DownloaderInterface),
@@ -13,14 +13,25 @@ pub enum DownloaderOrManager<'a> {
}
impl<'a> DownloaderOrManager<'a> {
- fn download(&self, package: &dyn PackageInterface, path: &str, prev_package: Option<&dyn PackageInterface>) -> Box<dyn PromiseInterface> {
+ fn download(
+ &self,
+ package: &dyn PackageInterface,
+ path: &str,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> Box<dyn PromiseInterface> {
match self {
Self::Interface(d) => d.download(package, path, prev_package),
Self::Manager(d) => d.download(package, path, prev_package),
}
}
- fn prepare(&self, r#type: &str, package: &dyn PackageInterface, path: &str, prev_package: Option<&dyn PackageInterface>) -> Box<dyn PromiseInterface> {
+ fn prepare(
+ &self,
+ r#type: &str,
+ package: &dyn PackageInterface,
+ path: &str,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> Box<dyn PromiseInterface> {
match self {
Self::Interface(d) => d.prepare(r#type, package, path, prev_package),
Self::Manager(d) => d.prepare(r#type, package, path, prev_package),
@@ -34,14 +45,25 @@ impl<'a> DownloaderOrManager<'a> {
}
}
- fn update(&self, package: &dyn PackageInterface, prev_package: &dyn PackageInterface, path: &str) -> Box<dyn PromiseInterface> {
+ fn update(
+ &self,
+ package: &dyn PackageInterface,
+ prev_package: &dyn PackageInterface,
+ path: &str,
+ ) -> Box<dyn PromiseInterface> {
match self {
Self::Interface(d) => d.update(package, prev_package, path),
Self::Manager(d) => d.update(package, prev_package, path),
}
}
- fn cleanup(&self, r#type: &str, package: &dyn PackageInterface, path: &str, prev_package: Option<&dyn PackageInterface>) -> Box<dyn PromiseInterface> {
+ fn cleanup(
+ &self,
+ r#type: &str,
+ package: &dyn PackageInterface,
+ path: &str,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> Box<dyn PromiseInterface> {
match self {
Self::Interface(d) => d.cleanup(r#type, package, path, prev_package),
Self::Manager(d) => d.cleanup(r#type, package, path, prev_package),
@@ -59,11 +81,21 @@ impl SyncHelper {
package: &dyn PackageInterface,
prev_package: Option<&dyn PackageInterface>,
) -> Result<()> {
- let r#type = if prev_package.is_some() { "update" } else { "install" };
+ let r#type = if prev_package.is_some() {
+ "update"
+ } else {
+ "install"
+ };
let result: Result<()> = (|| {
- Self::r#await(r#loop, Some(downloader.download(package, &path, prev_package)))?;
- Self::r#await(r#loop, Some(downloader.prepare(r#type, package, &path, prev_package)))?;
+ Self::r#await(
+ r#loop,
+ Some(downloader.download(package, &path, prev_package)),
+ )?;
+ Self::r#await(
+ r#loop,
+ Some(downloader.prepare(r#type, package, &path, prev_package)),
+ )?;
if r#type == "update" {
if let Some(prev) = prev_package {
Self::r#await(r#loop, Some(downloader.update(package, prev, &path)))?;
@@ -75,11 +107,17 @@ impl SyncHelper {
})();
if result.is_err() {
- Self::r#await(r#loop, Some(downloader.cleanup(r#type, package, &path, prev_package)))?;
+ Self::r#await(
+ r#loop,
+ Some(downloader.cleanup(r#type, package, &path, prev_package)),
+ )?;
return result;
}
- Self::r#await(r#loop, Some(downloader.cleanup(r#type, package, &path, prev_package)))?;
+ Self::r#await(
+ r#loop,
+ Some(downloader.cleanup(r#type, package, &path, prev_package)),
+ )?;
Ok(())
}
diff --git a/crates/shirabe/src/util/tar.rs b/crates/shirabe/src/util/tar.rs
index 253f142..2d44392 100644
--- a/crates/shirabe/src/util/tar.rs
+++ b/crates/shirabe/src/util/tar.rs
@@ -31,7 +31,11 @@ impl Tar {
return Err(anyhow::anyhow!(RuntimeException {
message: format!(
"Archive has more than one top level directories, and no composer.json was found on the top level, so it's an invalid archive. Top level paths found were: {}",
- top_level_paths.keys().cloned().collect::<Vec<_>>().join(",")
+ top_level_paths
+ .keys()
+ .cloned()
+ .collect::<Vec<_>>()
+ .join(",")
),
code: 0,
}));
@@ -50,7 +54,9 @@ impl Tar {
}
Err(anyhow::anyhow!(RuntimeException {
- message: "No composer.json found either at the top level or within the topmost directory".to_string(),
+ message:
+ "No composer.json found either at the top level or within the topmost directory"
+ .to_string(),
code: 0,
}))
}
diff --git a/crates/shirabe/src/util/tls_helper.rs b/crates/shirabe/src/util/tls_helper.rs
index ecacbcd..21b53a4 100644
--- a/crates/shirabe/src/util/tls_helper.rs
+++ b/crates/shirabe/src/util/tls_helper.rs
@@ -3,8 +3,8 @@
use shirabe_external_packages::composer::ca_bundle::ca_bundle::CaBundle;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_php_shim::{
- base64_decode, openssl_get_publickey, openssl_pkey_get_details, openssl_x509_parse,
- preg_quote, substr_count, PhpMixed, RuntimeException,
+ PhpMixed, RuntimeException, base64_decode, openssl_get_publickey, openssl_pkey_get_details,
+ openssl_x509_parse, preg_quote, substr_count,
};
/// @deprecated Use composer/ca-bundle and composer/composer 2.2 if you still need PHP 5 compatibility
@@ -53,14 +53,16 @@ impl TlsHelper {
}
};
- let common_name = info.get("subject")
+ let common_name = info
+ .get("subject")
.and_then(|v| v.as_array())
.and_then(|subj| subj.get("commonName"))
.and_then(|cn| cn.as_string())
.map(|s| s.to_lowercase())?;
let mut subject_alt_names = vec![];
- if let Some(san_value) = info.get("extensions")
+ if let Some(san_value) = info
+ .get("extensions")
.and_then(|v| v.as_array())
.and_then(|ext| ext.get("subjectAltName"))
.and_then(|v| v.as_string())
@@ -126,7 +128,8 @@ impl TlsHelper {
message: "Failed to retrieve public key details".to_string(),
code: 0,
})?;
- let pubkeypem = pubkeydetails.get("key")
+ let pubkeypem = pubkeydetails
+ .get("key")
.and_then(|v| v.as_string())
.unwrap_or("")
.to_string();
@@ -139,7 +142,10 @@ impl TlsHelper {
let der = base64_decode(pemtrim).unwrap_or_default();
- Ok(shirabe_php_shim::hash("sha1", &String::from_utf8_lossy(&der)))
+ Ok(shirabe_php_shim::hash(
+ "sha1",
+ &String::from_utf8_lossy(&der),
+ ))
}
pub fn is_openssl_parse_safe() -> bool {
diff --git a/crates/shirabe/src/util/url.rs b/crates/shirabe/src/util/url.rs
index 78ac7cb..7d0ab21 100644
--- a/crates/shirabe/src/util/url.rs
+++ b/crates/shirabe/src/util/url.rs
@@ -1,36 +1,99 @@
//! ref: composer/src/Composer/Util/Url.php
-use shirabe_external_packages::composer::pcre::preg::Preg;
-use shirabe_php_shim::{in_array, parse_url, PhpMixed, PHP_URL_HOST, PHP_URL_PORT};
use crate::config::Config;
use crate::util::github::GitHub;
+use shirabe_external_packages::composer::pcre::preg::Preg;
+use shirabe_php_shim::{PHP_URL_HOST, PHP_URL_PORT, PhpMixed, in_array, parse_url};
pub struct Url;
impl Url {
pub fn update_dist_reference(config: &Config, mut url: String, r#ref: &str) -> String {
- let host = parse_url(&url, PHP_URL_HOST).as_string_opt().map(|s| s.to_string()).unwrap_or_default();
+ let host = parse_url(&url, PHP_URL_HOST)
+ .as_string_opt()
+ .map(|s| s.to_string())
+ .unwrap_or_default();
if host == "api.github.com" || host == "github.com" || host == "www.github.com" {
- if let Some(m) = Preg::match_(r"(?i)^https?://(?:www\.)?github\.com/([^/]+)/([^/]+)/(zip|tar)ball/(.+)$", &url) {
- url = format!("https://api.github.com/repos/{}/{}/{}ball/{}", m.get("1").unwrap_or(&String::new()), m.get("2").unwrap_or(&String::new()), m.get("3").unwrap_or(&String::new()), r#ref);
- } else if let Some(m) = Preg::match_(r"(?i)^https?://(?:www\.)?github\.com/([^/]+)/([^/]+)/archive/.+\.(zip|tar)(?:\.gz)?$", &url) {
- url = format!("https://api.github.com/repos/{}/{}/{}ball/{}", m.get("1").unwrap_or(&String::new()), m.get("2").unwrap_or(&String::new()), m.get("3").unwrap_or(&String::new()), r#ref);
- } else if let Some(m) = Preg::match_(r"(?i)^https?://api\.github\.com/repos/([^/]+)/([^/]+)/(zip|tar)ball(?:/.+)?$", &url) {
- url = format!("https://api.github.com/repos/{}/{}/{}ball/{}", m.get("1").unwrap_or(&String::new()), m.get("2").unwrap_or(&String::new()), m.get("3").unwrap_or(&String::new()), r#ref);
+ if let Some(m) = Preg::match_(
+ r"(?i)^https?://(?:www\.)?github\.com/([^/]+)/([^/]+)/(zip|tar)ball/(.+)$",
+ &url,
+ ) {
+ url = format!(
+ "https://api.github.com/repos/{}/{}/{}ball/{}",
+ m.get("1").unwrap_or(&String::new()),
+ m.get("2").unwrap_or(&String::new()),
+ m.get("3").unwrap_or(&String::new()),
+ r#ref
+ );
+ } else if let Some(m) = Preg::match_(
+ r"(?i)^https?://(?:www\.)?github\.com/([^/]+)/([^/]+)/archive/.+\.(zip|tar)(?:\.gz)?$",
+ &url,
+ ) {
+ url = format!(
+ "https://api.github.com/repos/{}/{}/{}ball/{}",
+ m.get("1").unwrap_or(&String::new()),
+ m.get("2").unwrap_or(&String::new()),
+ m.get("3").unwrap_or(&String::new()),
+ r#ref
+ );
+ } else if let Some(m) = Preg::match_(
+ r"(?i)^https?://api\.github\.com/repos/([^/]+)/([^/]+)/(zip|tar)ball(?:/.+)?$",
+ &url,
+ ) {
+ url = format!(
+ "https://api.github.com/repos/{}/{}/{}ball/{}",
+ m.get("1").unwrap_or(&String::new()),
+ m.get("2").unwrap_or(&String::new()),
+ m.get("3").unwrap_or(&String::new()),
+ r#ref
+ );
}
} else if host == "bitbucket.org" || host == "www.bitbucket.org" {
- if let Some(m) = Preg::match_(r"(?i)^https?://(?:www\.)?bitbucket\.org/([^/]+)/([^/]+)/get/(.+)\.(zip|tar\.gz|tar\.bz2)$", &url) {
- url = format!("https://bitbucket.org/{}/{}/get/{}.{}", m.get("1").unwrap_or(&String::new()), m.get("2").unwrap_or(&String::new()), r#ref, m.get("4").unwrap_or(&String::new()));
+ if let Some(m) = Preg::match_(
+ r"(?i)^https?://(?:www\.)?bitbucket\.org/([^/]+)/([^/]+)/get/(.+)\.(zip|tar\.gz|tar\.bz2)$",
+ &url,
+ ) {
+ url = format!(
+ "https://bitbucket.org/{}/{}/get/{}.{}",
+ m.get("1").unwrap_or(&String::new()),
+ m.get("2").unwrap_or(&String::new()),
+ r#ref,
+ m.get("4").unwrap_or(&String::new())
+ );
}
} else if host == "gitlab.com" || host == "www.gitlab.com" {
- if let Some(m) = Preg::match_(r"(?i)^https?://(?:www\.)?gitlab\.com/api/v[34]/projects/([^/]+)/repository/archive\.(zip|tar\.gz|tar\.bz2|tar)\?sha=.+$", &url) {
- url = format!("https://gitlab.com/api/v4/projects/{}/repository/archive.{}?sha={}", m.get("1").unwrap_or(&String::new()), m.get("2").unwrap_or(&String::new()), r#ref);
+ if let Some(m) = Preg::match_(
+ r"(?i)^https?://(?:www\.)?gitlab\.com/api/v[34]/projects/([^/]+)/repository/archive\.(zip|tar\.gz|tar\.bz2|tar)\?sha=.+$",
+ &url,
+ ) {
+ url = format!(
+ "https://gitlab.com/api/v4/projects/{}/repository/archive.{}?sha={}",
+ m.get("1").unwrap_or(&String::new()),
+ m.get("2").unwrap_or(&String::new()),
+ r#ref
+ );
}
- } else if in_array(PhpMixed::String(host.clone()), &config.get("github-domains"), true) {
- url = Preg::replace(r"(?i)(/repos/[^/]+/[^/]+/(zip|tar)ball)(?:/.+)?$", &format!("$1/{}", r#ref), url);
- } else if in_array(PhpMixed::String(host.clone()), &config.get("gitlab-domains"), true) {
- url = Preg::replace(r"(?i)(/api/v[34]/projects/[^/]+/repository/archive\.(?:zip|tar\.gz|tar\.bz2|tar)\?sha=).+$", &format!("${{1}}{}", r#ref), url);
+ } else if in_array(
+ PhpMixed::String(host.clone()),
+ &config.get("github-domains"),
+ true,
+ ) {
+ url = Preg::replace(
+ r"(?i)(/repos/[^/]+/[^/]+/(zip|tar)ball)(?:/.+)?$",
+ &format!("$1/{}", r#ref),
+ url,
+ );
+ } else if in_array(
+ PhpMixed::String(host.clone()),
+ &config.get("gitlab-domains"),
+ true,
+ ) {
+ url = Preg::replace(
+ r"(?i)(/api/v[34]/projects/[^/]+/repository/archive\.(?:zip|tar\.gz|tar\.bz2|tar)\?sha=).+$",
+ &format!("${{1}}{}", r#ref),
+ url,
+ );
}
assert!(!url.is_empty());
@@ -43,7 +106,10 @@ impl Url {
return url.to_string();
}
- let mut origin = parse_url(url, PHP_URL_HOST).as_string_opt().map(|s| s.to_string()).unwrap_or_default();
+ let mut origin = parse_url(url, PHP_URL_HOST)
+ .as_string_opt()
+ .map(|s| s.to_string())
+ .unwrap_or_default();
if let Some(port) = parse_url(url, PHP_URL_PORT).as_i64_opt() {
origin = format!("{}:{}", origin, port);
}
@@ -62,7 +128,13 @@ impl Url {
// Gitlab can be installed in a non-root context (i.e. gitlab.com/foo). When downloading archives the originUrl
// is the host without the path, so we look for the registered gitlab-domains matching the host here
- if !origin.contains('/') && !in_array(PhpMixed::String(origin.clone()), &config.get("gitlab-domains"), true) {
+ if !origin.contains('/')
+ && !in_array(
+ PhpMixed::String(origin.clone()),
+ &config.get("gitlab-domains"),
+ true,
+ )
+ {
for gitlab_domain in config.get("gitlab-domains").as_vec_string() {
if !gitlab_domain.is_empty() && gitlab_domain.starts_with(&origin) {
return gitlab_domain;
@@ -82,10 +154,20 @@ impl Url {
r"(?i)^(?P<prefix>[a-z0-9]+://)?(?P<user>[^:/\s@]+):(?P<password>[^@\s/]+)@",
|m| {
// if the username looks like a long (12char+) hex string, or a modern github token (e.g. ghp_xxx, github_pat_xxx) we obfuscate that
- if Preg::is_match(GitHub::GITHUB_TOKEN_REGEX, m.get("user").map(|s| s.as_str()).unwrap_or("")) {
- format!("{}***:***@", m.get("prefix").map(|s| s.as_str()).unwrap_or(""))
+ if Preg::is_match(
+ GitHub::GITHUB_TOKEN_REGEX,
+ m.get("user").map(|s| s.as_str()).unwrap_or(""),
+ ) {
+ format!(
+ "{}***:***@",
+ m.get("prefix").map(|s| s.as_str()).unwrap_or("")
+ )
} else {
- format!("{}{}:***@", m.get("prefix").map(|s| s.as_str()).unwrap_or(""), m.get("user").map(|s| s.as_str()).unwrap_or(""))
+ format!(
+ "{}{}:***@",
+ m.get("prefix").map(|s| s.as_str()).unwrap_or(""),
+ m.get("user").map(|s| s.as_str()).unwrap_or("")
+ )
}
},
url,
diff --git a/crates/shirabe/src/util/zip.rs b/crates/shirabe/src/util/zip.rs
index 9c9135d..d76d805 100644
--- a/crates/shirabe/src/util/zip.rs
+++ b/crates/shirabe/src/util/zip.rs
@@ -2,7 +2,9 @@
use anyhow::Result;
use indexmap::IndexMap;
-use shirabe_php_shim::{dirname, extension_loaded, implode, stream_get_contents, RuntimeException, ZipArchive};
+use shirabe_php_shim::{
+ RuntimeException, ZipArchive, dirname, extension_loaded, implode, stream_get_contents,
+};
pub struct Zip;
@@ -101,8 +103,9 @@ impl Zip {
}
Err(RuntimeException {
- message: "No composer.json found either at the top level or within the topmost directory"
- .to_string(),
+ message:
+ "No composer.json found either at the top level or within the topmost directory"
+ .to_string(),
code: 0,
}
.into())