{"action":"closed","number":159,"pull_request":{"url":"https://api.github.com/repos/nerdvegas/rez/pulls/159","id":30805946,"html_url":"https://github.com/nerdvegas/rez/pull/159","diff_url":"https://github.com/nerdvegas/rez/pull/159.diff","patch_url":"https://github.com/nerdvegas/rez/pull/159.patch","issue_url":"https://api.github.com/repos/nerdvegas/rez/issues/159","number":159,"state":"closed","locked":false,"title":"Windows and OSX Support","user":{"login":"mstreatfield","id":353434,"avatar_url":"https://avatars.githubusercontent.com/u/353434?v=3","gravatar_id":"","url":"https://api.github.com/users/mstreatfield","html_url":"https://github.com/mstreatfield","followers_url":"https://api.github.com/users/mstreatfield/followers","following_url":"https://api.github.com/users/mstreatfield/following{/other_user}","gists_url":"https://api.github.com/users/mstreatfield/gists{/gist_id}","starred_url":"https://api.github.com/users/mstreatfield/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mstreatfield/subscriptions","organizations_url":"https://api.github.com/users/mstreatfield/orgs","repos_url":"https://api.github.com/users/mstreatfield/repos","events_url":"https://api.github.com/users/mstreatfield/events{/privacy}","received_events_url":"https://api.github.com/users/mstreatfield/received_events","type":"User","site_admin":false},"body":"This pull request introduces the changes required for Rez to work on OSX and Windows.  The main changes are:\r\n\r\n* fix the install process.\r\n* complete the Windows specitific `system` and `platform_` implementations.\r\n* replace the `Windows` stub shell implementation with `cmd` for the Windows Command Prompt.\r\n* move the `prompt` setting from `rezconfig` to the individual shell implementations (as it is shell specific).\r\n* create a `rezconfig.py` for easier cross-platform configuration within the same Rez install.\r\n* update the resource location code.\r\n* update the unit tests.\r\n\r\nA bit more detail...\r\n\r\n* Colour in stdout/stderr messages is explicitly disabled.  Although it should work, it doesn't.  I have been unable to determine why (according to the Colorama documentation we are doing everything right).\r\n* In the context of `config.py` the `os.path.expanduser` implementation is a bit dangerous.  This method is implemented differently on Windows which caused problems with weak references in the implicit packages list.  I have created a custom (although slightly limited) version of `expanduser` for this purpose which is sufficient for our needs.  This is documented.\r\n* Creating `rezconfig.py` was necessary to be able to support cross-platform configuration in the same file, as suggested by Chad in issue #55 and inline with other open source projects.  Currently both the yaml and .py file are support (for backwards compatibility) but dropping the yaml longer term would reduce code complexity.\r\n* Where Windows doesn't explicitly support a feature (such as `os.chmod` for forwarding scripts etc.) I've blcoked this out with a comment and `if/else`.  Perhaps there are other cross-platform solutions we can use here, but I don't know what they are.\r\n* The changes to the resource system where subtle - essentially escaping a regex and removing a `to_posixpath` translation.  Otherwise this was the easiest thing I had to change (where I initially thought it the most complex).\r\n* There is a method called `_keytoken` in Rex which I had to extend (with `get_key_topken`) and make shell specific as it was assuming `${THIS}` for variable reference.  I don't fully understand why it's necessary - especially in the python context - but it is.\r\n* As the command prompt is shell specific I've moved this configuration from `rezconfig` into the plugins themselves.\r\n* The inheritence between `Shell`, `UnixShell` and the other implementations is a bit broken - or at least the `Shell` API is not clearly defined.  I've tidied this up a little bit (but not very much).  More work could be done here to improve readability.  This area feels a bit brittle.\r\n* No automatic shell detection is performed.  If you are on Windows you use the Windows Command Prompt and that's it.  This could be extended in the future, but as this is sufficient for my needs I've not investigated further/other shells.\r\n* Generally the changes to the tests where to support `\\` instead of '/' and are pretty straight forward.  The thing to remember here is the context - in some cases even if the test is running on Windows it's comparing against a hardcoded value in the fixtures and so `/` is required.  Therefore the changes might look inconsistent but they are correct.\r\n* I'm a little disappointed with my changes to `test_shells.py` - I've had to skip a lot of the tests.  This is in part due to some tests exercising features of the Windows Command Prompt that aren't support.  More could be done here.\r\n* Binding and forwarding scripts don't work.  This is due to the way Windows recognises executables (with the `PATHEXT` environment variable) and the lack of support for shebang lines.  It should be possible to support them, but I need to better understand how Windows handles this area.  Suggestions?\r\n* The string escaping in Rex has caused some problems and is incompatible with the Windows Command Prompt.  In general I haven't handled escaping in this shell due to issues that Federico has raised.  But the current implementation seems a bit too much and you'll see I'm explicitly replacing the `\"` in the `set` command.  Longer term this is probably incorrect - but I think changes to Rex are required first.\r\n\r\nThis branch was made from 2.0 and not resources2 - I realise this is probably an issue - however I had already started work before resources2 was created/finished.  The sheer number of changes in the resources2 branch (which go beyond directly improving the resource system) is going to make this hard to integrate.  I don't have time to tackle this immediately - but I do need Windows support now - so took the path of least resistance.  ","created_at":"2015-03-09T22:21:03Z","updated_at":"2015-04-20T23:30:07Z","closed_at":"2015-04-20T23:30:07Z","merged_at":null,"merge_commit_sha":"362b19d3cbeb29e20374ce745ac5392ab172ac2e","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/nerdvegas/rez/pulls/159/commits","review_comments_url":"https://api.github.com/repos/nerdvegas/rez/pulls/159/comments","review_comment_url":"https://api.github.com/repos/nerdvegas/rez/pulls/comments{/number}","comments_url":"https://api.github.com/repos/nerdvegas/rez/issues/159/comments","statuses_url":"https://api.github.com/repos/nerdvegas/rez/statuses/fcac25bdf1dd11ba8d1d83f3fdd00015c7e8d188","head":{"label":"mstreatfield:55_windows_and_osx_support","ref":"55_windows_and_osx_support","sha":"fcac25bdf1dd11ba8d1d83f3fdd00015c7e8d188","user":{"login":"mstreatfield","id":353434,"avatar_url":"https://avatars.githubusercontent.com/u/353434?v=3","gravatar_id":"","url":"https://api.github.com/users/mstreatfield","html_url":"https://github.com/mstreatfield","followers_url":"https://api.github.com/users/mstreatfield/followers","following_url":"https://api.github.com/users/mstreatfield/following{/other_user}","gists_url":"https://api.github.com/users/mstreatfield/gists{/gist_id}","starred_url":"https://api.github.com/users/mstreatfield/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mstreatfield/subscriptions","organizations_url":"https://api.github.com/users/mstreatfield/orgs","repos_url":"https://api.github.com/users/mstreatfield/repos","events_url":"https://api.github.com/users/mstreatfield/events{/privacy}","received_events_url":"https://api.github.com/users/mstreatfield/received_events","type":"User","site_admin":false},"repo":{"id":21260678,"name":"rez","full_name":"mstreatfield/rez","owner":{"login":"mstreatfield","id":353434,"avatar_url":"https://avatars.githubusercontent.com/u/353434?v=3","gravatar_id":"","url":"https://api.github.com/users/mstreatfield","html_url":"https://github.com/mstreatfield","followers_url":"https://api.github.com/users/mstreatfield/followers","following_url":"https://api.github.com/users/mstreatfield/following{/other_user}","gists_url":"https://api.github.com/users/mstreatfield/gists{/gist_id}","starred_url":"https://api.github.com/users/mstreatfield/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mstreatfield/subscriptions","organizations_url":"https://api.github.com/users/mstreatfield/orgs","repos_url":"https://api.github.com/users/mstreatfield/repos","events_url":"https://api.github.com/users/mstreatfield/events{/privacy}","received_events_url":"https://api.github.com/users/mstreatfield/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/mstreatfield/rez","description":"Rez - An integrated package configuration, build and deployment system for software","fork":true,"url":"https://api.github.com/repos/mstreatfield/rez","forks_url":"https://api.github.com/repos/mstreatfield/rez/forks","keys_url":"https://api.github.com/repos/mstreatfield/rez/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mstreatfield/rez/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mstreatfield/rez/teams","hooks_url":"https://api.github.com/repos/mstreatfield/rez/hooks","issue_events_url":"https://api.github.com/repos/mstreatfield/rez/issues/events{/number}","events_url":"https://api.github.com/repos/mstreatfield/rez/events","assignees_url":"https://api.github.com/repos/mstreatfield/rez/assignees{/user}","branches_url":"https://api.github.com/repos/mstreatfield/rez/branches{/branch}","tags_url":"https://api.github.com/repos/mstreatfield/rez/tags","blobs_url":"https://api.github.com/repos/mstreatfield/rez/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mstreatfield/rez/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mstreatfield/rez/git/refs{/sha}","trees_url":"https://api.github.com/repos/mstreatfield/rez/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mstreatfield/rez/statuses/{sha}","languages_url":"https://api.github.com/repos/mstreatfield/rez/languages","stargazers_url":"https://api.github.com/repos/mstreatfield/rez/stargazers","contributors_url":"https://api.github.com/repos/mstreatfield/rez/contributors","subscribers_url":"https://api.github.com/repos/mstreatfield/rez/subscribers","subscription_url":"https://api.github.com/repos/mstreatfield/rez/subscription","commits_url":"https://api.github.com/repos/mstreatfield/rez/commits{/sha}","git_commits_url":"https://api.github.com/repos/mstreatfield/rez/git/commits{/sha}","comments_url":"https://api.github.com/repos/mstreatfield/rez/comments{/number}","issue_comment_url":"https://api.github.com/repos/mstreatfield/rez/issues/comments{/number}","contents_url":"https://api.github.com/repos/mstreatfield/rez/contents/{+path}","compare_url":"https://api.github.com/repos/mstreatfield/rez/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mstreatfield/rez/merges","archive_url":"https://api.github.com/repos/mstreatfield/rez/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mstreatfield/rez/downloads","issues_url":"https://api.github.com/repos/mstreatfield/rez/issues{/number}","pulls_url":"https://api.github.com/repos/mstreatfield/rez/pulls{/number}","milestones_url":"https://api.github.com/repos/mstreatfield/rez/milestones{/number}","notifications_url":"https://api.github.com/repos/mstreatfield/rez/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mstreatfield/rez/labels{/name}","releases_url":"https://api.github.com/repos/mstreatfield/rez/releases{/id}","created_at":"2014-06-27T01:48:54Z","updated_at":"2014-06-25T02:11:54Z","pushed_at":"2015-04-20T23:23:53Z","git_url":"git://github.com/mstreatfield/rez.git","ssh_url":"git@github.com:mstreatfield/rez.git","clone_url":"https://github.com/mstreatfield/rez.git","svn_url":"https://github.com/mstreatfield/rez","homepage":"","size":14959,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"nerdvegas:2.0","ref":"2.0","sha":"013a4aad3abb6b20ec2305f89153f2b815c54c28","user":{"login":"nerdvegas","id":1632842,"avatar_url":"https://avatars.githubusercontent.com/u/1632842?v=3","gravatar_id":"","url":"https://api.github.com/users/nerdvegas","html_url":"https://github.com/nerdvegas","followers_url":"https://api.github.com/users/nerdvegas/followers","following_url":"https://api.github.com/users/nerdvegas/following{/other_user}","gists_url":"https://api.github.com/users/nerdvegas/gists{/gist_id}","starred_url":"https://api.github.com/users/nerdvegas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nerdvegas/subscriptions","organizations_url":"https://api.github.com/users/nerdvegas/orgs","repos_url":"https://api.github.com/users/nerdvegas/repos","events_url":"https://api.github.com/users/nerdvegas/events{/privacy}","received_events_url":"https://api.github.com/users/nerdvegas/received_events","type":"User","site_admin":false},"repo":{"id":4052021,"name":"rez","full_name":"nerdvegas/rez","owner":{"login":"nerdvegas","id":1632842,"avatar_url":"https://avatars.githubusercontent.com/u/1632842?v=3","gravatar_id":"","url":"https://api.github.com/users/nerdvegas","html_url":"https://github.com/nerdvegas","followers_url":"https://api.github.com/users/nerdvegas/followers","following_url":"https://api.github.com/users/nerdvegas/following{/other_user}","gists_url":"https://api.github.com/users/nerdvegas/gists{/gist_id}","starred_url":"https://api.github.com/users/nerdvegas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nerdvegas/subscriptions","organizations_url":"https://api.github.com/users/nerdvegas/orgs","repos_url":"https://api.github.com/users/nerdvegas/repos","events_url":"https://api.github.com/users/nerdvegas/events{/privacy}","received_events_url":"https://api.github.com/users/nerdvegas/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/nerdvegas/rez","description":"Rez - An integrated package configuration, build and deployment system for software","fork":false,"url":"https://api.github.com/repos/nerdvegas/rez","forks_url":"https://api.github.com/repos/nerdvegas/rez/forks","keys_url":"https://api.github.com/repos/nerdvegas/rez/keys{/key_id}","collaborators_url":"https://api.github.com/repos/nerdvegas/rez/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/nerdvegas/rez/teams","hooks_url":"https://api.github.com/repos/nerdvegas/rez/hooks","issue_events_url":"https://api.github.com/repos/nerdvegas/rez/issues/events{/number}","events_url":"https://api.github.com/repos/nerdvegas/rez/events","assignees_url":"https://api.github.com/repos/nerdvegas/rez/assignees{/user}","branches_url":"https://api.github.com/repos/nerdvegas/rez/branches{/branch}","tags_url":"https://api.github.com/repos/nerdvegas/rez/tags","blobs_url":"https://api.github.com/repos/nerdvegas/rez/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/nerdvegas/rez/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/nerdvegas/rez/git/refs{/sha}","trees_url":"https://api.github.com/repos/nerdvegas/rez/git/trees{/sha}","statuses_url":"https://api.github.com/repos/nerdvegas/rez/statuses/{sha}","languages_url":"https://api.github.com/repos/nerdvegas/rez/languages","stargazers_url":"https://api.github.com/repos/nerdvegas/rez/stargazers","contributors_url":"https://api.github.com/repos/nerdvegas/rez/contributors","subscribers_url":"https://api.github.com/repos/nerdvegas/rez/subscribers","subscription_url":"https://api.github.com/repos/nerdvegas/rez/subscription","commits_url":"https://api.github.com/repos/nerdvegas/rez/commits{/sha}","git_commits_url":"https://api.github.com/repos/nerdvegas/rez/git/commits{/sha}","comments_url":"https://api.github.com/repos/nerdvegas/rez/comments{/number}","issue_comment_url":"https://api.github.com/repos/nerdvegas/rez/issues/comments{/number}","contents_url":"https://api.github.com/repos/nerdvegas/rez/contents/{+path}","compare_url":"https://api.github.com/repos/nerdvegas/rez/compare/{base}...{head}","merges_url":"https://api.github.com/repos/nerdvegas/rez/merges","archive_url":"https://api.github.com/repos/nerdvegas/rez/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/nerdvegas/rez/downloads","issues_url":"https://api.github.com/repos/nerdvegas/rez/issues{/number}","pulls_url":"https://api.github.com/repos/nerdvegas/rez/pulls{/number}","milestones_url":"https://api.github.com/repos/nerdvegas/rez/milestones{/number}","notifications_url":"https://api.github.com/repos/nerdvegas/rez/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/nerdvegas/rez/labels{/name}","releases_url":"https://api.github.com/repos/nerdvegas/rez/releases{/id}","created_at":"2012-04-17T12:02:03Z","updated_at":"2015-04-19T01:46:17Z","pushed_at":"2015-04-20T23:28:36Z","git_url":"git://github.com/nerdvegas/rez.git","ssh_url":"git@github.com:nerdvegas/rez.git","clone_url":"https://github.com/nerdvegas/rez.git","svn_url":"https://github.com/nerdvegas/rez","homepage":"","size":16982,"stargazers_count":77,"watchers_count":77,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":34,"mirror_url":null,"open_issues_count":43,"forks":34,"open_issues":43,"watchers":77,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/nerdvegas/rez/pulls/159"},"html":{"href":"https://github.com/nerdvegas/rez/pull/159"},"issue":{"href":"https://api.github.com/repos/nerdvegas/rez/issues/159"},"comments":{"href":"https://api.github.com/repos/nerdvegas/rez/issues/159/comments"},"review_comments":{"href":"https://api.github.com/repos/nerdvegas/rez/pulls/159/comments"},"review_comment":{"href":"https://api.github.com/repos/nerdvegas/rez/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/nerdvegas/rez/pulls/159/commits"},"statuses":{"href":"https://api.github.com/repos/nerdvegas/rez/statuses/fcac25bdf1dd11ba8d1d83f3fdd00015c7e8d188"}},"merged":false,"mergeable":true,"mergeable_state":"clean","merged_by":null,"comments":1,"review_comments":0,"commits":3,"additions":2898,"deletions":303,"changed_files":36}}