123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687(*********************************************************************************)(* Dunolint - A tool to lint and help manage files in dune projects *)(* Copyright (C) 2024-2025 Mathieu Barbin <mathieu.barbin@gmail.com> *)(* *)(* This file is part of Dunolint. *)(* *)(* Dunolint is free software; you can redistribute it and/or modify it *)(* under the terms of the GNU Lesser General Public License as published by *)(* the Free Software Foundation either version 3 of the License, or any later *)(* version, with the LGPL-3.0 Linking Exception. *)(* *)(* Dunolint is distributed in the hope that it will be useful, but WITHOUT *)(* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *)(* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *)(* and the file `NOTICE.md` at the root of this repository for more details. *)(* *)(* You should have received a copy of the GNU Lesser General Public License *)(* and the LGPL-3.0 Linking Exception along with this library. If not, see *)(* <http://www.gnu.org/licenses/> and <https://spdx.org>, respectively. *)(*********************************************************************************)moduleConfig_with_location=structtypet={config:Dunolint.Config.t;location:Relative_path.t}endmoduleEnclosing_result=structtype'at=('a,Dune_project_context.Invalid_dune_project.t)Result.tendmoduleDune_project_context_with_location=structtypet={dune_project_context:Dune_project_context.tEnclosing_result.t;location:Relative_path.t}endmoduleItem=structtypet=|ConfigofConfig_with_location.t|Dune_project_contextofDune_project_context_with_location.topenstruct(* Future plans include making use of the dune linter to keep some
contextual information (e.g. enclosing library context). This part of the
project hasn't been written yet.
In the meanwhile we wish to enforce the right dependency ordering between
libraries, and silencing @unused-libs warnings. *)open!Dune_linterendendtypet=Item.tlistletempty=[]letconfigs(t:t)=(* Return configs in rule processing order: shallowest (root) to deepest.
Since configs are added at the head as we traverse deeper, we reverse to
get shallowest first. *)List.rev_filter_mapt~f:(function|Configconfig->Someconfig|Dune_project_context_->None);;letadd_configt~config~location=Item.Config{config;location}::tletadd_dune_project_contextt~dune_project_context~location=Item.Dune_project_context{dune_project_context;location}::t;;letenclosing_dune_project_context(t:t)=List.find_mapt~f:(function|Config_->None|Dune_project_context{dune_project_context;location=_}->Somedune_project_context);;letenclosing_dune_lang_version(t:t)=Option.map(enclosing_dune_project_contextt)~f:(function|Error_aserr->err|Okdune_project_context->Ok(Dune_project_context.dune_lang_versiondune_project_context));;