{"action":"created","comment":{"url":"https://api.github.com/repos/dotnet/roslyn/pulls/comments/66533496","id":66533496,"diff_hunk":"@@ -0,0 +1,184 @@\n+#r \"System.Net.Http.dll\"\n+\n+using System.Net.Http;\n+using System.Runtime.CompilerServices;\n+using System.Text.RegularExpressions;\n+\n+var knownRepos = new[] { \"coreclr\", \"corefx\", \"projectk-tfs\", \"symreader\" };\n+\n+if (Args.Count < 1)\n+{\n+    Console.Error.WriteLine(\"Usage: fxupdate <Roslyn branch> [/c:<repo>=<commit-sha1>]\");\n+    Console.Error.WriteLine($\"Where <repo> is name of a repo: {string.Join(\", \", knownRepos)}\");\n+    return 1;\n+}\n+\n+string roslynBranch = Args[0];\n+\n+var commits = \n+    Args.Skip(1).Where(a => a.StartsWith(\"/c:\")).Select(a => a.Substring(\"/c:\".Length)).\n+    ToDictionary(k => k.Split('=')[0].Trim(), k => k.Split('=')[1].Trim(), StringComparer.OrdinalIgnoreCase);\n+\n+string unknownRepo = commits.Keys.FirstOrDefault(k => !knownRepos.Contains(k));\n+if (unknownRepo != null)\n+{\n+    Console.Error.WriteLine($\"Unknown repo: {unknownRepo}\");\n+    return 1;\n+}\n+\n+string GetScriptPath([CallerFilePath]string path = null) => path;\n+string roslynRoot = Path.GetFullPath(Path.Combine(GetScriptPath(), \"..\", \"..\", \"..\"));\n+\n+string coreFxChannel, coreClrChannel, symReaderChannel, projectkChannel;\n+\n+switch (roslynBranch)\n+{\n+    case \"master\":\n+    case \"future-stabilization\":\n+        coreFxChannel = coreClrChannel = projectkChannel = symReaderChannel = \"master\";\n+        break;\n+\n+    case \"stabilization\":\n+        coreFxChannel = coreClrChannel = projectkChannel = \"release/1.0.0\";\n+        symReaderChannel = \"netcore1.0\";\n+        break;\n+\n+    default:\n+        Console.Error.WriteLine($\"Error: Unexpected branch name: '{roslynBranch}'.\");\n+        return 2;\n+}\n+\n+// fetch latest CoreCLR and CoreFX package versions:\n+var client = new HttpClient();\n+\n+IEnumerable<KeyValuePair<string, string>> ParsePackageVersions(string content) =>\n+    from line in content.Split(new[] { '\\r', '\\n' }, StringSplitOptions.RemoveEmptyEntries)\n+    let pair = line.Split(' ')\n+    select new KeyValuePair<string, string>(pair[0], pair[1]);\n+\n+string GetVersionSuffix(string version)\n+{\n+    int dash = version.IndexOf('-');\n+    return (dash > 0) ? version.Substring(dash) : \"\";\n+}\n+\n+string GetCommonVersionSuffix(IEnumerable<KeyValuePair<string, string>> packages)\n+{\n+    var firstPkg = packages.First();\n+    string firstSuffix = GetVersionSuffix(firstPkg.Value);\n+    var otherPkg = packages.FirstOrDefault(p => GetVersionSuffix(p.Value) != firstSuffix);\n+    if (otherPkg.Key != null)\n+    {\n+        Console.Error.WriteLine($\"Error: Inconsistent version suffixes: {firstPkg.Key} {firstPkg.Value} vs {otherPkg.Key} {otherPkg.Value}\");\n+        Environment.Exit(3);\n+    }\n+\n+    return firstSuffix;\n+}\n+\n+async Task<string> DownloadPackageList(string repo, string channel)\n+{\n+    string versionsUrl = \"https://raw.githubusercontent.com/dotnet/versions\";\n+    string commit = commits.ContainsKey(repo) ? \"blob/\" + commits[repo] : \"master\";\n+    string url = $\"{versionsUrl}/{commit}/build-info/dotnet/{repo}/{channel}/Latest_Packages.txt\";\n+\n+    try\n+    {\n+        return await client.GetStringAsync(url);\n+    }\n+    catch (HttpRequestException e)\n+    {\n+        Console.Error.WriteLine();\n+        Console.Error.WriteLine($\"Error downloading {url}\");\n+        Console.Error.WriteLine(e.Message);\n+        Environment.Exit(4);\n+        return null;\n+    }\n+}\n+\n+Write(\"Downloading list of CoreFX packages...\");\n+var coreFXPackages = ParsePackageVersions(await DownloadPackageList(\"corefx\", coreFxChannel));\n+var coreFXVersionSuffix = GetCommonVersionSuffix(coreFXPackages);\n+WriteLine($\"Done. Version suffix: {coreFXVersionSuffix}\");\n+\n+Write(\"Downloading list of ProjectK packages ...\");\n+var projectkPackages = ParsePackageVersions(await DownloadPackageList(\"projectk-tfs\", projectkChannel));\n+WriteLine(\"Done.\");\n+\n+Write(\"Downloading list of CoreCLR packages ...\");\n+var coreClrPackages = ParsePackageVersions(await DownloadPackageList(\"coreclr\", coreClrChannel));\n+var coreClrVersionSuffix = GetCommonVersionSuffix(coreClrPackages);\n+WriteLine($\"Done. Version suffix: {coreClrVersionSuffix}\");\n+\n+Write(\"Downloading list of SymReader packages ...\");\n+var symReaderPackages = ParsePackageVersions(await DownloadPackageList(\"symreader\", symReaderChannel));\n+WriteLine(\"Done.\");\n+\n+var packages = coreFXPackages.Concat(projectkPackages).Concat(coreClrPackages).Concat(symReaderPackages).ToArray();\n+\n+WriteLine(\"Updating project.json files ...\");\n+\n+void UpdateProjectJsonFiles(string root)\n+{\n+    foreach (var filePath in Directory.EnumerateFiles(root, \"project.json\", SearchOption.AllDirectories))\n+    {\n+        Write($\"  {filePath} ... \");\n+\n+        string originalText = File.ReadAllText(filePath);\n+        string text = originalText;\n+\n+        foreach (var package in packages)\n+        {\n+            // only update pre-release versions\n+            text = Regex.Replace(\n+                text,\n+                $\"\\\"{package.Key}\\\": \\\"[0-9]+[.][0-9]+[.][0-9]+-[-a-zA-Z0-9]+\\\"\",\n+                $\"\\\"{package.Key}\\\": \\\"{package.Value}\\\"\");\n+        }\n+\n+        if (text != originalText)\n+        {\n+            File.WriteAllText(filePath, text);\n+\n+            WriteLine(\"UPDATED\");\n+        }\n+        else\n+        {\n+            WriteLine(\"OK\");\n+        }\n+    }\n+}\n+\n+UpdateProjectJsonFiles(Path.Combine(roslynRoot, \"src\"));\n+UpdateProjectJsonFiles(Path.Combine(roslynRoot, \"build\"));\n+\n+WriteLine(\"Done.\");\n+\n+WriteLine(\"Updating VSL.Versions.targets ...\");\n+\n+void UpdateTargetsFile(string path)\n+{\n+    string originalText = File.ReadAllText(path);\n+    string newText = originalText;\n+\n+    newText = UpdateVersionElement(newText, \"CoreFXVersionSuffix\", coreFXVersionSuffix);\n+    newText = UpdateVersionElement(newText, \"CoreClrVersionSuffix\", coreClrVersionSuffix);\n+\n+    if (originalText != newText)\n+    {\n+        File.WriteAllText(path, newText);\n+    }\n+}\n+\n+string UpdateVersionElement(string text, string elementName, string newValue)\n+{\n+    return Regex.Replace(\n+        text,\n+        $\"<{elementName}>[^<]+</{elementName}>\",\n+        $\"<{elementName}>{newValue}</{elementName}>\");\n+}\n+\n+UpdateTargetsFile(Path.Combine(roslynRoot, \"build\", \"Targets\", \"VSL.Versions.targets\"));","path":"build/scripts/fxupdate.csx","position":181,"original_position":181,"commit_id":"06af39169c97288dc2624739027561246db03dee","original_commit_id":"06af39169c97288dc2624739027561246db03dee","user":{"login":"tmat","id":41759,"avatar_url":"https://avatars.githubusercontent.com/u/41759?v=3","gravatar_id":"","url":"https://api.github.com/users/tmat","html_url":"https://github.com/tmat","followers_url":"https://api.github.com/users/tmat/followers","following_url":"https://api.github.com/users/tmat/following{/other_user}","gists_url":"https://api.github.com/users/tmat/gists{/gist_id}","starred_url":"https://api.github.com/users/tmat/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tmat/subscriptions","organizations_url":"https://api.github.com/users/tmat/orgs","repos_url":"https://api.github.com/users/tmat/repos","events_url":"https://api.github.com/users/tmat/events{/privacy}","received_events_url":"https://api.github.com/users/tmat/received_events","type":"User","site_admin":false},"body":"Yes","created_at":"2016-06-09T22:29:22Z","updated_at":"2016-06-09T22:29:22Z","html_url":"https://github.com/dotnet/roslyn/pull/11899#discussion_r66533496","pull_request_url":"https://api.github.com/repos/dotnet/roslyn/pulls/11899","_links":{"self":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/comments/66533496"},"html":{"href":"https://github.com/dotnet/roslyn/pull/11899#discussion_r66533496"},"pull_request":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/11899"}}},"pull_request":{"url":"https://api.github.com/repos/dotnet/roslyn/pulls/11899","id":73281918,"html_url":"https://github.com/dotnet/roslyn/pull/11899","diff_url":"https://github.com/dotnet/roslyn/pull/11899.diff","patch_url":"https://github.com/dotnet/roslyn/pull/11899.patch","issue_url":"https://api.github.com/repos/dotnet/roslyn/issues/11899","number":11899,"state":"open","locked":false,"title":"Add fxupdate.csx script for updating versions of dependencies","user":{"login":"tmat","id":41759,"avatar_url":"https://avatars.githubusercontent.com/u/41759?v=3","gravatar_id":"","url":"https://api.github.com/users/tmat","html_url":"https://github.com/tmat","followers_url":"https://api.github.com/users/tmat/followers","following_url":"https://api.github.com/users/tmat/following{/other_user}","gists_url":"https://api.github.com/users/tmat/gists{/gist_id}","starred_url":"https://api.github.com/users/tmat/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tmat/subscriptions","organizations_url":"https://api.github.com/users/tmat/orgs","repos_url":"https://api.github.com/users/tmat/repos","events_url":"https://api.github.com/users/tmat/events{/privacy}","received_events_url":"https://api.github.com/users/tmat/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-06-09T20:40:19Z","updated_at":"2016-06-09T22:29:22Z","closed_at":null,"merged_at":null,"merge_commit_sha":"84c20884399ab0da67fe21ba65a21ccf48548d4c","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/dotnet/roslyn/pulls/11899/commits","review_comments_url":"https://api.github.com/repos/dotnet/roslyn/pulls/11899/comments","review_comment_url":"https://api.github.com/repos/dotnet/roslyn/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dotnet/roslyn/issues/11899/comments","statuses_url":"https://api.github.com/repos/dotnet/roslyn/statuses/06af39169c97288dc2624739027561246db03dee","head":{"label":"tmat:FxUpdate","ref":"FxUpdate","sha":"06af39169c97288dc2624739027561246db03dee","user":{"login":"tmat","id":41759,"avatar_url":"https://avatars.githubusercontent.com/u/41759?v=3","gravatar_id":"","url":"https://api.github.com/users/tmat","html_url":"https://github.com/tmat","followers_url":"https://api.github.com/users/tmat/followers","following_url":"https://api.github.com/users/tmat/following{/other_user}","gists_url":"https://api.github.com/users/tmat/gists{/gist_id}","starred_url":"https://api.github.com/users/tmat/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tmat/subscriptions","organizations_url":"https://api.github.com/users/tmat/orgs","repos_url":"https://api.github.com/users/tmat/repos","events_url":"https://api.github.com/users/tmat/events{/privacy}","received_events_url":"https://api.github.com/users/tmat/received_events","type":"User","site_admin":false},"repo":{"id":30440379,"name":"roslyn","full_name":"tmat/roslyn","owner":{"login":"tmat","id":41759,"avatar_url":"https://avatars.githubusercontent.com/u/41759?v=3","gravatar_id":"","url":"https://api.github.com/users/tmat","html_url":"https://github.com/tmat","followers_url":"https://api.github.com/users/tmat/followers","following_url":"https://api.github.com/users/tmat/following{/other_user}","gists_url":"https://api.github.com/users/tmat/gists{/gist_id}","starred_url":"https://api.github.com/users/tmat/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tmat/subscriptions","organizations_url":"https://api.github.com/users/tmat/orgs","repos_url":"https://api.github.com/users/tmat/repos","events_url":"https://api.github.com/users/tmat/events{/privacy}","received_events_url":"https://api.github.com/users/tmat/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/tmat/roslyn","description":"The .NET Compiler Platform (\"Roslyn\") provides open-source C# and Visual Basic compilers with rich code analysis APIs.","fork":true,"url":"https://api.github.com/repos/tmat/roslyn","forks_url":"https://api.github.com/repos/tmat/roslyn/forks","keys_url":"https://api.github.com/repos/tmat/roslyn/keys{/key_id}","collaborators_url":"https://api.github.com/repos/tmat/roslyn/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/tmat/roslyn/teams","hooks_url":"https://api.github.com/repos/tmat/roslyn/hooks","issue_events_url":"https://api.github.com/repos/tmat/roslyn/issues/events{/number}","events_url":"https://api.github.com/repos/tmat/roslyn/events","assignees_url":"https://api.github.com/repos/tmat/roslyn/assignees{/user}","branches_url":"https://api.github.com/repos/tmat/roslyn/branches{/branch}","tags_url":"https://api.github.com/repos/tmat/roslyn/tags","blobs_url":"https://api.github.com/repos/tmat/roslyn/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/tmat/roslyn/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/tmat/roslyn/git/refs{/sha}","trees_url":"https://api.github.com/repos/tmat/roslyn/git/trees{/sha}","statuses_url":"https://api.github.com/repos/tmat/roslyn/statuses/{sha}","languages_url":"https://api.github.com/repos/tmat/roslyn/languages","stargazers_url":"https://api.github.com/repos/tmat/roslyn/stargazers","contributors_url":"https://api.github.com/repos/tmat/roslyn/contributors","subscribers_url":"https://api.github.com/repos/tmat/roslyn/subscribers","subscription_url":"https://api.github.com/repos/tmat/roslyn/subscription","commits_url":"https://api.github.com/repos/tmat/roslyn/commits{/sha}","git_commits_url":"https://api.github.com/repos/tmat/roslyn/git/commits{/sha}","comments_url":"https://api.github.com/repos/tmat/roslyn/comments{/number}","issue_comment_url":"https://api.github.com/repos/tmat/roslyn/issues/comments{/number}","contents_url":"https://api.github.com/repos/tmat/roslyn/contents/{+path}","compare_url":"https://api.github.com/repos/tmat/roslyn/compare/{base}...{head}","merges_url":"https://api.github.com/repos/tmat/roslyn/merges","archive_url":"https://api.github.com/repos/tmat/roslyn/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/tmat/roslyn/downloads","issues_url":"https://api.github.com/repos/tmat/roslyn/issues{/number}","pulls_url":"https://api.github.com/repos/tmat/roslyn/pulls{/number}","milestones_url":"https://api.github.com/repos/tmat/roslyn/milestones{/number}","notifications_url":"https://api.github.com/repos/tmat/roslyn/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/tmat/roslyn/labels{/name}","releases_url":"https://api.github.com/repos/tmat/roslyn/releases{/id}","deployments_url":"https://api.github.com/repos/tmat/roslyn/deployments","created_at":"2015-02-07T01:09:01Z","updated_at":"2016-01-11T17:34:59Z","pushed_at":"2016-06-09T21:42:20Z","git_url":"git://github.com/tmat/roslyn.git","ssh_url":"git@github.com:tmat/roslyn.git","clone_url":"https://github.com/tmat/roslyn.git","svn_url":"https://github.com/tmat/roslyn","homepage":"","size":165073,"stargazers_count":0,"watchers_count":0,"language":"C#","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":"dotnet:stabilization","ref":"stabilization","sha":"dae35cd2f5ef7398d7eacc23d1110c658e661dc1","user":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"repo":{"id":29078997,"name":"roslyn","full_name":"dotnet/roslyn","owner":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dotnet/roslyn","description":"The .NET Compiler Platform (\"Roslyn\") provides open-source C# and Visual Basic compilers with rich code analysis APIs.","fork":false,"url":"https://api.github.com/repos/dotnet/roslyn","forks_url":"https://api.github.com/repos/dotnet/roslyn/forks","keys_url":"https://api.github.com/repos/dotnet/roslyn/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dotnet/roslyn/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dotnet/roslyn/teams","hooks_url":"https://api.github.com/repos/dotnet/roslyn/hooks","issue_events_url":"https://api.github.com/repos/dotnet/roslyn/issues/events{/number}","events_url":"https://api.github.com/repos/dotnet/roslyn/events","assignees_url":"https://api.github.com/repos/dotnet/roslyn/assignees{/user}","branches_url":"https://api.github.com/repos/dotnet/roslyn/branches{/branch}","tags_url":"https://api.github.com/repos/dotnet/roslyn/tags","blobs_url":"https://api.github.com/repos/dotnet/roslyn/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dotnet/roslyn/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dotnet/roslyn/git/refs{/sha}","trees_url":"https://api.github.com/repos/dotnet/roslyn/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dotnet/roslyn/statuses/{sha}","languages_url":"https://api.github.com/repos/dotnet/roslyn/languages","stargazers_url":"https://api.github.com/repos/dotnet/roslyn/stargazers","contributors_url":"https://api.github.com/repos/dotnet/roslyn/contributors","subscribers_url":"https://api.github.com/repos/dotnet/roslyn/subscribers","subscription_url":"https://api.github.com/repos/dotnet/roslyn/subscription","commits_url":"https://api.github.com/repos/dotnet/roslyn/commits{/sha}","git_commits_url":"https://api.github.com/repos/dotnet/roslyn/git/commits{/sha}","comments_url":"https://api.github.com/repos/dotnet/roslyn/comments{/number}","issue_comment_url":"https://api.github.com/repos/dotnet/roslyn/issues/comments{/number}","contents_url":"https://api.github.com/repos/dotnet/roslyn/contents/{+path}","compare_url":"https://api.github.com/repos/dotnet/roslyn/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dotnet/roslyn/merges","archive_url":"https://api.github.com/repos/dotnet/roslyn/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dotnet/roslyn/downloads","issues_url":"https://api.github.com/repos/dotnet/roslyn/issues{/number}","pulls_url":"https://api.github.com/repos/dotnet/roslyn/pulls{/number}","milestones_url":"https://api.github.com/repos/dotnet/roslyn/milestones{/number}","notifications_url":"https://api.github.com/repos/dotnet/roslyn/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dotnet/roslyn/labels{/name}","releases_url":"https://api.github.com/repos/dotnet/roslyn/releases{/id}","deployments_url":"https://api.github.com/repos/dotnet/roslyn/deployments","created_at":"2015-01-11T02:39:03Z","updated_at":"2016-06-09T16:24:18Z","pushed_at":"2016-06-09T22:06:37Z","git_url":"git://github.com/dotnet/roslyn.git","ssh_url":"git@github.com:dotnet/roslyn.git","clone_url":"https://github.com/dotnet/roslyn.git","svn_url":"https://github.com/dotnet/roslyn","homepage":"","size":303124,"stargazers_count":5329,"watchers_count":5329,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1327,"mirror_url":null,"open_issues_count":2919,"forks":1327,"open_issues":2919,"watchers":5329,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/11899"},"html":{"href":"https://github.com/dotnet/roslyn/pull/11899"},"issue":{"href":"https://api.github.com/repos/dotnet/roslyn/issues/11899"},"comments":{"href":"https://api.github.com/repos/dotnet/roslyn/issues/11899/comments"},"review_comments":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/11899/comments"},"review_comment":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dotnet/roslyn/pulls/11899/commits"},"statuses":{"href":"https://api.github.com/repos/dotnet/roslyn/statuses/06af39169c97288dc2624739027561246db03dee"}}}}
{"actor":{"display_login":"tmat"}}