Construct the effective command to run based on changes and target masks.
For fpm build, the original command is returned unchanged.
For fpm run and fpm test, if the user did not already pin names via
--name/positional patterns, this routine can inject a computed set of
target names corresponding to the changed files. This reduces redundant
builds and speeds up iterative workflows.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(fpm_build_settings), | intent(in) | :: | settings | |||
| character(len=*), | intent(in) | :: | full_cmdline | |||
| character(len=*), | intent(in) | :: | cmd_prefix | |||
| character(len=*), | intent(in) | :: | cmd_rest | |||
| type(root_info_t), | intent(in), | allocatable | :: | roots(:) | ||
| integer(kind=int64), | intent(in), | allocatable | :: | file_mask(:) | ||
| integer, | intent(in) | :: | changed_idx(:) | |||
| integer, | intent(in) | :: | changed_count |
function build_run_command(settings, full_cmdline, cmd_prefix, cmd_rest, roots, file_mask, changed_idx, changed_count) result(cmd) use watch_cmdsplice, only: inject_names_into_cmd class(fpm_build_settings), intent(in) :: settings character(len=*), intent(in) :: full_cmdline character(len=*), intent(in) :: cmd_prefix character(len=*), intent(in) :: cmd_rest type(root_info_t), allocatable, intent(in) :: roots(:) integer(int64), allocatable, intent(in) :: file_mask(:) integer, intent(in) :: changed_idx(:) integer, intent(in) :: changed_count character(len=:), allocatable :: cmd logical :: is_test, is_run integer(int64) :: hitmask character(len=:), allocatable :: names_str integer :: j, idx logical :: user_pinned_names is_test = .false. is_run = .false. user_pinned_names = .false. select type (s => settings) type is (fpm_test_settings) is_test = .true. if (allocated(s%name)) user_pinned_names = (size(s%name) > 0) type is (fpm_run_settings) is_run = .true. if (allocated(s%name)) user_pinned_names = (size(s%name) > 0) class default continue end select if (user_pinned_names) then cmd = trim(full_cmdline) return end if if (.not. is_test .and. .not. is_run) then cmd = trim(full_cmdline) return end if if (.not. allocated(roots) .or. size(roots) == 0) then cmd = trim(full_cmdline) return end if if (.not. allocated(file_mask)) then cmd = trim(full_cmdline) return end if hitmask = 0_int64 do j = 1, changed_count idx = changed_idx(j) if (idx < 1 .or. idx > size(file_mask)) cycle hitmask = ior(hitmask, file_mask(idx)) end do if (hitmask == 0_int64) then cmd = trim(full_cmdline) return end if names_str = join_names_from_mask(roots, hitmask) if (len_trim(names_str) == 0) then cmd = trim(full_cmdline) return end if if (len_trim(cmd_prefix) == 0) then cmd = trim(full_cmdline) return end if cmd = inject_names_into_cmd(cmd_prefix, cmd_rest, names_str) contains function join_names_from_mask(roots, mask) result(s) type(root_info_t), intent(in) :: roots(:) integer(int64), intent(in) :: mask character(len=:), allocatable :: s integer :: rr character(len=:), allocatable :: nm s = "" do rr = 1, size(roots) if (iand(mask, roots(rr)%mask) == 0_int64) cycle if (.not. allocated(roots(rr)%name)) cycle nm = trim(roots(rr)%name) if (len_trim(nm) == 0) cycle if (len(s) > 0) s = s // " " s = s // nm end do end function join_names_from_mask end function build_run_command