Skip to content

Instantly share code, notes, and snippets.

@mfansler
Last active November 30, 2023 20:18
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mfansler/5a1a703d1ac6bb2139547003248c3827 to your computer and use it in GitHub Desktop.
Save mfansler/5a1a703d1ac6bb2139547003248c3827 to your computer and use it in GitHub Desktop.
Convert `conda list` output to YAML
#!/usr/bin/env awk -f
#' Author: Mervin Fansler
#' GitHub: @mfansler
#' License: MIT
#'
#' Basic usage
#' $ conda list --export | awk -f list_export_to_yaml.awk
#'
#' Omitting builds with 'no_builds'
#' $ conda list --export | awk -v no_builds=1 -f list_export_to_yaml.awk
#'
#' Specifying channels with 'channels'
#' $ conda list --export | awk -v channels="conda-forge,defaults" -f list_export_to_yaml.awk
BEGIN {
FS="=";
if (channels) split(channels, channels_arr, ",");
else channels_arr[0]="defaults";
}
{
# skip header
if ($1 ~ /^#/) next;
if ($3 ~ /pypi/) { # pypi packages
pip=1;
pypi[i++]=" - "$1"=="$2" ";
} else { # conda packages
if ($1 ~ /pip/) pip=1;
else { # should we keep builds?
if (no_builds) conda[j++]=" - "$1"="$2" ";
else conda[j++]=" - "$1"="$2"="$3" ";
}
}
}
END {
# emit channel info
print "channels: ";
for (k in channels_arr) print " - "channels_arr[k]" ";
# emit conda pkg info
print "dependencies: ";
for (j in conda) print conda[j];
# emit PyPI pkg info
if (pip) print " - pip ";
if (length(pypi) > 0) {
print " - pip: ";
for (i in pypi) print pypi[i];
}
}
#!/usr/bin/env awk -f
#' Author: Mervin Fansler
#' GitHub: @mfansler
#' License: MIT
#' Basic usage
#' $ conda list | awk -f list_to_yaml.awk
#'
#' Omitting builds with 'no_builds'
#' $ conda list | awk -v no_builds=1 -f list_export_to_yaml.awk
{
# skip header
if ($1 ~ /^#/) { next }
if ($4 ~ /pypi/) { # pypi packages
pip=1;
pypi[i++]=" - "$1"=="$2" ";
} else { # conda packages
if ($1 ~ /pip/) {
pip=1;
} else {
if (no_builds) conda[j++]=" - "$1"="$2" ";
else conda[j++]=" - "$1"="$2"="$3" ";
}
# include channels
if (!seen[$4]) {
if (length($4) == 0) {
channels[k++]=" - defaults ";
} else {
channels[k++]=" - "$4" ";
}
++seen[$4];
}
}
}
END {
# emit channel info
print "channels: ";
for (k in channels) print channels[k];
# emit conda pkg info
print "dependencies: ";
for (j in conda) print conda[j];
# emit PyPI pkg info
if (pip) print " - pip ";
if (length(pypi) > 0) {
print " - pip: ";
for (i in pypi) print pypi[i];
}
}
@mfansler
Copy link
Author

mfansler commented Sep 8, 2020

Revision Notes

Revision 4

  • include builds by default
  • provide no_builds variable to disable build specification in YAML
  • alternative script for conda list --export format (list_export_to_yaml.awk)
  • include channels variable for specify channels in result YAML; note that --export format lacks channel information

Revision 3

  • bug fix: handle no pip case

Revision 2

  • improved header detection

Revision 1

  • only includes versions (no build strings)
  • pip (if included) does not include version info; assuming latest pip is always preferred
  • channels are not emitted in any order; this should be manually adjusted! (Hint: usually defaults last, preceded by conda-forge)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment