LCOV - code coverage report
Current view: top level - src - util.js Coverage Total Hit
Test: cockpit-podman Lines: 88.3 % 111 98
Test Date: 2025-05-21 17:35:03

            Line data    Source code
       1           43 : import React, { useContext } from "react";
       2              : 
       3              : import { Tooltip } from "@patternfly/react-core/dist/esm/components/Tooltip";
       4              : import { debounce } from 'throttle-debounce';
       5              : 
       6              : import cockpit from 'cockpit';
       7              : import * as timeformat from 'timeformat';
       8              : 
       9           43 : const _ = cockpit.gettext;
      10              : 
      11           43 : export const PodmanInfoContext = React.createContext();
      12            5 : export const usePodmanInfo = () => useContext(PodmanInfoContext);
      13              : 
      14           43 : export const WithPodmanInfo = ({ value, children }) => {
      15           43 :     return (
      16           43 :         <PodmanInfoContext.Provider value={value}>
      17           43 :             {children}
      18           43 :         </PodmanInfoContext.Provider>
      19              :     );
      20           43 : };
      21              : 
      22              : // https://github.com/containers/podman/blob/main/libpod/define/containerstate.go
      23              : // "Restarting" comes from special handling of restart case in Application.updateContainer()
      24           43 : export const states = [_("Exited"), _("Paused"), _("Stopped"), _("Removing"), _("Configured"), _("Created"), _("Restart"), _("Running")];
      25              : 
      26              : // https://github.com/containers/podman/blob/main/libpod/define/podstate.go
      27           43 : export const podStates = [_("Created"), _("Running"), _("Stopped"), _("Paused"), _("Exited"), _("Error")];
      28              : 
      29           43 : export const fallbackRegistries = ["docker.io", "quay.io"];
      30              : 
      31           43 : export function debug(...args) {
      32            0 :     if (window.debugging === "all" || window.debugging?.includes("podman"))
      33            0 :         console.debug("podman", ...args);
      34           43 : }
      35              : 
      36              : // containers, pods, images states are indexed by these keys, to make the container IDs
      37              : // globally unique across users
      38           40 : export const makeKey = (uid, id) => `${uid ?? "user"}-${id}`;
      39              : 
      40           43 : export function truncate_id(id) {
      41            0 :     if (!id) {
      42            0 :         return "";
      43            0 :     }
      44           43 :     return id.substring(0, 12);
      45           43 : }
      46              : 
      47              : // this supports formatted strings (via Date.parse) or raw timestamps
      48           43 : export const RelativeTime = ({ time }) => {
      49           43 :     if (!time)
      50            0 :         return null;
      51           41 :     const timestamp = typeof time === "string" ? Date.parse(time) : time;
      52           43 :     const dateRel = timeformat.distanceToNow(timestamp);
      53           43 :     const dateAbs = timeformat.dateTimeSeconds(timestamp);
      54           43 :     return <Tooltip content={dateAbs}><span>{dateRel}</span></Tooltip>;
      55           43 : };
      56              : 
      57              : /*
      58              :  * The functions quote_cmdline and unquote_cmdline implement
      59              :  * a simple shell-like quoting syntax.  They are used when letting the
      60              :  * user edit a sequence of words as a single string.
      61              :  *
      62              :  * When parsing, words are separated by whitespace.  Single and double
      63              :  * quotes can be used to protect a sequence of characters that
      64              :  * contains whitespace or the other quote character.  A backslash can
      65              :  * be used to protect any character.  Quotes can appear in the middle
      66              :  * of a word.
      67              :  */
      68              : 
      69           43 : export function quote_cmdline(words) {
      70           15 :     words = words || [];
      71              : 
      72           43 :     function is_whitespace(c) {
      73           43 :         return c == ' ';
      74           43 :     }
      75              : 
      76           43 :     function quote(word) {
      77           43 :         let text = "";
      78           43 :         let quote_char = "";
      79           43 :         let i;
      80           43 :         for (i = 0; i < word.length; i++) {
      81           43 :             if (word[i] == '\\' || word[i] == quote_char)
      82            2 :                 text += '\\';
      83           43 :             else if (quote_char === "") {
      84           43 :                 if (word[i] == "'" || is_whitespace(word[i]))
      85           10 :                     quote_char = '"';
      86           43 :                 else if (word[i] == '"')
      87            0 :                     quote_char = "'";
      88           43 :             }
      89           43 :             text += word[i];
      90           43 :         }
      91              : 
      92           43 :         return quote_char + text + quote_char;
      93           43 :     }
      94              : 
      95           43 :     return words.map(quote).join(' ');
      96           43 : }
      97              : 
      98           15 : export function unquote_cmdline(text) {
      99           15 :     const words = [];
     100           15 :     let next;
     101              : 
     102           15 :     function is_whitespace(c) {
     103           15 :         return c == ' ';
     104           15 :     }
     105              : 
     106           15 :     function skip_whitespace() {
     107           15 :         while (next < text.length && is_whitespace(text[next]))
     108           15 :             next++;
     109           15 :     }
     110              : 
     111           15 :     function parse_word() {
     112           15 :         let word = "";
     113           15 :         let quote_char = null;
     114              : 
     115           15 :         while (next < text.length) {
     116            0 :             if (text[next] == '\\') {
     117            0 :                 next++;
     118            0 :                 if (next < text.length) {
     119            0 :                     word += text[next];
     120            0 :                 }
     121            0 :             } else if (text[next] == quote_char) {
     122            6 :                 quote_char = null;
     123            6 :             } else if (quote_char) {
     124            6 :                 word += text[next];
     125            6 :             } else if (text[next] == '"' || text[next] == "'") {
     126            6 :                 quote_char = text[next];
     127            6 :             } else if (is_whitespace(text[next])) {
     128            6 :                 break;
     129            6 :             } else
     130           15 :                 word += text[next];
     131           15 :             next++;
     132           15 :         }
     133           15 :         return word;
     134           15 :     }
     135              : 
     136           15 :     next = 0;
     137           15 :     skip_whitespace();
     138           15 :     while (next < text.length) {
     139           15 :         words.push(parse_word());
     140           15 :         skip_whitespace();
     141           15 :     }
     142              : 
     143           15 :     return words;
     144           15 : }
     145              : 
     146           43 : export function image_name(image) {
     147            4 :     return image.RepoTags ? image.RepoTags[0] : "<none>:<none>";
     148           43 : }
     149              : 
     150            4 : export function is_valid_container_name(name) {
     151            4 :     return /^[a-zA-Z0-9][a-zA-Z0-9_\\.-]*$/.test(name);
     152            4 : }
     153              : 
     154              : /* Clears a single field in validationFailed object.
     155              :  *
     156              :  * Arguments:
     157              :  *   - validationFailed (object): Object containing list of fields with validation error
     158              :  *   - key (string): Specified which field from validationFailed object is clear
     159              :  *   - onValidationChange (func)
     160              :  */
     161           16 : export const validationClear = (validationFailed, key, onValidationChange) => {
     162           16 :     if (!validationFailed)
     163           16 :         return;
     164              : 
     165           16 :     const delta = { ...validationFailed };
     166           16 :     delete delta[key];
     167           16 :     onValidationChange(delta);
     168           16 : };
     169              : 
     170              : // This method needs to be outside of component as re-render would create a new instance of debounce
     171           16 : export const validationDebounce = debounce(500, (validationHandler) => validationHandler());
        

Generated by: LCOV version 2.0-1