How can I get a list of all packages with their license from a Podfile.lock?

305 Views Asked by At

Due to compliance reasons, I need to generate a list of all software packages we use with their licenses. Also for indirect (transitive) dependencies.

I know how to do the same with Python using pkg.get_metadata_lines("PKG-INFO") or for JavaScript using yarn licenses, but I have no clue how to do it with a Podfile.lock.

Given a Podfile.lock, how can I do something like this:

$ get-licenses Podfile.lock
BigInt==1.2.3;MIT
CryptoSwift==4.5.6;Apache License 2.0
SwiftProtobuf==1.3.5;BSDv3
1

There are 1 best solutions below

0
On

Python example to get transitive dependencies:

import networkx as nx
import matplotlib.pyplot as plt
import yaml


def fetch_connected_nodes(g, node, seen=None):
    if seen is None:
        seen = set()

    for nr in g.neighbors(node):
        if nr != node and nr not in seen:
            seen.add(nr)
            fetch_connected_nodes(g, nr, seen)

    return seen


def make_pod_graph(pods: dict, package_name: str):
    pod_graph: nx.DiGraph = nx.DiGraph()

    def add_pods(pod, parent):
        parent = parent.split(' ')[0]
        if isinstance(pod, dict):
            # Really only 1 key in the dict.
            for k, v in pod.items():
                add_pods(k, parent)
                add_pods(v, k)
        elif isinstance(pod, list):
            for i in pod:
                add_pods(i, parent)
        else:
            pod_params = pod.split(' ')
            pod_graph.add_node(pod_params[0])
            attrs = {'version': ''.join(pod_params[1:]).strip('()=')} if len(pod_params) > 1 else None

            if parent is not None:
                pod_graph.add_edge(parent, pod_params[0], attr=attrs)

    for p in pods:
        add_pods(p, package_name)

    return pod_graph


with open('Podfile.lock', 'r') as pod_file_lock:
    pod_data = yaml.safe_load(pod_file_lock)
    g_pod = make_pod_graph(pod_data['PODS'], 'Podfile.lock')

    for s in g_pod.neighbors('Podfile.lock'):
        print(f'{s};{";".join(fetch_connected_nodes(g_pod, s))}')

    # nx.draw(g_pod, with_labels=True, pos=nx.shell_layout(g_pod))
    # plt.show()

Result for this file:

GRMustache.swift;
GzipSwift;
Just;
PromiseKit;PromiseKit/CorePromise;PromiseKit/UIKit;PromiseKit/Foundation
PromiseKit/CorePromise;
PromiseKit/Foundation;PromiseKit/CorePromise
Sparkle;

You can get licenses using DEPENDENCIES or EXTERNAL SOURCES sections. Just find specific files in repos. Or, if you can find those packages using the OS package system (and then use, for example yarn licenses list, on them), that's an option.