GithubHelp home page GithubHelp logo

microsoft / cmd-call-graph Goto Github PK

View Code? Open in Web Editor NEW
49.0 11.0 18.0 1.3 MB

A simple tool to generate a call graph for calls within Windows CMD (batch) files.

License: MIT License

Python 97.78% Shell 2.22%
batch-script batch-file static-code-analysis call-graph call-graph-analysis python

cmd-call-graph's Issues

Visual representation of node size

It would be nice to visualize somehow the relationship between nodes from the point of view of number of lines of code. For example, have node size be proportional to the number of lines of code.

Fix connection type for blocks ending in goto

As an example:

    goto :foo
    :foo
    exit

This snippet creates the following dot file:

digraph g {
__begin__ [label=<<b>__begin__</b><br />(line 1)>]
__begin__ -> foo [label=goto,color=red3]
__begin__ -> foo [label=nested,color=blue3]
foo [label=<<b>foo</b><br />(line 2)>,color=red,penwidth=2]
}

The connection of type nested is wrong, and should not be reported.

Fix handling of nodes with %

If a node has a name with percent signs in it, for example %command%, the dot program doesn't seem to like it, and outputs a garbage node with just a percent sign and a letter or number.

Figure out why that's the case, and fix it.

Follow calls to external batch scripts

We could extend the tool to follow calls to external batch scripts, and produce a larger call graph including a set of scripts.

There is already some primitive logic to identify external calls in CallGraph._AnnotateNode, as it generates Command instances of type external_call, but those commands are not processed in the later loop that goes through all Command instances. Therefore the logic to process external calls can be added to that loop.

What we can do there is simply call CallGraph.Build again to recursively generate another instance of CallGraph, that we would need to add to a container in the original CallGraph instance itself, keeping track of this new type of connection.

There are a few open questions that come to mind:

  1. we need to handle recursion and not fall into the trap of infinite loops (for example, specifying a depth parameter to limit how deep we go in the chain of calls.
  2. we need to de-duplicate call graphs for external batch files, so that if we call a given file multiple times we point to the same sub-graph.
  3. we need to handle gracefully calls to non-batch files or files we don't want to expand (for example if we reached maximum depth). For example, by adding a single node for the file if we don't want or can't expand the given file
  4. we need to decide how to visually represent the different files. For example, we could have rectangular enclosures around each batch file involved in the graph.
  5. we may want to limit the set of files to expand (for example, only the ones belonging to a specific codebase). This might be achieved by specifying a set of files to expand as a command-line parameter.

Make the ordering of the resulting graph deterministic

The rendered graphs often have different shapes. It would be nice to change the resulting dot code to always use the same ordering, if possible.

Also, it would be nice to have begin at the start and the terminating nodes at the end.

Improve detection of exit nodes

Some exit nodes are not detected by the current logic, which is rather primitive and looks at where the script ends, rather than exploiting the call graph.

For example, the script wouldn't recognize the bar node as the exit node in the following code:

goto :foo
:bar
exit /b 1
:foo
goto bar

Add unit tests

The script was published "as-is", but for any further change, and to validate existing behavior, we really need to add some basic tests.

Update description replacing files with file

The description and the README say:

A simple tool to generate a call graph for Windows CMD (batch) files.

IMHO, it should read "for Windows CMD (batch) file."

The "files" suggest one can generate graph for batch scripts CALL-ing other batch scripts which, AFAICT, is not the case. Call graph can be generated for single batch file only.

Fix the build

Unit tests are failing, but the recent changes only touch README.md.

The error is the following:

2019-01-06T17:35:53.2926467Z =================================== FAILURES ===================================
2019-01-06T17:35:53.2930569Z ______________________ CodeLineTest.test_command_counters ______________________
2019-01-06T17:35:53.2933899Z 
2019-01-06T17:35:53.2940444Z self = <pytest_cov.plugin.CovPlugin object at 0x7f336dc97cd0>
2019-01-06T17:35:53.2950537Z item = <TestCaseFunction test_command_counters>
2019-01-06T17:35:53.2957731Z 
2019-01-06T17:35:53.2958299Z     @compat.hookwrapper
2019-01-06T17:35:53.2973012Z     def pytest_runtest_call(self, item):
2019-01-06T17:35:53.2989594Z >       if (item.get_marker('no_cover')
2019-01-06T17:35:53.2990087Z                 or 'no_cover' in getattr(item, 'fixturenames', ())):
2019-01-06T17:35:53.2990448Z E               AttributeError: 'TestCaseFunction' object has no attribute 'get_marker'

This seems to be related to a very recent change in pytest. From https://docs.pytest.org/en/latest/changelog.html#pytest-4-1-0-2019-01-05:

#4546: Remove Node.get_marker(name) the return value was not usable for more than a existence check. - pytest-dev/pytest#4546

Add a lint mode

The tool can identify some flaws in batch files, for example goto / call to non-existing labels.

Implement a --lint option that only outputs potential problems with a given script.

Improve command-line options

All the options around getting a richer output should be enabled by default. That's how I mostly use the tool and there is no reason to disable them unless specifically desired by the user.

Also I think using stdin as input can be confusing (the tool just hangs if no input is given), so I'd change -i to be mandatory and possibly even positional instead of an argument.

Track the terminating vs. non-terminating code paths for a given node

A node can be both terminating and non-terminating, depending on how it's invoked.

If it's reached via goto or nested from a node that would have been terminating, it's terminating for that code path. But if it's reached via call from a non-terminating node, it's not terminating.

It would be nice to surface this information somehow. The easiest option might be a warning, not sure how to actually represent this case in the call graph.

Migrate CI to Azure Pipelines

It would be nice to run automated tests on Azure Pipelines instead of Travis.

Once that works, we could even automate publishing the build artifacts to PyPi.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.