Coder Social home page Coder Social logo

drafter's Introduction

Drafter

English Version

Drafter是什么

  • Drafter是一个命令行工具,用于分析iOS工程的代码,支持Objective-C和Swift。
  • 自动解析代码并生成方法调用关系图。
  • 自动解析代码并生成类继承关系图。

安装

执行以下指令,会自动安装到/usr/local/bin目录中:

curl "https://raw.githubusercontent.com/L-Zephyr/Drafter/master/install.sh" | /bin/sh

或者直接下载并编译源码

基本使用

指定一个文件或文件夹,Drafter会自动解析所有的OC和Swift代码文件,解析各个类型中方法的调用流程以及类型之间的继承关系,并以图表的形式展现出来。

导出HTML在浏览器中查看

以AFNetworking的源码为例,在命令行中执行如下命令,在参数-f后输入文件或目录:

drafter -f ./AFNetworking

解析结果会输出到当前路径下的DrafterStage文件夹中,用浏览器打开./DrafterStage/index.html文件即可浏览,建议使用chrome浏览器:

call graph

界面主要分为三个部分:

  1. 左边可以切换方法调用图(Call Graph)和类图(Class Diagram)模式,查看方法调用图时,列表中显示工程中的所有类型,选择可以直接切换。开启Intrinsic Method Only选项仅显示类型内部的方法调用(为防止调用过多默认打开);开启Show Access Level选项则会在方法节点的左上角显示该方法的访问等级;

  2. 中间是主要的展示区域,类型中的方法和方法之间的调用关系会以流程图的形式展示出来,选中一个方法会将该方法及其所调用的方法一起高亮出来;Pick按钮可以选择仅展示指定的方法;在类图模式中这里会显示工程中的类型继承关系,虚线表示实现协议,实线表示继承父类(UML): class diagram

  3. 右侧为详细信息面板,选中节点后自动弹出,展示该节点的所有信息,包括所有参数的名称以及类型等,Invokes字段列出了它所调用的方法,点击可以快速定位;

在浏览器中交互式的查看可以帮助你快速找到一个类型的关键逻辑,强烈建议通过这种方式来使用Drafter。前端部分的代码开源在DrafterStage,在Chrome环境下经过测试。

导出为PNG

这部分为第一个版本的旧接口,不建议使用

  • 如果要导出为PNG图片,首先确保电脑中安装了Graphviz,可以直接通过Homebrew来安装:brew install graphviz

  • 生成方法调用关系图,以AFNetworking为例,在命令后面使用-t参数指定输出类型为png,如:

    drafter -f ./AFHTTPSessionManager.m -t png

    在当前位置会自动生成一张以"文件名+.png"格式来命名的图片:

    1

  • 生成类继承关系图,使用-m参数将解析模式设定为inherit,解析继承结构:

    drafter -f ./AFNetworking -t png -m inherit

    在当前位置的文件夹中会生成一张名为"Inheritance.png"的图片,类图的表示遵循UML规则,虚线表示遵循协议,实线表示继承父类:

    3

参数

  • -f、—file <arg>
    必要参数,指定一个文件或文件夹,多个参数之间用逗号分隔,切勿出现空格。

  • --disable-auto-open

    禁止解析结束后自动打开结果。

  • --disable-cache

    在本次解析中不使用上一次缓存。

  • -t、--type

    可选参数,指定结果的输出形式,参数值为html或png,默认为html。

  • -m、—mode <arg>
    可选参数,仅在PNG模式中有效,指定解析模式,参数值可以为invoke、inherit、both。invoke表示只解析方法调用关系、inherit表示只解析类继承关系、both表示同时执行两种解析模式。默认为invoke。

  • -s、—search <arg>
    可选参数,仅在PNG模式中有效,指定关键字,多个关键字之间用逗号分隔,关键字忽略大小写。根据关键字过滤解析结果,只保留包含指定关键字的节点分支,如:

    drafter -f ./XXViewController.swift -s viewdidload -t png

    生成的结果中只包含"viewDidLoad"这个方法下的调用信息:

    4

  • -self、—self-method-only
    可选参数,仅在PNG模式中解析调用关系图时有效,生成结果仅保留用户自定义的方法。 默认情况下解析调用关系时会将所有的方法调用都解析出来,文件较大时结果会比较杂乱,开启该选项仅保留本文件中定义的方法,让结果更加清晰:

    drafter -f ./AFHTTPSessionManager.m -self -t png

    可以看到,与上面的第一个例子对比,去掉了调用外部方法的连线,整个代码执行的逻辑更加清晰:

    2

实现原理

实现细节请看https://juejin.im/post/5a3088e95188253ee45b6cbe

english-version

What is Drafter

  • Drafter is a command-line tool for analyzing iOS code, supporting Objective-C and Swift.
  • Automatically generates Call Graph.
  • Automatically generates Class Diagram.

Install

Run the following command, drafter will automatically install into the /usr/local/bin directory.

curl "https://raw.githubusercontent.com/L-Zephyr/Drafter/master/install.sh" | /bin/sh

Or you can download and compile the source directly.

Basic Use

Export to HTML

Run the following command. Enter the file or directory path after the -f argument :

drafter -f ./AFNetworking

Analysis result will be generated to the path ./DrafterStage. Then just open the file ./DrafterStage/index.html in browser (Recommended Chrome) :

call graph

In the browser you can interactively browse the Call Graph and the Class Dragram, it is strongly recommended to use drafter in this way.

Export to PNG

Deprecated !

  • If you would like to get png from the analysis result. First make sure Graphviz was correctly installed. You can install Graphviz by brew: brew install graphviz.

  • Generate the method call graph. Use argument -t png to specify the png mode, for example:

    drafter -f ./AFHTTPSessionManager.m -t png

    A picture will automatically generate in the current path, name as "file name + .png":

    1

  • Generate the inheritance graph

    drafter -f ./AFNetworking -m inherit -t png

    A picture named "Inheritance.png" will be generated in the current path:

    3

Parameter

  • -f , —file <arg>
    Required. Specify a file or folder, multiple parameters are separated by commas, don't use space.

  • -dao, --disable-auto-open

    Do not browse the result automatically when analysis finished.

  • -dc, --disable-cache

    Do not use cache in this parse.

  • -t , —type <arg>

    Optional. Specify the output type, html or png. Defaults to html.

  • -m , —mode <arg>
    Optional. Specify the parsing mode, only valid in png mode. Assigning invoke will generate call graph, assigning inherit will generate inheritance graph, or both to do both call and inheritance analysis. Defaults to invoke

  • -s , —search <arg>
    Optional. Specify keywords to filter the results, only valid in png mode. Multiple arguments are separated by commas. For example:

    drafter -f ./XXViewController.swift -s viewdidload -t png

    The generated graph will only contains the viewDidLoad branch.

    4

  • -self , —self-method-only
    Optional. Only takes effect when parsing the call graph in png mode, the generated graph will only contains the methods that user defined in the same file.

    By default, all the method calls will be parsed. The result will get cluttered when dealing with the large file. Turn on this option, only the methods defined in this file are saved. This will help you highlight the main logic in you code.

    For example:

    drafter -f ./AFHTTPSessionManager.m -self -t png

    As you can see, in contrast to the first example above, the connection to the external method is removed:

    2

drafter's People

Contributors

l-zephyr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

drafter's Issues

error: -static-stdlib is no longer supported for Apple platforms

