{"action":"created","comment":{"url":"https://api.github.com/repos/sourcegraph/srclib/pulls/comments/54364726","id":54364726,"diff_hunk":"@@ -0,0 +1,186 @@\n+package cli\n+\n+import (\n+\t\"bytes\"\n+\t\"encoding/json\"\n+\t\"fmt\"\n+\t\"io/ioutil\"\n+\t\"log\"\n+\t\"os\"\n+\t\"path/filepath\"\n+\n+\t\"sourcegraph.com/sourcegraph/go-flags\"\n+\n+\t\"sourcegraph.com/sourcegraph/srclib/config\"\n+\t\"sourcegraph.com/sourcegraph/srclib/graph\"\n+\t\"sourcegraph.com/sourcegraph/srclib/grapher\"\n+\t\"sourcegraph.com/sourcegraph/srclib/plan\"\n+)\n+\n+func init() {\n+\tcliInit = append(cliInit, func(cli *flags.Command) {\n+\t\t_, err := cli.AddCommand(\"coverage\",\n+\t\t\t\"srclib coverage\",\n+\t\t\t\"compute approximate amount of code successfully analyzed by srclib\",\n+\t\t\t&coverageCmd,\n+\t\t)\n+\t\tif err != nil {\n+\t\t\tlog.Fatal(err)\n+\t\t}\n+\t})\n+}\n+\n+type Coverage struct {\n+\tFileScore      float32  // % files successfully processed\n+\tRefScore       float32  // % internal refs that resolve to a def\n+\tTokDensity     float32  // average number of refs/defs per LoC\n+\tUncoveredFiles []string // files for which srclib data was not successfully generated (best-effort guess)\n+}\n+\n+type codeFileDatum struct {\n+\tLoC          int\n+\tNumRefs      int\n+\tNumDefs      int\n+\tNumRefsValid int\n+}\n+\n+type CoverageCmd struct {\n+}\n+\n+var coverageCmd CoverageCmd\n+\n+func (c *CoverageCmd) Execute(args []string) error {\n+\trepo, err := OpenLocalRepo()\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\n+\tcvg, err := coverage(repo)\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\n+\tout, err := json.MarshalIndent(cvg, \"\", \"  \")\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\tfmt.Println(string(out))\n+\n+\treturn nil\n+}\n+\n+var codeExts = []string{\".go\", \".java\", \".py\", \".rb\", \".cpp\", \".ts\", \".cs\"} // codeExt lists all file extensions that indicate a code file we want to cover\n+var codeExts_ = make(map[string]struct{})\n+\n+func init() {\n+\tfor _, ext := range codeExts {\n+\t\tcodeExts_[ext] = struct{}{}\n+\t}\n+}\n+\n+func coverage(repo *Repo) (*Coverage, error) {\n+\tlineSep := []byte{'\\n'}\n+\tcodeFileData := make(map[string]*codeFileDatum)\n+\tlog.Printf(repo.RootDir)\n+\tfilepath.Walk(repo.RootDir, func(path string, info os.FileInfo, err error) error {\n+\t\tif filepath.IsAbs(path) {\n+\t\t\tvar err error\n+\t\t\tpath, err = filepath.Rel(repo.RootDir, path)\n+\t\t\tif err != nil {\n+\t\t\t\treturn err\n+\t\t\t}\n+\t\t}\n+\n+\t\tif info.IsDir() {","path":"cli/coverage_cmd.go","position":94,"original_position":94,"commit_id":"05268efc3998528aa1c77381d6e85498aa99a2dc","original_commit_id":"05268efc3998528aa1c77381d6e85498aa99a2dc","user":{"login":"jpoler","id":5551484,"avatar_url":"https://avatars.githubusercontent.com/u/5551484?v=3","gravatar_id":"","url":"https://api.github.com/users/jpoler","html_url":"https://github.com/jpoler","followers_url":"https://api.github.com/users/jpoler/followers","following_url":"https://api.github.com/users/jpoler/following{/other_user}","gists_url":"https://api.github.com/users/jpoler/gists{/gist_id}","starred_url":"https://api.github.com/users/jpoler/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jpoler/subscriptions","organizations_url":"https://api.github.com/users/jpoler/orgs","repos_url":"https://api.github.com/users/jpoler/repos","events_url":"https://api.github.com/users/jpoler/events{/privacy}","received_events_url":"https://api.github.com/users/jpoler/received_events","type":"User","site_admin":false},"body":"It may also be worthwhile to check whether the directory name starts with `.` and if so return `filepath.SkipDir`.","created_at":"2016-02-29T02:43:02Z","updated_at":"2016-02-29T02:43:02Z","html_url":"https://github.com/sourcegraph/srclib/pull/254#discussion_r54364726","pull_request_url":"https://api.github.com/repos/sourcegraph/srclib/pulls/254","_links":{"self":{"href":"https://api.github.com/repos/sourcegraph/srclib/pulls/comments/54364726"},"html":{"href":"https://github.com/sourcegraph/srclib/pull/254#discussion_r54364726"},"pull_request":{"href":"https://api.github.com/repos/sourcegraph/srclib/pulls/254"}}},"pull_request":{"url":"https://api.github.com/repos/sourcegraph/srclib/pulls/254","id":61012390,"html_url":"https://github.com/sourcegraph/srclib/pull/254","diff_url":"https://github.com/sourcegraph/srclib/pull/254.diff","patch_url":"https://github.com/sourcegraph/srclib/pull/254.patch","issue_url":"https://api.github.com/repos/sourcegraph/srclib/issues/254","number":254,"state":"open","locked":false,"title":"Coverage cmd","user":{"login":"beyang","id":1646931,"avatar_url":"https://avatars.githubusercontent.com/u/1646931?v=3","gravatar_id":"","url":"https://api.github.com/users/beyang","html_url":"https://github.com/beyang","followers_url":"https://api.github.com/users/beyang/followers","following_url":"https://api.github.com/users/beyang/following{/other_user}","gists_url":"https://api.github.com/users/beyang/gists{/gist_id}","starred_url":"https://api.github.com/users/beyang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/beyang/subscriptions","organizations_url":"https://api.github.com/users/beyang/orgs","repos_url":"https://api.github.com/users/beyang/repos","events_url":"https://api.github.com/users/beyang/events{/privacy}","received_events_url":"https://api.github.com/users/beyang/received_events","type":"User","site_admin":false},"body":"Coverage command for srclib data","created_at":"2016-02-28T23:28:03Z","updated_at":"2016-02-29T02:43:02Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e0e10f10aaa399e31d47f7c697a4cf111c898739","assignee":{"login":"jpoler","id":5551484,"avatar_url":"https://avatars.githubusercontent.com/u/5551484?v=3","gravatar_id":"","url":"https://api.github.com/users/jpoler","html_url":"https://github.com/jpoler","followers_url":"https://api.github.com/users/jpoler/followers","following_url":"https://api.github.com/users/jpoler/following{/other_user}","gists_url":"https://api.github.com/users/jpoler/gists{/gist_id}","starred_url":"https://api.github.com/users/jpoler/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jpoler/subscriptions","organizations_url":"https://api.github.com/users/jpoler/orgs","repos_url":"https://api.github.com/users/jpoler/repos","events_url":"https://api.github.com/users/jpoler/events{/privacy}","received_events_url":"https://api.github.com/users/jpoler/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/sourcegraph/srclib/pulls/254/commits","review_comments_url":"https://api.github.com/repos/sourcegraph/srclib/pulls/254/comments","review_comment_url":"https://api.github.com/repos/sourcegraph/srclib/pulls/comments{/number}","comments_url":"https://api.github.com/repos/sourcegraph/srclib/issues/254/comments","statuses_url":"https://api.github.com/repos/sourcegraph/srclib/statuses/05268efc3998528aa1c77381d6e85498aa99a2dc","head":{"label":"sourcegraph:coverage-cmd","ref":"coverage-cmd","sha":"05268efc3998528aa1c77381d6e85498aa99a2dc","user":{"login":"sourcegraph","id":3979584,"avatar_url":"https://avatars.githubusercontent.com/u/3979584?v=3","gravatar_id":"","url":"https://api.github.com/users/sourcegraph","html_url":"https://github.com/sourcegraph","followers_url":"https://api.github.com/users/sourcegraph/followers","following_url":"https://api.github.com/users/sourcegraph/following{/other_user}","gists_url":"https://api.github.com/users/sourcegraph/gists{/gist_id}","starred_url":"https://api.github.com/users/sourcegraph/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sourcegraph/subscriptions","organizations_url":"https://api.github.com/users/sourcegraph/orgs","repos_url":"https://api.github.com/users/sourcegraph/repos","events_url":"https://api.github.com/users/sourcegraph/events{/privacy}","received_events_url":"https://api.github.com/users/sourcegraph/received_events","type":"Organization","site_admin":false},"repo":{"id":22002058,"name":"srclib","full_name":"sourcegraph/srclib","owner":{"login":"sourcegraph","id":3979584,"avatar_url":"https://avatars.githubusercontent.com/u/3979584?v=3","gravatar_id":"","url":"https://api.github.com/users/sourcegraph","html_url":"https://github.com/sourcegraph","followers_url":"https://api.github.com/users/sourcegraph/followers","following_url":"https://api.github.com/users/sourcegraph/following{/other_user}","gists_url":"https://api.github.com/users/sourcegraph/gists{/gist_id}","starred_url":"https://api.github.com/users/sourcegraph/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sourcegraph/subscriptions","organizations_url":"https://api.github.com/users/sourcegraph/orgs","repos_url":"https://api.github.com/users/sourcegraph/repos","events_url":"https://api.github.com/users/sourcegraph/events{/privacy}","received_events_url":"https://api.github.com/users/sourcegraph/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/sourcegraph/srclib","description":"srclib is a polyglot code analysis library, built for hackability. It consists of language analysis toolchains (currently for Go and Java, with Python, JavaScript, and Ruby in beta) with a common output format, and a CLI tool for running the analysis.","fork":false,"url":"https://api.github.com/repos/sourcegraph/srclib","forks_url":"https://api.github.com/repos/sourcegraph/srclib/forks","keys_url":"https://api.github.com/repos/sourcegraph/srclib/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sourcegraph/srclib/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sourcegraph/srclib/teams","hooks_url":"https://api.github.com/repos/sourcegraph/srclib/hooks","issue_events_url":"https://api.github.com/repos/sourcegraph/srclib/issues/events{/number}","events_url":"https://api.github.com/repos/sourcegraph/srclib/events","assignees_url":"https://api.github.com/repos/sourcegraph/srclib/assignees{/user}","branches_url":"https://api.github.com/repos/sourcegraph/srclib/branches{/branch}","tags_url":"https://api.github.com/repos/sourcegraph/srclib/tags","blobs_url":"https://api.github.com/repos/sourcegraph/srclib/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sourcegraph/srclib/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sourcegraph/srclib/git/refs{/sha}","trees_url":"https://api.github.com/repos/sourcegraph/srclib/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sourcegraph/srclib/statuses/{sha}","languages_url":"https://api.github.com/repos/sourcegraph/srclib/languages","stargazers_url":"https://api.github.com/repos/sourcegraph/srclib/stargazers","contributors_url":"https://api.github.com/repos/sourcegraph/srclib/contributors","subscribers_url":"https://api.github.com/repos/sourcegraph/srclib/subscribers","subscription_url":"https://api.github.com/repos/sourcegraph/srclib/subscription","commits_url":"https://api.github.com/repos/sourcegraph/srclib/commits{/sha}","git_commits_url":"https://api.github.com/repos/sourcegraph/srclib/git/commits{/sha}","comments_url":"https://api.github.com/repos/sourcegraph/srclib/comments{/number}","issue_comment_url":"https://api.github.com/repos/sourcegraph/srclib/issues/comments{/number}","contents_url":"https://api.github.com/repos/sourcegraph/srclib/contents/{+path}","compare_url":"https://api.github.com/repos/sourcegraph/srclib/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sourcegraph/srclib/merges","archive_url":"https://api.github.com/repos/sourcegraph/srclib/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sourcegraph/srclib/downloads","issues_url":"https://api.github.com/repos/sourcegraph/srclib/issues{/number}","pulls_url":"https://api.github.com/repos/sourcegraph/srclib/pulls{/number}","milestones_url":"https://api.github.com/repos/sourcegraph/srclib/milestones{/number}","notifications_url":"https://api.github.com/repos/sourcegraph/srclib/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sourcegraph/srclib/labels{/name}","releases_url":"https://api.github.com/repos/sourcegraph/srclib/releases{/id}","deployments_url":"https://api.github.com/repos/sourcegraph/srclib/deployments","created_at":"2014-07-19T04:38:41Z","updated_at":"2016-02-28T04:44:14Z","pushed_at":"2016-02-28T23:28:03Z","git_url":"git://github.com/sourcegraph/srclib.git","ssh_url":"git@github.com:sourcegraph/srclib.git","clone_url":"https://github.com/sourcegraph/srclib.git","svn_url":"https://github.com/sourcegraph/srclib","homepage":"https://srclib.org","size":4374,"stargazers_count":760,"watchers_count":760,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":47,"mirror_url":null,"open_issues_count":62,"forks":47,"open_issues":62,"watchers":760,"default_branch":"master"}},"base":{"label":"sourcegraph:master","ref":"master","sha":"c3825e28670a299a4f709adb5717feaf8471b463","user":{"login":"sourcegraph","id":3979584,"avatar_url":"https://avatars.githubusercontent.com/u/3979584?v=3","gravatar_id":"","url":"https://api.github.com/users/sourcegraph","html_url":"https://github.com/sourcegraph","followers_url":"https://api.github.com/users/sourcegraph/followers","following_url":"https://api.github.com/users/sourcegraph/following{/other_user}","gists_url":"https://api.github.com/users/sourcegraph/gists{/gist_id}","starred_url":"https://api.github.com/users/sourcegraph/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sourcegraph/subscriptions","organizations_url":"https://api.github.com/users/sourcegraph/orgs","repos_url":"https://api.github.com/users/sourcegraph/repos","events_url":"https://api.github.com/users/sourcegraph/events{/privacy}","received_events_url":"https://api.github.com/users/sourcegraph/received_events","type":"Organization","site_admin":false},"repo":{"id":22002058,"name":"srclib","full_name":"sourcegraph/srclib","owner":{"login":"sourcegraph","id":3979584,"avatar_url":"https://avatars.githubusercontent.com/u/3979584?v=3","gravatar_id":"","url":"https://api.github.com/users/sourcegraph","html_url":"https://github.com/sourcegraph","followers_url":"https://api.github.com/users/sourcegraph/followers","following_url":"https://api.github.com/users/sourcegraph/following{/other_user}","gists_url":"https://api.github.com/users/sourcegraph/gists{/gist_id}","starred_url":"https://api.github.com/users/sourcegraph/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sourcegraph/subscriptions","organizations_url":"https://api.github.com/users/sourcegraph/orgs","repos_url":"https://api.github.com/users/sourcegraph/repos","events_url":"https://api.github.com/users/sourcegraph/events{/privacy}","received_events_url":"https://api.github.com/users/sourcegraph/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/sourcegraph/srclib","description":"srclib is a polyglot code analysis library, built for hackability. It consists of language analysis toolchains (currently for Go and Java, with Python, JavaScript, and Ruby in beta) with a common output format, and a CLI tool for running the analysis.","fork":false,"url":"https://api.github.com/repos/sourcegraph/srclib","forks_url":"https://api.github.com/repos/sourcegraph/srclib/forks","keys_url":"https://api.github.com/repos/sourcegraph/srclib/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sourcegraph/srclib/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sourcegraph/srclib/teams","hooks_url":"https://api.github.com/repos/sourcegraph/srclib/hooks","issue_events_url":"https://api.github.com/repos/sourcegraph/srclib/issues/events{/number}","events_url":"https://api.github.com/repos/sourcegraph/srclib/events","assignees_url":"https://api.github.com/repos/sourcegraph/srclib/assignees{/user}","branches_url":"https://api.github.com/repos/sourcegraph/srclib/branches{/branch}","tags_url":"https://api.github.com/repos/sourcegraph/srclib/tags","blobs_url":"https://api.github.com/repos/sourcegraph/srclib/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sourcegraph/srclib/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sourcegraph/srclib/git/refs{/sha}","trees_url":"https://api.github.com/repos/sourcegraph/srclib/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sourcegraph/srclib/statuses/{sha}","languages_url":"https://api.github.com/repos/sourcegraph/srclib/languages","stargazers_url":"https://api.github.com/repos/sourcegraph/srclib/stargazers","contributors_url":"https://api.github.com/repos/sourcegraph/srclib/contributors","subscribers_url":"https://api.github.com/repos/sourcegraph/srclib/subscribers","subscription_url":"https://api.github.com/repos/sourcegraph/srclib/subscription","commits_url":"https://api.github.com/repos/sourcegraph/srclib/commits{/sha}","git_commits_url":"https://api.github.com/repos/sourcegraph/srclib/git/commits{/sha}","comments_url":"https://api.github.com/repos/sourcegraph/srclib/comments{/number}","issue_comment_url":"https://api.github.com/repos/sourcegraph/srclib/issues/comments{/number}","contents_url":"https://api.github.com/repos/sourcegraph/srclib/contents/{+path}","compare_url":"https://api.github.com/repos/sourcegraph/srclib/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sourcegraph/srclib/merges","archive_url":"https://api.github.com/repos/sourcegraph/srclib/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sourcegraph/srclib/downloads","issues_url":"https://api.github.com/repos/sourcegraph/srclib/issues{/number}","pulls_url":"https://api.github.com/repos/sourcegraph/srclib/pulls{/number}","milestones_url":"https://api.github.com/repos/sourcegraph/srclib/milestones{/number}","notifications_url":"https://api.github.com/repos/sourcegraph/srclib/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sourcegraph/srclib/labels{/name}","releases_url":"https://api.github.com/repos/sourcegraph/srclib/releases{/id}","deployments_url":"https://api.github.com/repos/sourcegraph/srclib/deployments","created_at":"2014-07-19T04:38:41Z","updated_at":"2016-02-28T04:44:14Z","pushed_at":"2016-02-28T23:28:03Z","git_url":"git://github.com/sourcegraph/srclib.git","ssh_url":"git@github.com:sourcegraph/srclib.git","clone_url":"https://github.com/sourcegraph/srclib.git","svn_url":"https://github.com/sourcegraph/srclib","homepage":"https://srclib.org","size":4374,"stargazers_count":760,"watchers_count":760,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":47,"mirror_url":null,"open_issues_count":62,"forks":47,"open_issues":62,"watchers":760,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/sourcegraph/srclib/pulls/254"},"html":{"href":"https://github.com/sourcegraph/srclib/pull/254"},"issue":{"href":"https://api.github.com/repos/sourcegraph/srclib/issues/254"},"comments":{"href":"https://api.github.com/repos/sourcegraph/srclib/issues/254/comments"},"review_comments":{"href":"https://api.github.com/repos/sourcegraph/srclib/pulls/254/comments"},"review_comment":{"href":"https://api.github.com/repos/sourcegraph/srclib/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/sourcegraph/srclib/pulls/254/commits"},"statuses":{"href":"https://api.github.com/repos/sourcegraph/srclib/statuses/05268efc3998528aa1c77381d6e85498aa99a2dc"}}}}