build_run_command Function

public function build_run_command(settings, full_cmdline, cmd_prefix, cmd_rest, roots, file_mask, changed_idx, changed_count) result(cmd)

Uses

  • proc~~build_run_command~~UsesGraph proc~build_run_command build_run_command module~watch_cmdsplice watch_cmdsplice proc~build_run_command->module~watch_cmdsplice

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.

Arguments

Type IntentOptional 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

Return Value character(len=:), allocatable


Calls

proc~~build_run_command~~CallsGraph proc~build_run_command build_run_command proc~inject_names_into_cmd inject_names_into_cmd proc~build_run_command->proc~inject_names_into_cmd

Called by

proc~~build_run_command~~CalledByGraph proc~build_run_command build_run_command proc~watcher_run watcher_t%watcher_run proc~watcher_run->proc~build_run_command

Source Code

   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