Cloning into 'Drafter'...
remote: Enumerating objects: 2485, done.
remote: Total 2485 (delta 0), reused 0 (delta 0), pack-reused 2485 (from 1)
Receiving objects: 100% (2485/2485), 12.68 MiB | 1.21 MiB/s, done.
Resolving deltas: 100% (1397/1397), done.
Fetching https://github.com/L-Zephyr/SwiftyParse.git from cache
Fetching https://github.com/kylef/Spectre.git from cache
Fetching https://github.com/kylef/PathKit.git from cache
Fetched https://github.com/L-Zephyr/SwiftyParse.git from cache (0.96s)
Fetched https://github.com/kylef/PathKit.git from cache (0.96s)
Fetched https://github.com/kylef/Spectre.git from cache (0.96s)
Computing version for https://github.com/L-Zephyr/SwiftyParse.git
Computed https://github.com/L-Zephyr/SwiftyParse.git at 0.1.0 (0.03s)
Computing version for https://github.com/kylef/PathKit.git
Computed https://github.com/kylef/PathKit.git at 0.9.1 (0.02s)
Computing version for https://github.com/kylef/Spectre.git
Computed https://github.com/kylef/Spectre.git at 0.8.0 (0.02s)
Creating working copy for https://github.com/kylef/PathKit.git
Working copy of https://github.com/kylef/PathKit.git resolved at 0.9.1
Creating working copy for https://github.com/L-Zephyr/SwiftyParse.git
Working copy of https://github.com/L-Zephyr/SwiftyParse.git resolved at 0.1.0
Creating working copy for https://github.com/kylef/Spectre.git
Working copy of https://github.com/kylef/Spectre.git resolved at 0.8.0
warning: 'drafter': the target name drafter has different case on the filesystem and the Package.swift manifest file
Building for production...
error: -static-stdlib is no longer supported for Apple platforms
error: -static-stdlib is no longer supported for Apple platforms

Archive: ./Template/template.zip
creating: ./Template/drafter/template/
inflating: ./Template/drafter/template/index.html
inflating: ./Template/drafter/template/bundle.js
/bin/sh: line 16: cd: .build/release: No such file or directory
cp: drafter: No such file or directory

内存耗尽、进程卡死、没有提示

解析项目比较大、文件比较多的项目时, 进程会卡死、并且没有任何提示.

ls -lR | grep ".h" | wc -l taoyali@taoyali-2
3790

项目目录下有七八千文件,20万行代码

安装报错error: terminated(72): xcrun --sdk macosx --find xctest output:

macOS Mojave 10.14 Xcode 10

xxxdeMacBook-Pro:~ niuge$ curl "https://raw.githubusercontent.com/L-Zephyr/Drafter/master/install.sh" | /bin/sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 233 100 233 0 0 143 0 0:00:01 0:00:01 --:--:-- 144
Cloning into 'Drafter'...
remote: Enumerating objects: 29, done.
remote: Counting objects: 100% (29/29), done.
remote: Compressing objects: 100% (20/20), done.
remote: Total 2427 (delta 6), reused 20 (delta 5), pack-reused 2398
Receiving objects: 100% (2427/2427), 10.65 MiB | 44.00 KiB/s, done.
Resolving deltas: 100% (1361/1361), done.
error: terminated(72): xcrun --sdk macosx --find xctest output:

/bin/sh: line 8: cd: .build/release: No such file or directory
cp: drafter: No such file or directory

error: terminated(72)

Cloning into 'Drafter'...
remote: Enumerating objects: 2485, done.
remote: Total 2485 (delta 0), reused 0 (delta 0), pack-reused 2485
Receiving objects: 100% (2485/2485), 12.68 MiB | 241.00 KiB/s, done.
Resolving deltas: 100% (1397/1397), done.
error: terminated(72): SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk SHELL=/bin/zsh LaunchInstanceID=1D399186-C268-49B3-9261-D0A7B0C229DD SECURITYSESSIONID=186a6 LIBRARY_PATH=/usr/local/lib TMPDIR=/var/folders/t9/k3ndly6s4y182yb5c9hhzlzr0000gn/T/ TERM_PROGRAM_VERSION=433 XPC_FLAGS=0x0 PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.BgPuPBmrGv/Listeners TERM_SESSION_ID=ECEF5100-49F9-4C8B-B306-959F1EA2FBA3 _=/usr/bin/swift __CF_USER_TEXT_ENCODING=0x1F5:0x19:0x34 XPC_SERVICE_NAME=0 CPATH=/usr/local/include TERM=xterm-256color LANG=zh_CN.UTF-8 LOGNAME=class OLDPWD=/Users/class USER=class SHLVL=2 PWD=/Users/class/Drafter TERM_PROGRAM=Apple_Terminal HOME=/Users/class xcrun --sdk macosx --find xctest output:
xcrun: error: unable to find utility "xctest", not a developer tool or in PATH

Archive: ./Template/template.zip
creating: ./Template/drafter/template/
inflating: ./Template/drafter/template/index.html
inflating: ./Template/drafter/template/bundle.js
/bin/sh: line 16: cd: .build/release: No such file or directory
cp: drafter: No such file or directory

