• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mirego / accent / #839

18 Mar 2026 03:13PM UTC coverage: 76.303% (+0.2%) from 76.071%
#839

push

github

simonprev
Rewrite ci-check.sh as a parallel task runner with live progress

Replace the linear sequential shell script with a bash runner that
executes phase-1 tasks serially (tests + compilation) then all phase-2
lint/format/type-check tasks in parallel. A spinner-based live dashboard
renders each task's state (pending/running/pass/fail) with elapsed time
and aggregated exit codes, replacing the simple per-step echo output.

2415 of 3165 relevant lines covered (76.3%)

22.97 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.83
/lib/movement/entries_commit_processor.ex
1
defmodule Movement.EntriesCommitProcessor do
2
  @moduledoc false
3
  alias Movement.MachineTranslations
4

5
  @no_action_keys ~w(noop autocorrect)
6
  @included_slave_actions ~w(new remove renew merge_on_corrected merge_on_proposed merge_on_proposed_force merge_on_corrected_force)
7

8
  @doc """
9
  For list of translations, new data (like the content of a file upload) and a given function,
10
  returns the list of operations that will be executed. The operations will be neither persisted nor run.
11

12
  The list contains the operations for keys that exists in the current translations list. For the removal of
13
  keys, use the process_for_remove/3 function.
14
  """
15
  @spec process(Movement.Context.t()) :: Movement.Context.t()
16
  def process(%Movement.Context{entries: entries, assigns: assigns, operations: operations} = context) do
17
    grouped_translations = group_by_key(assigns[:translations])
27✔
18
    versioned_translations_by_key = assigns[:versioned_translations_by_key] || %{}
27✔
19
    source_translations_by_key = assigns[:source_translations_by_key] || %{}
27✔
20

21
    new_operations =
27✔
22
      entries
23
      |> Enum.map(fn entry ->
24
        current_translation = fetch_current_translation(grouped_translations, entry.key)
52✔
25

26
        versioned_translation_ids =
52✔
27
          fetch_versioned_translation_ids(versioned_translations_by_key, entry.key, current_translation)
52✔
28

29
        source_translation_id =
52✔
30
          fetch_source_translation_id(source_translations_by_key, entry.key, current_translation)
52✔
31

32
        suggested_translation = %Movement.SuggestedTranslation{
52✔
33
          text: entry.value,
52✔
34
          key: entry.key,
52✔
35
          file_comment: entry.comment,
52✔
36
          file_index: entry.index,
52✔
37
          value_type: entry.value_type,
52✔
38
          plural: entry.plural,
52✔
39
          locked: entry.locked,
52✔
40
          translation_id: current_translation && current_translation.id,
52✔
41
          revision_id: Map.get(assigns[:revision], :id),
42
          version_id: assigns[:version] && Map.get(assigns[:version], :id),
52✔
43
          placeholders: entry.placeholders,
52✔
44
          versioned_translation_ids: versioned_translation_ids,
45
          source_translation_id: source_translation_id
46
        }
47

48
        operation = assigns[:comparer].(current_translation, suggested_translation)
52✔
49

50
        operation =
52✔
51
          if MachineTranslations.enable_machine_translation?(
52
               operation,
53
               entry,
54
               assigns[:revision],
55
               assigns[:project],
56
               assigns[:batch_action]
57
             ) do
58
            %{operation | machine_translations_enabled: true}
×
59
          else
60
            operation
52✔
61
          end
62

63
        %{operation | options: assigns[:options]}
52✔
64
      end)
65
      |> filter_for_revision(assigns[:revision])
66
      |> MachineTranslations.translate(assigns[:project], assigns[:master_revision], assigns[:revision])
67

68
    %{context | operations: new_operations ++ operations}
27✔
69
  end
70

71
  @doc """
72
  For list of translations and new data (like the content of a file upload),
73
  returns the list of operations concerning removed keys from the content that will be exectued.
74
  """
75
  @spec process_for_remove(Movement.Context.t()) :: Movement.Context.t()
76
  def process_for_remove(%Movement.Context{entries: entries, assigns: assigns, operations: operations} = context) do
77
    grouped_entries = group_by_key(entries)
17✔
78

79
    new_operations =
17✔
80
      assigns[:translations]
81
      |> Enum.filter(&(!&1.removed && not Map.has_key?(grouped_entries, &1.key)))
13✔
82
      |> Enum.map(fn current_translation ->
83
        suggested_translation = %{current_translation | marked_as_removed: true}
2✔
84

85
        assigns[:comparer].(suggested_translation, suggested_translation)
2✔
86
      end)
87

88
    %{context | operations: new_operations ++ operations}
17✔
89
  end
90

91
  defp group_by_key(list), do: Enum.group_by(list, & &1.key)
44✔
92

93
  defp fetch_current_translation(grouped_translations, key) do
94
    grouped_translations
95
    |> Map.get(key)
96
    |> case do
52✔
97
      [value | _rest] when is_map(value) -> value
20✔
98
      _ -> nil
32✔
99
    end
100
  end
101

102
  defp fetch_versioned_translation_ids(_versioned_translations_by_key, _key, current_translation)
20✔
103
       when not is_nil(current_translation),
104
       do: []
105

106
  defp fetch_versioned_translation_ids(versioned_translations_by_key, key, _current_translation) do
107
    versioned_translations_by_key
108
    |> Map.get(key, [])
109
    |> Enum.map(& &1.id)
32✔
110
  end
111

112
  defp fetch_source_translation_id(_source_translations_by_key, _key, current_translation)
20✔
113
       when not is_nil(current_translation),
114
       do: nil
115

116
  defp fetch_source_translation_id(source_translations_by_key, key, _current_translation) do
117
    case Map.get(source_translations_by_key, key) do
32✔
118
      %{id: id} -> id
1✔
119
      _ -> nil
31✔
120
    end
121
  end
122

123
  defp filter_for_revision(operations, %{master: true}) do
124
    Enum.filter(
26✔
125
      operations,
126
      fn operation ->
127
        operation.action not in @no_action_keys
51✔
128
      end
129
    )
130
  end
131

132
  defp filter_for_revision(operations, _) do
133
    Enum.filter(
1✔
134
      operations,
135
      fn operation ->
136
        operation.action in @included_slave_actions and operation.action not in @no_action_keys
1✔
137
      end
138
    )
139
  end
140
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc