Skip to content

Commit

Permalink
adding basics for citelang gen (will be an action) (#9)
Browse files Browse the repository at this point in the history
* adding basics for citelang gen (will be an action)
Signed-off-by: vsoch <vsoch@users.noreply.github.com>
  • Loading branch information
vsoch authored Mar 24, 2022
1 parent 6cddd86 commit 5057eae
Show file tree
Hide file tree
Showing 12 changed files with 240 additions and 112 deletions.
1 change: 1 addition & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ jobs:

- name: Run Tests
env:
CITELANG_LIBRARIES_KEY: ${{ secrets.CITELANG_LIBRARIES_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
export PATH="/usr/share/miniconda/bin:$PATH"
Expand Down
27 changes: 27 additions & 0 deletions .github/workflows/test-action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: test-action

on:
pull_request: []

jobs:
test-action:
name: Test CiteLang
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v2

- name: Install CiteLang
run: pip install -e .

- name: Test citelang gen
uses: ./action/gen
env:
CITELANG_LIBRARIES_KEY: ${{ secrets.CITELANG_LIBRARIES_KEY }}
with:
package: citelang
manager: pypi
outfile: citelang.md

- name: View generated file
run: cat citelang.md
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ RUN pip install ipython
WORKDIR /code
COPY . /code
RUN pip install -e .[all]
ENTRYPOINT ["citelang"]
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ that when you publish your software, you should publish it to an appropriate pac

## TODO

- citelang should be able to parse requirements.txt or go.sum, etc.
- add graphic summary
- add GitHub actions
- finish GitHub actions (render, docs, remember to mention to use token, etc.)
- add gha to run here!

## Contributors

Expand Down
39 changes: 39 additions & 0 deletions action/gen/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: "citelang gen action"
description: "Generate a citelang markdown for your package"
inputs:
manager:
description: the name of the package manager
required: true
package:
description: the name of the package
required: true
outfile:
description: the name of the outputfile.
required: true
default: citelang.md
args:
description: additional arguments / parameters for citelang.
required: false
default: ""

runs:
using: "composite"
steps:

- name: Install CiteLang
shell: bash
run: |
which citelang
retval=$?
if [[ "${retval}" != "0" ]]; then
pip install citelang
fi
- name: Generate CiteLang
env:
manager: ${{ inputs.manager }}
package: ${{ inputs.package }}
outfile: ${{ inputs.outfile }}
args: ${{ inputs.args }}
run: citelang gen ${manager} ${package} --outfile ${outfile} ${args}
shell: bash
13 changes: 11 additions & 2 deletions citelang/client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,16 +106,23 @@ def get_parser():
credit = subparsers.add_parser(
"credit", description="calculate dependency credit for a package."
)
gen = subparsers.add_parser(
"gen", description="Generate a credit markdown file for a package of choice."
)
gen.add_argument("--outfile", "-o", help="Save to an output markdown file.")

render = subparsers.add_parser(
"render", description="render a credit tree into your markdown."
)
render.add_argument("filename", help="Markdown file to render software table into.")
render.add_argument("--outfile", "-o", help="Save to an output json file.")

for command in [pkg, deps, graph, credit, badge]:
for command in [pkg, deps, graph, credit, badge, gen]:
command.add_argument(
"package", help="package manager and name to parse", nargs=2
)

for command in [pkg, deps, graph, credit, badge]:
command.add_argument(
"--json",
dest="json",
Expand All @@ -125,7 +132,7 @@ def get_parser():
)
command.add_argument("--outfile", "-o", help="Save to an output json file.")

for command in [graph, credit, badge, render]:
for command in [graph, credit, badge, render, gen]:
command.add_argument(
"--max-depth", help="maximum depth to parse tree (default is unset)"
)
Expand Down Expand Up @@ -243,6 +250,8 @@ def help(return_code=0):
from .credit import main
elif args.command == "deps":
from .deps import main
elif args.command == "gen":
from .gen import main
elif args.command == "graph":
from .graph import main
elif args.command == "render":
Expand Down
26 changes: 26 additions & 0 deletions citelang/client/gen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2022, Vanessa Sochat"
__license__ = "MPL 2.0"

from citelang.main import Client
import citelang.utils as utils


def main(args, parser, extra, subparser):

cli = Client(quiet=args.quiet, settings_file=args.settings_file)
result = cli.gen(
name=args.package[1],
manager=args.package[0],
use_cache=not args.no_cache,
max_depth=args.max_depth,
max_deps=args.max_depth,
min_credit=args.min_credit,
credit_split=args.credit_split,
)

if args.outfile:
utils.write_file(result.render(), args.outfile)
print("Saved to %s" % args.outfile)
else:
print(result.render())
126 changes: 25 additions & 101 deletions citelang/main/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,61 +24,38 @@ def dependencies(self, manager, name, use_cache=True):
pkg = package.Package(manager, name, client=self, use_cache=use_cache)
return pkg.dependencies()

def render(
self,
filename,
use_cache=True,
max_depth=None,
max_deps=None,
min_credit=0.01,
credit_split=0.5,
):
def gen(self, name, manager, *args, **kwargs):
"""
Generate a one off credit table for a named library
"""
# Generate a root for our graph
root = self._graph(name=name, manager=manager, **kwargs)

# Prepare a parser that can generate a table
p = parser.Parser()
p.add_lib(name=name, manager=manager)
p.prepare_table({"%s:%s" % (manager, name): root})
return p

def render(self, filename, **kwargs):
"""
Given a filename with references, render the citelang table.
"""
p = parser.Parser(filename)
libs = p.parse()
p.parse()

# Derive each as a package credit tree
roots = {}
for lib in libs:
for lib in p.libs:
if "name" not in lib or "manager" not in lib:
logger.warning("Skipping %s, missing name or manager." % lib)
uid = "%s:%s" % (lib["manager"], lib["name"])
if "version" in lib or "release" in lib:
version = lib.get("version") or lib.get("release")
uid = "%s@%s" % (uid, version)
lib["name"] = "%s@%s" % (lib["name"], version)
roots[uid] = self._graph(
manager=lib["manager"],
name=lib["name"],
use_cache=use_cache,
max_depth=max_depth,
max_deps=max_deps,
min_credit=min_credit,
credit_split=credit_split,
)

# Generate the table with multiple roots - flatten out credit
table = {}

# Multiplier for credit depending on total packages
splitby = 1 / len(roots)
for lib, root in roots.items():
manager = lib.split(":")[0]
for node in root.iternodes():
if manager not in table:
table[manager] = {}
if node.name not in table[manager]:
table[manager][node.name] = {
"credit": 0,
"url": node.obj.homepage,
}
table[manager][node.name]["credit"] += node.credit * splitby

# Add listing of packages and dependencies to parser
p.data = table
p.round_by = root.round_by
roots[uid] = self._graph(manager=lib["manager"], name=lib["name"], **kwargs)

p.prepare_table(roots)
return p

def package_managers(self, use_cache=True):
Expand Down Expand Up @@ -114,58 +91,22 @@ def check_manager(self, name, use_cache=True):
managers = "\n".join(managers)
logger.exit(f"{name} is not a known manager. Choices are:\n{managers}")

def graph(
self,
manager,
name,
use_cache=True,
max_depth=None,
max_deps=None,
min_credit=0.01,
credit_split=0.5,
fmt=None,
):
def graph(self, fmt=None, *args, **kwargs):
"""
Generate a graph for a package.
credit_split is how to split credit between some package and its dependents. E.g., 0.5 means 50/50. 0.8 means
the main package gets 80%, and dependencies split 20%. We go up until the min credit 0.05 at which case we
stop adding.
"""
root = self._graph(
manager=manager,
name=name,
use_cache=use_cache,
max_depth=max_depth,
max_deps=max_deps,
min_credit=min_credit,
credit_split=credit_split,
)
root = self._graph(*args, **kwargs)
return results.Graph(root).graph(fmt=fmt)

def badge(
self,
manager,
name,
use_cache=True,
max_depth=None,
max_deps=None,
min_credit=0.01,
credit_split=0.5,
fmt=None,
):
def badge(self, *args, **kwargs):
"""
Generate a badge for a package
"""
root = self._graph(
manager=manager,
name=name,
use_cache=use_cache,
max_depth=max_depth,
max_deps=max_deps,
min_credit=min_credit,
credit_split=credit_split,
)
root = self._graph(*args, **kwargs)
return results.Badge(root)

def _graph(
Expand Down Expand Up @@ -294,28 +235,11 @@ def _graph(
root.children_names = list(node_names)
return root

def credit(
self,
manager,
name,
use_cache=True,
max_depth=None,
max_deps=None,
min_credit=0.05,
credit_split=0.5,
):
def credit(self, *args, **kwargs):
"""
Get the credit root node, then do additional graph parsing.
"""
root = self._graph(
manager=manager,
name=name,
use_cache=use_cache,
max_depth=max_depth,
max_deps=max_deps,
min_credit=min_credit,
credit_split=credit_split,
)
root = self._graph(*args, **kwargs)
return results.Tree(root)

def package(self, manager, name, use_cache=True):
Expand Down
Loading

0 comments on commit 5057eae

Please sign in to comment.