ParserRunner中parse方法并发写入results是否存在线程不安全的问题?

`var results: [FileParserResult] = []

    // 1. 解析OC文件
    for file in ocFiles {
        print("Parsing: \(file.lastComponent)")
        semaphore.wait()
        DispatchQueue.global().async {
            if let result = FileParser(file).run(usingCache) {
                results.append(result)
            }
            self.semaphore.signal()
        }
    }`

DispatchQueue.global()中的任务是并发执行,同时解析4个文件,在results.append(result)中是否会存在线程安全问题?

error: -static-stdlib is no longer supported for Apple platforms

Environment

【Mac】Apple M2
【OS】14.1.1 (23B81)

What I have done

curl "https://raw.githubusercontent.com/L-Zephyr/Drafter/master/install.sh" | /bin/sh

What I have got

Cloning into 'Drafter'...
remote: Enumerating objects: 2485, done.
remote: Total 2485 (delta 0), reused 0 (delta 0), pack-reused 2485
Receiving objects: 100% (2485/2485), 12.68 MiB | 3.16 MiB/s, done.
Resolving deltas: 100% (1397/1397), done.
Fetching https://github.com/kylef/Spectre.git from cache
Fetching https://github.com/kylef/PathKit.git from cache
Fetching https://github.com/L-Zephyr/SwiftyParse.git from cache
Fetched https://github.com/kylef/Spectre.git (1.81s)
Fetched https://github.com/L-Zephyr/SwiftyParse.git (1.81s)
Fetched https://github.com/kylef/PathKit.git (1.81s)
Computing version for https://github.com/L-Zephyr/SwiftyParse.git
Computed https://github.com/L-Zephyr/SwiftyParse.git at 0.1.0 (0.51s)
Computing version for https://github.com/kylef/PathKit.git
Computed https://github.com/kylef/PathKit.git at 0.9.1 (0.63s)
Computing version for https://github.com/kylef/Spectre.git
Computed https://github.com/kylef/Spectre.git at 0.8.0 (0.54s)
Creating working copy for https://github.com/kylef/PathKit.git
Working copy of https://github.com/kylef/PathKit.git resolved at 0.9.1
Creating working copy for https://github.com/kylef/Spectre.git
Working copy of https://github.com/kylef/Spectre.git resolved at 0.8.0
Creating working copy for https://github.com/L-Zephyr/SwiftyParse.git
Working copy of https://github.com/L-Zephyr/SwiftyParse.git resolved at 0.1.0
warning: 'drafter': the target name drafter has different case on the filesystem and the Package.swift manifest file
Building for production...
remark: Incremental compilation has been disabled: it is not compatible with whole module optimization
remark: Incremental compilation has been disabled: it is not compatible with whole module optimization
error: -static-stdlib is no longer supported for Apple platforms
error: -static-stdlib is no longer supported for Apple platforms
Archive: ./Template/template.zip
creating: ./Template/drafter/template/
inflating: ./Template/drafter/template/index.html
inflating: ./Template/drafter/template/bundle.js
Untitled-1.sh: line 16: cd: .build/release: No such file or directory
cp: drafter: No such file or directory

What I need help

How to solve this problem?
error: -static-stdlib is no longer supported for Apple platforms error: -static-stdlib is no longer supported for Apple platforms

Parsing Swift Issue

Parsing: FailureMessage.swift

The tool is breaking during pasring the file above.

Always show blank View

image as the image show, I have try Folder and files, but it did not work when I installing ,It show a lot of warnings, below is the details

