{"action":"opened","number":72,"pull_request":{"url":"https://api.github.com/repos/rustyio/sync/pulls/72","id":92908540,"html_url":"https://github.com/rustyio/sync/pull/72","diff_url":"https://github.com/rustyio/sync/pull/72.diff","patch_url":"https://github.com/rustyio/sync/pull/72.patch","issue_url":"https://api.github.com/repos/rustyio/sync/issues/72","number":72,"state":"open","locked":false,"title":"Fix for sync to work with meck","user":{"login":"toddgjohnson","id":6968217,"avatar_url":"https://avatars.githubusercontent.com/u/6968217?v=3","gravatar_id":"","url":"https://api.github.com/users/toddgjohnson","html_url":"https://github.com/toddgjohnson","followers_url":"https://api.github.com/users/toddgjohnson/followers","following_url":"https://api.github.com/users/toddgjohnson/following{/other_user}","gists_url":"https://api.github.com/users/toddgjohnson/gists{/gist_id}","starred_url":"https://api.github.com/users/toddgjohnson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/toddgjohnson/subscriptions","organizations_url":"https://api.github.com/users/toddgjohnson/orgs","repos_url":"https://api.github.com/users/toddgjohnson/repos","events_url":"https://api.github.com/users/toddgjohnson/events{/privacy}","received_events_url":"https://api.github.com/users/toddgjohnson/received_events","type":"User","site_admin":false},"body":"Currently, the Erlang mocking library [meck](http://github.com/eproxus/meck) breaks when used with sync.  Specifically, when meck loads a mocked module as a binary into the code server, sync picks this up as a change to the beam while running `sync_scanner:process_beam_lastmod()` and subsequently reloads the beam file into the code server, overwriting the loaded mock.\r\n\r\nThis PR proposes a general improvement to the `compare_beams()` cast method in sync_scanner which effectively makes sync only compare \"relevant\" beams, i.e. beams which have valid beam file references.  And as a side effect meck can be used with sync.\r\n\r\nCurrently, the return values of `code:which()` and `filelib:last_modified()` [here](https://github.com/rustyio/sync/blob/master/src/sync_scanner.erl#L181-L182) are not validated.  As a result, when `code:which()` doesn't return a filename but instead an atom describing the module status (see [the doc](http://erlang.org/doc/man/code.html#which-1)), this atom (instead of a valid path) is passed to `filelib:last_modified()` which returns 0 ([file doesn't exist](http://erlang.org/doc/man/filelib.html#last_modified-1)).  Finally, the {module_name, last_modified} tuple is inappropriately added to the list to be processed.  (For example, the zlib module is usually a preloaded module with no file reference, but is compared in the tuple list each time).  This is a general description of why ignoring the returns of these two calls doesn't make sense.  In the case of meck not working, it is a different outcome of the same issue...\r\n\r\nThe steps that break meck are the following:\r\n\r\n1. A user module \"mod1\" is loaded from path \"ebin/mod1.beam\" into the code server.\r\n2. A sync compare_beams method runs and adds a tuple, {\"mod1\", {{2016,10,14},{17,25,24}}}, to the beam lastmod list.\r\n2. Then `meck:expect()` is called to mock \"mod1\".  It pokes a binary into the code server,  **specifying the empty list (\"\") as the beam file reference** ([here](https://github.com/eproxus/meck/blob/master/src/meck_code.erl#L117)), which makes sense, since the loaded mocked module has now overridden the beam file.\r\n3. On the next compare_beams run, `filelib:last_modified()` is called with the empty list (\"\") and it returns 0 (since the file \"\" doesn't exist).\r\n4. Finally `sync_scanner:process_beam_lastmod()` sees a difference between the original datetime tuple and {\"mod1\", 0}, and reloads the beam from the path \"ebin/mod1.beam\" ultimately clobbering the loaded mock.\r\n\r\nIn summary, only beams with valid file references should be included in the list when comparing beam lastmod times.  It makes sense in general, and allows meck, and possibly other libraries which programmatically alter binaries in the code server to run alongside sync.\r\n\r\n","created_at":"2016-11-09T05:49:31Z","updated_at":"2016-11-09T05:49:31Z","closed_at":null,"merged_at":null,"merge_commit_sha":null,"assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/rustyio/sync/pulls/72/commits","review_comments_url":"https://api.github.com/repos/rustyio/sync/pulls/72/comments","review_comment_url":"https://api.github.com/repos/rustyio/sync/pulls/comments{/number}","comments_url":"https://api.github.com/repos/rustyio/sync/issues/72/comments","statuses_url":"https://api.github.com/repos/rustyio/sync/statuses/20846b02126846d69f1f4b2d00fcad580ef5c0d0","head":{"label":"toddgjohnson:validate-beams","ref":"validate-beams","sha":"20846b02126846d69f1f4b2d00fcad580ef5c0d0","user":{"login":"toddgjohnson","id":6968217,"avatar_url":"https://avatars.githubusercontent.com/u/6968217?v=3","gravatar_id":"","url":"https://api.github.com/users/toddgjohnson","html_url":"https://github.com/toddgjohnson","followers_url":"https://api.github.com/users/toddgjohnson/followers","following_url":"https://api.github.com/users/toddgjohnson/following{/other_user}","gists_url":"https://api.github.com/users/toddgjohnson/gists{/gist_id}","starred_url":"https://api.github.com/users/toddgjohnson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/toddgjohnson/subscriptions","organizations_url":"https://api.github.com/users/toddgjohnson/orgs","repos_url":"https://api.github.com/users/toddgjohnson/repos","events_url":"https://api.github.com/users/toddgjohnson/events{/privacy}","received_events_url":"https://api.github.com/users/toddgjohnson/received_events","type":"User","site_admin":false},"repo":{"id":70956898,"name":"sync","full_name":"toddgjohnson/sync","owner":{"login":"toddgjohnson","id":6968217,"avatar_url":"https://avatars.githubusercontent.com/u/6968217?v=3","gravatar_id":"","url":"https://api.github.com/users/toddgjohnson","html_url":"https://github.com/toddgjohnson","followers_url":"https://api.github.com/users/toddgjohnson/followers","following_url":"https://api.github.com/users/toddgjohnson/following{/other_user}","gists_url":"https://api.github.com/users/toddgjohnson/gists{/gist_id}","starred_url":"https://api.github.com/users/toddgjohnson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/toddgjohnson/subscriptions","organizations_url":"https://api.github.com/users/toddgjohnson/orgs","repos_url":"https://api.github.com/users/toddgjohnson/repos","events_url":"https://api.github.com/users/toddgjohnson/events{/privacy}","received_events_url":"https://api.github.com/users/toddgjohnson/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/toddgjohnson/sync","description":"On-the-fly recompiling and reloading in Erlang. Code without friction.","fork":true,"url":"https://api.github.com/repos/toddgjohnson/sync","forks_url":"https://api.github.com/repos/toddgjohnson/sync/forks","keys_url":"https://api.github.com/repos/toddgjohnson/sync/keys{/key_id}","collaborators_url":"https://api.github.com/repos/toddgjohnson/sync/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/toddgjohnson/sync/teams","hooks_url":"https://api.github.com/repos/toddgjohnson/sync/hooks","issue_events_url":"https://api.github.com/repos/toddgjohnson/sync/issues/events{/number}","events_url":"https://api.github.com/repos/toddgjohnson/sync/events","assignees_url":"https://api.github.com/repos/toddgjohnson/sync/assignees{/user}","branches_url":"https://api.github.com/repos/toddgjohnson/sync/branches{/branch}","tags_url":"https://api.github.com/repos/toddgjohnson/sync/tags","blobs_url":"https://api.github.com/repos/toddgjohnson/sync/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/toddgjohnson/sync/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/toddgjohnson/sync/git/refs{/sha}","trees_url":"https://api.github.com/repos/toddgjohnson/sync/git/trees{/sha}","statuses_url":"https://api.github.com/repos/toddgjohnson/sync/statuses/{sha}","languages_url":"https://api.github.com/repos/toddgjohnson/sync/languages","stargazers_url":"https://api.github.com/repos/toddgjohnson/sync/stargazers","contributors_url":"https://api.github.com/repos/toddgjohnson/sync/contributors","subscribers_url":"https://api.github.com/repos/toddgjohnson/sync/subscribers","subscription_url":"https://api.github.com/repos/toddgjohnson/sync/subscription","commits_url":"https://api.github.com/repos/toddgjohnson/sync/commits{/sha}","git_commits_url":"https://api.github.com/repos/toddgjohnson/sync/git/commits{/sha}","comments_url":"https://api.github.com/repos/toddgjohnson/sync/comments{/number}","issue_comment_url":"https://api.github.com/repos/toddgjohnson/sync/issues/comments{/number}","contents_url":"https://api.github.com/repos/toddgjohnson/sync/contents/{+path}","compare_url":"https://api.github.com/repos/toddgjohnson/sync/compare/{base}...{head}","merges_url":"https://api.github.com/repos/toddgjohnson/sync/merges","archive_url":"https://api.github.com/repos/toddgjohnson/sync/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/toddgjohnson/sync/downloads","issues_url":"https://api.github.com/repos/toddgjohnson/sync/issues{/number}","pulls_url":"https://api.github.com/repos/toddgjohnson/sync/pulls{/number}","milestones_url":"https://api.github.com/repos/toddgjohnson/sync/milestones{/number}","notifications_url":"https://api.github.com/repos/toddgjohnson/sync/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/toddgjohnson/sync/labels{/name}","releases_url":"https://api.github.com/repos/toddgjohnson/sync/releases{/id}","deployments_url":"https://api.github.com/repos/toddgjohnson/sync/deployments","created_at":"2016-10-15T00:42:41Z","updated_at":"2016-10-15T00:42:42Z","pushed_at":"2016-11-09T03:51:57Z","git_url":"git://github.com/toddgjohnson/sync.git","ssh_url":"git@github.com:toddgjohnson/sync.git","clone_url":"https://github.com/toddgjohnson/sync.git","svn_url":"https://github.com/toddgjohnson/sync","homepage":"","size":286,"stargazers_count":0,"watchers_count":0,"language":"Erlang","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"rustyio:master","ref":"master","sha":"a8562367fa30ca9051e2b3555796a6118f5e4b3c","user":{"login":"rustyio","id":28964,"avatar_url":"https://avatars.githubusercontent.com/u/28964?v=3","gravatar_id":"","url":"https://api.github.com/users/rustyio","html_url":"https://github.com/rustyio","followers_url":"https://api.github.com/users/rustyio/followers","following_url":"https://api.github.com/users/rustyio/following{/other_user}","gists_url":"https://api.github.com/users/rustyio/gists{/gist_id}","starred_url":"https://api.github.com/users/rustyio/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rustyio/subscriptions","organizations_url":"https://api.github.com/users/rustyio/orgs","repos_url":"https://api.github.com/users/rustyio/repos","events_url":"https://api.github.com/users/rustyio/events{/privacy}","received_events_url":"https://api.github.com/users/rustyio/received_events","type":"User","site_admin":false},"repo":{"id":727813,"name":"sync","full_name":"rustyio/sync","owner":{"login":"rustyio","id":28964,"avatar_url":"https://avatars.githubusercontent.com/u/28964?v=3","gravatar_id":"","url":"https://api.github.com/users/rustyio","html_url":"https://github.com/rustyio","followers_url":"https://api.github.com/users/rustyio/followers","following_url":"https://api.github.com/users/rustyio/following{/other_user}","gists_url":"https://api.github.com/users/rustyio/gists{/gist_id}","starred_url":"https://api.github.com/users/rustyio/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rustyio/subscriptions","organizations_url":"https://api.github.com/users/rustyio/orgs","repos_url":"https://api.github.com/users/rustyio/repos","events_url":"https://api.github.com/users/rustyio/events{/privacy}","received_events_url":"https://api.github.com/users/rustyio/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/rustyio/sync","description":"On-the-fly recompiling and reloading in Erlang. Code without friction.","fork":false,"url":"https://api.github.com/repos/rustyio/sync","forks_url":"https://api.github.com/repos/rustyio/sync/forks","keys_url":"https://api.github.com/repos/rustyio/sync/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rustyio/sync/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rustyio/sync/teams","hooks_url":"https://api.github.com/repos/rustyio/sync/hooks","issue_events_url":"https://api.github.com/repos/rustyio/sync/issues/events{/number}","events_url":"https://api.github.com/repos/rustyio/sync/events","assignees_url":"https://api.github.com/repos/rustyio/sync/assignees{/user}","branches_url":"https://api.github.com/repos/rustyio/sync/branches{/branch}","tags_url":"https://api.github.com/repos/rustyio/sync/tags","blobs_url":"https://api.github.com/repos/rustyio/sync/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rustyio/sync/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rustyio/sync/git/refs{/sha}","trees_url":"https://api.github.com/repos/rustyio/sync/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rustyio/sync/statuses/{sha}","languages_url":"https://api.github.com/repos/rustyio/sync/languages","stargazers_url":"https://api.github.com/repos/rustyio/sync/stargazers","contributors_url":"https://api.github.com/repos/rustyio/sync/contributors","subscribers_url":"https://api.github.com/repos/rustyio/sync/subscribers","subscription_url":"https://api.github.com/repos/rustyio/sync/subscription","commits_url":"https://api.github.com/repos/rustyio/sync/commits{/sha}","git_commits_url":"https://api.github.com/repos/rustyio/sync/git/commits{/sha}","comments_url":"https://api.github.com/repos/rustyio/sync/comments{/number}","issue_comment_url":"https://api.github.com/repos/rustyio/sync/issues/comments{/number}","contents_url":"https://api.github.com/repos/rustyio/sync/contents/{+path}","compare_url":"https://api.github.com/repos/rustyio/sync/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rustyio/sync/merges","archive_url":"https://api.github.com/repos/rustyio/sync/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rustyio/sync/downloads","issues_url":"https://api.github.com/repos/rustyio/sync/issues{/number}","pulls_url":"https://api.github.com/repos/rustyio/sync/pulls{/number}","milestones_url":"https://api.github.com/repos/rustyio/sync/milestones{/number}","notifications_url":"https://api.github.com/repos/rustyio/sync/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rustyio/sync/labels{/name}","releases_url":"https://api.github.com/repos/rustyio/sync/releases{/id}","deployments_url":"https://api.github.com/repos/rustyio/sync/deployments","created_at":"2010-06-18T14:25:31Z","updated_at":"2016-11-02T22:12:53Z","pushed_at":"2016-11-04T02:14:22Z","git_url":"git://github.com/rustyio/sync.git","ssh_url":"git@github.com:rustyio/sync.git","clone_url":"https://github.com/rustyio/sync.git","svn_url":"https://github.com/rustyio/sync","homepage":"","size":358,"stargazers_count":566,"watchers_count":566,"language":"Erlang","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":149,"mirror_url":null,"open_issues_count":15,"forks":149,"open_issues":15,"watchers":566,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/rustyio/sync/pulls/72"},"html":{"href":"https://github.com/rustyio/sync/pull/72"},"issue":{"href":"https://api.github.com/repos/rustyio/sync/issues/72"},"comments":{"href":"https://api.github.com/repos/rustyio/sync/issues/72/comments"},"review_comments":{"href":"https://api.github.com/repos/rustyio/sync/pulls/72/comments"},"review_comment":{"href":"https://api.github.com/repos/rustyio/sync/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/rustyio/sync/pulls/72/commits"},"statuses":{"href":"https://api.github.com/repos/rustyio/sync/statuses/20846b02126846d69f1f4b2d00fcad580ef5c0d0"}},"merged":false,"mergeable":null,"mergeable_state":"unknown","merged_by":null,"comments":0,"review_comments":0,"commits":1,"additions":14,"deletions":5,"changed_files":1}}
{"actor":{"display_login":"toddgjohnson"}}