/Users/huihuadeng/Drafter/Sources/drafter/Drafter.swift:143:5: warning: 'fileprivate' modifier is redundant for instance method declared in a fileprivate extension
fileprivate func craftInheritGraph() {
^~~~~~~~~~~~

/Users/huihuadeng/Drafter/Sources/drafter/Drafter.swift:163:5: warning: 'fileprivate' modifier is redundant for instance method declared in a fileprivate extension
fileprivate func craftinvokeGraph() {
^~~~~~~~~~~~

[4/4] Linking drafter
Build complete! (106.21s)

安装失败

Working copy of https://github.com/kylef/PathKit.git resolved at 0.9.1
'drafter' /Users/zhang/Drafter: warning: the target name drafter has different case on the filesystem and the Package.swift manifest file
remark: Incremental compilation has been disabled: it is not compatible with wremark: Incremental compilation has been disabled: it is not compatible with w/Users/zhang/Drafter/.build/checkouts/PathKit/Sources/PathKit.swift:98:14: warning: 'Hashable.hashValue' is deprecated as a protocol requirement; conform type 'Path' to 'Hashable' by implementing 'hash(into:)' instead
public var hashValue: Int {
^
/Users/zhang/Drafter/.build/checkouts/PathKit/Sources/PathKit.swift:591:12: error: value of optional type 'UnsafeMutablePointer?' (aka 'Optional<UnsafeMutablePointer>') must be unwrapped to a value of type 'UnsafeMutablePointer' (aka 'UnsafeMutablePointer')
free(cPattern)
^
/Users/zhang/Drafter/.build/checkouts/PathKit/Sources/PathKit.swift:591:12: note: coalesce using '??' to provide a default when the optional value contains 'nil'
free(cPattern)
^
?? <#default value#>
/Users/zhang/Drafter/.build/checkouts/PathKit/Sources/PathKit.swift:591:12: note: force-unwrap using '!' to abort execution if the optional value contains 'nil'
free(cPattern)
^
!
[1/3] Compiling PathKit PathKit.swift
Archive: ./Template/template.zip
creating: ./Template/drafter/template/
inflating: ./Template/drafter/template/index.html
inflating: ./Template/drafter/template/bundle.js
/bin/sh: line 16: cd: .build/release: No such file or directory
cp: drafter: No such file or directory

安装失败

sudo curl "https://raw.githubusercontent.com/L-Zephyr/Drafter/master/install.sh" | /bin/sh

% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 306 100 306 0 0 329 0 --:--:-- --:--:-- --:--:-- 329
正克隆到 'Drafter'...
remote: Enumerating objects: 81, done.
remote: Counting objects: 100% (81/81), done.
remote: Compressing objects: 100% (53/53), done.
remote: Total 2479 (delta 21), reused 56 (delta 15), pack-reused 2398
接收对象中: 100% (2479/2479), 12.69 MiB | 689.00 KiB/s, 完成.
处理 delta 中: 100% (1376/1376), 完成.
/Users/chengfeixiao/Drafter: error: manifest parse error(s):
:29:9: note: in file included from :29:
#import "string.h"
^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/string.h:180:10: note: in file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/string.h:180:
#include "strings.h"
^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/strings.h:92:10: note: in file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/strings.h:92:
#include <string.h>
^
/usr/local/include/string.h:25:10: error: 'plist/Node.h' file not found
#include <plist/Node.h>
^
:0: error: could not build Objective-C module 'Darwin'
Archive: ./Template/template.zip
creating: ./Template/drafter/template/
inflating: ./Template/drafter/template/index.html
inflating: ./Template/drafter/template/bundle.js
/bin/sh: line 9: cd: .build/release: No such file or directory
cp: cannot stat 'drafter': No such file or directory

缺少DrafterTests_Info.plist文件, 导致单元测试编译不过.

应该是漏提交了Drafter/drafter.xcodeproj/DrafterTests_Info.plist文件
单元测试编译不通过, 提示:

:-1: Build input file cannot be found: '/Users/zhihuitang/repo/ios/Drafter/drafter.xcodeproj/DrafterTests_Info.plist'

从本地Helloworld项目中copy过去一个plist也可以修复这个问题.

Class diagram 過大無法載入?

@L-Zephyr 你好,感謝你開發Drafter, 自Droxygen 後很久沒用自動生成的class diagram 了。
我生成的HTML 有 5MB, 但 class diagram 沒發載入,試了Firefox 和safari都不行。按了停留在第一個class的畫面,如圖:

screenshot 2018-11-28 at 11 13 52

如有需要,我可傳生成的文件供你參考,謝謝!

建议加入 颜色分辨

感谢作者写了这个工具,对于团队开发最近几年少有的实用和好用的项目,建议ui 上可以 最小工作量的优化,颜色优化。

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.